Implement enumeration

This commit is contained in:
2025-10-04 12:40:07 +02:00
parent 2519b3f9e9
commit af9ad5b712
2 changed files with 868 additions and 922 deletions

View File

@@ -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;