From db27f865f1f8d55de8121b96c31cedac3288e7e6 Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Tue, 11 Nov 2025 18:55:43 +0100 Subject: [PATCH] Add assembly generation stage --- boot/stage15/cl.elna | 22 +- boot/stage16/cl.elna | 1096 +++++++++++++++++++++++++----------------- 2 files changed, 668 insertions(+), 450 deletions(-) diff --git a/boot/stage15/cl.elna b/boot/stage15/cl.elna index 3f2dde2..031cec2 100644 --- a/boot/stage15/cl.elna +++ b/boot/stage15/cl.elna @@ -1109,10 +1109,10 @@ begin _write_s("\tbeqz", 5) elsif instruction_kind = ElnaTacOperator.start then argument_count := 0; - _write_z("\taddi sp, sp, -128\n\tsw ra, 124(sp)\n\tsw s0, 120(sp)\n\taddi s0, sp, 128\0") + _write_z("\taddi sp, sp, -144\n\tsw ra, 140(sp)\n\tsw s0, 136(sp)\n\taddi s0, sp, 144\0") elsif instruction_kind = ElnaTacOperator.ret then argument_count := 0; - _write_z("\tlw ra, 124(sp)\n\tlw s0, 120(sp)\n\taddi sp, sp, 128\0") + _write_z("\tlw ra, 140(sp)\n\tlw s0, 136(sp)\n\taddi sp, sp, 144\0") end; return argument_count end; @@ -1900,7 +1900,7 @@ begin first_instruction := _elna_tac_unary_expression(operand_node, symbol_table); (* Save the value of the left expression on the stack. *) - instruction := _elna_tac_store_word(ElnaTacRegister.t0, ElnaTacRegister.sp, 64); + instruction := _elna_tac_store_word(ElnaTacRegister.t0, ElnaTacRegister.sp, 72); _elna_tac_instruction_set_next(first_instruction, instruction); current_instruction := instruction; @@ -1910,7 +1910,7 @@ begin current_instruction := instruction; (* Load the left expression from the stack; *) - instruction := _elna_tac_load_word(ElnaTacRegister.t1, ElnaTacRegister.sp, 64); + instruction := _elna_tac_load_word(ElnaTacRegister.t1, ElnaTacRegister.sp, 72); _elna_tac_instruction_set_next(current_instruction, instruction); current_instruction := instruction; @@ -2088,7 +2088,7 @@ begin stack_offset := argument_count * 4; instruction := _elna_tac_store_word(ElnaTacRegister.t0, - ElnaTacRegister.sp, 116 - stack_offset); + ElnaTacRegister.sp, 132 - stack_offset); _elna_tac_instruction_set_next(current_instruction, instruction); current_instruction := instruction; @@ -2103,9 +2103,9 @@ begin argument_count := argument_count - 1; stack_offset := argument_count * 4; - (* Calculate the stack offset: 116 - (4 * argument_counter) *) + (* Calculate the stack offset: 132 - (4 * argument_counter) *) instruction := _elna_tac_load_word(ElnaTacRegister.a0 + argument_count, - ElnaTacRegister.sp, 116 - stack_offset); + ElnaTacRegister.sp, 132 - stack_offset); _elna_tac_instruction_set_next(current_instruction, instruction); current_instruction := instruction; @@ -2502,7 +2502,7 @@ begin first_instruction := _elna_tac_designator(current_expression, symbol_table, @is_address); (* Save the assignee address on the stack. *) - current_instruction := _elna_tac_store_word(ElnaTacRegister.t0, ElnaTacRegister.sp, 60); + current_instruction := _elna_tac_store_word(ElnaTacRegister.t0, ElnaTacRegister.sp, 76); _elna_tac_instruction_set_next(first_instruction, current_instruction); (* Compile the assignment. *) @@ -2510,7 +2510,7 @@ begin instruction := _elna_tac_binary_expression(current_expression, symbol_table); _elna_tac_instruction_set_next(current_instruction, instruction); - current_instruction := _elna_tac_load_word(ElnaTacRegister.t1, ElnaTacRegister.sp, 60); + current_instruction := _elna_tac_load_word(ElnaTacRegister.t1, ElnaTacRegister.sp, 76); _elna_tac_instruction_set_next(instruction, current_instruction); instruction := _elna_tac_store_word(ElnaTacRegister.t0, ElnaTacRegister.t1, 0); @@ -3415,9 +3415,9 @@ begin current_word := current_word + 4; - (* Calculate the stack offset: 88 - (4 * parameter_counter) *) + (* Calculate the stack offset: 104 - (4 * parameter_counter) *) offset := parameter_index * 4; - current_word^ := 88 - offset; + current_word^ := 104 - offset; return result end; diff --git a/boot/stage16/cl.elna b/boot/stage16/cl.elna index f76edae..189c69f 100644 --- a/boot/stage16/cl.elna +++ b/boot/stage16/cl.elna @@ -7,13 +7,13 @@ (* Stage 16 compiler. *) type - _elna_tac_declaration = record - next: Word; - name: Word; - length: Word; - body: Word + (** + * List of intermediate representation items. + *) + ElnaInstructionList = record + next: Word end; - elna_rtl_declaration = record + ElnaInstructionDeclaration = record next: Word; name: Word; length: Word; @@ -90,11 +90,7 @@ type field: Word; length: Word end; - _elna_tac_module = record - data: Word; - code: Word - end; - elna_rtl_module = record + ElnaInstructionModule = record data: Word; code: Word end; @@ -352,14 +348,12 @@ type InfoKind = (type_info, parameter_info, temporary_info, procedure_info); TypeKind = (primitive, enumeration, _record); ElnaTacOperator = ( - load_immediate, - load_address, + get_address, add, - add_immediate, load_word, store_word, jal, - move, + assign, sub, div, rem, @@ -367,10 +361,12 @@ type _xor, _or, and, - seqz, - snez, slt, - xor_immediate, + sgt, + sle, + sge, + seq, + sne, neg, not, jump, @@ -407,7 +403,7 @@ type start, ret ); - ElnaTacOperand = (register, immediate, symbol, offset); + ElnaTacOperand = (register, immediate, symbol, offset, stack); ElnaRtlOperand = (register, immediate, symbol, offset); ElnaRtlRegister = ( zero, @@ -454,6 +450,7 @@ var compiler_strings_length: Word; label_counter: Word; symbol_table_store: Word; + temporary_variable_counter: Word; (** * Calculates and returns the string token length between quotes, including the @@ -662,24 +659,20 @@ proc _elna_tac_instruction_size(); end; proc _elna_tac_instruction_get_kind(this: Word); +begin + this := this + 4; return this^ end; proc _elna_tac_instruction_set_kind(this: Word, value: Word); begin + this := this + 4; this^ := value end; -proc _elna_tac_instruction_get_next(this: Word); -begin - this := this + 4; - return this^ -end; - -proc _elna_tac_instruction_set_next(this: Word, value: Word); +proc elna_instruction_list_concatenate(this: Word, value: Word); begin .elna_tac_instruction_set_next_loop; - this := this + 4; if value <> 0 then if this^ <> 0 then this := this^; @@ -742,7 +735,19 @@ begin result := malloc(_elna_tac_instruction_size()); _elna_tac_instruction_set_kind(result, kind); - _elna_tac_instruction_set_next(result, 0); + elna_instruction_list_concatenate(result, 0); + + return result +end; + +proc elna_rtl_instruction_create(kind: Word); +var + result: Word; +begin + result := malloc(elna_rtl_instruction_size()); + + elna_rtl_instruction_set_kind(result, kind); + ElnaInstructionList_set_next(result, 0); return result end; @@ -752,23 +757,14 @@ proc elna_rtl_instruction_size(); end; proc elna_rtl_instruction_get_kind(this: Word); - return this^ -end; - -proc elna_rtl_instruction_get_next(this: Word); begin this := this + 4; return this^ end; -proc elna_rtl_instruction_set_next(this: Word, value: Word); -begin - this := this + 4; - this^ := value -end; - proc elna_rtl_instruction_set_kind(this: Word, value: Word); begin + this := this + 4; this^ := value end; @@ -818,39 +814,298 @@ begin this^ := operand_length end; -proc elna_rtl_instruction(tac_instruction: Word); +proc elna_rtl_load_operand_value(tac_instruction: Word, operand_number: Word, into: Word); var result: Word; + operand_value: Word; + operand_length: Word; + operand_type: Word; + next_instruction: Word; instruction_size: Word; begin instruction_size := elna_rtl_instruction_size(); + operand_value := _elna_tac_instruction_get_operand_value(tac_instruction, operand_number); + operand_length := _elna_tac_instruction_get_operand_length(tac_instruction, operand_number); + operand_type := _elna_tac_instruction_get_operand_type(tac_instruction, operand_number); result := malloc(instruction_size); - memcpy(result, tac_instruction, instruction_size); + if operand_type = ElnaTacOperand.immediate then + elna_rtl_instruction_set_kind(result, ElnaRtlOperator.load_immediate); + elna_rtl_instruction_set_operand(result, 1, ElnaRtlOperand.register, into, 0); + elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.immediate, operand_value, operand_length); + ElnaInstructionList_set_next(result, 0) + elsif operand_type = ElnaTacOperand.stack then + elna_rtl_instruction_set_kind(result, ElnaRtlOperator.load_word); + elna_rtl_instruction_set_operand(result, 1, ElnaRtlOperand.register, into, 0); + elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.offset, ElnaRtlRegister.sp, operand_value); + ElnaInstructionList_set_next(result, 0) + elsif operand_type = ElnaTacOperand.symbol then + elna_rtl_instruction_set_kind(result, ElnaRtlOperator.load_address); + elna_rtl_instruction_set_operand(result, 1, ElnaRtlOperand.register, into, 0); + elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.symbol, operand_value, operand_length); + + next_instruction := malloc(instruction_size); + elna_rtl_instruction_set_kind(next_instruction, ElnaRtlOperator.load_word); + elna_rtl_instruction_set_operand(next_instruction, 1, ElnaRtlOperand.register, into, 0); + elna_rtl_instruction_set_operand(next_instruction, 2, ElnaRtlOperand.offset, into, 0); + ElnaInstructionList_set_next(next_instruction, 0); + + ElnaInstructionList_set_next(result, next_instruction) + elsif operand_type = ElnaTacOperand.register then + elna_rtl_instruction_set_kind(result, ElnaRtlOperator.move); + elna_rtl_instruction_set_operand(result, 1, ElnaRtlOperand.register, into, 0); + elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.register, operand_value, 0); + ElnaInstructionList_set_next(result, 0) + end; return result end; -proc _elna_tac_module_create(data: Word, code: Word); +proc elna_rtl_load_operand_address(tac_instruction: Word, operand_number: Word, into: Word); var result: Word; + operand_value: Word; + operand_length: Word; + operand_type: Word; begin - result := malloc(_elna_tac_module_size()); + operand_value := _elna_tac_instruction_get_operand_value(tac_instruction, operand_number); + operand_length := _elna_tac_instruction_get_operand_length(tac_instruction, operand_number); + operand_type := _elna_tac_instruction_get_operand_type(tac_instruction, operand_number); - _elna_tac_module_set_data(result, data); - _elna_tac_module_set_code(result, code); + result := malloc(elna_rtl_instruction_size()); + ElnaInstructionList_set_next(result, 0); + + if operand_type = ElnaTacOperand.stack then + elna_rtl_instruction_set_kind(result, ElnaRtlOperator.add_immediate); + 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 + elna_rtl_instruction_set_kind(result, ElnaRtlOperator.load_address); + elna_rtl_instruction_set_operand(result, 1, ElnaRtlOperand.register, into, 0); + elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.symbol, operand_value, operand_length) + end; return result end; -proc _elna_tac_load_immediate(target_register: Word, source_immediate: Word, immediate_length: Word); +proc elna_rtl_binary_operands(tac_instruction: Word, next_instruction: Word); +var + lhs: Word; + rhs: Word; +begin + lhs := elna_rtl_load_operand_value(tac_instruction, 2, ElnaRtlRegister.t2); + rhs := elna_rtl_load_operand_value(tac_instruction, 3, ElnaRtlRegister.t3); + + next_instruction^ := ElnaInstructionList_get_next(lhs); + if next_instruction^ = 0 then + ElnaInstructionList_set_next(lhs, rhs) + else + ElnaInstructionList_set_next(next_instruction^, rhs) + end; + next_instruction^ := ElnaInstructionList_get_next(rhs); + if next_instruction^ = 0 then + next_instruction^ := rhs + end; + + return lhs +end; + +proc elna_rtl_binary_arithmetic(tac_instruction: Word, binary_result: Word, next_instruction: Word); +var + lhs: Word; +begin + lhs := elna_rtl_binary_operands(tac_instruction, next_instruction); + elna_rtl_instruction_set_operand(binary_result, 2, ElnaRtlOperand.register, ElnaRtlRegister.t2, 0); + elna_rtl_instruction_set_operand(binary_result, 3, ElnaRtlOperand.register, ElnaRtlRegister.t3, 0); + + ElnaInstructionList_set_next(next_instruction^, binary_result); + next_instruction^ := binary_result; + + return lhs +end; + +proc elna_rtl_binary_equality(tac_instruction: Word, binary_result: Word, next_instruction: Word); +var + operands: Word; + intermediate_instruction: Word; +begin + operands := elna_rtl_binary_operands(tac_instruction, next_instruction); + intermediate_instruction := elna_rtl_instruction_create(ElnaRtlOperator._xor); + + elna_rtl_instruction_set_operand(intermediate_instruction, 1, ElnaRtlOperand.register, ElnaRtlRegister.t2, 0); + elna_rtl_instruction_set_operand(intermediate_instruction, 2, ElnaRtlOperand.register, ElnaRtlRegister.t2, 0); + elna_rtl_instruction_set_operand(intermediate_instruction, 3, ElnaRtlOperand.register, ElnaRtlRegister.t3, 0); + ElnaInstructionList_set_next(next_instruction^, intermediate_instruction); + next_instruction^ := intermediate_instruction; + + elna_rtl_instruction_set_operand(binary_result, 2, ElnaRtlOperand.register, ElnaRtlRegister.t2, 0); + ElnaInstructionList_set_next(next_instruction^, binary_result); + next_instruction^ := binary_result; + + return operands +end; + +proc elna_rtl_instruction(tac_instruction: Word, next_instruction: Word); +var + result: Word; + instruction_size: Word; + instruction_kind: Word; + operand_type: Word; + operand_value: Word; + operands: Word; + intermediate_instruction: Word; +begin + instruction_size := elna_rtl_instruction_size(); + result := malloc(instruction_size); + instruction_kind := _elna_tac_instruction_get_kind(tac_instruction); + memcpy(result + 4, tac_instruction + 4, instruction_size - 4); + next_instruction^ := 0; + + if instruction_kind = ElnaTacOperator.get_address then + operand_type := _elna_tac_instruction_get_operand_type(tac_instruction, 2); + + if operand_type = ElnaTacOperand.stack then + operand_value := _elna_tac_instruction_get_operand_value(tac_instruction, 2); + elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.register, ElnaRtlRegister.sp, 0); + elna_rtl_instruction_set_operand(result, 3, ElnaRtlOperand.immediate, operand_value, 0); + elna_rtl_instruction_set_kind(result, ElnaRtlOperator.add) + elsif operand_type = ElnaTacOperand.symbol then + elna_rtl_instruction_set_kind(result, ElnaRtlOperator.load_address) + + (* Debug. Error stream output. + _syscall(2, name_pointer, name_length, 0, 0, 0, 64); + printf("# here %i\n\0", operand_type); + fflush(0); *) + end; + elsif instruction_kind = ElnaTacOperator.add then + result := elna_rtl_binary_arithmetic(tac_instruction, result, next_instruction); + elna_rtl_instruction_set_kind(next_instruction^, ElnaRtlOperator.add) + elsif instruction_kind = ElnaTacOperator.load_word then + operand_type := _elna_tac_instruction_get_operand_type(tac_instruction, 2); + + if operand_type = ElnaTacOperand.stack then + operand_value := _elna_tac_instruction_get_operand_value(tac_instruction, 1); + next_instruction^ := elna_rtl_instruction_create(ElnaRtlOperator.load_word); + elna_rtl_instruction_set_operand(next_instruction^, 1, ElnaRtlOperand.register, operand_value, 0); + elna_rtl_instruction_set_operand(next_instruction^, 2, ElnaRtlOperand.offset, operand_value, 0); + + operand_value := _elna_tac_instruction_get_operand_value(tac_instruction, 2); + elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.offset, ElnaRtlRegister.sp, operand_value); + ElnaInstructionList_set_next(result, next_instruction^) + end; + elna_rtl_instruction_set_kind(result, ElnaRtlOperator.load_word) + elsif instruction_kind = ElnaTacOperator.store_word then + elna_rtl_instruction_set_kind(result, ElnaRtlOperator.store_word) + elsif instruction_kind = ElnaTacOperator.jal then + elna_rtl_instruction_set_kind(result, ElnaRtlOperator.jal) + elsif instruction_kind = ElnaTacOperator.sub then + result := elna_rtl_binary_arithmetic(tac_instruction, result, next_instruction); + elna_rtl_instruction_set_kind(next_instruction^, ElnaRtlOperator.sub) + elsif instruction_kind = ElnaTacOperator.mul then + result := elna_rtl_binary_arithmetic(tac_instruction, result, next_instruction); + elna_rtl_instruction_set_kind(next_instruction^, ElnaRtlOperator.mul) + elsif instruction_kind = ElnaTacOperator.div then + result := elna_rtl_binary_arithmetic(tac_instruction, result, next_instruction); + elna_rtl_instruction_set_kind(next_instruction^, ElnaRtlOperator.div) + elsif instruction_kind = ElnaTacOperator.rem then + result := elna_rtl_binary_arithmetic(tac_instruction, result, next_instruction); + elna_rtl_instruction_set_kind(next_instruction^, ElnaRtlOperator.rem) + elsif instruction_kind = ElnaTacOperator._xor then + result := elna_rtl_binary_arithmetic(tac_instruction, result, next_instruction); + elna_rtl_instruction_set_kind(next_instruction^, ElnaRtlOperator._xor) + elsif instruction_kind = ElnaTacOperator._or then + result := elna_rtl_binary_arithmetic(tac_instruction, result, next_instruction); + elna_rtl_instruction_set_kind(next_instruction^, ElnaRtlOperator._or) + elsif instruction_kind = ElnaTacOperator.and then + result := elna_rtl_binary_arithmetic(tac_instruction, result, next_instruction); + elna_rtl_instruction_set_kind(next_instruction^, ElnaRtlOperator.and) + elsif instruction_kind = ElnaTacOperator.slt then + result := elna_rtl_binary_arithmetic(tac_instruction, result, next_instruction); + elna_rtl_instruction_set_kind(next_instruction^, ElnaRtlOperator.slt) + elsif instruction_kind = ElnaTacOperator.sgt then + operands := elna_rtl_binary_operands(tac_instruction, next_instruction); + elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.register, ElnaRtlRegister.t3, 0); + elna_rtl_instruction_set_operand(result, 3, ElnaRtlOperand.register, ElnaRtlRegister.t2, 0); + + ElnaInstructionList_set_next(next_instruction^, result); + next_instruction^ := result; + + result := operands; + elna_rtl_instruction_set_kind(next_instruction^, ElnaRtlOperator.slt) + elsif instruction_kind = ElnaTacOperator.sle then + operands := elna_rtl_binary_operands(tac_instruction, next_instruction); + intermediate_instruction := elna_rtl_instruction_create(ElnaRtlOperator.slt); + + elna_rtl_instruction_set_operand(intermediate_instruction, 1, ElnaRtlOperand.register, ElnaRtlRegister.t2, 0); + elna_rtl_instruction_set_operand(intermediate_instruction, 2, ElnaRtlOperand.register, ElnaRtlRegister.t3, 0); + elna_rtl_instruction_set_operand(intermediate_instruction, 3, ElnaRtlOperand.register, ElnaRtlRegister.t2, 0); + ElnaInstructionList_set_next(next_instruction^, intermediate_instruction); + next_instruction^ := intermediate_instruction; + + elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.register, ElnaRtlRegister.t2, 0); + elna_rtl_instruction_set_operand(result, 3, ElnaRtlOperand.immediate, 1, 0); + ElnaInstructionList_set_next(next_instruction^, result); + next_instruction^ := result; + + result := operands; + elna_rtl_instruction_set_kind(next_instruction^, ElnaRtlOperator.xor_immediate) + elsif instruction_kind = ElnaTacOperator.sge then + operands := elna_rtl_binary_operands(tac_instruction, next_instruction); + intermediate_instruction := elna_rtl_instruction_create(ElnaRtlOperator.slt); + + elna_rtl_instruction_set_operand(intermediate_instruction, 1, ElnaRtlOperand.register, ElnaRtlRegister.t2, 0); + elna_rtl_instruction_set_operand(intermediate_instruction, 2, ElnaRtlOperand.register, ElnaRtlRegister.t2, 0); + elna_rtl_instruction_set_operand(intermediate_instruction, 3, ElnaRtlOperand.register, ElnaRtlRegister.t3, 0); + ElnaInstructionList_set_next(next_instruction^, intermediate_instruction); + next_instruction^ := intermediate_instruction; + + elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.register, ElnaRtlRegister.t2, 0); + elna_rtl_instruction_set_operand(result, 3, ElnaRtlOperand.immediate, 1, 0); + ElnaInstructionList_set_next(next_instruction^, result); + next_instruction^ := result; + + result := operands; + elna_rtl_instruction_set_kind(next_instruction^, ElnaRtlOperator.xor_immediate) + elsif instruction_kind = ElnaTacOperator.seq then + result := elna_rtl_binary_equality(tac_instruction, result, next_instruction); + elna_rtl_instruction_set_kind(next_instruction^, ElnaRtlOperator.seqz) + elsif instruction_kind = ElnaTacOperator.sne then + result := elna_rtl_binary_equality(tac_instruction, result, next_instruction); + elna_rtl_instruction_set_kind(next_instruction^, ElnaRtlOperator.snez) + elsif instruction_kind = ElnaTacOperator.neg then + elna_rtl_instruction_set_kind(result, ElnaRtlOperator.neg) + elsif instruction_kind = ElnaTacOperator.not then + elna_rtl_instruction_set_kind(result, ElnaRtlOperator.not) + elsif instruction_kind = ElnaTacOperator.jump then + elna_rtl_instruction_set_kind(result, ElnaRtlOperator.jump) + elsif instruction_kind = ElnaTacOperator.beqz then + elna_rtl_instruction_set_kind(result, ElnaRtlOperator.beqz) + elsif instruction_kind = ElnaTacOperator.start then + elna_rtl_instruction_set_kind(result, ElnaRtlOperator.start) + elsif instruction_kind = ElnaTacOperator.ret then + elna_rtl_instruction_set_kind(result, ElnaRtlOperator.ret) + elsif instruction_kind = ElnaTacOperator.label then + elna_rtl_instruction_set_kind(result, ElnaRtlOperator.label) + elsif instruction_kind = ElnaTacOperator.assign then + free(result); + operand_value := _elna_tac_instruction_get_operand_value(tac_instruction, 1); + result := elna_rtl_load_operand_value(tac_instruction, 2, operand_value); + next_instruction^ := ElnaInstructionList_get_next(result) + end; + if next_instruction^ = 0 then + next_instruction^ := result; + end; + return result +end; + +proc elna_instruction_module_create(data: Word, code: Word); var result: Word; begin - result := _elna_tac_instruction_create(ElnaTacOperator.load_immediate); + result := malloc(ElnaInstructionModule_size()); - _elna_tac_instruction_set_operand(result, 1, ElnaTacOperand.register, target_register, 0); - _elna_tac_instruction_set_operand(result, 2, ElnaTacOperand.immediate, source_immediate, immediate_length); + ElnaInstructionModule_set_data(result, data); + ElnaInstructionModule_set_code(result, code); return result end; @@ -859,7 +1114,7 @@ proc _elna_tac_load_address(target_register: Word, source_symbol: Word, symbol_l var result: Word; begin - result := _elna_tac_instruction_create(ElnaTacOperator.load_address); + result := _elna_tac_instruction_create(ElnaTacOperator.get_address); _elna_tac_instruction_set_operand(result, 1, ElnaTacOperand.register, target_register, 0); _elna_tac_instruction_set_operand(result, 2, ElnaTacOperand.symbol, source_symbol, symbol_length); @@ -890,7 +1145,7 @@ begin return result end; -proc _elna_tac_add(destination: Word, lhs: Word, rhs: Word); +proc _elna_tac_add(destination: Word, lhs: Word, rhs_type: Word, rhs: Word); var result: Word; begin @@ -898,20 +1153,7 @@ begin _elna_tac_instruction_set_operand(result, 1, ElnaTacOperand.register, destination, 0); _elna_tac_instruction_set_operand(result, 2, ElnaTacOperand.register, lhs, 0); - _elna_tac_instruction_set_operand(result, 3, ElnaTacOperand.register, rhs, 0); - - return result -end; - -proc _elna_tac_mul(destination: Word, lhs: Word, rhs: Word); -var - result: Word; -begin - result := _elna_tac_instruction_create(ElnaTacOperator.mul); - - _elna_tac_instruction_set_operand(result, 1, ElnaTacOperand.register, destination, 0); - _elna_tac_instruction_set_operand(result, 2, ElnaTacOperand.register, lhs, 0); - _elna_tac_instruction_set_operand(result, 3, ElnaTacOperand.register, rhs, 0); + _elna_tac_instruction_set_operand(result, 3, rhs_type, rhs, 0); return result end; @@ -929,110 +1171,6 @@ begin return result end; -proc _elna_tac_div(destination: Word, lhs: Word, rhs: Word); -var - result: Word; -begin - result := _elna_tac_instruction_create(ElnaTacOperator.div); - - _elna_tac_instruction_set_operand(result, 1, ElnaTacOperand.register, destination, 0); - _elna_tac_instruction_set_operand(result, 2, ElnaTacOperand.register, lhs, 0); - _elna_tac_instruction_set_operand(result, 3, ElnaTacOperand.register, rhs, 0); - - return result -end; - -proc _elna_tac_rem(destination: Word, lhs: Word, rhs: Word); -var - result: Word; -begin - result := _elna_tac_instruction_create(ElnaTacOperator.rem); - - _elna_tac_instruction_set_operand(result, 1, ElnaTacOperand.register, destination, 0); - _elna_tac_instruction_set_operand(result, 2, ElnaTacOperand.register, lhs, 0); - _elna_tac_instruction_set_operand(result, 3, ElnaTacOperand.register, rhs, 0); - - return result -end; - -proc _elna_tac_xor(destination: Word, lhs: Word, rhs: Word); -var - result: Word; -begin - result := _elna_tac_instruction_create(ElnaTacOperator._xor); - - _elna_tac_instruction_set_operand(result, 1, ElnaTacOperand.register, destination, 0); - _elna_tac_instruction_set_operand(result, 2, ElnaTacOperand.register, lhs, 0); - _elna_tac_instruction_set_operand(result, 3, ElnaTacOperand.register, rhs, 0); - - return result -end; - -proc _elna_tac_xor_immediate(destination: Word, lhs: Word, rhs: Word); -var - result: Word; -begin - result := _elna_tac_instruction_create(ElnaTacOperator._xor); - - _elna_tac_instruction_set_operand(result, 1, ElnaTacOperand.register, destination, 0); - _elna_tac_instruction_set_operand(result, 2, ElnaTacOperand.register, lhs, 0); - _elna_tac_instruction_set_operand(result, 3, ElnaTacOperand.immediate, rhs, 0); - - return result -end; - -proc _elna_tac_or(destination: Word, lhs: Word, rhs: Word); -var - result: Word; -begin - result := _elna_tac_instruction_create(ElnaTacOperator._or); - - _elna_tac_instruction_set_operand(result, 1, ElnaTacOperand.register, destination, 0); - _elna_tac_instruction_set_operand(result, 2, ElnaTacOperand.register, lhs, 0); - _elna_tac_instruction_set_operand(result, 3, ElnaTacOperand.register, rhs, 0); - - return result -end; - -proc _elna_tac_and(destination: Word, lhs: Word, rhs: Word); -var - result: Word; -begin - result := _elna_tac_instruction_create(ElnaTacOperator.and); - - _elna_tac_instruction_set_operand(result, 1, ElnaTacOperand.register, destination, 0); - _elna_tac_instruction_set_operand(result, 2, ElnaTacOperand.register, lhs, 0); - _elna_tac_instruction_set_operand(result, 3, ElnaTacOperand.register, rhs, 0); - - return result -end; - -proc _elna_tac_add_immediate(destination: Word, lhs: Word, rhs: Word); -var - result: Word; -begin - result := _elna_tac_instruction_create(ElnaTacOperator.add_immediate); - - _elna_tac_instruction_set_operand(result, 1, ElnaTacOperand.register, destination, 0); - _elna_tac_instruction_set_operand(result, 2, ElnaTacOperand.register, lhs, 0); - _elna_tac_instruction_set_operand(result, 3, ElnaTacOperand.immediate, rhs, 0); - - return result -end; - -proc _elna_tac_slt(destination: Word, lhs: Word, rhs: Word); -var - result: Word; -begin - result := _elna_tac_instruction_create(ElnaTacOperator.slt); - - _elna_tac_instruction_set_operand(result, 1, ElnaTacOperand.register, destination, 0); - _elna_tac_instruction_set_operand(result, 2, ElnaTacOperand.register, lhs, 0); - _elna_tac_instruction_set_operand(result, 3, ElnaTacOperand.register, rhs, 0); - - return result -end; - proc _elna_tac_jal(symbol: Word, length: Word); var result: Word; @@ -1068,42 +1206,6 @@ begin return result end; -proc _elna_tac_move(destination: Word, source: Word); -var - result: Word; -begin - result := _elna_tac_instruction_create(ElnaTacOperator.move); - - _elna_tac_instruction_set_operand(result, 1, ElnaTacOperand.register, destination, 0); - _elna_tac_instruction_set_operand(result, 2, ElnaTacOperand.register, source, 0); - - return result -end; - -proc _elna_tac_seqz(destination: Word, source: Word); -var - result: Word; -begin - result := _elna_tac_instruction_create(ElnaTacOperator.seqz); - - _elna_tac_instruction_set_operand(result, 1, ElnaTacOperand.register, destination, 0); - _elna_tac_instruction_set_operand(result, 2, ElnaTacOperand.register, source, 0); - - return result -end; - -proc _elna_tac_snez(destination: Word, source: Word); -var - result: Word; -begin - result := _elna_tac_instruction_create(ElnaTacOperator.snez); - - _elna_tac_instruction_set_operand(result, 1, ElnaTacOperand.register, destination, 0); - _elna_tac_instruction_set_operand(result, 2, ElnaTacOperand.register, source, 0); - - return result -end; - proc _elna_tac_neg(destination: Word, source: Word); var result: Word; @@ -1214,10 +1316,10 @@ begin _write_s("\tbeqz", 5) elsif instruction_kind = ElnaRtlOperator.start then argument_count := 0; - _write_z("\taddi sp, sp, -128\n\tsw ra, 124(sp)\n\tsw s0, 120(sp)\n\taddi s0, sp, 128\0") + _write_z("\taddi sp, sp, -144\n\tsw ra, 140(sp)\n\tsw s0, 136(sp)\n\taddi s0, sp, 144\0") elsif instruction_kind = ElnaRtlOperator.ret then argument_count := 0; - _write_z("\tlw ra, 124(sp)\n\tlw s0, 120(sp)\n\taddi sp, sp, 128\0") + _write_z("\tlw ra, 140(sp)\n\tlw s0, 136(sp)\n\taddi sp, sp, 144\0") end; return argument_count end; @@ -1298,23 +1400,23 @@ var current_copy: Word; next_copy: Word; first_copy: Word; + last_copy: Word; begin if instruction <> 0 then - first_copy := elna_rtl_instruction(instruction); - instruction := _elna_tac_instruction_get_next(instruction) + first_copy := elna_rtl_instruction(instruction, @current_copy); + instruction := ElnaInstructionList_get_next(instruction) else first_copy := 0; + current_copy := 0 end; - current_copy := first_copy; - .elna_rtl_instructions_start; if instruction <> 0 then - next_copy := elna_rtl_instruction(instruction); + next_copy := elna_rtl_instruction(instruction, @last_copy); - instruction := _elna_tac_instruction_get_next(instruction); - elna_rtl_instruction_set_next(current_copy, next_copy); - current_copy := next_copy; + instruction := ElnaInstructionList_get_next(instruction); + ElnaInstructionList_set_next(current_copy, next_copy); + current_copy := last_copy; goto elna_rtl_instructions_start end; @@ -1326,7 +1428,7 @@ begin .elna_writer_instructions_start; if instruction <> 0 then _elna_writer_instruction(instruction); - instruction := elna_rtl_instruction_get_next(instruction); + instruction := ElnaInstructionList_get_next(instruction); goto elna_writer_instructions_start end end; @@ -1338,9 +1440,9 @@ var body_statements: Word; begin .elna_writer_procedure_loop; - name_pointer := elna_rtl_declaration_get_name(procedure); - name_length := elna_rtl_declaration_get_length(procedure); - body_statements := elna_rtl_declaration_get_body(procedure); + name_pointer := ElnaInstructionDeclaration_get_name(procedure); + name_length := ElnaInstructionDeclaration_get_length(procedure); + body_statements := ElnaInstructionDeclaration_get_body(procedure); (* Write .type _procedure_name, @function. *) _write_z(".type \0"); @@ -1355,7 +1457,7 @@ begin _elna_writer_instructions(body_statements); _write_z("\tret\n\0"); - procedure := elna_rtl_declaration_get_next(procedure); + procedure := ElnaInstructionList_get_next(procedure); if procedure <> 0 then goto elna_writer_procedure_loop end @@ -1369,9 +1471,9 @@ var begin .elna_writer_variable_loop; if variable <> 0 then - name := elna_rtl_declaration_get_name(variable); - name_length := elna_rtl_declaration_get_length(variable); - size := elna_rtl_declaration_get_body(variable); + name := ElnaInstructionDeclaration_get_name(variable); + name_length := ElnaInstructionDeclaration_get_length(variable); + size := ElnaInstructionDeclaration_get_body(variable); _write_z(".type \0"); _write_s(name, name_length); @@ -1384,7 +1486,7 @@ begin _write_i(size); _write_c('\n'); - variable := elna_rtl_declaration_get_next(variable); + variable := ElnaInstructionList_get_next(variable); goto elna_writer_variable_loop end @@ -1392,20 +1494,17 @@ end; proc elna_rtl_module_declaration(tac_module: Word); var - result: Word; + code_part: Word; + data_part: Word; current_part: Word; begin - result := malloc(elna_rtl_module_size()); + current_part := ElnaInstructionModule_get_data(tac_module); + data_part := elna_rtl_globals(current_part); - current_part := _elna_tac_module_get_data(tac_module); - current_part := elna_rtl_globals(current_part); - elna_rtl_module_set_data(result, current_part); + current_part := ElnaInstructionModule_get_code(tac_module); + code_part := elna_rtl_procedures(current_part); - current_part := _elna_tac_module_get_code(tac_module); - current_part := elna_rtl_procedures(current_part); - elna_rtl_module_set_code(result, current_part); - - return result + return elna_instruction_module_create(data_part, code_part) end; proc _elna_writer_module(pair: Word); @@ -1418,7 +1517,7 @@ begin _write_z(".globl main\n\n\0"); _write_z(".section .data\n\0"); - current_part := elna_rtl_module_get_data(pair); + current_part := ElnaInstructionModule_get_data(pair); _elna_writer_variable(current_part); _write_z(".section .text\n\n\0"); @@ -1426,7 +1525,7 @@ begin _write_z(".type _load_byte, @function\n_load_byte:\n\tlb a0, (a0)\nret\n\n\0"); _write_z(".type _store_byte, @function\n_store_byte:\n\tsb a0, (a1)\nret\n\n\0"); - current_part := elna_rtl_module_get_code(pair); + current_part := ElnaInstructionModule_get_code(pair); _elna_writer_procedure(current_part); _write_z(".section .rodata\n.type strings, @object\nstrings: .ascii \0"); @@ -1467,16 +1566,27 @@ begin return result end; -proc _elna_tac_integer_literal(integer_literal_node: Word); +proc _elna_tac_integer_literal(integer_literal_node: Word, instruction: Word, operand_type: Word, operand_value: Word, operand_length: Word); var integer_token: Word; integer_length: Word; token_kind: Word; + result: Word; begin integer_token := _integer_literal_node_get_value(integer_literal_node); integer_length := _integer_literal_node_get_length(integer_literal_node); - return _elna_tac_load_immediate(ElnaRtlRegister.t0, integer_token, integer_length) + if instruction <> 0 then + instruction^ := 0; + operand_type^ := ElnaTacOperand.immediate; + operand_value^ := integer_token; + operand_length^ := integer_length + end; + result := _elna_tac_instruction_create(ElnaTacOperator.assign); + _elna_tac_instruction_set_operand(result, 1, ElnaTacOperand.register, ElnaRtlRegister.t0, 0); + _elna_tac_instruction_set_operand(result, 2, ElnaTacOperand.immediate, integer_token, integer_length); + + return result end; proc _elna_parser_character_literal(); @@ -1499,15 +1609,26 @@ begin return result end; -proc _elna_tac_character_literal(character_literal_node: Word); +proc _elna_tac_character_literal(character_literal_node: Word, instruction: Word, operand_type: Word, operand_value: Word, operand_length: Word); var character: Word; character_length: Word; + result: Word; begin character := _character_literal_node_get_value(character_literal_node); character_length := _character_literal_node_get_length(character_literal_node); - return _elna_tac_load_immediate(ElnaRtlRegister.t0, character, character_length) + if instruction <> 0 then + instruction^ := 0; + operand_type^ := ElnaTacOperand.immediate; + operand_value^ := character; + operand_length^ := character_length + end; + result := _elna_tac_instruction_create(ElnaTacOperator.assign); + _elna_tac_instruction_set_operand(result, 1, ElnaTacOperand.register, ElnaRtlRegister.t0); + _elna_tac_instruction_set_operand(result, 2, ElnaTacOperand.immediate, character, character_length); + + return result end; proc _elna_parser_variable_expression(); @@ -1530,7 +1651,7 @@ begin return result end; -proc _elna_tac_variable_expression(variable_expression: Word, symbol_table: Word); +proc _elna_tac_variable_expression(variable_expression: Word, symbol_table: Word, new_api_instruction: Word, operand_type: Word, operand_value: Word, operand_length: Word); var name: Word; name_token: Word; @@ -1542,9 +1663,9 @@ begin lookup_result := _symbol_table_lookup(symbol_table, name, name_token); if lookup_result <> 0 then - instruction := _elna_tac_local_designator(lookup_result) + instruction := _elna_tac_local_designator(lookup_result, new_api_instruction, operand_type, operand_value, operand_length) else - instruction := _elna_tac_global_designator(variable_expression) + instruction := _elna_tac_global_designator(variable_expression, new_api_instruction, operand_type, operand_value, operand_length) end; return instruction end; @@ -1568,24 +1689,43 @@ begin return result end; -proc _elna_tac_string_literal(string_literal_node: Word); +proc _elna_tac_string_literal(string_literal_node: Word, new_api_instruction: Word, operand_type: Word, operand_value: Word, operand_length: Word); var token_start: Word; - length: Word; offset: Word; instruction: Word; first_instruction: Word; next_instruction: Word; + string_constant: Word; begin token_start := _string_literal_node_get_value(string_literal_node); - length := _string_literal_node_get_length(string_literal_node); offset := _add_string(token_start); + string_constant := "strings"; + first_instruction := _elna_tac_load_address(ElnaRtlRegister.t0, string_constant, 7); - first_instruction := _elna_tac_load_address(ElnaRtlRegister.t0, "strings", 7); - instruction := _elna_tac_load_immediate(ElnaRtlRegister.t1, offset, 0); - _elna_tac_instruction_set_next(first_instruction, instruction); - next_instruction := _elna_tac_add(ElnaRtlRegister.t0, ElnaRtlRegister.t0, ElnaRtlRegister.t1); - _elna_tac_instruction_set_next(instruction, next_instruction); + (* Add offset to the string block pointer. *) + next_instruction := _elna_tac_instruction_create(ElnaTacOperator.add); + _elna_tac_instruction_set_operand(next_instruction, 1, ElnaTacOperand.register, ElnaRtlRegister.t0, 0); + _elna_tac_instruction_set_operand(next_instruction, 2, ElnaTacOperand.register, ElnaRtlRegister.t0, 0); + _elna_tac_instruction_set_operand(next_instruction, 3, ElnaTacOperand.immediate, offset, 0); + + elna_instruction_list_concatenate(first_instruction, next_instruction); + + if new_api_instruction <> 0 then + new_api_instruction^ := _elna_tac_load_address(ElnaRtlRegister.t0, string_constant, 7); + + (* Add offset to the string block pointer. *) + instruction := _elna_tac_instruction_create(ElnaTacOperator.add); + _elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.register, ElnaRtlRegister.t0, 0); + _elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.register, ElnaRtlRegister.t0, 0); + _elna_tac_instruction_set_operand(instruction, 3, ElnaTacOperand.immediate, offset, 0); + + elna_instruction_list_concatenate(new_api_instruction^, instruction); + + operand_type^ := ElnaTacOperand.register; + operand_value^ := ElnaRtlRegister.t0; + operand_length^ := 0 + end; return first_instruction end; @@ -1643,9 +1783,8 @@ begin return simple_expression end; -proc _elna_tac_simple_expression(parser_node: Word, symbol_table: Word, is_address: Word); +proc _elna_tac_simple_expression(parser_node: Word, symbol_table: Word, is_address: Word, new_api_instruction: Word, operand_type: Word, operand_value: Word, operand_length: Word); var - is_address: Word; node_kind: Word; instruction: Word; begin @@ -1653,13 +1792,13 @@ begin node_kind := _node_get_kind(parser_node); if node_kind = NodeKind.character_literal then - instruction := _elna_tac_character_literal(parser_node) + instruction := _elna_tac_character_literal(parser_node, new_api_instruction, operand_type, operand_value, operand_length) elsif node_kind = NodeKind.string_literal then - instruction := _elna_tac_string_literal(parser_node) + instruction := _elna_tac_string_literal(parser_node, new_api_instruction, operand_type, operand_value, operand_length) elsif node_kind = NodeKind.integer_literal then - instruction := _elna_tac_integer_literal(parser_node) + instruction := _elna_tac_integer_literal(parser_node, new_api_instruction, operand_type, operand_value, operand_length) else - instruction := _elna_tac_variable_expression(parser_node, symbol_table); + instruction := _elna_tac_variable_expression(parser_node, symbol_table, new_api_instruction, operand_type, operand_value, operand_length); is_address^ := 1 end; return instruction @@ -1699,7 +1838,7 @@ begin return result end; -proc _elna_tac_unary_expression(parser_node: Word, symbol_table: Word); +proc _elna_tac_unary_expression(parser_node: Word, symbol_table: Word, new_api_instruction: Word, operand_type: Word, operand_value: Word, operand_length: Word); var current_character: Word; token_kind: Word; @@ -1723,20 +1862,40 @@ begin end; if operator = '@' then - first_instruction := _elna_tac_designator(operand, symbol_table, @is_address) + first_instruction := _elna_tac_designator(operand, symbol_table, @is_address, new_api_instruction, operand_type, operand_value, operand_length); + if new_api_instruction <> 0 then + instruction := _elna_tac_instruction_create(ElnaTacOperator.get_address); + ElnaInstructionList_set_next(instruction, 0); + _elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.register, ElnaRtlRegister.t0, 0); + _elna_tac_instruction_set_operand(instruction, 2, operand_type^, operand_value^, operand_length^); + + operand_type^ := ElnaTacOperand.register; + operand_value^ := ElnaRtlRegister.t0; + operand_length^ := 0; + + if new_api_instruction^ = 0 then + new_api_instruction^ := instruction + else + elna_instruction_list_concatenate(new_api_instruction^, instruction) + end + end else - first_instruction := _elna_tac_designator(operand, symbol_table, @is_address); + if operator = 0 then + first_instruction := _elna_tac_designator(operand, symbol_table, @is_address, new_api_instruction, operand_type, operand_value, operand_length) + else + first_instruction := _elna_tac_designator(operand, symbol_table, @is_address, 0, 0, 0, 0) + end; if is_address then instruction := _elna_tac_load_word(ElnaRtlRegister.t0, ElnaRtlRegister.t0, 0); - _elna_tac_instruction_set_next(first_instruction, instruction) + elna_instruction_list_concatenate(first_instruction, instruction) end end; if operator = '-' then instruction := _elna_tac_neg(ElnaRtlRegister.t0, ElnaRtlRegister.t0); - _elna_tac_instruction_set_next(first_instruction, instruction) + elna_instruction_list_concatenate(first_instruction, instruction) elsif operator = '~' then instruction := _elna_tac_not(ElnaRtlRegister.t0, ElnaRtlRegister.t0); - _elna_tac_instruction_set_next(first_instruction, instruction) + elna_instruction_list_concatenate(first_instruction, instruction) end; return first_instruction end; @@ -1808,7 +1967,7 @@ begin return result end; -proc _elna_tac_binary_expression(parser_node: Word, symbol_table: Word); +proc _elna_tac_binary_expression(parser_node: Word, symbol_table: Word, new_api_instruction: Word, operand_type: Word, operand_value: Word, operand_length: Word); var token_kind: Word; expression_kind: Word; @@ -1820,86 +1979,76 @@ begin expression_kind := _node_get_kind(parser_node); if expression_kind <> NodeKind.binary_expression then - first_instruction := _elna_tac_unary_expression(parser_node, symbol_table) + first_instruction := _elna_tac_unary_expression(parser_node, symbol_table, new_api_instruction, operand_type, operand_value, operand_length) else token_kind := _binary_expression_get_operator(parser_node); operand_node := _binary_expression_get_lhs(parser_node); - first_instruction := _elna_tac_unary_expression(operand_node, symbol_table); + first_instruction := _elna_tac_unary_expression(operand_node, symbol_table, 0, 0, 0, 0); (* Save the value of the left expression on the stack. *) - instruction := _elna_tac_store_word(ElnaRtlRegister.t0, ElnaRtlRegister.sp, 64); - _elna_tac_instruction_set_next(first_instruction, instruction); + instruction := _elna_tac_store_word(ElnaRtlRegister.t0, ElnaRtlRegister.sp, 72); + elna_instruction_list_concatenate(first_instruction, instruction); current_instruction := instruction; operand_node := _binary_expression_get_rhs(parser_node); - instruction := _elna_tac_unary_expression(operand_node, symbol_table); - _elna_tac_instruction_set_next(current_instruction, instruction); + instruction := _elna_tac_unary_expression(operand_node, symbol_table, 0, 0, 0, 0); + elna_instruction_list_concatenate(current_instruction, instruction); current_instruction := instruction; (* Load the left expression from the stack; *) - instruction := _elna_tac_load_word(ElnaRtlRegister.t1, ElnaRtlRegister.sp, 64); - _elna_tac_instruction_set_next(current_instruction, instruction); + instruction := _elna_tac_load_word(ElnaRtlRegister.t1, ElnaRtlRegister.sp, 72); + elna_instruction_list_concatenate(current_instruction, instruction); current_instruction := instruction; + instruction := malloc(_elna_tac_instruction_size()); + elna_instruction_list_concatenate(instruction, 0); + _elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.register, ElnaRtlRegister.t0, 0); + _elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.stack, 72, 0); + _elna_tac_instruction_set_operand(instruction, 3, ElnaTacOperand.register, ElnaRtlRegister.t0, 0); + if token_kind = ElnaLexerKind.plus then - instruction := _elna_tac_add(ElnaRtlRegister.t0, ElnaRtlRegister.t0, ElnaRtlRegister.t1); - _elna_tac_instruction_set_next(current_instruction, instruction) + _elna_tac_instruction_set_kind(instruction, ElnaTacOperator.add); + elna_instruction_list_concatenate(current_instruction, instruction) elsif token_kind = ElnaLexerKind.minus then - instruction := _elna_tac_sub(ElnaRtlRegister.t0, ElnaRtlRegister.t1, ElnaRtlRegister.t0); - _elna_tac_instruction_set_next(current_instruction, instruction) + _elna_tac_instruction_set_kind(instruction, ElnaTacOperator.sub); + elna_instruction_list_concatenate(current_instruction, instruction) elsif token_kind = ElnaLexerKind.multiplication then - instruction := _elna_tac_mul(ElnaRtlRegister.t0, ElnaRtlRegister.t0, ElnaRtlRegister.t1); - _elna_tac_instruction_set_next(current_instruction, instruction) + _elna_tac_instruction_set_kind(instruction, ElnaTacOperator.mul); + elna_instruction_list_concatenate(current_instruction, instruction) elsif token_kind = ElnaLexerKind.and then - instruction := _elna_tac_and(ElnaRtlRegister.t0, ElnaRtlRegister.t0, ElnaRtlRegister.t1); - _elna_tac_instruction_set_next(current_instruction, instruction) + _elna_tac_instruction_set_kind(instruction, ElnaTacOperator.and); + elna_instruction_list_concatenate(current_instruction, instruction) elsif token_kind = ElnaLexerKind._or then - instruction := _elna_tac_or(ElnaRtlRegister.t0, ElnaRtlRegister.t0, ElnaRtlRegister.t1); - _elna_tac_instruction_set_next(current_instruction, instruction) + _elna_tac_instruction_set_kind(instruction, ElnaTacOperator._or); + elna_instruction_list_concatenate(current_instruction, instruction) elsif token_kind = ElnaLexerKind._xor then - instruction := _elna_tac_xor(ElnaRtlRegister.t0, ElnaRtlRegister.t0, ElnaRtlRegister.t1); - _elna_tac_instruction_set_next(current_instruction, instruction) + _elna_tac_instruction_set_kind(instruction, ElnaTacOperator._xor); + elna_instruction_list_concatenate(current_instruction, instruction) elsif token_kind = ElnaLexerKind.equals then - instruction := _elna_tac_xor(ElnaRtlRegister.t0, ElnaRtlRegister.t0, ElnaRtlRegister.t1); - _elna_tac_instruction_set_next(current_instruction, instruction); - current_instruction := instruction; - - instruction := _elna_tac_seqz(ElnaRtlRegister.t0, ElnaRtlRegister.t0); - _elna_tac_instruction_set_next(current_instruction, instruction) + _elna_tac_instruction_set_kind(instruction, ElnaTacOperator.seq); + elna_instruction_list_concatenate(current_instruction, instruction) elsif token_kind = ElnaLexerKind.remainder then - instruction := _elna_tac_rem(ElnaRtlRegister.t0, ElnaRtlRegister.t1, ElnaRtlRegister.t0); - _elna_tac_instruction_set_next(current_instruction, instruction) + _elna_tac_instruction_set_kind(instruction, ElnaTacOperator.rem); + elna_instruction_list_concatenate(current_instruction, instruction) elsif token_kind = ElnaLexerKind.division then - instruction := _elna_tac_div(ElnaRtlRegister.t0, ElnaRtlRegister.t1, ElnaRtlRegister.t0); - _elna_tac_instruction_set_next(current_instruction, instruction) + _elna_tac_instruction_set_kind(instruction, ElnaTacOperator.div); + elna_instruction_list_concatenate(current_instruction, instruction) elsif token_kind = ElnaLexerKind.less_than then - instruction := _elna_tac_slt(ElnaRtlRegister.t0, ElnaRtlRegister.t1, ElnaRtlRegister.t0); - _elna_tac_instruction_set_next(current_instruction, instruction) + _elna_tac_instruction_set_kind(instruction, ElnaTacOperator.slt); + elna_instruction_list_concatenate(current_instruction, instruction) elsif token_kind = ElnaLexerKind.greater_than then - instruction := _elna_tac_slt(ElnaRtlRegister.t0, ElnaRtlRegister.t0, ElnaRtlRegister.t1); - _elna_tac_instruction_set_next(current_instruction, instruction) + _elna_tac_instruction_set_kind(instruction, ElnaTacOperator.sgt); + elna_instruction_list_concatenate(current_instruction, instruction) elsif token_kind = ElnaLexerKind.less_equal then - instruction := _elna_tac_slt(ElnaRtlRegister.t0, ElnaRtlRegister.t0, ElnaRtlRegister.t1); - _elna_tac_instruction_set_next(current_instruction, instruction); - current_instruction := instruction; - - instruction := _elna_tac_xor_immediate(ElnaRtlRegister.t0, ElnaRtlRegister.t0, 1); - _elna_tac_instruction_set_next(current_instruction, instruction) - elsif token_kind = ElnaLexerKind.not_equal then - instruction := _elna_tac_xor(ElnaRtlRegister.t0, ElnaRtlRegister.t0, ElnaRtlRegister.t1); - _elna_tac_instruction_set_next(current_instruction, instruction); - current_instruction := instruction; - - instruction := _elna_tac_snez(ElnaRtlRegister.t0, ElnaRtlRegister.t0); - _elna_tac_instruction_set_next(current_instruction, instruction) + _elna_tac_instruction_set_kind(instruction, ElnaTacOperator.sle); + elna_instruction_list_concatenate(current_instruction, instruction) elsif token_kind = ElnaLexerKind.greater_equal then - instruction := _elna_tac_slt(ElnaRtlRegister.t0, ElnaRtlRegister.t1, ElnaRtlRegister.t0); - _elna_tac_instruction_set_next(current_instruction, instruction); - current_instruction := instruction; - - instruction := _elna_tac_xor_immediate(ElnaRtlRegister.t0, ElnaRtlRegister.t0, 1); - _elna_tac_instruction_set_next(current_instruction, instruction) + _elna_tac_instruction_set_kind(instruction, ElnaTacOperator.sge); + elna_instruction_list_concatenate(current_instruction, instruction) + elsif token_kind = ElnaLexerKind.not_equal then + _elna_tac_instruction_set_kind(instruction, ElnaTacOperator.sne); + elna_instruction_list_concatenate(current_instruction, instruction) end end; return first_instruction @@ -2002,11 +2151,11 @@ begin if parsed_expression = 0 then goto elna_tac_call_finalize else - instruction := _elna_tac_binary_expression(parsed_expression, symbol_table); + instruction := _elna_tac_binary_expression(parsed_expression, symbol_table, 0, 0, 0, 0); if first_instruction = 0 then first_instruction := instruction else - _elna_tac_instruction_set_next(current_instruction, instruction) + elna_instruction_list_concatenate(current_instruction, instruction) end; current_instruction := instruction; @@ -2014,8 +2163,8 @@ begin stack_offset := argument_count * 4; instruction := _elna_tac_store_word(ElnaRtlRegister.t0, - ElnaRtlRegister.sp, 116 - stack_offset); - _elna_tac_instruction_set_next(current_instruction, instruction); + ElnaRtlRegister.sp, 132 - stack_offset); + elna_instruction_list_concatenate(current_instruction, instruction); current_instruction := instruction; argument_count := argument_count + 1; @@ -2029,10 +2178,10 @@ begin argument_count := argument_count - 1; stack_offset := argument_count * 4; - (* Calculate the stack offset: 116 - (4 * argument_counter) *) + (* Calculate the stack offset: 132 - (4 * argument_counter) *) instruction := _elna_tac_load_word(ElnaRtlRegister.a0 + argument_count, - ElnaRtlRegister.sp, 116 - stack_offset); - _elna_tac_instruction_set_next(current_instruction, instruction); + ElnaRtlRegister.sp, 132 - stack_offset); + elna_instruction_list_concatenate(current_instruction, instruction); current_instruction := instruction; goto elna_tac_call_finalize @@ -2041,7 +2190,7 @@ begin if first_instruction = 0 then first_instruction := instruction else - _elna_tac_instruction_set_next(current_instruction, instruction) + elna_instruction_list_concatenate(current_instruction, instruction) end; return first_instruction end; @@ -2122,27 +2271,41 @@ begin return _elna_tac_label(label_name, label_length) end; -proc _elna_tac_local_designator(symbol: Word); +proc _elna_tac_local_designator(symbol: Word, instruction: Word, operand_type: Word, operand_value: Word, operand_length: Word); var variable_offset: Word; begin variable_offset := _parameter_info_get_offset(symbol); - return _elna_tac_add_immediate(ElnaRtlRegister.t0, ElnaRtlRegister.sp, variable_offset) + if instruction <> 0 then + instruction^ := 0; + operand_type^ := ElnaTacOperand.stack; + operand_value^ := variable_offset; + operand_length^ := 0 + end; + + return _elna_tac_add(ElnaRtlRegister.t0, ElnaRtlRegister.sp, ElnaTacOperand.immediate, variable_offset) end; -proc _elna_tac_global_designator(variable_expression: Word); +proc _elna_tac_global_designator(variable_expression: Word, instruction: Word, operand_type: Word, operand_value: Word, operand_length: Word); var - name: Word; - token_length: Word; + name_pointer: Word; + name_length: Word; begin - name := _variable_expression_get_name(variable_expression); - token_length := _variable_expression_get_length(variable_expression); + name_pointer := _variable_expression_get_name(variable_expression); + name_length := _variable_expression_get_length(variable_expression); - return _elna_tac_load_address(ElnaRtlRegister.t0, name, token_length) + if instruction <> 0 then + instruction^ := 0; + operand_type^ := ElnaTacOperand.symbol; + operand_value^ := name_pointer; + operand_length^ := name_length + end; + + return _elna_tac_load_address(ElnaRtlRegister.t0, name_pointer, name_length) end; -proc _elna_tac_enumeration_value(field_access_expression: Word); +proc _elna_tac_enumeration_value(field_access_expression: Word, new_api_instruction: Word, operand_type: Word, operand_value: Word, operand_length: Word); var enumeration_type: Word; members: Word; @@ -2185,7 +2348,17 @@ begin counter := counter + 1; goto elna_tac_enumeration_value_members end; - instruction := _elna_tac_load_immediate(ElnaRtlRegister.t0, counter, 0) + (* Found. *) + instruction := _elna_tac_instruction_create(ElnaTacOperator.assign); + _elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.register, ElnaRtlRegister.t0); + _elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.immediate, counter, 0); + + if new_api_instruction <> 0 then + new_api_instruction^ := 0; + operand_type^ := ElnaTacOperand.immediate; + operand_value^ := counter; + operand_length^ := 0 + end end; return instruction end; @@ -2216,33 +2389,51 @@ begin return result end; -proc _elna_tac_designator(parser_node: Word, symbol_table: Word, is_address: Word); +proc _elna_tac_designator(parser_node: Word, symbol_table: Word, is_address: Word, new_api_instruction: Word, operand_type: Word, operand_value: Word, operand_length: Word); var - name_token: Word; - lookup_result: Word; - token_kind: Word; parser_node: Word; node_kind: Word; first_instruction: Word; - instruction: Word; + last_instruction: Word; begin node_kind := _node_get_kind(parser_node); if node_kind = NodeKind.dereference_expression then parser_node := _dereference_expression_get_pointer(parser_node); - first_instruction := _elna_tac_simple_expression(parser_node, symbol_table, is_address); - instruction := _elna_tac_load_word(ElnaRtlRegister.t0, ElnaRtlRegister.t0, 0); - _elna_tac_instruction_set_next(first_instruction, instruction) + first_instruction := _elna_tac_simple_expression(parser_node, symbol_table, is_address, new_api_instruction, operand_type, operand_value, operand_length); + + if new_api_instruction <> 0 then + last_instruction := _elna_tac_instruction_create(ElnaTacOperator.load_word); + _elna_tac_instruction_set_operand(last_instruction, 1, ElnaTacOperand.register, ElnaRtlRegister.t0, 0); + _elna_tac_instruction_set_operand(last_instruction, 2, operand_type^, operand_value^, operand_length^); + + if new_api_instruction^ = 0 then + new_api_instruction^ := last_instruction + else + elna_instruction_list_concatenate(new_api_instruction^, last_instruction); + new_api_instruction^ := last_instruction + end; + operand_type^ := ElnaTacOperand.register; + operand_value^ := ElnaRtlRegister.t0; + operand_length^ := 0 + end; + + last_instruction := _elna_tac_load_word(ElnaRtlRegister.t0, ElnaRtlRegister.t0, 0); + elna_instruction_list_concatenate(first_instruction, last_instruction) elsif node_kind = NodeKind.field_access_expression then - first_instruction := _elna_tac_enumeration_value(parser_node); + first_instruction := _elna_tac_enumeration_value(parser_node, new_api_instruction, operand_type, operand_value, operand_length); is_address^ := 0 elsif node_kind = NodeKind.call then first_instruction := _elna_tac_call(parser_node, symbol_table); - instruction := _elna_tac_move(ElnaRtlRegister.t0, ElnaRtlRegister.a0); - _elna_tac_instruction_set_next(first_instruction, instruction); + + last_instruction := _elna_tac_instruction_create(ElnaTacOperator.assign); + _elna_tac_instruction_set_operand(last_instruction, 1, ElnaTacOperand.register, ElnaRtlRegister.t0, 0); + _elna_tac_instruction_set_operand(last_instruction, 2, ElnaTacOperand.register, ElnaRtlRegister.a0, 0); + + elna_instruction_list_concatenate(first_instruction, last_instruction); is_address^ := 0 else - first_instruction := _elna_tac_simple_expression(parser_node, symbol_table, is_address) + first_instruction := _elna_tac_simple_expression(parser_node, symbol_table, is_address, new_api_instruction, operand_type, operand_value, operand_length) end; return first_instruction end; @@ -2276,24 +2467,47 @@ var first_instruction: Word; instruction: Word; current_instruction: Word; + new_api_instruction: Word; + operand_type: Word; + operand_value: Word; + operand_length: Word; begin + new_api_instruction := 0; + operand_type := 0; + operand_value := 0; + operand_length := 0; + current_expression := _assign_statement_get_assignee(parser_tree); - first_instruction := _elna_tac_designator(current_expression, symbol_table, @is_address); + first_instruction := _elna_tac_designator(current_expression, symbol_table, @is_address, 0, 0, 0, 0); (* Save the assignee address on the stack. *) - current_instruction := _elna_tac_store_word(ElnaRtlRegister.t0, ElnaRtlRegister.sp, 60); - _elna_tac_instruction_set_next(first_instruction, current_instruction); + current_instruction := _elna_tac_store_word(ElnaRtlRegister.t0, ElnaRtlRegister.sp, 76); + elna_instruction_list_concatenate(first_instruction, current_instruction); (* Compile the assignment. *) current_expression := _assign_statement_get_assignment(parser_tree); - instruction := _elna_tac_binary_expression(current_expression, symbol_table); - _elna_tac_instruction_set_next(current_instruction, instruction); + instruction := _elna_tac_binary_expression(current_expression, symbol_table, @new_api_instruction, @operand_type, @operand_value, @operand_length); - current_instruction := _elna_tac_load_word(ElnaRtlRegister.t1, ElnaRtlRegister.sp, 60); - _elna_tac_instruction_set_next(instruction, current_instruction); + if operand_type = 0 then + elna_instruction_list_concatenate(current_instruction, instruction) + else + elna_instruction_list_concatenate(current_instruction, new_api_instruction); + if new_api_instruction <> 0 then + current_instruction := new_api_instruction + end; + + instruction := _elna_tac_instruction_create(ElnaTacOperator.assign); + _elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.register, ElnaRtlRegister.t0, 0); + _elna_tac_instruction_set_operand(instruction, 2, operand_type, operand_value, operand_length); + + elna_instruction_list_concatenate(current_instruction, instruction) + end; + + current_instruction := _elna_tac_load_word(ElnaRtlRegister.t1, ElnaRtlRegister.sp, 76); + elna_instruction_list_concatenate(instruction, current_instruction); instruction := _elna_tac_store_word(ElnaRtlRegister.t0, ElnaRtlRegister.t1, 0); - _elna_tac_instruction_set_next(current_instruction, instruction); + elna_instruction_list_concatenate(current_instruction, instruction); return first_instruction end; @@ -2326,9 +2540,13 @@ var instruction: Word; begin return_expression := _return_statement_get_returned(parser_node); - first_instruction := _elna_tac_binary_expression(return_expression, symbol_table); - instruction := _elna_tac_move(ElnaRtlRegister.a0, ElnaRtlRegister.t0); - _elna_tac_instruction_set_next(first_instruction, instruction); + first_instruction := _elna_tac_binary_expression(return_expression, symbol_table, 0, 0, 0, 0); + + instruction := _elna_tac_instruction_create(ElnaTacOperator.assign); + _elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.register, ElnaRtlRegister.a0, 0); + _elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.register, ElnaRtlRegister.t0, 0); + + elna_instruction_list_concatenate(first_instruction, instruction); return first_instruction end; @@ -2389,27 +2607,27 @@ var begin (* Compile condition. *) current_node := _conditional_statements_get_condition(parser_node); - first_instruction := _elna_tac_binary_expression(current_node, symbol_table); + first_instruction := _elna_tac_binary_expression(current_node, symbol_table, 0, 0, 0, 0); (* condition_label is the label in front of the next elsif condition or end. *) condition_label := label_counter; label_counter := label_counter + 1; current_instruction := _elna_tac_beqz(ElnaRtlRegister.t0, condition_label, 0); - _elna_tac_instruction_set_next(first_instruction, current_instruction); + elna_instruction_list_concatenate(first_instruction, current_instruction); current_node := _conditional_statements_get_statements(parser_node); instruction := _elna_tac_statements(current_node, symbol_table); if instruction <> 0 then - _elna_tac_instruction_set_next(current_instruction, instruction); + elna_instruction_list_concatenate(current_instruction, instruction); current_instruction := instruction end; instruction := _elna_tac_jump(after_end_label, 0); - _elna_tac_instruction_set_next(current_instruction, instruction); + elna_instruction_list_concatenate(current_instruction, instruction); current_instruction := _elna_tac_label(condition_label, 0); - _elna_tac_instruction_set_next(instruction, current_instruction); + elna_instruction_list_concatenate(instruction, current_instruction); return first_instruction end; @@ -2533,7 +2751,7 @@ begin if first_instruction = 0 then first_instruction := instruction else - _elna_tac_instruction_set_next(current_instruction, instruction) + elna_instruction_list_concatenate(current_instruction, instruction) end; current_instruction := instruction; goto elna_tac_statements_loop @@ -2561,7 +2779,7 @@ begin current_node := _conditional_statements_get_next(current_node); if current_node <> 0 then instruction := _elna_tac_conditional_statements(current_node, after_end_label, symbol_table); - _elna_tac_instruction_set_next(current_instruction, instruction); + elna_instruction_list_concatenate(current_instruction, instruction); current_instruction := instruction; goto elna_tac_if_statement_loop end; @@ -2570,12 +2788,12 @@ begin if current_node <> 0 then instruction := _elna_tac_statements(current_node, symbol_table); if instruction <> 0 then - _elna_tac_instruction_set_next(current_instruction, instruction); + elna_instruction_list_concatenate(current_instruction, instruction); current_instruction := instruction end end; instruction := _elna_tac_label(after_end_label, 0); - _elna_tac_instruction_set_next(current_instruction, instruction); + elna_instruction_list_concatenate(current_instruction, instruction); return first_instruction end; @@ -2919,9 +3137,9 @@ begin result := malloc(_parameter_info_size()); _info_set_kind(result, InfoKind.parameter_info); - (* Calculate the stack offset: 88 - (4 * parameter_counter) *) + (* Calculate the stack offset: 104 - (4 * parameter_counter) *) offset := parameter_index * 4; - _parameter_info_set_offset(result, 88 - offset); + _parameter_info_set_offset(result, 104 - offset); return result end; @@ -3117,12 +3335,11 @@ begin symbol_info := _parameter_info_get_offset(symbol_info); - instruction := _elna_tac_store_word(ElnaRtlRegister.a0 + parameter_counter, - ElnaRtlRegister.sp, symbol_info); + instruction := _elna_tac_store_word(ElnaRtlRegister.a0 + parameter_counter, ElnaRtlRegister.sp, symbol_info); if first_instruction = 0 then first_instruction := instruction else - _elna_tac_instruction_set_next(current_instruction, instruction) + elna_instruction_list_concatenate(current_instruction, instruction) end; current_instruction := instruction; @@ -3141,15 +3358,15 @@ var body: Word; result: Word; begin - result := malloc(elna_rtl_declaration_size()); - name := _elna_tac_declaration_get_name(tac_declaration); - length := _elna_tac_declaration_get_length(tac_declaration); - body := _elna_tac_declaration_get_body(tac_declaration); + result := malloc(ElnaInstructionDeclaration_size()); + name := ElnaInstructionDeclaration_get_name(tac_declaration); + length := ElnaInstructionDeclaration_get_length(tac_declaration); + body := ElnaInstructionDeclaration_get_body(tac_declaration); - elna_rtl_declaration_set_next(result, 0); - elna_rtl_declaration_set_name(result, name); - elna_rtl_declaration_set_length(result, length); - elna_rtl_declaration_set_body(result, body); + ElnaInstructionList_set_next(result, 0); + ElnaInstructionDeclaration_set_name(result, name); + ElnaInstructionDeclaration_set_length(result, length); + ElnaInstructionDeclaration_set_body(result, body); return result end; @@ -3161,16 +3378,16 @@ var body: Word; result: Word; begin - result := malloc(elna_rtl_declaration_size()); - name := _elna_tac_declaration_get_name(tac_declaration); - length := _elna_tac_declaration_get_length(tac_declaration); - body := _elna_tac_declaration_get_body(tac_declaration); + result := malloc(ElnaInstructionDeclaration_size()); + name := ElnaInstructionDeclaration_get_name(tac_declaration); + length := ElnaInstructionDeclaration_get_length(tac_declaration); + body := ElnaInstructionDeclaration_get_body(tac_declaration); body := elna_rtl_instructions(body); - elna_rtl_declaration_set_next(result, 0); - elna_rtl_declaration_set_name(result, name); - elna_rtl_declaration_set_length(result, length); - elna_rtl_declaration_set_body(result, body); + ElnaInstructionList_set_next(result, 0); + ElnaInstructionDeclaration_set_name(result, name); + ElnaInstructionDeclaration_set_length(result, length); + ElnaInstructionDeclaration_set_body(result, body); return result end; @@ -3188,15 +3405,15 @@ var result: Word; result_size: Word; begin - result := malloc(_elna_tac_declaration_size()); + result := malloc(ElnaInstructionDeclaration_size()); - _elna_tac_declaration_set_next(result, 0); + ElnaInstructionList_set_next(result, 0); name_pointer := _declaration_get_name(parser_node); name_length := _declaration_get_length(parser_node); - _elna_tac_declaration_set_name(result, name_pointer); - _elna_tac_declaration_set_length(result, name_length); + ElnaInstructionDeclaration_set_name(result, name_pointer); + ElnaInstructionDeclaration_set_length(result, name_length); symbol_info := _symbol_table_lookup(@symbol_table_global, name_pointer, name_length); new_symbol_table := _procedure_info_get_symbol_table(symbol_info); @@ -3206,17 +3423,17 @@ begin current_parameter := _procedure_declaration_get_parameters(parser_node); current_parameter := _elna_tac_parameters(current_parameter, new_symbol_table); - _elna_tac_instruction_set_next(first_instruction, current_parameter); + elna_instruction_list_concatenate(first_instruction, current_parameter); body := _procedure_declaration_get_body(parser_node); instruction := _elna_tac_statements(body, new_symbol_table); - _elna_tac_instruction_set_next(first_instruction, instruction); + elna_instruction_list_concatenate(first_instruction, instruction); (* Write the epilogue. *) instruction := _elna_tac_instruction_create(ElnaTacOperator.ret); - _elna_tac_instruction_set_next(first_instruction, instruction); + elna_instruction_list_concatenate(first_instruction, instruction); - _elna_tac_declaration_set_body(result, first_instruction); + ElnaInstructionDeclaration_set_body(result, first_instruction); return result end; @@ -3260,7 +3477,7 @@ var begin if tac_procedure <> 0 then first_copy := elna_rtl_global_declaration(tac_procedure); - tac_procedure := _elna_tac_declaration_get_next(tac_procedure) + tac_procedure := ElnaInstructionList_get_next(tac_procedure) else first_copy := 0; end; @@ -3271,8 +3488,8 @@ begin if tac_procedure <> 0 then next_copy := elna_rtl_global_declaration(tac_procedure); - tac_procedure := _elna_tac_declaration_get_next(tac_procedure); - elna_rtl_declaration_set_next(current_copy, next_copy); + tac_procedure := ElnaInstructionList_get_next(tac_procedure); + ElnaInstructionList_set_next(current_copy, next_copy); current_copy := next_copy; goto elna_rtl_globals_start end; @@ -3288,7 +3505,7 @@ var begin if tac_procedure <> 0 then first_copy := elna_rtl_procedure_declaration(tac_procedure); - tac_procedure := _elna_tac_declaration_get_next(tac_procedure) + tac_procedure := ElnaInstructionList_get_next(tac_procedure) else first_copy := 0; end; @@ -3299,8 +3516,8 @@ begin if tac_procedure <> 0 then next_copy := elna_rtl_procedure_declaration(tac_procedure); - tac_procedure := _elna_tac_declaration_get_next(tac_procedure); - elna_rtl_declaration_set_next(current_copy, next_copy); + tac_procedure := ElnaInstructionList_get_next(tac_procedure); + ElnaInstructionList_set_next(current_copy, next_copy); current_copy := next_copy; goto elna_rtl_procedures_start end; @@ -3324,7 +3541,7 @@ begin if first_procedure = 0 then first_procedure := result else - _elna_tac_declaration_set_next(current_procedure, result) + ElnaInstructionList_set_next(current_procedure, result) end; current_procedure := result; @@ -3475,25 +3692,25 @@ var variable_type: Word; result: Word; begin - result := malloc(_elna_tac_declaration_size()); + result := malloc(ElnaInstructionDeclaration_size()); - _elna_tac_declaration_set_next(result, 0); + ElnaInstructionList_set_next(result, 0); name := _declaration_get_name(parser_tree); name_length := _declaration_get_length(parser_tree); variable_type := _variable_declaration_get__type(parser_tree); - _elna_tac_declaration_set_name(result, name); - _elna_tac_declaration_set_length(result, name_length); + ElnaInstructionDeclaration_set_name(result, name); + ElnaInstructionDeclaration_set_length(result, name_length); name := _named_type_expression_get_name(variable_type); name_length := _named_type_expression_get_length(variable_type); if string_compare("Array", 5, name, name_length) then (* Else we assume this is a zeroed 4096 bytes big array. *) - _elna_tac_declaration_set_body(result, 4096) + ElnaInstructionDeclaration_set_body(result, 4096) else - _elna_tac_declaration_set_body(result, 4) + ElnaInstructionDeclaration_set_body(result, 4) end; return result end; @@ -3514,8 +3731,8 @@ begin new_length := field_length + name_length; new_length := new_length + 5; - first_result := malloc(_elna_tac_declaration_size()); - _elna_tac_declaration_set_next(first_result, 0); + first_result := malloc(ElnaInstructionDeclaration_size()); + ElnaInstructionList_set_next(first_result, 0); new_name := malloc(new_length); @@ -3526,16 +3743,16 @@ begin name_target := name_target + 5; memcpy(name_target, field_pointer^, field_length); - _elna_tac_declaration_set_name(first_result, new_name); - _elna_tac_declaration_set_length(first_result, new_length); + ElnaInstructionDeclaration_set_name(first_result, new_name); + ElnaInstructionDeclaration_set_length(first_result, new_length); - instruction := _elna_tac_add_immediate(ElnaRtlRegister.a0, ElnaRtlRegister.a0, field_offset, 0); + instruction := _elna_tac_add(ElnaRtlRegister.a0, ElnaRtlRegister.a0, ElnaTacOperand.immediate, field_offset); next_instruction := _elna_tac_load_word(ElnaRtlRegister.a0, ElnaRtlRegister.a0, 0); - _elna_tac_instruction_set_next(instruction, next_instruction); - _elna_tac_declaration_set_body(first_result, instruction); + elna_instruction_list_concatenate(instruction, next_instruction); + ElnaInstructionDeclaration_set_body(first_result, instruction); - second_result := malloc(_elna_tac_declaration_size()); - _elna_tac_declaration_set_next(second_result, 0); + second_result := malloc(ElnaInstructionDeclaration_size()); + ElnaInstructionList_set_next(second_result, 0); new_name := malloc(new_length); @@ -3546,15 +3763,15 @@ begin name_target := name_target + 5; memcpy(name_target, field_pointer^, field_length); - _elna_tac_declaration_set_name(second_result, new_name); - _elna_tac_declaration_set_length(second_result, new_length); + ElnaInstructionDeclaration_set_name(second_result, new_name); + ElnaInstructionDeclaration_set_length(second_result, new_length); - instruction := _elna_tac_add_immediate(ElnaRtlRegister.a0, ElnaRtlRegister.a0, field_offset, 0); + instruction := _elna_tac_add(ElnaRtlRegister.a0, ElnaRtlRegister.a0, ElnaTacOperand.immediate, field_offset); next_instruction := _elna_tac_store_word(ElnaRtlRegister.a1, ElnaRtlRegister.a0, 0); - _elna_tac_instruction_set_next(instruction, next_instruction); - _elna_tac_declaration_set_body(second_result, instruction); + elna_instruction_list_concatenate(instruction, next_instruction); + ElnaInstructionDeclaration_set_body(second_result, instruction); - _elna_tac_declaration_set_next(first_result, second_result); + ElnaInstructionList_set_next(first_result, second_result); return first_result end; @@ -3571,12 +3788,9 @@ var field_offset: Word; field_pointer: Word; begin - first_result := malloc(_elna_tac_declaration_size()); + first_result := malloc(ElnaInstructionDeclaration_size()); result := 0; - (* Debug. Error stream output. - _syscall(2, name_pointer, name_length, 0, 0, 0, 64); *) - type_size := _type_get_size(type_representation); new_length := name_length + 5; new_name := malloc(new_length); @@ -3584,11 +3798,14 @@ begin memcpy(new_name, name_pointer, name_length); memcpy(new_name + name_length, "_size", 5); - _elna_tac_declaration_set_name(first_result, new_name); - _elna_tac_declaration_set_length(first_result, new_length); + ElnaInstructionDeclaration_set_name(first_result, new_name); + ElnaInstructionDeclaration_set_length(first_result, new_length); - instruction := _elna_tac_load_immediate(ElnaRtlRegister.a0, type_size, 0); - _elna_tac_declaration_set_body(first_result, instruction); + instruction := _elna_tac_instruction_create(ElnaTacOperator.assign); + _elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.register, ElnaRtlRegister.a0, 0); + _elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.immediate, type_size, 0); + + ElnaInstructionDeclaration_set_body(first_result, instruction); field_count := _record_type_get_length(type_representation); field_pointer := _record_type_get_members(type_representation); @@ -3599,8 +3816,8 @@ begin if field_count > 0 then result := _elna_tac_type_field(name_pointer, name_length, field_pointer, field_offset); - _elna_tac_declaration_set_next(current_result^, result); - current_result^ := _elna_tac_declaration_get_next(result); + ElnaInstructionList_set_next(current_result^, result); + current_result^ := ElnaInstructionList_get_next(result); field_offset := field_offset + 4; field_count := field_count - 1; @@ -3647,7 +3864,7 @@ begin first_result := result; current_result := out_result elsif result <> 0 then - _elna_tac_declaration_set_next(current_result, result); + ElnaInstructionList_set_next(current_result, result); current_result := out_result end; parser_node := _declaration_get_next(parser_node); @@ -3713,7 +3930,7 @@ begin if first_variable = 0 then first_variable := node else - _elna_tac_declaration_set_next(current_variable, node) + ElnaInstructionList_set_next(current_variable, node) end; current_variable := node; @@ -3770,15 +3987,15 @@ begin current_declaration := code_part; .elna_tac_module_declaration_types; - next_declaration := _elna_tac_declaration_get_next(current_declaration); + next_declaration := ElnaInstructionList_get_next(current_declaration); if next_declaration <> 0 then current_declaration := next_declaration; goto elna_tac_module_declaration_types end; - _elna_tac_declaration_set_next(current_declaration, type_part); + ElnaInstructionList_set_next(current_declaration, type_part); - return _elna_tac_module_create(data_part, code_part) + return elna_instruction_module_create(data_part, code_part) end; proc _elna_name_procedure_declaration(parser_node: Word); @@ -4790,7 +5007,8 @@ proc _initialize_global_state(); begin compiler_strings_position := @compiler_strings; source_code := malloc(495616); - symbol_table_store := malloc(4194304) + symbol_table_store := malloc(4194304); + temporary_variable_counter := 0 end; (*