This commit is contained in:
nub31
2026-02-09 19:34:47 +01:00
parent 9fb9c50a0b
commit 96670b1201
7 changed files with 335 additions and 262 deletions

View File

@@ -13,26 +13,14 @@ public sealed class Parser(string fileName, List<Token> tokens)
private Ast Parse(out List<Diagnostic> diagnostics)
{
var functionDefinitions = new List<NodeDefinitionFunc>();
var structDefinitions = new List<NodeDefinitionStruct>();
var definitions = new List<NodeDefinition>();
diagnostics = [];
try
{
while (Peek() != null)
{
var definition = ParseDefinition();
switch (definition)
{
case NodeDefinitionFunc def:
functionDefinitions.Add(def);
break;
case NodeDefinitionStruct def:
structDefinitions.Add(def);
break;
default:
throw new ArgumentOutOfRangeException(nameof(definition));
}
definitions.Add(ParseDefinition());
}
}
catch (CompileException e)
@@ -40,7 +28,7 @@ public sealed class Parser(string fileName, List<Token> tokens)
diagnostics.Add(e.Diagnostic);
}
return new Ast(structDefinitions, functionDefinitions);
return new Ast(definitions);
}
private NodeDefinition ParseDefinition()
@@ -88,6 +76,18 @@ public sealed class Parser(string fileName, List<Token> tokens)
return new NodeDefinitionStruct(TokensFrom(startIndex), name, fields);
}
if (TryExpectKeyword(Keyword.Module))
{
var name = ExpectIdent();
return new NodeDefinitionModule(TokensFrom(startIndex), name);
}
if (TryExpectKeyword(Keyword.Import))
{
var name = ExpectIdent();
return new NodeDefinitionImport(TokensFrom(startIndex), name);
}
throw new CompileException(Diagnostic.Error("Not a valid definition").At(fileName, Peek()).Build());
}
@@ -248,7 +248,10 @@ public sealed class Parser(string fileName, List<Token> tokens)
}
else if (TryExpectKeyword(Keyword.Struct))
{
var module = ExpectIdent();
ExpectSymbol(Symbol.ColonColon);
var name = ExpectIdent();
var initializers = new List<NodeExpressionStructLiteral.Initializer>();
ExpectSymbol(Symbol.OpenCurly);
@@ -261,7 +264,7 @@ public sealed class Parser(string fileName, List<Token> tokens)
initializers.Add(new NodeExpressionStructLiteral.Initializer(TokensFrom(initializerStartIndex), fieldName, fieldValue));
}
expr = new NodeExpressionStructLiteral(TokensFrom(startIndex), name, initializers);
expr = new NodeExpressionStructLiteral(TokensFrom(startIndex), module, name, initializers);
}
else
{
@@ -330,7 +333,9 @@ public sealed class Parser(string fileName, List<Token> tokens)
case "u64":
return new NodeTypeUInt(TokensFrom(startIndex), 64);
default:
return new NodeTypeCustom(TokensFrom(startIndex), ident);
ExpectSymbol(Symbol.ColonColon);
var name = ExpectIdent();
return new NodeTypeCustom(TokensFrom(startIndex), ident, name);
}
}
@@ -342,6 +347,17 @@ public sealed class Parser(string fileName, List<Token> tokens)
return tokens.GetRange(startIndex, index - startIndex);
}
private void ExpectKeyword(Keyword keyword)
{
if (Peek() is TokenKeyword token && token.Keyword == keyword)
{
Consume();
return;
}
throw new CompileException(Diagnostic.Error($"Expected '{keyword.AsString()}'").At(fileName, Peek()).Build());
}
private bool TryExpectKeyword(Keyword keyword)
{
if (Peek() is TokenKeyword token && token.Keyword == keyword)
@@ -516,10 +532,9 @@ public sealed class Parser(string fileName, List<Token> tokens)
}
}
public sealed class Ast(List<NodeDefinitionStruct> structs, List<NodeDefinitionFunc> functions)
public sealed class Ast(List<NodeDefinition> definitions)
{
public readonly List<NodeDefinitionStruct> Structs = structs;
public readonly List<NodeDefinitionFunc> Functions = functions;
public readonly List<NodeDefinition> Definitions = definitions;
}
public abstract class Node(List<Token> tokens)
@@ -529,6 +544,16 @@ public abstract class Node(List<Token> tokens)
public abstract class NodeDefinition(List<Token> tokens) : Node(tokens);
public sealed class NodeDefinitionModule(List<Token> tokens, TokenIdent name) : NodeDefinition(tokens)
{
public readonly TokenIdent Name = name;
}
public sealed class NodeDefinitionImport(List<Token> tokens, TokenIdent name) : NodeDefinition(tokens)
{
public readonly TokenIdent Name = name;
}
public sealed class NodeDefinitionFunc(List<Token> tokens, TokenIdent name, List<NodeDefinitionFunc.Param> parameters, NodeStatement body, NodeType returnType) : NodeDefinition(tokens)
{
public readonly TokenIdent Name = name;
@@ -616,8 +641,9 @@ public sealed class NodeExpressionBoolLiteral(List<Token> tokens, TokenBoolLiter
public readonly TokenBoolLiteral Value = value;
}
public sealed class NodeExpressionStructLiteral(List<Token> tokens, TokenIdent name, List<NodeExpressionStructLiteral.Initializer> initializers) : NodeExpression(tokens)
public sealed class NodeExpressionStructLiteral(List<Token> tokens, TokenIdent module, TokenIdent name, List<NodeExpressionStructLiteral.Initializer> initializers) : NodeExpression(tokens)
{
public readonly TokenIdent Module = module;
public readonly TokenIdent Name = name;
public readonly List<Initializer> Initializers = initializers;
@@ -702,8 +728,9 @@ public sealed class NodeTypeBool(List<Token> tokens) : NodeType(tokens);
public sealed class NodeTypeString(List<Token> tokens) : NodeType(tokens);
public sealed class NodeTypeCustom(List<Token> tokens, TokenIdent name) : NodeType(tokens)
public sealed class NodeTypeCustom(List<Token> tokens, TokenIdent module, TokenIdent name) : NodeType(tokens)
{
public readonly TokenIdent Module = module;
public readonly TokenIdent Name = name;
}