Remove symbol table
This commit is contained in:
@@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,7 +37,7 @@ public class Generator
|
|||||||
{
|
{
|
||||||
return "l";
|
return "l";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type.Equals(NubType.Int32) || type.Equals(NubType.Bool))
|
if (type.Equals(NubType.Int32) || type.Equals(NubType.Bool))
|
||||||
{
|
{
|
||||||
return "w";
|
return "w";
|
||||||
@@ -59,26 +58,27 @@ public class Generator
|
|||||||
|
|
||||||
_builder.Append('$');
|
_builder.Append('$');
|
||||||
_builder.Append(node.Name);
|
_builder.Append(node.Name);
|
||||||
|
|
||||||
_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));
|
||||||
@@ -114,33 +114,33 @@ public class Generator
|
|||||||
private void GenerateBreak()
|
private void GenerateBreak()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GenerateContinue()
|
private void GenerateContinue()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
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}");
|
||||||
|
|
||||||
_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,24 +212,24 @@ 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}");
|
||||||
|
|
||||||
var output = GenName();
|
var output = GenName();
|
||||||
_builder.AppendLine($" %{output} ={QbeTypeName(funcCall.Type)} call ${funcCall.FuncCall.Name}({string.Join(", ", parameters)})");
|
_builder.AppendLine($" %{output} ={QbeTypeName(funcCall.Type)} call ${funcCall.FuncCall.Name}({string.Join(", ", parameters)})");
|
||||||
|
|
||||||
return $"%{output}";
|
return $"%{output}";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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}";
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user