Create a parser context
This commit is contained in:
@@ -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;
|
||||||
|
@@ -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()) AND (result <> NIL) DO
|
WHILE (i < Narg()) AND (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] <> '-') AND (parsed = FALSE) THEN
|
||||||
parsed := TRUE;
|
parsed := TRUE;
|
||||||
|
|
||||||
IF Length(result^.input) > 0 THEN
|
IF Length(result^.input) > 0 THEN
|
||||||
|
@@ -1,13 +1,15 @@
|
|||||||
MODULE Compiler;
|
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 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 @@ PROCEDURE 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 compile_from_stream;
|
END compile_from_stream;
|
||||||
|
@@ -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,
|
||||||
|
@@ -346,68 +346,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
|
|
||||||
token^.kind := lexerKindAnd
|
|
||||||
END;
|
|
||||||
IF compare_keyword('OR', lexer^.start, lexer^.current.iterator) THEN
|
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
|
||||||
@@ -421,11 +418,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
|
||||||
|
@@ -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
@@ -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.
|
||||||
|
@@ -610,12 +610,13 @@ BEGIN
|
|||||||
INC(counter)
|
INC(counter)
|
||||||
END
|
END
|
||||||
END transpile_module_name;
|
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
|
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)
|
||||||
|
Reference in New Issue
Block a user