Parse call expressions

This commit is contained in:
2025-06-07 23:50:33 +02:00
parent c9c9b217a2
commit 2c27047ffb
5 changed files with 571 additions and 355 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. *)
PROCEDURE transpiler_lex(lexer: PLexer): LexerToken;
@ -174,7 +174,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));
@ -459,7 +461,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;
@ -470,6 +472,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;
@ -509,6 +517,13 @@ BEGIN
result^.unary_operator := astUnaryOperatorNot;
result^.unary_operand := parse_factor(lexer)
END;
IF (result = NIL) AND (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) AND (next_token.kind = lexerKindIdentifier) THEN
NEW(result);
@ -525,6 +540,7 @@ VAR
next_token: LexerToken;
inner_expression: PAstExpression;
designator: PAstExpression;
arguments: PPAstExpression;
handled: BOOLEAN;
BEGIN
designator := parse_factor(lexer);
@ -563,6 +579,38 @@ BEGIN
designator^.aggregate := inner_expression;
designator^.field := next_token.identifierKind;
next_token := transpiler_lex(lexer);
handled := TRUE
END;
IF ~handled AND (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
@ -570,4 +618,75 @@ BEGIN
RETURN designator
END parse_designator;
PROCEDURE 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 parse_binary_expression;
PROCEDURE 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) AND (next_token.kind = lexerKindNotEqual) THEN
result := parse_binary_expression(lexer, left, astBinaryOperatorNotEquals)
END;
IF (result = NIL) AND (next_token.kind = lexerKindEqual) THEN
result := parse_binary_expression(lexer, left, astBinaryOperatorEquals)
END;
IF (result = NIL) AND (next_token.kind = lexerKindGreaterThan) THEN
result := parse_binary_expression(lexer, left, astBinaryOperatorGreater)
END;
IF (result = NIL) AND (next_token.kind = lexerKindLessThan) THEN
result := parse_binary_expression(lexer, left, astBinaryOperatorLess)
END;
IF (result = NIL) AND (next_token.kind = lexerKindGreaterEqual) THEN
result := parse_binary_expression(lexer, left, astBinaryOperatorGreaterEqual)
END;
IF (result = NIL) AND (next_token.kind = lexerKindLessEqual) THEN
result := parse_binary_expression(lexer, left, astBinaryOperatorLessEqual)
END;
IF (result = NIL) AND (next_token.kind = lexerKindAnd) THEN
result := parse_binary_expression(lexer, left, astBinaryOperatorConjunction)
END;
IF (result = NIL) AND (next_token.kind = lexerKindOr) THEN
result := parse_binary_expression(lexer, left, astBinaryOperatorDisjunction)
END;
IF (result = NIL) AND (next_token.kind = lexerKindMinus) THEN
result := parse_binary_expression(lexer, left, astBinaryOperatorSubtraction)
END;
IF (result = NIL) AND (next_token.kind = lexerKindPlus) THEN
result := parse_binary_expression(lexer, left, astBinaryOperatorSum)
END
END;
IF (result = NIL) AND (left <> NIL) THEN
result := left;
lexer^ := saved
END;
RETURN result
END parse_expression;
END Parser.