Shorten the module declaration

This commit is contained in:
Eugen Wissner 2025-06-05 12:34:17 +02:00
parent 7c12fc1364
commit 3ca8491f64
Signed by: belka
GPG Key ID: A27FDC1E8EE902C0
7 changed files with 191 additions and 64 deletions

View File

@ -105,12 +105,12 @@ task :backport do
source source
.gsub(/^(var|type|const|begin)/) { |match| match.upcase } .gsub(/^(var|type|const|begin)/) { |match| match.upcase }
.gsub(/^[[:alnum:]]* ?module/) { |match| match.upcase }
.gsub(/\b(record|nil|or|false|true)\b/) { |match| match.upcase } .gsub(/\b(record|nil|or|false|true)\b/) { |match| match.upcase }
.gsub(/proc\(/, 'PROCEDURE(') .gsub(/proc\(/, 'PROCEDURE(')
.gsub(/ & /, ' AND ') .gsub(/ & /, ' AND ')
.gsub(/ -> /, ': ') .gsub(/ -> /, ': ')
.gsub(/program;/, "MODULE #{module_name};") .gsub(/program;/, "MODULE #{module_name};")
.gsub(/module;/, "IMPLEMENTATION MODULE #{module_name};")
.gsub(/end\./, "END #{module_name}.") .gsub(/end\./, "END #{module_name}.")
.gsub(/([[:space:]]*)end(;?)$/, '\1END\2') .gsub(/([[:space:]]*)end(;?)$/, '\1END\2')
.gsub(/^([[:space:]]*)(while|return|if)\b/) { |match| match.upcase } .gsub(/^([[:space:]]*)(while|return|if)\b/) { |match| match.upcase }

View File

@ -1,4 +1,4 @@
implementation module CommandLineInterface; module;
from SYSTEM import ADR, TSIZE; from SYSTEM import ADR, TSIZE;

View File

@ -1,3 +1,3 @@
implementation module Common; module;
end. end.

View File

@ -1,4 +1,4 @@
implementation module Lexer; module;
from FIO import ReadNBytes, StdErr; from FIO import ReadNBytes, StdErr;
from SYSTEM import ADR, TSIZE; from SYSTEM import ADR, TSIZE;

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

@ -1,4 +1,4 @@
implementation module Parser; module;
from SYSTEM import TSIZE; from SYSTEM import TSIZE;
@ -337,4 +337,130 @@ begin
return result return result
end; end;
proc 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;
proc 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;
proc 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;
proc 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;
end. end.

View File

@ -1,4 +1,4 @@
implementation module Transpiler; module;
from FIO import WriteNBytes, WriteLine, WriteChar, WriteString; from FIO import WriteNBytes, WriteLine, WriteChar, WriteString;
from SYSTEM import ADR, ADDRESS, TSIZE; from SYSTEM import ADR, ADDRESS, TSIZE;
@ -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. *)
proc transpiler_lex(lexer: PLexer) -> LexerToken; proc transpiler_lex(lexer: PLexer) -> LexerToken;
@ -44,79 +44,72 @@ begin
written_bytes := WriteNBytes(output, ADDRESS(lexer^.Current - lexer^.Start), lexer^.Start) written_bytes := WriteNBytes(output, ADDRESS(lexer^.Current - lexer^.Start), lexer^.Start)
end; end;
proc transpile_import(context: PTranspilerContext); proc 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; end;
proc transpile_import_part(context: PTranspilerContext); proc transpile_import_part(context: PTranspilerContext, imports: PPAstImportStatement);
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; end;
proc transpile_constant(context: PTranspilerContext); proc transpile_constant_declaration(context: PTranspilerContext, declaration: PAstConstantDeclaration);
var var
token: LexerToken; buffer: [20]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; end;
proc transpile_constant_part(context: PTranspilerContext) -> PPAstConstantDeclaration; proc 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
INC(current_declaration, TSIZE(PAstConstantDeclaration))
end; end;
return nil WriteLine(context^.output)
end
end; end;
proc transpile_module(context: PTranspilerContext) -> PAstModule; proc transpile_module(context: PTranspilerContext) -> PAstModule;
@ -127,20 +120,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);
@ -149,9 +134,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);
@ -621,7 +609,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);
@ -664,10 +653,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] <> '.') & (ORD(context^.input_name[counter]) <> 0) do while (context^.input_name[counter] <> '.') & (ORD(context^.input_name[counter]) <> 0) do
WriteChar(context^.output, context^.input_name[counter]); WriteChar(context^.output, context^.input_name[counter]);