This commit is contained in:
nub31
2026-02-10 19:50:55 +01:00
parent d3e2dcede8
commit 6ae10d5f90
7 changed files with 215 additions and 64 deletions

View File

@@ -4,20 +4,25 @@ namespace Compiler;
public sealed class Parser(string fileName, List<Token> tokens)
{
public static Ast Parse(string fileName, List<Token> tokens, out List<Diagnostic> diagnostics)
public static Ast? Parse(string fileName, List<Token> tokens, out List<Diagnostic> diagnostics)
{
return new Parser(fileName, tokens).Parse(out diagnostics);
}
private int index;
private Ast Parse(out List<Diagnostic> diagnostics)
private Ast? Parse(out List<Diagnostic> diagnostics)
{
var definitions = new List<NodeDefinition>();
diagnostics = [];
TokenIdent? moduleName = null;
try
{
ExpectKeyword(Keyword.Module);
moduleName = ExpectIdent();
while (Peek() != null)
{
definitions.Add(ParseDefinition());
@@ -28,7 +33,10 @@ public sealed class Parser(string fileName, List<Token> tokens)
diagnostics.Add(e.Diagnostic);
}
return new Ast(definitions, fileName);
if (moduleName == null || diagnostics.Any(x => x.Severity == DiagnosticSeverity.Error))
return null;
return new Ast(fileName, moduleName, definitions);
}
private NodeDefinition ParseDefinition()
@@ -76,12 +84,6 @@ 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);
}
throw new CompileException(Diagnostic.Error("Not a valid definition").At(fileName, Peek()).Build());
}
@@ -355,6 +357,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)
{
Next();
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)
@@ -529,9 +542,10 @@ public sealed class Parser(string fileName, List<Token> tokens)
}
}
public sealed class Ast(List<NodeDefinition> definitions, string fileName)
public sealed class Ast(string fileName, TokenIdent moduleName, List<NodeDefinition> definitions)
{
public string FileName { get; } = fileName;
public TokenIdent ModuleName { get; } = moduleName;
public List<NodeDefinition> Definitions { get; } = definitions;
}
@@ -542,11 +556,6 @@ 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 TokenIdent Name { get; } = name;
}
public sealed class NodeDefinitionFunc(List<Token> tokens, TokenIdent name, List<NodeDefinitionFunc.Param> parameters, NodeStatement body, NodeType returnType) : NodeDefinition(tokens)
{
public TokenIdent Name { get; } = name;