Label factor refactor
This commit is contained in:
@@ -10,12 +10,14 @@ public class Generator
|
|||||||
private readonly List<DefinitionNode> _definitions;
|
private readonly List<DefinitionNode> _definitions;
|
||||||
private readonly SymbolTable _symbolTable;
|
private readonly SymbolTable _symbolTable;
|
||||||
private readonly StringBuilder _builder;
|
private readonly StringBuilder _builder;
|
||||||
|
private readonly LabelFactory _labelFactory;
|
||||||
|
|
||||||
public Generator(IReadOnlyCollection<DefinitionNode> definitions)
|
public Generator(IReadOnlyCollection<DefinitionNode> definitions)
|
||||||
{
|
{
|
||||||
_definitions = [];
|
_definitions = [];
|
||||||
_builder = new StringBuilder();
|
_builder = new StringBuilder();
|
||||||
_symbolTable = new SymbolTable();
|
_labelFactory = new LabelFactory();
|
||||||
|
_symbolTable = new SymbolTable(_labelFactory);
|
||||||
|
|
||||||
foreach (var globalVariableDefinition in definitions.OfType<GlobalVariableDefinitionNode>())
|
foreach (var globalVariableDefinition in definitions.OfType<GlobalVariableDefinitionNode>())
|
||||||
{
|
{
|
||||||
@@ -194,14 +196,14 @@ public class Generator
|
|||||||
|
|
||||||
private void GenerateIf(IfNode ifStatement, LocalFunc func)
|
private void GenerateIf(IfNode ifStatement, LocalFunc func)
|
||||||
{
|
{
|
||||||
var endLabel = _symbolTable.LabelFactory.Create();
|
var endLabel = _labelFactory.Create();
|
||||||
GenerateIf(ifStatement, endLabel, func);
|
GenerateIf(ifStatement, endLabel, func);
|
||||||
_builder.AppendLine($"{endLabel}:");
|
_builder.AppendLine($"{endLabel}:");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GenerateIf(IfNode ifStatement, string endLabel, LocalFunc func)
|
private void GenerateIf(IfNode ifStatement, string endLabel, LocalFunc func)
|
||||||
{
|
{
|
||||||
var nextLabel = _symbolTable.LabelFactory.Create();
|
var nextLabel = _labelFactory.Create();
|
||||||
GenerateExpression(ifStatement.Condition, func);
|
GenerateExpression(ifStatement.Condition, func);
|
||||||
_builder.AppendLine(" cmp rax, 0");
|
_builder.AppendLine(" cmp rax, 0");
|
||||||
_builder.AppendLine($" je {nextLabel}");
|
_builder.AppendLine($" je {nextLabel}");
|
||||||
@@ -455,9 +457,8 @@ public class Generator
|
|||||||
}
|
}
|
||||||
case StringType:
|
case StringType:
|
||||||
{
|
{
|
||||||
var ident = _symbolTable.LabelFactory.Create();
|
var label = _symbolTable.DefineString(literal.Literal);
|
||||||
_symbolTable.DefineString(ident, literal.Literal);
|
_builder.AppendLine($" mov rax, {label}");
|
||||||
_builder.AppendLine($" mov rax, {ident}");
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PrimitiveType primitive:
|
case PrimitiveType primitive:
|
||||||
|
|||||||
7
Nub.Lang/Nub.Lang/Backend/Custom/LabelFactory.cs
Normal file
7
Nub.Lang/Nub.Lang/Backend/Custom/LabelFactory.cs
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
namespace Nub.Lang.Backend.Custom;
|
||||||
|
|
||||||
|
public class LabelFactory
|
||||||
|
{
|
||||||
|
private int _index;
|
||||||
|
public string Create() => $"label{++_index}";
|
||||||
|
}
|
||||||
@@ -7,18 +7,25 @@ public class SymbolTable
|
|||||||
{
|
{
|
||||||
private readonly List<Func> _funcDefinitions = [];
|
private readonly List<Func> _funcDefinitions = [];
|
||||||
private readonly List<GlobalVariable> _globalVariables = [];
|
private readonly List<GlobalVariable> _globalVariables = [];
|
||||||
public LabelFactory LabelFactory { get; } = new();
|
private LabelFactory _labelFactory;
|
||||||
|
|
||||||
public readonly Dictionary<string, string> Strings = [];
|
public readonly Dictionary<string, string> Strings = [];
|
||||||
|
|
||||||
public void DefineString(string label, string value)
|
public SymbolTable(LabelFactory labelFactory)
|
||||||
{
|
{
|
||||||
|
_labelFactory = labelFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string DefineString(string value)
|
||||||
|
{
|
||||||
|
var label = _labelFactory.Create();
|
||||||
Strings.Add(label, value);
|
Strings.Add(label, value);
|
||||||
|
return label;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DefineGlobalVariable(GlobalVariableDefinitionNode globalVariableDefinition)
|
public void DefineGlobalVariable(GlobalVariableDefinitionNode globalVariableDefinition)
|
||||||
{
|
{
|
||||||
var identifier = LabelFactory.Create();
|
var identifier = _labelFactory.Create();
|
||||||
_globalVariables.Add(new GlobalVariable(globalVariableDefinition.Name, globalVariableDefinition.Value.Type, identifier));
|
_globalVariables.Add(new GlobalVariable(globalVariableDefinition.Name, globalVariableDefinition.Value.Type, identifier));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,8 +62,8 @@ public class SymbolTable
|
|||||||
throw new Exception($"Func {existing} is already defined");
|
throw new Exception($"Func {existing} is already defined");
|
||||||
}
|
}
|
||||||
|
|
||||||
var startLabel = LabelFactory.Create();
|
var startLabel = _labelFactory.Create();
|
||||||
var endLabel = LabelFactory.Create();
|
var endLabel = _labelFactory.Create();
|
||||||
_funcDefinitions.Add(new LocalFunc(localFuncDefinition.Name, startLabel, endLabel, localFuncDefinition.Parameters, localFuncDefinition.ReturnType, _globalVariables.Concat<Variable>(ResolveFuncVariables(localFuncDefinition)).ToList()));
|
_funcDefinitions.Add(new LocalFunc(localFuncDefinition.Name, startLabel, endLabel, localFuncDefinition.Parameters, localFuncDefinition.ReturnType, _globalVariables.Concat<Variable>(ResolveFuncVariables(localFuncDefinition)).ToList()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -213,10 +220,3 @@ public class LocalFunc : Func
|
|||||||
|
|
||||||
public override string ToString() => $"{Name}({string.Join(", ", Parameters.Select(p => p.ToString()))}){(ReturnType.HasValue ? ": " + ReturnType.Value : "")}";
|
public override string ToString() => $"{Name}({string.Join(", ", Parameters.Select(p => p.ToString()))}){(ReturnType.HasValue ? ": " + ReturnType.Value : "")}";
|
||||||
}
|
}
|
||||||
|
|
||||||
public class LabelFactory
|
|
||||||
{
|
|
||||||
private int _index;
|
|
||||||
|
|
||||||
public string Create() => $"label{++_index}";
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user