Parse and transpile unary operations

This commit is contained in:
2025-06-06 18:25:53 +02:00
parent 3ca8491f64
commit 8d52410be9
6 changed files with 297 additions and 29 deletions

View File

@ -1,6 +1,6 @@
module;
from FIO import WriteNBytes, WriteLine, WriteChar, WriteString;
from FIO import StdErr, WriteNBytes, WriteLine, WriteChar, WriteString;
from SYSTEM import ADR, ADDRESS, TSIZE;
from NumberIO import IntToStr;
@ -9,12 +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 AstModule, PAstModule, AstTypeExpressionKind,
from Parser import AstTypeExpressionKind, AstExpressionKind, AstLiteralKind, AstUnaryOperator,
AstModule, PAstModule, AstExpression, 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_type_expression, parse_variable_part, parse_type_part, parse_constant_part, parse_import_part,
parse_designator;
(* Calls lexer_lex() but skips the comments. *)
proc transpiler_lex(lexer: PLexer) -> LexerToken;
@ -117,7 +119,7 @@ var
token: LexerToken;
result: PAstModule;
begin
ALLOCATE(result, TSIZE(AstModule));
NEW(result);
token := transpiler_lex(context^.lexer);
if token.kind = lexerKindModule then
@ -404,12 +406,12 @@ begin
return result
end;
proc transpile_expression(context: PTranspilerContext, trailing_token: LexerKind);
proc transpile_unchanged(context: PTranspilerContext, trailing_token: LexerKind);
var
token: LexerToken;
written_bytes: CARDINAL;
begin
token := transpiler_lex(context^.lexer);
token := lexer_current(context^.lexer);
while (token.kind <> trailing_token) & (token.kind <> lexerKindEnd) do
written_bytes := 0;
@ -433,7 +435,7 @@ begin
WriteString(context^.output, 'AND ');
written_bytes := 1
end;
if token.kind = lexerKindNot then
if token.kind = lexerKindTilde then
WriteString(context^.output, 'NOT ');
written_bytes := 1
end;
@ -445,12 +447,92 @@ begin
end
end;
proc 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;
proc transpile_unary_operator(context: PTranspilerContext, operator: AstUnaryOperator);
begin
if operator = astUnaryOperatorMinus then
WriteChar(context^.output, '-')
end;
if operator = astUnaryOperatorNot then
WriteChar(context^.output, '~')
end
end;
proc transpile_expression(context: PTranspilerContext, expression: PAstExpression);
var
literal: PAstLiteral;
buffer: [20]CHAR;
written_bytes: CARDINAL;
begin
if expression^.kind = astExpressionKindLiteral then
literal := expression^.literal;
if literal^.kind = astLiteralKindInteger then
IntToStr(literal^.integer, 0, buffer);
WriteString(context^.output, buffer);
end;
if literal^.kind = astLiteralKindString then
WriteString(context^.output, literal^.string)
end
end;
if expression^.kind = astExpressionKindIdentifier then
written_bytes := WriteNBytes(context^.output, ORD(expression^.identifier[1]), ADR(expression^.identifier[2]))
end;
if expression^.kind = astExpressionKindDereference then
transpile_expression(context, expression^.reference);
WriteChar(context^.output, '^')
end;
if expression^.kind = astExpressionKindArrayAccess then
transpile_expression(context, expression^.array);
WriteChar(context^.output, '[');
transpile_expression(context, expression^.index);
WriteChar(context^.output, ']')
end;
if expression^.kind = astExpressionKindFieldAccess then
transpile_expression(context, expression^.aggregate);
WriteChar(context^.output, '.');
written_bytes := WriteNBytes(context^.output, ORD(expression^.field[1]), ADR(expression^.field[2]));
end;
if expression^.kind = astExpressionKindUnary then
transpile_unary_operator(context, expression^.unary_operator);
transpile_expression(context, expression^.unary_operand)
end
end;
proc transpile_if_statement(context: PTranspilerContext);
var
token: LexerToken;
expression: PAstExpression;
lexer: Lexer;
begin
WriteString(context^.output, ' IF ');
transpile_expression(context, lexerKindThen);
lexer := context^.lexer^;
token := transpiler_lex(ADR(lexer));
expression := parse_expression(ADR(lexer));
if expression <> nil then
context^.lexer^ := lexer;
transpile_expression(context, expression);
WriteChar(context^.output, ' ')
end;
if expression = nil then
token := transpiler_lex(context^.lexer)
end;
transpile_unchanged(context, lexerKindThen);
WriteString(context^.output, 'THEN');
WriteLine(context^.output);
@ -464,7 +546,8 @@ var
token: LexerToken;
begin
WriteString(context^.output, ' WHILE ');
transpile_expression(context, lexerKindDo);
token := transpiler_lex(context^.lexer);
transpile_unchanged(context, lexerKindDo);
WriteString(context^.output, 'DO');
WriteLine(context^.output);
@ -474,9 +557,12 @@ begin
end;
proc transpile_assignment_statement(context: PTranspilerContext);
var
token: LexerToken;
begin
WriteString(context^.output, ' := ');
transpile_expression(context, lexerKindSemicolon);
token := transpiler_lex(context^.lexer);
transpile_unchanged(context, lexerKindSemicolon);
end;
proc transpile_call_statement(context: PTranspilerContext);
@ -541,7 +627,8 @@ var
token: LexerToken;
begin
WriteString(context^.output, ' RETURN ');
transpile_expression(context, lexerKindSemicolon)
token := transpiler_lex(context^.lexer);
transpile_unchanged(context, lexerKindSemicolon)
end;
proc transpile_statement(context: PTranspilerContext);