diff options
| author | Eugen Wissner <belka@caraus.de> | 2026-10-03 20:51:22 +0200 |
|---|---|---|
| committer | Eugen Wissner <belka@caraus.de> | 2026-10-03 20:51:22 +0200 |
| commit | e4ce7f658741a7428597da4872435a1b0bae944c (patch) | |
| tree | 50f65abf6fa4468db7bc93a6ae61d623a2dd8566 /source/main.elna | |
| parent | 5d808dd4c4003968bbdf180e1e1193231db5d43b (diff) | |
| download | elna-e4ce7f658741a7428597da4872435a1b0bae944c.tar.gz | |
Rework generics for parameters to be plain types
Diffstat (limited to 'source/main.elna')
| -rw-r--r-- | source/main.elna | 196 |
1 files changed, 89 insertions, 107 deletions
diff --git a/source/main.elna b/source/main.elna index adac5ac..26853c3 100644 --- a/source/main.elna +++ b/source/main.elna @@ -14,17 +14,17 @@ type index: Word end StringBuffer* = record - data: Pointer; + data: ^Word8; size: Word; capacity: Word end - SourceCode = record + SourceCode#[T] = record position: ElnaLocation; - input: Pointer; - empty: proc(stream: Pointer) -> Bool; - advance: proc(stream: Pointer); - head: proc(stream: Pointer) -> Word8 + input: ^T; + empty: proc(stream: ^T) -> Bool; + advance: proc(stream: ^T); + head: proc(stream: ^T) -> Word8 end Tokenizer* = record length: Word; @@ -34,14 +34,11 @@ type (* Standard procedures. *) -proc reallocarray(ptr: Pointer; n: Word; size: Word) -> Pointer -return realloc(ptr, n * size) - proc string_dup(origin: []const Word8) -> []const Word8 var copy: ^Word8 begin - copy := malloc(origin.length); + copy := malloc#[Word8](origin.length); strncpy(copy, origin.ptr, origin.length) return copy[1 to origin.length] @@ -50,7 +47,7 @@ var result: StringBuffer begin result.capacity := 64u; - result.data := malloc(result.capacity); + result.data := malloc#[Word8](result.capacity); result.size := 0u return result @@ -89,60 +86,46 @@ begin file_handle := fopen(filename, "rb\0".ptr); if file_handle <> nil then - result := malloc(#size(SourceFile)); + result := malloc#[SourceFile](#size(SourceFile)); result^.handle := file_handle; result^.size := 0u; result^.index := 1u end return result -proc source_file_empty(source_input: Pointer) -> Bool -var - source_file: ^SourceFile -begin - source_file := cast(source_input: ^SourceFile); - - if source_file^.index > source_file^.size then - source_file^.size := fread(cast(@source_file^.buffer: Pointer), 1u, 1024u, source_file^.handle); - source_file^.index := 1u +proc source_file_empty(source_input: ^SourceFile) -> Bool + if source_input^.index > source_input^.size then + source_input^.size := fread(source_input^.buffer.ptr, 1u, 1024u, source_input^.handle); + source_input^.index := 1u end -return source_file^.size = 0u +return source_input^.size = 0u -proc source_file_head(source_input: Pointer) -> Word8 -var - source_file: ^SourceFile -begin - source_file := cast(source_input: ^SourceFile) -return source_file^.buffer[source_file^.index] - -proc source_file_advance(source_input: Pointer) -var - source_file: ^SourceFile -begin - source_file := cast(source_input: ^SourceFile); +proc source_file_head(source_input: ^SourceFile) -> Word8 +return source_input^.buffer[source_input^.index] - source_file^.index := source_file^.index + 1u +proc source_file_advance(source_input: ^SourceFile) + source_input^.index := source_input^.index + 1u return -proc source_code_empty(source_code: ^SourceCode) -> Bool +proc source_code_empty#[T](source_code: ^SourceCode#[T]) -> Bool return source_code^.empty(source_code^.input) -proc source_code_head(source_code: SourceCode) -> Word8 +proc source_code_head#[T](source_code: SourceCode#[T]) -> Word8 return source_code.head(source_code.input) -proc source_code_advance(source_code: ^SourceCode) +proc source_code_advance#[T](source_code: ^SourceCode#[T]) begin source_code^.advance(source_code^.input); source_code^.position.column := source_code^.position.column return -proc source_code_break(source_code: ^SourceCode) +proc source_code_break#[T](source_code: ^SourceCode#[T]) begin source_code^.position.line := source_code^.position.line + 1u; source_code^.position.column := 0u return -proc source_code_expect(source_code: ^SourceCode; expected: Word8) -> Bool +proc source_code_expect#[T](source_code: ^SourceCode#[T]; expected: Word8) -> Bool return ~source_code_empty(source_code) & source_code_head(source_code^) = expected (* @@ -187,7 +170,7 @@ begin return successful (* Skip spaces. *) -proc lexer_spaces(source_code: ^SourceCode) +proc lexer_spaces#[T](source_code: ^SourceCode#[T]) var current: Word8 begin @@ -205,7 +188,7 @@ return proc lexer_is_ident(char: Word8) -> Bool return isalnum(cast(char: Int)) <> 0 or char = '_' -proc lexer_identifier(source_code: ^SourceCode; token_content: ^StringBuffer) +proc lexer_identifier#[T](source_code: ^SourceCode#[T]; token_content: ^StringBuffer) var content_length: Word begin @@ -215,7 +198,7 @@ begin end return -proc lexer_comment(source_code: ^SourceCode; token_content: ^StringBuffer) -> Bool +proc lexer_comment#[T](source_code: ^SourceCode#[T]; token_content: ^StringBuffer) -> Bool var trailing: Word begin @@ -236,7 +219,7 @@ begin end return trailing = 2u -proc lexer_character(source_code: ^SourceCode; token_content: ^Word8) -> Bool +proc lexer_character#[T](source_code: ^SourceCode#[T]; token_content: ^Word8) -> Bool var successful: Bool begin @@ -257,7 +240,7 @@ begin end return successful -proc lexer_string(source_code: ^SourceCode; token_content: ^StringBuffer) -> Bool +proc lexer_string#[T](source_code: ^SourceCode#[T]; token_content: ^StringBuffer) -> Bool var token_end, constructed_string: ^Word8 token_length: Word @@ -279,7 +262,7 @@ begin end return is_valid -proc lexer_number(source_code: ^SourceCode; token_content: ^Int) +proc lexer_number#[T](source_code: ^SourceCode#[T]; token_content: ^Int) begin token_content^ := 0; @@ -296,81 +279,81 @@ var current_token: ^ElnaLexerToken begin if token_content = "if" then - current_token := malloc(#size(ElnaLexerToken)); + current_token := malloc#[ElnaLexerToken](#size(ElnaLexerToken)); current_token^.kind := ElnaLexerKind._if elsif token_content = "then" then - current_token := malloc(#size(ElnaLexerToken)); + current_token := malloc#[ElnaLexerToken](#size(ElnaLexerToken)); current_token^.kind := ElnaLexerKind._then elsif token_content = "else" then - current_token := malloc(#size(ElnaLexerToken)); + current_token := malloc#[ElnaLexerToken](#size(ElnaLexerToken)); current_token^.kind := ElnaLexerKind._else elsif token_content = "elsif" then - current_token := malloc(#size(ElnaLexerToken)); + current_token := malloc#[ElnaLexerToken](#size(ElnaLexerToken)); current_token^.kind := ElnaLexerKind._elsif elsif token_content = "while" then - current_token := malloc(#size(ElnaLexerToken)); + current_token := malloc#[ElnaLexerToken](#size(ElnaLexerToken)); current_token^.kind := ElnaLexerKind._while elsif token_content = "do" then - current_token := malloc(#size(ElnaLexerToken)); + current_token := malloc#[ElnaLexerToken](#size(ElnaLexerToken)); current_token^.kind := ElnaLexerKind._do elsif token_content = "proc" then - current_token := malloc(#size(ElnaLexerToken)); + current_token := malloc#[ElnaLexerToken](#size(ElnaLexerToken)); current_token^.kind := ElnaLexerKind._proc elsif token_content = "begin" then - current_token := malloc(#size(ElnaLexerToken)); + current_token := malloc#[ElnaLexerToken](#size(ElnaLexerToken)); current_token^.kind := ElnaLexerKind._begin elsif token_content = "end" then - current_token := malloc(#size(ElnaLexerToken)); + current_token := malloc#[ElnaLexerToken](#size(ElnaLexerToken)); current_token^.kind := ElnaLexerKind._end elsif token_content = "extern" then - current_token := malloc(#size(ElnaLexerToken)); + current_token := malloc#[ElnaLexerToken](#size(ElnaLexerToken)); current_token^.kind := ElnaLexerKind._extern elsif token_content = "const" then - current_token := malloc(#size(ElnaLexerToken)); + current_token := malloc#[ElnaLexerToken](#size(ElnaLexerToken)); current_token^.kind := ElnaLexerKind._const elsif token_content = "var" then - current_token := malloc(#size(ElnaLexerToken)); + current_token := malloc#[ElnaLexerToken](#size(ElnaLexerToken)); current_token^.kind := ElnaLexerKind._var elsif token_content = "case" then - current_token := malloc(#size(ElnaLexerToken)); + current_token := malloc#[ElnaLexerToken](#size(ElnaLexerToken)); current_token^.kind := ElnaLexerKind._case elsif token_content = "of" then - current_token := malloc(#size(ElnaLexerToken)); + current_token := malloc#[ElnaLexerToken](#size(ElnaLexerToken)); current_token^.kind := ElnaLexerKind._of elsif token_content = "type" then - current_token := malloc(#size(ElnaLexerToken)); + current_token := malloc#[ElnaLexerToken](#size(ElnaLexerToken)); current_token^.kind := ElnaLexerKind._type elsif token_content = "record" then - current_token := malloc(#size(ElnaLexerToken)); + current_token := malloc#[ElnaLexerToken](#size(ElnaLexerToken)); current_token^.kind := ElnaLexerKind._record elsif token_content = "true" then - current_token := malloc(#size(ElnaLexerBooleanToken)); + current_token := malloc#[ElnaLexerBooleanToken](#size(ElnaLexerBooleanToken)); current_token^.kind := ElnaLexerKind.boolean; cast(current_token: ^ElnaLexerBooleanToken)^.value := true elsif token_content = "false" then - current_token := malloc(#size(ElnaLexerBooleanToken)); + current_token := malloc#[ElnaLexerBooleanToken](#size(ElnaLexerBooleanToken)); current_token^.kind := ElnaLexerKind.boolean; cast(current_token: ^ElnaLexerBooleanToken)^.value := false elsif token_content = "nil" then - current_token := malloc(#size(ElnaLexerToken)); + current_token := malloc#[ElnaLexerToken](#size(ElnaLexerToken)); current_token^.kind := ElnaLexerKind.null elsif token_content = "or" then - current_token := malloc(#size(ElnaLexerToken)); + current_token := malloc#[ElnaLexerToken](#size(ElnaLexerToken)); current_token^.kind := ElnaLexerKind._or elsif token_content = "return" then - current_token := malloc(#size(ElnaLexerToken)); + current_token := malloc#[ElnaLexerToken](#size(ElnaLexerToken)); current_token^.kind := ElnaLexerKind._return elsif token_content = "cast" then - current_token := malloc(#size(ElnaLexerToken)); + current_token := malloc#[ElnaLexerToken](#size(ElnaLexerToken)); current_token^.kind := ElnaLexerKind._cast elsif token_content = "defer" then - current_token := malloc(#size(ElnaLexerToken)); + current_token := malloc#[ElnaLexerToken](#size(ElnaLexerToken)); current_token^.kind := ElnaLexerKind._defer elsif token_content = "import" then - current_token := malloc(#size(ElnaLexerToken)); + current_token := malloc#[ElnaLexerToken](#size(ElnaLexerToken)); current_token^.kind := ElnaLexerKind._import else - current_token := malloc(#size(ElnaLexerStringToken)); + current_token := malloc#[ElnaLexerStringToken](#size(ElnaLexerStringToken)); current_token^.kind := ElnaLexerKind.identifier; cast(current_token: ^ElnaLexerStringToken)^.value := string_dup(token_content) end @@ -381,13 +364,13 @@ var new_length: Word begin new_length := lexer^.length + 1u; - lexer^.data := cast(reallocarray(cast(lexer^.data: Pointer), new_length, #size(Pointer)): ^^ElnaLexerToken); + lexer^.data := realloc#[^ElnaLexerToken](lexer^.data, new_length * #size(^ElnaLexerToken)); (lexer^.data + lexer^.length)^ := token; lexer^.length := new_length return (* Read the next token from the input. *) -proc lexer_next(source_code: SourceCode; token_buffer: ^StringBuffer) -> ^ElnaLexerToken +proc lexer_next#[T](source_code: SourceCode#[T]; token_buffer: ^StringBuffer) -> ^ElnaLexerToken var current_token: ^ElnaLexerToken := nil first_char: Word8 @@ -401,11 +384,11 @@ begin source_code_advance(@source_code); lexer_identifier(@source_code, token_buffer); - current_token := malloc(#size(ElnaLexerStringToken)); + current_token := malloc#[ElnaLexerStringToken](#size(ElnaLexerStringToken)); current_token^.kind := ElnaLexerKind.trait; cast(current_token: ^ElnaLexerStringToken)^.value := string_dup(string_buffer_clear(token_buffer)) elsif isdigit(cast(first_char: Int)) <> 0 then - current_token := malloc(#size(ElnaLexerIntegerToken)); + current_token := malloc#[ElnaLexerIntegerToken](#size(ElnaLexerIntegerToken)); lexer_number(@source_code, @cast(current_token: ^ElnaLexerIntegerToken)^.value); if source_code_expect(@source_code, 'u') then @@ -418,37 +401,37 @@ begin source_code_advance(@source_code); if source_code_empty(@source_code) then - current_token := malloc(#size(ElnaLexerToken)); + current_token := malloc#[ElnaLexerToken](#size(ElnaLexerToken)); current_token^.kind := ElnaLexerKind.left_paren elsif source_code_head(source_code) = '*' then source_code_advance(@source_code); if lexer_comment(@source_code, token_buffer) then - current_token := malloc(#size(ElnaLexerStringToken)); + current_token := malloc#[ElnaLexerStringToken](#size(ElnaLexerStringToken)); cast(current_token: ^ElnaLexerStringToken)^.value := string_dup(string_buffer_clear(token_buffer)); current_token^.kind := ElnaLexerKind.comment end else - current_token := malloc(#size(ElnaLexerToken)); + current_token := malloc#[ElnaLexerToken](#size(ElnaLexerToken)); current_token^.kind := ElnaLexerKind.left_paren end elsif first_char = ')' then - current_token := malloc(#size(ElnaLexerToken)); + current_token := malloc#[ElnaLexerToken](#size(ElnaLexerToken)); current_token^.kind := ElnaLexerKind.right_paren; source_code_advance(@source_code) elsif first_char = '{' then - current_token := malloc(#size(ElnaLexerToken)); + current_token := malloc#[ElnaLexerToken](#size(ElnaLexerToken)); current_token^.kind := ElnaLexerKind.left_brace; source_code_advance(@source_code) elsif first_char = '}' then - current_token := malloc(#size(ElnaLexerToken)); + current_token := malloc#[ElnaLexerToken](#size(ElnaLexerToken)); current_token^.kind := ElnaLexerKind.right_brace; source_code_advance(@source_code) elsif first_char = '\'' then source_code_advance(@source_code); if lexer_character(@source_code, @first_char) & source_code_expect(@source_code, '\'') then - current_token := malloc(#size(ElnaLexerCharacterToken)); + current_token := malloc#[ElnaLexerCharacterToken](#size(ElnaLexerCharacterToken)); current_token^.kind := ElnaLexerKind.character; cast(current_token: ^ElnaLexerCharacterToken)^.value := first_char; source_code_advance(@source_code) @@ -457,21 +440,21 @@ begin source_code_advance(@source_code); if lexer_string(@source_code, token_buffer) then - current_token := malloc(#size(ElnaLexerStringToken)); + current_token := malloc#[ElnaLexerStringToken](#size(ElnaLexerStringToken)); current_token^.kind := ElnaLexerKind.string; cast(current_token: ^ElnaLexerStringToken)^.value := string_dup(string_buffer_clear(token_buffer)) end elsif first_char = '[' then - current_token := malloc(#size(ElnaLexerToken)); + current_token := malloc#[ElnaLexerToken](#size(ElnaLexerToken)); current_token^.kind := ElnaLexerKind.left_square; source_code_advance(@source_code) elsif first_char = ']' then - current_token := malloc(#size(ElnaLexerToken)); + current_token := malloc#[ElnaLexerToken](#size(ElnaLexerToken)); current_token^.kind := ElnaLexerKind.right_square; source_code_advance(@source_code) elsif first_char = '>' then source_code_advance(@source_code); - current_token := malloc(#size(ElnaLexerToken)); + current_token := malloc#[ElnaLexerToken](#size(ElnaLexerToken)); if source_code_empty(@source_code) then current_token^.kind := ElnaLexerKind.greater_than @@ -486,7 +469,7 @@ begin end elsif first_char = '<' then source_code_advance(@source_code); - current_token := malloc(#size(ElnaLexerToken)); + current_token := malloc#[ElnaLexerToken](#size(ElnaLexerToken)); if source_code_empty(@source_code) then current_token^.kind := ElnaLexerKind.less_than @@ -503,28 +486,28 @@ begin current_token^.kind := ElnaLexerKind.less_than end elsif first_char = '=' then - current_token := malloc(#size(ElnaLexerToken)); + current_token := malloc#[ElnaLexerToken](#size(ElnaLexerToken)); current_token^.kind := ElnaLexerKind.equals; source_code_advance(@source_code) elsif first_char = ';' then - current_token := malloc(#size(ElnaLexerToken)); + current_token := malloc#[ElnaLexerToken](#size(ElnaLexerToken)); current_token^.kind := ElnaLexerKind.semicolon; source_code_advance(@source_code) elsif first_char = '.' then - current_token := malloc(#size(ElnaLexerToken)); + current_token := malloc#[ElnaLexerToken](#size(ElnaLexerToken)); current_token^.kind := ElnaLexerKind.dot; source_code_advance(@source_code) elsif first_char = ',' then - current_token := malloc(#size(ElnaLexerToken)); + current_token := malloc#[ElnaLexerToken](#size(ElnaLexerToken)); current_token^.kind := ElnaLexerKind.comma; source_code_advance(@source_code) elsif first_char = '+' then - current_token := malloc(#size(ElnaLexerToken)); + current_token := malloc#[ElnaLexerToken](#size(ElnaLexerToken)); current_token^.kind := ElnaLexerKind.plus; source_code_advance(@source_code) elsif first_char = '-' then source_code_advance(@source_code); - current_token := malloc(#size(ElnaLexerToken)); + current_token := malloc#[ElnaLexerToken](#size(ElnaLexerToken)); if source_code_empty(@source_code) then current_token^.kind := ElnaLexerKind.minus @@ -535,20 +518,20 @@ begin current_token^.kind := ElnaLexerKind.minus end elsif first_char = '*' then - current_token := malloc(#size(ElnaLexerToken)); + current_token := malloc#[ElnaLexerToken](#size(ElnaLexerToken)); current_token^.kind := ElnaLexerKind.multiplication; source_code_advance(@source_code) elsif first_char = '/' then - current_token := malloc(#size(ElnaLexerToken)); + current_token := malloc#[ElnaLexerToken](#size(ElnaLexerToken)); current_token^.kind := ElnaLexerKind.division; source_code_advance(@source_code) elsif first_char = '%' then - current_token := malloc(#size(ElnaLexerToken)); + current_token := malloc#[ElnaLexerToken](#size(ElnaLexerToken)); current_token^.kind := ElnaLexerKind.remainder; source_code_advance(@source_code) elsif first_char = ':' then source_code_advance(@source_code); - current_token := malloc(#size(ElnaLexerToken)); + current_token := malloc#[ElnaLexerToken](#size(ElnaLexerToken)); if source_code_empty(@source_code) then current_token^.kind := ElnaLexerKind.colon @@ -559,34 +542,34 @@ begin current_token^.kind := ElnaLexerKind.colon end elsif first_char = '^' then - current_token := malloc(#size(ElnaLexerToken)); + current_token := malloc#[ElnaLexerToken](#size(ElnaLexerToken)); current_token^.kind := ElnaLexerKind.hat; source_code_advance(@source_code) elsif first_char = '@' then - current_token := malloc(#size(ElnaLexerToken)); + current_token := malloc#[ElnaLexerToken](#size(ElnaLexerToken)); current_token^.kind := ElnaLexerKind.at; source_code_advance(@source_code) elsif first_char = '!' then - current_token := malloc(#size(ElnaLexerToken)); + current_token := malloc#[ElnaLexerToken](#size(ElnaLexerToken)); current_token^.kind := ElnaLexerKind.exclamation; source_code_advance(@source_code) elsif first_char = '&' then - current_token := malloc(#size(ElnaLexerToken)); + current_token := malloc#[ElnaLexerToken](#size(ElnaLexerToken)); current_token^.kind := ElnaLexerKind.and; source_code_advance(@source_code) elsif first_char = '~' then - current_token := malloc(#size(ElnaLexerToken)); + current_token := malloc#[ElnaLexerToken](#size(ElnaLexerToken)); current_token^.kind := ElnaLexerKind.not; source_code_advance(@source_code) elsif first_char = '|' then - current_token := malloc(#size(ElnaLexerToken)); + current_token := malloc#[ElnaLexerToken](#size(ElnaLexerToken)); current_token^.kind := ElnaLexerKind.pipe; source_code_advance(@source_code) end return current_token (* Split the source text into tokens. *) -proc lexer_text(source_code: SourceCode) -> Tokenizer +proc lexer_text#[T](source_code: SourceCode#[T]) -> Tokenizer var current_token: ^ElnaLexerToken token_buffer: StringBuffer @@ -769,7 +752,7 @@ return Compilation entry. *) -proc compile_in_stages(command_line: ^CommandLine; source_code: SourceCode) -> Int +proc compile_in_stages#[T](command_line: ^CommandLine; source_code: SourceCode#[T]) -> Int var return_code: Int := 0 lexer: Tokenizer @@ -786,7 +769,7 @@ proc process(argc: Int; argv: ^^Word8) -> Int var tokens: ^ElnaLexerToken tokens_size: Word - source_code: SourceCode + source_code: SourceCode#[SourceFile] command_line: ^CommandLine return_code: Int := 0 source_file: ^SourceFile @@ -821,7 +804,6 @@ begin return return_code proc initialize_global_state() -begin stdin := fdopen(0, "r\0".ptr); stdout := fdopen(1, "w\0".ptr); stderr := fdopen(2, "w\0".ptr) |
