diff --git a/src/compiler/Generation/QBE/QBEGenerator.cs b/src/compiler/Generation/QBE/QBEGenerator.cs index b6f7363..3604451 100644 --- a/src/compiler/Generation/QBE/QBEGenerator.cs +++ b/src/compiler/Generation/QBE/QBEGenerator.cs @@ -19,7 +19,7 @@ public static class QBEGenerator private static Stack _breakLabels = []; private static Stack _continueLabels = []; private static Queue<(BoundAnonymousFuncNode Func, string Name)> _anonymousFunctions = []; - private static Dictionary _implFunctions = []; + private static Dictionary _implFunctions = []; private static Stack _variables = []; private static Stack _variableScopes = []; private static int _tmpIndex; @@ -65,7 +65,7 @@ public static class QBEGenerator _writer.NewLine(); } - foreach (var funcDef in _syntaxTree.Definitions.OfType()) + foreach (var funcDef in _syntaxTree.TopLevelNodes.OfType()) { 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))} = {{"); diff --git a/src/compiler/Syntax/Binding/Binder.cs b/src/compiler/Syntax/Binding/Binder.cs index 4d83b2e..636968d 100644 --- a/src/compiler/Syntax/Binding/Binder.cs +++ b/src/compiler/Syntax/Binding/Binder.cs @@ -23,34 +23,34 @@ public static class Binder _variables = []; _funcReturnType = null; - var definitions = new List(); + var definitions = new List(); - 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(); + var functions = new List(); 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(); + var functions = new List(); 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(); + var structFields = new List(); 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) diff --git a/src/compiler/Syntax/DefinitionTable.cs b/src/compiler/Syntax/DefinitionTable.cs index b5dfeca..ca84082 100644 --- a/src/compiler/Syntax/DefinitionTable.cs +++ b/src/compiler/Syntax/DefinitionTable.cs @@ -1,158 +1,23 @@ -using Common; -using Syntax.Binding; using Syntax.Node; -using Syntax.Parsing; namespace Syntax; public class DefinitionTable { - private readonly IEnumerable _syntaxTrees; + private readonly List _topLevelNodes; public DefinitionTable(IEnumerable syntaxTrees) { - _syntaxTrees = syntaxTrees; - } - - public Optional LookupFunction(string @namespace, string name) - { - var definition = _syntaxTrees - .Where(c => c.Namespace == @namespace) - .SelectMany(c => c.Definitions) - .OfType() - .SingleOrDefault(f => f.Name == name); - - return Optional.OfNullable(definition); - } - - public Optional LookupStruct(string @namespace, string name) - { - var definition = _syntaxTrees - .Where(c => c.Namespace == @namespace) - .SelectMany(c => c.Definitions) - .OfType() - .SingleOrDefault(f => f.Name == name); - - return Optional.OfNullable(definition); - } - - public Optional LookupTrait(string @namespace, string name) - { - var definition = _syntaxTrees - .Where(c => c.Namespace == @namespace) - .SelectMany(c => c.Definitions) - .OfType() - .SingleOrDefault(f => f.Name == name); - - return Optional.OfNullable(definition); - } - - public Optional> LookupTraitImplementationForType(NubType type, string funcName) - { - var implementations = _syntaxTrees - .SelectMany(c => c.Definitions) - .OfType() - .Where(c => c.ForType == type); - - var implementation = implementations.SingleOrDefault(c => c.Functions.Any(x => x.Name == funcName)); - - var value = implementation == null ? null : new Tuple(implementation, implementation.Functions.First(x => x.Name == funcName)); - - return Optional.OfNullable(value); - } - - public Optional 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.Empty(); + _topLevelNodes = syntaxTrees.SelectMany(x => x.TopLevelNodes).ToList(); } } public class BoundDefinitionTable { - private readonly IEnumerable _syntaxTrees; + private readonly List _topLevelNodes; public BoundDefinitionTable(IEnumerable syntaxTrees) { - _syntaxTrees = syntaxTrees; - } - - public Optional LookupFunc(string @namespace, string name) - { - var definition = _syntaxTrees - .Where(c => c.Namespace == @namespace) - .SelectMany(c => c.Definitions) - .OfType() - .SingleOrDefault(f => f.Name == name); - - return Optional.OfNullable(definition); - } - - public Optional LookupStruct(string @namespace, string name) - { - var definition = _syntaxTrees - .Where(c => c.Namespace == @namespace) - .SelectMany(c => c.Definitions) - .OfType() - .SingleOrDefault(f => f.Name == name); - - return Optional.OfNullable(definition); - } - - public Optional LookupTrait(string @namespace, string name) - { - var definition = _syntaxTrees - .Where(c => c.Namespace == @namespace) - .SelectMany(c => c.Definitions) - .OfType() - .SingleOrDefault(f => f.Name == name); - - return Optional.OfNullable(definition); - } - - public Optional> LookupTraitImplementationForType(NubType type, string funcName) - { - var implementations = _syntaxTrees - .SelectMany(c => c.Definitions) - .OfType() - .Where(c => c.ForType == type); - - var implementation = implementations.SingleOrDefault(c => c.Functions.Any(x => x.Name == funcName)); - - var value = implementation == null ? null : new Tuple(implementation, implementation.Functions.First(x => x.Name == funcName)); - - return Optional.OfNullable(value); - } - - public Optional 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.Empty(); - } - - public IEnumerable GetStructs() - { - return _syntaxTrees - .SelectMany(c => c.Definitions) - .OfType(); - } - - public IEnumerable GetTraits() - { - return _syntaxTrees - .SelectMany(c => c.Definitions) - .OfType(); + _topLevelNodes = syntaxTrees.SelectMany(x => x.TopLevelNodes).ToList(); } } \ No newline at end of file diff --git a/src/compiler/Syntax/Node/Definition.cs b/src/compiler/Syntax/Node/Definition.cs index bb82f5d..19c3e1e 100644 --- a/src/compiler/Syntax/Node/Definition.cs +++ b/src/compiler/Syntax/Node/Definition.cs @@ -3,34 +3,34 @@ using Syntax.Tokenization; namespace Syntax.Node; -public abstract record DefinitionNode(IEnumerable Tokens, string Namespace) : Node(Tokens); -public abstract record BoundDefinitionNode(IEnumerable Tokens, string Namespace) : BoundNode(Tokens); - public record FuncParameter(string Name, NubType Type); -public abstract record FuncDefinition(IEnumerable Tokens, string Namespace, string Name, List Parameters, NubType ReturnType) : DefinitionNode(Tokens, Namespace); -public abstract record BoundFuncDefinition(IEnumerable Tokens, string Namespace, string Name, List Parameters, NubType ReturnType) : BoundDefinitionNode(Tokens, Namespace); +public abstract record TopLevelNode(IEnumerable Tokens, string Namespace) : Node(Tokens); +public abstract record BoundTopLevelNode(IEnumerable Tokens, string Namespace) : BoundNode(Tokens); -public record LocalFuncDefinitionNode(IEnumerable Tokens, string Namespace, string Name, List Parameters, BlockNode Body, NubType ReturnType, bool Exported) : FuncDefinition(Tokens, Namespace, Name, Parameters, ReturnType); -public record BoundLocalFuncDefinitionNode(IEnumerable Tokens, string Namespace, string Name, List Parameters, BoundBlock Body, NubType ReturnType, bool Exported) : BoundFuncDefinition(Tokens, Namespace, Name, Parameters, ReturnType); +public abstract record DefinitionNode(IEnumerable Tokens) : Node(Tokens); +public abstract record BoundDefinitionNode(IEnumerable Tokens) : BoundNode(Tokens); -public record ExternFuncDefinitionNode(IEnumerable Tokens, string Namespace, string Name, string CallName, List Parameters, NubType ReturnType) : FuncDefinition(Tokens, Namespace, Name, Parameters, ReturnType); -public record BoundExternFuncDefinitionNode(IEnumerable Tokens, string Namespace, string Name, string CallName, List Parameters, NubType ReturnType) : BoundFuncDefinition(Tokens, Namespace, Name, Parameters, ReturnType); +public record LocalFuncNode(IEnumerable Tokens, string Namespace, string Name, List Parameters, BlockNode Body, NubType ReturnType, bool Exported) : TopLevelNode(Tokens, Namespace); +public record BoundLocalFuncNode(IEnumerable Tokens, string Namespace, string Name, List Parameters, BoundBlock Body, NubType ReturnType, bool Exported) : BoundTopLevelNode(Tokens, Namespace); -public record StructField(string Name, NubType Type, Optional Value); -public record BoundStructField(string Name, NubType Type, Optional Value); +public record ExternFuncNode(IEnumerable Tokens, string Namespace, string Name, string CallName, List Parameters, NubType ReturnType) : TopLevelNode(Tokens, Namespace); +public record BoundExternFuncNode(IEnumerable Tokens, string Namespace, string Name, string CallName, List Parameters, NubType ReturnType) : BoundTopLevelNode(Tokens, Namespace); -public record StructDefinitionNode(IEnumerable Tokens, string Namespace, string Name, List Fields) : DefinitionNode(Tokens, Namespace); -public record BoundStructDefinitionNode(IEnumerable Tokens, string Namespace, string Name, List Fields) : BoundDefinitionNode(Tokens, Namespace); +public record StructFieldNode(IEnumerable Tokens, string Name, NubType Type, Optional Value) : DefinitionNode(Tokens); +public record StructNode(IEnumerable Tokens, string Namespace, string Name, List Fields) : TopLevelNode(Tokens, Namespace); -public record TraitFunc(string Name, List Parameters, NubType ReturnType); -public record BountTraitFunc(string Name, List Parameters, NubType ReturnType); +public record BoundStructFieldNode(IEnumerable Tokens, string Name, NubType Type, Optional Value) : BoundDefinitionNode(Tokens); +public record BoundStructNode(IEnumerable Tokens, string Namespace, string Name, List Fields) : BoundTopLevelNode(Tokens, Namespace); -public record TraitDefinitionNode(IEnumerable Tokens, string Namespace, string Name, List Functions) : DefinitionNode(Tokens, Namespace); -public record BoundTraitDefinitionNode(IEnumerable Tokens, string Namespace, string Name, List Functions) : BoundDefinitionNode(Tokens, Namespace); +public record TraitFuncNode(IEnumerable Tokens, string Name, List Parameters, NubType ReturnType) : DefinitionNode(Tokens); +public record TraitNode(IEnumerable Tokens, string Namespace, string Name, List Functions) : TopLevelNode(Tokens, Namespace); -public record ImplementationFuncNode(IEnumerable Tokens, string Name, List Parameters, NubType ReturnType, BlockNode Body) : BoundNode(Tokens); -public record BoundImplementationFuncNode(IEnumerable Tokens, string Name, List Parameters, NubType ReturnType, BoundBlock Body) : BoundNode(Tokens); +public record BoundTraitFuncNode(IEnumerable Tokens, string Name, List Parameters, NubType ReturnType) : BoundDefinitionNode(Tokens); +public record BoundTraitNode(IEnumerable Tokens, string Namespace, string Name, List Functions) : BoundTopLevelNode(Tokens, Namespace); -public record BoundTraitImplementationDefinitionNode(IEnumerable Tokens, string Namespace, NubType TraitType, NubType ForType, List Functions) : BoundDefinitionNode(Tokens, Namespace); -public record TraitImplementationDefinitionNode(IEnumerable Tokens, string Namespace, NubType TraitType, NubType ForType, List Functions) : DefinitionNode(Tokens, Namespace); \ No newline at end of file +public record TraitFuncImplNode(IEnumerable Tokens, string Name, List Parameters, NubType ReturnType, BlockNode Body) : DefinitionNode(Tokens); +public record TraitImplNode(IEnumerable Tokens, string Namespace, NubType TraitType, NubType ForType, List Functions) : TopLevelNode(Tokens, Namespace); + +public record BoundTraitFuncImplNode(IEnumerable Tokens, string Name, List Parameters, NubType ReturnType, BoundBlock Body) : BoundDefinitionNode(Tokens); +public record BoundTraitImplNode(IEnumerable Tokens, string Namespace, NubType TraitType, NubType ForType, List Functions) : BoundTopLevelNode(Tokens, Namespace); \ No newline at end of file diff --git a/src/compiler/Syntax/Node/Node.cs b/src/compiler/Syntax/Node/Node.cs index 14b11fd..1076dce 100644 --- a/src/compiler/Syntax/Node/Node.cs +++ b/src/compiler/Syntax/Node/Node.cs @@ -6,5 +6,4 @@ public abstract record Node(IEnumerable Tokens); public abstract record BoundNode(IEnumerable Tokens); public record BlockNode(IEnumerable Tokens, List Statements) : Node(Tokens); - -public record BoundBlock(IEnumerable Tokens, List Statements); \ No newline at end of file +public record BoundBlock(IEnumerable Tokens, List Statements) : BoundNode(Tokens); \ No newline at end of file diff --git a/src/compiler/Syntax/Node/SyntaxTree.cs b/src/compiler/Syntax/Node/SyntaxTree.cs index 53c312c..d965c6c 100644 --- a/src/compiler/Syntax/Node/SyntaxTree.cs +++ b/src/compiler/Syntax/Node/SyntaxTree.cs @@ -1,4 +1,4 @@ namespace Syntax.Node; -public record SyntaxTree(string Namespace, List Definitions); -public record BoundSyntaxTree(string Namespace, List Definitions); +public record SyntaxTree(string Namespace, List TopLevelNodes); +public record BoundSyntaxTree(string Namespace, List TopLevelNodes); diff --git a/src/compiler/Syntax/Parsing/Parser.cs b/src/compiler/Syntax/Parsing/Parser.cs index 69d4b21..07906c4 100644 --- a/src/compiler/Syntax/Parsing/Parser.cs +++ b/src/compiler/Syntax/Parsing/Parser.cs @@ -29,7 +29,7 @@ public static class Parser try { - List definitions = []; + List 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 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()); + } + + return node; } - private static DefinitionNode ParseFuncDefinition(int startIndex, List modifiers) + private static TopLevelNode ParseFunc(int startIndex, List modifiers) { var name = ExpectIdentifier(); List 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 LocalFuncDefinitionNode(GetTokensForNode(startIndex), _namespace, name.Value, parameters, body, returnType, exported); + return new LocalFuncNode(GetTokensForNode(startIndex), _namespace, name.Value, parameters, body, returnType, exported); } - private static StructDefinitionNode ParseStruct(int startIndex, List modifiers) + private static StructNode ParseStruct(int startIndex) { var name = ExpectIdentifier().Value; ExpectSymbol(Symbol.OpenBrace); - List variables = []; + List 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 StructDefinitionNode(GetTokensForNode(startIndex), _namespace, name, variables); + return new StructNode(GetTokensForNode(startIndex), _namespace, name, variables); } - private static TraitDefinitionNode ParseTrait(int startIndex, List modifiers) + private static TraitNode ParseTrait(int startIndex) { var name = ExpectIdentifier().Value; ExpectSymbol(Symbol.OpenBrace); - List functions = []; + List 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 TraitFunc(funcName, parameters, returnType)); + functions.Add(new TraitFuncNode(GetTokensForNode(funcStartIndex), 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 modifiers) + private static TraitImplNode ParseImplementation(int startIndex) { var traitType = ParseType(); ExpectSymbol(Symbol.For); var forType = ParseType(); - List functions = []; + List 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()