Parse call expressions
This commit is contained in:
@ -1,11 +1,12 @@
|
||||
module;
|
||||
|
||||
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. *)
|
||||
proc transpiler_lex(lexer: PLexer) -> LexerToken;
|
||||
@ -34,7 +35,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));
|
||||
|
||||
@ -136,7 +139,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;
|
||||
@ -181,7 +186,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 +483,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 +494,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 +540,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 +564,7 @@ var
|
||||
next_token: LexerToken;
|
||||
inner_expression: PAstExpression;
|
||||
designator: PAstExpression;
|
||||
arguments: PPAstExpression;
|
||||
handled: BOOLEAN;
|
||||
begin
|
||||
designator := parse_factor(lexer);
|
||||
@ -569,7 +590,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
|
||||
@ -582,6 +603,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_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
|
||||
@ -590,4 +643,118 @@ 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;
|
||||
written_bytes: CARDINAL;
|
||||
begin
|
||||
left := parse_designator(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;
|
||||
if (result = nil) & (next_token.kind = lexerKindAsterisk) then
|
||||
result := parse_binary_expression(lexer, left, astBinaryOperatorMultiplication)
|
||||
end
|
||||
end;
|
||||
if (result = nil) & (left <> nil) then
|
||||
result := left
|
||||
end;
|
||||
|
||||
return result
|
||||
end;
|
||||
|
||||
proc 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;
|
||||
|
||||
proc 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;
|
||||
|
||||
proc parse_call_statement(lexer: PLexer, call: PAstExpression) -> PAstStatement;
|
||||
var
|
||||
result: PAstStatement;
|
||||
begin
|
||||
NEW(result);
|
||||
result^.kind := astStatementKindCall;
|
||||
result^.call := call;
|
||||
|
||||
return result
|
||||
end;
|
||||
|
||||
end.
|
||||
|
Reference in New Issue
Block a user