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