aboutsummaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/cctype.elna23
-rw-r--r--source/command_line_interface.elna18
-rw-r--r--source/common.elna40
-rw-r--r--source/cstdio.elna49
-rw-r--r--source/cstdlib.elna22
-rw-r--r--source/cstring.elna27
-rw-r--r--source/lexer.elna139
-rw-r--r--source/main.elna218
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.