summaryrefslogtreecommitdiff
path: root/boot
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2025-12-17 00:52:46 +0100
committerEugen Wissner <belka@caraus.de>2025-12-17 12:00:25 +0100
commit3a8bf8ae8810e4dddbce75de0d811ea3e37d4e69 (patch)
tree68170be4959126c1edc8190497db3a58ab3704da /boot
parent1cf71f1a5f5208db3d88c25c45b531096db12496 (diff)
downloadelna-3a8bf8ae8810e4dddbce75de0d811ea3e37d4e69.tar.gz
Preserve passed procedure parameters
Diffstat (limited to 'boot')
-rw-r--r--boot/stage17/cl.elna216
1 files changed, 90 insertions, 126 deletions
diff --git a/boot/stage17/cl.elna b/boot/stage17/cl.elna
index b40e2e0..4209824 100644
--- a/boot/stage17/cl.elna
+++ b/boot/stage17/cl.elna
@@ -26,7 +26,9 @@ type
name: Word;
length: Word;
body: Word;
- stack: Word
+ stack: Word;
+ parameters: Word;
+ count: Word
end;
ElnaTreeNode = record
kind: Word
@@ -239,11 +241,6 @@ type
kind: Word;
_type: Word
end;
- ElnaSymbolParameterInfo = record
- kind: Word;
- offset: Word;
- variable_type: Word
- end;
ElnaSymbolTemporaryInfo = record
kind: Word;
offset: Word;
@@ -467,8 +464,8 @@ type
allocate_stack,
ret
);
- ElnaTacOperand = (temporary, immediate, symbol, stack, pseudo, list);
- ElnaRtlOperand = (register, immediate, symbol, offset, pseudo);
+ ElnaTacOperand = (temporary, immediate, symbol, pseudo, list);
+ ElnaRtlOperand = (register, immediate, symbol, pseudo, offset);
ElnaRtlRegister = (
zero,
ra,
@@ -833,10 +830,6 @@ begin
result := elna_rtl_instruction_create(ElnaRtlOperator.li);
elna_rtl_instruction_set_operand(result, 1, ElnaRtlOperand.register, into, 0);
elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.immediate, operand_value, operand_length)
- elsif operand_type = ElnaTacOperand.stack then
- result := elna_rtl_instruction_create(ElnaRtlOperator.lw);
- elna_rtl_instruction_set_operand(result, 1, ElnaRtlOperand.register, into, 0);
- elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.offset, ElnaRtlRegister.sp, operand_value)
elsif operand_type = ElnaTacOperand.symbol then
result := elna_rtl_instruction_create(ElnaRtlOperator.la);
elna_rtl_instruction_set_operand(result, 1, ElnaRtlOperand.register, into, 0);
@@ -1074,13 +1067,7 @@ begin
operand_value := _elna_tac_instruction_get_operand_value(tac_instruction, 2);
operand_length := _elna_tac_instruction_get_operand_length(tac_instruction, 2);
- if operand_type = ElnaTacOperand.stack then
- result := elna_rtl_instruction_create(ElnaRtlOperator.add);
-
- elna_rtl_copy_operand(tac_instruction, 1, result);
- elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.register, ElnaRtlRegister.sp, 0);
- elna_rtl_instruction_set_operand(result, 3, ElnaRtlOperand.immediate, operand_value, 0)
- elsif operand_type = ElnaTacOperand.symbol then
+ if operand_type = ElnaTacOperand.symbol then
result := elna_rtl_instruction_create(ElnaRtlOperator.la);
elna_rtl_copy_operand(tac_instruction, 1, result);
@@ -1126,9 +1113,7 @@ begin
operand_type := _elna_tac_instruction_get_operand_type(tac_instruction, 2);
operand_value := _elna_tac_instruction_get_operand_value(tac_instruction, 2);
operand_length := _elna_tac_instruction_get_operand_length(tac_instruction, 2);
- if operand_type = ElnaTacOperand.stack then
- elna_rtl_instruction_set_operand(next_instruction^, 2, ElnaRtlOperand.offset, ElnaRtlRegister.sp, operand_value)
- elsif operand_type = ElnaTacOperand.pseudo then
+ if operand_type = ElnaTacOperand.pseudo then
elna_rtl_instruction_set_operand(next_instruction^, 2, ElnaRtlOperand.pseudo, operand_value, operand_length)
end;
if operands = 0 then
@@ -1589,7 +1574,7 @@ var
stack_instruction: ^ElnaInstructionList;
begin
.elna_alloc_procedure_loop;
- temporary_variable_counter := 32;
+ temporary_variable_counter := 4;
variable_map := 0;
elna_alloc_instructions(rtl_declaration^.body);
@@ -1837,20 +1822,14 @@ end;
proc _elna_tac_variable_expression(variable_expression: ^ElnaTreeVariableExpression, symbol_table: Word, operand_type: Word, operand_value: Word, operand_length: Word);
var
- lookup_result: ^ElnaSymbolParameterInfo;
+ lookup_result: ^ElnaSymbolTemporaryInfo;
begin
lookup_result := _symbol_table_lookup(symbol_table, variable_expression^.name, variable_expression^.length);
if lookup_result <> nil then
- if lookup_result^.kind = ElnaSymbolInfoKind.temporary_info then
- operand_type^ := ElnaTacOperand.pseudo;
- operand_value^ := variable_expression^.name;
- operand_length^ := variable_expression^.length
- else
- operand_type^ := ElnaTacOperand.stack;
- operand_value^ := lookup_result^.offset;
- operand_length^ := 0
- end
+ operand_type^ := ElnaTacOperand.pseudo;
+ operand_value^ := variable_expression^.name;
+ operand_length^ := variable_expression^.length
else
operand_type^ := ElnaTacOperand.symbol;
operand_value^ := variable_expression^.name;
@@ -3365,27 +3344,6 @@ begin
return result
end;
-(**
- * Parameters:
- * parameter_index - Parameter index.
- * parameter_type - Parameter type.
- *)
-proc _parameter_info_create(parameter_index: Word, parameter_type: Word);
-var
- offset: Word;
- result: ^ElnaSymbolParameterInfo;
-begin
- result := malloc(ElnaSymbolParameterInfo_size());
- result^.kind := ElnaSymbolInfoKind.parameter_info;
-
- (* Calculate the stack offset: 28 - (4 * parameter_counter) *)
- offset := parameter_index * 4;
- result^.offset := 28 - offset;
- result^.variable_type := parameter_type;
-
- return result
-end;
-
proc _type_info_create(type_representation: Word);
var
result: ^ElnaSymbolTypeInfo;
@@ -3433,21 +3391,6 @@ end;
(**
* Parameters:
- * parameter_index - Parameter index.
- *)
-proc elna_name_procedure_parameter(parser_node: ^ElnaTreeVariableDeclaration, parameter_index: Word, symbol_table: Word);
-var
- info: Word;
- variable_type1: Word;
-begin
- variable_type1 := elna_name_type_expression(parser_node^._type);
-
- info := _parameter_info_create(parameter_index, variable_type1);
- _symbol_table_enter(symbol_table, parser_node^.name, parser_node^.length, info)
-end;
-
-(**
- * Parameters:
* variable_index - Variable index.
*)
proc elna_name_procedure_temporary(parser_node: ^ElnaTreeVariableDeclaration, variable_index: Word, symbol_table: Word);
@@ -3552,39 +3495,43 @@ begin
return result
end;
-proc _elna_tac_parameters(current_parameter: ^ElnaTreeDeclaration, new_symbol_table: Word);
+proc _elna_tac_parameters(ast_list: ^ElnaTreeDeclaration, parameter_count: ^Word);
var
- name_pointer: Word;
- name_length: Word;
- parameter_counter: Word;
- instruction: Word;
- first_instruction: Word;
- current_instruction: Word;
- symbol_info: ^ElnaSymbolParameterInfo;
+ ast_parameter: ^ElnaTreeDeclaration;
+ parameter_index: Word;
+ current_parameter: Word;
+ parameter_list: Word;
begin
- first_instruction := 0;
- parameter_counter := 0;
+ ast_parameter := ast_list;
+ parameter_count^ := 0;
- .elna_tac_parameters_loop;
- if current_parameter <> 0 then
- symbol_info := _symbol_table_lookup(new_symbol_table, current_parameter^.name, current_parameter^.length);
+ .elna_tac_parameters_count;
+ if ast_parameter <> nil then
+ ast_parameter := ast_parameter^.next;
+ parameter_count^ := parameter_count^ + 1;
- instruction := _elna_tac_instruction_create(ElnaTacOperator.store);
- _elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.temporary, 11 + parameter_counter, 0);
- _elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.stack, symbol_info^.offset, 0);
- if first_instruction = nil then
- first_instruction := instruction
- else
- elna_instruction_list_concatenate(current_instruction, instruction)
- end;
- current_instruction := instruction;
+ goto elna_tac_parameters_count
+ end;
+ (* The parameters are saved as an array of name pointer + name length. *)
+ parameter_list := malloc(parameter_count^ * 8);
+ current_parameter := parameter_list;
- parameter_counter := parameter_counter + 1;
+ ast_parameter := ast_list;
+ parameter_index := 0;
- current_parameter := current_parameter^.next;
+ .elna_tac_parameters_loop;
+ if parameter_index < parameter_count^ then
+ current_parameter^ := ast_parameter^.name;
+ current_parameter := current_parameter + 4;
+ current_parameter^ := ast_parameter^.length;
+ current_parameter := current_parameter + 4;
+
+ parameter_index := parameter_index + 1;
+ ast_parameter := ast_parameter^.next;
goto elna_tac_parameters_loop
end;
- return first_instruction
+
+ return parameter_list
end;
proc elna_rtl_global_declaration(tac_declaration: ^ElnaInstructionDeclaration);
@@ -3601,9 +3548,48 @@ begin
return result
end;
+proc elna_rtl_parameters(parameters: Word, count: Word);
+var
+ result: Word;
+ current_instruction: Word;
+ last_instruction: Word;
+ parameter_index: Word;
+ parameter_name: Word;
+ name_length: Word;
+begin
+ result := nil;
+ parameter_index := 0;
+
+ .elna_rtl_parameters_loop;
+ if parameter_index < count then
+ parameter_name := parameters^;
+ parameters := parameters + 4;
+ name_length := parameters^;
+ parameters := parameters + 4;
+
+ current_instruction := elna_rtl_instruction_create(ElnaRtlOperator.move);
+ elna_rtl_instruction_set_operand(current_instruction, 1, ElnaRtlOperand.pseudo, parameter_name, name_length);
+ elna_rtl_instruction_set_operand(current_instruction, 2, ElnaRtlOperand.register, 11 + parameter_index, 0);
+
+ if result = nil then
+ result := current_instruction
+ else
+ elna_instruction_list_concatenate(last_instruction, current_instruction)
+ end;
+ last_instruction := current_instruction;
+
+ parameter_index := parameter_index + 1;
+ goto elna_rtl_parameters_loop
+ end;
+
+ return result
+end;
+
proc elna_rtl_procedure_declaration(tac_declaration: ^ElnaInstructionDeclaration);
var
result: ^ElnaInstructionDeclaration;
+ body: ^ElnaInstructionList;
+ parameters: ^ElnaInstructionList;
begin
result := malloc(ElnaInstructionDeclaration_size());
@@ -3611,20 +3597,19 @@ begin
result^.name := tac_declaration^.name;
result^.length := tac_declaration^.length;
result^.stack := tac_declaration^.stack;
- result^.body := elna_rtl_instructions(tac_declaration^.body);
+
+ parameters = elna_rtl_parameters(tac_declaration^.parameters, tac_declaration^.count);
+ body := elna_rtl_instructions(tac_declaration^.body);
+ result^.body := elna_instruction_list_concatenate(parameters, body);
return result
end;
proc _elna_tac_procedure_declaration(parser_node: ElnaTreeProcedureDeclaration);
var
- current_parameter: Word;
- new_symbol_table: Word;
symbol_info: ^ElnaSymbolProcedureInfo;
- instruction: Word;
- first_instruction: Word;
result: ^ElnaInstructionDeclaration;
- result_size: Word;
+ parameter_count: Word;
begin
result := malloc(ElnaInstructionDeclaration_size());
@@ -3635,15 +3620,10 @@ begin
result^.length := parser_node^.length;
symbol_info := _symbol_table_lookup(@symbol_table_global, parser_node^.name, parser_node^.length);
- new_symbol_table := symbol_info^.symbol_table;
- current_parameter := parser_node^.parameters;
- first_instruction := _elna_tac_parameters(current_parameter, new_symbol_table);
-
- instruction := _elna_tac_statements(parser_node^.body, new_symbol_table);
- first_instruction := elna_instruction_list_concatenate(first_instruction, instruction);
-
- result^.body := first_instruction;
+ result^.parameters := _elna_tac_parameters(parser_node^.parameters, @parameter_count);
+ result^.count := parameter_count;
+ result^.body := _elna_tac_statements(parser_node^.body, symbol_info^.symbol_table);
return result
end;
@@ -4128,23 +4108,12 @@ end;
proc elna_name_procedure_declaration(parser_node: ^ElnaTreeProcedureDeclaration);
var
new_symbol_table: Word;
- parameter_counter: Word;
symbol_info: Word;
- current_parameter: ^ElnaTreeDeclaration;
begin
new_symbol_table := _symbol_table_create();
symbol_info := _procedure_info_create(new_symbol_table);
- current_parameter := parser_node^.parameters;
- parameter_counter := 0;
- .elna_name_procedure_declaration_parameter;
- if current_parameter <> nil then
- elna_name_procedure_parameter(current_parameter, parameter_counter, new_symbol_table);
- parameter_counter := parameter_counter + 1;
-
- current_parameter := current_parameter^.next;
- goto elna_name_procedure_declaration_parameter
- end;
+ elna_name_procedure_temporaries(parser_node^.parameters, new_symbol_table);
elna_name_procedure_temporaries(parser_node^.temporaries, new_symbol_table);
_symbol_table_enter(@symbol_table_global, parser_node^.name, parser_node^.length, symbol_info)
@@ -4278,7 +4247,6 @@ end;
proc elna_type_variable_expression(parser_node: ^ElnaTreeVariableExpression, symbol_table: Word);
var
variable_info: ^ElnaSymbolInfo;
- parameter_info: ^ElnaSymbolParameterInfo;
temporary_info: ^ElnaSymbolTemporaryInfo;
begin
variable_info := _symbol_table_lookup(symbol_table, parser_node^.name, parser_node^.length);
@@ -4286,11 +4254,7 @@ begin
if variable_info = nil then
variable_info := _symbol_table_lookup(@symbol_table_global, parser_node^.name, parser_node^.length)
end;
-
- if variable_info^.kind = ElnaSymbolInfoKind.parameter_info then
- parameter_info := variable_info;
- parser_node^.type_decoration := parameter_info^.variable_type
- elsif variable_info^.kind = ElnaSymbolInfoKind.temporary_info then
+ if variable_info^.kind = ElnaSymbolInfoKind.temporary_info then
temporary_info := variable_info;
parser_node^.type_decoration := temporary_info^.variable_type
end