update runtime tok look for main in defult namespace
This commit is contained in:
@@ -17,7 +17,7 @@ public sealed class Parser
|
||||
|
||||
public Parser(IEnumerable<Token> tokens)
|
||||
{
|
||||
_namespace = "global";
|
||||
_namespace = "default";
|
||||
_tokens = tokens;
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ public sealed class Parser
|
||||
{
|
||||
try
|
||||
{
|
||||
definitions.Add(ParseTopLevel());
|
||||
definitions.Add(ParseDefinition());
|
||||
}
|
||||
catch (ParseException ex)
|
||||
{
|
||||
@@ -50,20 +50,15 @@ public sealed class Parser
|
||||
return new SyntaxTree(_namespace, definitions, _diagnostics);
|
||||
}
|
||||
|
||||
private DefinitionSyntax ParseTopLevel()
|
||||
private DefinitionSyntax ParseDefinition()
|
||||
{
|
||||
var startIndex = _tokenIndex;
|
||||
List<ModifierToken> modifiers = [];
|
||||
|
||||
while (TryExpectModifier(out var modifier))
|
||||
{
|
||||
modifiers.Add(modifier);
|
||||
}
|
||||
|
||||
var keyword = ExpectSymbol();
|
||||
var node = keyword.Symbol switch
|
||||
{
|
||||
Symbol.Func => ParseFunc(startIndex, modifiers),
|
||||
Symbol.Extern => ParseExtern(startIndex),
|
||||
Symbol.Func => ParseFunc(startIndex),
|
||||
Symbol.Struct => ParseStruct(startIndex),
|
||||
Symbol.Trait => ParseTrait(startIndex),
|
||||
Symbol.Impl => ParseImplementation(startIndex),
|
||||
@@ -74,19 +69,52 @@ public sealed class Parser
|
||||
.Build())
|
||||
};
|
||||
|
||||
if (modifiers.Count != 0)
|
||||
{
|
||||
throw new ParseException(Diagnostic
|
||||
.Error($"Invalid modifiers: {string.Join(", ", modifiers.Select(x => x.Modifier))}")
|
||||
.WithHelp($"Remove the following modifiers: {modifiers.Select(x => x.Modifier)}'")
|
||||
.At(SourceSpan.Merge(modifiers.Select(x => x.Span)))
|
||||
.Build());
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
private DefinitionSyntax ParseFunc(int startIndex, List<ModifierToken> modifiers)
|
||||
private DefinitionSyntax ParseExtern(int startIndex)
|
||||
{
|
||||
var keyword = ExpectSymbol();
|
||||
return keyword.Symbol switch
|
||||
{
|
||||
Symbol.Func => ParseExternFunc(startIndex),
|
||||
_ => throw new ParseException(Diagnostic.Error($"Unexpected symbol {keyword.Symbol} after extern declaration").At(keyword).Build())
|
||||
};
|
||||
}
|
||||
|
||||
private ExternFuncSyntax ParseExternFunc(int startIndex)
|
||||
{
|
||||
var name = ExpectIdentifier();
|
||||
List<FuncParameterSyntax> parameters = [];
|
||||
|
||||
ExpectSymbol(Symbol.OpenParen);
|
||||
|
||||
while (!TryExpectSymbol(Symbol.CloseParen))
|
||||
{
|
||||
parameters.Add(ParseFuncParameter());
|
||||
|
||||
if (!TryExpectSymbol(Symbol.Comma) && Peek().TryGetValue(out var token) && token is not SymbolToken { Symbol: Symbol.CloseParen })
|
||||
{
|
||||
_diagnostics.Add(Diagnostic
|
||||
.Warning("Missing comma between function parameters")
|
||||
.WithHelp("Add a ',' to separate parameters")
|
||||
.At(token)
|
||||
.Build());
|
||||
}
|
||||
}
|
||||
|
||||
var returnType = TryExpectSymbol(Symbol.Colon) ? ParseType() : new NubVoidType();
|
||||
var callName = name.Value;
|
||||
|
||||
if (TryExpectSymbol(Symbol.Calls))
|
||||
{
|
||||
callName = ExpectIdentifier().Value;
|
||||
}
|
||||
|
||||
return new ExternFuncSyntax(GetTokens(startIndex), _namespace, name.Value, callName, parameters, returnType);
|
||||
}
|
||||
|
||||
private LocalFuncSyntax ParseFunc(int startIndex)
|
||||
{
|
||||
var name = ExpectIdentifier();
|
||||
List<FuncParameterSyntax> parameters = [];
|
||||
@@ -110,32 +138,9 @@ public sealed class Parser
|
||||
var returnType = TryExpectSymbol(Symbol.Colon) ? ParseType() : new NubVoidType();
|
||||
_functionReturnType = returnType;
|
||||
|
||||
var isExtern = modifiers.RemoveAll(x => x.Modifier == Modifier.Extern) > 0;
|
||||
if (isExtern)
|
||||
{
|
||||
if (modifiers.Count != 0)
|
||||
{
|
||||
throw new ParseException(Diagnostic
|
||||
.Error($"Invalid modifier for extern function: {modifiers[0].Modifier}")
|
||||
.WithHelp($"Extern functions cannot use the '{modifiers[0].Modifier}' modifier")
|
||||
.At(modifiers[0])
|
||||
.Build());
|
||||
}
|
||||
|
||||
var callName = name.Value;
|
||||
|
||||
if (TryExpectSymbol(Symbol.Calls))
|
||||
{
|
||||
callName = ExpectIdentifier().Value;
|
||||
}
|
||||
|
||||
return new ExternFuncSyntax(GetTokens(startIndex), _namespace, name.Value, callName, parameters, returnType);
|
||||
}
|
||||
|
||||
var body = ParseBlock();
|
||||
var exported = modifiers.RemoveAll(x => x.Modifier == Modifier.Export) > 0;
|
||||
|
||||
return new LocalFuncSyntax(GetTokens(startIndex), _namespace, name.Value, parameters, body, returnType, exported);
|
||||
return new LocalFuncSyntax(GetTokens(startIndex), _namespace, name.Value, parameters, body, returnType);
|
||||
}
|
||||
|
||||
private StructSyntax ParseStruct(int startIndex)
|
||||
@@ -657,7 +662,7 @@ public sealed class Parser
|
||||
catch (ParseException ex)
|
||||
{
|
||||
_diagnostics.Add(ex.Diagnostic);
|
||||
RecoverToNextStatement();
|
||||
Next();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -805,19 +810,6 @@ public sealed class Parser
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool TryExpectModifier([NotNullWhen(true)] out ModifierToken? modifier)
|
||||
{
|
||||
if (Peek() is { Value: ModifierToken modifierToken })
|
||||
{
|
||||
modifier = modifierToken;
|
||||
Next();
|
||||
return true;
|
||||
}
|
||||
|
||||
modifier = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool TryExpectIdentifier([NotNullWhen(true)] out IdentifierToken? identifier)
|
||||
{
|
||||
if (Peek() is { Value: IdentifierToken identifierToken })
|
||||
@@ -851,23 +843,7 @@ public sealed class Parser
|
||||
while (Peek().HasValue)
|
||||
{
|
||||
var token = Peek().Value;
|
||||
if (token is SymbolToken { Symbol: Symbol.Func or Symbol.Struct or Symbol.Trait or Symbol.Impl } or ModifierToken)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
Next();
|
||||
}
|
||||
}
|
||||
|
||||
private void RecoverToNextStatement()
|
||||
{
|
||||
while (Peek().TryGetValue(out var token))
|
||||
{
|
||||
if (token is SymbolToken { Symbol: Symbol.CloseBrace } or IdentifierToken or SymbolToken
|
||||
{
|
||||
Symbol: Symbol.Return or Symbol.If or Symbol.While or Symbol.Let or Symbol.Break or Symbol.Continue
|
||||
})
|
||||
if (token is SymbolToken { Symbol: Symbol.Extern or Symbol.Func or Symbol.Struct or Symbol.Trait or Symbol.Impl })
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user