summaryrefslogtreecommitdiff
path: root/boot/stage14.elna
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2025-10-04 12:40:07 +0200
committerEugen Wissner <belka@caraus.de>2025-10-05 11:13:24 +0200
commitaf9ad5b712003b41a981beafe519275b14d6c159 (patch)
tree47081d013dcfda053e765f80e48c8502876d810b /boot/stage14.elna
parent2519b3f9e999fc0f97c61c8f2a26d6c3e4f5f92c (diff)
downloadelna-af9ad5b712003b41a981beafe519275b14d6c159.tar.gz
Implement enumeration
Diffstat (limited to 'boot/stage14.elna')
-rw-r--r--boot/stage14.elna92
1 files changed, 88 insertions, 4 deletions
diff --git a/boot/stage14.elna b/boot/stage14.elna
index 6e5e186..ecb9347 100644
--- a/boot/stage14.elna
+++ b/boot/stage14.elna
@@ -10,6 +10,7 @@
(* - Space independent parsing. *)
(* - Label names in goto statements aren't required to begin with a dot. *)
(* - Dereferencing pointers pointing to word long data. *)
+(* - Enumeration type. *)
const
symbol_builtin_name_int := "Int";
@@ -416,9 +417,21 @@ begin
end;
proc _compile_variable_expression();
+var
+ name: Word;
+ lookup_result: Word;
+ name_token: Word;
begin
- _compile_designator();
- _write_z("\tlw t0, (t0)\n\0")
+ name := _lexer_global_get_start();
+ name_token := _lexer_global_get_end() + -name;
+ lookup_result := _symbol_table_lookup(@symbol_table_global, name, name_token);
+
+ if lookup_result <> 0 then
+ _compile_enumeration_value(lookup_result)
+ else
+ _compile_designator();
+ _write_z("\tlw t0, (t0)\n\0")
+ end
end;
(**
@@ -738,6 +751,50 @@ begin
_write_c('\n')
end;
+proc _compile_enumeration_value(symbol: Word);
+var
+ enumeration_type: Word;
+ members: Word;
+ members_length: Word;
+ token_type: Word;
+ value_name: Word;
+ name_length: Word;
+ member_name: Word;
+ member_length: Word;
+ counter: Word;
+begin
+ enumeration_type := _type_info_get_type(symbol);
+ members := _enumeration_type_get_members(enumeration_type);
+ members_length := _enumeration_type_get_length(enumeration_type);
+
+ (* Skip enumeration type name and dot. Read the enumeration value. *)
+ _lexer_skip_token();
+ _lexer_read_token(@token_type);
+ _lexer_skip_token();
+ _lexer_read_token(@token_type);
+
+ value_name := _lexer_global_get_start();
+ name_length := _lexer_global_get_end() + -value_name;
+ _lexer_skip_token();
+ counter := 1;
+
+ .compile_enumeration_value_members;
+ if members_length > 0 then
+ member_name := _load_word(members);
+ member_length := _load_word(members + 4);
+
+ if _lexer_compare_keyword(value_name, name_length, member_name, member_length) = 0 then
+ members_length := members_length + -1;
+ members := members + 8;
+ counter := counter + 1;
+ goto .compile_enumeration_value_members
+ end;
+ _write_z("\tli t0, \0");
+ _write_i(counter);
+ _write_c('\n')
+ end
+end;
+
proc _compile_designator();
var
name_token: Word;
@@ -1040,7 +1097,7 @@ begin
_enumeration_type_set_members(result, memory_start);
_enumeration_type_set_length(result, member_count);
- return result
+ return _type_info_create(result)
end;
proc _read_type_expression();
@@ -1104,6 +1161,24 @@ begin
return _load_word(this)
end;
+proc _type_info_create(type_representation: Word);
+var
+ result: Word;
+ current_word: Word;
+begin
+ result := memory_free_pointer;
+ current_word := result;
+ (* 1 is INFO_TYPE *)
+ _store_word(1, current_word);
+
+ current_word := current_word + 4;
+ _store_word(type_representation, current_word);
+
+ memory_free_pointer := current_word + 4;
+
+ return result
+end;
+
(**
* Parameters:
* temporary_index - Parameter index.
@@ -1427,11 +1502,20 @@ end;
proc _compile_type_declaration();
var
token_kind: Word;
+ type_name: Word;
+ name_length: Word;
+ type_info: Word;
begin
+ type_name := _lexer_global_get_start();
+ name_length := _lexer_global_get_end() + -type_name;
+
_lexer_skip_token();
_lexer_read_token(@token_kind);
_lexer_skip_token();
- _read_type_expression();
+ type_info := _read_type_expression();
+
+ _symbol_table_enter(@symbol_table_global, type_name, name_length, type_info);
+
_lexer_read_token(@token_kind);
_lexer_skip_token()
end;