This commit is contained in:
nub31
2025-07-05 16:25:45 +02:00
parent d9308dfb94
commit 9a4f018fff
7 changed files with 99 additions and 256 deletions

View File

@@ -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))} = {{");

View File

@@ -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)

View File

@@ -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();
}
}

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);

View File

@@ -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()