Skip to content

Commit

Permalink
Add UserData to AstNode, add more var tracking in CompilationUnit
Browse files Browse the repository at this point in the history
  • Loading branch information
Washi1337 committed Jan 17, 2025
1 parent 313ee9c commit 5d121df
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 8 deletions.
9 changes: 9 additions & 0 deletions src/Core/Echo.Ast/AstNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,15 @@ public AddressRange? OriginalRange
get;
set;
}

/// <summary>
/// Gets or sets additional user data that is associated to the AST node.
/// </summary>
public object? UserData
{
get;
set;
}

/// <summary>
/// Obtains the parent compilation unit the AST is added to (if available).
Expand Down
4 changes: 2 additions & 2 deletions src/Core/Echo.Ast/AstVariableExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public static class AstVariableExtensions
/// <param name="self">The variable to cross-reference.</param>
/// <param name="unit">The compilation unit to cross-reference in.</param>
/// <returns>The expressions referencing the variable.</returns>
public static IEnumerable<VariableExpression<TInstruction>> GetIsUsedBy<TInstruction>(
public static IReadOnlyList<VariableExpression<TInstruction>> GetIsUsedBy<TInstruction>(
this IVariable self,
CompilationUnit<TInstruction> unit)
where TInstruction : notnull
Expand All @@ -28,7 +28,7 @@ public static IEnumerable<VariableExpression<TInstruction>> GetIsUsedBy<TInstruc
/// <param name="self">The variable to cross-reference.</param>
/// <param name="unit">The compilation unit to cross-reference in.</param>
/// <returns>The statements writing to the variable.</returns>
public static IEnumerable<Statement<TInstruction>> GetIsWrittenBy<TInstruction>(
public static IReadOnlyList<Statement<TInstruction>> GetIsWrittenBy<TInstruction>(
this IVariable self,
CompilationUnit<TInstruction> unit)
where TInstruction : notnull
Expand Down
26 changes: 21 additions & 5 deletions src/Core/Echo.Ast/CompilationUnit.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public class CompilationUnit<TInstruction> : AstNode<TInstruction>
{
private readonly Dictionary<IVariable, List<VariableExpression<TInstruction>>> _variableUses = new();
private readonly Dictionary<IVariable, List<Statement<TInstruction>>> _variableWrites = new();
private readonly HashSet<IVariable> _variables = new();

private BlockStatement<TInstruction> _root = null!;

Expand All @@ -35,15 +36,20 @@ public BlockStatement<TInstruction> Root
internal set => UpdateChildNotNull(ref _root, value);
}

/// <summary>
/// Gets a collection of all referenced variables in the compilation unit.
/// </summary>
public IReadOnlyCollection<IVariable> Variables => _variables;

/// <summary>
/// Gets all expressions in the compilation unit that reference the provided variable.
/// </summary>
/// <param name="variable">The variable to cross-reference.</param>
/// <returns>The expressions referencing the variable.</returns>
public IEnumerable<VariableExpression<TInstruction>> GetVariableUses(IVariable variable)
public IReadOnlyList<VariableExpression<TInstruction>> GetVariableUses(IVariable variable)
{
return !_variableUses.TryGetValue(variable, out var uses)
? Enumerable.Empty<VariableExpression<TInstruction>>()
? Array.Empty<VariableExpression<TInstruction>>()
: uses.ToArray(); // Clone to prevent list being modified after returning.
}

Expand All @@ -52,10 +58,10 @@ public IEnumerable<VariableExpression<TInstruction>> GetVariableUses(IVariable v
/// </summary>
/// <param name="variable">The variable to cross-reference.</param>
/// <returns>The statements writing to the variable.</returns>
public IEnumerable<Statement<TInstruction>> GetVariableWrites(IVariable variable)
public IReadOnlyList<Statement<TInstruction>> GetVariableWrites(IVariable variable)
{
return !_variableWrites.TryGetValue(variable, out var writes)
? Enumerable.Empty<Statement<TInstruction>>()
? Array.Empty<Statement<TInstruction>>()
: writes.ToArray(); // Clone to prevent list being modified after returning.
}

Expand All @@ -68,6 +74,7 @@ internal void RegisterVariableUse(VariableExpression<TInstruction> expression)
}

uses.Add(expression);
_variables.Add(expression.Variable);
}

internal void UnregisterVariableUse(VariableExpression<TInstruction> expression)
Expand All @@ -76,7 +83,11 @@ internal void UnregisterVariableUse(VariableExpression<TInstruction> expression)
{
uses.Remove(expression);
if (uses.Count == 0)
{
_variableUses.Remove(expression.Variable);
if (!_variableWrites.ContainsKey(expression.Variable))
_variables.Remove(expression.Variable);
}
}
}

Expand All @@ -89,6 +100,7 @@ internal void RegisterVariableWrite(IVariable variable, Statement<TInstruction>
}

writes.Add(statement);
_variables.Add(variable);
}

internal void UnregisterVariableWrite(IVariable variable, Statement<TInstruction> statement)
Expand All @@ -97,7 +109,11 @@ internal void UnregisterVariableWrite(IVariable variable, Statement<TInstruction
{
writes.Remove(statement);
if (writes.Count == 0)
_variableUses.Remove(variable);
{
_variableWrites.Remove(variable);
if (!_variableUses.ContainsKey(variable))
_variables.Remove(variable);
}
}
}

Expand Down
9 changes: 9 additions & 0 deletions src/Core/Echo.Ast/SyntheticVariable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,15 @@ public string Name
{
get;
}

/// <summary>
/// Gets or sets additional user data associated to the synthetic variable.
/// </summary>
public object? UserData
{
get;
set;
}

private string GenerateName()
{
Expand Down
2 changes: 1 addition & 1 deletion src/Core/Echo.Ast/VariableExpression.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public VariableExpression(IVariable variable)
public IVariable Variable
{
get => _variable;
internal set
set
{
if (_variable != value)
{
Expand Down

0 comments on commit 5d121df

Please sign in to comment.