diff options
| author | Eugen Wissner <belka@caraus.de> | 2025-10-04 12:40:07 +0200 |
|---|---|---|
| committer | Eugen Wissner <belka@caraus.de> | 2025-10-05 11:13:24 +0200 |
| commit | af9ad5b712003b41a981beafe519275b14d6c159 (patch) | |
| tree | 47081d013dcfda053e765f80e48c8502876d810b /boot/stage14.elna | |
| parent | 2519b3f9e999fc0f97c61c8f2a26d6c3e4f5f92c (diff) | |
| download | elna-af9ad5b712003b41a981beafe519275b14d6c159.tar.gz | |
Implement enumeration
Diffstat (limited to 'boot/stage14.elna')
| -rw-r--r-- | boot/stage14.elna | 92 |
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; |
