From 09d79159d2fb83085d436759933507cbfb76f61f Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Tue, 9 Dec 2025 17:16:31 +0100 Subject: [PATCH] Assign stack offset to local variables in a later pass --- boot/stage17/cl.elna | 755 +++++++++++++++++++++++-------------------- 1 file changed, 405 insertions(+), 350 deletions(-) diff --git a/boot/stage17/cl.elna b/boot/stage17/cl.elna index e10be76..0136ce2 100644 --- a/boot/stage17/cl.elna +++ b/boot/stage17/cl.elna @@ -458,8 +458,8 @@ type allocate_stack, ret ); - ElnaTacOperand = (temporary, immediate, symbol, stack); - ElnaRtlOperand = (register, immediate, symbol, offset); + ElnaTacOperand = (temporary, immediate, symbol, stack, pseudo); + ElnaRtlOperand = (register, immediate, symbol, offset, pseudo); ElnaRtlRegister = ( zero, ra, @@ -499,6 +499,7 @@ var symbol_table_global: Array; compiler_strings: Array; classification: Array; + variable_map: Array; source_code: Word; compiler_strings_position: Word; @@ -518,22 +519,22 @@ var *) proc _string_length(string: Word); var - counter: Word; - current_byte: Word; + counter1: Word; + current_byte1: Word; begin (* Reset the counter. *) - counter := 0; + counter1 := 0; .string_length_loop; string := string + 1; - current_byte := _load_byte(string); - if current_byte <> '"' then - counter := counter + 1; + current_byte1 := _load_byte(string); + if current_byte1 <> '"' then + counter1 := counter1 + 1; goto string_length_loop end; - return counter + return counter1 end; (** @@ -546,40 +547,27 @@ end; *) proc _add_string(string: Word); var - contents: Word; - result: Word; - current_byte: Word; + contents1: Word; + result1: Word; + current_byte1: Word; begin - contents := string + 1; - result := compiler_strings_length; + contents1 := string + 1; + result1 := compiler_strings_length; .add_string_loop; - current_byte := _load_byte(contents); - if current_byte <> '"' then - _store_byte(current_byte, compiler_strings_position); + current_byte1 := _load_byte(contents1); + if current_byte1 <> '"' then + _store_byte(current_byte1, compiler_strings_position); compiler_strings_position := compiler_strings_position + 1; - contents := contents + 1; + contents1 := contents1 + 1; - if current_byte <> '\\' then + if current_byte1 <> '\\' then compiler_strings_length := compiler_strings_length + 1 end; goto add_string_loop end; - return result -end; - -(** - * Reads standard input into a buffer. - * - * Parameters: - * buffer - Buffer pointer. - * size - Buffer size. - * - * Returns the amount of bytes written in a0. - *) -proc _read_file(buffer: Word, size: Word); - return _syscall(0, buffer, size, 0, 0, 0, 63) + return result1 end; (** @@ -591,53 +579,7 @@ end; *) proc _write_s(buffer: Word, size: Word); begin - _syscall(1, buffer, size, 0, 0, 0, 64) -end; - -(** - * Writes a number to a string buffer. - * - * Parameters: - * number - Whole number. - * output_buffer - Buffer pointer. - * - * Sets a0 to the length of the written number. - *) -proc _print_i(number: Word, output_buffer: Word); -var - local_buffer: Word; - is_negative: Word; - current_character: Word; - result: Word; -begin - local_buffer := @result + 11; - - if number >= 0 then - is_negative := 0 - else - number = -number; - is_negative := 1 - end; - - .print_i_digit10; - current_character := number % 10; - _store_byte(current_character + '0', local_buffer); - - number := number / 10; - local_buffer := local_buffer - 1; - - if number <> 0 then - goto print_i_digit10 - end; - if is_negative = 1 then - _store_byte('-', local_buffer); - local_buffer := local_buffer - 1 - end; - result := @result + 11; - result := result - local_buffer; - memcpy(output_buffer, local_buffer + 1, result); - - return result + write(1, buffer, size) end; (** @@ -647,12 +589,9 @@ end; * number - Whole number. *) proc _write_i(number: Word); -var - local_buffer: Word; - length: Word; begin - length := _print_i(number, @local_buffer); - _write_s(@local_buffer, length) + printf("%i\0", number); + fflush(nil) end; (** @@ -663,7 +602,7 @@ end; *) proc _write_c(character: Word); begin - _write_s(@character, 1) + write(1, @character, 1) end; (** @@ -673,19 +612,9 @@ end; * string - String. *) proc _write_z(string: Word); -var - next_byte: Word; begin - (* Check for 0 character. *) - next_byte := _load_byte(string); - - if next_byte <> 0 then - (* Print a character. *) - _write_c(next_byte); - - (* Advance the input string by one byte. *) - _write_z(string + 1) - end + printf("%s\0", string); + fflush(nil) end; (** @@ -698,11 +627,11 @@ end; *) proc _is_alpha(character: Word); var - is_underscore: Word; + is_underscore1: Word; begin - is_underscore := character = '_'; + is_underscore1 := character = '_'; - return isalpha(character) or is_underscore + return isalpha(character) or is_underscore1 end; proc _is_alnum(character: Word); @@ -727,13 +656,13 @@ end; proc elna_instruction_list_concatenate(this: Word, value: Word); var - start: Word; + start1: Word; begin if this = 0 then - start := value; + start1 := value; goto elna_instruction_list_concatenate_end else - start := this + start1 := this end; .elna_instruction_list_concatenate_loop; if value <> 0 then @@ -744,7 +673,7 @@ begin end; this^ := value; .elna_instruction_list_concatenate_end; - return start + return start1 end; proc _elna_tac_instruction_get_operand_type(this: Word, n: Word); @@ -795,26 +724,26 @@ end; proc _elna_tac_instruction_create(kind: Word); var - result: Word; + result1: Word; begin - result := malloc(_elna_tac_instruction_size()); + result1 := malloc(_elna_tac_instruction_size()); - _elna_tac_instruction_set_kind(result, kind); - elna_instruction_list_concatenate(result, 0); + _elna_tac_instruction_set_kind(result1, kind); + elna_instruction_list_concatenate(result1, 0); - return result + return result1 end; proc elna_rtl_instruction_create(kind: Word); var - result: ^ElnaInstructionList; + result1: ^ElnaInstructionList; begin - result := malloc(elna_rtl_instruction_size()); + result1 := malloc(elna_rtl_instruction_size()); - elna_rtl_instruction_set_kind(result, kind); - result^.next := nil; + elna_rtl_instruction_set_kind(result1, kind); + result1^.next := nil; - return result + return result1 end; proc elna_rtl_instruction_size(); @@ -881,41 +810,45 @@ end; proc elna_rtl_load_operand_value(tac_instruction: Word, operand_number: Word, into: Word); var - result: ^ElnaInstructionList; - operand_value: Word; - operand_length: Word; - operand_type: Word; + result1: ^ElnaInstructionList; + operand_value1: Word; + operand_length1: Word; + operand_type1: Word; next_instruction: Word; begin - 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); + operand_value1 := _elna_tac_instruction_get_operand_value(tac_instruction, operand_number); + operand_length1 := _elna_tac_instruction_get_operand_length(tac_instruction, operand_number); + operand_type1 := _elna_tac_instruction_get_operand_type(tac_instruction, operand_number); - if operand_type = ElnaTacOperand.immediate then - result := elna_rtl_instruction_create(ElnaRtlOperator.li); - elna_rtl_instruction_set_operand(result, 1, ElnaRtlOperand.register, into, 0); - elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.immediate, operand_value, operand_length) - elsif operand_type = ElnaTacOperand.stack then - result := elna_rtl_instruction_create(ElnaRtlOperator.lw); - elna_rtl_instruction_set_operand(result, 1, ElnaRtlOperand.register, into, 0); - elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.offset, ElnaRtlRegister.sp, operand_value) - elsif operand_type = ElnaTacOperand.symbol then - result := elna_rtl_instruction_create(ElnaRtlOperator.la); - elna_rtl_instruction_set_operand(result, 1, ElnaRtlOperand.register, into, 0); - elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.symbol, operand_value, operand_length); + if operand_type1 = ElnaTacOperand.immediate then + result1 := elna_rtl_instruction_create(ElnaRtlOperator.li); + elna_rtl_instruction_set_operand(result1, 1, ElnaRtlOperand.register, into, 0); + elna_rtl_instruction_set_operand(result1, 2, ElnaRtlOperand.immediate, operand_value1, operand_length1) + elsif operand_type1 = ElnaTacOperand.stack then + result1 := elna_rtl_instruction_create(ElnaRtlOperator.lw); + elna_rtl_instruction_set_operand(result1, 1, ElnaRtlOperand.register, into, 0); + elna_rtl_instruction_set_operand(result1, 2, ElnaRtlOperand.offset, ElnaRtlRegister.sp, operand_value1) + elsif operand_type1 = ElnaTacOperand.symbol then + result1 := elna_rtl_instruction_create(ElnaRtlOperator.la); + elna_rtl_instruction_set_operand(result1, 1, ElnaRtlOperand.register, into, 0); + elna_rtl_instruction_set_operand(result1, 2, ElnaRtlOperand.symbol, operand_value1, operand_length1); next_instruction := elna_rtl_instruction_create(ElnaRtlOperator.lw); elna_rtl_instruction_set_operand(next_instruction, 1, ElnaRtlOperand.register, into, 0); elna_rtl_instruction_set_operand(next_instruction, 2, ElnaRtlOperand.offset, into, 0); - result^.next := next_instruction - elsif operand_type = ElnaTacOperand.temporary then - 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) + result1^.next := next_instruction + elsif operand_type1 = ElnaTacOperand.temporary then + result1 := elna_rtl_instruction_create(ElnaRtlOperator.move); + elna_rtl_instruction_set_operand(result1, 1, ElnaRtlOperand.register, into, 0); + elna_rtl_instruction_set_operand(result1, 2, ElnaRtlOperand.register, operand_value1, 0) + elsif operand_type1 = ElnaTacOperand.pseudo then + result1 := elna_rtl_instruction_create(ElnaRtlOperator.move); + elna_rtl_instruction_set_operand(result1, 1, ElnaRtlOperand.register, into, 0); + elna_rtl_instruction_set_operand(result1, 2, ElnaRtlOperand.pseudo, operand_value1, operand_length1) end; - return result + return result1 end; proc elna_rtl_load_operand_address(tac_instruction: Word, operand_number: Word, into: Word); @@ -937,6 +870,10 @@ begin result := elna_rtl_instruction_create(ElnaRtlOperator.la); elna_rtl_instruction_set_operand(result, 1, ElnaRtlOperand.register, into, 0); elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.symbol, operand_value, operand_length) + elsif operand_type = ElnaTacOperand.pseudo then + result := elna_rtl_instruction_create(ElnaRtlOperator.la); + elna_rtl_instruction_set_operand(result, 1, ElnaRtlOperand.register, into, 0); + elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.pseudo, operand_value, operand_length) end; return result @@ -1053,23 +990,23 @@ end; proc elna_rtl_instruction(tac_instruction: Word, next_instruction: ^^ElnaInstructionList); var result: ^ElnaInstructionList; - instruction_size: Word; instruction_kind: Word; operand_type: Word; operand_value: Word; + operand_length: Word; operands: ^ElnaInstructionList; intermediate_instruction: ^ElnaInstructionList; begin - instruction_size := elna_rtl_instruction_size(); - result := malloc(instruction_size); + result := malloc(elna_rtl_instruction_size()); instruction_kind := _elna_tac_instruction_get_kind(tac_instruction); next_instruction^ := nil; if instruction_kind = ElnaTacOperator.get_address then operand_type := _elna_tac_instruction_get_operand_type(tac_instruction, 2); + operand_value := _elna_tac_instruction_get_operand_value(tac_instruction, 2); + operand_length := _elna_tac_instruction_get_operand_length(tac_instruction, 2); if operand_type = ElnaTacOperand.stack then - 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); @@ -1085,6 +1022,11 @@ begin elna_rtl_copy_operand(tac_instruction, 1, result); elna_rtl_copy_operand(tac_instruction, 2, result) + elsif operand_type = ElnaTacOperand.pseudo then + result := elna_rtl_instruction_create(ElnaRtlOperator.la); + + elna_rtl_copy_operand(tac_instruction, 1, result); + elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.pseudo, operand_value, operand_length) end elsif instruction_kind = ElnaTacOperator.add then result := elna_rtl_binary_arithmetic(tac_instruction, next_instruction, ElnaRtlOperator.add) @@ -1108,6 +1050,13 @@ begin elna_rtl_copy_operand(tac_instruction, 1, result); operand_value := _elna_tac_instruction_get_operand_value(tac_instruction, 2); elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.offset, operand_value, 0) + elsif operand_type = ElnaTacOperand.pseudo then + operand_value := _elna_tac_instruction_get_operand_value(tac_instruction, 2); + operand_length := _elna_tac_instruction_get_operand_length(tac_instruction, 2); + + result := elna_rtl_instruction_create(ElnaRtlOperator.lw); + elna_rtl_copy_operand(tac_instruction, 1, result); + elna_rtl_instruction_set_operand(result, 2, ElnaRtlOperand.pseudo, operand_value, operand_length) end elsif instruction_kind = ElnaTacOperator.store then operands := elna_rtl_load_operand_value(tac_instruction, 1, ElnaRtlRegister.t0); @@ -1118,12 +1067,14 @@ begin elna_rtl_instruction_set_operand(next_instruction^, 1, ElnaRtlOperand.register, ElnaRtlRegister.t0, 0); operand_type := _elna_tac_instruction_get_operand_type(tac_instruction, 2); + operand_value := _elna_tac_instruction_get_operand_value(tac_instruction, 2); + operand_length := _elna_tac_instruction_get_operand_length(tac_instruction, 2); if operand_type = ElnaTacOperand.stack then - operand_value := _elna_tac_instruction_get_operand_value(tac_instruction, 2); elna_rtl_instruction_set_operand(next_instruction^, 2, ElnaRtlOperand.offset, ElnaRtlRegister.sp, operand_value) elsif operand_type = ElnaTacOperand.temporary then - operand_value := _elna_tac_instruction_get_operand_value(tac_instruction, 2); elna_rtl_instruction_set_operand(next_instruction^, 2, ElnaRtlOperand.offset, operand_value, 0) + elsif operand_type = ElnaTacOperand.pseudo then + elna_rtl_instruction_set_operand(next_instruction^, 2, ElnaRtlOperand.pseudo, operand_value, operand_length) end; if operands = 0 then result^.next := next_instruction^ @@ -1224,6 +1175,7 @@ begin elsif instruction_kind = ElnaTacOperator.copy then operand_type := _elna_tac_instruction_get_operand_type(tac_instruction, 1); operand_value := _elna_tac_instruction_get_operand_value(tac_instruction, 1); + operand_length := _elna_tac_instruction_get_operand_length(tac_instruction, 1); if operand_type = ElnaTacOperand.temporary then result := elna_rtl_load_operand_value(tac_instruction, 2, operand_value); @@ -1237,6 +1189,20 @@ begin _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 = nil then + result^.next := next_instruction^ + else + operands^.next := next_instruction^ + end + elsif operand_type = ElnaTacOperand.pseudo then + operands := elna_rtl_load_operand_value(tac_instruction, 2, ElnaRtlRegister.t4); + result := operands; + operands := result^.next; + + next_instruction^ := elna_rtl_instruction_create(ElnaRtlOperator.move); + _elna_tac_instruction_set_operand(next_instruction^, 1, ElnaRtlOperand.pseudo, operand_value, operand_length); + _elna_tac_instruction_set_operand(next_instruction^, 2, ElnaRtlOperand.register, ElnaRtlRegister.t4, 0); + if operands = nil then result^.next := next_instruction^ else @@ -1264,95 +1230,101 @@ end; proc _elna_tac_label(counter: Word, length: Word); var - result: Word; + result1: Word; begin - result := _elna_tac_instruction_create(ElnaTacOperator.label); + result1 := _elna_tac_instruction_create(ElnaTacOperator.label); - _elna_tac_instruction_set_operand(result, 1, ElnaTacOperand.symbol, counter, length); + _elna_tac_instruction_set_operand(result1, 1, ElnaTacOperand.symbol, counter, length); - return result + return result1 end; proc _elna_writer_instruction_name(instruction_kind: Word); var - argument_count: Word; + argument_count1: Word; begin if instruction_kind = ElnaRtlOperator.li then - argument_count := 2; + argument_count1 := 2; _write_s("\tli", 3) elsif instruction_kind = ElnaRtlOperator.la then - argument_count := 2; + argument_count1 := 2; _write_s("\tla", 3) elsif instruction_kind = ElnaRtlOperator.add then - argument_count := 3; + argument_count1 := 3; _write_s("\tadd", 4) elsif instruction_kind = ElnaRtlOperator.addi then - argument_count := 3; + argument_count1 := 3; _write_s("\taddi", 5) elsif instruction_kind = ElnaRtlOperator.lw then - argument_count := 2; + argument_count1 := 2; _write_s("\tlw", 3) elsif instruction_kind = ElnaRtlOperator.sw then - argument_count := 2; + argument_count1 := 2; _write_s("\tsw", 3) elsif instruction_kind = ElnaRtlOperator.jal then - argument_count := 1; + argument_count1 := 1; _write_s("\tcall", 5) elsif instruction_kind = ElnaRtlOperator.move then - argument_count := 2; + argument_count1 := 2; _write_s("\tmv", 3) elsif instruction_kind = ElnaRtlOperator.sub then - argument_count := 3; + argument_count1 := 3; _write_s("\tsub", 4) elsif instruction_kind = ElnaRtlOperator.mul then - argument_count := 3; + argument_count1 := 3; _write_s("\tmul", 4) elsif instruction_kind = ElnaRtlOperator.div then - argument_count := 3; + argument_count1 := 3; _write_s("\tdiv", 4) elsif instruction_kind = ElnaRtlOperator.rem then - argument_count := 3; + argument_count1 := 3; _write_s("\trem", 4) elsif instruction_kind = ElnaRtlOperator._xor then - argument_count := 3; + argument_count1 := 3; _write_s("\txor", 4) elsif instruction_kind = ElnaRtlOperator.xori then - argument_count := 3; + argument_count1 := 3; _write_s("\txori", 5) elsif instruction_kind = ElnaRtlOperator._or then - argument_count := 3; + argument_count1 := 3; _write_s("\tor", 3) elsif instruction_kind = ElnaRtlOperator.and then - argument_count := 3; + argument_count1 := 3; _write_s("\tand", 4) elsif instruction_kind = ElnaRtlOperator.seqz then - argument_count := 2; + argument_count1 := 2; _write_s("\tseqz", 5) elsif instruction_kind = ElnaRtlOperator.snez then - argument_count := 2; + argument_count1 := 2; _write_s("\tsnez", 5) elsif instruction_kind = ElnaRtlOperator.slt then - argument_count := 3; + argument_count1 := 3; _write_s("\tslt", 4) elsif instruction_kind = ElnaRtlOperator.neg then - argument_count := 2; + argument_count1 := 2; _write_s("\tneg", 4) elsif instruction_kind = ElnaRtlOperator.not then - argument_count := 2; + argument_count1 := 2; _write_s("\tnot", 4) elsif instruction_kind = ElnaRtlOperator.j then - argument_count := 1; + argument_count1 := 1; _write_s("\tj", 2) elsif instruction_kind = ElnaRtlOperator.beqz then - argument_count := 2; + argument_count1 := 2; _write_s("\tbeqz", 5) elsif instruction_kind = ElnaRtlOperator.bnez then - argument_count := 2; + argument_count1 := 2; _write_s("\tbnez", 5) - else (* ElnaRtlOperator.allocate_stack or ElnaRtlOperator.ret *) - argument_count := 0 + elsif instruction_kind = ElnaRtlOperator.allocate_stack then + (* Write the prologue. *) + _write_z("\taddi sp, sp, -208\n\tsw ra, 204(sp)\n\tsw s0, 200(sp)\n\taddi s0, sp, 208\n\0"); + argument_count1 := 0 + elsif instruction_kind = ElnaRtlOperator.ret then + (* Write the epilogue. *) + _write_z("\tlw ra, 204(sp)\n\tlw s0, 200(sp)\n\taddi sp, sp, 208\n\0"); + argument_count1 := 0 end; - return argument_count + return argument_count1 end; proc _elna_writer_register(register: Word); @@ -1392,10 +1364,85 @@ begin end end; -proc _elna_writer_instruction(instruction: Word); +proc elna_alloc_variable(operand_value: Word, operand_length: Word); +var + pseudo_symbol1: Word; +begin + pseudo_symbol1 := _symbol_table_lookup(@variable_map, operand_value, operand_length); + if pseudo_symbol1 = nil then + _symbol_table_enter(@variable_map, operand_value, operand_length, temporary_variable_counter); + pseudo_symbol1 := temporary_variable_counter; + temporary_variable_counter := temporary_variable_counter + 4 + end; + return pseudo_symbol1 +end; + +proc elna_alloc_instruction(instruction: Word); var instruction_kind: Word; - argument_count: Word; + operand_type: Word; + operand_value: Word; + operand_length: Word; + pseudo_symbol1: Word; +begin + instruction_kind := elna_rtl_instruction_get_kind(instruction); + + if instruction_kind = ElnaRtlOperator.move then + operand_type := elna_rtl_instruction_get_operand_type(instruction, 1); + operand_value := elna_rtl_instruction_get_operand_value(instruction, 1); + operand_length := elna_rtl_instruction_get_operand_length(instruction, 1); + + if operand_type = ElnaRtlOperand.pseudo then + pseudo_symbol1 := elna_alloc_variable(operand_value, operand_length); + elna_rtl_instruction_set_kind(instruction, ElnaRtlOperator.sw); + + operand_type := elna_rtl_instruction_get_operand_type(instruction, 2); + operand_value := elna_rtl_instruction_get_operand_value(instruction, 2); + operand_length := elna_rtl_instruction_get_operand_length(instruction, 2); + + elna_rtl_instruction_set_operand(instruction, 1, operand_type, operand_value, operand_length); + elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlOperand.offset, ElnaRtlRegister.sp, pseudo_symbol1); + + goto elna_alloc_instruction_end + end; + + operand_type := elna_rtl_instruction_get_operand_type(instruction, 2); + operand_value := elna_rtl_instruction_get_operand_value(instruction, 2); + operand_length := elna_rtl_instruction_get_operand_length(instruction, 2); + + if operand_type = ElnaRtlOperand.pseudo then + pseudo_symbol1 := elna_alloc_variable(operand_value, operand_length); + elna_rtl_instruction_set_kind(instruction, ElnaRtlOperator.lw); + elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlOperand.offset, ElnaRtlRegister.sp, pseudo_symbol1); + + goto elna_alloc_instruction_end + end + elsif instruction_kind = ElnaRtlOperator.la then + operand_type := elna_rtl_instruction_get_operand_type(instruction, 2); + operand_value := elna_rtl_instruction_get_operand_value(instruction, 2); + operand_length := elna_rtl_instruction_get_operand_length(instruction, 2); + + if operand_type = ElnaRtlOperand.pseudo then + (* Debug. Error stream output. + printf("# %i %.*s\n\0", operand_length, operand_length, operand_value); + fflush(nil); *) + + pseudo_symbol1 := elna_alloc_variable(operand_value, operand_length); + elna_rtl_instruction_set_kind(instruction, ElnaRtlOperator.addi); + + elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlOperand.register, ElnaRtlRegister.sp, 0); + elna_rtl_instruction_set_operand(instruction, 3, ElnaRtlOperand.immediate, pseudo_symbol1, 0); + + goto elna_alloc_instruction_end + end + end; + .elna_alloc_instruction_end; +end; + +proc _elna_writer_instruction(instruction: Word); +var + argument_count1: Word; + instruction_kind: Word; current_argument: Word; operand_value: Word; operand_length: Word; @@ -1403,22 +1450,22 @@ begin instruction_kind := elna_rtl_instruction_get_kind(instruction); if instruction_kind = ElnaRtlOperator.label then - argument_count := 0; + argument_count1 := 0; operand_value := elna_rtl_instruction_get_operand_value(instruction, 1); operand_length := elna_rtl_instruction_get_operand_length(instruction, 1); _write_label(operand_value, operand_length); _write_c(':') else - argument_count := _elna_writer_instruction_name(instruction_kind) + argument_count1 := _elna_writer_instruction_name(instruction_kind) end; current_argument := 1; .elna_writer_instruction_loop; - if current_argument <= argument_count then + if current_argument <= argument_count1 then _elna_writer_operand(instruction, current_argument); current_argument := current_argument + 1 end; - if current_argument <= argument_count then + if current_argument <= argument_count1 then _write_c(','); goto elna_writer_instruction_loop end; @@ -1428,10 +1475,10 @@ end; proc elna_rtl_instructions(instruction: ^ElnaInstructionList); var + last_copy1: ^ElnaInstructionList; current_copy: ^ElnaInstructionList; next_copy: ^ElnaInstructionList; first_copy: ^ElnaInstructionList; - last_copy: ^ElnaInstructionList; begin if instruction <> nil then first_copy := elna_rtl_instruction(instruction, @current_copy); @@ -1443,27 +1490,61 @@ begin .elna_rtl_instructions_start; if instruction <> nil then - next_copy := elna_rtl_instruction(instruction, @last_copy); + next_copy := elna_rtl_instruction(instruction, @last_copy1); instruction := instruction^.next; current_copy^.next := next_copy; - current_copy := last_copy; + current_copy := last_copy1; goto elna_rtl_instructions_start end; return first_copy end; +proc elna_alloc_instructions(instruction: ^ElnaInstructionList); +begin + .elna_alloc_instructions_start; + + if instruction <> nil then + elna_alloc_instruction(instruction); + instruction := instruction^.next; + goto elna_alloc_instructions_start + end +end; + proc _elna_writer_instructions(instruction: ^ElnaInstructionList); begin .elna_writer_instructions_start; - if instruction <> 0 then + if instruction <> nil then _elna_writer_instruction(instruction); instruction := instruction^.next; goto elna_writer_instructions_start end end; +proc elna_alloc_procedure(rtl_declaration: ^ElnaInstructionDeclaration); +var + stack_instruction: ^ElnaInstructionList; +begin + .elna_alloc_procedure_loop; + temporary_variable_counter := 136; + variable_map := 0; + + elna_alloc_instructions(rtl_declaration^.body); + if rtl_declaration^.stack then + stack_instruction := elna_rtl_instruction_create(ElnaRtlOperator.allocate_stack); + stack_instruction^.next := rtl_declaration^.body; + rtl_declaration^.body := stack_instruction; + stack_instruction := elna_rtl_instruction_create(ElnaRtlOperator.ret); + elna_instruction_list_concatenate(rtl_declaration^.body, stack_instruction) + end; + + rtl_declaration := rtl_declaration^.next; + if rtl_declaration <> nil then + goto elna_alloc_procedure_loop + end +end; + proc _elna_writer_procedure(procedure: ^ElnaInstructionDeclaration); begin .elna_writer_procedure_loop; @@ -1478,19 +1559,11 @@ begin _write_s(procedure^.name, procedure^.length); _write_z(":\n\0"); - (* Write the prologue. *) - if procedure^.stack then - _write_z("\taddi sp, sp, -144\n\tsw ra, 140(sp)\n\tsw s0, 136(sp)\n\taddi s0, sp, 144\n\0") - end; _elna_writer_instructions(procedure^.body); - (* Write the epilogue. *) - if procedure^.stack then - _write_z("\tlw ra, 140(sp)\n\tlw s0, 136(sp)\n\taddi sp, sp, 144\n\0") - end; _write_z("\tret\n\0"); procedure := procedure^.next; - if procedure <> 0 then + if procedure <> nil then goto elna_writer_procedure_loop end end; @@ -1527,6 +1600,11 @@ begin return elna_instruction_module_create(data_part, code_part) end; +proc elna_alloc_module(pair: ^ElnaInstructionModule); +begin + elna_alloc_procedure(pair^.code) +end; + proc _elna_writer_module(pair: ^ElnaInstructionModule); var compiler_strings_copy: Word; @@ -1539,7 +1617,6 @@ begin _elna_writer_variable(pair^.data); _write_z(".section .text\n\n\0"); - _write_z(".type _syscall, @function\n_syscall:\n\tmv a7, a6\n\tecall\n\tret\n\n\0"); _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"); @@ -1697,10 +1774,17 @@ var lookup_result: ^_parameter_info; begin lookup_result := _symbol_table_lookup(symbol_table, variable_expression^.name, variable_expression^.length); + if lookup_result <> nil then - operand_type^ := ElnaTacOperand.stack; - operand_value^ := lookup_result^.offset; - operand_length^ := 0 + if lookup_result^.kind = InfoKind.temporary_info then + operand_type^ := ElnaTacOperand.pseudo; + operand_value^ := variable_expression^.name; + operand_length^ := variable_expression^.length + else + operand_type^ := ElnaTacOperand.stack; + operand_value^ := lookup_result^.offset; + operand_length^ := 0 + end else operand_type^ := ElnaTacOperand.symbol; operand_value^ := variable_expression^.name; @@ -1796,20 +1880,20 @@ end; proc elna_parser_designator(); var simple_expression: Word; - token_kind: Word; + token_kind1: Word; begin simple_expression := elna_parser_simple_expression(); .elna_parser_designator_loop; - _elna_lexer_read_token(@token_kind); + _elna_lexer_read_token(@token_kind1); - if token_kind = ElnaLexerKind.hat then + if token_kind1 = ElnaLexerKind.hat then simple_expression := elna_parser_dereference_expression(simple_expression); goto elna_parser_designator_loop - elsif token_kind = ElnaLexerKind.dot then + elsif token_kind1 = ElnaLexerKind.dot then simple_expression := elna_parser_field_access_expression(simple_expression); goto elna_parser_designator_loop - elsif token_kind = ElnaLexerKind.left_paren then + elsif token_kind1 = ElnaLexerKind.left_paren then simple_expression := elna_parser_call(simple_expression); goto elna_parser_designator_loop end; @@ -2015,8 +2099,6 @@ end; proc _elna_tac_binary_expression(parser_node: ^ElnaTreeBinaryExpression, symbol_table: Word, operand_type: Word, operand_value: Word, operand_length: Word); var - token_kind: Word; - operand_node: Word; first_instruction: Word; instruction: Word; current_instruction: Word; @@ -2027,17 +2109,14 @@ begin if parser_node^.kind <> ElnaTreeKind.binary_expression then first_instruction := _elna_tac_unary_expression(parser_node, symbol_table, operand_type, operand_value, operand_length) else - token_kind := parser_node^.operator; - - operand_node := parser_node^.lhs; lhs_type := 0; lhs_value := 0; lhs_length := 0; - first_instruction := _elna_tac_unary_expression(operand_node, symbol_table, @lhs_type, @lhs_value, @lhs_length); + first_instruction := _elna_tac_unary_expression(parser_node^.lhs, symbol_table, @lhs_type, @lhs_value, @lhs_length); (* Save the value of the left expression on the stack. *) instruction := _elna_tac_instruction_create(ElnaTacOperator.copy); - _elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.stack, 72, 0); + _elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.pseudo, "$lhs", 4); _elna_tac_instruction_set_operand(instruction, 2, lhs_type, lhs_value, lhs_length); if first_instruction = 0 then @@ -2047,53 +2126,52 @@ begin end; current_instruction := instruction; - operand_node := parser_node^.rhs; lhs_type := 0; lhs_value := 0; lhs_length := 0; - instruction := _elna_tac_unary_expression(operand_node, symbol_table, @lhs_type, @lhs_value, @lhs_length); + instruction := _elna_tac_unary_expression(parser_node^.rhs, symbol_table, @lhs_type, @lhs_value, @lhs_length); current_instruction := elna_instruction_list_concatenate(current_instruction, instruction); (* Load the left expression from the stack; *) instruction := _elna_tac_instruction_create(ElnaTacOperator.copy); _elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.temporary, 7, 0); - _elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.stack, 72, 0); + _elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.pseudo, "$lhs", 4); elna_instruction_list_concatenate(current_instruction, instruction); current_instruction := instruction; - if token_kind = ElnaLexerKind.plus then + if parser_node^.operator = ElnaLexerKind.plus then instruction := _elna_tac_instruction_create(ElnaTacOperator.add) - elsif token_kind = ElnaLexerKind.minus then + elsif parser_node^.operator = ElnaLexerKind.minus then instruction := _elna_tac_instruction_create(ElnaTacOperator.subtract) - elsif token_kind = ElnaLexerKind.multiplication then + elsif parser_node^.operator = ElnaLexerKind.multiplication then instruction := _elna_tac_instruction_create(ElnaTacOperator.multiply) - elsif token_kind = ElnaLexerKind.and then + elsif parser_node^.operator = ElnaLexerKind.and then instruction := _elna_tac_instruction_create(ElnaTacOperator.and) - elsif token_kind = ElnaLexerKind._or then + elsif parser_node^.operator = ElnaLexerKind._or then instruction := _elna_tac_instruction_create(ElnaTacOperator._or) - elsif token_kind = ElnaLexerKind._xor then + elsif parser_node^.operator = ElnaLexerKind._xor then instruction := _elna_tac_instruction_create(ElnaTacOperator._xor) - elsif token_kind = ElnaLexerKind.equals then + elsif parser_node^.operator = ElnaLexerKind.equals then instruction := _elna_tac_instruction_create(ElnaTacOperator.equal) - elsif token_kind = ElnaLexerKind.remainder then + elsif parser_node^.operator = ElnaLexerKind.remainder then instruction := _elna_tac_instruction_create(ElnaTacOperator.remainder) - elsif token_kind = ElnaLexerKind.division then + elsif parser_node^.operator = ElnaLexerKind.division then instruction := _elna_tac_instruction_create(ElnaTacOperator.divide) - elsif token_kind = ElnaLexerKind.less_than then + elsif parser_node^.operator = ElnaLexerKind.less_than then instruction := _elna_tac_instruction_create(ElnaTacOperator.less_than) - elsif token_kind = ElnaLexerKind.greater_than then + elsif parser_node^.operator = ElnaLexerKind.greater_than then instruction := _elna_tac_instruction_create(ElnaTacOperator.greater_than) - elsif token_kind = ElnaLexerKind.less_equal then + elsif parser_node^.operator = ElnaLexerKind.less_equal then instruction := _elna_tac_instruction_create(ElnaTacOperator.less_or_equal) - elsif token_kind = ElnaLexerKind.greater_equal then + elsif parser_node^.operator = ElnaLexerKind.greater_equal then instruction := _elna_tac_instruction_create(ElnaTacOperator.greater_or_equal) - elsif token_kind = ElnaLexerKind.not_equal then + elsif parser_node^.operator = ElnaLexerKind.not_equal then instruction := _elna_tac_instruction_create(ElnaTacOperator.not_equal) end; _elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.temporary, 6, 0); - _elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.stack, 72, 0); + _elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.pseudo, "$lhs", 4); _elna_tac_instruction_set_operand(instruction, 3, lhs_type, lhs_value, lhs_length); elna_instruction_list_concatenate(current_instruction, instruction); @@ -2181,9 +2259,9 @@ end; proc _elna_tac_call(parsed_call: Word, symbol_table: Word); var + argument_count1: Word; name_length: Word; name: Word; - argument_count: Word; stack_offset: Word; parsed_expression: ^ElnaTreeVariableExpression; instruction: Word; @@ -2196,12 +2274,12 @@ begin parsed_expression := _call_get_name(parsed_call); name := parsed_expression^.name; name_length := parsed_expression^.length; - argument_count := 0; + argument_count1 := 0; first_instruction := 0; .elna_tac_call_loop; - parsed_expression := _call_get_argument(parsed_call, argument_count + 1); + parsed_expression := _call_get_argument(parsed_call, argument_count1 + 1); if parsed_expression = 0 then goto elna_tac_call_finalize else @@ -2219,11 +2297,11 @@ begin end; (* Save the argument on the stack. *) - stack_offset := argument_count * 4; + stack_offset := argument_count1 * 4; instruction := _elna_tac_instruction_create(ElnaTacOperator.store); _elna_tac_instruction_set_operand(instruction, 1, operand_type, operand_value, operand_length); - _elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.stack, 132 - stack_offset, 0); + _elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.stack, 56 - stack_offset, 0); if first_instruction = 0 then first_instruction := instruction else @@ -2231,21 +2309,21 @@ begin end; current_instruction := instruction; - argument_count := argument_count + 1; + argument_count1 := argument_count1 + 1; goto elna_tac_call_loop end; .elna_tac_call_finalize; (* Load the argument from the stack. *) - if argument_count <> 0 then + if argument_count1 <> 0 then (* Decrement the argument counter. *) - argument_count := argument_count - 1; - stack_offset := argument_count * 4; + argument_count1 := argument_count1 - 1; + stack_offset := argument_count1 * 4; - (* Calculate the stack offset: 132 - (4 * argument_counter) *) + (* Calculate the stack offset: 56 - (4 * argument_counter) *) instruction := _elna_tac_instruction_create(ElnaTacOperator.copy); - _elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.temporary, 11 + argument_count, 0); - _elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.stack, 132 - stack_offset, 0); + _elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.temporary, 11 + argument_count1, 0); + _elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.stack, 56 - stack_offset, 0); elna_instruction_list_concatenate(current_instruction, instruction); current_instruction := instruction; @@ -2263,43 +2341,38 @@ end; proc elna_parser_goto_statement(); var - token_kind: Word; - label_name: Word; - label_length: Word; - result: ^ElnaTreeGotoStatement; + token_kind1: Word; + result1: ^ElnaTreeGotoStatement; begin _elna_lexer_skip_token(); - _elna_lexer_read_token(@token_kind); + _elna_lexer_read_token(@token_kind1); + + result1 := malloc(ElnaTreeGotoStatement_size()); + result1^.kind := ElnaTreeKind.goto_statement; + result1^.next := nil; + result1^.label := _elna_lexer_global_get_start(); + result1^.length := _elna_lexer_global_get_end() - result1^.label; - label_name := _elna_lexer_global_get_start(); - label_length := _elna_lexer_global_get_end() - label_name; _elna_lexer_skip_token(); - result := malloc(ElnaTreeGotoStatement_size()); - - result^.kind := ElnaTreeKind.goto_statement; - result^.next := nil; - result^.label := label_name; - result^.length := label_length; - - return result + return result1 end; proc _elna_tac_goto_statement(parser_node: ^ElnaTreeGotoStatement); var - label_length: Word; - label_with_dot: Word; - instruction: Word; + label_length1: Word; + label_with_dot1: Word; + instruction1: Word; begin - label_length := parser_node^.length + 1; - label_with_dot := malloc(label_length); + label_length1 := parser_node^.length + 1; + label_with_dot1 := malloc(label_length1); - _store_byte('.', label_with_dot); - memcpy(label_with_dot + 1, parser_node^.label, parser_node^.length); + _store_byte('.', label_with_dot1); + memcpy(label_with_dot1 + 1, parser_node^.label, parser_node^.length); - instruction := _elna_tac_instruction_create(ElnaTacOperator.jump); - _elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.symbol, label_with_dot, label_length); - return instruction + instruction1 := _elna_tac_instruction_create(ElnaTacOperator.jump); + _elna_tac_instruction_set_operand(instruction1, 1, ElnaTacOperand.symbol, label_with_dot1, label_length1); + return instruction1 end; proc elna_parser_label_declaration(); @@ -2375,25 +2448,21 @@ end; proc elna_parser_field_access_expression(aggregate: Word); var token_kind: Word; - name_pointer: Word; - name_length: Word; result: ^ElnaTreeFieldAccessExpression; begin (* Skip dot. Read the enumeration value. *) _elna_lexer_skip_token(); _elna_lexer_read_token(@token_kind); - name_pointer := _elna_lexer_global_get_start(); - name_length := _elna_lexer_global_get_end() - name_pointer; - - _elna_lexer_skip_token(); result := malloc(ElnaTreeFieldAccessExpression_size()); result^.kind := ElnaTreeKind.field_access_expression; - result^.aggregate := aggregate; - result^.field := name_pointer; - result^.length := name_length; result^.type_decoration := nil; + result^.aggregate := aggregate; + result^.field := _elna_lexer_global_get_start(); + result^.length := _elna_lexer_global_get_end() - result^.field; + + _elna_lexer_skip_token(); return result end; @@ -2516,41 +2585,53 @@ begin operand_length := 0; first_instruction := _elna_tac_designator(parser_tree^.assignee, symbol_table, @is_address, @operand_type, @operand_value, @operand_length); - current_instruction := _elna_tac_instruction_create(ElnaTacOperator.get_address); - _elna_tac_instruction_set_operand(current_instruction, 1, ElnaTacOperand.temporary, 6, 0); - _elna_tac_instruction_set_operand(current_instruction, 2, operand_type, operand_value, operand_length); - first_instruction := elna_instruction_list_concatenate(first_instruction, current_instruction); + if operand_type = ElnaTacOperand.pseudo then + current_instruction := _elna_tac_instruction_create(ElnaTacOperator.copy); + _elna_tac_instruction_set_operand(current_instruction, 1, operand_type, operand_value, operand_length); - (* Save the assignee address on the stack. *) - current_instruction := _elna_tac_instruction_create(ElnaTacOperator.store); - _elna_tac_instruction_set_operand(current_instruction, 1, ElnaTacOperand.temporary, 6, 0); - _elna_tac_instruction_set_operand(current_instruction, 2, ElnaTacOperand.stack, 76, 0); - elna_instruction_list_concatenate(first_instruction, current_instruction); + operand_type := 0; + operand_value := 0; + operand_length := 0; + instruction := _elna_tac_binary_expression(parser_tree^.assignment, symbol_table, @operand_type, @operand_value, @operand_length); + _elna_tac_instruction_set_operand(current_instruction, 2, operand_type, operand_value, operand_length); - (* Compile the assignment. *) - operand_type := 0; - operand_value := 0; - operand_length := 0; - instruction := _elna_tac_binary_expression(parser_tree^.assignment, symbol_table, @operand_type, @operand_value, @operand_length); + first_instruction := elna_instruction_list_concatenate(instruction, current_instruction) + else + current_instruction := _elna_tac_instruction_create(ElnaTacOperator.get_address); + _elna_tac_instruction_set_operand(current_instruction, 1, ElnaTacOperand.temporary, 6, 0); + _elna_tac_instruction_set_operand(current_instruction, 2, operand_type, operand_value, operand_length); + first_instruction := elna_instruction_list_concatenate(first_instruction, current_instruction); + + (* Save the assignee address on the stack. *) + current_instruction := _elna_tac_instruction_create(ElnaTacOperator.store); + _elna_tac_instruction_set_operand(current_instruction, 1, ElnaTacOperand.temporary, 6, 0); + _elna_tac_instruction_set_operand(current_instruction, 2, ElnaTacOperand.stack, 0, 0); + elna_instruction_list_concatenate(first_instruction, current_instruction); + + (* Compile the assignment. *) + operand_type := 0; + operand_value := 0; + operand_length := 0; + instruction := _elna_tac_binary_expression(parser_tree^.assignment, symbol_table, @operand_type, @operand_value, @operand_length); + + if instruction <> 0 then + elna_instruction_list_concatenate(current_instruction, instruction); + current_instruction := instruction + end; + + instruction := _elna_tac_instruction_create(ElnaTacOperator.copy); + _elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.temporary, 7, 0); + _elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.stack, 0, 0); + + elna_instruction_list_concatenate(current_instruction, instruction); + current_instruction := instruction; + + instruction := _elna_tac_instruction_create(ElnaTacOperator.store); + _elna_tac_instruction_set_operand(instruction, 1, operand_type, operand_value, operand_length); + _elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.temporary, 7, 0); - if instruction <> 0 then elna_instruction_list_concatenate(current_instruction, instruction); - current_instruction := instruction end; - - instruction := _elna_tac_instruction_create(ElnaTacOperator.copy); - _elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.temporary, 7, 0); - _elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.stack, 76, 0); - - elna_instruction_list_concatenate(current_instruction, instruction); - current_instruction := instruction; - - instruction := _elna_tac_instruction_create(ElnaTacOperator.store); - _elna_tac_instruction_set_operand(instruction, 1, operand_type, operand_value, operand_length); - _elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.temporary, 7, 0); - - elna_instruction_list_concatenate(current_instruction, instruction); - return first_instruction end; @@ -3248,9 +3329,9 @@ begin result := malloc(_parameter_info_size()); result^.kind := InfoKind.parameter_info; - (* Calculate the stack offset: 104 - (4 * parameter_counter) *) + (* Calculate the stack offset: 28 - (4 * parameter_counter) *) offset := parameter_index * 4; - result^.offset := 104 - offset; + result^.offset := 28 - offset; result^.variable_type := parameter_type; return result @@ -3308,11 +3389,11 @@ end; proc elna_name_procedure_parameter(parser_node: ^ElnaTreeVariableDeclaration, parameter_index: Word, symbol_table: Word); var info: Word; - variable_type: Word; + variable_type1: Word; begin - variable_type := elna_name_type_expression(parser_node^._type); + variable_type1 := elna_name_type_expression(parser_node^._type); - info := _parameter_info_create(parameter_index, variable_type); + info := _parameter_info_create(parameter_index, variable_type1); _symbol_table_enter(symbol_table, parser_node^.name, parser_node^.length, info) end; @@ -3323,11 +3404,11 @@ end; proc elna_name_procedure_temporary(parser_node: ^ElnaTreeVariableDeclaration, variable_index: Word, symbol_table: Word); var info: Word; - variable_type: Word; + variable_type1: Word; begin - variable_type := elna_name_type_expression(parser_node^._type); + variable_type1 := elna_name_type_expression(parser_node^._type); - info := _temporary_info_create(variable_index, variable_type); + info := _temporary_info_create(variable_index, variable_type1); _symbol_table_enter(symbol_table, parser_node^.name, parser_node^.length, info) end; @@ -3473,25 +3554,15 @@ end; proc elna_rtl_procedure_declaration(tac_declaration: ^ElnaInstructionDeclaration); var - body: Word; result: ^ElnaInstructionDeclaration; - return_instruction: ^ElnaInstructionList; begin result := malloc(ElnaInstructionDeclaration_size()); - body := tac_declaration^.body; - body := elna_rtl_instructions(body); - - return_instruction := elna_rtl_instruction_create(ElnaRtlOperator.allocate_stack); - return_instruction^.next := body; - body := return_instruction; - return_instruction := elna_rtl_instruction_create(ElnaRtlOperator.ret); - elna_instruction_list_concatenate(body, return_instruction); result^.next := nil; result^.name := tac_declaration^.name; result^.length := tac_declaration^.length; result^.stack := tac_declaration^.stack; - result^.body := body; + result^.body := elna_rtl_instructions(tac_declaration^.body); return result end; @@ -3621,14 +3692,14 @@ var current_procedure: ^ElnaInstructionList; first_procedure: Word; begin - first_procedure := 0; + first_procedure := nil; .elna_tac_procedures_loop; if parser_node = 0 then goto elna_tac_procedures_end end; result := _elna_tac_procedure_declaration(parser_node); - if first_procedure = 0 then + if first_procedure = nil then first_procedure := result else current_procedure^.next := result @@ -3749,7 +3820,7 @@ var token_kind: Word; name: Word; name_length: Word; - variable_type: Word; + variable_type1: Word; result: ^ElnaTreeVariableDeclaration; begin _elna_lexer_read_token(@token_kind); @@ -3762,14 +3833,14 @@ begin _elna_lexer_read_token(@token_kind); _elna_lexer_skip_token(); - variable_type := elna_parser_type_expression(); + variable_type1 := elna_parser_type_expression(); result := malloc(ElnaTreeVariableDeclaration_size()); result^.kind := ElnaTreeKind.variable_declaration; result^.next := nil; result^.name := name; result^.length := name_length; - result^._type := variable_type; + result^._type := variable_type1; return result end; @@ -4238,11 +4309,6 @@ begin .elna_type_field_access_expression_field; if string_compare(parser_node^.field, parser_node^.length, current_field^.name, current_field^.length) = 0 then - (* Debug. Error stream output. - _syscall(2, name_pointer, name_length, 0, 0, 0, 64); - printf("# if %.*s\n\0", name_length, name_pointer); - fflush(0) *) - field_count := field_count - 1; current_field := current_field + ElnaTypeField_size(); goto elna_type_field_access_expression_field @@ -4371,20 +4437,10 @@ begin elna_type_module_declaration(parser_node); tac := _elna_tac_module_declaration(parser_node); rtl := elna_rtl_module_declaration(tac); + elna_alloc_module(rtl); _elna_writer_module(rtl) end; -(** - * Terminates the program. a0 contains the return code. - * - * Parameters: - * a0 - Status code. - *) -proc _exit(status: Word); -begin - _syscall(status, 0, 0, 0, 0, 0, 93) -end; - (** * Looks for a symbol in the given symbol table. * @@ -5312,7 +5368,6 @@ begin compiler_strings_position := @compiler_strings; source_code := malloc(495616); symbol_table_store := malloc(4194304); - temporary_variable_counter := 0 end; (* @@ -5332,12 +5387,12 @@ begin .start_read; (* Second argument is buffer size. Modifying update the source_code definition. *) - last_read := _read_file(offset, 409600); + last_read := read(0, offset, 409600); if last_read > 0 then offset := offset + last_read; goto start_read end; _compile(); - _exit(0) + exit(0) end;