This commit is contained in:
nub31
2025-07-05 16:25:45 +02:00
parent 5c7e12feeb
commit 5246e54ac9
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> _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))} = {{");

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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());
} }
private static DefinitionNode ParseFuncDefinition(int startIndex, List<ModifierToken> modifiers) return node;
}
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 StructNode ParseStruct(int startIndex)
}
private static StructDefinitionNode ParseStruct(int startIndex, List<ModifierToken> modifiers)
{ {
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 TraitNode ParseTrait(int startIndex)
}
private static TraitDefinitionNode ParseTrait(int startIndex, List<ModifierToken> modifiers)
{ {
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 TraitNode(GetTokensForNode(startIndex), _namespace, name, functions);
} }
return new TraitDefinitionNode(GetTokensForNode(startIndex), _namespace, name, functions); private static TraitImplNode ParseImplementation(int startIndex)
}
private static TraitImplementationDefinitionNode ParseImplementation(int startIndex, List<ModifierToken> modifiers)
{ {
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()