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