Shorten the module declaration

This commit is contained in:
Eugen Wissner 2025-06-05 12:33:15 +02:00
parent 92ba0ff871
commit 9bc6b50b94
Signed by: belka
GPG Key ID: A27FDC1E8EE902C0
3 changed files with 183 additions and 60 deletions

View File

@ -4,7 +4,16 @@ FROM Common IMPORT Identifier, PIdentifier;
FROM Lexer IMPORT PLexer; FROM Lexer IMPORT PLexer;
TYPE TYPE
AstImportStatement = RECORD
package: Identifier;
symbols: PIdentifier
END;
PAstImportStatement = POINTER TO AstImportStatement;
PPAstImportStatement = POINTER TO PAstImportStatement;
AstConstantDeclaration = RECORD AstConstantDeclaration = RECORD
constant_name: Identifier;
constant_value: INTEGER
END; END;
PAstConstantDeclaration = POINTER TO AstConstantDeclaration; PAstConstantDeclaration = POINTER TO AstConstantDeclaration;
PPAstConstantDeclaration = POINTER TO PAstConstantDeclaration; PPAstConstantDeclaration = POINTER TO PAstConstantDeclaration;
@ -53,6 +62,7 @@ TYPE
PPAstVariableDeclaration = POINTER TO PAstVariableDeclaration; PPAstVariableDeclaration = POINTER TO PAstVariableDeclaration;
AstModule = RECORD AstModule = RECORD
imports: PPAstImportStatement;
constants: PPAstConstantDeclaration; constants: PPAstConstantDeclaration;
types: PPAstTypeDeclaration; types: PPAstTypeDeclaration;
variables: PPAstVariableDeclaration variables: PPAstVariableDeclaration
@ -62,5 +72,7 @@ TYPE
PROCEDURE parse_type_expression(lexer: PLexer): PAstTypeExpression; PROCEDURE parse_type_expression(lexer: PLexer): PAstTypeExpression;
PROCEDURE parse_type_part(lexer: PLexer): PPAstTypeDeclaration; PROCEDURE parse_type_part(lexer: PLexer): PPAstTypeDeclaration;
PROCEDURE parse_variable_part(lexer: PLexer): PPAstVariableDeclaration; PROCEDURE parse_variable_part(lexer: PLexer): PPAstVariableDeclaration;
PROCEDURE parse_constant_part(lexer: PLexer): PPAstConstantDeclaration;
PROCEDURE parse_import_part(lexer: PLexer): PPAstImportStatement;
END Parser. END Parser.

View File

@ -324,4 +324,126 @@ BEGIN
RETURN result RETURN result
END parse_variable_part; END parse_variable_part;
PROCEDURE parse_constant_declaration(lexer: PLexer): PAstConstantDeclaration;
VAR
token: LexerToken;
result: PAstConstantDeclaration;
BEGIN
ALLOCATE(result, TSIZE(AstConstantDeclaration));
token := lexer_current(lexer);
result^.constant_name := token.identifierKind;
token := transpiler_lex(lexer);
token := transpiler_lex(lexer);
result^.constant_value := token.integerKind;
token := transpiler_lex(lexer);
RETURN result
END parse_constant_declaration;
PROCEDURE parse_constant_part(lexer: PLexer): PPAstConstantDeclaration;
VAR
token: LexerToken;
result: PPAstConstantDeclaration;
current_declaration: PPAstConstantDeclaration;
declaration_count: CARDINAL;
BEGIN
token := lexer_current(lexer);
ALLOCATE(result, TSIZE(PAstConstantDeclaration));
current_declaration := result;
declaration_count := 0;
IF token.kind = lexerKindConst THEN
token := transpiler_lex(lexer);
WHILE token.kind = lexerKindIdentifier DO
INC(declaration_count);
REALLOCATE(result, TSIZE(PAstConstantDeclaration) * (declaration_count + 1));
current_declaration := result;
INC(current_declaration, TSIZE(PAstConstantDeclaration) * (declaration_count - 1));
current_declaration^ := parse_constant_declaration(lexer);
token := transpiler_lex(lexer)
END
END;
IF declaration_count <> 0 THEN
INC(current_declaration, TSIZE(PAstConstantDeclaration))
END;
current_declaration^ := NIL;
RETURN result
END parse_constant_part;
PROCEDURE parse_import_statement(lexer: PLexer): PAstImportStatement;
VAR
result: PAstImportStatement;
token: LexerToken;
symbol_count: CARDINAL;
current_symbol: PIdentifier;
BEGIN
ALLOCATE(result, TSIZE(AstImportStatement));
symbol_count := 1;
token := transpiler_lex(lexer);
result^.package := token.identifierKind;
token := transpiler_lex(lexer);
ALLOCATE(result^.symbols, TSIZE(Identifier) * 2);
current_symbol := result^.symbols;
token := transpiler_lex(lexer);
current_symbol^ := token.identifierKind;
token := transpiler_lex(lexer);
WHILE token.kind <> lexerKindSemicolon DO
token := transpiler_lex(lexer);
INC(symbol_count);
REALLOCATE(result^.symbols, TSIZE(Identifier) * (symbol_count + 1));
current_symbol := result^.symbols;
INC(current_symbol, TSIZE(Identifier) * (symbol_count - 1));
current_symbol^ := token.identifierKind;
token := transpiler_lex(lexer)
END;
INC(current_symbol, TSIZE(Identifier));
MemZero(current_symbol, TSIZE(Identifier));
token := transpiler_lex(lexer);
RETURN result
END parse_import_statement;
PROCEDURE parse_import_part(lexer: PLexer): PPAstImportStatement;
VAR
token: LexerToken;
import_statement: PPAstImportStatement;
result: PPAstImportStatement;
import_count: CARDINAL;
BEGIN
token := lexer_current(lexer);
ALLOCATE(result, TSIZE(PAstImportStatement));
import_statement := result;
import_count := 0;
WHILE token.kind = lexerKindFrom DO
INC(import_count);
REALLOCATE(result, TSIZE(PAstImportStatement) * (import_count + 1));
import_statement := result;
INC(import_statement, TSIZE(PAstImportStatement) * (import_count - 1));
import_statement^ := parse_import_statement(lexer);
token := lexer_current(lexer)
END;
IF import_count > 0 THEN
INC(import_statement, TSIZE(PAstImportStatement))
END;
import_statement^ := NIL;
RETURN result
END parse_import_part;
END Parser. END Parser.

View File

@ -10,11 +10,11 @@ FROM MemUtils IMPORT MemCopy, MemZero;
FROM Common IMPORT Identifier, PIdentifier, ShortString; FROM Common IMPORT Identifier, PIdentifier, ShortString;
FROM Lexer IMPORT Lexer, LexerToken, lexer_current, lexer_lex, LexerKind; FROM Lexer IMPORT Lexer, LexerToken, lexer_current, lexer_lex, LexerKind;
FROM Parser IMPORT AstModule, PAstModule, AstTypeExpressionKind, FROM Parser IMPORT AstModule, PAstModule, AstTypeExpressionKind,
AstConstantDeclaration, PPAstConstantDeclaration, PAstConstantDeclaration, PPAstConstantDeclaration,
AstTypeDeclaration, PAstTypeDeclaration, PPAstTypeDeclaration, AstTypeDeclaration, PAstTypeDeclaration, PPAstTypeDeclaration,
PAstVariableDeclaration, PPAstVariableDeclaration, PAstVariableDeclaration, PPAstVariableDeclaration, PAstImportStatement, PPAstImportStatement,
PAstTypeExpression, PPAstTypeExpression, AstFieldDeclaration, PAstFieldDeclaration, PAstTypeExpression, PPAstTypeExpression, AstFieldDeclaration, PAstFieldDeclaration,
parse_type_expression, parse_variable_part, parse_type_part; parse_type_expression, parse_variable_part, parse_type_part, parse_constant_part, parse_import_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;
@ -41,76 +41,69 @@ VAR
BEGIN 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; END write_current;
PROCEDURE transpile_import(context: PTranspilerContext); PROCEDURE transpile_import_statement(context: PTranspilerContext; import_statement: PAstImportStatement);
VAR VAR
token: LexerToken; token: LexerToken;
written_bytes: CARDINAL;
current_symbol: PIdentifier;
BEGIN BEGIN
WriteString(context^.output, 'FROM '); WriteString(context^.output, 'FROM ');
token := transpiler_lex(context^.lexer); written_bytes := WriteNBytes(context^.output, ORD(import_statement^.package[1]), ADR(import_statement^.package[2]));
write_current(context^.lexer, context^.output);
token := transpiler_lex(context^.lexer);
WriteString(context^.output, ' IMPORT '); WriteString(context^.output, ' IMPORT ');
token := transpiler_lex(context^.lexer); current_symbol := import_statement^.symbols;
write_current(context^.lexer, context^.output); written_bytes := WriteNBytes(context^.output, ORD(current_symbol^[1]), ADR(current_symbol^[2]));
INC(current_symbol, TSIZE(Identifier));
token := transpiler_lex(context^.lexer); WHILE ORD(current_symbol^[1]) <> 0 DO
WHILE token.kind <> lexerKindSemicolon DO
WriteString(context^.output, ', '); WriteString(context^.output, ', ');
token := transpiler_lex(context^.lexer); written_bytes := WriteNBytes(context^.output, ORD(current_symbol^[1]), ADR(current_symbol^[2]));
write_current(context^.lexer, context^.output); INC(current_symbol, TSIZE(Identifier))
token := transpiler_lex(context^.lexer)
END; END;
write_semicolon(context^.output); write_semicolon(context^.output)
token := transpiler_lex(context^.lexer) END transpile_import_statement;
END transpile_import; PROCEDURE transpile_import_part(context: PTranspilerContext; imports: PPAstImportStatement);
PROCEDURE transpile_import_part(context: PTranspilerContext);
VAR VAR
token: LexerToken; import_statement: PAstImportStatement;
BEGIN BEGIN
token := lexer_current(context^.lexer); WHILE imports^ <> NIL DO
transpile_import_statement(context, imports^);
WHILE token.kind = lexerKindFrom DO INC(imports, TSIZE(PAstImportStatement))
transpile_import(context);
token := lexer_current(context^.lexer)
END; END;
WriteLine(context^.output) WriteLine(context^.output)
END transpile_import_part; END transpile_import_part;
PROCEDURE transpile_constant(context: PTranspilerContext); PROCEDURE transpile_constant_declaration(context: PTranspilerContext; declaration: PAstConstantDeclaration);
VAR VAR
token: LexerToken; buffer: ARRAY[1..20] OF CHAR;
written_bytes: CARDINAL;
BEGIN BEGIN
WriteString(context^.output, ' '); WriteString(context^.output, ' ');
token := lexer_current(context^.lexer); written_bytes := WriteNBytes(context^.output, ORD(declaration^.constant_name[1]), ADR(declaration^.constant_name[2]));
write_current(context^.lexer, context^.output);
token := transpiler_lex(context^.lexer);
WriteString(context^.output, ' = '); WriteString(context^.output, ' = ');
token := transpiler_lex(context^.lexer); IntToStr(declaration^.constant_value, 0, buffer);
write_current(context^.lexer, context^.output); WriteString(context^.output, buffer);
token := transpiler_lex(context^.lexer);
write_semicolon(context^.output) write_semicolon(context^.output)
END transpile_constant; END transpile_constant_declaration;
PROCEDURE transpile_constant_part(context: PTranspilerContext): PPAstConstantDeclaration; PROCEDURE transpile_constant_part(context: PTranspilerContext; declarations: PPAstConstantDeclaration);
VAR VAR
token: LexerToken; current_declaration: PPAstConstantDeclaration;
BEGIN BEGIN
token := lexer_current(context^.lexer); IF declarations^ <> NIL THEN
IF token.kind = lexerKindConst THEN
WriteString(context^.output, 'CONST'); WriteString(context^.output, 'CONST');
WriteLine(context^.output); WriteLine(context^.output);
token := transpiler_lex(context^.lexer);
WHILE token.kind = lexerKindIdentifier DO current_declaration := declarations;
transpile_constant(context); WHILE current_declaration^ <> NIL DO
token := transpiler_lex(context^.lexer) transpile_constant_declaration(context, current_declaration^);
END
END; INC(current_declaration, TSIZE(PAstConstantDeclaration))
RETURN NIL END;
WriteLine(context^.output)
END
END transpile_constant_part; END transpile_constant_part;
PROCEDURE transpile_module(context: PTranspilerContext): PAstModule; PROCEDURE transpile_module(context: PTranspilerContext): PAstModule;
VAR VAR
@ -120,20 +113,12 @@ BEGIN
ALLOCATE(result, TSIZE(AstModule)); ALLOCATE(result, TSIZE(AstModule));
token := transpiler_lex(context^.lexer); token := transpiler_lex(context^.lexer);
IF token.kind = lexerKindDefinition THEN IF token.kind = lexerKindModule THEN
WriteString(context^.output, 'DEFINITION '); WriteString(context^.output, 'IMPLEMENTATION ')
token := transpiler_lex(context^.lexer)
END;
IF token.kind = lexerKindImplementation THEN
WriteString(context^.output, 'IMPLEMENTATION ');
token := transpiler_lex(context^.lexer)
END; END;
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. *)
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);
@ -142,9 +127,12 @@ BEGIN
(* Write the module body. *) (* Write the module body. *)
token := transpiler_lex(context^.lexer); token := transpiler_lex(context^.lexer);
transpile_import_part(context);
result^.constants := transpile_constant_part(context); result^.imports := parse_import_part(context^.lexer);
transpile_import_part(context, result^.imports);
result^.constants := parse_constant_part(context^.lexer);
transpile_constant_part(context, result^.constants);
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);
@ -590,7 +578,8 @@ VAR
seen_constants: PPAstConstantDeclaration; seen_constants: PPAstConstantDeclaration;
BEGIN BEGIN
token := transpile_procedure_heading(context); token := transpile_procedure_heading(context);
seen_constants := transpile_constant_part(context); seen_constants := parse_constant_part(context^.lexer);
transpile_constant_part(context, seen_constants);
seen_variables := parse_variable_part(context^.lexer); seen_variables := parse_variable_part(context^.lexer);
transpile_variable_part(context, seen_variables); transpile_variable_part(context, seen_variables);
@ -631,10 +620,10 @@ BEGIN
END; END;
IF last_slash = 0 THEN IF last_slash = 0 THEN
counter := 1; counter := 1
END; END;
IF last_slash <> 0 THEN IF last_slash <> 0 THEN
counter := last_slash + 1; counter := last_slash + 1
END; END;
WHILE (context^.input_name[counter] <> '.') AND (ORD(context^.input_name[counter]) <> 0) DO WHILE (context^.input_name[counter] <> '.') AND (ORD(context^.input_name[counter]) <> 0) DO
WriteChar(context^.output, context^.input_name[counter]); WriteChar(context^.output, context^.input_name[counter]);