Create a parser context

This commit is contained in:
2025-06-13 15:24:24 +02:00
parent 9341017103
commit 20b5dd027f
10 changed files with 283 additions and 248 deletions

View File

@ -45,6 +45,8 @@ end
File.open t.name, 'w' do |output| File.open t.name, 'w' do |output|
compiler_command = compiler + sources compiler_command = compiler + sources
compiler_command << '-o'
compiler_command << Pathname.new(t.name).sub_ext('.def').to_path
puts puts
puts(compiler_command * ' ') puts(compiler_command * ' ')

View File

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

View File

@ -22,6 +22,7 @@ begin
result^.lex := false; result^.lex := false;
result^.parse := false; result^.parse := false;
MemZero(ADR(result^.input), 256); MemZero(ADR(result^.input), 256);
result^.output[1] := CHAR(0);
while (i < Narg()) & (result <> nil) do while (i < Narg()) & (result <> nil) do
parsed := GetArg(parameter, i); parsed := GetArg(parameter, i);
@ -35,7 +36,20 @@ begin
parsed := true; parsed := true;
result^.parse := true result^.parse := true
end; 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] <> '-') & (parsed = false) then
parsed := true; parsed := true;
if Length(result^.input) > 0 then if Length(result^.input) > 0 then

View File

@ -1,13 +1,15 @@
program; program;
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 SYSTEM import ADR;
from M2RTS import HALT, ExitOnHalt; from M2RTS import HALT, ExitOnHalt;
from Lexer import Lexer, lexer_destroy, lexer_initialize; from Lexer import Lexer, lexer_destroy, lexer_initialize;
from Parser import Parser;
from Transpiler import transpile; from Transpiler import transpile;
from CommandLineInterface import PCommandLine, parse_command_line; from CommandLineInterface import PCommandLine, parse_command_line;
from Parser import PAstModule, parse_module; from Parser import PAstModule, parse;
from Strings import Length;
var var
command_line: PCommandLine; command_line: PCommandLine;
@ -16,6 +18,7 @@ proc compile_from_stream();
var var
lexer: Lexer; lexer: Lexer;
source_input: File; source_input: File;
source_output: File;
ast_module: PAstModule; ast_module: PAstModule;
begin begin
source_input := OpenToRead(command_line^.input); source_input := OpenToRead(command_line^.input);
@ -28,14 +31,30 @@ begin
ExitOnHalt(2) ExitOnHalt(2)
end; 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 if IsNoError(source_input) then
lexer_initialize(ADR(lexer), source_input); lexer_initialize(ADR(lexer), source_input);
ast_module := parse_module(ADR(lexer)); ast_module := parse(ADR(lexer));
transpile(ast_module, StdOut, command_line^.input); transpile(ast_module, StdOut, source_output, command_line^.input);
lexer_destroy(ADR(lexer)); lexer_destroy(ADR(lexer));
Close(source_output);
Close(source_input) Close(source_input)
end end
end; end;

View File

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

View File

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

View File

@ -195,15 +195,6 @@ TYPE
END; END;
PAstModule = POINTER TO AstModule; PAstModule = POINTER TO AstModule;
PROCEDURE parse_type_expression(lexer: PLexer): PAstTypeExpression; PROCEDURE parse(lexer: PLexer): PAstModule;
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;
END Parser. END Parser.

File diff suppressed because it is too large Load Diff

View File

@ -10,10 +10,11 @@ TYPE
TranspilerContext = RECORD TranspilerContext = RECORD
input_name: ShortString; input_name: ShortString;
output: File; output: File;
definition: File;
indentation: CARDINAL indentation: CARDINAL
END; END;
PTranspilerContext = POINTER TO TranspilerContext; 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. END Transpiler.

View File

@ -643,12 +643,13 @@ begin
end end
end; end;
proc transpile(ast_module: PAstModule, output: File, input_name: ShortString); proc transpile(ast_module: PAstModule, output: File, definition: File, input_name: ShortString);
var var
context: TranspilerContext; context: TranspilerContext;
begin begin
context.input_name := input_name; context.input_name := input_name;
context.output := output; context.output := output;
context.definition := definition;
context.indentation := 0; context.indentation := 0;
transpile_module(ADR(context), ast_module) transpile_module(ADR(context), ast_module)