This commit is contained in:
nub31
2025-10-25 18:07:34 +02:00
parent 3f18aa4782
commit 396ddf93a2
18 changed files with 951 additions and 598 deletions

View File

@@ -19,9 +19,7 @@ public sealed class Parser
_tokens = tokens;
_tokenIndex = 0;
string? moduleName = null;
var imports = new List<string>();
var definitions = new List<DefinitionSyntax>();
var topLevelSyntaxNodes = new List<TopLevelSyntaxNode>();
while (HasToken)
{
@@ -29,53 +27,21 @@ public sealed class Parser
{
var startIndex = _tokenIndex;
if (TryExpectSymbol(Symbol.Import))
{
var name = ExpectStringLiteral();
if (imports.Contains(name.Value))
{
Diagnostics.Add(Diagnostic
.Warning($"Module {name.Value} is imported twice")
.At(name)
.WithHelp($"Remove duplicate import \"{name.Value}\"")
.Build());
}
else
{
imports.Add(name.Value);
}
continue;
}
if (TryExpectSymbol(Symbol.Module))
{
if (moduleName != null)
{
throw new ParseException(Diagnostic
.Error("Module is declared more than once")
.At(CurrentToken)
.WithHelp("Remove duplicate module declaration")
.Build());
}
moduleName = ExpectStringLiteral().Value;
continue;
}
var exported = TryExpectSymbol(Symbol.Export);
if (TryExpectSymbol(Symbol.Extern))
{
var externSymbol = ExpectStringLiteral();
ExpectSymbol(Symbol.Func);
definitions.Add(ParseFunc(startIndex, exported, externSymbol.Value));
topLevelSyntaxNodes.Add(ParseFunc(startIndex, exported, externSymbol));
continue;
}
var keyword = ExpectSymbol();
DefinitionSyntax definition = keyword.Symbol switch
TopLevelSyntaxNode definition = keyword.Symbol switch
{
Symbol.Module => ParseModule(startIndex),
Symbol.Import => ParseImport(startIndex),
Symbol.Func => ParseFunc(startIndex, exported, null),
Symbol.Struct => ParseStruct(startIndex, exported),
Symbol.Enum => ParseEnum(startIndex, exported),
@@ -86,7 +52,7 @@ public sealed class Parser
.Build())
};
definitions.Add(definition);
topLevelSyntaxNodes.Add(definition);
}
catch (ParseException e)
{
@@ -103,7 +69,19 @@ public sealed class Parser
}
}
return new SyntaxTree(definitions, moduleName ?? "default", imports);
return new SyntaxTree(topLevelSyntaxNodes);
}
private ImportSyntax ParseImport(int startIndex)
{
var name = ExpectIdentifier();
return new ImportSyntax(GetTokens(startIndex), name);
}
private ModuleSyntax ParseModule(int startIndex)
{
var name = ExpectIdentifier();
return new ModuleSyntax(GetTokens(startIndex), name);
}
private FuncParameterSyntax ParseFuncParameter()
@@ -113,10 +91,10 @@ public sealed class Parser
ExpectSymbol(Symbol.Colon);
var type = ParseType();
return new FuncParameterSyntax(GetTokens(startIndex), name.Value, type);
return new FuncParameterSyntax(GetTokens(startIndex), name, type);
}
private FuncSyntax ParseFunc(int startIndex, bool exported, string? externSymbol)
private FuncSyntax ParseFunc(int startIndex, bool exported, StringLiteralToken? externSymbol)
{
var name = ExpectIdentifier();
List<FuncParameterSyntax> parameters = [];
@@ -136,7 +114,7 @@ public sealed class Parser
var returnType = TryExpectSymbol(Symbol.Colon) ? ParseType() : new VoidTypeSyntax([]);
var prototype = new FuncPrototypeSyntax(GetTokens(startIndex), name.Value, exported, externSymbol, parameters, returnType);
var prototype = new FuncPrototypeSyntax(GetTokens(startIndex), name, exported, externSymbol, parameters, returnType);
BlockSyntax? body = null;
var bodyStartIndex = _tokenIndex;
@@ -160,7 +138,7 @@ public sealed class Parser
{
var memberStartIndex = _tokenIndex;
var fieldName = ExpectIdentifier().Value;
var fieldName = ExpectIdentifier();
ExpectSymbol(Symbol.Colon);
var fieldType = ParseType();
@@ -174,7 +152,7 @@ public sealed class Parser
fields.Add(new StructFieldSyntax(GetTokens(memberStartIndex), fieldName, fieldType, fieldValue));
}
return new StructSyntax(GetTokens(startIndex), name.Value, exported, fields);
return new StructSyntax(GetTokens(startIndex), name, exported, fields);
}
private EnumSyntax ParseEnum(int startIndex, bool exported)
@@ -192,13 +170,11 @@ public sealed class Parser
ExpectSymbol(Symbol.OpenBrace);
long value = -1;
while (!TryExpectSymbol(Symbol.CloseBrace))
{
var memberStartIndex = _tokenIndex;
var fieldName = ExpectIdentifier().Value;
long fieldValue;
var fieldName = ExpectIdentifier();
IntLiteralToken? value = null;
if (TryExpectSymbol(Symbol.Assign))
{
@@ -210,19 +186,13 @@ public sealed class Parser
.Build());
}
fieldValue = Convert.ToInt64(intLiteralToken.Value, intLiteralToken.Base);
value = fieldValue;
}
else
{
fieldValue = value + 1;
value = fieldValue;
value = intLiteralToken;
}
fields.Add(new EnumFieldSyntax(GetTokens(memberStartIndex), fieldName, fieldValue));
fields.Add(new EnumFieldSyntax(GetTokens(memberStartIndex), fieldName, value));
}
return new EnumSyntax(GetTokens(startIndex), name.Value, exported, type, fields);
return new EnumSyntax(GetTokens(startIndex), name, exported, type, fields);
}
private StatementSyntax ParseStatement()
@@ -267,7 +237,7 @@ public sealed class Parser
private VariableDeclarationSyntax ParseVariableDeclaration(int startIndex)
{
var name = ExpectIdentifier().Value;
var name = ExpectIdentifier();
TypeSyntax? explicitType = null;
if (TryExpectSymbol(Symbol.Colon))
@@ -334,12 +304,12 @@ public sealed class Parser
private ForSyntax ParseFor(int startIndex)
{
var itemName = ExpectIdentifier().Value;
string? indexName = null;
var itemName = ExpectIdentifier();
IdentifierToken? indexName = null;
if (TryExpectSymbol(Symbol.Comma))
{
indexName = ExpectIdentifier().Value;
indexName = ExpectIdentifier();
}
ExpectSymbol(Symbol.In);
@@ -467,10 +437,10 @@ public sealed class Parser
var token = ExpectToken();
var expr = token switch
{
BoolLiteralToken boolLiteral => new BoolLiteralSyntax(GetTokens(startIndex), boolLiteral.Value),
StringLiteralToken stringLiteral => new StringLiteralSyntax(GetTokens(startIndex), stringLiteral.Value),
FloatLiteralToken floatLiteral => new FloatLiteralSyntax(GetTokens(startIndex), floatLiteral.Value),
IntLiteralToken intLiteral => new IntLiteralSyntax(GetTokens(startIndex), intLiteral.Value, intLiteral.Base),
BoolLiteralToken boolLiteral => new BoolLiteralSyntax(GetTokens(startIndex), boolLiteral),
StringLiteralToken stringLiteral => new StringLiteralSyntax(GetTokens(startIndex), stringLiteral),
FloatLiteralToken floatLiteral => new FloatLiteralSyntax(GetTokens(startIndex), floatLiteral),
IntLiteralToken intLiteral => new IntLiteralSyntax(GetTokens(startIndex), intLiteral),
IdentifierToken identifier => ParseIdentifier(startIndex, identifier),
SymbolToken symbolToken => symbolToken.Symbol switch
{
@@ -528,10 +498,10 @@ public sealed class Parser
if (TryExpectSymbol(Symbol.DoubleColon))
{
var name = ExpectIdentifier();
return new ModuleIdentifierSyntax(GetTokens(startIndex), identifier.Value, name.Value);
return new ModuleIdentifierSyntax(GetTokens(startIndex), identifier, name);
}
return new LocalIdentifierSyntax(GetTokens(startIndex), identifier.Value);
return new LocalIdentifierSyntax(GetTokens(startIndex), identifier);
}
private ExpressionSyntax ParseParenthesizedExpression()
@@ -560,7 +530,7 @@ public sealed class Parser
if (TryExpectSymbol(Symbol.Period))
{
var member = ExpectIdentifier().Value;
var member = ExpectIdentifier();
expr = new MemberAccessSyntax(GetTokens(startIndex), expr, member);
continue;
}
@@ -627,12 +597,12 @@ public sealed class Parser
return new StructInitializerSyntax(GetTokens(startIndex), type, initializers);
}
private Dictionary<string, ExpressionSyntax> ParseStructInitializerBody()
private Dictionary<IdentifierToken, ExpressionSyntax> ParseStructInitializerBody()
{
Dictionary<string, ExpressionSyntax> initializers = [];
Dictionary<IdentifierToken, ExpressionSyntax> initializers = [];
while (!TryExpectSymbol(Symbol.CloseBrace))
{
var name = ExpectIdentifier().Value;
var name = ExpectIdentifier();
ExpectSymbol(Symbol.Assign);
var value = ParseExpression();
initializers.Add(name, value);
@@ -732,16 +702,16 @@ public sealed class Parser
return new BoolTypeSyntax(GetTokens(startIndex));
default:
{
string? module = null;
IdentifierToken? module = null;
if (TryExpectSymbol(Symbol.DoubleColon))
{
var customTypeName = ExpectIdentifier();
module = name.Value;
module = name;
name = customTypeName;
}
return new CustomTypeSyntax(GetTokens(startIndex), module, name.Value);
return new CustomTypeSyntax(GetTokens(startIndex), module, name);
}
}
}
@@ -780,7 +750,7 @@ public sealed class Parser
{
ExpectSymbol(Symbol.CloseBracket);
var baseType = ParseType();
return new ConstArrayTypeSyntax(GetTokens(startIndex), baseType, Convert.ToInt64(intLiteral.Value, intLiteral.Base));
return new ConstArrayTypeSyntax(GetTokens(startIndex), baseType, intLiteral.AsU64);
}
else if (TryExpectSymbol(Symbol.QuestionMark))
{
@@ -938,7 +908,7 @@ public sealed class Parser
}
}
public record SyntaxTree(List<DefinitionSyntax> Definitions, string ModuleName, List<string> Imports);
public record SyntaxTree(List<TopLevelSyntaxNode> TopLevelSyntaxNodes);
public class ParseException : Exception
{