Parse the variable part to AST

This commit is contained in:
Eugen Wissner 2025-06-04 12:13:40 +02:00
parent ff547a295d
commit 92ba0ff871
Signed by: belka
GPG Key ID: A27FDC1E8EE902C0
3 changed files with 83 additions and 29 deletions

View File

@ -46,6 +46,8 @@ TYPE
PPAstTypeDeclaration = POINTER TO PAstTypeDeclaration; PPAstTypeDeclaration = POINTER TO PAstTypeDeclaration;
AstVariableDeclaration = RECORD AstVariableDeclaration = RECORD
variable_name: Identifier;
variable_type: PAstTypeExpression
END; END;
PAstVariableDeclaration = POINTER TO AstVariableDeclaration; PAstVariableDeclaration = POINTER TO AstVariableDeclaration;
PPAstVariableDeclaration = POINTER TO PAstVariableDeclaration; PPAstVariableDeclaration = POINTER TO PAstVariableDeclaration;
@ -58,7 +60,7 @@ TYPE
PAstModule = POINTER TO AstModule; PAstModule = POINTER TO AstModule;
PROCEDURE parse_type_expression(lexer: PLexer): PAstTypeExpression; PROCEDURE parse_type_expression(lexer: PLexer): PAstTypeExpression;
PROCEDURE parse_type_declaration(lexer: PLexer): PAstTypeDeclaration;
PROCEDURE parse_type_part(lexer: PLexer): PPAstTypeDeclaration; PROCEDURE parse_type_part(lexer: PLexer): PPAstTypeDeclaration;
PROCEDURE parse_variable_part(lexer: PLexer): PPAstVariableDeclaration;
END Parser. END Parser.

View File

@ -272,4 +272,56 @@ BEGIN
RETURN result RETURN result
END parse_type_part; END parse_type_part;
PROCEDURE parse_variable_declaration(lexer: PLexer): PAstVariableDeclaration;
VAR
token: LexerToken;
result: PAstVariableDeclaration;
BEGIN
ALLOCATE(result, TSIZE(AstVariableDeclaration));
token := lexer_current(lexer);
result^.variable_name := token.identifierKind;
token := transpiler_lex(lexer);
token := transpiler_lex(lexer);
result^.variable_type := parse_type_expression(lexer);
token := transpiler_lex(lexer);
RETURN result
END parse_variable_declaration;
PROCEDURE parse_variable_part(lexer: PLexer): PPAstVariableDeclaration;
VAR
token: LexerToken;
result: PPAstVariableDeclaration;
current_declaration: PPAstVariableDeclaration;
declaration_count: CARDINAL;
BEGIN
token := lexer_current(lexer);
ALLOCATE(result, TSIZE(PAstVariableDeclaration));
current_declaration := result;
declaration_count := 0;
IF token.kind = lexerKindVar THEN
token := transpiler_lex(lexer);
WHILE token.kind = lexerKindIdentifier DO
INC(declaration_count);
REALLOCATE(result, TSIZE(PAstVariableDeclaration) * (declaration_count + 1));
current_declaration := result;
INC(current_declaration, TSIZE(PAstVariableDeclaration) * (declaration_count - 1));
current_declaration^ := parse_variable_declaration(lexer);
token := transpiler_lex(lexer)
END
END;
IF declaration_count <> 0 THEN
INC(current_declaration, TSIZE(PAstVariableDeclaration))
END;
current_declaration^ := NIL;
RETURN result
END parse_variable_part;
END Parser. END Parser.

View File

@ -12,9 +12,9 @@ FROM Lexer IMPORT Lexer, LexerToken, lexer_current, lexer_lex, LexerKind;
FROM Parser IMPORT AstModule, PAstModule, AstTypeExpressionKind, FROM Parser IMPORT AstModule, PAstModule, AstTypeExpressionKind,
AstConstantDeclaration, PPAstConstantDeclaration, AstConstantDeclaration, PPAstConstantDeclaration,
AstTypeDeclaration, PAstTypeDeclaration, PPAstTypeDeclaration, AstTypeDeclaration, PAstTypeDeclaration, PPAstTypeDeclaration,
AstVariableDeclaration, PPAstVariableDeclaration, PAstVariableDeclaration, PPAstVariableDeclaration,
PAstTypeExpression, AstTypeExpression, PPAstTypeExpression, AstFieldDeclaration, PAstFieldDeclaration, PAstTypeExpression, PPAstTypeExpression, AstFieldDeclaration, PAstFieldDeclaration,
parse_type_expression, parse_type_declaration, parse_type_part; parse_type_expression, parse_variable_part, parse_type_part;
(* Calls lexer_lex() but skips the comments. *) (* Calls lexer_lex() but skips the comments. *)
PROCEDURE transpiler_lex(lexer: PLexer): LexerToken; PROCEDURE transpiler_lex(lexer: PLexer): LexerToken;
@ -131,7 +131,9 @@ BEGIN
WriteString(context^.output, 'MODULE '); WriteString(context^.output, 'MODULE ');
(* Write the module name and end the line with a semicolon and newline. *) (* Write the module name and end the line with a semicolon and newline. *)
token := transpiler_lex(context^.lexer); IF token.kind <> lexerKindProgram THEN
token := transpiler_lex(context^.lexer);
END;
transpile_module_name(context); transpile_module_name(context);
token := transpiler_lex(context^.lexer); token := transpiler_lex(context^.lexer);
@ -145,7 +147,9 @@ BEGIN
result^.constants := transpile_constant_part(context); result^.constants := transpile_constant_part(context);
result^.types := parse_type_part(context^.lexer); result^.types := parse_type_part(context^.lexer);
transpile_type_part(context, result^.types); transpile_type_part(context, result^.types);
result^.variables := transpile_variable_part(context);
result^.variables := parse_variable_part(context^.lexer);
transpile_variable_part(context, result^.variables);
transpile_procedure_part(context); transpile_procedure_part(context);
transpile_statement_part(context); transpile_statement_part(context);
@ -316,40 +320,34 @@ BEGIN
WriteLine(context^.output) WriteLine(context^.output)
END END
END transpile_type_part; END transpile_type_part;
PROCEDURE transpile_variable_declaration(context: PTranspilerContext); PROCEDURE transpile_variable_declaration(context: PTranspilerContext; declaration: PAstVariableDeclaration);
VAR VAR
token: LexerToken; written_bytes: CARDINAL;
type_expression: PAstTypeExpression;
BEGIN BEGIN
WriteString(context^.output, ' '); WriteString(context^.output, ' ');
token := lexer_current(context^.lexer); written_bytes := WriteNBytes(context^.output, ORD(declaration^.variable_name[1]), ADR(declaration^.variable_name[2]));
write_current(context^.lexer, context^.output);
token := transpiler_lex(context^.lexer);
WriteString(context^.output, ': '); WriteString(context^.output, ': ');
token := transpiler_lex(context^.lexer);
type_expression := parse_type_expression(context^.lexer); transpile_type_expression(context, declaration^.variable_type);
transpile_type_expression(context, type_expression);
token := transpiler_lex(context^.lexer);
write_semicolon(context^.output) write_semicolon(context^.output)
END transpile_variable_declaration; END transpile_variable_declaration;
PROCEDURE transpile_variable_part(context: PTranspilerContext): PPAstVariableDeclaration; PROCEDURE transpile_variable_part(context: PTranspilerContext; declarations: PPAstVariableDeclaration);
VAR VAR
token: LexerToken; current_declaration: PPAstVariableDeclaration;
BEGIN BEGIN
token := lexer_current(context^.lexer); IF declarations^ <> NIL THEN
IF token.kind = lexerKindVar THEN
WriteString(context^.output, 'VAR'); WriteString(context^.output, 'VAR');
WriteLine(context^.output); WriteLine(context^.output);
token := transpiler_lex(context^.lexer);
WHILE token.kind = lexerKindIdentifier DO current_declaration := declarations;
transpile_variable_declaration(context); WHILE current_declaration^ <> NIL DO
token := transpiler_lex(context^.lexer) transpile_variable_declaration(context, current_declaration^);
END
END; INC(current_declaration, TSIZE(PAstVariableDeclaration))
RETURN NIL END;
WriteLine(context^.output)
END
END transpile_variable_part; END transpile_variable_part;
PROCEDURE transpile_procedure_heading(context: PTranspilerContext): LexerToken; PROCEDURE transpile_procedure_heading(context: PTranspilerContext): LexerToken;
VAR VAR
@ -593,7 +591,9 @@ VAR
BEGIN BEGIN
token := transpile_procedure_heading(context); token := transpile_procedure_heading(context);
seen_constants := transpile_constant_part(context); seen_constants := transpile_constant_part(context);
seen_variables := transpile_variable_part(context);
seen_variables := parse_variable_part(context^.lexer);
transpile_variable_part(context, seen_variables);
transpile_statement_part(context); transpile_statement_part(context);
WriteString(context^.output, 'END '); WriteString(context^.output, 'END ');