diff options
Diffstat (limited to 'source')
| -rw-r--r-- | source/cctype.elna | 23 | ||||
| -rw-r--r-- | source/command_line_interface.elna | 18 | ||||
| -rw-r--r-- | source/common.elna | 40 | ||||
| -rw-r--r-- | source/cstdio.elna | 49 | ||||
| -rw-r--r-- | source/cstdlib.elna | 22 | ||||
| -rw-r--r-- | source/cstring.elna | 27 | ||||
| -rw-r--r-- | source/lexer.elna | 139 | ||||
| -rw-r--r-- | source/main.elna | 218 |
8 files changed, 284 insertions, 252 deletions
diff --git a/source/cctype.elna b/source/cctype.elna index 3906cd1..13dc50a 100644 --- a/source/cctype.elna +++ b/source/cctype.elna @@ -1,14 +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; -proc isdigit*(c: Int ) -> Int; extern; -proc isalnum*(c: Int) -> Int; extern; -proc isalpha*(c: Int) -> Int; extern; -proc isspace*(c: Int) -> Int; extern; +proc isdigit*(c: Int ) -> Int +extern -proc tolower*(c: Int) -> Int; extern; -proc toupper*(c: Int) -> Int; extern; +proc isalnum*(c: Int) -> Int +extern + +proc isalpha*(c: Int) -> Int +extern + +proc isspace*(c: Int) -> Int +extern + +proc tolower*(c: Int) -> Int +extern + +proc toupper*(c: Int) -> Int +extern end. diff --git a/source/command_line_interface.elna b/source/command_line_interface.elna index 040fdeb..78e1cf5 100644 --- a/source/command_line_interface.elna +++ b/source/command_line_interface.elna @@ -5,9 +5,7 @@ (* Command line handling. *) -module; - -import cstdlib, cstring, common; +import cstdlib, cstring, common type CommandLine* = record @@ -15,14 +13,14 @@ type output: ^Char; lex: Bool; parse: Bool - end; + end -proc parse_command_line*(argc: Int, argv: ^^Char) -> ^CommandLine; +proc parse_command_line*(argc: Int, argv: ^^Char) -> ^CommandLine var - parameter: ^Char; - i: Int; - result: ^CommandLine; - parsed: Bool; + parameter: ^Char + i: Int + result: ^CommandLine + parsed: Bool begin i := 1; result := cast(malloc(#size(CommandLine)): ^CommandLine); @@ -88,6 +86,6 @@ begin end; return result -end; +end end. diff --git a/source/common.elna b/source/common.elna index e7b30ca..33a79b8 100644 --- a/source/common.elna +++ b/source/common.elna @@ -1,50 +1,50 @@ (* 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; -import cstring, cstdio; +import cstring, cstdio type - Identifier = [256]Char; + Identifier = [256]Char TextLocation* = record line: Word; column: Word - end; + end -proc write*(fd: Int, buf: Pointer, Word: Int) -> Int; extern; +proc write*(fd: Int, buf: Pointer, Word: Int) -> Int +extern -proc write_s*(value: String); +proc write_s*(value: String) begin (* fwrite(cast(value.ptr: Pointer), value.length, 1u, stdout) *) write(1, cast(value.ptr: Pointer), cast(value.length: Int)) -end; +end -proc write_z*(value: ^Char); +proc write_z*(value: ^Char) begin write(1, cast(value: Pointer), cast(strlen(value): Int)) -end; +end -proc write_b*(value: Bool); +proc write_b*(value: Bool) begin if value then write_s("true") else write_s("false") end -end; +end -proc write_c*(value: Char); +proc write_c*(value: Char) begin putchar(cast(value: Int)); fflush(nil) -end; +end -proc write_i*(value: Int); +proc write_i*(value: Int) var - digit: Int; - n: Word; - buffer: [10]Char; + digit: Int + n: Word + buffer: [10]Char begin n := 10u; @@ -62,11 +62,11 @@ begin n := n + 1u; write_c(buffer[n]) end -end; +end -proc write_u*(value: Word); +proc write_u*(value: Word) begin write_i(cast(value: Int)) -end; +end end. diff --git a/source/cstdio.elna b/source/cstdio.elna index c7507ff..b86014f 100644 --- a/source/cstdio.elna +++ b/source/cstdio.elna @@ -1,29 +1,46 @@ (* 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; + FILE* = record end var - stdin*: ^FILE := extern; - stdout*: ^FILE := extern; - stderr*: ^FILE := extern; + stdin*: ^FILE := extern + stdout*: ^FILE := extern + stderr*: ^FILE := extern -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 fopen*(pathname: ^Char, mode: ^Char) -> ^FILE +extern -proc fread*(ptr: Pointer, size: Word, nmemb: Word, stream: ^FILE) -> Word; extern; -proc fwrite*(ptr: Pointer, size: Word, nitems: Word, stream: ^FILE) -> Word; extern; +proc fclose*(stream: ^FILE) -> Int +extern -proc perror(s: ^Char); extern; +proc fseek*(stream: ^FILE, off: Int, whence: Int) -> Int +extern -proc puts(s: ^Char) -> Int; extern; -proc putchar(c: 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 fwrite*(ptr: Pointer, size: Word, nitems: 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 index da2029c..3346440 100644 --- a/source/cstdlib.elna +++ b/source/cstdlib.elna @@ -1,15 +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; -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 malloc(size: Word) -> Pointer +extern -proc atoi(str: ^Char) -> Int; extern; +proc free(ptr: Pointer) +extern -proc exit(code: Int) -> !; extern; +proc calloc(nmemb: Word, size: Word) -> Pointer +extern + +proc realloc(ptr: Pointer, size: Word) -> Pointer +extern + +proc atoi(str: ^Char) -> Int +extern + +proc exit(code: Int) -> ! +extern end. diff --git a/source/cstring.elna b/source/cstring.elna index 24d852a..ef04e59 100644 --- a/source/cstring.elna +++ b/source/cstring.elna @@ -1,15 +1,26 @@ (* 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: Word) -> ^Char; extern; -proc memcpy(dst: Pointer, src: Pointer, n: Word); extern; +proc memset(ptr: Pointer, c: Int, n: Word) -> ^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 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/lexer.elna b/source/lexer.elna index d5f529b..e6fc38c 100644 --- a/source/lexer.elna +++ b/source/lexer.elna @@ -1,12 +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; -import cstdio, cstring, cctype, cstdlib, common; +import cstdio, cstring, cctype, cstdlib, common const - CHUNK_SIZE := 85536u; + CHUNK_SIZE := 85536u type (* @@ -38,7 +37,7 @@ type greater, less, other - ); + ) TransitionState = ( start, colon, @@ -56,7 +55,7 @@ type leading_zero, decimal_suffix, finish - ); + ) LexerToken = record kind: LexerKind; value: union @@ -67,18 +66,18 @@ type end; start_location: TextLocation; end_location: TextLocation - end; - TransitionAction = proc(^Lexer, ^LexerToken); + end + TransitionAction = proc(^Lexer, ^LexerToken) Transition = record action: TransitionAction; next_state: TransitionState - end; - TransitionClasses = [22]Transition; + end + TransitionClasses = [22]Transition BufferPosition* = record iterator: ^Char; location: TextLocation - end; + end Lexer* = record input: ^FILE; buffer: ^Char; @@ -86,7 +85,7 @@ type length: Word; start: BufferPosition; current: BufferPosition - end; + end LexerKind* = ( unknown, identifier, @@ -153,15 +152,15 @@ type _program, _module, _import - ); + ) var - classification: [128]TransitionClass; - transitions: [16]TransitionClasses; + classification: [128]TransitionClass + transitions: [16]TransitionClasses -proc initialize_classification(); +proc initialize_classification() var - i: Word; + i: Word begin classification[1] := TransitionClass.eof; (* NUL *) classification[2] := TransitionClass.invalid; (* SOH *) @@ -297,13 +296,13 @@ begin classification[i] := TransitionClass.other; i := i + 1u end -end; +end -proc compare_keyword(keyword: String, token_start: BufferPosition, token_end: ^Char) -> Bool; +proc compare_keyword(keyword: String, token_start: BufferPosition, token_end: ^Char) -> Bool var - result: Bool; - index: Word; - continue: Bool; + result: Bool + index: Word + continue: Bool begin index := 0u; result := true; @@ -319,28 +318,28 @@ begin result := result & index = keyword.length; return result & (token_start.iterator = token_end) -end; +end (* Reached the end of file. *) -proc transition_action_eof(lexer: ^Lexer, token: ^LexerToken); +proc transition_action_eof(lexer: ^Lexer, token: ^LexerToken) begin token^.kind := LexerKind.unknown -end; +end -proc increment(position: ^BufferPosition); +proc increment(position: ^BufferPosition) begin position^.iterator := position^.iterator + 1 -end; +end (* Add the character to the token currently read and advance to the next character. *) -proc transition_action_accumulate(lexer: ^Lexer, token: ^LexerToken); +proc transition_action_accumulate(lexer: ^Lexer, token: ^LexerToken) begin increment(@lexer^.current) -end; +end (* The current character is not a part of the token. Finish the token already * read. Don't advance to the next character. *) -proc transition_action_finalize(lexer: ^Lexer, token: ^LexerToken); +proc transition_action_finalize(lexer: ^Lexer, token: ^LexerToken) begin if lexer^.start.iterator^ = ':' then token^.kind := LexerKind.colon @@ -360,10 +359,10 @@ begin if lexer^.start.iterator^ = '.' then token^.kind := LexerKind.dot end -end; +end (* An action for tokens containing multiple characters. *) -proc transition_action_composite(lexer: ^Lexer, token: ^LexerToken); +proc transition_action_composite(lexer: ^Lexer, token: ^LexerToken) begin if lexer^.start.iterator^ = '<' then if lexer^.current.iterator^ = '>' then @@ -383,10 +382,10 @@ begin token^.kind := LexerKind.arrow end; increment(@lexer^.current) -end; +end (* Skip a space. *) -proc transition_action_skip(lexer: ^Lexer, token: ^LexerToken); +proc transition_action_skip(lexer: ^Lexer, token: ^LexerToken) begin increment(@lexer^.start); @@ -395,12 +394,12 @@ begin lexer^.start.location.column := 1u end; lexer^.current := lexer^.start -end; +end (* Delimited string action. *) -proc transition_action_delimited(lexer: ^Lexer, token: ^LexerToken); +proc transition_action_delimited(lexer: ^Lexer, token: ^LexerToken) var - text_length: Word; + text_length: Word begin if lexer^.start.iterator^ = '(' then token^.kind := LexerKind.comment @@ -422,10 +421,10 @@ begin token^.kind := LexerKind.string end; increment(@lexer^.current) -end; +end (* Finalize keyword or identifier. *) -proc transition_action_key_id(lexer: ^Lexer, token: ^LexerToken); +proc transition_action_key_id(lexer: ^Lexer, token: ^LexerToken) begin token^.kind := LexerKind.identifier; @@ -515,11 +514,11 @@ begin token^.kind := LexerKind.boolean; token^.value.booleanKind := false end -end; +end (* Action for tokens containing only one character. The character cannot be * followed by other characters forming a composite token. *) -proc transition_action_single(lexer: ^Lexer, token: ^LexerToken); +proc transition_action_single(lexer: ^Lexer, token: ^LexerToken) begin if lexer^.current.iterator^ = '&' then token^.kind := LexerKind.and @@ -567,14 +566,14 @@ begin token^.kind := LexerKind.pipe end; increment(@lexer^.current) -end; +end (* Handle an integer literal. *) -proc transition_action_integer(lexer: ^Lexer, token: ^LexerToken); +proc transition_action_integer(lexer: ^Lexer, token: ^LexerToken) var - buffer: String; - integer_length: Word; - found: Bool; + buffer: String + integer_length: Word + found: Bool begin token^.kind := LexerKind.integer; @@ -584,12 +583,12 @@ begin token^.value.identifierKind[cast(token^.value.identifierKind[1]: Int) + 2] := '\0'; token^.value.integerKind := atoi(@token^.value.identifierKind[2]) -end; +end -proc set_default_transition(current_state: TransitionState, default_action: TransitionAction, next_state: TransitionState) -> Int; +proc set_default_transition(current_state: TransitionState, default_action: TransitionAction, next_state: TransitionState) -> Int var - default_transition: Transition; - state_index: Int; + default_transition: Transition + state_index: Int begin default_transition.action := default_action; default_transition.next_state := next_state; @@ -619,7 +618,7 @@ begin transitions[state_index][cast(TransitionClass.other: Int) + 1] := default_transition; return state_index -end; +end (* * The transition table describes transitions from one state to another, given @@ -637,9 +636,9 @@ end; * For the meaning of actions see labels in the lex_next function, which * handles each action. *) -proc initialize_transitions(); +proc initialize_transitions() var - state_index: Int; + state_index: Int begin (* Start state. *) state_index := cast(TransitionState.start: Int) + 1; @@ -877,9 +876,9 @@ begin transitions[state_index][cast(TransitionClass.x: Int) + 1].action := nil; transitions[state_index][cast(TransitionClass.x: Int) + 1].next_state := TransitionState.finish -end; +end -proc lexer_make*(lexer: ^Lexer, input: ^FILE); +proc lexer_make*(lexer: ^Lexer, input: ^FILE) begin lexer^.input := input; lexer^.length := 0u; @@ -887,17 +886,17 @@ begin lexer^.buffer := cast(malloc(CHUNK_SIZE): ^Char); memset(cast(lexer^.buffer: Pointer), 0, CHUNK_SIZE); lexer^.size := CHUNK_SIZE -end; +end (* Returns the last read token. *) -proc lexer_current*(lexer: ^Lexer) -> LexerToken; +proc lexer_current*(lexer: ^Lexer) -> LexerToken var - current_class: TransitionClass; - current_state: TransitionState; - current_transition: Transition; - result: LexerToken; - index1: Word; - index2: Word; + current_class: TransitionClass + current_state: TransitionState + current_transition: Transition + result: LexerToken + index1: Word + index2: Word begin lexer^.current := lexer^.start; current_state := TransitionState.start; @@ -919,12 +918,12 @@ begin result.end_location := lexer^.current.location; return result -end; +end (* Read and return the next token. *) -proc lexer_lex*(lexer: ^Lexer) -> LexerToken; +proc lexer_lex*(lexer: ^Lexer) -> LexerToken var - result: LexerToken; + result: LexerToken begin if lexer^.length = 0u then lexer^.length := fread(cast(lexer^.buffer: Pointer), CHUNK_SIZE, 1u, lexer^.input); @@ -936,17 +935,17 @@ begin result := lexer_current(lexer); return result -end; +end -proc lexer_destroy*(lexer: ^Lexer); +proc lexer_destroy*(lexer: ^Lexer) begin free(cast(lexer^.buffer: Pointer)) -end; +end -proc lexer_initialize(); +proc lexer_initialize() begin initialize_classification(); initialize_transitions() -end; +end end. diff --git a/source/main.elna b/source/main.elna index dae045b..db5e76f 100644 --- a/source/main.elna +++ b/source/main.elna @@ -1,9 +1,8 @@ (* 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; -import cstdio, cctype, common, command_line_interface, lexer; +import cstdio, cstdlib, cstring, cctype, common, command_line_interface, lexer type SourceFile* = record @@ -11,12 +10,12 @@ type handle: ^FILE; size: Word; index: Word - end; + end StringBuffer* = record data: Pointer; size: Word; capacity: Word - end; + end SourceCode = record position: TextLocation; @@ -24,7 +23,7 @@ type empty: proc(Pointer) -> Bool; advance: proc(Pointer); head: proc(Pointer) -> Char - end; + end Token* = record kind: LexerKind; value: union @@ -33,49 +32,49 @@ type boolean_value: Bool; char_value: Char end - end; + end Tokenizer* = record length: Word; data: ^Token - end; + end (* Standard procedures. *) -proc reallocarray(ptr: Pointer, n: Word, size: Word) -> Pointer; +proc reallocarray(ptr: Pointer, n: Word, size: Word) -> Pointer return realloc(ptr, n * size) -end; +end -proc substring(string: String, start: Word, count: Word) -> String; +proc substring(string: String, start: Word, count: Word) -> String return String(string.ptr + start, count) -end; +end -proc open_substring(string: String, start: Word) -> String; +proc open_substring(string: String, start: Word) -> String return substring(string, start, string.length - start) -end; +end -proc string_dup(origin: String) -> String; +proc string_dup(origin: String) -> String var - copy: ^Char; + copy: ^Char begin copy := cast(malloc(origin.length): ^Char); strncpy(copy, origin.ptr, origin.length); return String(copy, origin.length) -end; +end -proc string_buffer_new() -> StringBuffer; +proc string_buffer_new() -> StringBuffer var - result: StringBuffer; + result: StringBuffer begin result.capacity := 64u; result.data := malloc(result.capacity); result.size := 0u; return result -end; +end -proc string_buffer_push(buffer: ^StringBuffer, char: Char); +proc string_buffer_push(buffer: ^StringBuffer, char: Char) begin if buffer^.size >= buffer^.capacity then buffer^.capacity := buffer^.capacity + 1024u; @@ -83,30 +82,30 @@ begin end; cast(buffer^.data + buffer^.size: ^Char)^ := cast(char: Char); buffer^.size := buffer^.size + 1u -end; +end -proc string_buffer_pop(buffer: ^StringBuffer, count: Word); +proc string_buffer_pop(buffer: ^StringBuffer, count: Word) begin buffer^.size := buffer^.size - count -end; +end -proc string_buffer_clear(buffer: ^StringBuffer) -> String; +proc string_buffer_clear(buffer: ^StringBuffer) -> String var - result: String; + result: String begin result := String(cast(buffer^.data: ^Char), buffer^.size); buffer^.size := 0u; return result -end; +end (* Source code stream procedures. *) -proc read_source(filename: ^Char) -> ^SourceFile; +proc read_source(filename: ^Char) -> ^SourceFile var - result: ^SourceFile; - file_handle: ^FILE; + result: ^SourceFile + file_handle: ^FILE begin file_handle := fopen(filename, "rb\0".ptr); @@ -117,11 +116,11 @@ begin result^.index := 1u end; return result -end; +end -proc source_file_empty(source_input: Pointer) -> Bool; +proc source_file_empty(source_input: Pointer) -> Bool var - source_file: ^SourceFile; + source_file: ^SourceFile begin source_file := cast(source_input: ^SourceFile); @@ -131,68 +130,62 @@ begin end; return source_file^.size = 0u -end; +end -proc source_file_head(source_input: Pointer) -> Char; +proc source_file_head(source_input: Pointer) -> Char var - source_file: ^SourceFile; + source_file: ^SourceFile begin source_file := cast(source_input: ^SourceFile); return source_file^.buffer[source_file^.index] -end; +end -proc source_file_advance(source_input: Pointer); +proc source_file_advance(source_input: Pointer) var - source_file: ^SourceFile; + source_file: ^SourceFile begin source_file := cast(source_input: ^SourceFile); source_file^.index := source_file^.index + 1u -end; +end -proc source_code_empty(source_code: ^SourceCode) -> Bool; +proc source_code_empty(source_code: ^SourceCode) -> Bool return source_code^.empty(source_code^.input) -end; +end -proc source_code_head(source_code: SourceCode) -> Char; +proc source_code_head(source_code: SourceCode) -> Char return source_code.head(source_code.input) -end; +end -proc source_code_advance(source_code: ^SourceCode); +proc source_code_advance(source_code: ^SourceCode) begin source_code^.advance(source_code^.input); source_code^.position.column := source_code^.position.column -end; +end -proc source_code_break(source_code: ^SourceCode); +proc source_code_break(source_code: ^SourceCode) begin source_code^.position.line := source_code^.position.line + 1u; source_code^.position.column := 0u -end; +end -proc source_code_expect(source_code: ^SourceCode, expected: Char) -> Bool; +proc source_code_expect(source_code: ^SourceCode, expected: Char) -> Bool return ~source_code_empty(source_code) & source_code_head(source_code^) = expected -end; +end (* Token procedures. *) -proc lexer_escape(escape: Char, result: ^Char) -> Bool; +proc lexer_escape(escape: Char, result: ^Char) -> Bool var - successful: Bool; + successful: Bool begin case escape of 'n': result^ := '\n'; successful := true - | 'a': - result^ := '\a'; - successful := true - | 'b': - result^ := '\b'; - successful := true | 't': result^ := '\t'; successful := true @@ -214,9 +207,6 @@ begin | '"': result^ := '"'; successful := true - | '?': - result^ := '\?'; - successful := true | '0': result^ := '\0'; successful := true @@ -224,12 +214,12 @@ begin successful := false end; return successful -end; +end (* Skip spaces. *) -proc lexer_spaces(source_code: ^SourceCode); +proc lexer_spaces(source_code: ^SourceCode) var - current: Char; + current: Char begin while ~source_code_empty(source_code) & isspace(cast(source_code_head(source_code^): Int)) <> 0 do current := source_code_head(source_code^); @@ -239,26 +229,26 @@ begin end; source_code_advance(source_code) end -end; +end (* Checker whether the character is allowed in an identificator. *) -proc lexer_is_ident(char: Char) -> Bool; +proc lexer_is_ident(char: Char) -> Bool return isalnum(cast(char: Int)) <> 0 or char = '_' -end; +end -proc lexer_identifier(source_code: ^SourceCode, token_content: ^StringBuffer); +proc lexer_identifier(source_code: ^SourceCode, token_content: ^StringBuffer) var - content_length: Word; + content_length: Word begin while ~source_code_empty(source_code) & lexer_is_ident(source_code_head(source_code^)) do string_buffer_push(token_content, source_code_head(source_code^)); source_code_advance(source_code) end -end; +end -proc lexer_comment(source_code: ^SourceCode, token_content: ^StringBuffer) -> Bool; +proc lexer_comment(source_code: ^SourceCode, token_content: ^StringBuffer) -> Bool var - trailing: Word; + trailing: Word begin trailing := 0u; @@ -277,11 +267,11 @@ begin end; return trailing = 2u -end; +end -proc lexer_character(source_code: ^SourceCode, token_content: ^Char) -> Bool; +proc lexer_character(source_code: ^SourceCode, token_content: ^Char) -> Bool var - successful: Bool; + successful: Bool begin successful := ~source_code_empty(source_code); @@ -299,14 +289,14 @@ begin source_code_advance(source_code) end; return successful -end; +end -proc lexer_string(source_code: ^SourceCode, token_content: ^StringBuffer) -> Bool; +proc lexer_string(source_code: ^SourceCode, token_content: ^StringBuffer) -> Bool var - token_end, constructed_string: ^Char; - token_length: Word; - is_valid: Bool := true; - next_char: Char; + token_end, constructed_string: ^Char + token_length: Word + is_valid: Bool := true + next_char: Char begin while is_valid & ~source_code_empty(source_code) & source_code_head(source_code^) <> '"' do is_valid := lexer_character(source_code, @next_char); @@ -322,9 +312,9 @@ begin is_valid := false end; return is_valid -end; +end -proc lexer_number(source_code: ^SourceCode, token_content: ^Int); +proc lexer_number(source_code: ^SourceCode, token_content: ^Int) begin token_content^ := 0; @@ -333,12 +323,12 @@ begin source_code_advance(source_code) end -end; +end (* Categorize an identifier. *) -proc lexer_categorize(token_content: String) -> Token; +proc lexer_categorize(token_content: String) -> Token var - current_token: Token; + current_token: Token begin if token_content = "if" then current_token.kind := LexerKind._if @@ -402,23 +392,23 @@ begin end; return current_token -end; +end -proc lexer_add_token(lexer: ^Tokenizer, token: Token); +proc lexer_add_token(lexer: ^Tokenizer, token: Token) var - new_length: Word; + new_length: Word begin new_length := lexer^.length + 1u; lexer^.data := cast(reallocarray(cast(lexer^.data: Pointer), new_length, #size(Token)): ^Token); (lexer^.data + lexer^.length)^ := token; lexer^.length := new_length -end; +end (* Read the next token from the input. *) -proc lexer_next(source_code: SourceCode, token_buffer: ^StringBuffer) -> Token; +proc lexer_next(source_code: SourceCode, token_buffer: ^StringBuffer) -> Token var - current_token: Token; - first_char: Char; + current_token: Token + first_char: Char begin current_token.kind := LexerKind.unknown; @@ -587,14 +577,14 @@ begin end; return current_token -end; +end (* Split the source text into tokens. *) -proc lexer_text(source_code: SourceCode) -> Tokenizer; +proc lexer_text(source_code: SourceCode) -> Tokenizer var - current_token: Token; - token_buffer: StringBuffer; - lexer: Tokenizer; + current_token: Token + token_buffer: StringBuffer + lexer: Tokenizer begin lexer := Tokenizer(0u, nil); token_buffer := string_buffer_new(); @@ -615,16 +605,16 @@ begin end; return lexer -end; +end (* Parser. *) -proc parse(tokens: ^Token, tokens_size: Word); +proc parse(tokens: ^Token, tokens_size: Word) var - current_token: ^Token; - i: Word := 0u; + current_token: ^Token + i: Word := 0u begin while i < tokens_size do current_token := tokens + i; @@ -777,16 +767,16 @@ begin i := i + 1u end; write_c('\n') -end; +end (* Compilation entry. *) -proc compile_in_stages(command_line: ^CommandLine, source_code: SourceCode) -> Int; +proc compile_in_stages(command_line: ^CommandLine, source_code: SourceCode) -> Int var - return_code: Int := 0; - lexer: Tokenizer; + return_code: Int := 0 + lexer: Tokenizer begin if command_line^.lex or command_line^.parse then lexer := lexer_text(source_code) @@ -796,16 +786,16 @@ begin end; return return_code -end; +end -proc process(argc: Int, argv: ^^Char) -> Int; +proc process(argc: Int, argv: ^^Char) -> Int var - tokens: ^Token; - tokens_size: Word; - source_code: SourceCode; - command_line: ^CommandLine; - return_code: Int := 0; - source_file: ^SourceFile; + tokens: ^Token + tokens_size: Word + source_code: SourceCode + command_line: ^CommandLine + return_code: Int := 0 + source_file: ^SourceFile begin command_line := parse_command_line(argc, argv); if command_line = nil then @@ -835,7 +825,7 @@ begin return_code := compile_in_stages(command_line, source_code) end; return return_code -end; +end return process(count, parameters) end. |
