Parse call expressions

This commit is contained in:
2025-06-07 23:50:53 +02:00
parent 8d52410be9
commit d707bdeaf9
5 changed files with 574 additions and 357 deletions

View File

@ -5,7 +5,7 @@ from SYSTEM import TSIZE;
from MemUtils import MemZero;
from Storage import ALLOCATE, REALLOCATE;
from Lexer import LexerKind, LexerToken, lexer_current, lexer_lex;
from Lexer import Lexer, LexerKind, LexerToken, lexer_current, lexer_lex;
(* Calls lexer_lex() but skips the comments. *)
proc transpiler_lex(lexer: PLexer) -> LexerToken;
@ -181,7 +181,9 @@ begin
while token.kind <> lexerKindRightParen do
INC(parameter_count);
REALLOCATE(result^.parameters, TSIZE(PAstTypeExpression) * (parameter_count + 1));
INC(parameter_count);
REALLOCATE(result^.parameters, TSIZE(PAstTypeExpression) * parameter_count);
DEC(parameter_count);
current_parameter := result^.parameters;
INC(current_parameter, TSIZE(PAstTypeExpression) * (parameter_count - 1));
@ -476,7 +478,7 @@ begin
literal^.kind := astLiteralKindInteger;
literal^.integer := token.integerKind;
end;
if token.kind = lexerKindCharacter then
if (token.kind = lexerKindCharacter) or (token.kind = lexerKindString) then
NEW(literal);
literal^.kind := astLiteralKindString;
@ -487,6 +489,12 @@ begin
literal^.kind := astLiteralKindNull;
end;
if token.kind = lexerKindBoolean then
NEW(literal);
literal^.kind := astLiteralKindBoolean;
literal^.boolean := token.booleanKind
end;
if literal <> nil then
token := transpiler_lex(lexer)
end;
@ -527,6 +535,13 @@ begin
result^.unary_operator := astUnaryOperatorNot;
result^.unary_operand := parse_factor(lexer)
end;
if (result = nil) & (next_token.kind = lexerKindLeftParen) then
next_token := transpiler_lex(lexer);
result := parse_expression(lexer);
if result <> nil then
next_token := transpiler_lex(lexer)
end
end;
if (result = nil) & (next_token.kind = lexerKindIdentifier) then
NEW(result);
@ -544,6 +559,7 @@ var
next_token: LexerToken;
inner_expression: PAstExpression;
designator: PAstExpression;
arguments: PPAstExpression;
handled: BOOLEAN;
begin
designator := parse_factor(lexer);
@ -582,6 +598,38 @@ begin
designator^.aggregate := inner_expression;
designator^.field := next_token.identifierKind;
next_token := transpiler_lex(lexer);
handled := true
end;
if ~handled & (next_token.kind = lexerKindLeftParen) then
NEW(designator);
next_token := transpiler_lex(lexer);
designator^.kind := astExpressionKindCall;
designator^.callable := inner_expression;
designator^.argument_count := 0;
designator^.arguments := nil;
if next_token.kind <> lexerKindRightParen then
ALLOCATE(designator^.arguments, TSIZE(PAstExpression));
designator^.argument_count := 1;
designator^.arguments^ := parse_designator(lexer);
next_token := lexer_current(lexer);
while next_token.kind = lexerKindComma do
next_token := transpiler_lex(lexer);
designator^.argument_count := designator^.argument_count + 1;
REALLOCATE(designator^.arguments, TSIZE(PAstExpression) * designator^.argument_count);
arguments := designator^.arguments;
INC(arguments, TSIZE(PAstExpression) * (designator^.argument_count - 1));
arguments^ := parse_designator(lexer);
next_token := lexer_current(lexer)
end
end;
next_token := transpiler_lex(lexer);
handled := true
end
@ -590,4 +638,77 @@ begin
return designator
end;
proc parse_binary_expression(lexer: PLexer, left: PAstExpression, operator: AstBinaryOperator) -> PAstExpression;
var
next_token: LexerToken;
result: PAstExpression;
right: PAstExpression;
begin
next_token := transpiler_lex(lexer);
right := parse_designator(lexer);
result := nil;
if right <> nil then
NEW(result);
result^.kind := astExpressionKindBinary;
result^.binary_operator := operator;
result^.lhs := left;
result^.rhs := right;
end;
return result
end;
proc parse_expression(lexer: PLexer) -> PAstExpression;
var
next_token: LexerToken;
left: PAstExpression;
result: PAstExpression;
saved: Lexer;
begin
left := parse_designator(lexer);
saved := lexer^;
result := nil;
next_token := lexer_current(lexer);
if left <> nil then
if (result = nil) & (next_token.kind = lexerKindNotEqual) then
result := parse_binary_expression(lexer, left, astBinaryOperatorNotEquals)
end;
if (result = nil) & (next_token.kind = lexerKindEqual) then
result := parse_binary_expression(lexer, left, astBinaryOperatorEquals)
end;
if (result = nil) & (next_token.kind = lexerKindGreaterThan) then
result := parse_binary_expression(lexer, left, astBinaryOperatorGreater)
end;
if (result = nil) & (next_token.kind = lexerKindLessThan) then
result := parse_binary_expression(lexer, left, astBinaryOperatorLess)
end;
if (result = nil) & (next_token.kind = lexerKindGreaterEqual) then
result := parse_binary_expression(lexer, left, astBinaryOperatorGreaterEqual)
end;
if (result = nil) & (next_token.kind = lexerKindLessEqual) then
result := parse_binary_expression(lexer, left, astBinaryOperatorLessEqual)
end;
if (result = nil) & (next_token.kind = lexerKindAnd) then
result := parse_binary_expression(lexer, left, astBinaryOperatorConjunction)
end;
if (result = nil) & (next_token.kind = lexerKindOr) then
result := parse_binary_expression(lexer, left, astBinaryOperatorDisjunction)
end;
if (result = nil) & (next_token.kind = lexerKindMinus) then
result := parse_binary_expression(lexer, left, astBinaryOperatorSubtraction)
end;
if (result = nil) & (next_token.kind = lexerKindPlus) then
result := parse_binary_expression(lexer, left, astBinaryOperatorSum)
end
end;
if (result = nil) & (left <> nil) then
result := left;
lexer^ := saved
end;
return result
end;
end.