This commit is contained in:
nub31
2025-11-03 16:01:20 +01:00
parent 7ce451768d
commit 7d49bf43b7
7 changed files with 207 additions and 109 deletions

View File

@@ -9,6 +9,19 @@ public sealed class Parser
private int _tokenIndex;
private Token? CurrentToken => _tokenIndex < _tokens.Count ? _tokens[_tokenIndex] : null;
private bool HasTrailingWhitespace(Token token)
{
var index = _tokens.IndexOf(token);
return index + 1 < _tokens.Count && _tokens[index + 1] is WhitespaceToken or CommentToken;
}
private bool HasLeadingWhitespace(Token token)
{
var index = _tokens.IndexOf(token);
return index - 1 < _tokens.Count && _tokens[index - 1] is WhitespaceToken or CommentToken;
}
private bool HasToken => CurrentToken != null;
public List<Diagnostic> Diagnostics { get; set; } = [];
@@ -194,27 +207,36 @@ public sealed class Parser
{
var startIndex = _tokenIndex;
if (TryExpectSymbol(out var symbol))
if (CurrentToken is SymbolToken symbolToken)
{
switch (symbol)
switch (symbolToken.Symbol)
{
case Symbol.OpenBrace:
Next();
return ParseBlock(startIndex);
case Symbol.Return:
Next();
return ParseReturn(startIndex);
case Symbol.If:
Next();
return ParseIf(startIndex);
case Symbol.While:
Next();
return ParseWhile(startIndex);
case Symbol.For:
Next();
return ParseFor(startIndex);
case Symbol.Let:
Next();
return ParseVariableDeclaration(startIndex);
case Symbol.Defer:
Next();
return ParseDefer(startIndex);
case Symbol.Break:
Next();
return new BreakSyntax(GetTokens(startIndex));
case Symbol.Continue:
Next();
return new ContinueSyntax(GetTokens(startIndex));
}
}
@@ -319,7 +341,7 @@ public sealed class Parser
var startIndex = _tokenIndex;
var left = ParsePrimaryExpression();
while (CurrentToken is SymbolToken symbolToken && TryGetBinaryOperator(symbolToken.Symbol, out var op) && GetBinaryOperatorPrecedence(op.Value) >= precedence)
while (CurrentToken is SymbolToken symbolToken && HasLeadingWhitespace(symbolToken) && HasTrailingWhitespace(symbolToken) && TryGetBinaryOperator(symbolToken.Symbol, out var op) && GetBinaryOperatorPrecedence(op.Value) >= precedence)
{
Next();
var right = ParseExpression(GetBinaryOperatorPrecedence(op.Value) + 1);
@@ -463,6 +485,68 @@ public sealed class Parser
return ParsePostfixOperators(expr);
}
private ExpressionSyntax ParsePostfixOperators(ExpressionSyntax expr)
{
if (CurrentToken == null || HasLeadingWhitespace(CurrentToken))
{
return expr;
}
var startIndex = _tokenIndex;
while (HasToken)
{
if (TryExpectSymbol(Symbol.Caret))
{
expr = new DereferenceSyntax(GetTokens(startIndex), expr);
continue;
}
if (TryExpectSymbol(Symbol.Period))
{
var member = ExpectIdentifier();
expr = new MemberAccessSyntax(GetTokens(startIndex), expr, member);
continue;
}
if (TryExpectSymbol(Symbol.OpenBracket))
{
var index = ParseExpression();
ExpectSymbol(Symbol.CloseBracket);
expr = new ArrayIndexAccessSyntax(GetTokens(startIndex), expr, index);
continue;
}
if (TryExpectSymbol(Symbol.OpenParen))
{
var parameters = new List<ExpressionSyntax>();
while (!TryExpectSymbol(Symbol.CloseParen))
{
parameters.Add(ParseExpression());
if (!TryExpectSymbol(Symbol.Comma))
{
ExpectSymbol(Symbol.CloseParen);
break;
}
}
expr = new FuncCallSyntax(GetTokens(startIndex), expr, parameters);
continue;
}
break;
}
return expr;
}
private ExpressionSyntax ParseParenthesizedExpression()
{
var expression = ParseExpression();
ExpectSymbol(Symbol.CloseParen);
return expression;
}
private AddressOfSyntax ParseAddressOf(int startIndex)
{
var expression = ParsePrimaryExpression();
@@ -518,63 +602,6 @@ public sealed class Parser
return new LocalIdentifierSyntax(GetTokens(startIndex), identifier);
}
private ExpressionSyntax ParseParenthesizedExpression()
{
var expression = ParseExpression();
ExpectSymbol(Symbol.CloseParen);
return expression;
}
private ExpressionSyntax ParsePostfixOperators(ExpressionSyntax expr)
{
var startIndex = _tokenIndex;
while (HasToken)
{
if (TryExpectSymbol(Symbol.Caret))
{
expr = new DereferenceSyntax(GetTokens(startIndex), expr);
continue;
}
if (TryExpectSymbol(Symbol.Period))
{
var member = ExpectIdentifier();
expr = new MemberAccessSyntax(GetTokens(startIndex), expr, member);
continue;
}
if (TryExpectSymbol(Symbol.OpenBracket))
{
var index = ParseExpression();
ExpectSymbol(Symbol.CloseBracket);
expr = new ArrayIndexAccessSyntax(GetTokens(startIndex), expr, index);
continue;
}
if (TryExpectSymbol(Symbol.OpenParen))
{
var parameters = new List<ExpressionSyntax>();
while (!TryExpectSymbol(Symbol.CloseParen))
{
parameters.Add(ParseExpression());
if (!TryExpectSymbol(Symbol.Comma))
{
ExpectSymbol(Symbol.CloseParen);
break;
}
}
expr = new FuncCallSyntax(GetTokens(startIndex), expr, parameters);
continue;
}
break;
}
return expr;
}
private ExpressionSyntax ParseArrayInitializer(int startIndex)
{
var values = new List<ExpressionSyntax>();
@@ -914,6 +941,10 @@ public sealed class Parser
private void Next()
{
_tokenIndex++;
while (_tokenIndex < _tokens.Count && _tokens[_tokenIndex] is WhitespaceToken or CommentToken)
{
_tokenIndex++;
}
}
private List<Token> GetTokens(int tokenStartIndex)