Parse call expressions

This commit is contained in:
2025-06-07 23:50:33 +02:00
parent c9c9b217a2
commit 62cdd39f51
5 changed files with 501 additions and 293 deletions

View File

@ -9,14 +9,14 @@ FROM MemUtils IMPORT MemCopy, MemZero;
FROM Common IMPORT Identifier, PIdentifier, ShortString;
FROM Lexer IMPORT Lexer, LexerToken, lexer_current, lexer_lex, LexerKind;
FROM Parser IMPORT AstTypeExpressionKind, AstExpressionKind, AstLiteralKind, AstUnaryOperator,
AstModule, PAstModule, AstExpression, PAstExpression, PAstLiteral,
FROM Parser IMPORT AstTypeExpressionKind, AstExpressionKind, AstLiteralKind, AstUnaryOperator, AstBinaryOperator,
AstModule, PAstModule, AstExpression, PPAstExpression, PAstExpression, PAstLiteral,
PAstConstantDeclaration, PPAstConstantDeclaration,
AstTypeDeclaration, PAstTypeDeclaration, PPAstTypeDeclaration,
PAstVariableDeclaration, PPAstVariableDeclaration, PAstImportStatement, PPAstImportStatement,
PAstTypeExpression, PPAstTypeExpression, AstFieldDeclaration, PAstFieldDeclaration,
parse_type_expression, parse_variable_part, parse_type_part, parse_constant_part, parse_import_part,
parse_designator;
parse_designator, parse_expression;
(* Calls lexer_lex() but skips the comments. *)
PROCEDURE transpiler_lex(lexer: PLexer): LexerToken;
@ -41,7 +41,7 @@ PROCEDURE write_current(lexer: PLexer; output: File);
VAR
written_bytes: CARDINAL;
BEGIN
written_bytes := WriteNBytes(output, ADDRESS(lexer^.Current - lexer^.Start), lexer^.Start)
written_bytes := WriteNBytes(output, ADDRESS(lexer^.current - lexer^.start), lexer^.start)
END write_current;
PROCEDURE transpile_import_statement(context: PTranspilerContext; import_statement: PAstImportStatement);
VAR
@ -425,19 +425,6 @@ BEGIN
token := transpiler_lex(context^.lexer)
END
END transpile_unchanged;
PROCEDURE parse_expression(lexer: PLexer): PAstExpression;
VAR
next_token: LexerToken;
result: PAstExpression;
written_bytes: CARDINAL;
BEGIN
result := parse_designator(lexer);
written_bytes := WriteNBytes(StdErr, ADDRESS(lexer^.Current - lexer^.Start), lexer^.Start);
WriteLine(StdErr);
RETURN result
END parse_expression;
PROCEDURE transpile_unary_operator(context: PTranspilerContext; operator: AstUnaryOperator);
BEGIN
IF operator = astUnaryOperatorMinus THEN
@ -447,11 +434,49 @@ BEGIN
WriteChar(context^.output, '~')
END
END transpile_unary_operator;
PROCEDURE transpile_binary_operator(context: PTranspilerContext; operator: AstBinaryOperator);
BEGIN
IF operator = astBinaryOperatorSum THEN
WriteChar(context^.output, '+')
END;
IF operator = astBinaryOperatorSubtraction THEN
WriteChar(context^.output, '-')
END;
IF operator = astBinaryOperatorMultiplication THEN
WriteChar(context^.output, '*')
END;
IF operator = astBinaryOperatorEquals THEN
WriteChar(context^.output, '=')
END;
IF operator = astBinaryOperatorNotEquals THEN
WriteChar(context^.output, '#')
END;
IF operator = astBinaryOperatorLess THEN
WriteChar(context^.output, '<')
END;
IF operator = astBinaryOperatorGreater THEN
WriteChar(context^.output, '>')
END;
IF operator = astBinaryOperatorLessEqual THEN
WriteString(context^.output, '<=')
END;
IF operator = astBinaryOperatorGreaterEqual THEN
WriteString(context^.output, '>=')
END;
IF operator = astBinaryOperatorDisjunction THEN
WriteString(context^.output, 'OR')
END;
IF operator = astBinaryOperatorConjunction THEN
WriteString(context^.output, 'AND')
END
END transpile_binary_operator;
PROCEDURE transpile_expression(context: PTranspilerContext; expression: PAstExpression);
VAR
literal: PAstLiteral;
buffer: ARRAY[1..20] OF CHAR;
written_bytes: CARDINAL;
argument_index: CARDINAL;
current_argument: PPAstExpression;
BEGIN
IF expression^.kind = astExpressionKindLiteral THEN
literal := expression^.literal;
@ -462,7 +487,16 @@ BEGIN
END;
IF literal^.kind = astLiteralKindString THEN
WriteString(context^.output, literal^.string)
END
END;
IF literal^.kind = astLiteralKindNull THEN
WriteString(context^.output, 'NIL')
END;
IF (literal^.kind = astLiteralKindBoolean) AND literal^.boolean THEN
WriteString(context^.output, 'TRUE')
END;
IF (literal^.kind = astLiteralKindBoolean) AND (literal^.boolean = FALSE) THEN
WriteString(context^.output, 'FALSE')
END
END;
IF expression^.kind = astExpressionKindIdentifier THEN
written_bytes := WriteNBytes(context^.output, ORD(expression^.identifier[1]), ADR(expression^.identifier[2]))
@ -485,6 +519,35 @@ BEGIN
IF expression^.kind = astExpressionKindUnary THEN
transpile_unary_operator(context, expression^.unary_operator);
transpile_expression(context, expression^.unary_operand)
END;
IF expression^.kind = astExpressionKindBinary THEN
transpile_expression(context, expression^.lhs);
WriteChar(context^.output, ' ');
transpile_binary_operator(context, expression^.binary_operator);
WriteChar(context^.output, ' ');
transpile_expression(context, expression^.rhs)
END;
IF expression^.kind = astExpressionKindCall THEN
transpile_expression(context, expression^.callable);
WriteChar(context^.output, '(');
current_argument := expression^.arguments;
IF expression^.argument_count > 0 THEN
transpile_expression(context, current_argument^);
argument_index := 1;
INC(current_argument, TSIZE(PAstExpression));
WHILE argument_index < expression^.argument_count DO
WriteString(context^.output, ', ');
transpile_expression(context, current_argument^);
INC(current_argument, TSIZE(PAstExpression));
INC(argument_index)
END
END;
WriteChar(context^.output, ')')
END
END transpile_expression;
PROCEDURE transpile_if_statement(context: PTranspilerContext);
@ -492,11 +555,12 @@ VAR
token: LexerToken;
expression: PAstExpression;
lexer: Lexer;
written_bytes: CARDINAL;
BEGIN
WriteString(context^.output, ' IF ');
token := transpiler_lex(context^.lexer);
lexer := context^.lexer^;
token := transpiler_lex(ADR(lexer));
expression := parse_expression(ADR(lexer));
IF expression <> NIL THEN
@ -504,8 +568,10 @@ BEGIN
transpile_expression(context, expression);
WriteChar(context^.output, ' ')
END;
IF expression = NIL THEN
token := transpiler_lex(context^.lexer)
token := lexer_current(context^.lexer);
IF token.kind <> lexerKindThen THEN
written_bytes := WriteNBytes(StdErr, 10, context^.lexer^.start);
WriteLine(StdErr)
END;
transpile_unchanged(context, lexerKindThen);