Parse call expressions
This commit is contained in:
@ -1,11 +1,12 @@
|
||||
IMPLEMENTATION MODULE Parser;
|
||||
|
||||
FROM FIO IMPORT ReadNBytes;
|
||||
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;
|
||||
@ -33,7 +34,9 @@ BEGIN
|
||||
|
||||
WHILE token.kind <> lexerKindEnd DO
|
||||
INC(field_count);
|
||||
REALLOCATE(field_declarations, TSIZE(AstFieldDeclaration) * (field_count + 1));
|
||||
INC(field_count);
|
||||
REALLOCATE(field_declarations, TSIZE(AstFieldDeclaration) * field_count);
|
||||
DEC(field_count);
|
||||
current_field := field_declarations;
|
||||
INC(current_field , TSIZE(AstFieldDeclaration) * (field_count - 1));
|
||||
|
||||
@ -131,7 +134,9 @@ BEGIN
|
||||
token := transpiler_lex(lexer);
|
||||
|
||||
INC(case_count);
|
||||
REALLOCATE(result^.cases, TSIZE(Identifier) * (case_count + 1));
|
||||
INC(case_count);
|
||||
REALLOCATE(result^.cases, TSIZE(Identifier) * case_count);
|
||||
DEC(case_count);
|
||||
current_case := result^.cases;
|
||||
INC(current_case, TSIZE(Identifier) * (case_count - 1));
|
||||
current_case^ := token.identifierKind;
|
||||
@ -174,7 +179,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 +466,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 +477,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 +522,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 +545,7 @@ VAR
|
||||
next_token: LexerToken;
|
||||
inner_expression: PAstExpression;
|
||||
designator: PAstExpression;
|
||||
arguments: PPAstExpression;
|
||||
handled: BOOLEAN;
|
||||
BEGIN
|
||||
designator := parse_factor(lexer);
|
||||
@ -550,7 +571,7 @@ BEGIN
|
||||
|
||||
designator^.kind := astExpressionKindArrayAccess;
|
||||
designator^.array := inner_expression;
|
||||
designator^.index := parse_designator(lexer);
|
||||
designator^.index := parse_expression(lexer);
|
||||
|
||||
next_token := transpiler_lex(lexer);
|
||||
handled := TRUE
|
||||
@ -563,6 +584,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_expression(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_expression(lexer);
|
||||
|
||||
next_token := lexer_current(lexer)
|
||||
END
|
||||
END;
|
||||
|
||||
next_token := transpiler_lex(lexer);
|
||||
handled := TRUE
|
||||
END
|
||||
@ -570,4 +623,113 @@ 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;
|
||||
written_bytes: CARDINAL;
|
||||
BEGIN
|
||||
left := parse_designator(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;
|
||||
IF (result = NIL) AND (next_token.kind = lexerKindAsterisk) THEN
|
||||
result := parse_binary_expression(lexer, left, astBinaryOperatorMultiplication)
|
||||
END
|
||||
END;
|
||||
IF (result = NIL) AND (left <> NIL) THEN
|
||||
result := left
|
||||
END;
|
||||
|
||||
RETURN result
|
||||
END parse_expression;
|
||||
PROCEDURE parse_return_statement(lexer: PLexer): PAstStatement;
|
||||
VAR
|
||||
token: LexerToken;
|
||||
result: PAstStatement;
|
||||
BEGIN
|
||||
NEW(result);
|
||||
result^.kind := astStatementKindReturn;
|
||||
|
||||
token := transpiler_lex(lexer);
|
||||
result^.returned := parse_expression(lexer);
|
||||
|
||||
RETURN result
|
||||
END parse_return_statement;
|
||||
PROCEDURE parse_assignment_statement(lexer: PLexer; assignee: PAstExpression): PAstStatement;
|
||||
VAR
|
||||
token: LexerToken;
|
||||
result: PAstStatement;
|
||||
BEGIN
|
||||
NEW(result);
|
||||
result^.kind := astStatementKindAssignment;
|
||||
result^.assignee := assignee;
|
||||
|
||||
token := transpiler_lex(lexer);
|
||||
result^.assignment := parse_expression(lexer);
|
||||
|
||||
RETURN result
|
||||
END parse_assignment_statement;
|
||||
PROCEDURE parse_call_statement(lexer: PLexer; call: PAstExpression): PAstStatement;
|
||||
VAR
|
||||
result: PAstStatement;
|
||||
BEGIN
|
||||
NEW(result);
|
||||
result^.kind := astStatementKindCall;
|
||||
result^.call := call;
|
||||
|
||||
RETURN result
|
||||
END parse_call_statement;
|
||||
END Parser.
|
||||
|
Reference in New Issue
Block a user