Create a parser context

This commit is contained in:
2025-06-13 15:23:59 +02:00
parent fdaeb25f73
commit fac024d1f3
9 changed files with 278 additions and 246 deletions

View File

@ -5,6 +5,7 @@ FROM Common IMPORT ShortString;
TYPE
CommandLine = RECORD
input: ShortString;
output: ShortString;
lex: BOOLEAN;
parse: BOOLEAN
END;

View File

@ -22,6 +22,7 @@ BEGIN
result^.lex := FALSE;
result^.parse := FALSE;
MemZero(ADR(result^.input), 256);
result^.output[1] := CHAR(0);
WHILE (i < Narg()) AND (result <> NIL) DO
parsed := GetArg(parameter, i);
@ -35,7 +36,20 @@ BEGIN
parsed := TRUE;
result^.parse := TRUE
END;
IF parameter[1] <> '-' THEN
IF CompareStr(parameter, '-o') = 0 THEN
INC(i);
IF i = Narg() THEN
WriteString(StdErr, 'Fatal error: expecting a file name following -o.');
result := NIL
END;
IF i < Narg() THEN
parsed := GetArg(parameter, i);
result^.output := parameter
END;
parsed := TRUE
END;
IF (parameter[1] <> '-') AND (parsed = FALSE) THEN
parsed := TRUE;
IF Length(result^.input) > 0 THEN

View File

@ -1,13 +1,15 @@
MODULE Compiler;
FROM FIO IMPORT Close, IsNoError, File, OpenToRead, StdErr, StdOut, WriteLine, WriteString;
FROM FIO IMPORT Close, IsNoError, File, OpenToRead, OpenToWrite, StdErr, StdOut, WriteLine, WriteString;
FROM SYSTEM IMPORT ADR;
FROM M2RTS IMPORT HALT, ExitOnHalt;
FROM Lexer IMPORT Lexer, lexer_destroy, lexer_initialize;
FROM Parser IMPORT Parser;
FROM Transpiler IMPORT transpile;
FROM CommandLineInterface IMPORT PCommandLine, parse_command_line;
FROM Parser IMPORT PAstModule, parse_module;
FROM Parser IMPORT PAstModule, parse;
FROM Strings IMPORT Length;
VAR
command_line: PCommandLine;
@ -16,6 +18,7 @@ PROCEDURE compile_from_stream();
VAR
lexer: Lexer;
source_input: File;
source_output: File;
ast_module: PAstModule;
BEGIN
source_input := OpenToRead(command_line^.input);
@ -28,14 +31,30 @@ BEGIN
ExitOnHalt(2)
END;
source_output := NIL;
IF Length(command_line^.output) > 0 THEN
source_output := OpenToWrite(command_line^.output);
IF IsNoError(source_output) = FALSE THEN
WriteString(StdErr, 'Fatal error: failed to create the output file "');
WriteString(StdErr, command_line^.output);
WriteString(StdErr, '".');
WriteLine(StdErr);
ExitOnHalt(2)
END
END;
IF IsNoError(source_input) THEN
lexer_initialize(ADR(lexer), source_input);
ast_module := parse_module(ADR(lexer));
transpile(ast_module, StdOut, command_line^.input);
ast_module := parse(ADR(lexer));
transpile(ast_module, StdOut, source_output, command_line^.input);
lexer_destroy(ADR(lexer));
Close(source_output);
Close(source_input)
END
END compile_from_stream;

View File

@ -32,7 +32,7 @@ TYPE
lexerKindProc,
lexerKindBegin,
lexerKindEnd,
lexerKindImplementation,
lexerKindXor,
lexerKindConst,
lexerKindVar,
lexerKindCase,
@ -48,7 +48,7 @@ TYPE
lexerKindOr,
lexerKindTilde,
lexerKindReturn,
lexerKindDefinition,
lexerKindDefer,
lexerKindRange,
lexerKindLeftParen,
lexerKindRightParen,

View File

@ -346,68 +346,65 @@ BEGIN
DEC(token^.identifierKind[1], lexer^.start.iterator);
MemCopy(lexer^.start.iterator, ORD(token^.identifierKind[1]), ADR(token^.identifierKind[2]));
IF compare_keyword('PROGRAM', lexer^.start, lexer^.current.iterator) THEN
IF compare_keyword('program', lexer^.start, lexer^.current.iterator) THEN
token^.kind := lexerKindProgram
END;
IF compare_keyword('IMPORT', lexer^.start, lexer^.current.iterator) THEN
IF compare_keyword('import', lexer^.start, lexer^.current.iterator) THEN
token^.kind := lexerKindImport
END;
IF compare_keyword('CONST', lexer^.start, lexer^.current.iterator) THEN
IF compare_keyword('const', lexer^.start, lexer^.current.iterator) THEN
token^.kind := lexerKindConst
END;
IF compare_keyword('VAR', lexer^.start, lexer^.current.iterator) THEN
IF compare_keyword('var', lexer^.start, lexer^.current.iterator) THEN
token^.kind := lexerKindVar
END;
IF compare_keyword('IF', lexer^.start, lexer^.current.iterator) THEN
IF compare_keyword('if', lexer^.start, lexer^.current.iterator) THEN
token^.kind := lexerKindIf
END;
IF compare_keyword('THEN', lexer^.start, lexer^.current.iterator) THEN
IF compare_keyword('then', lexer^.start, lexer^.current.iterator) THEN
token^.kind := lexerKindThen
END;
IF compare_keyword('ELSIF', lexer^.start, lexer^.current.iterator) THEN
IF compare_keyword('elsif', lexer^.start, lexer^.current.iterator) THEN
token^.kind := lexerKindElsif
END;
IF compare_keyword('ELSE', lexer^.start, lexer^.current.iterator) THEN
IF compare_keyword('else', lexer^.start, lexer^.current.iterator) THEN
token^.kind := lexerKindElse
END;
IF compare_keyword('WHILE', lexer^.start, lexer^.current.iterator) THEN
IF compare_keyword('while', lexer^.start, lexer^.current.iterator) THEN
token^.kind := lexerKindWhile
END;
IF compare_keyword('DO', lexer^.start, lexer^.current.iterator) THEN
IF compare_keyword('do', lexer^.start, lexer^.current.iterator) THEN
token^.kind := lexerKindDo
END;
IF compare_keyword('proc', lexer^.start, lexer^.current.iterator) THEN
token^.kind := lexerKindProc
END;
IF compare_keyword('BEGIN', lexer^.start, lexer^.current.iterator) THEN
IF compare_keyword('begin', lexer^.start, lexer^.current.iterator) THEN
token^.kind := lexerKindBegin
END;
IF compare_keyword('END', lexer^.start, lexer^.current.iterator) THEN
IF compare_keyword('end', lexer^.start, lexer^.current.iterator) THEN
token^.kind := lexerKindEnd
END;
IF compare_keyword('TYPE', lexer^.start, lexer^.current.iterator) THEN
IF compare_keyword('type', lexer^.start, lexer^.current.iterator) THEN
token^.kind := lexerKindType
END;
IF compare_keyword('RECORD', lexer^.start, lexer^.current.iterator) THEN
token^.kind := lexerKindRecord
END;
IF compare_keyword('UNION', lexer^.start, lexer^.current.iterator) THEN
IF compare_keyword('union', lexer^.start, lexer^.current.iterator) THEN
token^.kind := lexerKindUnion
END;
IF compare_keyword('NIL', lexer^.start, lexer^.current.iterator) THEN
token^.kind := lexerKindNull
END;
IF compare_keyword('AND', lexer^.start, lexer^.current.iterator) THEN
token^.kind := lexerKindAnd
END;
IF compare_keyword('OR', lexer^.start, lexer^.current.iterator) THEN
token^.kind := lexerKindOr
END;
IF compare_keyword('RETURN', lexer^.start, lexer^.current.iterator) THEN
IF compare_keyword('return', lexer^.start, lexer^.current.iterator) THEN
token^.kind := lexerKindReturn
END;
IF compare_keyword('DEFINITION', lexer^.start, lexer^.current.iterator) THEN
token^.kind := lexerKindDefinition
IF compare_keyword('defer', lexer^.start, lexer^.current.iterator) THEN
token^.kind := lexerKindDefer
END;
IF compare_keyword('TO', lexer^.start, lexer^.current.iterator) THEN
token^.kind := lexerKindTo
@ -421,11 +418,11 @@ BEGIN
IF compare_keyword('FROM', lexer^.start, lexer^.current.iterator) THEN
token^.kind := lexerKindFrom
END;
IF compare_keyword('MODULE', lexer^.start, lexer^.current.iterator) THEN
IF compare_keyword('module', lexer^.start, lexer^.current.iterator) THEN
token^.kind := lexerKindModule
END;
IF compare_keyword('IMPLEMENTATION', lexer^.start, lexer^.current.iterator) THEN
token^.kind := lexerKindImplementation
IF compare_keyword('xor', lexer^.start, lexer^.current.iterator) THEN
token^.kind := lexerKindXor
END;
IF compare_keyword('POINTER', lexer^.start, lexer^.current.iterator) THEN
token^.kind := lexerKindPointer

View File

@ -195,15 +195,6 @@ TYPE
END;
PAstModule = POINTER TO AstModule;
PROCEDURE parse_type_expression(lexer: PLexer): PAstTypeExpression;
PROCEDURE parse_type_part(lexer: PLexer): PPAstTypedDeclaration;
PROCEDURE parse_variable_part(lexer: PLexer): PPAstVariableDeclaration;
PROCEDURE parse_constant_part(lexer: PLexer): PPAstConstantDeclaration;
PROCEDURE parse_import_part(lexer: PLexer): PPAstImportStatement;
PROCEDURE parse_designator(lexer: PLexer): PAstExpression;
PROCEDURE parse_expression(lexer: PLexer): PAstExpression;
PROCEDURE parse_statement_part(lexer: PLexer): AstCompoundStatement;
PROCEDURE parse_procedure_part(lexer: PLexer): PPAstProcedureDeclaration;
PROCEDURE parse_module(lexer: PLexer): PAstModule;
PROCEDURE parse(lexer: PLexer): PAstModule;
END Parser.

File diff suppressed because it is too large Load Diff

View File

@ -10,10 +10,11 @@ TYPE
TranspilerContext = RECORD
input_name: ShortString;
output: File;
definition: File;
indentation: CARDINAL
END;
PTranspilerContext = POINTER TO TranspilerContext;
PROCEDURE transpile(ast_module: PAstModule; output: File; input_name: ShortString);
PROCEDURE transpile(ast_module: PAstModule; output: File; definition: File; input_name: ShortString);
END Transpiler.

View File

@ -610,12 +610,13 @@ BEGIN
INC(counter)
END
END transpile_module_name;
PROCEDURE transpile(ast_module: PAstModule; output: File; input_name: ShortString);
PROCEDURE transpile(ast_module: PAstModule; output: File; definition: File; input_name: ShortString);
VAR
context: TranspilerContext;
BEGIN
context.input_name := input_name;
context.output := output;
context.definition := definition;
context.indentation := 0;
transpile_module(ADR(context), ast_module)