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