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