...
This commit is contained in:
@@ -19,7 +19,7 @@ public static class QBEGenerator
|
||||
private static Stack<string> _breakLabels = [];
|
||||
private static Stack<string> _continueLabels = [];
|
||||
private static Queue<(BoundAnonymousFuncNode Func, string Name)> _anonymousFunctions = [];
|
||||
private static Dictionary<BoundImplementationFuncNode, string> _implFunctions = [];
|
||||
private static Dictionary<BoundTraitFuncImplNode, string> _implFunctions = [];
|
||||
private static Stack<Variable> _variables = [];
|
||||
private static Stack<int> _variableScopes = [];
|
||||
private static int _tmpIndex;
|
||||
@@ -65,7 +65,7 @@ public static class QBEGenerator
|
||||
_writer.NewLine();
|
||||
}
|
||||
|
||||
foreach (var funcDef in _syntaxTree.Definitions.OfType<BoundLocalFuncDefinitionNode>())
|
||||
foreach (var funcDef in _syntaxTree.TopLevelNodes.OfType<BoundLocalFuncNode>())
|
||||
{
|
||||
EmitFuncDefinition(funcDef, FuncName(funcDef), funcDef.Parameters, funcDef.ReturnType, funcDef.Body, funcDef.Exported);
|
||||
_writer.NewLine();
|
||||
@@ -121,15 +121,15 @@ public static class QBEGenerator
|
||||
{
|
||||
return funcDef switch
|
||||
{
|
||||
BoundExternFuncDefinitionNode externFuncDefinition => $"${externFuncDefinition.CallName}",
|
||||
BoundLocalFuncDefinitionNode localFuncDefinition => localFuncDefinition.Exported
|
||||
BoundExternFuncNode externFuncDefinition => $"${externFuncDefinition.CallName}",
|
||||
BoundLocalFuncNode localFuncDefinition => localFuncDefinition.Exported
|
||||
? $"${localFuncDefinition.Name}"
|
||||
: $"${localFuncDefinition.Namespace}_{localFuncDefinition.Name}",
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(funcDef))
|
||||
};
|
||||
}
|
||||
|
||||
private static string ImplFuncName(BoundTraitImplementationDefinitionNode implDef, string funcName)
|
||||
private static string ImplFuncName(BoundTraitImplNode implDef, string funcName)
|
||||
{
|
||||
return $"$impl{++_implFuncNameIndex}";
|
||||
}
|
||||
@@ -495,7 +495,7 @@ public static class QBEGenerator
|
||||
}
|
||||
}
|
||||
|
||||
private static int OffsetOf(BoundStructDefinitionNode structDefinition, string member)
|
||||
private static int OffsetOf(BoundStructNode structDefinition, string member)
|
||||
{
|
||||
var offset = 0;
|
||||
|
||||
@@ -586,7 +586,7 @@ public static class QBEGenerator
|
||||
_writer.EndFunction();
|
||||
}
|
||||
|
||||
private static void EmitStructDefinition(BoundStructDefinitionNode structDef)
|
||||
private static void EmitStructDefinition(BoundStructNode structDef)
|
||||
{
|
||||
var structType = new NubCustomType(structDef.Namespace, structDef.Name);
|
||||
_writer.WriteLine($"type {CustomTypeName(structType)} = {{ ");
|
||||
@@ -608,7 +608,7 @@ public static class QBEGenerator
|
||||
_writer.WriteLine("}");
|
||||
return;
|
||||
|
||||
string StructDefQBEType(BoundStructField field)
|
||||
string StructDefQBEType(BoundStructFieldNode field)
|
||||
{
|
||||
return field.Type switch
|
||||
{
|
||||
@@ -634,7 +634,7 @@ public static class QBEGenerator
|
||||
}
|
||||
}
|
||||
|
||||
private static void EmitTraitVTable(BoundTraitDefinitionNode traitDef)
|
||||
private static void EmitTraitVTable(BoundTraitNode traitDef)
|
||||
{
|
||||
_writer.WriteLine($"type {CustomTypeName(new NubCustomType(traitDef.Namespace, traitDef.Name))} = {{");
|
||||
|
||||
|
||||
@@ -23,34 +23,34 @@ public static class Binder
|
||||
_variables = [];
|
||||
_funcReturnType = null;
|
||||
|
||||
var definitions = new List<BoundDefinitionNode>();
|
||||
var definitions = new List<BoundTopLevelNode>();
|
||||
|
||||
foreach (var definition in syntaxTree.Definitions)
|
||||
foreach (var topLevel in syntaxTree.TopLevelNodes)
|
||||
{
|
||||
definitions.Add(BindDefinition(definition));
|
||||
definitions.Add(BindTopLevel(topLevel));
|
||||
}
|
||||
|
||||
diagnostics = [];
|
||||
return new BoundSyntaxTree(syntaxTree.Namespace, definitions);
|
||||
}
|
||||
|
||||
private static BoundDefinitionNode BindDefinition(DefinitionNode node)
|
||||
private static BoundTopLevelNode BindTopLevel(TopLevelNode node)
|
||||
{
|
||||
return node switch
|
||||
{
|
||||
ExternFuncDefinitionNode definition => BindExternFuncDefinition(definition),
|
||||
TraitImplementationDefinitionNode definition => BindTraitImplementation(definition),
|
||||
TraitDefinitionNode definition => BindTraitDefinition(definition),
|
||||
LocalFuncDefinitionNode definition => BindLocalFuncDefinition(definition),
|
||||
StructDefinitionNode definition => BindStruct(definition),
|
||||
ExternFuncNode definition => BindExternFuncDefinition(definition),
|
||||
TraitImplNode definition => BindTraitImplementation(definition),
|
||||
TraitNode definition => BindTraitDefinition(definition),
|
||||
LocalFuncNode definition => BindLocalFuncDefinition(definition),
|
||||
StructNode definition => BindStruct(definition),
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(node))
|
||||
};
|
||||
}
|
||||
|
||||
private static BoundTraitImplementationDefinitionNode BindTraitImplementation(TraitImplementationDefinitionNode node)
|
||||
private static BoundTraitImplNode BindTraitImplementation(TraitImplNode node)
|
||||
{
|
||||
_variables.Clear();
|
||||
var functions = new List<BoundImplementationFuncNode>();
|
||||
var functions = new List<BoundTraitFuncImplNode>();
|
||||
|
||||
foreach (var function in node.Functions)
|
||||
{
|
||||
@@ -59,25 +59,25 @@ public static class Binder
|
||||
_variables[parameter.Name] = parameter.Type;
|
||||
}
|
||||
|
||||
functions.Add(new BoundImplementationFuncNode(function.Tokens, function.Name, function.Parameters, function.ReturnType, BindBlock(function.Body)));
|
||||
functions.Add(new BoundTraitFuncImplNode(function.Tokens, function.Name, function.Parameters, function.ReturnType, BindBlock(function.Body)));
|
||||
}
|
||||
|
||||
return new BoundTraitImplementationDefinitionNode(node.Tokens, node.Namespace, node.TraitType, node.ForType, functions);
|
||||
return new BoundTraitImplNode(node.Tokens, node.Namespace, node.TraitType, node.ForType, functions);
|
||||
}
|
||||
|
||||
private static BoundTraitDefinitionNode BindTraitDefinition(TraitDefinitionNode node)
|
||||
private static BoundTraitNode BindTraitDefinition(TraitNode node)
|
||||
{
|
||||
var functions = new List<BountTraitFunc>();
|
||||
var functions = new List<BoundTraitFuncNode>();
|
||||
|
||||
foreach (var func in node.Functions)
|
||||
{
|
||||
functions.Add(new BountTraitFunc(func.Name, func.Parameters, func.ReturnType));
|
||||
functions.Add(new BoundTraitFuncNode(node.Tokens, func.Name, func.Parameters, func.ReturnType));
|
||||
}
|
||||
|
||||
return new BoundTraitDefinitionNode(node.Tokens, node.Namespace, node.Name, functions);
|
||||
return new BoundTraitNode(node.Tokens, node.Namespace, node.Name, functions);
|
||||
}
|
||||
|
||||
private static BoundStructDefinitionNode BindStruct(StructDefinitionNode node)
|
||||
private static BoundStructNode BindStruct(StructNode node)
|
||||
{
|
||||
var defOpt = _definitionTable.LookupStruct(node.Namespace, node.Name);
|
||||
if (!defOpt.TryGetValue(out var definition))
|
||||
@@ -85,7 +85,7 @@ public static class Binder
|
||||
throw new NotImplementedException("Diagnostics not implemented");
|
||||
}
|
||||
|
||||
var structFields = new List<BoundStructField>();
|
||||
var structFields = new List<BoundStructFieldNode>();
|
||||
|
||||
foreach (var structField in node.Fields)
|
||||
{
|
||||
@@ -102,18 +102,18 @@ public static class Binder
|
||||
value = BindExpression(structField.Value.Value, definitionField.Type);
|
||||
}
|
||||
|
||||
structFields.Add(new BoundStructField(structField.Name, structField.Type, value));
|
||||
structFields.Add(new BoundStructFieldNode(structField.Tokens, structField.Name, structField.Type, value));
|
||||
}
|
||||
|
||||
return new BoundStructDefinitionNode(node.Tokens, node.Namespace, node.Name, structFields);
|
||||
return new BoundStructNode(node.Tokens, node.Namespace, node.Name, structFields);
|
||||
}
|
||||
|
||||
private static BoundExternFuncDefinitionNode BindExternFuncDefinition(ExternFuncDefinitionNode node)
|
||||
private static BoundExternFuncNode BindExternFuncDefinition(ExternFuncNode node)
|
||||
{
|
||||
return new BoundExternFuncDefinitionNode(node.Tokens, node.Namespace, node.Name, node.CallName, node.Parameters, node.ReturnType);
|
||||
return new BoundExternFuncNode(node.Tokens, node.Namespace, node.Name, node.CallName, node.Parameters, node.ReturnType);
|
||||
}
|
||||
|
||||
private static BoundLocalFuncDefinitionNode BindLocalFuncDefinition(LocalFuncDefinitionNode node)
|
||||
private static BoundLocalFuncNode BindLocalFuncDefinition(LocalFuncNode node)
|
||||
{
|
||||
_variables.Clear();
|
||||
_funcReturnType = node.ReturnType;
|
||||
@@ -125,7 +125,7 @@ public static class Binder
|
||||
|
||||
var body = BindBlock(node.Body);
|
||||
|
||||
return new BoundLocalFuncDefinitionNode(node.Tokens, node.Namespace, node.Name, node.Parameters, body, node.ReturnType, node.Exported);
|
||||
return new BoundLocalFuncNode(node.Tokens, node.Namespace, node.Name, node.Parameters, body, node.ReturnType, node.Exported);
|
||||
}
|
||||
|
||||
private static BoundBlock BindBlock(BlockNode node)
|
||||
|
||||
@@ -1,158 +1,23 @@
|
||||
using Common;
|
||||
using Syntax.Binding;
|
||||
using Syntax.Node;
|
||||
using Syntax.Parsing;
|
||||
|
||||
namespace Syntax;
|
||||
|
||||
public class DefinitionTable
|
||||
{
|
||||
private readonly IEnumerable<SyntaxTree> _syntaxTrees;
|
||||
private readonly List<TopLevelNode> _topLevelNodes;
|
||||
|
||||
public DefinitionTable(IEnumerable<SyntaxTree> syntaxTrees)
|
||||
{
|
||||
_syntaxTrees = syntaxTrees;
|
||||
}
|
||||
|
||||
public Optional<FuncDefinition> LookupFunction(string @namespace, string name)
|
||||
{
|
||||
var definition = _syntaxTrees
|
||||
.Where(c => c.Namespace == @namespace)
|
||||
.SelectMany(c => c.Definitions)
|
||||
.OfType<FuncDefinition>()
|
||||
.SingleOrDefault(f => f.Name == name);
|
||||
|
||||
return Optional.OfNullable(definition);
|
||||
}
|
||||
|
||||
public Optional<StructDefinitionNode> LookupStruct(string @namespace, string name)
|
||||
{
|
||||
var definition = _syntaxTrees
|
||||
.Where(c => c.Namespace == @namespace)
|
||||
.SelectMany(c => c.Definitions)
|
||||
.OfType<StructDefinitionNode>()
|
||||
.SingleOrDefault(f => f.Name == name);
|
||||
|
||||
return Optional.OfNullable(definition);
|
||||
}
|
||||
|
||||
public Optional<TraitDefinitionNode> LookupTrait(string @namespace, string name)
|
||||
{
|
||||
var definition = _syntaxTrees
|
||||
.Where(c => c.Namespace == @namespace)
|
||||
.SelectMany(c => c.Definitions)
|
||||
.OfType<TraitDefinitionNode>()
|
||||
.SingleOrDefault(f => f.Name == name);
|
||||
|
||||
return Optional.OfNullable(definition);
|
||||
}
|
||||
|
||||
public Optional<Tuple<TraitImplementationDefinitionNode, ImplementationFuncNode>> LookupTraitImplementationForType(NubType type, string funcName)
|
||||
{
|
||||
var implementations = _syntaxTrees
|
||||
.SelectMany(c => c.Definitions)
|
||||
.OfType<TraitImplementationDefinitionNode>()
|
||||
.Where(c => c.ForType == type);
|
||||
|
||||
var implementation = implementations.SingleOrDefault(c => c.Functions.Any(x => x.Name == funcName));
|
||||
|
||||
var value = implementation == null ? null : new Tuple<TraitImplementationDefinitionNode, ImplementationFuncNode>(implementation, implementation.Functions.First(x => x.Name == funcName));
|
||||
|
||||
return Optional.OfNullable(value);
|
||||
}
|
||||
|
||||
public Optional<TraitFunc> LookupFunctionOnTrait(string @namespace, string name, string funcName)
|
||||
{
|
||||
var traitDef = LookupTrait(@namespace, name);
|
||||
if (traitDef.HasValue)
|
||||
{
|
||||
var function = traitDef.Value.Functions.SingleOrDefault(x => x.Name == funcName);
|
||||
return Optional.OfNullable(function);
|
||||
}
|
||||
|
||||
return Optional<TraitFunc>.Empty();
|
||||
_topLevelNodes = syntaxTrees.SelectMany(x => x.TopLevelNodes).ToList();
|
||||
}
|
||||
}
|
||||
|
||||
public class BoundDefinitionTable
|
||||
{
|
||||
private readonly IEnumerable<BoundSyntaxTree> _syntaxTrees;
|
||||
private readonly List<BoundTopLevelNode> _topLevelNodes;
|
||||
|
||||
public BoundDefinitionTable(IEnumerable<BoundSyntaxTree> syntaxTrees)
|
||||
{
|
||||
_syntaxTrees = syntaxTrees;
|
||||
}
|
||||
|
||||
public Optional<BoundFuncDefinition> LookupFunc(string @namespace, string name)
|
||||
{
|
||||
var definition = _syntaxTrees
|
||||
.Where(c => c.Namespace == @namespace)
|
||||
.SelectMany(c => c.Definitions)
|
||||
.OfType<BoundFuncDefinition>()
|
||||
.SingleOrDefault(f => f.Name == name);
|
||||
|
||||
return Optional.OfNullable(definition);
|
||||
}
|
||||
|
||||
public Optional<BoundStructDefinitionNode> LookupStruct(string @namespace, string name)
|
||||
{
|
||||
var definition = _syntaxTrees
|
||||
.Where(c => c.Namespace == @namespace)
|
||||
.SelectMany(c => c.Definitions)
|
||||
.OfType<BoundStructDefinitionNode>()
|
||||
.SingleOrDefault(f => f.Name == name);
|
||||
|
||||
return Optional.OfNullable(definition);
|
||||
}
|
||||
|
||||
public Optional<BoundTraitDefinitionNode> LookupTrait(string @namespace, string name)
|
||||
{
|
||||
var definition = _syntaxTrees
|
||||
.Where(c => c.Namespace == @namespace)
|
||||
.SelectMany(c => c.Definitions)
|
||||
.OfType<BoundTraitDefinitionNode>()
|
||||
.SingleOrDefault(f => f.Name == name);
|
||||
|
||||
return Optional.OfNullable(definition);
|
||||
}
|
||||
|
||||
public Optional<Tuple<BoundTraitImplementationDefinitionNode, BoundImplementationFuncNode>> LookupTraitImplementationForType(NubType type, string funcName)
|
||||
{
|
||||
var implementations = _syntaxTrees
|
||||
.SelectMany(c => c.Definitions)
|
||||
.OfType<BoundTraitImplementationDefinitionNode>()
|
||||
.Where(c => c.ForType == type);
|
||||
|
||||
var implementation = implementations.SingleOrDefault(c => c.Functions.Any(x => x.Name == funcName));
|
||||
|
||||
var value = implementation == null ? null : new Tuple<BoundTraitImplementationDefinitionNode, BoundImplementationFuncNode>(implementation, implementation.Functions.First(x => x.Name == funcName));
|
||||
|
||||
return Optional.OfNullable(value);
|
||||
}
|
||||
|
||||
public Optional<BountTraitFunc> LookupFunctionOnTrait(string @namespace, string name, string funcName)
|
||||
{
|
||||
var traitDef = LookupTrait(@namespace, name);
|
||||
if (traitDef.HasValue)
|
||||
{
|
||||
var function = traitDef.Value.Functions.SingleOrDefault(x => x.Name == funcName);
|
||||
return Optional.OfNullable(function);
|
||||
}
|
||||
|
||||
return Optional<BountTraitFunc>.Empty();
|
||||
}
|
||||
|
||||
public IEnumerable<BoundStructDefinitionNode> GetStructs()
|
||||
{
|
||||
return _syntaxTrees
|
||||
.SelectMany(c => c.Definitions)
|
||||
.OfType<BoundStructDefinitionNode>();
|
||||
}
|
||||
|
||||
public IEnumerable<BoundTraitDefinitionNode> GetTraits()
|
||||
{
|
||||
return _syntaxTrees
|
||||
.SelectMany(c => c.Definitions)
|
||||
.OfType<BoundTraitDefinitionNode>();
|
||||
_topLevelNodes = syntaxTrees.SelectMany(x => x.TopLevelNodes).ToList();
|
||||
}
|
||||
}
|
||||
@@ -3,34 +3,34 @@ using Syntax.Tokenization;
|
||||
|
||||
namespace Syntax.Node;
|
||||
|
||||
public abstract record DefinitionNode(IEnumerable<Token> Tokens, string Namespace) : Node(Tokens);
|
||||
public abstract record BoundDefinitionNode(IEnumerable<Token> Tokens, string Namespace) : BoundNode(Tokens);
|
||||
|
||||
public record FuncParameter(string Name, NubType Type);
|
||||
|
||||
public abstract record FuncDefinition(IEnumerable<Token> Tokens, string Namespace, string Name, List<FuncParameter> Parameters, NubType ReturnType) : DefinitionNode(Tokens, Namespace);
|
||||
public abstract record BoundFuncDefinition(IEnumerable<Token> Tokens, string Namespace, string Name, List<FuncParameter> Parameters, NubType ReturnType) : BoundDefinitionNode(Tokens, Namespace);
|
||||
public abstract record TopLevelNode(IEnumerable<Token> Tokens, string Namespace) : Node(Tokens);
|
||||
public abstract record BoundTopLevelNode(IEnumerable<Token> Tokens, string Namespace) : BoundNode(Tokens);
|
||||
|
||||
public record LocalFuncDefinitionNode(IEnumerable<Token> Tokens, string Namespace, string Name, List<FuncParameter> Parameters, BlockNode Body, NubType ReturnType, bool Exported) : FuncDefinition(Tokens, Namespace, Name, Parameters, ReturnType);
|
||||
public record BoundLocalFuncDefinitionNode(IEnumerable<Token> Tokens, string Namespace, string Name, List<FuncParameter> Parameters, BoundBlock Body, NubType ReturnType, bool Exported) : BoundFuncDefinition(Tokens, Namespace, Name, Parameters, ReturnType);
|
||||
public abstract record DefinitionNode(IEnumerable<Token> Tokens) : Node(Tokens);
|
||||
public abstract record BoundDefinitionNode(IEnumerable<Token> Tokens) : BoundNode(Tokens);
|
||||
|
||||
public record ExternFuncDefinitionNode(IEnumerable<Token> Tokens, string Namespace, string Name, string CallName, List<FuncParameter> Parameters, NubType ReturnType) : FuncDefinition(Tokens, Namespace, Name, Parameters, ReturnType);
|
||||
public record BoundExternFuncDefinitionNode(IEnumerable<Token> Tokens, string Namespace, string Name, string CallName, List<FuncParameter> Parameters, NubType ReturnType) : BoundFuncDefinition(Tokens, Namespace, Name, Parameters, ReturnType);
|
||||
public record LocalFuncNode(IEnumerable<Token> Tokens, string Namespace, string Name, List<FuncParameter> Parameters, BlockNode Body, NubType ReturnType, bool Exported) : TopLevelNode(Tokens, Namespace);
|
||||
public record BoundLocalFuncNode(IEnumerable<Token> Tokens, string Namespace, string Name, List<FuncParameter> Parameters, BoundBlock Body, NubType ReturnType, bool Exported) : BoundTopLevelNode(Tokens, Namespace);
|
||||
|
||||
public record StructField(string Name, NubType Type, Optional<ExpressionNode> Value);
|
||||
public record BoundStructField(string Name, NubType Type, Optional<BoundExpressionNode> Value);
|
||||
public record ExternFuncNode(IEnumerable<Token> Tokens, string Namespace, string Name, string CallName, List<FuncParameter> Parameters, NubType ReturnType) : TopLevelNode(Tokens, Namespace);
|
||||
public record BoundExternFuncNode(IEnumerable<Token> Tokens, string Namespace, string Name, string CallName, List<FuncParameter> Parameters, NubType ReturnType) : BoundTopLevelNode(Tokens, Namespace);
|
||||
|
||||
public record StructDefinitionNode(IEnumerable<Token> Tokens, string Namespace, string Name, List<StructField> Fields) : DefinitionNode(Tokens, Namespace);
|
||||
public record BoundStructDefinitionNode(IEnumerable<Token> Tokens, string Namespace, string Name, List<BoundStructField> Fields) : BoundDefinitionNode(Tokens, Namespace);
|
||||
public record StructFieldNode(IEnumerable<Token> Tokens, string Name, NubType Type, Optional<ExpressionNode> Value) : DefinitionNode(Tokens);
|
||||
public record StructNode(IEnumerable<Token> Tokens, string Namespace, string Name, List<StructFieldNode> Fields) : TopLevelNode(Tokens, Namespace);
|
||||
|
||||
public record TraitFunc(string Name, List<FuncParameter> Parameters, NubType ReturnType);
|
||||
public record BountTraitFunc(string Name, List<FuncParameter> Parameters, NubType ReturnType);
|
||||
public record BoundStructFieldNode(IEnumerable<Token> Tokens, string Name, NubType Type, Optional<BoundExpressionNode> Value) : BoundDefinitionNode(Tokens);
|
||||
public record BoundStructNode(IEnumerable<Token> Tokens, string Namespace, string Name, List<BoundStructFieldNode> Fields) : BoundTopLevelNode(Tokens, Namespace);
|
||||
|
||||
public record TraitDefinitionNode(IEnumerable<Token> Tokens, string Namespace, string Name, List<TraitFunc> Functions) : DefinitionNode(Tokens, Namespace);
|
||||
public record BoundTraitDefinitionNode(IEnumerable<Token> Tokens, string Namespace, string Name, List<BountTraitFunc> Functions) : BoundDefinitionNode(Tokens, Namespace);
|
||||
public record TraitFuncNode(IEnumerable<Token> Tokens, string Name, List<FuncParameter> Parameters, NubType ReturnType) : DefinitionNode(Tokens);
|
||||
public record TraitNode(IEnumerable<Token> Tokens, string Namespace, string Name, List<TraitFuncNode> Functions) : TopLevelNode(Tokens, Namespace);
|
||||
|
||||
public record ImplementationFuncNode(IEnumerable<Token> Tokens, string Name, List<FuncParameter> Parameters, NubType ReturnType, BlockNode Body) : BoundNode(Tokens);
|
||||
public record BoundImplementationFuncNode(IEnumerable<Token> Tokens, string Name, List<FuncParameter> Parameters, NubType ReturnType, BoundBlock Body) : BoundNode(Tokens);
|
||||
public record BoundTraitFuncNode(IEnumerable<Token> Tokens, string Name, List<FuncParameter> Parameters, NubType ReturnType) : BoundDefinitionNode(Tokens);
|
||||
public record BoundTraitNode(IEnumerable<Token> Tokens, string Namespace, string Name, List<BoundTraitFuncNode> Functions) : BoundTopLevelNode(Tokens, Namespace);
|
||||
|
||||
public record BoundTraitImplementationDefinitionNode(IEnumerable<Token> Tokens, string Namespace, NubType TraitType, NubType ForType, List<BoundImplementationFuncNode> Functions) : BoundDefinitionNode(Tokens, Namespace);
|
||||
public record TraitImplementationDefinitionNode(IEnumerable<Token> Tokens, string Namespace, NubType TraitType, NubType ForType, List<ImplementationFuncNode> Functions) : DefinitionNode(Tokens, Namespace);
|
||||
public record TraitFuncImplNode(IEnumerable<Token> Tokens, string Name, List<FuncParameter> Parameters, NubType ReturnType, BlockNode Body) : DefinitionNode(Tokens);
|
||||
public record TraitImplNode(IEnumerable<Token> Tokens, string Namespace, NubType TraitType, NubType ForType, List<TraitFuncImplNode> Functions) : TopLevelNode(Tokens, Namespace);
|
||||
|
||||
public record BoundTraitFuncImplNode(IEnumerable<Token> Tokens, string Name, List<FuncParameter> Parameters, NubType ReturnType, BoundBlock Body) : BoundDefinitionNode(Tokens);
|
||||
public record BoundTraitImplNode(IEnumerable<Token> Tokens, string Namespace, NubType TraitType, NubType ForType, List<BoundTraitFuncImplNode> Functions) : BoundTopLevelNode(Tokens, Namespace);
|
||||
@@ -6,5 +6,4 @@ public abstract record Node(IEnumerable<Token> Tokens);
|
||||
public abstract record BoundNode(IEnumerable<Token> Tokens);
|
||||
|
||||
public record BlockNode(IEnumerable<Token> Tokens, List<StatementNode> Statements) : Node(Tokens);
|
||||
|
||||
public record BoundBlock(IEnumerable<Token> Tokens, List<BoundStatementNode> Statements);
|
||||
public record BoundBlock(IEnumerable<Token> Tokens, List<BoundStatementNode> Statements) : BoundNode(Tokens);
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace Syntax.Node;
|
||||
|
||||
public record SyntaxTree(string Namespace, List<DefinitionNode> Definitions);
|
||||
public record BoundSyntaxTree(string Namespace, List<BoundDefinitionNode> Definitions);
|
||||
public record SyntaxTree(string Namespace, List<TopLevelNode> TopLevelNodes);
|
||||
public record BoundSyntaxTree(string Namespace, List<BoundTopLevelNode> TopLevelNodes);
|
||||
|
||||
@@ -29,7 +29,7 @@ public static class Parser
|
||||
|
||||
try
|
||||
{
|
||||
List<DefinitionNode> definitions = [];
|
||||
List<TopLevelNode> definitions = [];
|
||||
|
||||
while (Peek().HasValue)
|
||||
{
|
||||
@@ -50,7 +50,7 @@ public static class Parser
|
||||
return null;
|
||||
}
|
||||
|
||||
private static DefinitionNode ParseDefinition()
|
||||
private static TopLevelNode ParseDefinition()
|
||||
{
|
||||
var startIndex = _index;
|
||||
List<ModifierToken> modifiers = [];
|
||||
@@ -61,21 +61,32 @@ public static class Parser
|
||||
}
|
||||
|
||||
var keyword = ExpectSymbol();
|
||||
return keyword.Symbol switch
|
||||
var node = keyword.Symbol switch
|
||||
{
|
||||
Symbol.Func => ParseFuncDefinition(startIndex, modifiers),
|
||||
Symbol.Struct => ParseStruct(startIndex, modifiers),
|
||||
Symbol.Trait => ParseTrait(startIndex, modifiers),
|
||||
Symbol.Impl => ParseImplementation(startIndex, modifiers),
|
||||
Symbol.Func => ParseFunc(startIndex, modifiers),
|
||||
Symbol.Struct => ParseStruct(startIndex),
|
||||
Symbol.Trait => ParseTrait(startIndex),
|
||||
Symbol.Impl => ParseImplementation(startIndex),
|
||||
_ => throw new ParseException(Diagnostic
|
||||
.Error($"Expected 'func' or 'struct', but found '{keyword.Symbol}'")
|
||||
.WithHelp("Valid definition keywords are 'func' and 'struct'")
|
||||
.At(keyword)
|
||||
.Build())
|
||||
};
|
||||
|
||||
if (modifiers.Count != 0)
|
||||
{
|
||||
throw new ParseException(Diagnostic
|
||||
.Error($"Invalid modifiers: {string.Join(", ", modifiers.Select(x => x.Modifier))}")
|
||||
.WithHelp($"Remove the following modifiers: {modifiers.Select(x => x.Modifier)}'")
|
||||
.At(SourceSpan.Merge(modifiers.Select(x => x.Span)))
|
||||
.Build());
|
||||
}
|
||||
|
||||
private static DefinitionNode ParseFuncDefinition(int startIndex, List<ModifierToken> modifiers)
|
||||
return node;
|
||||
}
|
||||
|
||||
private static TopLevelNode ParseFunc(int startIndex, List<ModifierToken> modifiers)
|
||||
{
|
||||
var name = ExpectIdentifier();
|
||||
List<FuncParameter> parameters = [];
|
||||
@@ -118,34 +129,27 @@ public static class Parser
|
||||
callName = ExpectIdentifier().Value;
|
||||
}
|
||||
|
||||
return new ExternFuncDefinitionNode(GetTokensForNode(startIndex), _namespace, name.Value, callName, parameters, returnType);
|
||||
return new ExternFuncNode(GetTokensForNode(startIndex), _namespace, name.Value, callName, parameters, returnType);
|
||||
}
|
||||
|
||||
var body = ParseBlock();
|
||||
var exported = modifiers.RemoveAll(x => x.Modifier == Modifier.Export) > 0;
|
||||
|
||||
if (modifiers.Count != 0)
|
||||
{
|
||||
throw new ParseException(Diagnostic
|
||||
.Error($"Invalid modifiers for function: {modifiers[0].Modifier}")
|
||||
.WithHelp($"Functions cannot use the '{modifiers[0].Modifier}' modifier")
|
||||
.At(modifiers[0])
|
||||
.Build());
|
||||
return new LocalFuncNode(GetTokensForNode(startIndex), _namespace, name.Value, parameters, body, returnType, exported);
|
||||
}
|
||||
|
||||
return new LocalFuncDefinitionNode(GetTokensForNode(startIndex), _namespace, name.Value, parameters, body, returnType, exported);
|
||||
}
|
||||
|
||||
private static StructDefinitionNode ParseStruct(int startIndex, List<ModifierToken> modifiers)
|
||||
private static StructNode ParseStruct(int startIndex)
|
||||
{
|
||||
var name = ExpectIdentifier().Value;
|
||||
|
||||
ExpectSymbol(Symbol.OpenBrace);
|
||||
|
||||
List<StructField> variables = [];
|
||||
List<StructFieldNode> variables = [];
|
||||
|
||||
while (!TryExpectSymbol(Symbol.CloseBrace))
|
||||
{
|
||||
var fieldStartIndex = _index;
|
||||
|
||||
var variableName = ExpectIdentifier().Value;
|
||||
ExpectSymbol(Symbol.Colon);
|
||||
var variableType = ParseType();
|
||||
@@ -157,31 +161,24 @@ public static class Parser
|
||||
variableValue = ParseExpression();
|
||||
}
|
||||
|
||||
variables.Add(new StructField(variableName, variableType, variableValue));
|
||||
variables.Add(new StructFieldNode(GetTokensForNode(fieldStartIndex), variableName, variableType, variableValue));
|
||||
}
|
||||
|
||||
if (modifiers.Count != 0)
|
||||
{
|
||||
throw new ParseException(Diagnostic
|
||||
.Error($"Invalid modifiers for struct: {modifiers[0].Modifier}")
|
||||
.WithHelp($"Structs cannot use the '{modifiers[0].Modifier}' modifier")
|
||||
.At(modifiers[0])
|
||||
.Build());
|
||||
return new StructNode(GetTokensForNode(startIndex), _namespace, name, variables);
|
||||
}
|
||||
|
||||
return new StructDefinitionNode(GetTokensForNode(startIndex), _namespace, name, variables);
|
||||
}
|
||||
|
||||
private static TraitDefinitionNode ParseTrait(int startIndex, List<ModifierToken> modifiers)
|
||||
private static TraitNode ParseTrait(int startIndex)
|
||||
{
|
||||
var name = ExpectIdentifier().Value;
|
||||
|
||||
ExpectSymbol(Symbol.OpenBrace);
|
||||
|
||||
List<TraitFunc> functions = [];
|
||||
List<TraitFuncNode> functions = [];
|
||||
|
||||
while (!TryExpectSymbol(Symbol.CloseBrace))
|
||||
{
|
||||
var funcStartIndex = _index;
|
||||
|
||||
ExpectSymbol(Symbol.Func);
|
||||
|
||||
var funcName = ExpectIdentifier().Value;
|
||||
@@ -204,28 +201,19 @@ public static class Parser
|
||||
|
||||
var returnType = TryExpectSymbol(Symbol.Colon) ? ParseType() : new NubVoidType();
|
||||
|
||||
if (modifiers.Count != 0)
|
||||
{
|
||||
throw new ParseException(Diagnostic
|
||||
.Error($"Invalid modifiers for trait: {modifiers[0].Modifier}")
|
||||
.WithHelp($"Traits cannot use the '{modifiers[0].Modifier}' modifier")
|
||||
.At(modifiers[0])
|
||||
.Build());
|
||||
functions.Add(new TraitFuncNode(GetTokensForNode(funcStartIndex), funcName, parameters, returnType));
|
||||
}
|
||||
|
||||
functions.Add(new TraitFunc(funcName, parameters, returnType));
|
||||
return new TraitNode(GetTokensForNode(startIndex), _namespace, name, functions);
|
||||
}
|
||||
|
||||
return new TraitDefinitionNode(GetTokensForNode(startIndex), _namespace, name, functions);
|
||||
}
|
||||
|
||||
private static TraitImplementationDefinitionNode ParseImplementation(int startIndex, List<ModifierToken> modifiers)
|
||||
private static TraitImplNode ParseImplementation(int startIndex)
|
||||
{
|
||||
var traitType = ParseType();
|
||||
ExpectSymbol(Symbol.For);
|
||||
var forType = ParseType();
|
||||
|
||||
List<ImplementationFuncNode> functions = [];
|
||||
List<TraitFuncImplNode> functions = [];
|
||||
|
||||
ExpectSymbol(Symbol.OpenBrace);
|
||||
while (!TryExpectSymbol(Symbol.CloseBrace))
|
||||
@@ -258,19 +246,10 @@ public static class Parser
|
||||
|
||||
var body = ParseBlock();
|
||||
|
||||
functions.AddRange(new ImplementationFuncNode(GetTokensForNode(funcStartIndex), functionName, parameters, returnType, body));
|
||||
functions.AddRange(new TraitFuncImplNode(GetTokensForNode(funcStartIndex), functionName, parameters, returnType, body));
|
||||
}
|
||||
|
||||
if (modifiers.Count != 0)
|
||||
{
|
||||
throw new ParseException(Diagnostic
|
||||
.Error($"Invalid modifiers for implementation: {modifiers[0].Modifier}")
|
||||
.WithHelp($"Implementations cannot use the '{modifiers[0].Modifier}' modifier")
|
||||
.At(modifiers[0])
|
||||
.Build());
|
||||
}
|
||||
|
||||
return new TraitImplementationDefinitionNode(GetTokensForNode(startIndex), _namespace, traitType, forType, functions);
|
||||
return new TraitImplNode(GetTokensForNode(startIndex), _namespace, traitType, forType, functions);
|
||||
}
|
||||
|
||||
private static FuncParameter ParseFuncParameter()
|
||||
|
||||
Reference in New Issue
Block a user