diangostics

This commit is contained in:
2026-02-08 19:24:06 +01:00
parent 00714ea4b0
commit e20f6cd7af
4 changed files with 208 additions and 32 deletions

View File

@@ -2,21 +2,31 @@
namespace Compiler;
public sealed class Parser(List<Token> tokens)
public sealed class Parser(string fileName, List<Token> tokens)
{
public static List<NodeDefinition> Parse(List<Token> tokens)
public static List<NodeDefinition> Parse(string fileName, List<Token> tokens, out List<Diagnostic> diagnostics)
{
return new Parser(tokens).Parse();
return new Parser(fileName, tokens).Parse(out diagnostics);
}
private int index;
private List<NodeDefinition> Parse()
private List<NodeDefinition> Parse(out List<Diagnostic> diagnostics)
{
var nodes = new List<NodeDefinition>();
diagnostics = [];
while (Peek() != null)
nodes.Add(ParseDefinition());
try
{
while (Peek() != null)
{
nodes.Add(ParseDefinition());
}
}
catch (CompileException e)
{
diagnostics.Add(e.Diagnostic);
}
return nodes;
}
@@ -66,7 +76,7 @@ public sealed class Parser(List<Token> tokens)
return new NodeDefinitionStruct(TokensFrom(startIndex), name, fields);
}
throw new Exception("Not a valid definition");
throw new CompileException(Diagnostic.Error("Not a valid definition").At(fileName, Peek()).Build());
}
private NodeStatement ParseStatement()
@@ -135,7 +145,7 @@ public sealed class Parser(List<Token> tokens)
return new NodeStatementAssignment(TokensFrom(startIndex), target, value);
}
throw new Exception("Not a valid followup for expression statement");
throw new CompileException(Diagnostic.Error("Cannot use expression in statement context unless called as a function or used in assignment").At(fileName, target).Build());
}
private NodeExpression ParseExpression(int minPrecedence = -1)
@@ -233,7 +243,7 @@ public sealed class Parser(List<Token> tokens)
}
else
{
throw new Exception("Not a valid expression leaf");
throw new CompileException(Diagnostic.Error("Expected start of expression").At(fileName, Peek()).Build());
}
if (TryExpectSymbol(Symbol.Period))
@@ -302,7 +312,7 @@ public sealed class Parser(List<Token> tokens)
}
}
throw new Exception("Not a valid type");
throw new CompileException(Diagnostic.Error("Expected type").At(fileName, Peek()).Build());
}
private List<Token> TokensFrom(int startIndex)
@@ -329,7 +339,7 @@ public sealed class Parser(List<Token> tokens)
return;
}
throw new Exception($"Expected symbol '{symbol}'");
throw new CompileException(Diagnostic.Error($"Expected '{symbol.AsString()}'").At(fileName, Peek()).Build());
}
private bool TryExpectSymbol(Symbol symbol)
@@ -351,7 +361,7 @@ public sealed class Parser(List<Token> tokens)
return token;
}
throw new Exception("Expected ident");
throw new CompileException(Diagnostic.Error("Expected identifier").At(fileName, Peek()).Build());
}
private bool TryExpectIdent([NotNullWhen(true)] out TokenIdent? ident)
@@ -409,7 +419,7 @@ public sealed class Parser(List<Token> tokens)
private Token Consume()
{
if (index >= tokens.Count)
throw new Exception("End of tokens");
throw new CompileException(Diagnostic.Error("Unexpected end of tokens").At(fileName, Peek()).Build());
return tokens[index++];
}