From 5146ea61b9a217ace1bca75a072f0dfa26e2de65 Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Sun, 10 Aug 2025 23:43:09 +0300 Subject: [PATCH] Add an empty cstdlib.elna source file --- source/CommandLineInterface.elna | 54 ++-- source/Compiler.elna | 74 ------ source/Lexer.elna | 385 ++++++++++++++-------------- source/Parser.elna | 14 +- source/Transpiler.elna | 129 +++++----- source/cctype.elna | 11 + source/{Common.elna => common.elna} | 2 - source/cstdio.elna | 23 ++ source/cstdlib.elna | 13 + source/cstring.elna | 15 ++ source/main.elna | 57 +--- 11 files changed, 360 insertions(+), 417 deletions(-) delete mode 100644 source/Compiler.elna create mode 100644 source/cctype.elna rename source/{Common.elna => common.elna} (86%) create mode 100644 source/cstdio.elna create mode 100644 source/cstdlib.elna create mode 100644 source/cstring.elna diff --git a/source/CommandLineInterface.elna b/source/CommandLineInterface.elna index feca658..8ea92e5 100644 --- a/source/CommandLineInterface.elna +++ b/source/CommandLineInterface.elna @@ -3,24 +3,20 @@ obtain one at https://mozilla.org/MPL/2.0/. *) module; -from Args import GetArg, Narg; from FIO import WriteString, WriteChar, WriteLine, StdErr; -from Strings import CompareStr, Length; -from MemUtils import MemZero; - -from Common import ShortString; +import cstdlib, common; type CommandLine = record - input: ShortString; - output: ShortString; + input: ^Char; + output: ^Char; lex: Bool; parse: Bool end; -proc parse_command_line*() -> ^CommandLine; +proc parse_command_line*(argc: Int, argv: ^^Char) -> ^CommandLine; var - parameter: ShortString; + parameter: ^Char; i: Word; result: ^CommandLine; parsed: Bool; @@ -29,43 +25,43 @@ begin NEW(result); result^.lex := false; result^.parse := false; - MemZero(@result^.input, 256); + memset(@result^.input, 0, 256); result^.output[1] := CHAR(0); - while (i < Narg()) & (result <> nil) do - parsed := GetArg(parameter, i); + while i < argc & result <> nil do + parameter := (argv + i)^; parsed := false; - if CompareStr(parameter, '--lex') = 0 then + if strcmp(parameter, "--lex\0".ptr) = 0 then parsed := true; result^.lex := true end; - if CompareStr(parameter, '--parse') = 0 then + if strcmp(parameter, "--parse\0".ptr) = 0 then parsed := true; result^.parse := true end; - if CompareStr(parameter, '-o') = 0 then + if strcmp(parameter, "-o\0".ptr) = 0 then i := i + 1u; - if i = Narg() then - WriteString(StdErr, 'Fatal error: expecting a file name following -o.'); + if i = argc then + WriteString(StdErr, "Fatal error: expecting a file name following -o."); result := nil end; - if i < Narg() then - parsed := GetArg(parameter, i); + if i < argc then + parameter := (argv + i)^; result^.output := parameter end; parsed := true end; - if (parameter[1] <> '-') & (parsed = false) then + if (parameter[1] <> '-') & ~parsed then parsed := true; - if Length(result^.input) > 0 then - WriteString(StdErr, 'Fatal error: only one source file can be compiled at once. First given "'); + if result^.input <> nil 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, "\", then \""); WriteString(StdErr, parameter); - WriteString(StdErr, '".'); + WriteString(StdErr, "\"."); WriteLine(StdErr); result := nil end; @@ -73,8 +69,8 @@ begin result^.input := parameter end end; - if parsed = false then - WriteString(StdErr, 'Fatal error: unknown command line options: '); + if ~parsed then + WriteString(StdErr, "Fatal error: unknown command line options: "); WriteString(StdErr, parameter); WriteChar(StdErr, '.'); @@ -83,10 +79,10 @@ begin result := nil end; - i := i + 1 + i := i + 1u end; - if (result <> nil) & (Length(result^.input) = 0) then - WriteString(StdErr, 'Fatal error: no input files.'); + if result <> nil & result^.input = nil then + WriteString(StdErr, "Fatal error: no input files."); WriteLine(StdErr); result := nil end; diff --git a/source/Compiler.elna b/source/Compiler.elna deleted file mode 100644 index 8e410f0..0000000 --- a/source/Compiler.elna +++ /dev/null @@ -1,74 +0,0 @@ -(* This Source Code Form is subject to the terms of the Mozilla Public License, - v. 2.0. If a copy of the MPL was not distributed with this file, You can - obtain one at https://mozilla.org/MPL/2.0/. *) -program; - -from FIO import Close, IsNoError, File, OpenToRead, OpenToWrite, StdErr, StdOut, WriteLine, WriteString; -from M2RTS import HALT, ExitOnHalt; - -from Lexer import Lexer, lexer_destroy, lexer_initialize; -from Transpiler import transpile; -from CommandLineInterface import CommandLine, parse_command_line; -from Parser import AstModule, parse; -from Strings import Length; - -var - command_line: ^CommandLine; - -proc compile_from_stream(); -var - lexer: Lexer; - source_input: File; - source_output: File; - ast_module: ^AstModule; -begin - source_input := OpenToRead(command_line^.input); - - if IsNoError(source_input) = false then - WriteString(StdErr, 'Fatal error: failed to read the input file "'); - WriteString(StdErr, command_line^.input); - WriteString(StdErr, '".'); - WriteLine(StdErr); - - 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(@lexer, source_input); - - ast_module := parse(@lexer); - transpile(ast_module, StdOut, source_output, command_line^.input); - - lexer_destroy(@lexer); - - Close(source_output); - Close(source_input) - end -end; - -begin - ExitOnHalt(0); - command_line := parse_command_line(); - - if command_line <> nil then - compile_from_stream() - end; - if command_line = nil then - ExitOnHalt(1) - end; - HALT() -end. diff --git a/source/Lexer.elna b/source/Lexer.elna index 219502e..183ef1f 100644 --- a/source/Lexer.elna +++ b/source/Lexer.elna @@ -3,7 +3,7 @@ obtain one at https://mozilla.org/MPL/2.0/. *) module; -import Common, cstdlib; +import cstdio, cstring, common; const CHUNK_SIZE := 85536; @@ -11,10 +11,10 @@ const type (* * Classification table assigns each possible character to a group (class). All - * characters of the same group a handled equivalently. - * - * Classification: - *) + * characters of the same group a handled equivalently. + * + * Classification: + *) TransitionClass = ( invalid, digit, @@ -63,7 +63,7 @@ type booleanKind: Bool; identifierKind: Identifier; integerKind: Int; - stringKind: ShortString + stringKind: String end; start_location: TextLocation; end_location: TextLocation @@ -293,7 +293,7 @@ begin i := 129u; while i <= 256u do classification[i] := TransitionClass.other; - i := i + 1 + i := i + 1u end end; @@ -392,7 +392,7 @@ proc transition_action_skip(lexer: ^Lexer, token: ^LexerToken); begin increment(@lexer^.start); - if ORD(lexer^.start.iterator^) = 10 then + if lexer^.start.iterator^ = '\n' then lexer^.start.location.line := lexer^.start.location.line + 1u; lexer^.start.location.column := 1u end; @@ -402,24 +402,24 @@ end; (* Delimited string action. *) proc transition_action_delimited(lexer: ^Lexer, token: ^LexerToken); var - text_length: Int; + text_length: Word; begin if lexer^.start.iterator^ = '(' then token^.kind := LexerKind.comment end; if lexer^.start.iterator^ = '"' then - text_length := lexer^.current.iterator - lexer^.start.iterator + 1; + text_length := cast(lexer^.current.iterator - lexer^.start.iterator + 1: Word); - MemZero(@token^.stringKind, #size(ShortString)); - MemCopy(lexer^.start.iterator, text_length, @token^.stringKind); + token^.stringKind := String(malloc(text_length), text_length); + memcpy(@token^.stringKind.ptr, lexer^.start.iterator, text_length); token^.kind := LexerKind.character end; if lexer^.start.iterator^ = "'" then - text_length := lexer^.current.iterator - lexer^.start.iterator + 1; + text_length := cast(lexer^.current.iterator - lexer^.start.iterator + 1: Word); - MemZero(@token^.stringKind, #size(ShortString)); - MemCopy(lexer^.start.iterator, text_length, @token^.stringKind); + token^.stringKind := String(malloc(text_length), text_length); + memcpy(@token^.stringKind.ptr, lexer^.start.iterator, text_length); token^.kind := LexerKind.string end; @@ -432,7 +432,7 @@ begin token^.kind := LexerKind.identifier; token^.identifierKind[1] := cast(lexer^.current.iterator - lexer^.start.iterator: Char); - MemCopy(lexer^.start.iterator, ORD(token^.identifierKind[1]), @token^.identifierKind[2]); + memcpy(@token^.identifierKind[2], lexer^.start.iterator, ORD(token^.identifierKind[1])); if compare_keyword("program", lexer^.start, lexer^.current.iterator) then token^.kind := LexerKind._program @@ -590,43 +590,47 @@ begin token^.kind := LexerKind.integer; integer_length := lexer^.current.iterator - lexer^.start.iterator; - MemZero(@token^.identifierKind, #size(Identifier)); - MemCopy(lexer^.start.iterator, integer_length, @token^.identifierKind[1]); + memset(@token^.identifierKind, 0, #size(Identifier)); + memcpy(@token^.identifierKind[1], lexer^.start.iterator, integer_length); buffer := InitStringCharStar(@token^.identifierKind[1]); token^.integerKind := StringToInteger(buffer, 10, found); buffer := KillString(buffer) end; -proc set_default_transition(current_state: TransitionState, default_action: TransitionAction, next_state: TransitionState); +proc set_default_transition(current_state: TransitionState, default_action: TransitionAction, next_state: TransitionState) -> Int; var default_transition: Transition; + state_index: Int; begin default_transition.action := default_action; default_transition.next_state := next_state; + state_index := cast(current_state: Int) + 1; - transitions[ORD(current_state) + 1][ORD(TransitionClass.invalid) + 1] := default_transition; - transitions[ORD(current_state) + 1][ORD(TransitionClass.digit) + 1] := default_transition; - transitions[ORD(current_state) + 1][ORD(TransitionClass.alpha) + 1] := default_transition; - transitions[ORD(current_state) + 1][ORD(TransitionClass.space) + 1] := default_transition; - transitions[ORD(current_state) + 1][ORD(TransitionClass.colon) + 1] := default_transition; - transitions[ORD(current_state) + 1][ORD(TransitionClass.equals) + 1] := default_transition; - transitions[ORD(current_state) + 1][ORD(TransitionClass.left_paren) + 1] := default_transition; - transitions[ORD(current_state) + 1][ORD(TransitionClass.right_paren) + 1] := default_transition; - transitions[ORD(current_state) + 1][ORD(TransitionClass.asterisk) + 1] := default_transition; - transitions[ORD(current_state) + 1][ORD(TransitionClass.underscore) + 1] := default_transition; - transitions[ORD(current_state) + 1][ORD(TransitionClass.single) + 1] := default_transition; - transitions[ORD(current_state) + 1][ORD(TransitionClass.hex) + 1] := default_transition; - transitions[ORD(current_state) + 1][ORD(TransitionClass.zero) + 1] := default_transition; - transitions[ORD(current_state) + 1][ORD(TransitionClass.x) + 1] := default_transition; - transitions[ORD(current_state) + 1][ORD(TransitionClass.eof) + 1] := default_transition; - transitions[ORD(current_state) + 1][ORD(TransitionClass.dot) + 1] := default_transition; - transitions[ORD(current_state) + 1][ORD(TransitionClass.minus) + 1] := default_transition; - transitions[ORD(current_state) + 1][ORD(TransitionClass.single_quote) + 1] := default_transition; - transitions[ORD(current_state) + 1][ORD(TransitionClass.double_quote) + 1] := default_transition; - transitions[ORD(current_state) + 1][ORD(TransitionClass.greater) + 1] := default_transition; - transitions[ORD(current_state) + 1][ORD(TransitionClass.less) + 1] := default_transition; - transitions[ORD(current_state) + 1][ORD(TransitionClass.other) + 1] := default_transition + transitions[state_index][cast(TransitionClass.invalid: Int) + 1] := default_transition; + transitions[state_index][cast(TransitionClass.digit: Int) + 1] := default_transition; + transitions[state_index][cast(TransitionClass.alpha: Int) + 1] := default_transition; + transitions[state_index][cast(TransitionClass.space: Int) + 1] := default_transition; + transitions[state_index][cast(TransitionClass.colon: Int) + 1] := default_transition; + transitions[state_index][cast(TransitionClass.equals: Int) + 1] := default_transition; + transitions[state_index][cast(TransitionClass.left_paren: Int) + 1] := default_transition; + transitions[state_index][cast(TransitionClass.right_paren: Int) + 1] := default_transition; + transitions[state_index][cast(TransitionClass.asterisk: Int) + 1] := default_transition; + transitions[state_index][cast(TransitionClass.underscore: Int) + 1] := default_transition; + transitions[state_index][cast(TransitionClass.single: Int) + 1] := default_transition; + transitions[state_index][cast(TransitionClass.hex: Int) + 1] := default_transition; + transitions[state_index][cast(TransitionClass.zero: Int) + 1] := default_transition; + transitions[state_index][cast(TransitionClass.x: Int) + 1] := default_transition; + transitions[state_index][cast(TransitionClass.eof: Int) + 1] := default_transition; + transitions[state_index][cast(TransitionClass.dot: Int) + 1] := default_transition; + transitions[state_index][cast(TransitionClass.minus: Int) + 1] := default_transition; + transitions[state_index][cast(TransitionClass.single_quote: Int) + 1] := default_transition; + transitions[state_index][cast(TransitionClass.double_quote: Int) + 1] := default_transition; + transitions[state_index][cast(TransitionClass.greater: Int) + 1] := default_transition; + transitions[state_index][cast(TransitionClass.less: Int) + 1] := default_transition; + transitions[state_index][cast(TransitionClass.other: Int) + 1] := default_transition; + + return state_index end; (* @@ -646,241 +650,245 @@ end; * handles each action. *) proc initialize_transitions(); +var + state_index: Int; begin (* Start state. *) - transitions[ORD(TransitionState.start) + 1][ORD(TransitionClass.invalid) + 1].action := nil; - transitions[ORD(TransitionState.start) + 1][ORD(TransitionClass.invalid) + 1].next_state := TransitionState.finish; + state_index := cast(TransitionState.start: Int) + 1; - transitions[ORD(TransitionState.start) + 1][ORD(TransitionClass.digit) + 1].action := transition_action_accumulate; - transitions[ORD(TransitionState.start) + 1][ORD(TransitionClass.digit) + 1].next_state := TransitionState.decimal; + transitions[state_index][cast(TransitionClass.invalid: Int) + 1].action := nil; + transitions[state_index][cast(TransitionClass.invalid: Int) + 1].next_state := TransitionState.finish; - transitions[ORD(TransitionState.start) + 1][ORD(TransitionClass.alpha) + 1].action := transition_action_accumulate; - transitions[ORD(TransitionState.start) + 1][ORD(TransitionClass.alpha) + 1].next_state := TransitionState.identifier; + transitions[state_index][cast(TransitionClass.digit: Int) + 1].action := transition_action_accumulate; + transitions[state_index][cast(TransitionClass.digit: Int) + 1].next_state := TransitionState.decimal; - transitions[ORD(TransitionState.start) + 1][ORD(TransitionClass.space) + 1].action := transition_action_skip; - transitions[ORD(TransitionState.start) + 1][ORD(TransitionClass.space) + 1].next_state := TransitionState.start; + transitions[state_index][cast(TransitionClass.alpha: Int) + 1].action := transition_action_accumulate; + transitions[state_index][cast(TransitionClass.alpha: Int) + 1].next_state := TransitionState.identifier; - transitions[ORD(TransitionState.start) + 1][ORD(TransitionClass.colon) + 1].action := transition_action_accumulate; - transitions[ORD(TransitionState.start) + 1][ORD(TransitionClass.colon) + 1].next_state := TransitionState.colon; + transitions[state_index][cast(TransitionClass.space: Int) + 1].action := transition_action_skip; + transitions[state_index][cast(TransitionClass.space: Int) + 1].next_state := TransitionState.start; - transitions[ORD(TransitionState.start) + 1][ORD(TransitionClass.equals) + 1].action := transition_action_single; - transitions[ORD(TransitionState.start) + 1][ORD(TransitionClass.equals) + 1].next_state := TransitionState.finish; + transitions[state_index][cast(TransitionClass.colon: Int) + 1].action := transition_action_accumulate; + transitions[state_index][cast(TransitionClass.colon: Int) + 1].next_state := TransitionState.colon; - transitions[ORD(TransitionState.start) + 1][ORD(TransitionClass.left_paren) + 1].action := transition_action_accumulate; - transitions[ORD(TransitionState.start) + 1][ORD(TransitionClass.left_paren) + 1].next_state := TransitionState.left_paren; + transitions[state_index][cast(TransitionClass.equals: Int) + 1].action := transition_action_single; + transitions[state_index][cast(TransitionClass.equals: Int) + 1].next_state := TransitionState.finish; - transitions[ORD(TransitionState.start) + 1][ORD(TransitionClass.right_paren) + 1].action := transition_action_single; - transitions[ORD(TransitionState.start) + 1][ORD(TransitionClass.right_paren) + 1].next_state := TransitionState.finish; + transitions[state_index][cast(TransitionClass.left_paren: Int) + 1].action := transition_action_accumulate; + transitions[state_index][cast(TransitionClass.left_paren: Int) + 1].next_state := TransitionState.left_paren; - transitions[ORD(TransitionState.start) + 1][ORD(TransitionClass.asterisk) + 1].action := transition_action_single; - transitions[ORD(TransitionState.start) + 1][ORD(TransitionClass.asterisk) + 1].next_state := TransitionState.finish; + transitions[state_index][cast(TransitionClass.right_paren: Int) + 1].action := transition_action_single; + transitions[state_index][cast(TransitionClass.right_paren: Int) + 1].next_state := TransitionState.finish; - transitions[ORD(TransitionState.start) + 1][ORD(TransitionClass.underscore) + 1].action := transition_action_accumulate; - transitions[ORD(TransitionState.start) + 1][ORD(TransitionClass.underscore) + 1].next_state := TransitionState.identifier; + transitions[state_index][cast(TransitionClass.asterisk: Int) + 1].action := transition_action_single; + transitions[state_index][cast(TransitionClass.asterisk: Int) + 1].next_state := TransitionState.finish; - transitions[ORD(TransitionState.start) + 1][ORD(TransitionClass.single) + 1].action := transition_action_single; - transitions[ORD(TransitionState.start) + 1][ORD(TransitionClass.single) + 1].next_state := TransitionState.finish; + transitions[state_index][cast(TransitionClass.underscore: Int) + 1].action := transition_action_accumulate; + transitions[state_index][cast(TransitionClass.underscore: Int) + 1].next_state := TransitionState.identifier; - transitions[ORD(TransitionState.start) + 1][ORD(TransitionClass.hex) + 1].action := transition_action_accumulate; - transitions[ORD(TransitionState.start) + 1][ORD(TransitionClass.hex) + 1].next_state := TransitionState.identifier; + transitions[state_index][cast(TransitionClass.single: Int) + 1].action := transition_action_single; + transitions[state_index][cast(TransitionClass.single: Int) + 1].next_state := TransitionState.finish; - transitions[ORD(TransitionState.start) + 1][ORD(TransitionClass.zero) + 1].action := transition_action_accumulate; - transitions[ORD(TransitionState.start) + 1][ORD(TransitionClass.zero) + 1].next_state := TransitionState.leading_zero; + transitions[state_index][cast(TransitionClass.hex: Int) + 1].action := transition_action_accumulate; + transitions[state_index][cast(TransitionClass.hex: Int) + 1].next_state := TransitionState.identifier; - transitions[ORD(TransitionState.start) + 1][ORD(TransitionClass.x) + 1].action := transition_action_accumulate; - transitions[ORD(TransitionState.start) + 1][ORD(TransitionClass.x) + 1].next_state := TransitionState.identifier; + transitions[state_index][cast(TransitionClass.zero: Int) + 1].action := transition_action_accumulate; + transitions[state_index][cast(TransitionClass.zero: Int) + 1].next_state := TransitionState.leading_zero; - transitions[ORD(TransitionState.start) + 1][ORD(TransitionClass.eof) + 1].action := transition_action_eof; - transitions[ORD(TransitionState.start) + 1][ORD(TransitionClass.eof) + 1].next_state := TransitionState.finish; + transitions[state_index][cast(TransitionClass.x: Int) + 1].action := transition_action_accumulate; + transitions[state_index][cast(TransitionClass.x: Int) + 1].next_state := TransitionState.identifier; - transitions[ORD(TransitionState.start) + 1][ORD(TransitionClass.dot) + 1].action := transition_action_accumulate; - transitions[ORD(TransitionState.start) + 1][ORD(TransitionClass.dot) + 1].next_state := TransitionState.dot; + transitions[state_index][cast(TransitionClass.eof: Int) + 1].action := transition_action_eof; + transitions[state_index][cast(TransitionClass.eof: Int) + 1].next_state := TransitionState.finish; - transitions[ORD(TransitionState.start) + 1][ORD(TransitionClass.minus) + 1].action := transition_action_accumulate; - transitions[ORD(TransitionState.start) + 1][ORD(TransitionClass.minus) + 1].next_state := TransitionState.minus; + transitions[state_index][cast(TransitionClass.dot: Int) + 1].action := transition_action_accumulate; + transitions[state_index][cast(TransitionClass.dot: Int) + 1].next_state := TransitionState.dot; - transitions[ORD(TransitionState.start) + 1][ORD(TransitionClass.single_quote) + 1].action := transition_action_accumulate; - transitions[ORD(TransitionState.start) + 1][ORD(TransitionClass.single_quote) + 1].next_state := TransitionState.character; + transitions[state_index][cast(TransitionClass.minus: Int) + 1].action := transition_action_accumulate; + transitions[state_index][cast(TransitionClass.minus: Int) + 1].next_state := TransitionState.minus; - transitions[ORD(TransitionState.start) + 1][ORD(TransitionClass.double_quote) + 1].action := transition_action_accumulate; - transitions[ORD(TransitionState.start) + 1][ORD(TransitionClass.double_quote) + 1].next_state := TransitionState.string; + transitions[state_index][cast(TransitionClass.single_quote: Int) + 1].action := transition_action_accumulate; + transitions[state_index][cast(TransitionClass.single_quote: Int) + 1].next_state := TransitionState.character; - transitions[ORD(TransitionState.start) + 1][ORD(TransitionClass.greater) + 1].action := transition_action_accumulate; - transitions[ORD(TransitionState.start) + 1][ORD(TransitionClass.greater) + 1].next_state := TransitionState.greater; + transitions[state_index][cast(TransitionClass.double_quote: Int) + 1].action := transition_action_accumulate; + transitions[state_index][cast(TransitionClass.double_quote: Int) + 1].next_state := TransitionState.string; - transitions[ORD(TransitionState.start) + 1][ORD(TransitionClass.less) + 1].action := transition_action_accumulate; - transitions[ORD(TransitionState.start) + 1][ORD(TransitionClass.less) + 1].next_state := TransitionState.less; + transitions[state_index][cast(TransitionClass.greater: Int) + 1].action := transition_action_accumulate; + transitions[state_index][cast(TransitionClass.greater: Int) + 1].next_state := TransitionState.greater; - transitions[ORD(TransitionState.start) + 1][ORD(TransitionClass.other) + 1].action := nil; - transitions[ORD(TransitionState.start) + 1][ORD(TransitionClass.other) + 1].next_state := TransitionState.finish; + transitions[state_index][cast(TransitionClass.less: Int) + 1].action := transition_action_accumulate; + transitions[state_index][cast(TransitionClass.less: Int) + 1].next_state := TransitionState.less; + + transitions[state_index][cast(TransitionClass.other: Int) + 1].action := nil; + transitions[state_index][cast(TransitionClass.other: Int) + 1].next_state := TransitionState.finish; (* Colon state. *) - set_default_transition(TransitionState.colon, transition_action_finalize, TransitionState.finish); + state_index := set_default_transition(TransitionState.colon, transition_action_finalize, TransitionState.finish); - transitions[ORD(TransitionState.colon) + 1][ORD(TransitionClass.equals) + 1].action := transition_action_composite; - transitions[ORD(TransitionState.colon) + 1][ORD(TransitionClass.equals) + 1].next_state := TransitionState.finish; + transitions[state_index][cast(TransitionClass.equals: Int) + 1].action := transition_action_composite; + transitions[state_index][cast(TransitionClass.equals: Int) + 1].next_state := TransitionState.finish; (* Identifier state. *) - set_default_transition(TransitionState.identifier, transition_action_key_id, TransitionState.finish); + state_index := set_default_transition(TransitionState.identifier, transition_action_key_id, TransitionState.finish); - transitions[ORD(TransitionState.identifier) + 1][ORD(TransitionClass.digit) + 1].action := transition_action_accumulate; - transitions[ORD(TransitionState.identifier) + 1][ORD(TransitionClass.digit) + 1].next_state := TransitionState.identifier; + transitions[state_index][cast(TransitionClass.digit: Int) + 1].action := transition_action_accumulate; + transitions[state_index][cast(TransitionClass.digit: Int) + 1].next_state := TransitionState.identifier; - transitions[ORD(TransitionState.identifier) + 1][ORD(TransitionClass.alpha) + 1].action := transition_action_accumulate; - transitions[ORD(TransitionState.identifier) + 1][ORD(TransitionClass.alpha) + 1].next_state := TransitionState.identifier; + transitions[state_index][cast(TransitionClass.alpha: Int) + 1].action := transition_action_accumulate; + transitions[state_index][cast(TransitionClass.alpha: Int) + 1].next_state := TransitionState.identifier; - transitions[ORD(TransitionState.identifier) + 1][ORD(TransitionClass.underscore) + 1].action := transition_action_accumulate; - transitions[ORD(TransitionState.identifier) + 1][ORD(TransitionClass.underscore) + 1].next_state := TransitionState.identifier; + transitions[state_index][cast(TransitionClass.underscore: Int) + 1].action := transition_action_accumulate; + transitions[state_index][cast(TransitionClass.underscore: Int) + 1].next_state := TransitionState.identifier; - transitions[ORD(TransitionState.identifier) + 1][ORD(TransitionClass.hex) + 1].action := transition_action_accumulate; - transitions[ORD(TransitionState.identifier) + 1][ORD(TransitionClass.hex) + 1].next_state := TransitionState.identifier; + transitions[state_index][cast(TransitionClass.hex: Int) + 1].action := transition_action_accumulate; + transitions[state_index][cast(TransitionClass.hex: Int) + 1].next_state := TransitionState.identifier; - transitions[ORD(TransitionState.identifier) + 1][ORD(TransitionClass.zero) + 1].action := transition_action_accumulate; - transitions[ORD(TransitionState.identifier) + 1][ORD(TransitionClass.zero) + 1].next_state := TransitionState.identifier; + transitions[state_index][cast(TransitionClass.zero: Int) + 1].action := transition_action_accumulate; + transitions[state_index][cast(TransitionClass.zero: Int) + 1].next_state := TransitionState.identifier; - transitions[ORD(TransitionState.identifier) + 1][ORD(TransitionClass.x) + 1].action := transition_action_accumulate; - transitions[ORD(TransitionState.identifier) + 1][ORD(TransitionClass.x) + 1].next_state := TransitionState.identifier; + transitions[state_index][cast(TransitionClass.x: Int) + 1].action := transition_action_accumulate; + transitions[state_index][cast(TransitionClass.x: Int) + 1].next_state := TransitionState.identifier; (* Decimal state. *) - set_default_transition(TransitionState.decimal, transition_action_integer, TransitionState.finish); + state_index := set_default_transition(TransitionState.decimal, transition_action_integer, TransitionState.finish); - transitions[ORD(TransitionState.decimal) + 1][ORD(TransitionClass.digit) + 1].action := transition_action_accumulate; - transitions[ORD(TransitionState.decimal) + 1][ORD(TransitionClass.digit) + 1].next_state := TransitionState.decimal; + transitions[state_index][cast(TransitionClass.digit: Int) + 1].action := transition_action_accumulate; + transitions[state_index][cast(TransitionClass.digit: Int) + 1].next_state := TransitionState.decimal; - transitions[ORD(TransitionState.decimal) + 1][ORD(TransitionClass.alpha) + 1].action := transition_action_accumulate; - transitions[ORD(TransitionState.decimal) + 1][ORD(TransitionClass.alpha) + 1].next_state := TransitionState.decimal_suffix; + transitions[state_index][cast(TransitionClass.alpha: Int) + 1].action := transition_action_accumulate; + transitions[state_index][cast(TransitionClass.alpha: Int) + 1].next_state := TransitionState.decimal_suffix; - transitions[ORD(TransitionState.decimal) + 1][ORD(TransitionClass.underscore) + 1].action := nil; - transitions[ORD(TransitionState.decimal) + 1][ORD(TransitionClass.underscore) + 1].next_state := TransitionState.finish; + transitions[state_index][cast(TransitionClass.underscore: Int) + 1].action := nil; + transitions[state_index][cast(TransitionClass.underscore: Int) + 1].next_state := TransitionState.finish; - transitions[ORD(TransitionState.decimal) + 1][ORD(TransitionClass.hex) + 1].action := transition_action_accumulate; - transitions[ORD(TransitionState.decimal) + 1][ORD(TransitionClass.hex) + 1].next_state := TransitionState.decimal_suffix; + transitions[state_index][cast(TransitionClass.hex: Int) + 1].action := transition_action_accumulate; + transitions[state_index][cast(TransitionClass.hex: Int) + 1].next_state := TransitionState.decimal_suffix; - transitions[ORD(TransitionState.decimal) + 1][ORD(TransitionClass.zero) + 1].action := transition_action_accumulate; - transitions[ORD(TransitionState.decimal) + 1][ORD(TransitionClass.zero) + 1].next_state := TransitionState.decimal; + transitions[state_index][cast(TransitionClass.zero: Int) + 1].action := transition_action_accumulate; + transitions[state_index][cast(TransitionClass.zero: Int) + 1].next_state := TransitionState.decimal; - transitions[ORD(TransitionState.decimal) + 1][ORD(TransitionClass.x) + 1].action := transition_action_accumulate; - transitions[ORD(TransitionState.decimal) + 1][ORD(TransitionClass.x) + 1].next_state := TransitionState.decimal_suffix; + transitions[state_index][cast(TransitionClass.x: Int) + 1].action := transition_action_accumulate; + transitions[state_index][cast(TransitionClass.x: Int) + 1].next_state := TransitionState.decimal_suffix; (* Greater state. *) - set_default_transition(TransitionState.greater, transition_action_finalize, TransitionState.finish); + state_index := set_default_transition(TransitionState.greater, transition_action_finalize, TransitionState.finish); - transitions[ORD(TransitionState.greater) + 1][ORD(TransitionClass.equals) + 1].action := transition_action_composite; - transitions[ORD(TransitionState.greater) + 1][ORD(TransitionClass.equals) + 1].next_state := TransitionState.finish; + transitions[state_index][cast(TransitionClass.equals: Int) + 1].action := transition_action_composite; + transitions[state_index][cast(TransitionClass.equals: Int) + 1].next_state := TransitionState.finish; (* Minus state. *) - set_default_transition(TransitionState.minus, transition_action_finalize, TransitionState.finish); + state_index := set_default_transition(TransitionState.minus, transition_action_finalize, TransitionState.finish); - transitions[ORD(TransitionState.minus) + 1][ORD(TransitionClass.greater) + 1].action := transition_action_composite; - transitions[ORD(TransitionState.minus) + 1][ORD(TransitionClass.greater) + 1].next_state := TransitionState.finish; + transitions[state_index][cast(TransitionClass.greater: Int) + 1].action := transition_action_composite; + transitions[state_index][cast(TransitionClass.greater: Int) + 1].next_state := TransitionState.finish; (* Left paren state. *) - set_default_transition(TransitionState.left_paren, transition_action_finalize, TransitionState.finish); + state_index := set_default_transition(TransitionState.left_paren, transition_action_finalize, TransitionState.finish); - transitions[ORD(TransitionState.left_paren) + 1][ORD(TransitionClass.asterisk) + 1].action := transition_action_accumulate; - transitions[ORD(TransitionState.left_paren) + 1][ORD(TransitionClass.asterisk) + 1].next_state := TransitionState.comment; + transitions[state_index][cast(TransitionClass.asterisk: Int) + 1].action := transition_action_accumulate; + transitions[state_index][cast(TransitionClass.asterisk: Int) + 1].next_state := TransitionState.comment; (* Less state. *) - set_default_transition(TransitionState.less, transition_action_finalize, TransitionState.finish); + state_index := set_default_transition(TransitionState.less, transition_action_finalize, TransitionState.finish); - transitions[ORD(TransitionState.less) + 1][ORD(TransitionClass.equals) + 1].action := transition_action_composite; - transitions[ORD(TransitionState.less) + 1][ORD(TransitionClass.equals) + 1].next_state := TransitionState.finish; + transitions[state_index][cast(TransitionClass.equals: Int) + 1].action := transition_action_composite; + transitions[state_index][cast(TransitionClass.equals: Int) + 1].next_state := TransitionState.finish; - transitions[ORD(TransitionState.less) + 1][ORD(TransitionClass.greater) + 1].action := transition_action_composite; - transitions[ORD(TransitionState.less) + 1][ORD(TransitionClass.greater) + 1].next_state := TransitionState.finish; + transitions[state_index][cast(TransitionClass.greater: Int) + 1].action := transition_action_composite; + transitions[state_index][cast(TransitionClass.greater: Int) + 1].next_state := TransitionState.finish; (* Hexadecimal after 0x. *) - set_default_transition(TransitionState.dot, transition_action_finalize, TransitionState.finish); + state_index := set_default_transition(TransitionState.dot, transition_action_finalize, TransitionState.finish); - transitions[ORD(TransitionState.dot) + 1][ORD(TransitionClass.dot) + 1].action := transition_action_composite; - transitions[ORD(TransitionState.dot) + 1][ORD(TransitionClass.dot) + 1].next_state := TransitionState.finish; + transitions[state_index][cast(TransitionClass.dot: Int) + 1].action := transition_action_composite; + transitions[state_index][cast(TransitionClass.dot: Int) + 1].next_state := TransitionState.finish; (* Comment. *) - set_default_transition(TransitionState.comment, transition_action_accumulate, TransitionState.comment); + state_index := set_default_transition(TransitionState.comment, transition_action_accumulate, TransitionState.comment); - transitions[ORD(TransitionState.comment) + 1][ORD(TransitionClass.asterisk) + 1].action := transition_action_accumulate; - transitions[ORD(TransitionState.comment) + 1][ORD(TransitionClass.asterisk) + 1].next_state := TransitionState.closing_comment; + transitions[state_index][cast(TransitionClass.asterisk: Int) + 1].action := transition_action_accumulate; + transitions[state_index][cast(TransitionClass.asterisk: Int) + 1].next_state := TransitionState.closing_comment; - transitions[ORD(TransitionState.comment) + 1][ORD(TransitionClass.eof) + 1].action := nil; - transitions[ORD(TransitionState.comment) + 1][ORD(TransitionClass.eof) + 1].next_state := TransitionState.finish; + transitions[state_index][cast(TransitionClass.eof: Int) + 1].action := nil; + transitions[state_index][cast(TransitionClass.eof: Int) + 1].next_state := TransitionState.finish; (* Closing comment. *) - set_default_transition(TransitionState.closing_comment, transition_action_accumulate, TransitionState.comment); + state_index := set_default_transition(TransitionState.closing_comment, transition_action_accumulate, TransitionState.comment); - transitions[ORD(TransitionState.closing_comment) + 1][ORD(TransitionClass.invalid) + 1].action := nil; - transitions[ORD(TransitionState.closing_comment) + 1][ORD(TransitionClass.invalid) + 1].next_state := TransitionState.finish; + transitions[state_index][cast(TransitionClass.invalid: Int) + 1].action := nil; + transitions[state_index][cast(TransitionClass.invalid: Int) + 1].next_state := TransitionState.finish; - transitions[ORD(TransitionState.closing_comment) + 1][ORD(TransitionClass.right_paren) + 1].action := transition_action_delimited; - transitions[ORD(TransitionState.closing_comment) + 1][ORD(TransitionClass.right_paren) + 1].next_state := TransitionState.finish; + transitions[state_index][cast(TransitionClass.right_paren: Int) + 1].action := transition_action_delimited; + transitions[state_index][cast(TransitionClass.right_paren: Int) + 1].next_state := TransitionState.finish; - transitions[ORD(TransitionState.closing_comment) + 1][ORD(TransitionClass.asterisk) + 1].action := transition_action_accumulate; - transitions[ORD(TransitionState.closing_comment) + 1][ORD(TransitionClass.asterisk) + 1].next_state := TransitionState.closing_comment; + transitions[state_index][cast(TransitionClass.asterisk: Int) + 1].action := transition_action_accumulate; + transitions[state_index][cast(TransitionClass.asterisk: Int) + 1].next_state := TransitionState.closing_comment; - transitions[ORD(TransitionState.closing_comment) + 1][ORD(TransitionClass.eof) + 1].action := nil; - transitions[ORD(TransitionState.closing_comment) + 1][ORD(TransitionClass.eof) + 1].next_state := TransitionState.finish; + transitions[state_index][cast(TransitionClass.eof: Int) + 1].action := nil; + transitions[state_index][cast(TransitionClass.eof: Int) + 1].next_state := TransitionState.finish; (* Character. *) - set_default_transition(TransitionState.character, transition_action_accumulate, TransitionState.character); + state_index := set_default_transition(TransitionState.character, transition_action_accumulate, TransitionState.character); - transitions[ORD(TransitionState.character) + 1][ORD(TransitionClass.invalid) + 1].action := nil; - transitions[ORD(TransitionState.character) + 1][ORD(TransitionClass.invalid) + 1].next_state := TransitionState.finish; + transitions[state_index][cast(TransitionClass.invalid: Int) + 1].action := nil; + transitions[state_index][cast(TransitionClass.invalid: Int) + 1].next_state := TransitionState.finish; - transitions[ORD(TransitionState.character) + 1][ORD(TransitionClass.eof) + 1].action := nil; - transitions[ORD(TransitionState.character) + 1][ORD(TransitionClass.eof) + 1].next_state := TransitionState.finish; + transitions[state_index][cast(TransitionClass.eof: Int) + 1].action := nil; + transitions[state_index][cast(TransitionClass.eof: Int) + 1].next_state := TransitionState.finish; - transitions[ORD(TransitionState.character) + 1][ORD(TransitionClass.single_quote) + 1].action := transition_action_delimited; - transitions[ORD(TransitionState.character) + 1][ORD(TransitionClass.single_quote) + 1].next_state := TransitionState.finish; + transitions[state_index][cast(TransitionClass.single_quote: Int) + 1].action := transition_action_delimited; + transitions[state_index][cast(TransitionClass.single_quote: Int) + 1].next_state := TransitionState.finish; (* String. *) - set_default_transition(TransitionState.string, transition_action_accumulate, TransitionState.string); + state_index := set_default_transition(TransitionState.string, transition_action_accumulate, TransitionState.string); - transitions[ORD(TransitionState.string) + 1][ORD(TransitionClass.invalid) + 1].action := nil; - transitions[ORD(TransitionState.string) + 1][ORD(TransitionClass.invalid) + 1].next_state := TransitionState.finish; + transitions[state_index][cast(TransitionClass.invalid: Int) + 1].action := nil; + transitions[state_index][cast(TransitionClass.invalid: Int) + 1].next_state := TransitionState.finish; - transitions[ORD(TransitionState.string) + 1][ORD(TransitionClass.eof) + 1].action := nil; - transitions[ORD(TransitionState.string) + 1][ORD(TransitionClass.eof) + 1].next_state := TransitionState.finish; + transitions[state_index][cast(TransitionClass.eof: Int) + 1].action := nil; + transitions[state_index][cast(TransitionClass.eof: Int) + 1].next_state := TransitionState.finish; - transitions[ORD(TransitionState.string) + 1][ORD(TransitionClass.double_quote) + 1].action := transition_action_delimited; - transitions[ORD(TransitionState.string) + 1][ORD(TransitionClass.double_quote) + 1].next_state := TransitionState.finish; + transitions[state_index][cast(TransitionClass.double_quote: Int) + 1].action := transition_action_delimited; + transitions[state_index][cast(TransitionClass.double_quote: Int) + 1].next_state := TransitionState.finish; (* Leading zero. *) - set_default_transition(TransitionState.leading_zero, transition_action_integer, TransitionState.finish); + state_index := set_default_transition(TransitionState.leading_zero, transition_action_integer, TransitionState.finish); - transitions[ORD(TransitionState.leading_zero) + 1][ORD(TransitionClass.digit) + 1].action := nil; - transitions[ORD(TransitionState.leading_zero) + 1][ORD(TransitionClass.digit) + 1].next_state := TransitionState.finish; + transitions[state_index][cast(TransitionClass.digit: Int) + 1].action := nil; + transitions[state_index][cast(TransitionClass.digit: Int) + 1].next_state := TransitionState.finish; - transitions[ORD(TransitionState.leading_zero) + 1][ORD(TransitionClass.alpha) + 1].action := nil; - transitions[ORD(TransitionState.leading_zero) + 1][ORD(TransitionClass.alpha) + 1].next_state := TransitionState.finish; + transitions[state_index][cast(TransitionClass.alpha: Int) + 1].action := nil; + transitions[state_index][cast(TransitionClass.alpha: Int) + 1].next_state := TransitionState.finish; - transitions[ORD(TransitionState.leading_zero) + 1][ORD(TransitionClass.underscore) + 1].action := nil; - transitions[ORD(TransitionState.leading_zero) + 1][ORD(TransitionClass.underscore) + 1].next_state := TransitionState.finish; + transitions[state_index][cast(TransitionClass.underscore: Int) + 1].action := nil; + transitions[state_index][cast(TransitionClass.underscore: Int) + 1].next_state := TransitionState.finish; - transitions[ORD(TransitionState.leading_zero) + 1][ORD(TransitionClass.hex) + 1].action := nil; - transitions[ORD(TransitionState.leading_zero) + 1][ORD(TransitionClass.hex) + 1].next_state := TransitionState.finish; + transitions[state_index][cast(TransitionClass.hex: Int) + 1].action := nil; + transitions[state_index][cast(TransitionClass.hex: Int) + 1].next_state := TransitionState.finish; - transitions[ORD(TransitionState.leading_zero) + 1][ORD(TransitionClass.zero) + 1].action := nil; - transitions[ORD(TransitionState.leading_zero) + 1][ORD(TransitionClass.zero) + 1].next_state := TransitionState.finish; + transitions[state_index][cast(TransitionClass.zero: Int) + 1].action := nil; + transitions[state_index][cast(TransitionClass.zero: Int) + 1].next_state := TransitionState.finish; - transitions[ORD(TransitionState.leading_zero) + 1][ORD(TransitionClass.x) + 1].action := nil; - transitions[ORD(TransitionState.leading_zero) + 1][ORD(TransitionClass.x) + 1].next_state := TransitionState.finish; + transitions[state_index][cast(TransitionClass.x: Int) + 1].action := nil; + transitions[state_index][cast(TransitionClass.x: Int) + 1].next_state := TransitionState.finish; (* Digit with a character suffix. *) - set_default_transition(TransitionState.decimal_suffix, transition_action_integer, TransitionState.finish); + state_index := set_default_transition(TransitionState.decimal_suffix, transition_action_integer, TransitionState.finish); - transitions[ORD(TransitionState.decimal_suffix) + 1][ORD(TransitionClass.alpha) + 1].action := nil; - transitions[ORD(TransitionState.decimal_suffix) + 1][ORD(TransitionClass.alpha) + 1].next_state := TransitionState.finish; + transitions[state_index][cast(TransitionClass.alpha: Int) + 1].action := nil; + transitions[state_index][cast(TransitionClass.alpha: Int) + 1].next_state := TransitionState.finish; - transitions[ORD(TransitionState.decimal_suffix) + 1][ORD(TransitionClass.digit) + 1].action := nil; - transitions[ORD(TransitionState.decimal_suffix) + 1][ORD(TransitionClass.digit) + 1].next_state := TransitionState.finish; + transitions[state_index][cast(TransitionClass.digit: Int) + 1].action := nil; + transitions[state_index][cast(TransitionClass.digit: Int) + 1].next_state := TransitionState.finish; - transitions[ORD(TransitionState.decimal_suffix) + 1][ORD(TransitionClass.hex) + 1].action := nil; - transitions[ORD(TransitionState.decimal_suffix) + 1][ORD(TransitionClass.hex) + 1].next_state := TransitionState.finish; + transitions[state_index][cast(TransitionClass.hex: Int) + 1].action := nil; + transitions[state_index][cast(TransitionClass.hex: Int) + 1].next_state := TransitionState.finish; - transitions[ORD(TransitionState.decimal_suffix) + 1][ORD(TransitionClass.zero) + 1].action := nil; - transitions[ORD(TransitionState.decimal_suffix) + 1][ORD(TransitionClass.zero) + 1].next_state := TransitionState.finish; + transitions[state_index][cast(TransitionClass.zero: Int) + 1].action := nil; + transitions[state_index][cast(TransitionClass.zero: Int) + 1].next_state := TransitionState.finish; - transitions[ORD(TransitionState.decimal_suffix) + 1][ORD(TransitionClass.x) + 1].action := nil; - transitions[ORD(TransitionState.decimal_suffix) + 1][ORD(TransitionClass.x) + 1].next_state := TransitionState.finish + transitions[state_index][cast(TransitionClass.x: Int) + 1].action := nil; + transitions[state_index][cast(TransitionClass.x: Int) + 1].next_state := TransitionState.finish end; proc lexer_make*(lexer: ^Lexer, input: ^FILE); @@ -889,7 +897,7 @@ begin lexer^.length := 0; lexer^.buffer := malloc(CHUNK_SIZE); - MemZero(lexer^.buffer, CHUNK_SIZE); + memset(lexer^.buffer, 0, CHUNK_SIZE); lexer^.size := CHUNK_SIZE end; @@ -907,14 +915,11 @@ begin current_state := TransitionState.start; while current_state <> TransitionState.finish do - index1 := ORD(lexer^.current.iterator^); - index1 := index1 + 1u; + index1 := cast(lexer^.current.iterator^: Word) + 1u; current_class := classification[index1]; - index1 := ORD(current_state); - index1 := index1 + 1u; - index2 := ORD(current_class); - index2 := index + 1u; + index1 := cast(current_state: Word) + 1u; + index2 := cast(current_class: Word) + 1u; current_transition := transitions[index1][index2]; if current_transition.action <> nil then diff --git a/source/Parser.elna b/source/Parser.elna index a1fd45d..a06ea13 100644 --- a/source/Parser.elna +++ b/source/Parser.elna @@ -3,11 +3,7 @@ obtain one at https://mozilla.org/MPL/2.0/. *) module; -import cstdlib; -from MemUtils import MemZero; - -from Common import Identifier, ShortString; -from Lexer import Lexer, LexerToken, lexer_current, lexer_lex; +import cstdlib, common, Lexer; type Parser = record @@ -24,7 +20,7 @@ type kind: AstLiteralKind; value: union integer: Int; - string: ShortString; + string: String; boolean: Bool end end; @@ -237,7 +233,7 @@ begin end end; current_field := current_field + 1; - MemZero(current_field, #size(AstFieldDeclaration)); + memset(current_field, 0, #size(AstFieldDeclaration)); return field_declarations end; @@ -331,7 +327,7 @@ begin token := parser_lex(parser^.lexer) end; current_case := current_case + 1; - MemZero(current_case, #size(Identifier)); + memset(current_case, 0, #size(Identifier)); return result end; @@ -608,7 +604,7 @@ begin token := parser_lex(parser^.lexer) end; current_symbol := current_symbol + 1; - MemZero(current_symbol, #size(Identifier)); + memset(current_symbol, 0, #size(Identifier)); token := parser_lex(parser^.lexer); diff --git a/source/Transpiler.elna b/source/Transpiler.elna index ae14a07..350d718 100644 --- a/source/Transpiler.elna +++ b/source/Transpiler.elna @@ -6,14 +6,11 @@ module; from FIO import File, WriteNBytes, WriteLine, WriteChar, WriteString; from NumberIO import IntToStr; -from Common import Identifier, ShortString; -from Parser import AstLiteralKind, AstUnaryOperator, AstBinaryOperator, AstModule, AstExpression, AstLiteral, - AstConstantDeclaration, AstStatement, AstTypedDeclaration, AstCompoundStatement, AstProcedureDeclaration, - AstVariableDeclaration, AstImportStatement, AstTypeExpression, AstFieldDeclaration; +import common, Parser; type TranspilerContext* = record - input_name: ShortString; + input_name: String; output: File; definition: File; indentation: Word @@ -26,7 +23,7 @@ begin count := 0; while count < context^.indentation do - WriteString(context^.output, ' '); + WriteString(context^.output, " "); count := count + 1u end end; @@ -43,17 +40,17 @@ var written_bytes: Word; current_symbol: ^Identifier; begin - WriteString(context^.output, 'FROM '); + WriteString(context^.output, "FROM "); written_bytes := WriteNBytes(context^.output, ORD(import_statement^.package[1]), @import_statement^.package[2]); - WriteString(context^.output, ' IMPORT '); + WriteString(context^.output, " IMPORT "); current_symbol := import_statement^.symbols; written_bytes := WriteNBytes(context^.output, ORD(current_symbol^[1]), @current_symbol^[2]); current_symbol := current_symbol + 1; - while ORD(current_symbol^[1]) <> 0 do - WriteString(context^.output, ', '); + while current_symbol^[1] <> '\0' do + WriteString(context^.output, ", "); written_bytes := WriteNBytes(context^.output, ORD(current_symbol^[1]), @current_symbol^[2]); current_symbol := current_symbol + 1; end; @@ -76,10 +73,10 @@ var buffer: [20]CHAR; written_bytes: Word; begin - WriteString(context^.output, ' '); + WriteString(context^.output, " "); written_bytes := WriteNBytes(context^.output, ORD(declaration^.constant_name[1]), @declaration^.constant_name[2]); - WriteString(context^.output, ' = '); + WriteString(context^.output, " = "); IntToStr(declaration^.constant_value, 0, buffer); WriteString(context^.output, buffer); @@ -92,7 +89,7 @@ var current_declaration: ^^AstConstantDeclaration; begin if declarations^ <> nil then - WriteString(context^.output, 'CONST'); + WriteString(context^.output, "CONST"); WriteLine(context^.output); current_declaration := declarations; @@ -110,9 +107,9 @@ end; proc transpile_module(context: ^TranspilerContext, result: ^AstModule); begin if result^.main = false then - WriteString(context^.output, 'IMPLEMENTATION ') + WriteString(context^.output, "IMPLEMENTATION ") end; - WriteString(context^.output, 'MODULE '); + WriteString(context^.output, "MODULE "); (* Write the module name and end the line with a semicolon and newline. *) transpile_module_name(context); @@ -129,10 +126,10 @@ begin transpile_procedure_part(context, result^.procedures); transpile_statement_part(context, result^.statements); - WriteString(context^.output, 'END '); + WriteString(context^.output, "END "); transpile_module_name(context); - WriteChar(context^.output, '.'); + WriteChar(context^.output, "."); WriteLine(context^.output) end; @@ -143,16 +140,16 @@ var begin current_field := fields; - while ORD(current_field^.field_name[1]) <> 0 do - WriteString(context^.output, ' '); + while current_field^.field_name[1] <> '\0' do + WriteString(context^.output, " "); written_bytes := WriteNBytes(context^.output, ORD(current_field^.field_name[1]), @current_field^.field_name[2]); - WriteString(context^.output, ': '); + WriteString(context^.output, ": "); transpile_type_expression(context, current_field^.field_type); current_field := current_field + 1; - if ORD(current_field^.field_name[1]) <> 0 then + if current_field^.field_name[1] <> '\0' then WriteChar(context^.output, ';') end; WriteLine(context^.output) @@ -161,15 +158,15 @@ end; proc transpile_record_type(context: ^TranspilerContext, type_expression: ^AstTypeExpression); begin - WriteString(context^.output, 'RECORD'); + WriteString(context^.output, "RECORD"); WriteLine(context^.output); transpile_type_fields(context, type_expression^.fields); - WriteString(context^.output, ' END') + WriteString(context^.output, " END") end; proc transpile_pointer_type(context: ^TranspilerContext, type_expression: ^AstTypeExpression); begin - WriteString(context^.output, 'POINTER TO '); + WriteString(context^.output, "POINTER TO "); transpile_type_expression(context, type_expression^.target) end; @@ -178,17 +175,17 @@ proc transpile_array_type(context: ^TranspilerContext, type_expression: ^AstType var buffer: [20]CHAR; begin - WriteString(context^.output, 'ARRAY'); + WriteString(context^.output, "ARRAY"); if type_expression^.length <> 0 then - WriteString(context^.output, '[1..'); + WriteString(context^.output, "[1.."); IntToStr(type_expression^.length, 0, buffer); WriteString(context^.output, buffer); WriteChar(context^.output, ']') end; - WriteString(context^.output, ' OF '); + WriteString(context^.output, " OF "); transpile_type_expression(context, type_expression^.base) end; @@ -200,22 +197,22 @@ var begin current_case := type_expression^.cases; - WriteString(context^.output, '('); + WriteString(context^.output, "("); WriteLine(context^.output); - WriteString(context^.output, ' '); + WriteString(context^.output, " "); written_bytes := WriteNBytes(context^.output, ORD(current_case^[1]), @current_case^[2]); current_case := current_case + 1; - while ORD(current_case^[1]) <> 0 do + while current_case^[1] <> '\0' do WriteChar(context^.output, ','); WriteLine(context^.output); - WriteString(context^.output, ' '); + WriteString(context^.output, " "); written_bytes := WriteNBytes(context^.output, ORD(current_case^[1]), @current_case^[2]); current_case := current_case + 1 end; WriteLine(context^.output); - WriteString(context^.output, ' )') + WriteString(context^.output, " )") end; proc transpile_named_type(context: ^TranspilerContext, type_expression: ^AstTypeExpression); @@ -231,7 +228,7 @@ var current_parameter: ^^AstTypeExpression; parameter_count: Word; begin - WriteString(context^.output, 'PROCEDURE('); + WriteString(context^.output, "PROCEDURE("); current_parameter := type_expression^.parameters; while current_parameter^ <> nil do @@ -240,7 +237,7 @@ begin current_parameter := current_parameter + 1; if current_parameter^ <> nil then - WriteString(context^.output, ', ') + WriteString(context^.output, ", ") end end; WriteChar(context^.output, ')') @@ -272,10 +269,10 @@ proc transpile_type_declaration(context: ^TranspilerContext, declaration: ^AstTy var written_bytes: Word; begin - WriteString(context^.output, ' '); + WriteString(context^.output, " "); written_bytes := WriteNBytes(context^.output, ORD(declaration^.identifier[1]), @declaration^.identifier[2]); - WriteString(context^.output, ' = '); + WriteString(context^.output, " = "); transpile_type_expression(context, declaration^.type_expression); write_semicolon(context^.output) @@ -286,7 +283,7 @@ var current_declaration: ^^AstTypedDeclaration; begin if declarations^ <> nil then - WriteString(context^.output, 'TYPE'); + WriteString(context^.output, "TYPE"); WriteLine(context^.output); current_declaration := declarations; @@ -303,10 +300,10 @@ proc transpile_variable_declaration(context: ^TranspilerContext, declaration: ^A var written_bytes: Word; begin - WriteString(context^.output, ' '); + WriteString(context^.output, " "); written_bytes := WriteNBytes(context^.output, ORD(declaration^.variable_name[1]), @declaration^.variable_name[2]); - WriteString(context^.output, ': '); + WriteString(context^.output, ": "); transpile_type_expression(context, declaration^.variable_type); write_semicolon(context^.output) @@ -317,7 +314,7 @@ var current_declaration: ^^AstVariableDeclaration; begin if declarations^ <> nil then - WriteString(context^.output, 'VAR'); + WriteString(context^.output, "VAR"); WriteLine(context^.output); current_declaration := declarations; @@ -338,7 +335,7 @@ var parameter_index: Word; current_parameter: ^AstTypedDeclaration; begin - WriteString(context^.output, 'PROCEDURE '); + WriteString(context^.output, "PROCEDURE "); written_bytes := WriteNBytes(context^.output, ORD(declaration^.name[1]), @declaration^.name[2]); WriteChar(context^.output, '('); @@ -347,22 +344,22 @@ begin while parameter_index < declaration^.parameter_count do written_bytes := WriteNBytes(context^.output, ORD(current_parameter^.identifier[1]), @current_parameter^.identifier[2]); - WriteString(context^.output, ': '); + WriteString(context^.output, ": "); transpile_type_expression(context, current_parameter^.type_expression); parameter_index := parameter_index + 1u; current_parameter := current_parameter + 1; if parameter_index <> declaration^.parameter_count then - WriteString(context^.output, '; ') + WriteString(context^.output, "; ") end end; - WriteString(context^.output, ')'); + WriteString(context^.output, ")"); (* Check for the return type and write it. *) if declaration^.return_type <> nil then - WriteString(context^.output, ': '); + WriteString(context^.output, ": "); transpile_type_expression(context, declaration^.return_type) end; write_semicolon(context^.output) @@ -388,10 +385,10 @@ begin | AstBinaryOperator.not_equals: WriteChar(context^.output, '#') | AstBinaryOperator.less: WriteChar(context^.output, '<') | AstBinaryOperator.greater: WriteChar(context^.output, '>') - | AstBinaryOperator.less_equal: WriteString(context^.output, '<=') - | AstBinaryOperator.greater_equal: WriteString(context^.output, '>=') - | AstBinaryOperator.disjunction: WriteString(context^.output, 'OR') - | AstBinaryOperatorConjunction: WriteString(context^.output, 'AND') + | AstBinaryOperator.less_equal: WriteString(context^.output, "<=") + | AstBinaryOperator.greater_equal: WriteString(context^.output, ">=") + | AstBinaryOperator.disjunction: WriteString(context^.output, "OR") + | AstBinaryOperatorConjunction: WriteString(context^.output, "AND") end end; @@ -414,13 +411,13 @@ begin WriteString(context^.output, literal^.string) end; if literal^.kind = AstLiteralKind.null then - WriteString(context^.output, 'NIL') + WriteString(context^.output, "NIL") end; if (literal^.kind = AstLiteralKind.boolean) & literal^.boolean then - WriteString(context^.output, 'TRUE') + WriteString(context^.output, "TRUE") end; if (literal^.kind = AstLiteralKind.boolean) & (literal^.boolean = false) then - WriteString(context^.output, 'FALSE') + WriteString(context^.output, "FALSE") end end; if expression^.kind = astExpressionKindIdentifier then @@ -466,7 +463,7 @@ begin current_argument := current_argument + 1; while argument_index < expression^.argument_count do - WriteString(context^.output, ', '); + WriteString(context^.output, ", "); transpile_expression(context, current_argument^); @@ -480,44 +477,44 @@ end; proc transpile_if_statement(context: ^TranspilerContext, statement: ^AstStatement); begin - WriteString(context^.output, 'IF '); + WriteString(context^.output, "IF "); transpile_expression(context, statement^.if_condition); - WriteString(context^.output, ' THEN'); + WriteString(context^.output, " THEN"); WriteLine(context^.output); context^.indentation := context^.indentation + 1u; transpile_compound_statement(context, statement^.if_branch); context^.indentation := context^.indentation - 1u; indent(context); - WriteString(context^.output, 'END') + WriteString(context^.output, "END") end; proc transpile_while_statement(context: ^TranspilerContext, statement: ^AstStatement); begin - WriteString(context^.output, 'WHILE '); + WriteString(context^.output, "WHILE "); transpile_expression(context, statement^.while_condition); - WriteString(context^.output, ' DO'); + WriteString(context^.output, " DO"); WriteLine(context^.output); context^.indentation := context^.indentation + 1u; transpile_compound_statement(context, statement^.while_body); context^.indentation := context^.indentation - 1u; indent(context); - WriteString(context^.output, 'END') + WriteString(context^.output, "END") end; proc transpile_assignment_statement(context: ^TranspilerContext, statement: ^AstStatement); begin transpile_expression(context, statement^.assignee); - WriteString(context^.output, ' := '); + WriteString(context^.output, " := "); transpile_expression(context, statement^.assignment) end; proc transpile_return_statement(context: ^TranspilerContext, statement: ^AstStatement); begin - WriteString(context^.output, 'RETURN '); + WriteString(context^.output, "RETURN "); transpile_expression(context, statement^.returned) end; @@ -567,7 +564,7 @@ end; proc transpile_statement_part(context: ^TranspilerContext, compound: AstCompoundStatement); begin if compound.count > 0 then - WriteString(context^.output, 'BEGIN'); + WriteString(context^.output, "BEGIN"); WriteLine(context^.output); context^.indentation := context^.indentation + 1u; @@ -586,7 +583,7 @@ begin transpile_variable_part(context, declaration^.variables, false); transpile_statement_part(context, declaration^.statements); - WriteString(context^.output, 'END '); + WriteString(context^.output, "END "); written_bytes := WriteNBytes(context^.output, ORD(declaration^.name[1]), @declaration^.name[2]); write_semicolon(context^.output) @@ -610,7 +607,7 @@ begin counter := 1u; last_slash := 0u; - while (context^.input_name[counter] <> '.') & (ORD(context^.input_name[counter]) <> 0) do + while context^.input_name[counter] <> '.' & context^.input_name[counter] <> '\0' do if context^.input_name[counter] = '/' then last_slash := counter end; @@ -623,13 +620,13 @@ begin if last_slash <> 0u then counter := last_slash + 1u end; - while (context^.input_name[counter] <> '.') & (ORD(context^.input_name[counter]) <> 0) do + while context^.input_name[counter] <> '.' & context^.input_name[counter] <> '\0' do WriteChar(context^.output, context^.input_name[counter]); counter := counter + 1u end end; -proc transpile*(ast_module: ^AstModule, output: File, definition: File, input_name: ShortString); +proc transpile*(ast_module: ^AstModule, output: File, definition: File, input_name: String); var context: TranspilerContext; begin diff --git a/source/cctype.elna b/source/cctype.elna new file mode 100644 index 0000000..a538c96 --- /dev/null +++ b/source/cctype.elna @@ -0,0 +1,11 @@ +(* This Source Code Form is subject to the terms of the Mozilla Public License, + v. 2.0. If a copy of the MPL was not distributed with this file, You can + obtain one at https://mozilla.org/MPL/2.0/. *) +module; + +proc isdigit(c: Int ) -> Int; extern; +proc isalnum(c: Int) -> Int; extern; +proc isalpha(c: Int) -> Int; extern; +proc isspace(c: Int) -> Int; extern; + +end. diff --git a/source/Common.elna b/source/common.elna similarity index 86% rename from source/Common.elna rename to source/common.elna index 627c972..19d0176 100644 --- a/source/Common.elna +++ b/source/common.elna @@ -4,12 +4,10 @@ module; type - ShortString = [256]Char; Identifier = [256]Char; TextLocation* = record line: Word; column: Word end; - FILE* = record end; end. diff --git a/source/cstdio.elna b/source/cstdio.elna new file mode 100644 index 0000000..a9352e7 --- /dev/null +++ b/source/cstdio.elna @@ -0,0 +1,23 @@ +(* This Source Code Form is subject to the terms of the Mozilla Public License, + v. 2.0. If a copy of the MPL was not distributed with this file, You can + obtain one at https://mozilla.org/MPL/2.0/. *) +module; + +type + FILE* = record end; + +proc fopen(pathname: ^Char, mode: ^Char) -> ^FILE; extern; +proc fclose(stream: ^FILE) -> Int; extern; +proc fseek(stream: ^FILE, off: Int, whence: Int) -> Int; extern; +proc rewind(stream: ^FILE); extern; +proc ftell(stream: ^FILE) -> Int; extern; +proc fflush(stream: ^FILE) -> Int; extern; + +proc fread(ptr: Pointer, size: Word, nmemb: Word, stream: ^FILE) -> Word; extern; + +proc perror(s: ^Char); extern; + +proc puts(s: ^Char) -> Int; extern; +proc putchar(c: Int) -> Int; extern; + +end. diff --git a/source/cstdlib.elna b/source/cstdlib.elna new file mode 100644 index 0000000..e5369f2 --- /dev/null +++ b/source/cstdlib.elna @@ -0,0 +1,13 @@ +(* This Source Code Form is subject to the terms of the Mozilla Public License, + v. 2.0. If a copy of the MPL was not distributed with this file, You can + obtain one at https://mozilla.org/MPL/2.0/. *) +module; + +proc malloc(size: Word) -> Pointer; extern; +proc free(ptr: Pointer); extern; +proc calloc(nmemb: Word, size: Word) -> Pointer; extern; +proc realloc(ptr: Pointer, size: Word) -> Pointer; extern; + +proc exit(code: Int) -> !; extern; + +end. diff --git a/source/cstring.elna b/source/cstring.elna new file mode 100644 index 0000000..1c1319f --- /dev/null +++ b/source/cstring.elna @@ -0,0 +1,15 @@ +(* This Source Code Form is subject to the terms of the Mozilla Public License, + v. 2.0. If a copy of the MPL was not distributed with this file, You can + obtain one at https://mozilla.org/MPL/2.0/. *) +module; + +proc memset(ptr: Pointer, c: Int, n: Int) -> ^Char; extern; +proc memcpy(dst: Pointer, src: Pointer, n: Word); extern; + +proc strcmp(s1: ^Char, s2: ^Char) -> Int; extern; +proc strncmp(s1: ^Char, s2: ^Char, n: Word) -> Int; extern; +proc strncpy(dst: ^Char, src: ^Char, dsize: Word) -> ^Char; extern; +proc strcpy(dst: ^Char, src: ^Char) -> ^Char; extern; +proc strlen(ptr: ^Char) -> Word; extern; + +end. diff --git a/source/main.elna b/source/main.elna index 0f3d001..d737aae 100644 --- a/source/main.elna +++ b/source/main.elna @@ -3,7 +3,7 @@ obtain one at https://mozilla.org/MPL/2.0/. *) program; -import Common, Lexer; +import cstdlib, cstring, cstdio, cctype, common, Lexer; const SEEK_SET* := 0; @@ -127,30 +127,8 @@ type External procedures. *) -proc fopen(pathname: ^Char, mode: ^Char) -> ^FILE; extern; -proc fclose(stream: ^FILE) -> Int; extern; -proc fseek(stream: ^FILE, off: Int, whence: Int) -> Int; extern; -proc rewind(stream: ^FILE); extern; -proc ftell(stream: ^FILE) -> Int; extern; -proc fread(ptr: Pointer, size: Word, nmemb: Word, stream: ^FILE) -> Word; extern; proc write(fd: Int, buf: Pointer, Word: Int) -> Int; extern; -proc malloc(size: Word) -> Pointer; extern; -proc free(ptr: Pointer); extern; -proc calloc(nmemb: Word, size: Word) -> Pointer; extern; -proc realloc(ptr: Pointer, size: Word) -> Pointer; extern; - -proc memset(ptr: ^Char, c: Int, n: Int) -> ^Char; extern; - -proc strcmp(s1: ^Char, s2: ^Char) -> Int; extern; -proc strncmp(s1: ^Char, s2: ^Char, n: Word) -> Int; extern; -proc strncpy(dst: ^Char, src: ^Char, dsize: Word) -> ^Char; extern; -proc strcpy(dst: ^Char, src: ^Char) -> ^Char; extern; -proc strlen(ptr: ^Char) -> Word; extern; - -proc perror(s: ^Char); extern; -proc exit(code: Int) -> !; extern; - (* Standard procedures. *) @@ -161,12 +139,12 @@ end; proc write_s(value: String); begin - write(0, cast(value.ptr: Pointer), cast(value.length: Int)) + write(1, cast(value.ptr: Pointer), cast(value.length: Int)) end; proc write_z(value: ^Char); begin - write(0, cast(value: Pointer), cast(strlen(value): Int)) + write(1, cast(value: Pointer), cast(strlen(value): Int)) end; proc write_b(value: Bool); @@ -180,7 +158,8 @@ end; proc write_c(value: Char); begin - write(0, cast(@value: Pointer), 1) + putchar(cast(value: Int)); + fflush(nil) end; proc write_i(value: Int); @@ -212,22 +191,6 @@ begin write_i(cast(value: Int)) end; -proc is_digit(c: Char) -> Bool; - return cast(c: Int) >= cast('0': Int) & cast(c: Int) <= cast('9': Int) -end; - -proc is_alpha(c: Char) -> Bool; - return cast(c: Int) >= cast('A': Int) & cast(c: Int) <= cast('z': Int) -end; - -proc is_alnum(c: Char) -> Bool; - return is_digit(c) or is_alpha(c) -end; - -proc is_space(c: Char) -> Bool; - return c = ' ' or c = '\n' or c = '\t' -end; - proc substring(string: String, start: Word, count: Word) -> String; return String(string.ptr + start, count) end; @@ -412,7 +375,7 @@ proc lexer_spaces(source_code: ^SourceCode); var current: Char; begin - while ~source_code_empty(source_code) & is_space(source_code_head(source_code^)) do + while ~source_code_empty(source_code) & isspace(cast(source_code_head(source_code^): Int)) <> 0 do current := source_code_head(source_code^); if current = '\n' then @@ -424,7 +387,7 @@ end; (* Checker whether the character is allowed in an identificator. *) proc lexer_is_ident(char: Char) -> Bool; - return is_alnum(char) or char = '_' + return isalnum(cast(char: Int)) <> 0 or char = '_' end; proc lexer_identifier(source_code: ^SourceCode, token_content: ^StringBuffer); @@ -511,7 +474,7 @@ proc lexer_number(source_code: ^SourceCode, token_content: ^Int); begin token_content^ := 0; - while ~source_code_empty(source_code) & is_digit(source_code_head(source_code^)) do + while ~source_code_empty(source_code) & isdigit(cast(source_code_head(source_code^): Int)) <> 0 do token_content^ := token_content^ * 10 + (cast(source_code_head(source_code^): Int) - cast('0': Int)); source_code_advance(source_code) @@ -607,7 +570,7 @@ begin first_char := source_code_head(source_code); - if is_alpha(first_char) or first_char = '_' then + if isalpha(cast(first_char: Int)) <> 0 or first_char = '_' then lexer_identifier(@source_code, token_buffer); current_token := lexer_categorize(string_buffer_clear(token_buffer)) elsif first_char = '#' then @@ -616,7 +579,7 @@ begin current_token.kind := TokenKind.trait; current_token.value.string := string_dup(string_buffer_clear(token_buffer)) - elsif is_digit(first_char) then + elsif isdigit(cast(first_char: Int)) <> 0 then lexer_number(@source_code, @current_token.value.int_value); if source_code_expect(@source_code, 'u') then