Parse call expressions

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

View File

@ -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.