diff --git a/Rakefile b/Rakefile index 774a3e7..8e6cff2 100644 --- a/Rakefile +++ b/Rakefile @@ -44,10 +44,12 @@ end .partition { |f| f.end_with? '.elna' } File.open t.name, 'w' do |output| - puts - puts(compiler * ' ') + compiler_command = compiler + sources - Open3.popen2(*compiler) do |cl_in, cl_out| + puts + puts(compiler_command * ' ') + + Open3.popen2(*compiler_command) do |cl_in, cl_out| cl_in.write File.read(*sources) cl_in.close @@ -104,7 +106,7 @@ task :backport do source .gsub(/^(var|type|const|begin)/) { |match| match.upcase } .gsub(/^[[:alnum:]]* ?module/) { |match| match.upcase } - .gsub(/\b(record|nil|or)\b/) { |match| match.upcase } + .gsub(/\b(record|nil|or|false|true)\b/) { |match| match.upcase } .gsub(/proc\(/, 'PROCEDURE(') .gsub(/ & /, ' AND ') .gsub(/ -> /, ': ') diff --git a/source/CommandLineInterface.def b/source/CommandLineInterface.def new file mode 100644 index 0000000..85be324 --- /dev/null +++ b/source/CommandLineInterface.def @@ -0,0 +1,15 @@ +DEFINITION MODULE CommandLineInterface; + +FROM Common IMPORT ShortString; + +TYPE + CommandLine = RECORD + input: ShortString; + lex: BOOLEAN; + parse: BOOLEAN + END; + PCommandLine = POINTER TO CommandLine; + +PROCEDURE parse_command_line(): PCommandLine; + +END CommandLineInterface. diff --git a/source/CommandLineInterface.elna b/source/CommandLineInterface.elna new file mode 100644 index 0000000..eb16b4f --- /dev/null +++ b/source/CommandLineInterface.elna @@ -0,0 +1,75 @@ +implementation module CommandLineInterface; + +from SYSTEM import ADR, TSIZE; + +from Args import GetArg, Narg; +from FIO import WriteString, WriteChar, WriteLine, StdErr; +from Storage import ALLOCATE; +from Strings import CompareStr, Length; +from MemUtils import MemZero; + +from Common import ShortString; + +proc parse_command_line() -> PCommandLine; +var + parameter: ShortString; + i: CARDINAL; + result: PCommandLine; + parsed: BOOLEAN; +begin + i := 1; + ALLOCATE(result, TSIZE(CommandLine)); + result^.lex := false; + result^.parse := false; + MemZero(ADR(result^.input), 256); + + while (i < Narg()) & (result <> nil) do + parsed := GetArg(parameter, i); + parsed := false; + + if CompareStr(parameter, '--lex') = 0 then + parsed := true; + result^.lex := true + end; + if CompareStr(parameter, '--parse') = 0 then + parsed := true; + result^.parse := true + end; + if parameter[0] <> '-' then + parsed := true; + + if Length(result^.input) > 0 then + WriteString(StdErr, 'Fatal error: only one source file can be compiled at once. First given "'); + WriteString(StdErr, result^.input); + WriteString(StdErr, '", then "'); + WriteString(StdErr, parameter); + WriteString(StdErr, '".'); + WriteLine(StdErr); + result := nil + end; + if result <> nil then + result^.input := parameter + end + end; + if parsed = false then + WriteString(StdErr, 'Fatal error: unknown command line options: '); + + WriteString(StdErr, parameter); + WriteChar(StdErr, '.'); + WriteLine(StdErr); + + result := nil + end; + + i := i + 1 + end; + if (result <> nil) & (Length(result^.input) = 0) then + WriteString(StdErr, 'Fatal error: no input files.'); + WriteLine(StdErr); + result := nil + end; + + return result +end; + +end CommandLineInterface. diff --git a/source/Common.def b/source/Common.def new file mode 100644 index 0000000..5925cbf --- /dev/null +++ b/source/Common.def @@ -0,0 +1,6 @@ +DEFINITION MODULE Common; + +TYPE + ShortString = ARRAY[0..255] OF CHAR; + +END Common. diff --git a/source/Common.elna b/source/Common.elna new file mode 100644 index 0000000..7b8d623 --- /dev/null +++ b/source/Common.elna @@ -0,0 +1,3 @@ +implementation module Common; + +end Common. diff --git a/source/Compiler.elna b/source/Compiler.elna index 4e6ea19..207e348 100644 --- a/source/Compiler.elna +++ b/source/Compiler.elna @@ -5,11 +5,15 @@ from SYSTEM import ADR; from Lexer import Lexer, lexer_destroy, lexer_initialize; from Transpiler import transpile; +from CommandLineInterface import PCommandLine, parse_command_line; var lexer: Lexer; + command_line: PCommandLine; begin + command_line := parse_command_line(); + lexer_initialize(ADR(lexer), StdIn); transpile(ADR(lexer)); diff --git a/source/Lexer.elna b/source/Lexer.elna index 902e93a..19cfd34 100644 --- a/source/Lexer.elna +++ b/source/Lexer.elna @@ -217,7 +217,7 @@ var index: CARDINAL; begin index := 0; - result := TRUE; + result := true; while (index < Length(Keyword)) & (TokenStart <> TokenEnd) & result DO result := (Keyword[index] = TokenStart^) or (Lower(Keyword[index]) = TokenStart^); @@ -409,11 +409,11 @@ begin end; if compare_keyword('TRUE', lexer^.Start, lexer^.Current) then token^.kind := lexerKindBoolean; - token^.booleanKind := TRUE + token^.booleanKind := true end; if compare_keyword('FALSE', lexer^.Start, lexer^.Current) then token^.kind := lexerKindBoolean; - token^.booleanKind := FALSE + token^.booleanKind := false end end; diff --git a/source/Parser.def b/source/Parser.def new file mode 100644 index 0000000..5b016de --- /dev/null +++ b/source/Parser.def @@ -0,0 +1,3 @@ +DEFINITION MODULE Parser; + +END Parser. diff --git a/source/Parser.elna b/source/Parser.elna new file mode 100644 index 0000000..edd30e5 --- /dev/null +++ b/source/Parser.elna @@ -0,0 +1,3 @@ +module Parser; + +end Parser. diff --git a/source/Transpiler.elna b/source/Transpiler.elna index 9820193..ec96152 100644 --- a/source/Transpiler.elna +++ b/source/Transpiler.elna @@ -441,6 +441,14 @@ begin WriteString('NIL '); written_bytes := 1 end; + if (token.kind = lexerKindBoolean) & token.booleanKind then + WriteString('TRUE '); + written_bytes := 1 + end; + if (token.kind = lexerKindBoolean) & (~token.booleanKind) then + WriteString('FALSE '); + written_bytes := 1 + end; if token.kind = lexerKindOr then WriteString('OR '); written_bytes := 1