Remove symbol table

This commit is contained in:
nub31
2025-05-05 16:10:16 +02:00
parent b67d33455d
commit 1f42a3f82d
2 changed files with 53 additions and 324 deletions

View File

@@ -7,28 +7,27 @@ public class Generator
{ {
private readonly List<DefinitionNode> _definitions; private readonly List<DefinitionNode> _definitions;
private readonly StringBuilder _builder = new(); private readonly StringBuilder _builder = new();
private readonly SymbolTable _symbolTable;
private readonly Dictionary<string, string> _variables = new(); private readonly Dictionary<string, string> _variables = new();
private readonly List<string> _strings = [];
public Generator(List<DefinitionNode> definitions) public Generator(List<DefinitionNode> definitions)
{ {
_definitions = definitions; _definitions = definitions;
_symbolTable = SymbolTable.Create(definitions);
} }
public string Generate() public string Generate()
{ {
for (var i = 0; i < _symbolTable.Strings.Count; i++)
{
var str = _symbolTable.Strings[i];
_builder.AppendLine($"data $str{i} = {{ b \"{str}\", b 0 }}");
}
foreach (var funcDefinition in _definitions.OfType<LocalFuncDefinitionNode>()) foreach (var funcDefinition in _definitions.OfType<LocalFuncDefinitionNode>())
{ {
GenerateFuncDefinition(funcDefinition); GenerateFuncDefinition(funcDefinition);
} }
for (var i = 0; i < _strings.Count; i++)
{
var str = _strings[i];
_builder.AppendLine($"data $str{i + 1} = {{ b \"{str}\", b 0 }}");
}
return _builder.ToString(); return _builder.ToString();
} }
@@ -62,23 +61,24 @@ public class Generator
_builder.AppendLine($"({string.Join(", ", parameters)}) {{"); _builder.AppendLine($"({string.Join(", ", parameters)}) {{");
_builder.AppendLine("@start"); _builder.AppendLine("@start");
GenerateBlock(node.Body, _symbolTable.ResolveLocalFunc(node.Name, node.Parameters.Select(x => x.Type).ToList())); GenerateBlock(node.Body);
if (!node.ReturnType.HasValue) if (!node.ReturnType.HasValue)
{ {
_builder.AppendLine(" ret"); _builder.AppendLine(" ret");
} }
_builder.AppendLine("}"); _builder.AppendLine("}");
} }
private void GenerateBlock(BlockNode block, LocalFuncDef func) private void GenerateBlock(BlockNode block)
{ {
foreach (var statement in block.Statements) foreach (var statement in block.Statements)
{ {
GenerateStatement(statement, func); GenerateStatement(statement);
} }
} }
private void GenerateStatement(StatementNode statement, LocalFuncDef func) private void GenerateStatement(StatementNode statement)
{ {
switch (statement) switch (statement)
{ {
@@ -89,22 +89,22 @@ public class Generator
GenerateContinue(); GenerateContinue();
break; break;
case FuncCallStatementNode funcCallStatement: case FuncCallStatementNode funcCallStatement:
GenerateStatementFuncCall(funcCallStatement, func); GenerateStatementFuncCall(funcCallStatement);
break; break;
case IfNode ifStatement: case IfNode ifStatement:
GenerateIf(ifStatement, func); GenerateIf(ifStatement);
break; break;
case ReturnNode @return: case ReturnNode @return:
GenerateReturn(@return, func); GenerateReturn(@return);
break; break;
case VariableAssignmentNode variableAssignment: case VariableAssignmentNode variableAssignment:
GenerateVariableAssignment(variableAssignment, func); GenerateVariableAssignment(variableAssignment);
break; break;
case VariableReassignmentNode variableReassignment: case VariableReassignmentNode variableReassignment:
GenerateVariableReassignment(variableReassignment, func); GenerateVariableReassignment(variableReassignment);
break; break;
case WhileNode whileStatement: case WhileNode whileStatement:
GenerateWhile(whileStatement, func); GenerateWhile(whileStatement);
break; break;
default: default:
throw new ArgumentOutOfRangeException(nameof(statement)); throw new ArgumentOutOfRangeException(nameof(statement));
@@ -119,12 +119,12 @@ public class Generator
{ {
} }
private void GenerateStatementFuncCall(FuncCallStatementNode funcCall, LocalFuncDef func) private void GenerateStatementFuncCall(FuncCallStatementNode funcCall)
{ {
var results = new List<(string, NubType)>(); var results = new List<(string, NubType)>();
foreach (var parameter in funcCall.FuncCall.Parameters) foreach (var parameter in funcCall.FuncCall.Parameters)
{ {
results.Add((GenerateExpression(parameter, func), parameter.Type)); results.Add((GenerateExpression(parameter), parameter.Type));
} }
var parameters = results.Select(p => $"{QbeTypeName(p.Item2)} {p.Item1}"); var parameters = results.Select(p => $"{QbeTypeName(p.Item2)} {p.Item1}");
@@ -132,15 +132,15 @@ public class Generator
_builder.AppendLine($" call ${funcCall.FuncCall.Name}({string.Join(", ", parameters)})"); _builder.AppendLine($" call ${funcCall.FuncCall.Name}({string.Join(", ", parameters)})");
} }
private void GenerateIf(IfNode ifStatement, LocalFuncDef func) private void GenerateIf(IfNode ifStatement)
{ {
} }
private void GenerateReturn(ReturnNode @return, LocalFuncDef func) private void GenerateReturn(ReturnNode @return)
{ {
if (@return.Value.HasValue) if (@return.Value.HasValue)
{ {
var result = GenerateExpression(@return.Value.Value, func); var result = GenerateExpression(@return.Value.Value);
_builder.AppendLine($" ret {result}"); _builder.AppendLine($" ret {result}");
} }
else else
@@ -149,61 +149,62 @@ public class Generator
} }
} }
private void GenerateVariableAssignment(VariableAssignmentNode variableAssignment, LocalFuncDef func) private void GenerateVariableAssignment(VariableAssignmentNode variableAssignment)
{ {
_variables[variableAssignment.Name] = GenerateExpression(variableAssignment.Value, func); _variables[variableAssignment.Name] = GenerateExpression(variableAssignment.Value);
} }
private void GenerateVariableReassignment(VariableReassignmentNode variableReassignment, LocalFuncDef func) private void GenerateVariableReassignment(VariableReassignmentNode variableReassignment)
{ {
_variables[variableReassignment.Name] = GenerateExpression(variableReassignment.Value, func); _variables[variableReassignment.Name] = GenerateExpression(variableReassignment.Value);
} }
private void GenerateWhile(WhileNode whileStatement, LocalFuncDef func) private void GenerateWhile(WhileNode whileStatement)
{ {
} }
private string GenerateExpression(ExpressionNode expression, LocalFuncDef func) private string GenerateExpression(ExpressionNode expression)
{ {
switch (expression) switch (expression)
{ {
case BinaryExpressionNode binaryExpression: case BinaryExpressionNode binaryExpression:
return GenerateBinaryExpression(binaryExpression, func); return GenerateBinaryExpression(binaryExpression);
case FuncCallExpressionNode funcCallExpression: case FuncCallExpressionNode funcCallExpression:
return GenerateExpressionFuncCall(funcCallExpression, func); return GenerateExpressionFuncCall(funcCallExpression);
case IdentifierNode identifier: case IdentifierNode identifier:
return GenerateIdentifier(identifier, func); return GenerateIdentifier(identifier);
case LiteralNode literal: case LiteralNode literal:
return GenerateLiteral(literal, func); return GenerateLiteral(literal);
case StructInitializerNode structInitializer: case StructInitializerNode structInitializer:
return GenerateStructInitializer(structInitializer, func); return GenerateStructInitializer(structInitializer);
case StructMemberAccessorNode structMemberAccessor: case StructMemberAccessorNode structMemberAccessor:
return GenerateStructMemberAccessor(structMemberAccessor, func); return GenerateStructMemberAccessor(structMemberAccessor);
default: default:
throw new ArgumentOutOfRangeException(nameof(expression)); throw new ArgumentOutOfRangeException(nameof(expression));
} }
} }
private string GenerateStructMemberAccessor(StructMemberAccessorNode structMemberAccessor, LocalFuncDef func) private string GenerateStructMemberAccessor(StructMemberAccessorNode structMemberAccessor)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
private string GenerateBinaryExpression(BinaryExpressionNode binaryExpression, LocalFuncDef func) private string GenerateBinaryExpression(BinaryExpressionNode binaryExpression)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
private string GenerateIdentifier(IdentifierNode identifier, LocalFuncDef func) private string GenerateIdentifier(IdentifierNode identifier)
{ {
return _variables[identifier.Identifier]; return _variables[identifier.Identifier];
} }
private string GenerateLiteral(LiteralNode literal, LocalFuncDef func) private string GenerateLiteral(LiteralNode literal)
{ {
if (literal.LiteralType.Equals(NubType.String)) if (literal.LiteralType.Equals(NubType.String))
{ {
return $"$str{_symbolTable.ResolveString(literal.Literal)}"; _strings.Add(literal.Literal);
return $"$str{_strings.Count}";
} }
else else
{ {
@@ -211,17 +212,17 @@ public class Generator
} }
} }
private string GenerateStructInitializer(StructInitializerNode structInitializer, LocalFuncDef func) private string GenerateStructInitializer(StructInitializerNode structInitializer)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
private string GenerateExpressionFuncCall(FuncCallExpressionNode funcCall, LocalFuncDef func) private string GenerateExpressionFuncCall(FuncCallExpressionNode funcCall)
{ {
var results = new List<(string, NubType)>(); var results = new List<(string, NubType)>();
foreach (var parameter in funcCall.FuncCall.Parameters) foreach (var parameter in funcCall.FuncCall.Parameters)
{ {
results.Add((GenerateExpression(parameter, func), parameter.Type)); results.Add((GenerateExpression(parameter), parameter.Type));
} }
var parameters = results.Select(p => $"{QbeTypeName(p.Item2)} {p.Item1}"); var parameters = results.Select(p => $"{QbeTypeName(p.Item2)} {p.Item1}");

View File

@@ -1,272 +0,0 @@
using Nub.Lang.Frontend.Parsing;
namespace Nub.Lang.Backend;
public class SymbolTable
{
public static SymbolTable Create(IEnumerable<DefinitionNode> program)
{
var externFuncDefs = new List<ExternFuncDef>();
var localFuncDefs = new List<LocalFuncDef>();
var localFuncIndex = 0;
var strings = new List<string>();
foreach (var node in program)
{
switch (node)
{
case ExternFuncDefinitionNode externFuncDefinitionNode:
{
var parameters = externFuncDefinitionNode.Parameters.Select(parameter => new Variable(parameter.Name, parameter.Type)).ToList();
externFuncDefs.Add(new ExternFuncDef
{
Name = externFuncDefinitionNode.Name,
Parameters = parameters,
ReturnType = externFuncDefinitionNode.ReturnType
});
break;
}
case LocalFuncDefinitionNode localFuncDefinitionNode:
{
var parameters = localFuncDefinitionNode.Parameters.Select(parameter => new Variable(parameter.Name, parameter.Type)).ToList();
var localVariables = new List<Variable>();
Search(localFuncDefinitionNode.Body);
localFuncDefs.Add(new LocalFuncDef
{
Name = localFuncDefinitionNode.Name,
Parameters = parameters,
LocalVariables = localVariables,
ReturnType = localFuncDefinitionNode.ReturnType
});
break;
void Search(BlockNode blockNode)
{
foreach (var statement in blockNode.Statements)
{
switch (statement)
{
case FuncCallStatementNode funcCallStatementNode:
{
foreach (var parameter in funcCallStatementNode.FuncCall.Parameters)
{
FindStrings(parameter);
}
break;
}
case IfNode ifNode:
{
SearchIf(ifNode);
break;
}
case ReturnNode returnNode:
{
if (returnNode.Value.HasValue)
{
FindStrings(returnNode.Value.Value);
}
break;
}
case WhileNode whileNode:
{
FindStrings(whileNode.Condition);
Search(whileNode.Body);
break;
}
case VariableAssignmentNode variableAssignmentNode:
{
FindStrings(variableAssignmentNode.Value);
localVariables.Add(new Variable(variableAssignmentNode.Name, variableAssignmentNode.Value.Type));
break;
}
case VariableReassignmentNode variableReassignmentNode:
{
FindStrings(variableReassignmentNode.Value);
break;
}
}
}
}
void SearchIf(IfNode ifNode)
{
FindStrings(ifNode.Condition);
Search(ifNode.Body);
if (ifNode.Else.HasValue)
{
ifNode.Else.Value.Match(SearchIf, Search);
}
}
void FindStrings(ExpressionNode expressionNode)
{
switch (expressionNode)
{
case BinaryExpressionNode binaryExpressionNode:
{
FindStrings(binaryExpressionNode.Left);
FindStrings(binaryExpressionNode.Right);
break;
}
case FuncCallExpressionNode funcCallExpressionNode:
{
foreach (var parameter in funcCallExpressionNode.FuncCall.Parameters)
{
FindStrings(parameter);
}
break;
}
case LiteralNode literalNode:
{
if (literalNode.LiteralType.Equals(NubType.String))
{
strings.Add(literalNode.Literal);
}
break;
}
case StructInitializerNode structInitializerNode:
{
foreach (var initializer in structInitializerNode.Initializers)
{
FindStrings(initializer.Value);
}
break;
}
}
}
}
case StructDefinitionNode structDefinitionNode:
{
throw new NotImplementedException();
}
default:
{
throw new ArgumentOutOfRangeException(nameof(node));
}
}
}
return new SymbolTable(strings, externFuncDefs, localFuncDefs);
}
private readonly List<string> _strings;
private readonly List<ExternFuncDef> _externFuncDefs;
private readonly List<LocalFuncDef> _localFuncDefs;
private SymbolTable(List<string> strings, List<ExternFuncDef> externFuncDefs, List<LocalFuncDef> localFuncDefs)
{
_strings = strings;
_externFuncDefs = externFuncDefs;
_localFuncDefs = localFuncDefs;
}
public IReadOnlyList<string> Strings => _strings;
public int ResolveString(string value)
{
var index = _strings.IndexOf(value);
if (index == -1)
{
throw new Exception("String not found: " + value);
}
return index;
}
public FuncDef ResolveFunc(string name, List<NubType> parameters)
{
var matching = _externFuncDefs.Concat<FuncDef>(_localFuncDefs).Where(funcDef => funcDef.SignatureMatches(name, parameters)).ToArray();
return matching.Length switch
{
0 => throw new Exception($"Could not resolve a func with signature {name}({string.Join(", ", parameters)})"),
> 1 => throw new Exception($"Multiple functions matches the signature {name}({string.Join(", ", parameters)})"),
_ => matching[0]
};
}
public LocalFuncDef ResolveLocalFunc(string name, List<NubType> parameters)
{
var funcDef = ResolveFunc(name, parameters);
if (funcDef is LocalFuncDef localFuncDef)
{
return localFuncDef;
}
throw new Exception($"Could not resolve a local func with signature {name}({string.Join(", ", parameters)})");
}
public ExternFuncDef ResolveExternFunc(string name, List<NubType> parameters)
{
var funcDef = ResolveFunc(name, parameters);
if (funcDef is ExternFuncDef externFuncDef)
{
return externFuncDef;
}
throw new Exception($"Could not resolve a extern func with signature {name}({string.Join(", ", parameters)})");
}
}
public abstract class FuncDef
{
public required string Name { get; init; }
public required List<Variable> Parameters { get; init; }
public required Optional<NubType> ReturnType { get; init; }
public virtual Variable ResolveVariable(string name)
{
var parameter = Parameters.FirstOrDefault(p => p.Name == name);
if (parameter == null)
{
throw new Exception($"Unable to resolve variable {name}");
}
return parameter;
}
public bool SignatureMatches(string name, List<NubType> parameterTypes)
{
if (Name != name) return false;
if (Parameters.Count != parameterTypes.Count) return false;
for (var i = 0; i < parameterTypes.Count; i++)
{
if (!Parameters[i].Type.Equals(parameterTypes[i])) return false;
}
return true;
}
}
public sealed class LocalFuncDef : FuncDef
{
public required List<Variable> LocalVariables { get; init; }
public override Variable ResolveVariable(string name)
{
return LocalVariables.FirstOrDefault(p => p.Name == name) ?? base.ResolveVariable(name);
}
public override string ToString()
{
return $"func {Name}({string.Join(", ", Parameters.Select(p => p.ToString()))}){(ReturnType.HasValue ? ": " + ReturnType.Value : "")}";
}
}
public sealed class ExternFuncDef : FuncDef;
public sealed class Variable(string name, NubType type)
{
public string Name { get; } = name;
public NubType Type { get; } = type;
public override string ToString() => $"{Name}: {Type}";
}