diff --git a/boot/stage16/cl.elna b/boot/stage16/cl.elna index e7eb475..ea918e4 100644 --- a/boot/stage16/cl.elna +++ b/boot/stage16/cl.elna @@ -831,41 +831,33 @@ var 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); if operand_type = ElnaTacOperand.immediate then - elna_rtl_instruction_set_kind(result, ElnaRtlOperator.load_immediate); + result := elna_rtl_instruction_create(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) + elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.immediate, operand_value, operand_length) elsif operand_type = ElnaTacOperand.stack then - elna_rtl_instruction_set_kind(result, ElnaRtlOperator.load_word); + result := elna_rtl_instruction_create(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) + 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); + result := elna_rtl_instruction_create(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); + next_instruction := elna_rtl_instruction_create(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); + result := elna_rtl_instruction_create(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) + elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.register, operand_value, 0) end; return result @@ -882,15 +874,12 @@ begin 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(elna_rtl_instruction_size()); - ElnaInstructionList_set_next(result, 0); - if operand_type = ElnaTacOperand.stack then - elna_rtl_instruction_set_kind(result, ElnaRtlOperator.add_immediate); + result := elna_rtl_instruction_create(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); + 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); + result := elna_rtl_instruction_create(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; @@ -920,13 +909,18 @@ begin return lhs end; -proc elna_rtl_binary_arithmetic(tac_instruction: Word, binary_result: Word, next_instruction: Word); +proc elna_rtl_binary_arithmetic(tac_instruction: Word, next_instruction: Word, operation: Word); var lhs: Word; + binary_result: Word; begin lhs := elna_rtl_binary_operands(tac_instruction, next_instruction); + binary_result := elna_rtl_instruction_create(operation); + + elna_rtl_copy_operand(tac_instruction, 1, binary_result); 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); + elna_rtl_instruction_set_kind(binary_result, operation); ElnaInstructionList_set_next(next_instruction^, binary_result); next_instruction^ := binary_result; @@ -955,6 +949,19 @@ begin return operands end; +proc elna_rtl_copy_operand(tac_instruction: Word, number: Word, rtl_instruction: Word); +var + operand_length: Word; + operand_type: Word; + operand_value: Word; +begin + operand_type := _elna_tac_instruction_get_operand_type(tac_instruction, number); + operand_value := _elna_tac_instruction_get_operand_value(tac_instruction, number); + operand_length := _elna_tac_instruction_get_operand_length(tac_instruction, number); + + elna_rtl_instruction_set_operand(rtl_instruction, number, operand_type, operand_value, operand_length) +end; + proc elna_rtl_instruction(tac_instruction: Word, next_instruction: Word); var result: Word; @@ -976,22 +983,24 @@ begin if operand_type = ElnaTacOperand.stack then operand_value := _elna_tac_instruction_get_operand_value(tac_instruction, 2); + result := elna_rtl_instruction_create(ElnaRtlOperator.add); + + elna_rtl_copy_operand(tac_instruction, 1, result); elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.register, ElnaRtlRegister.sp, 0); - elna_rtl_instruction_set_operand(result, 3, ElnaRtlOperand.immediate, operand_value, 0); - elna_rtl_instruction_set_kind(result, ElnaRtlOperator.add) + elna_rtl_instruction_set_operand(result, 3, ElnaRtlOperand.immediate, operand_value, 0) elsif operand_type = ElnaTacOperand.symbol then - elna_rtl_instruction_set_kind(result, ElnaRtlOperator.load_address) + result := elna_rtl_instruction_create(ElnaRtlOperator.load_address); + + elna_rtl_copy_operand(tac_instruction, 1, result); + elna_rtl_copy_operand(tac_instruction, 2, result) elsif operand_type = ElnaTacOperand.register then - elna_rtl_instruction_set_kind(result, ElnaRtlOperator.move); - else - (* Debug. Error stream output. - _syscall(2, name_pointer, name_length, 0, 0, 0, 64); *) - printf("# here %i\n\0", operand_type); - fflush(0); - end; + result := elna_rtl_instruction_create(ElnaRtlOperator.move); + + elna_rtl_copy_operand(tac_instruction, 1, result); + elna_rtl_copy_operand(tac_instruction, 2, result) + 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) + result := elna_rtl_binary_arithmetic(tac_instruction, next_instruction, ElnaRtlOperator.add) elsif instruction_kind = ElnaTacOperator.load_word then operand_type := _elna_tac_instruction_get_operand_type(tac_instruction, 2); @@ -1007,33 +1016,37 @@ begin 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) + operands := elna_rtl_load_operand_value(tac_instruction, 1, ElnaRtlRegister.t0); + next_instruction^ := result; + result := operands; + operands := ElnaInstructionList_get_next(result); + + elna_rtl_instruction_set_kind(next_instruction^, ElnaRtlOperator.store_word); + elna_rtl_instruction_set_operand(next_instruction^, 1, ElnaRtlOperand.register, ElnaRtlRegister.t0, 0); + + if operands = 0 then + ElnaInstructionList_set_next(result, next_instruction^) + else + ElnaInstructionList_set_next(operands, next_instruction^) + end 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) + result := elna_rtl_binary_arithmetic(tac_instruction, 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) + result := elna_rtl_binary_arithmetic(tac_instruction, 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) + result := elna_rtl_binary_arithmetic(tac_instruction, 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) + result := elna_rtl_binary_arithmetic(tac_instruction, 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) + result := elna_rtl_binary_arithmetic(tac_instruction, 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) + result := elna_rtl_binary_arithmetic(tac_instruction, 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) + result := elna_rtl_binary_arithmetic(tac_instruction, 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) + result := elna_rtl_binary_arithmetic(tac_instruction, 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); @@ -1100,9 +1113,27 @@ begin elna_rtl_instruction_set_kind(result, ElnaRtlOperator.label) elsif instruction_kind = ElnaTacOperator.assign then free(result); + operand_type := _elna_tac_instruction_get_operand_type(tac_instruction, 1); 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) + + if operand_type = ElnaTacOperand.register then + result := elna_rtl_load_operand_value(tac_instruction, 2, operand_value); + next_instruction^ := ElnaInstructionList_get_next(result) + elsif operand_type = ElnaTacOperand.stack then + operands := elna_rtl_load_operand_value(tac_instruction, 2, ElnaRtlRegister.t4); + result := operands; + operands := ElnaInstructionList_get_next(result); + + next_instruction^ := elna_rtl_instruction_create(ElnaRtlOperator.store_word); + _elna_tac_instruction_set_operand(next_instruction^, 1, ElnaRtlOperand.register, ElnaRtlRegister.t4, 0); + _elna_tac_instruction_set_operand(next_instruction^, 2, ElnaRtlOperand.offset, ElnaRtlRegister.sp, operand_value); + + if operands = 0 then + ElnaInstructionList_set_next(result, next_instruction^) + else + ElnaInstructionList_set_next(operands, next_instruction^) + end + end end; if next_instruction^ = 0 then next_instruction^ := result; @@ -1122,18 +1153,6 @@ begin return result end; -proc _elna_tac_load_address(target_register: Word, source_symbol: Word, symbol_length: Word); -var - result: Word; -begin - 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); - - return result -end; - proc _elna_tac_jump(source_symbol: Word, symbol_length: Word); var result: Word; @@ -1145,43 +1164,6 @@ begin return result end; -proc _elna_tac_add(destination: Word, lhs: Word, rhs_type: Word, rhs: Word); -var - result: Word; -begin - result := _elna_tac_instruction_create(ElnaTacOperator.add); - - _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, rhs_type, rhs, 0); - - return result -end; - -proc _elna_tac_sub(destination: Word, lhs: Word, rhs: Word); -var - result: Word; -begin - result := _elna_tac_instruction_create(ElnaTacOperator.sub); - - _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; -begin - result := _elna_tac_instruction_create(ElnaTacOperator.jal); - - _elna_tac_instruction_set_operand(result, 1, ElnaTacOperand.symbol, symbol, length); - - return result -end; - proc _elna_tac_load_word(target: Word, register: Word, offset: Word); var result: Word; @@ -1206,30 +1188,6 @@ begin return result end; -proc _elna_tac_neg(destination: Word, source: Word); -var - result: Word; -begin - result := _elna_tac_instruction_create(ElnaTacOperator.neg); - - _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_not(destination: Word, source: Word); -var - result: Word; -begin - result := _elna_tac_instruction_create(ElnaTacOperator.not); - - _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_label(counter: Word, length: Word); var result: Word; @@ -1810,6 +1768,7 @@ var is_address: Word; first_instruction: Word; instruction: Word; + temp: Word; begin operator := 0; operand := 0; @@ -1836,17 +1795,11 @@ begin first_instruction := elna_instruction_list_concatenate(first_instruction, instruction) else + current_character := operand_type^; first_instruction := _elna_tac_designator(operand, symbol_table, @is_address, operand_type, operand_value, operand_length); + operand := operand_type^; - if operand_type^ = ElnaTacOperand.immediate then - first_instruction := _elna_tac_instruction_create(ElnaTacOperator.assign); - _elna_tac_instruction_set_operand(first_instruction, 1, ElnaTacOperand.register, ElnaRtlRegister.t0, 0); - _elna_tac_instruction_set_operand(first_instruction, 2, operand_type^, operand_value^, operand_length^); - - operand_type^ := ElnaTacOperand.register; - operand_value^ := ElnaRtlRegister.t0; - operand_length^ := 0 - elsif first_instruction = 0 then + if first_instruction = 0 then first_instruction := _elna_tac_instruction_create(ElnaTacOperator.get_address); _elna_tac_instruction_set_operand(first_instruction, 1, ElnaTacOperand.register, ElnaRtlRegister.t0, 0); _elna_tac_instruction_set_operand(first_instruction, 2, operand_type^, operand_value^, operand_length^); @@ -1855,7 +1808,6 @@ begin operand_value^ := ElnaRtlRegister.t0; operand_length^ := 0 end; - if is_address then instruction := _elna_tac_instruction_create(ElnaTacOperator.load_word); _elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.register, ElnaRtlRegister.t0, 0); @@ -1869,10 +1821,14 @@ begin end end; if operator = '-' then - instruction := _elna_tac_neg(ElnaRtlRegister.t0, ElnaRtlRegister.t0); + instruction := _elna_tac_instruction_create(ElnaTacOperator.neg); + _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_instruction_list_concatenate(first_instruction, instruction) elsif operator = '~' then - instruction := _elna_tac_not(ElnaRtlRegister.t0, ElnaRtlRegister.t0); + instruction := _elna_tac_instruction_create(ElnaTacOperator.not); + _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_instruction_list_concatenate(first_instruction, instruction) end; return first_instruction @@ -1971,11 +1927,15 @@ begin first_instruction := _elna_tac_unary_expression(operand_node, symbol_table, @lhs_type, @lhs_value, @lhs_length); (* Save the value of the left expression on the stack. *) - instruction := _elna_tac_instruction_create(ElnaTacOperator.store_word); - _elna_tac_instruction_set_operand(instruction, 1, lhs_type, lhs_value, lhs_length); - _elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.offset, ElnaRtlRegister.sp, 72); + instruction := _elna_tac_instruction_create(ElnaTacOperator.assign); + _elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.stack, 72, 0); + _elna_tac_instruction_set_operand(instruction, 2, lhs_type, lhs_value, lhs_length); - elna_instruction_list_concatenate(first_instruction, instruction); + if first_instruction = 0 then + first_instruction := instruction + else + elna_instruction_list_concatenate(first_instruction, instruction) + end; current_instruction := instruction; operand_node := _binary_expression_get_rhs(parser_node); @@ -1983,13 +1943,22 @@ begin lhs_value := 0; lhs_length := 0; instruction := _elna_tac_unary_expression(operand_node, symbol_table, @lhs_type, @lhs_value, @lhs_length); - elna_instruction_list_concatenate(current_instruction, instruction); - current_instruction := instruction; + + (* Debug. Error stream output. + _syscall(2, name_pointer, name_length, 0, 0, 0, 64); + if lhs_length = 0 then + printf("# here %i\n\0", lhs_value); + else + printf("# here %.*s\n\0", lhs_length, lhs_value); + end; + fflush(0); *) + + current_instruction := elna_instruction_list_concatenate(current_instruction, instruction); (* Load the left expression from the stack; *) - instruction := _elna_tac_instruction_create(ElnaTacOperator.load_word); + instruction := _elna_tac_instruction_create(ElnaTacOperator.assign); _elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.register, ElnaRtlRegister.t1, 0); - _elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.offset, ElnaRtlRegister.sp, 72); + _elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.stack, 72, 0); elna_instruction_list_concatenate(current_instruction, instruction); current_instruction := instruction; @@ -2145,7 +2114,9 @@ begin else elna_instruction_list_concatenate(current_instruction, instruction) end; - current_instruction := instruction; + if instruction <> 0 then + current_instruction := instruction + end; (* Save the argument on the stack. *) stack_offset := argument_count * 4; @@ -2153,8 +2124,11 @@ begin instruction := _elna_tac_instruction_create(ElnaTacOperator.store_word); _elna_tac_instruction_set_operand(instruction, 1, operand_type, operand_value, operand_length); _elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.offset, ElnaRtlRegister.sp, 132 - stack_offset); - - elna_instruction_list_concatenate(current_instruction, instruction); + if first_instruction = 0 then + first_instruction := instruction + else + elna_instruction_list_concatenate(current_instruction, instruction) + end; current_instruction := instruction; argument_count := argument_count + 1; @@ -2176,7 +2150,8 @@ begin goto elna_tac_call_finalize end; - instruction := _elna_tac_jal(name, name_length); + instruction := _elna_tac_instruction_create(ElnaTacOperator.jal); + _elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.symbol, name, name_length); if first_instruction = 0 then first_instruction := instruction else @@ -2359,7 +2334,7 @@ begin first_instruction := elna_instruction_list_concatenate(first_instruction, last_instruction) elsif node_kind = NodeKind.field_access_expression then - _elna_tac_enumeration_value(parser_node, operand_type, operand_value, operand_length); + first_instruction := _elna_tac_enumeration_value(parser_node, operand_type, operand_value, operand_length); is_address^ := 0 elsif node_kind = NodeKind.call then first_instruction := _elna_tac_call(parser_node, symbol_table); @@ -2435,10 +2410,14 @@ begin operand_length := 0; instruction := _elna_tac_binary_expression(current_expression, symbol_table, @operand_type, @operand_value, @operand_length); - elna_instruction_list_concatenate(current_instruction, instruction); + if instruction <> 0 then + elna_instruction_list_concatenate(current_instruction, instruction); + 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_load_word(ElnaRtlRegister.t1, ElnaRtlRegister.sp, 76); + elna_instruction_list_concatenate(current_instruction, instruction); + current_instruction := instruction; instruction := _elna_tac_instruction_create(ElnaTacOperator.store_word); _elna_tac_instruction_set_operand(instruction, 1, operand_type, operand_value, operand_length); @@ -2489,8 +2468,7 @@ begin _elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.register, ElnaRtlRegister.a0, 0); _elna_tac_instruction_set_operand(instruction, 2, operand_type, operand_value, operand_length); - elna_instruction_list_concatenate(first_instruction, instruction); - return first_instruction + return elna_instruction_list_concatenate(first_instruction, instruction) end; (** @@ -2626,6 +2604,7 @@ proc _elna_parser_statement(); var token_kind: Word; result : Word; + temporary: Word; begin result := 0; _elna_lexer_read_token(@token_kind); @@ -2640,8 +2619,9 @@ begin result := _elna_parser_label_declaration() elsif token_kind = ElnaLexerKind.identifier then result := _elna_parser_designator(); + temporary := _node_get_kind(result); - if _node_get_kind(result) <> NodeKind.call then + if temporary <> NodeKind.call then result := _elna_parser_assign_statement(result) end end; @@ -3667,59 +3647,61 @@ begin return result end; -proc _elna_tac_type_field(name_pointer: Word, name_length: Word, field_pointer: Word, field_offset: Word); +proc _elna_tac_accessor(name_pointer: Word, name_length: Word, field_pointer: Word, field_offset: Word, result: Word, method: Word); var - first_result: Word; - second_result: Word; + instruction: Word; new_name: Word; + name_target: Word; new_length: Word; field_length: Word; - instruction: Word; - name_target: Word; - next_instruction: Word; begin field_length := field_pointer + 4; field_length := field_length^; new_length := field_length + name_length; new_length := new_length + 5; - first_result := malloc(ElnaInstructionDeclaration_size()); - ElnaInstructionList_set_next(first_result, 0); + result^ := malloc(ElnaInstructionDeclaration_size()); + ElnaInstructionList_set_next(result^, 0); new_name := malloc(new_length); name_target := new_name; memcpy(name_target, name_pointer, name_length); name_target := name_target + name_length; - memcpy(name_target, "_get_", 5); + memcpy(name_target, method, 5); name_target := name_target + 5; memcpy(name_target, field_pointer^, field_length); - ElnaInstructionDeclaration_set_name(first_result, new_name); - ElnaInstructionDeclaration_set_length(first_result, new_length); + ElnaInstructionDeclaration_set_name(result^, new_name); + ElnaInstructionDeclaration_set_length(result^, new_length); - instruction := _elna_tac_add(ElnaRtlRegister.a0, ElnaRtlRegister.a0, ElnaTacOperand.immediate, field_offset); - next_instruction := _elna_tac_load_word(ElnaRtlRegister.a0, ElnaRtlRegister.a0, 0); + instruction := _elna_tac_instruction_create(ElnaTacOperator.add); + + _elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.register, ElnaRtlRegister.a0, 0); + _elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.register, ElnaRtlRegister.a0, 0); + _elna_tac_instruction_set_operand(instruction, 3, ElnaTacOperand.immediate, field_offset, 0); + + return instruction +end; + +proc _elna_tac_type_field(name_pointer: Word, name_length: Word, field_pointer: Word, field_offset: Word); +var + first_result: Word; + second_result: Word; + instruction: Word; + next_instruction: Word; +begin + instruction := _elna_tac_accessor(name_pointer, name_length, field_pointer, field_offset, @first_result, "_get_"); + next_instruction := _elna_tac_instruction_create(ElnaTacOperator.load_word); + _elna_tac_instruction_set_operand(next_instruction, 1, ElnaTacOperand.register, ElnaRtlRegister.a0, 0); + _elna_tac_instruction_set_operand(next_instruction, 2, ElnaTacOperand.offset, ElnaRtlRegister.a0, 0); elna_instruction_list_concatenate(instruction, next_instruction); ElnaInstructionDeclaration_set_body(first_result, instruction); - second_result := malloc(ElnaInstructionDeclaration_size()); - ElnaInstructionList_set_next(second_result, 0); - - new_name := malloc(new_length); - - name_target := new_name; - memcpy(name_target, name_pointer, name_length); - name_target := name_target + name_length; - memcpy(name_target, "_set_", 5); - name_target := name_target + 5; - memcpy(name_target, field_pointer^, field_length); - - ElnaInstructionDeclaration_set_name(second_result, new_name); - ElnaInstructionDeclaration_set_length(second_result, new_length); - - instruction := _elna_tac_add(ElnaRtlRegister.a0, ElnaRtlRegister.a0, ElnaTacOperand.immediate, field_offset); - next_instruction := _elna_tac_store_word(ElnaRtlRegister.a1, ElnaRtlRegister.a0, 0); + instruction := _elna_tac_accessor(name_pointer, name_length, field_pointer, field_offset, @second_result, "_set_"); + next_instruction := _elna_tac_instruction_create(ElnaTacOperator.store_word); + _elna_tac_instruction_set_operand(next_instruction, 1, ElnaTacOperand.register, ElnaRtlRegister.a1, 0); + _elna_tac_instruction_set_operand(next_instruction, 2, ElnaTacOperand.offset, ElnaRtlRegister.a0, 0); elna_instruction_list_concatenate(instruction, next_instruction); ElnaInstructionDeclaration_set_body(second_result, instruction);