Add code generator procedures and enumerations

This commit is contained in:
2025-10-27 12:13:27 +01:00
parent 37a698da91
commit 33f09b1a1f

View File

@@ -152,6 +152,42 @@ type
);
InfoKind = (type_info, parameter_info, temporary_info, procedure_info);
TypeKind = (primitive, enumeration);
ElnaGeneratorKind = (load_immediate);
ElnaGeneratorOperand = (register, immediate);
ElnaGeneratorRegister = (
zero,
ra,
sp,
gp,
tp,
t0,
t1,
t2,
s0,
s1,
a0,
a1,
a2,
a3,
a4,
a5,
a6,
a7,
s2,
s3,
s4,
s5,
s6,
s7,
s8,
s9,
s10,
s11,
t3,
t4,
t5,
t6
);
var
symbol_table_global: Array;
@@ -504,6 +540,107 @@ proc _node_get_kind(this: Word);
return this^
end;
proc _elna_generator_instruction_size();
return 44
end;
proc _elna_generator_instruction_get_kind(this: Word);
return this^
end;
proc _elna_generator_instruction_set_kind(this: Word, value: Word);
begin
this^ := value
end;
proc _elna_generator_instruction_get_next(this: Word);
begin
this := this + 4;
return this^
end;
proc _elna_generator_instruction_set_next(this: Word, value: Word);
begin
this := this + 4;
this^ := value
end;
proc _elna_generator_instruction_get_operand_type(this: Word, n: Word);
begin
n := n - 1;
n := n * 12;
this := this + 8;
this := this + n;
return this^
end;
proc _elna_generator_instruction_get_operand_value(this: Word, n: Word);
begin
n := n - 1;
n := n * 12;
this := this + 8;
this := this + n;
this := this + 4;
return this^
end;
proc _elna_generator_instruction_get_operand_length(this: Word, n: Word);
begin
n := n - 1;
n := n * 12;
this := this + 8;
this := this + n;
this := this + 8;
return this^
end;
proc _elna_generator_instruction_set_operand(this: Word, n: Word, operand_type: Word, operand_value: Word, operand_length: Word);
begin
n := n - 1;
n := n * 12;
this := this + 8;
this := this + n;
this^ := operand_type;
this := this + 4;
this^ := operand_value;
this := this + 4;
this^ := operand_length
end;
proc _elna_generator_load_immediate(target_register: Word, source_immediate: Word, immediate_length: Word);
var
result: Word;
instruction_size: Word;
begin
instruction_size := _elna_generator_instruction_size();
result := _allocate(instruction_size);
_elna_generator_instruction_set_kind(result, ElnaGeneratorKind.load_immediate);
_elna_generator_instruction_set_next(result, 0);
_elna_generator_instruction_set_operand(result, 1, ElnaGeneratorOperand.register, target_register, 0);
_elna_generator_instruction_set_operand(result, 2, ElnaGeneratorOperand.immediate, source_immediate, immediate_length);
return result
end;
proc _elna_writer_instruction(instruction: Word);
var
immediate_value: Word;
immediate_length: Word;
begin
_write_z("\tli t0, \0");
immediate_value := _elna_generator_instruction_get_operand_value(instruction, 2);
immediate_length := _elna_generator_instruction_get_operand_length(instruction, 2);
_write_s(immediate_value, immediate_length);
_write_c('\n')
end;
proc _node_set_kind(this: Word, kind: Word);
begin
this^ := kind
@@ -564,14 +701,13 @@ var
integer_token: Word;
integer_length: Word;
token_kind: Word;
instruction: Word;
begin
_write_z("\tli t0, \0");
integer_token := _integer_literal_node_get_value(integer_literal_node);
integer_length := _integer_literal_node_get_length(integer_literal_node);
_write_s(integer_token, integer_length);
_write_c('\n')
instruction := _elna_generator_load_immediate(ElnaGeneratorRegister.t0, integer_token, integer_length);
_elna_writer_instruction(instruction)
end;
proc _character_literal_node_size();
@@ -628,13 +764,13 @@ proc _compile_character_literal(character_literal_node: Word);
var
character: Word;
character_length: Word;
instruction: Word;
begin
character := _character_literal_node_get_value(character_literal_node);
character_length := _character_literal_node_get_length(character_literal_node);
_write_z("\tli t0, \0");
_write_s(character, character_length);
_write_c('\n')
instruction := _elna_generator_load_immediate(ElnaGeneratorRegister.t0, character, character_length);
_elna_writer_instruction(instruction)
end;
proc _variable_expression_size();
@@ -2385,6 +2521,12 @@ begin
return result
end;
proc _procedure_info_get_symbol_table(this: Word);
begin
this := this + 4;
return this^
end;
(**
* Parameters:
* parameter_index - Parameter index.
@@ -2398,17 +2540,8 @@ begin
name_position := _declaration_get_name(parser_node);
name_length := _declaration_get_length(parser_node);
_write_z("\tsw a\0");
_write_i(parameter_index);
_write_z(", \0");
info := _parameter_info_create(parameter_index);
_symbol_table_enter(symbol_table, name_position, name_length, info);
info := _parameter_info_get_offset(info);
_write_i(info);
_write_z("(sp)\n\0")
_symbol_table_enter(symbol_table, name_position, name_length, info)
end;
(**
@@ -2612,12 +2745,12 @@ var
new_symbol_table: Word;
symbol_info: Word;
begin
new_symbol_table := _symbol_table_create();
symbol_info := _procedure_info_create(new_symbol_table);
name_pointer := _declaration_get_name(parser_node);
name_length := _declaration_get_length(parser_node);
symbol_info := _symbol_table_lookup(@symbol_table_global, name_pointer, name_length);
new_symbol_table := _procedure_info_get_symbol_table(symbol_info);
(* Write .type _procedure_name, @function. *)
_write_z(".type \0");
@@ -2633,23 +2766,27 @@ begin
current_parameter := _procedure_declaration_get_parameters(parser_node);
parameter_counter := 0;
.compile_procedure_declaration_parameter;
if current_parameter = 0 then
goto compile_procedure_declaration_end
.compile_procedure_declaration_parameters;
if current_parameter <> 0 then
name_pointer := _declaration_get_name(current_parameter);
name_length := _declaration_get_length(current_parameter);
symbol_info := _symbol_table_lookup(new_symbol_table, name_pointer, name_length);
symbol_info := _parameter_info_get_offset(symbol_info);
_write_z("\tsw a\0");
_write_i(parameter_counter);
_write_z(", \0");
_write_i(symbol_info);
_write_z("(sp)\n\0");
(* _read_procedure_parameter(current_parameter, parameter_counter, new_symbol_table); *)
parameter_counter := parameter_counter + 1;
current_parameter := _declaration_get_next(current_parameter);
goto compile_procedure_declaration_parameters
end;
_read_procedure_parameter(current_parameter, parameter_counter, new_symbol_table);
parameter_counter := parameter_counter + 1;
current_parameter := _declaration_get_next(current_parameter);
goto compile_procedure_declaration_parameter;
.compile_procedure_declaration_end;
current_parameter := _procedure_declaration_get_temporaries(parser_node);
_read_procedure_temporaries(current_parameter, new_symbol_table);
_symbol_table_enter(@symbol_table_global, name_pointer, name_length, symbol_info);
current_parameter := _procedure_declaration_get_body(parser_node);
_compile_statements(current_parameter, new_symbol_table);
@@ -2821,20 +2958,6 @@ begin
return result
end;
proc _read_type_part(parser_node: Word);
begin
.read_type_part_loop;
if parser_node = 0 then
goto read_type_part_end
end;
_read_type_declaration(parser_node);
parser_node := _declaration_get_next(parser_node);
goto read_type_part_loop;
.read_type_part_end
end;
proc _variable_declaration_size();
return 20
end;
@@ -3076,12 +3199,59 @@ begin
_write_c('\n')
end;
proc _read_procedure_declaration(parser_node: Word);
var
name_pointer: Word;
name_length: Word;
new_symbol_table: Word;
parameter_counter: Word;
symbol_info: Word;
current_parameter: Word;
begin
new_symbol_table := _symbol_table_create();
symbol_info := _procedure_info_create(new_symbol_table);
name_pointer := _declaration_get_name(parser_node);
name_length := _declaration_get_length(parser_node);
current_parameter := _procedure_declaration_get_parameters(parser_node);
parameter_counter := 0;
.compile_procedure_declaration_parameter;
if current_parameter <> 0 then
_read_procedure_parameter(current_parameter, parameter_counter, new_symbol_table);
parameter_counter := parameter_counter + 1;
current_parameter := _declaration_get_next(current_parameter);
goto compile_procedure_declaration_parameter
end;
current_parameter := _procedure_declaration_get_temporaries(parser_node);
_read_procedure_temporaries(current_parameter, new_symbol_table);
_symbol_table_enter(@symbol_table_global, name_pointer, name_length, symbol_info)
end;
proc _read_module_declaration(parser_node: Word);
var
current_part: Word;
result: Word;
begin
current_part := _module_declaration_get_types(parser_node);
_read_type_part(current_part)
.read_module_declaration_type;
if current_part <> 0 then
_read_type_declaration(current_part);
current_part := _declaration_get_next(current_part);
goto read_module_declaration_type
end;
current_part := _module_declaration_get_procedures(parser_node);
.read_module_declaration_procedure;
if current_part <> 0 then
_read_procedure_declaration(current_part);
current_part := _declaration_get_next(current_part);
goto read_module_declaration_procedure
end
end;
proc _compile();