From 1f42a3f82dbc9638bc9377fdb782b30ac5f8d440 Mon Sep 17 00:00:00 2001 From: nub31 Date: Mon, 5 May 2025 16:10:16 +0200 Subject: [PATCH] Remove symbol table --- lang/Nub.Lang/Backend/Generator.cs | 105 ++++++----- lang/Nub.Lang/Backend/SymbolTable.cs | 272 --------------------------- 2 files changed, 53 insertions(+), 324 deletions(-) delete mode 100644 lang/Nub.Lang/Backend/SymbolTable.cs diff --git a/lang/Nub.Lang/Backend/Generator.cs b/lang/Nub.Lang/Backend/Generator.cs index a752279..2453837 100644 --- a/lang/Nub.Lang/Backend/Generator.cs +++ b/lang/Nub.Lang/Backend/Generator.cs @@ -7,28 +7,27 @@ public class Generator { private readonly List _definitions; private readonly StringBuilder _builder = new(); - private readonly SymbolTable _symbolTable; private readonly Dictionary _variables = new(); - + private readonly List _strings = []; + public Generator(List definitions) { _definitions = definitions; - _symbolTable = SymbolTable.Create(definitions); } 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()) { 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(); } @@ -38,7 +37,7 @@ public class Generator { return "l"; } - + if (type.Equals(NubType.Int32) || type.Equals(NubType.Bool)) { return "w"; @@ -59,26 +58,27 @@ public class Generator _builder.Append('$'); _builder.Append(node.Name); - + _builder.AppendLine($"({string.Join(", ", parameters)}) {{"); _builder.AppendLine("@start"); - GenerateBlock(node.Body, _symbolTable.ResolveLocalFunc(node.Name, node.Parameters.Select(x => x.Type).ToList())); + GenerateBlock(node.Body); if (!node.ReturnType.HasValue) { _builder.AppendLine(" ret"); } + _builder.AppendLine("}"); } - - private void GenerateBlock(BlockNode block, LocalFuncDef func) + + private void GenerateBlock(BlockNode block) { 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) { @@ -89,22 +89,22 @@ public class Generator GenerateContinue(); break; case FuncCallStatementNode funcCallStatement: - GenerateStatementFuncCall(funcCallStatement, func); + GenerateStatementFuncCall(funcCallStatement); break; case IfNode ifStatement: - GenerateIf(ifStatement, func); + GenerateIf(ifStatement); break; case ReturnNode @return: - GenerateReturn(@return, func); + GenerateReturn(@return); break; case VariableAssignmentNode variableAssignment: - GenerateVariableAssignment(variableAssignment, func); + GenerateVariableAssignment(variableAssignment); break; case VariableReassignmentNode variableReassignment: - GenerateVariableReassignment(variableReassignment, func); + GenerateVariableReassignment(variableReassignment); break; case WhileNode whileStatement: - GenerateWhile(whileStatement, func); + GenerateWhile(whileStatement); break; default: throw new ArgumentOutOfRangeException(nameof(statement)); @@ -114,33 +114,33 @@ public class Generator private void GenerateBreak() { } - + private void GenerateContinue() { } - - private void GenerateStatementFuncCall(FuncCallStatementNode funcCall, LocalFuncDef func) + + private void GenerateStatementFuncCall(FuncCallStatementNode funcCall) { var results = new List<(string, NubType)>(); 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}"); - + _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) { - var result = GenerateExpression(@return.Value.Value, func); + var result = GenerateExpression(@return.Value.Value); _builder.AppendLine($" ret {result}"); } 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) { case BinaryExpressionNode binaryExpression: - return GenerateBinaryExpression(binaryExpression, func); + return GenerateBinaryExpression(binaryExpression); case FuncCallExpressionNode funcCallExpression: - return GenerateExpressionFuncCall(funcCallExpression, func); + return GenerateExpressionFuncCall(funcCallExpression); case IdentifierNode identifier: - return GenerateIdentifier(identifier, func); + return GenerateIdentifier(identifier); case LiteralNode literal: - return GenerateLiteral(literal, func); + return GenerateLiteral(literal); case StructInitializerNode structInitializer: - return GenerateStructInitializer(structInitializer, func); + return GenerateStructInitializer(structInitializer); case StructMemberAccessorNode structMemberAccessor: - return GenerateStructMemberAccessor(structMemberAccessor, func); + return GenerateStructMemberAccessor(structMemberAccessor); default: throw new ArgumentOutOfRangeException(nameof(expression)); } } - private string GenerateStructMemberAccessor(StructMemberAccessorNode structMemberAccessor, LocalFuncDef func) + private string GenerateStructMemberAccessor(StructMemberAccessorNode structMemberAccessor) { throw new NotImplementedException(); } - private string GenerateBinaryExpression(BinaryExpressionNode binaryExpression, LocalFuncDef func) + private string GenerateBinaryExpression(BinaryExpressionNode binaryExpression) { throw new NotImplementedException(); } - private string GenerateIdentifier(IdentifierNode identifier, LocalFuncDef func) + private string GenerateIdentifier(IdentifierNode identifier) { return _variables[identifier.Identifier]; } - private string GenerateLiteral(LiteralNode literal, LocalFuncDef func) + private string GenerateLiteral(LiteralNode literal) { if (literal.LiteralType.Equals(NubType.String)) { - return $"$str{_symbolTable.ResolveString(literal.Literal)}"; + _strings.Add(literal.Literal); + return $"$str{_strings.Count}"; } else { @@ -211,24 +212,24 @@ public class Generator } } - private string GenerateStructInitializer(StructInitializerNode structInitializer, LocalFuncDef func) + private string GenerateStructInitializer(StructInitializerNode structInitializer) { throw new NotImplementedException(); } - private string GenerateExpressionFuncCall(FuncCallExpressionNode funcCall, LocalFuncDef func) + private string GenerateExpressionFuncCall(FuncCallExpressionNode funcCall) { var results = new List<(string, NubType)>(); 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 output = GenName(); _builder.AppendLine($" %{output} ={QbeTypeName(funcCall.Type)} call ${funcCall.FuncCall.Name}({string.Join(", ", parameters)})"); - + return $"%{output}"; } diff --git a/lang/Nub.Lang/Backend/SymbolTable.cs b/lang/Nub.Lang/Backend/SymbolTable.cs deleted file mode 100644 index 48747bb..0000000 --- a/lang/Nub.Lang/Backend/SymbolTable.cs +++ /dev/null @@ -1,272 +0,0 @@ -using Nub.Lang.Frontend.Parsing; - -namespace Nub.Lang.Backend; - -public class SymbolTable -{ - public static SymbolTable Create(IEnumerable program) - { - var externFuncDefs = new List(); - var localFuncDefs = new List(); - var localFuncIndex = 0; - - var strings = new List(); - - 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(); - - 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 _strings; - private readonly List _externFuncDefs; - private readonly List _localFuncDefs; - - private SymbolTable(List strings, List externFuncDefs, List localFuncDefs) - { - _strings = strings; - _externFuncDefs = externFuncDefs; - _localFuncDefs = localFuncDefs; - } - - public IReadOnlyList 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 parameters) - { - var matching = _externFuncDefs.Concat(_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 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 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 Parameters { get; init; } - public required Optional 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 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 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}"; -} \ No newline at end of file