summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--boot/stage22/cl.elna68
-rw-r--r--boot/stage23/cl.elna67
2 files changed, 115 insertions, 20 deletions
diff --git a/boot/stage22/cl.elna b/boot/stage22/cl.elna
index 8409ddc..4e882a6 100644
--- a/boot/stage22/cl.elna
+++ b/boot/stage22/cl.elna
@@ -8,6 +8,7 @@ program;
(* Stage 22 compiler. *)
(* - Support 2 word procedure arguments. *)
+(* - Support returning 2 word aggregates. *)
(* - Characters are parsed to a character ASCII code. *)
(* - Strings are parsed and their length doesn't count for escaping backslash. *)
@@ -349,7 +350,8 @@ type
end
ElnaSymbolProcedureInfo = record
kind: ElnaSymbolInfoKind;
- symbol_table: ^ElnaSymbolTable
+ symbol_table: ^ElnaSymbolTable;
+ return_type: ^ElnaType
end
ElnaError = record
@@ -1199,6 +1201,9 @@ var
instruction: ^ElnaRtlInstruction
current_register: Word
registers_used: Word
+ target_operand: ElnaRtlOperand
+ pseudo_symbol: ^ElnaRtlObjectInfo
+ long_word_type: ^ElnaRtlType
begin
current_register := 0;
current_argument := tac_instruction^.operands[2].value;
@@ -1220,11 +1225,38 @@ begin
tac_instruction^.operands[1].value, tac_instruction^.operands[1].length, 0);
elna_list_append(instructions, instruction);
- instruction := elna_rtl_instruction_create(ElnaRtlOperator.mv);
- elna_rtl_instruction_set_operand(instruction, 1, tac_instruction^.operands[3].kind,
- tac_instruction^.operands[3].value, tac_instruction^.operands[3].length, 0);
- elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.register, ElnaRtlRegister.a0, 0, 0);
- elna_list_append(instructions, instruction)
+ pseudo_symbol := elna_symbol_table_lookup(variable_map, tac_instruction^.operands[3].value, tac_instruction^.operands[3].length);
+
+ if pseudo_symbol^.rtl_type^.kind = ElnaRtlTypeKind.byte_array then
+ target_operand.kind := ElnaRtlKind.register;
+ target_operand.value := ElnaRtlRegister.t0;
+ target_operand.length := 0;
+ target_operand.offset := 0;
+ long_word_type := elna_rtl_constant_type(4);
+
+ instruction := elna_rtl_variable_address(variable_map, pseudo_symbol, @tac_instruction^.operands[3], @target_operand);
+ elna_list_append(instructions, instruction);
+
+ instruction := elna_rtl_instruction_create(ElnaRtlOperator.sw);
+ elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.a0, 0, 0);
+ elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.memory,
+ target_operand.value, target_operand.length, 0);
+ instruction^.types[1] := long_word_type;
+ elna_list_append(instructions, instruction);
+
+ instruction := elna_rtl_instruction_create(ElnaRtlOperator.sw);
+ elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.a1, 0, 0);
+ elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.memory,
+ target_operand.value, target_operand.length, 4);
+ instruction^.types[1] := long_word_type;
+ elna_list_append(instructions, instruction)
+ else
+ instruction := elna_rtl_instruction_create(ElnaRtlOperator.mv);
+ elna_rtl_instruction_set_operand(instruction, 1, tac_instruction^.operands[3].kind,
+ tac_instruction^.operands[3].value, tac_instruction^.operands[3].length, 0);
+ elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.register, ElnaRtlRegister.a0, 0, 0);
+ elna_list_append(instructions, instruction)
+ end
end
proc elna_rtl_store(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction, variable_map: ^ElnaSymbolTable)
@@ -3057,11 +3089,20 @@ var
arguments_operand: ^ElnaTacOperand
call_instruction: ^ElnaTacInstruction
argument_entry: ^ElnaTreeExpressionList
+ procedure_info: ^ElnaSymbolProcedureInfo
begin
parsed_expression := parsed_call^.callee;
arguments_operand := malloc(parsed_call^.count * #size(ElnaTacOperand));
+ procedure_info := elna_symbol_table_lookup(symbol_table, parsed_expression^.name, parsed_expression^.length);
- elna_tac_make_variable(operand, symbol_table, word_type);
+ (* TODO: procedure_info should never be nil. *)
+ if procedure_info = nil then
+ elna_tac_make_variable(operand, symbol_table, word_type)
+ elsif procedure_info^.return_type = nil then
+ elna_tac_make_variable(operand, symbol_table, word_type)
+ else
+ elna_tac_make_variable(operand, symbol_table, procedure_info^.return_type)
+ end;
call_instruction := elna_tac_instruction_create(ElnaTacOperator.proc_call);
elna_tac_instruction_set_operand(call_instruction, 1, ElnaTacKind.label, parsed_expression^.name, parsed_expression^.length);
@@ -4023,13 +4064,14 @@ end
* Parameters:
* symbol_table - Local symbol table.
*)
-proc procedure_info_create(symbol_table: ^ElnaSymbolTable) -> ^ElnaSymbolProcedureInfo
+proc procedure_info_create(symbol_table: ^ElnaSymbolTable, return_type: ^ElnaRtlType) -> ^ElnaSymbolProcedureInfo
var
result: ^ElnaSymbolProcedureInfo
begin
result := malloc(#size(ElnaSymbolProcedureInfo));
result^.kind := ElnaSymbolInfoKind.procedure_info;
result^.symbol_table := symbol_table;
+ result^.return_type := return_type;
return result
end
@@ -4949,10 +4991,16 @@ end
proc elna_name_procedure_declaration(parser_node: ^ElnaTreeProcedureDeclaration)
var
new_symbol_table: ^ElnaSymbolTable
- symbol_info: Word
+ symbol_info: ^ElnaSymbolProcedureInfo
+ return_type: ^ElnaType
begin
+ if parser_node^.return_type = nil then
+ return_type := nil
+ else
+ return_type := elna_name_type_expression(parser_node^.return_type);
+ end;
new_symbol_table := elna_symbol_table_create(symbol_table_global);
- symbol_info := procedure_info_create(new_symbol_table);
+ symbol_info := procedure_info_create(new_symbol_table, return_type);
elna_name_procedure_temporaries(parser_node^.parameters, new_symbol_table);
elna_name_procedure_temporaries(parser_node^.temporaries, new_symbol_table);
diff --git a/boot/stage23/cl.elna b/boot/stage23/cl.elna
index 7115b95..01f8f54 100644
--- a/boot/stage23/cl.elna
+++ b/boot/stage23/cl.elna
@@ -344,7 +344,8 @@ type
end
ElnaSymbolProcedureInfo = record
kind: ElnaSymbolInfoKind;
- symbol_table: ^ElnaSymbolTable
+ symbol_table: ^ElnaSymbolTable;
+ return_type: ^ElnaType
end
ElnaError = record
@@ -1193,6 +1194,9 @@ var
instruction: ^ElnaRtlInstruction
current_register: Word
registers_used: Word
+ target_operand: ElnaRtlOperand
+ pseudo_symbol: ^ElnaRtlObjectInfo
+ long_word_type: ^ElnaRtlType
begin
current_register := 0;
current_argument := tac_instruction^.operands[2].value;
@@ -1214,11 +1218,38 @@ begin
tac_instruction^.operands[1].value, tac_instruction^.operands[1].length, 0);
elna_list_append(instructions, instruction);
- instruction := elna_rtl_instruction_create(ElnaRtlOperator.mv);
- elna_rtl_instruction_set_operand(instruction, 1, tac_instruction^.operands[3].kind,
- tac_instruction^.operands[3].value, tac_instruction^.operands[3].length, 0);
- elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.register, ElnaRtlRegister.a0, 0, 0);
- elna_list_append(instructions, instruction)
+ pseudo_symbol := elna_symbol_table_lookup(variable_map, tac_instruction^.operands[3].value, tac_instruction^.operands[3].length);
+
+ if pseudo_symbol^.rtl_type^.kind = ElnaRtlTypeKind.byte_array then
+ target_operand.kind := ElnaRtlKind.register;
+ target_operand.value := ElnaRtlRegister.t0;
+ target_operand.length := 0;
+ target_operand.offset := 0;
+ long_word_type := elna_rtl_constant_type(4);
+
+ instruction := elna_rtl_variable_address(variable_map, pseudo_symbol, @tac_instruction^.operands[3], @target_operand);
+ elna_list_append(instructions, instruction);
+
+ instruction := elna_rtl_instruction_create(ElnaRtlOperator.sw);
+ elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.a0, 0, 0);
+ elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.memory,
+ target_operand.value, target_operand.length, 0);
+ instruction^.types[1] := long_word_type;
+ elna_list_append(instructions, instruction);
+
+ instruction := elna_rtl_instruction_create(ElnaRtlOperator.sw);
+ elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.a1, 0, 0);
+ elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.memory,
+ target_operand.value, target_operand.length, 4);
+ instruction^.types[1] := long_word_type;
+ elna_list_append(instructions, instruction)
+ else
+ instruction := elna_rtl_instruction_create(ElnaRtlOperator.mv);
+ elna_rtl_instruction_set_operand(instruction, 1, tac_instruction^.operands[3].kind,
+ tac_instruction^.operands[3].value, tac_instruction^.operands[3].length, 0);
+ elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.register, ElnaRtlRegister.a0, 0, 0);
+ elna_list_append(instructions, instruction)
+ end
end
proc elna_rtl_store(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction, variable_map: ^ElnaSymbolTable)
@@ -3046,11 +3077,20 @@ var
arguments_operand: ^ElnaTacOperand
call_instruction: ^ElnaTacInstruction
argument_entry: ^ElnaTreeExpressionList
+ procedure_info: ^ElnaSymbolProcedureInfo
begin
parsed_expression := parsed_call^.callee;
arguments_operand := malloc(parsed_call^.count * #size(ElnaTacOperand));
+ procedure_info := elna_symbol_table_lookup(symbol_table, parsed_expression^.name, parsed_expression^.length);
- elna_tac_make_variable(operand, symbol_table, word_type);
+ (* TODO: procedure_info should never be nil. *)
+ if procedure_info = nil then
+ elna_tac_make_variable(operand, symbol_table, word_type)
+ elsif procedure_info^.return_type = nil then
+ elna_tac_make_variable(operand, symbol_table, word_type)
+ else
+ elna_tac_make_variable(operand, symbol_table, procedure_info^.return_type)
+ end;
call_instruction := elna_tac_instruction_create(ElnaTacOperator.proc_call);
elna_tac_instruction_set_operand(call_instruction, 1, ElnaTacKind.label, parsed_expression^.name, parsed_expression^.length);
@@ -4012,13 +4052,14 @@ end
* Parameters:
* symbol_table - Local symbol table.
*)
-proc procedure_info_create(symbol_table: ^ElnaSymbolTable) -> ^ElnaSymbolProcedureInfo
+proc procedure_info_create(symbol_table: ^ElnaSymbolTable, return_type: ^ElnaRtlType) -> ^ElnaSymbolProcedureInfo
var
result: ^ElnaSymbolProcedureInfo
begin
result := malloc(#size(ElnaSymbolProcedureInfo));
result^.kind := ElnaSymbolInfoKind.procedure_info;
result^.symbol_table := symbol_table;
+ result^.return_type := return_type;
return result
end
@@ -4938,10 +4979,16 @@ end
proc elna_name_procedure_declaration(parser_node: ^ElnaTreeProcedureDeclaration)
var
new_symbol_table: ^ElnaSymbolTable
- symbol_info: Word
+ symbol_info: ^ElnaSymbolProcedureInfo
+ return_type: ^ElnaType
begin
+ if parser_node^.return_type = nil then
+ return_type := nil
+ else
+ return_type := elna_name_type_expression(parser_node^.return_type);
+ end;
new_symbol_table := elna_symbol_table_create(symbol_table_global);
- symbol_info := procedure_info_create(new_symbol_table);
+ symbol_info := procedure_info_create(new_symbol_table, return_type);
elna_name_procedure_temporaries(parser_node^.parameters, new_symbol_table);
elna_name_procedure_temporaries(parser_node^.temporaries, new_symbol_table);