...
This commit is contained in:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user