Implement enumeration
This commit is contained in:
@@ -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;
|
||||
|
1698
boot/stage15.elna
1698
boot/stage15.elna
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user