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