Use pseudo register in binary expressions
This commit is contained in:
@@ -1253,7 +1253,7 @@ begin
|
|||||||
return result
|
return result
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc _elna_tac_label(counter: Word, length: Word);
|
proc elna_tac_label(counter: Word, length: Word);
|
||||||
var
|
var
|
||||||
result1: Word;
|
result1: Word;
|
||||||
begin
|
begin
|
||||||
@@ -1264,7 +1264,7 @@ begin
|
|||||||
return result1
|
return result1
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc _elna_writer_instruction_name(instruction_kind: Word);
|
proc elna_riscv_instruction_name(instruction_kind: Word);
|
||||||
var
|
var
|
||||||
argument_count: Word;
|
argument_count: Word;
|
||||||
begin
|
begin
|
||||||
@@ -1344,13 +1344,13 @@ begin
|
|||||||
return argument_count
|
return argument_count
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc _elna_writer_register(register: Word);
|
proc elna_riscv_register(register: Word);
|
||||||
begin
|
begin
|
||||||
_write_c('x');
|
_write_c('x');
|
||||||
_write_i(register - 1)
|
_write_i(register - 1)
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc _elna_writer_operand(instruction: Word, n: Word);
|
proc elna_riscv_operand(instruction: Word, n: Word);
|
||||||
var
|
var
|
||||||
operand_value: Word;
|
operand_value: Word;
|
||||||
operand_length: Word;
|
operand_length: Word;
|
||||||
@@ -1362,11 +1362,11 @@ begin
|
|||||||
|
|
||||||
_write_c(' ');
|
_write_c(' ');
|
||||||
if operand_type = ElnaRtlOperand.register then
|
if operand_type = ElnaRtlOperand.register then
|
||||||
_elna_writer_register(operand_value)
|
elna_riscv_register(operand_value)
|
||||||
elsif operand_type = ElnaRtlOperand.offset then
|
elsif operand_type = ElnaRtlOperand.offset then
|
||||||
_write_i(operand_length);
|
_write_i(operand_length);
|
||||||
_write_c('(');
|
_write_c('(');
|
||||||
_elna_writer_register(operand_value);
|
elna_riscv_register(operand_value);
|
||||||
_write_c(')')
|
_write_c(')')
|
||||||
elsif operand_type = ElnaRtlOperand.symbol then
|
elsif operand_type = ElnaRtlOperand.symbol then
|
||||||
if operand_length = 0 then
|
if operand_length = 0 then
|
||||||
@@ -1394,6 +1394,36 @@ begin
|
|||||||
return pseudo_symbol1
|
return pseudo_symbol1
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
(**
|
||||||
|
* If the first operand of an instruction is an operation target and expected
|
||||||
|
* to be a register, but is not a register, then this procedure rewrites it
|
||||||
|
* to a temporary register and preserves its value in the following instruction.
|
||||||
|
*)
|
||||||
|
proc elna_alloc_operation_target(instruction: ^ElnaInstructionList);
|
||||||
|
var
|
||||||
|
operand_type: Word;
|
||||||
|
operand_value: Word;
|
||||||
|
operand_length: Word;
|
||||||
|
pseudo_symbol: Word;
|
||||||
|
store_instruction: ^ElnaInstructionList;
|
||||||
|
begin
|
||||||
|
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
|
||||||
|
store_instruction := elna_rtl_instruction_create(ElnaRtlOperator.sw);
|
||||||
|
store_instruction^.next := instruction^.next;
|
||||||
|
|
||||||
|
pseudo_symbol := elna_alloc_variable(operand_value, operand_length);
|
||||||
|
elna_rtl_instruction_set_operand(store_instruction, 1, ElnaRtlOperand.register, ElnaRtlRegister.t0, 0);
|
||||||
|
elna_rtl_instruction_set_operand(store_instruction, 2, ElnaRtlOperand.offset, ElnaRtlRegister.sp, pseudo_symbol);
|
||||||
|
|
||||||
|
instruction^.next := store_instruction;
|
||||||
|
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlOperand.register, ElnaRtlRegister.t0, 0)
|
||||||
|
end
|
||||||
|
end;
|
||||||
|
|
||||||
proc elna_alloc_instruction(instruction: ^ElnaInstructionList);
|
proc elna_alloc_instruction(instruction: ^ElnaInstructionList);
|
||||||
var
|
var
|
||||||
instruction_kind: Word;
|
instruction_kind: Word;
|
||||||
@@ -1448,7 +1478,9 @@ begin
|
|||||||
elna_rtl_instruction_set_operand(instruction, 3, ElnaRtlOperand.immediate, pseudo_symbol, 0);
|
elna_rtl_instruction_set_operand(instruction, 3, ElnaRtlOperand.immediate, pseudo_symbol, 0);
|
||||||
|
|
||||||
goto elna_alloc_instruction_end
|
goto elna_alloc_instruction_end
|
||||||
end
|
end;
|
||||||
|
|
||||||
|
elna_alloc_operation_target(instruction)
|
||||||
elsif instruction_kind = ElnaRtlOperator.sw then
|
elsif instruction_kind = ElnaRtlOperator.sw then
|
||||||
operand_type := elna_rtl_instruction_get_operand_type(instruction, 2);
|
operand_type := elna_rtl_instruction_get_operand_type(instruction, 2);
|
||||||
operand_value := elna_rtl_instruction_get_operand_value(instruction, 2);
|
operand_value := elna_rtl_instruction_get_operand_value(instruction, 2);
|
||||||
@@ -1469,11 +1501,53 @@ begin
|
|||||||
|
|
||||||
goto elna_alloc_instruction_end
|
goto elna_alloc_instruction_end
|
||||||
end
|
end
|
||||||
|
elsif instruction_kind = ElnaRtlOperator._or then
|
||||||
|
elna_alloc_operation_target(instruction)
|
||||||
|
elsif instruction_kind = ElnaRtlOperator.and then
|
||||||
|
elna_alloc_operation_target(instruction)
|
||||||
|
elsif instruction_kind = ElnaRtlOperator.mul then
|
||||||
|
elna_alloc_operation_target(instruction)
|
||||||
|
elsif instruction_kind = ElnaRtlOperator.sub then
|
||||||
|
elna_alloc_operation_target(instruction)
|
||||||
|
elsif instruction_kind = ElnaRtlOperator.add then
|
||||||
|
elna_alloc_operation_target(instruction)
|
||||||
|
elsif instruction_kind = ElnaRtlOperator._xor then
|
||||||
|
elna_alloc_operation_target(instruction)
|
||||||
|
elsif instruction_kind = ElnaRtlOperator.rem then
|
||||||
|
elna_alloc_operation_target(instruction)
|
||||||
|
elsif instruction_kind = ElnaRtlOperator.slt then
|
||||||
|
elna_alloc_operation_target(instruction)
|
||||||
|
elsif instruction_kind = ElnaRtlOperator.beqz 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
|
||||||
|
old_instruction := malloc(elna_rtl_instruction_size());
|
||||||
|
memcpy(old_instruction, instruction, elna_rtl_instruction_size());
|
||||||
|
|
||||||
|
pseudo_symbol := elna_alloc_variable(operand_value, operand_length);
|
||||||
|
elna_rtl_instruction_set_kind(instruction, ElnaRtlOperator.lw);
|
||||||
|
|
||||||
|
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlOperand.register, ElnaRtlRegister.t0, 0);
|
||||||
|
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlOperand.offset, ElnaRtlRegister.sp, pseudo_symbol);
|
||||||
|
|
||||||
|
instruction^.next := old_instruction;
|
||||||
|
elna_rtl_instruction_set_operand(old_instruction, 1, ElnaRtlOperand.register, ElnaRtlRegister.t0, 0);
|
||||||
|
|
||||||
|
goto elna_alloc_instruction_end
|
||||||
|
end
|
||||||
|
elsif instruction_kind = ElnaRtlOperator.seqz then
|
||||||
|
elna_alloc_operation_target(instruction)
|
||||||
|
elsif instruction_kind = ElnaRtlOperator.snez then
|
||||||
|
elna_alloc_operation_target(instruction)
|
||||||
|
elsif instruction_kind = ElnaRtlOperator.xori then
|
||||||
|
elna_alloc_operation_target(instruction)
|
||||||
end;
|
end;
|
||||||
.elna_alloc_instruction_end;
|
.elna_alloc_instruction_end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc _elna_writer_instruction(instruction: Word);
|
proc elna_riscv_instruction(instruction: Word);
|
||||||
var
|
var
|
||||||
argument_count: Word;
|
argument_count: Word;
|
||||||
instruction_kind: Word;
|
instruction_kind: Word;
|
||||||
@@ -1503,18 +1577,18 @@ begin
|
|||||||
printf("\tlw ra, %i(sp)\n\tlw s0, %i(sp)\n\taddi sp, sp, %i\n\0", operand_value + 4, operand_value, operand_value + 8);
|
printf("\tlw ra, %i(sp)\n\tlw s0, %i(sp)\n\taddi sp, sp, %i\n\0", operand_value + 4, operand_value, operand_value + 8);
|
||||||
fflush(nil)
|
fflush(nil)
|
||||||
else
|
else
|
||||||
argument_count := _elna_writer_instruction_name(instruction_kind)
|
argument_count := elna_riscv_instruction_name(instruction_kind)
|
||||||
end;
|
end;
|
||||||
current_argument := 1;
|
current_argument := 1;
|
||||||
|
|
||||||
.elna_writer_instruction_loop;
|
.elna_riscv_instruction_loop;
|
||||||
if current_argument <= argument_count then
|
if current_argument <= argument_count then
|
||||||
_elna_writer_operand(instruction, current_argument);
|
elna_riscv_operand(instruction, current_argument);
|
||||||
current_argument := current_argument + 1
|
current_argument := current_argument + 1
|
||||||
end;
|
end;
|
||||||
if current_argument <= argument_count then
|
if current_argument <= argument_count then
|
||||||
_write_c(',');
|
_write_c(',');
|
||||||
goto elna_writer_instruction_loop
|
goto elna_riscv_instruction_loop
|
||||||
end;
|
end;
|
||||||
|
|
||||||
_write_c('\n')
|
_write_c('\n')
|
||||||
@@ -1559,13 +1633,13 @@ begin
|
|||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc _elna_writer_instructions(instruction: ^ElnaInstructionList);
|
proc elna_riscv_instructions(instruction: ^ElnaInstructionList);
|
||||||
begin
|
begin
|
||||||
.elna_writer_instructions_start;
|
.elna_riscv_instructions_start;
|
||||||
if instruction <> nil then
|
if instruction <> nil then
|
||||||
_elna_writer_instruction(instruction);
|
elna_riscv_instruction(instruction);
|
||||||
instruction := instruction^.next;
|
instruction := instruction^.next;
|
||||||
goto elna_writer_instructions_start
|
goto elna_riscv_instructions_start
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@@ -1596,9 +1670,9 @@ begin
|
|||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc _elna_writer_procedure(procedure: ^ElnaInstructionDeclaration);
|
proc elna_riscv_procedure(procedure: ^ElnaInstructionDeclaration);
|
||||||
begin
|
begin
|
||||||
.elna_writer_procedure_loop;
|
.elna_riscv_procedure_loop;
|
||||||
|
|
||||||
(* Write .type _procedure_name, @function. *)
|
(* Write .type _procedure_name, @function. *)
|
||||||
_write_z(".type \0");
|
_write_z(".type \0");
|
||||||
@@ -1610,18 +1684,18 @@ begin
|
|||||||
_write_s(procedure^.name, procedure^.length);
|
_write_s(procedure^.name, procedure^.length);
|
||||||
_write_z(":\n\0");
|
_write_z(":\n\0");
|
||||||
|
|
||||||
_elna_writer_instructions(procedure^.body);
|
elna_riscv_instructions(procedure^.body);
|
||||||
_write_z("\tret\n\0");
|
_write_z("\tret\n\0");
|
||||||
|
|
||||||
procedure := procedure^.next;
|
procedure := procedure^.next;
|
||||||
if procedure <> nil then
|
if procedure <> nil then
|
||||||
goto elna_writer_procedure_loop
|
goto elna_riscv_procedure_loop
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc _elna_writer_variable(variable: ^ElnaInstructionDeclaration);
|
proc elna_riscv_variable(variable: ^ElnaInstructionDeclaration);
|
||||||
begin
|
begin
|
||||||
.elna_writer_variable_loop;
|
.elna_riscv_variable_loop;
|
||||||
if variable <> 0 then
|
if variable <> 0 then
|
||||||
_write_z(".type \0");
|
_write_z(".type \0");
|
||||||
_write_s(variable^.name, variable^.length);
|
_write_s(variable^.name, variable^.length);
|
||||||
@@ -1636,7 +1710,7 @@ begin
|
|||||||
_write_c('\n');
|
_write_c('\n');
|
||||||
variable := variable^.next;
|
variable := variable^.next;
|
||||||
|
|
||||||
goto elna_writer_variable_loop
|
goto elna_riscv_variable_loop
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@@ -1656,7 +1730,7 @@ begin
|
|||||||
elna_alloc_procedure(pair^.code)
|
elna_alloc_procedure(pair^.code)
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc _elna_writer_module(pair: ^ElnaInstructionModule);
|
proc elna_riscv_module(pair: ^ElnaInstructionModule);
|
||||||
var
|
var
|
||||||
compiler_strings_copy: Word;
|
compiler_strings_copy: Word;
|
||||||
compiler_strings_end: Word;
|
compiler_strings_end: Word;
|
||||||
@@ -1665,13 +1739,13 @@ begin
|
|||||||
_write_z(".globl main\n\n\0");
|
_write_z(".globl main\n\n\0");
|
||||||
_write_z(".section .data\n\0");
|
_write_z(".section .data\n\0");
|
||||||
|
|
||||||
_elna_writer_variable(pair^.data);
|
elna_riscv_variable(pair^.data);
|
||||||
|
|
||||||
_write_z(".section .text\n\n\0");
|
_write_z(".section .text\n\n\0");
|
||||||
_write_z(".type _load_byte, @function\n_load_byte:\n\tlb a0, (a0)\nret\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");
|
_write_z(".type _store_byte, @function\n_store_byte:\n\tsb a0, (a1)\nret\n\n\0");
|
||||||
|
|
||||||
_elna_writer_procedure(pair^.code);
|
elna_riscv_procedure(pair^.code);
|
||||||
|
|
||||||
_write_z(".section .rodata\n.type strings, @object\nstrings: .ascii \0");
|
_write_z(".section .rodata\n.type strings, @object\nstrings: .ascii \0");
|
||||||
_write_c('"');
|
_write_c('"');
|
||||||
@@ -1679,13 +1753,13 @@ begin
|
|||||||
compiler_strings_copy := @compiler_strings;
|
compiler_strings_copy := @compiler_strings;
|
||||||
compiler_strings_end := compiler_strings_position;
|
compiler_strings_end := compiler_strings_position;
|
||||||
|
|
||||||
.elna_writer_module_loop;
|
.elna_riscv_module_loop;
|
||||||
if compiler_strings_copy < compiler_strings_end then
|
if compiler_strings_copy < compiler_strings_end then
|
||||||
current_byte := _load_byte(compiler_strings_copy);
|
current_byte := _load_byte(compiler_strings_copy);
|
||||||
compiler_strings_copy := compiler_strings_copy + 1;
|
compiler_strings_copy := compiler_strings_copy + 1;
|
||||||
_write_c(current_byte);
|
_write_c(current_byte);
|
||||||
|
|
||||||
goto elna_writer_module_loop
|
goto elna_riscv_module_loop
|
||||||
end;
|
end;
|
||||||
_write_c('"');
|
_write_c('"');
|
||||||
_write_c('\n');
|
_write_c('\n');
|
||||||
@@ -1743,7 +1817,7 @@ begin
|
|||||||
return result
|
return result
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc _elna_tac_integer_literal(integer_literal_node: ^ElnaTreeIntegerLiteral, operand_type: Word, operand_value: Word, operand_length: Word);
|
proc elna_tac_integer_literal(integer_literal_node: ^ElnaTreeIntegerLiteral, operand_type: Word, operand_value: Word, operand_length: Word);
|
||||||
begin
|
begin
|
||||||
operand_type^ := ElnaTacOperand.immediate;
|
operand_type^ := ElnaTacOperand.immediate;
|
||||||
operand_value^ := integer_literal_node^.value;
|
operand_value^ := integer_literal_node^.value;
|
||||||
@@ -1752,7 +1826,7 @@ begin
|
|||||||
return nil
|
return nil
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc _elna_tac_boolean_literal(boolean_literal_node: ^ElnaTreeBooleanLiteral, operand_type: Word, operand_value: Word, operand_length: Word);
|
proc elna_tac_boolean_literal(boolean_literal_node: ^ElnaTreeBooleanLiteral, operand_type: Word, operand_value: Word, operand_length: Word);
|
||||||
begin
|
begin
|
||||||
operand_type^ := ElnaTacOperand.immediate;
|
operand_type^ := ElnaTacOperand.immediate;
|
||||||
operand_value^ := boolean_literal_node^.value;
|
operand_value^ := boolean_literal_node^.value;
|
||||||
@@ -1761,7 +1835,7 @@ begin
|
|||||||
return nil
|
return nil
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc _elna_tac_nil_literal(nil_node: Word, operand_type: Word, operand_value: Word, operand_length: Word);
|
proc elna_tac_nil_literal(nil_node: Word, operand_type: Word, operand_value: Word, operand_length: Word);
|
||||||
begin
|
begin
|
||||||
operand_type^ := ElnaTacOperand.immediate;
|
operand_type^ := ElnaTacOperand.immediate;
|
||||||
operand_value^ := 0;
|
operand_value^ := 0;
|
||||||
@@ -1791,7 +1865,7 @@ begin
|
|||||||
return result
|
return result
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc _elna_tac_character_literal(character_literal_node: ^ElnaTreeCharacterLiteral, operand_type: Word, operand_value: Word, operand_length: Word);
|
proc elna_tac_character_literal(character_literal_node: ^ElnaTreeCharacterLiteral, operand_type: Word, operand_value: Word, operand_length: Word);
|
||||||
begin
|
begin
|
||||||
operand_type^ := ElnaTacOperand.immediate;
|
operand_type^ := ElnaTacOperand.immediate;
|
||||||
operand_value^ := character_literal_node^.value;
|
operand_value^ := character_literal_node^.value;
|
||||||
@@ -1820,7 +1894,7 @@ begin
|
|||||||
return result
|
return result
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc _elna_tac_variable_expression(variable_expression: ^ElnaTreeVariableExpression, symbol_table: Word, operand_type: Word, operand_value: Word, operand_length: Word);
|
proc elna_tac_variable_expression(variable_expression: ^ElnaTreeVariableExpression, symbol_table: Word, operand_type: Word, operand_value: Word, operand_length: Word);
|
||||||
var
|
var
|
||||||
lookup_result: ^ElnaSymbolTemporaryInfo;
|
lookup_result: ^ElnaSymbolTemporaryInfo;
|
||||||
begin
|
begin
|
||||||
@@ -1945,22 +2019,22 @@ begin
|
|||||||
return simple_expression
|
return simple_expression
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc _elna_tac_simple_expression(parser_node: ^ElnaTreeNode, symbol_table: Word, operand_type: Word, operand_value: Word, operand_length: Word);
|
proc elna_tac_simple_expression(parser_node: ^ElnaTreeNode, symbol_table: Word, operand_type: Word, operand_value: Word, operand_length: Word);
|
||||||
var
|
var
|
||||||
instruction: Word;
|
instruction: Word;
|
||||||
begin
|
begin
|
||||||
if parser_node^.kind = ElnaTreeKind.character_literal then
|
if parser_node^.kind = ElnaTreeKind.character_literal then
|
||||||
instruction := _elna_tac_character_literal(parser_node, operand_type, operand_value, operand_length)
|
instruction := elna_tac_character_literal(parser_node, operand_type, operand_value, operand_length)
|
||||||
elsif parser_node^.kind = ElnaTreeKind.string_literal then
|
elsif parser_node^.kind = ElnaTreeKind.string_literal then
|
||||||
instruction := _elna_tac_string_literal(parser_node, operand_type, operand_value, operand_length)
|
instruction := _elna_tac_string_literal(parser_node, operand_type, operand_value, operand_length)
|
||||||
elsif parser_node^.kind = ElnaTreeKind.integer_literal then
|
elsif parser_node^.kind = ElnaTreeKind.integer_literal then
|
||||||
instruction := _elna_tac_integer_literal(parser_node, operand_type, operand_value, operand_length)
|
instruction := elna_tac_integer_literal(parser_node, operand_type, operand_value, operand_length)
|
||||||
elsif parser_node^.kind = ElnaTreeKind.boolean_literal then
|
elsif parser_node^.kind = ElnaTreeKind.boolean_literal then
|
||||||
instruction := _elna_tac_boolean_literal(parser_node, operand_type, operand_value, operand_length)
|
instruction := elna_tac_boolean_literal(parser_node, operand_type, operand_value, operand_length)
|
||||||
elsif parser_node^.kind = ElnaTreeKind.null then
|
elsif parser_node^.kind = ElnaTreeKind.null then
|
||||||
instruction := _elna_tac_nil_literal(parser_node, operand_type, operand_value, operand_length)
|
instruction := elna_tac_nil_literal(parser_node, operand_type, operand_value, operand_length)
|
||||||
else
|
else
|
||||||
instruction := _elna_tac_variable_expression(parser_node, symbol_table, operand_type, operand_value, operand_length)
|
instruction := elna_tac_variable_expression(parser_node, symbol_table, operand_type, operand_value, operand_length)
|
||||||
end;
|
end;
|
||||||
return instruction
|
return instruction
|
||||||
end;
|
end;
|
||||||
@@ -2000,7 +2074,7 @@ begin
|
|||||||
return result
|
return result
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc _elna_tac_unary_expression(parser_node: ^ElnaTreeUnaryExpression, symbol_table: Word, operand_type: Word, operand_value: Word, operand_length: Word);
|
proc elna_tac_unary_expression(parser_node: ^ElnaTreeUnaryExpression, symbol_table: Word, operand_type: Word, operand_value: Word, operand_length: Word);
|
||||||
var
|
var
|
||||||
current_character: Word;
|
current_character: Word;
|
||||||
token_kind: Word;
|
token_kind: Word;
|
||||||
@@ -2022,7 +2096,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
if operator = '@' then
|
if operator = '@' then
|
||||||
first_instruction := _elna_tac_designator(operand, symbol_table, @is_address, operand_type, operand_value, operand_length);
|
first_instruction := elna_tac_designator(operand, symbol_table, @is_address, operand_type, operand_value, operand_length);
|
||||||
|
|
||||||
instruction := _elna_tac_instruction_create(ElnaTacOperator.get_address);
|
instruction := _elna_tac_instruction_create(ElnaTacOperator.get_address);
|
||||||
_elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.temporary, 6, 0);
|
_elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.temporary, 6, 0);
|
||||||
@@ -2035,7 +2109,7 @@ begin
|
|||||||
first_instruction := elna_instruction_list_concatenate(first_instruction, instruction)
|
first_instruction := elna_instruction_list_concatenate(first_instruction, instruction)
|
||||||
else
|
else
|
||||||
current_character := operand_type^;
|
current_character := operand_type^;
|
||||||
first_instruction := _elna_tac_designator(operand, symbol_table, @is_address, operand_type, operand_value, operand_length);
|
first_instruction := elna_tac_designator(operand, symbol_table, @is_address, operand_type, operand_value, operand_length);
|
||||||
operand := operand_type^;
|
operand := operand_type^;
|
||||||
|
|
||||||
if is_address then
|
if is_address then
|
||||||
@@ -2142,7 +2216,7 @@ begin
|
|||||||
return result
|
return result
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc _elna_tac_binary_expression(parser_node: ^ElnaTreeBinaryExpression, symbol_table: Word, operand_type: Word, operand_value: Word, operand_length: Word);
|
proc elna_tac_binary_expression(parser_node: ^ElnaTreeBinaryExpression, symbol_table: Word, operand_type: Word, operand_value: Word, operand_length: Word);
|
||||||
var
|
var
|
||||||
first_instruction: Word;
|
first_instruction: Word;
|
||||||
instruction: Word;
|
instruction: Word;
|
||||||
@@ -2152,12 +2226,12 @@ var
|
|||||||
lhs_length: Word;
|
lhs_length: Word;
|
||||||
begin
|
begin
|
||||||
if parser_node^.kind <> ElnaTreeKind.binary_expression then
|
if parser_node^.kind <> ElnaTreeKind.binary_expression then
|
||||||
first_instruction := _elna_tac_unary_expression(parser_node, symbol_table, operand_type, operand_value, operand_length)
|
first_instruction := elna_tac_unary_expression(parser_node, symbol_table, operand_type, operand_value, operand_length)
|
||||||
else
|
else
|
||||||
lhs_type := 0;
|
lhs_type := 0;
|
||||||
lhs_value := 0;
|
lhs_value := 0;
|
||||||
lhs_length := 0;
|
lhs_length := 0;
|
||||||
first_instruction := _elna_tac_unary_expression(parser_node^.lhs, 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. *)
|
(* Save the value of the left expression on the stack. *)
|
||||||
instruction := _elna_tac_instruction_create(ElnaTacOperator.copy);
|
instruction := _elna_tac_instruction_create(ElnaTacOperator.copy);
|
||||||
@@ -2174,7 +2248,7 @@ begin
|
|||||||
lhs_type := 0;
|
lhs_type := 0;
|
||||||
lhs_value := 0;
|
lhs_value := 0;
|
||||||
lhs_length := 0;
|
lhs_length := 0;
|
||||||
instruction := _elna_tac_unary_expression(parser_node^.rhs, 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);
|
current_instruction := elna_instruction_list_concatenate(current_instruction, instruction);
|
||||||
|
|
||||||
if parser_node^.operator = ElnaLexerKind.plus then
|
if parser_node^.operator = ElnaLexerKind.plus then
|
||||||
@@ -2206,15 +2280,15 @@ begin
|
|||||||
elsif parser_node^.operator = ElnaLexerKind.not_equal then
|
elsif parser_node^.operator = ElnaLexerKind.not_equal then
|
||||||
instruction := _elna_tac_instruction_create(ElnaTacOperator.not_equal)
|
instruction := _elna_tac_instruction_create(ElnaTacOperator.not_equal)
|
||||||
end;
|
end;
|
||||||
_elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.temporary, 6, 0);
|
_elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.pseudo, "$binary", 7);
|
||||||
_elna_tac_instruction_set_operand(instruction, 2, ElnaTacOperand.pseudo, "$lhs", 4);
|
_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_tac_instruction_set_operand(instruction, 3, lhs_type, lhs_value, lhs_length);
|
||||||
|
|
||||||
elna_instruction_list_concatenate(current_instruction, instruction);
|
operand_type^ := ElnaTacOperand.pseudo;
|
||||||
|
operand_value^ := "$binary";
|
||||||
|
operand_length^ := 7;
|
||||||
|
|
||||||
operand_type^ := ElnaTacOperand.temporary;
|
elna_instruction_list_concatenate(current_instruction, instruction)
|
||||||
operand_value^ := 6;
|
|
||||||
operand_length^ := 0
|
|
||||||
end;
|
end;
|
||||||
return first_instruction
|
return first_instruction
|
||||||
end;
|
end;
|
||||||
@@ -2293,7 +2367,7 @@ begin
|
|||||||
return result
|
return result
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc _elna_tac_call(parsed_call: Word, symbol_table: Word);
|
proc elna_tac_call(parsed_call: Word, symbol_table: Word);
|
||||||
var
|
var
|
||||||
argument_count: Word;
|
argument_count: Word;
|
||||||
name_length: Word;
|
name_length: Word;
|
||||||
@@ -2338,7 +2412,7 @@ begin
|
|||||||
operand_type := 0;
|
operand_type := 0;
|
||||||
operand_value := 0;
|
operand_value := 0;
|
||||||
operand_length := 0;
|
operand_length := 0;
|
||||||
instruction := _elna_tac_binary_expression(parsed_expression, symbol_table, @operand_type, @operand_value, @operand_length);
|
instruction := elna_tac_binary_expression(parsed_expression, symbol_table, @operand_type, @operand_value, @operand_length);
|
||||||
if first_instruction = 0 then
|
if first_instruction = 0 then
|
||||||
first_instruction := instruction
|
first_instruction := instruction
|
||||||
else
|
else
|
||||||
@@ -2400,7 +2474,7 @@ begin
|
|||||||
return result1
|
return result1
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc _elna_tac_goto_statement(parser_node: ^ElnaTreeGotoStatement);
|
proc elna_tac_goto_statement(parser_node: ^ElnaTreeGotoStatement);
|
||||||
var
|
var
|
||||||
label_length1: Word;
|
label_length1: Word;
|
||||||
label_with_dot1: Word;
|
label_with_dot1: Word;
|
||||||
@@ -2441,11 +2515,11 @@ begin
|
|||||||
return result
|
return result
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc _elna_tac_label_declaration(parser_node: ^ElnaTreeLabelDeclaration);
|
proc elna_tac_label_declaration(parser_node: ^ElnaTreeLabelDeclaration);
|
||||||
return _elna_tac_label(parser_node^.label, parser_node^.length)
|
return elna_tac_label(parser_node^.label, parser_node^.length)
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc _elna_tac_enumeration_value(field_access_expression: ^ElnaTreeFieldAccessExpression, operand_type: Word, operand_value: Word, operand_length: Word);
|
proc elna_tac_enumeration_value(field_access_expression: ^ElnaTreeFieldAccessExpression, operand_type: Word, operand_value: Word, operand_length: Word);
|
||||||
var
|
var
|
||||||
enumeration_type: ^ElnaTypeEnumeration;
|
enumeration_type: ^ElnaTypeEnumeration;
|
||||||
members: Word;
|
members: Word;
|
||||||
@@ -2509,7 +2583,7 @@ begin
|
|||||||
return result
|
return result
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc _elna_tac_designator(parser_node: ^ElnaTreeExpression, symbol_table: Word, is_address: Word, operand_type: Word, operand_value: Word, operand_length: Word);
|
proc elna_tac_designator(parser_node: ^ElnaTreeExpression, symbol_table: Word, is_address: Word, operand_type: Word, operand_value: Word, operand_length: Word);
|
||||||
var
|
var
|
||||||
field_access_expression: ^ElnaTreeFieldAccessExpression;
|
field_access_expression: ^ElnaTreeFieldAccessExpression;
|
||||||
dereference_expression: ^ElnaTreeDereferenceExpression;
|
dereference_expression: ^ElnaTreeDereferenceExpression;
|
||||||
@@ -2524,7 +2598,7 @@ var
|
|||||||
begin
|
begin
|
||||||
if parser_node^.kind = ElnaTreeKind.dereference_expression then
|
if parser_node^.kind = ElnaTreeKind.dereference_expression then
|
||||||
dereference_expression := parser_node;
|
dereference_expression := parser_node;
|
||||||
first_instruction := _elna_tac_designator(dereference_expression^.pointer, symbol_table, is_address, operand_type, operand_value, operand_length);
|
first_instruction := elna_tac_designator(dereference_expression^.pointer, symbol_table, is_address, operand_type, operand_value, operand_length);
|
||||||
|
|
||||||
last_instruction := _elna_tac_instruction_create(ElnaTacOperator.copy);
|
last_instruction := _elna_tac_instruction_create(ElnaTacOperator.copy);
|
||||||
_elna_tac_instruction_set_operand(last_instruction, 1, ElnaTacOperand.temporary, 6, 0);
|
_elna_tac_instruction_set_operand(last_instruction, 1, ElnaTacOperand.temporary, 6, 0);
|
||||||
@@ -2541,11 +2615,11 @@ begin
|
|||||||
expression_type := field_access_expression^.type_decoration;
|
expression_type := field_access_expression^.type_decoration;
|
||||||
|
|
||||||
if expression_type^.kind = ElnaTypeKind.enumeration then
|
if expression_type^.kind = ElnaTypeKind.enumeration then
|
||||||
first_instruction := _elna_tac_enumeration_value(field_access_expression, operand_type, operand_value, operand_length);
|
first_instruction := elna_tac_enumeration_value(field_access_expression, operand_type, operand_value, operand_length);
|
||||||
is_address^ := 0
|
is_address^ := 0
|
||||||
else
|
else
|
||||||
designator_base := field_access_expression^.aggregate;
|
designator_base := field_access_expression^.aggregate;
|
||||||
first_instruction := _elna_tac_designator(designator_base, symbol_table, is_address, operand_type, operand_value, operand_length);
|
first_instruction := elna_tac_designator(designator_base, symbol_table, is_address, operand_type, operand_value, operand_length);
|
||||||
aggregate_type := designator_base^.type_decoration;
|
aggregate_type := designator_base^.type_decoration;
|
||||||
|
|
||||||
field_count := aggregate_type^.length;
|
field_count := aggregate_type^.length;
|
||||||
@@ -2573,14 +2647,14 @@ begin
|
|||||||
first_instruction := elna_instruction_list_concatenate(first_instruction, last_instruction)
|
first_instruction := elna_instruction_list_concatenate(first_instruction, last_instruction)
|
||||||
end;
|
end;
|
||||||
elsif parser_node^.kind = ElnaTreeKind.call then
|
elsif parser_node^.kind = ElnaTreeKind.call then
|
||||||
first_instruction := _elna_tac_call(parser_node, symbol_table);
|
first_instruction := elna_tac_call(parser_node, symbol_table);
|
||||||
|
|
||||||
operand_type^ := ElnaTacOperand.temporary;
|
operand_type^ := ElnaTacOperand.temporary;
|
||||||
operand_value^ := 11;
|
operand_value^ := 11;
|
||||||
operand_length^ := 0;
|
operand_length^ := 0;
|
||||||
is_address^ := 0
|
is_address^ := 0
|
||||||
else
|
else
|
||||||
first_instruction := _elna_tac_simple_expression(parser_node, symbol_table, operand_type, operand_value, operand_length);
|
first_instruction := elna_tac_simple_expression(parser_node, symbol_table, operand_type, operand_value, operand_length);
|
||||||
is_address^ := 0
|
is_address^ := 0
|
||||||
end;
|
end;
|
||||||
return first_instruction
|
return first_instruction
|
||||||
@@ -2606,7 +2680,7 @@ begin
|
|||||||
return result
|
return result
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc _elna_tac_assign_statement(parser_tree: ^ElnaTreeAssignStatement, symbol_table: Word);
|
proc elna_tac_assign_statement(parser_tree: ^ElnaTreeAssignStatement, symbol_table: Word);
|
||||||
var
|
var
|
||||||
is_address: Word;
|
is_address: Word;
|
||||||
first_instruction: Word;
|
first_instruction: Word;
|
||||||
@@ -2619,7 +2693,7 @@ begin
|
|||||||
operand_type := 0;
|
operand_type := 0;
|
||||||
operand_value := 0;
|
operand_value := 0;
|
||||||
operand_length := 0;
|
operand_length := 0;
|
||||||
first_instruction := _elna_tac_designator(parser_tree^.assignee, symbol_table, @is_address, @operand_type, @operand_value, @operand_length);
|
first_instruction := elna_tac_designator(parser_tree^.assignee, symbol_table, @is_address, @operand_type, @operand_value, @operand_length);
|
||||||
|
|
||||||
if operand_type = ElnaTacOperand.pseudo then
|
if operand_type = ElnaTacOperand.pseudo then
|
||||||
current_instruction := _elna_tac_instruction_create(ElnaTacOperator.copy);
|
current_instruction := _elna_tac_instruction_create(ElnaTacOperator.copy);
|
||||||
@@ -2628,26 +2702,22 @@ begin
|
|||||||
operand_type := 0;
|
operand_type := 0;
|
||||||
operand_value := 0;
|
operand_value := 0;
|
||||||
operand_length := 0;
|
operand_length := 0;
|
||||||
instruction := _elna_tac_binary_expression(parser_tree^.assignment, symbol_table, @operand_type, @operand_value, @operand_length);
|
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);
|
_elna_tac_instruction_set_operand(current_instruction, 2, operand_type, operand_value, operand_length);
|
||||||
|
|
||||||
first_instruction := elna_instruction_list_concatenate(instruction, current_instruction)
|
first_instruction := elna_instruction_list_concatenate(instruction, current_instruction)
|
||||||
else
|
else
|
||||||
|
(* Save the assignee address on the stack. *)
|
||||||
current_instruction := _elna_tac_instruction_create(ElnaTacOperator.get_address);
|
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, 1, ElnaTacOperand.pseudo, "$assign", 7);
|
||||||
_elna_tac_instruction_set_operand(current_instruction, 2, operand_type, operand_value, operand_length);
|
_elna_tac_instruction_set_operand(current_instruction, 2, operand_type, operand_value, operand_length);
|
||||||
first_instruction := elna_instruction_list_concatenate(first_instruction, current_instruction);
|
first_instruction := elna_instruction_list_concatenate(first_instruction, current_instruction);
|
||||||
|
|
||||||
(* Save the assignee address on the stack. *)
|
|
||||||
current_instruction := _elna_tac_instruction_create(ElnaTacOperator.copy);
|
|
||||||
_elna_tac_instruction_set_operand(current_instruction, 1, ElnaTacOperand.pseudo, "$assign", 7);
|
|
||||||
_elna_tac_instruction_set_operand(current_instruction, 2, ElnaTacOperand.temporary, 6, 0);
|
|
||||||
elna_instruction_list_concatenate(first_instruction, current_instruction);
|
|
||||||
(* Compile the assignment. *)
|
(* Compile the assignment. *)
|
||||||
operand_type := 0;
|
operand_type := 0;
|
||||||
operand_value := 0;
|
operand_value := 0;
|
||||||
operand_length := 0;
|
operand_length := 0;
|
||||||
instruction := _elna_tac_binary_expression(parser_tree^.assignment, symbol_table, @operand_type, @operand_value, @operand_length);
|
instruction := elna_tac_binary_expression(parser_tree^.assignment, symbol_table, @operand_type, @operand_value, @operand_length);
|
||||||
|
|
||||||
if instruction <> 0 then
|
if instruction <> 0 then
|
||||||
elna_instruction_list_concatenate(current_instruction, instruction);
|
elna_instruction_list_concatenate(current_instruction, instruction);
|
||||||
@@ -2684,7 +2754,7 @@ begin
|
|||||||
return result
|
return result
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc _elna_tac_return_statement(parser_node: ^ElnaTreeReturnStatement, symbol_table: Word);
|
proc elna_tac_return_statement(parser_node: ^ElnaTreeReturnStatement, symbol_table: Word);
|
||||||
var
|
var
|
||||||
first_instruction: Word;
|
first_instruction: Word;
|
||||||
instruction: Word;
|
instruction: Word;
|
||||||
@@ -2695,7 +2765,7 @@ begin
|
|||||||
operand_type := 0;
|
operand_type := 0;
|
||||||
operand_value := 0;
|
operand_value := 0;
|
||||||
operand_length := 0;
|
operand_length := 0;
|
||||||
first_instruction := _elna_tac_binary_expression(parser_node^.returned, symbol_table, @operand_type, @operand_value, @operand_length);
|
first_instruction := elna_tac_binary_expression(parser_node^.returned, symbol_table, @operand_type, @operand_value, @operand_length);
|
||||||
|
|
||||||
instruction := _elna_tac_instruction_create(ElnaTacOperator._return);
|
instruction := _elna_tac_instruction_create(ElnaTacOperator._return);
|
||||||
_elna_tac_instruction_set_operand(instruction, 1, operand_type, operand_value, operand_length);
|
_elna_tac_instruction_set_operand(instruction, 1, operand_type, operand_value, operand_length);
|
||||||
@@ -2746,7 +2816,7 @@ begin
|
|||||||
return result
|
return result
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc _elna_tac_conditional_statements(parser_node: ^ElnaTreeConditionalStatements, after_end_label: Word, symbol_table: Word);
|
proc elna_tac_conditional_statements(parser_node: ^ElnaTreeConditionalStatements, after_end_label: Word, symbol_table: Word);
|
||||||
var
|
var
|
||||||
condition_label: Word;
|
condition_label: Word;
|
||||||
instruction: Word;
|
instruction: Word;
|
||||||
@@ -2760,7 +2830,7 @@ begin
|
|||||||
operand_type := 0;
|
operand_type := 0;
|
||||||
operand_value := 0;
|
operand_value := 0;
|
||||||
operand_length := 0;
|
operand_length := 0;
|
||||||
first_instruction := _elna_tac_binary_expression(parser_node^.condition, symbol_table, @operand_type, @operand_value, @operand_length);
|
first_instruction := elna_tac_binary_expression(parser_node^.condition, symbol_table, @operand_type, @operand_value, @operand_length);
|
||||||
|
|
||||||
(* condition_label is the label in front of the next elsif condition or end. *)
|
(* condition_label is the label in front of the next elsif condition or end. *)
|
||||||
condition_label := label_counter;
|
condition_label := label_counter;
|
||||||
@@ -2772,7 +2842,7 @@ begin
|
|||||||
|
|
||||||
elna_instruction_list_concatenate(first_instruction, current_instruction);
|
elna_instruction_list_concatenate(first_instruction, current_instruction);
|
||||||
|
|
||||||
instruction := _elna_tac_statements(parser_node^.statements, symbol_table);
|
instruction := elna_tac_statements(parser_node^.statements, symbol_table);
|
||||||
if instruction <> 0 then
|
if instruction <> 0 then
|
||||||
elna_instruction_list_concatenate(current_instruction, instruction);
|
elna_instruction_list_concatenate(current_instruction, instruction);
|
||||||
current_instruction := instruction
|
current_instruction := instruction
|
||||||
@@ -2782,7 +2852,7 @@ begin
|
|||||||
_elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.symbol, after_end_label, 0);
|
_elna_tac_instruction_set_operand(instruction, 1, ElnaTacOperand.symbol, after_end_label, 0);
|
||||||
elna_instruction_list_concatenate(current_instruction, instruction);
|
elna_instruction_list_concatenate(current_instruction, instruction);
|
||||||
|
|
||||||
current_instruction := _elna_tac_label(condition_label, 0);
|
current_instruction := elna_tac_label(condition_label, 0);
|
||||||
elna_instruction_list_concatenate(instruction, current_instruction);
|
elna_instruction_list_concatenate(instruction, current_instruction);
|
||||||
|
|
||||||
return first_instruction
|
return first_instruction
|
||||||
@@ -2884,7 +2954,7 @@ begin
|
|||||||
return first_statement
|
return first_statement
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc _elna_tac_statements(parser_node: Word, symbol_table: Word);
|
proc elna_tac_statements(parser_node: Word, symbol_table: Word);
|
||||||
var
|
var
|
||||||
current_statement: ^ElnaTreeStatement;
|
current_statement: ^ElnaTreeStatement;
|
||||||
instruction: Word;
|
instruction: Word;
|
||||||
@@ -2896,7 +2966,7 @@ begin
|
|||||||
|
|
||||||
.elna_tac_statements_loop;
|
.elna_tac_statements_loop;
|
||||||
if current_statement <> nil then
|
if current_statement <> nil then
|
||||||
instruction := _elna_tac_statement(current_statement, symbol_table);
|
instruction := elna_tac_statement(current_statement, symbol_table);
|
||||||
current_statement := current_statement^.next;
|
current_statement := current_statement^.next;
|
||||||
if instruction = 0 then
|
if instruction = 0 then
|
||||||
goto elna_tac_statements_loop
|
goto elna_tac_statements_loop
|
||||||
@@ -2912,7 +2982,7 @@ begin
|
|||||||
return first_instruction
|
return first_instruction
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc _elna_tac_if_statement(parser_node: ^ElnaTreeIfStatement, symbol_table: Word);
|
proc elna_tac_if_statement(parser_node: ^ElnaTreeIfStatement, symbol_table: Word);
|
||||||
var
|
var
|
||||||
current_node: ^ElnaTreeConditionalStatements;
|
current_node: ^ElnaTreeConditionalStatements;
|
||||||
after_end_label: Word;
|
after_end_label: Word;
|
||||||
@@ -2925,13 +2995,13 @@ begin
|
|||||||
label_counter := label_counter + 1;
|
label_counter := label_counter + 1;
|
||||||
|
|
||||||
current_node := parser_node^.conditionals;
|
current_node := parser_node^.conditionals;
|
||||||
first_instruction := _elna_tac_conditional_statements(current_node, after_end_label, symbol_table);
|
first_instruction := elna_tac_conditional_statements(current_node, after_end_label, symbol_table);
|
||||||
current_instruction := first_instruction;
|
current_instruction := first_instruction;
|
||||||
|
|
||||||
.elna_tac_if_statement_loop;
|
.elna_tac_if_statement_loop;
|
||||||
current_node := current_node^.next;
|
current_node := current_node^.next;
|
||||||
if current_node <> nil then
|
if current_node <> nil then
|
||||||
instruction := _elna_tac_conditional_statements(current_node, after_end_label, symbol_table);
|
instruction := elna_tac_conditional_statements(current_node, after_end_label, symbol_table);
|
||||||
elna_instruction_list_concatenate(current_instruction, instruction);
|
elna_instruction_list_concatenate(current_instruction, instruction);
|
||||||
current_instruction := instruction;
|
current_instruction := instruction;
|
||||||
goto elna_tac_if_statement_loop
|
goto elna_tac_if_statement_loop
|
||||||
@@ -2939,34 +3009,34 @@ begin
|
|||||||
current_node := parser_node^._else;
|
current_node := parser_node^._else;
|
||||||
|
|
||||||
if parser_node^._else <> nil then
|
if parser_node^._else <> nil then
|
||||||
instruction := _elna_tac_statements(parser_node^._else, symbol_table);
|
instruction := elna_tac_statements(parser_node^._else, symbol_table);
|
||||||
if instruction <> 0 then
|
if instruction <> 0 then
|
||||||
elna_instruction_list_concatenate(current_instruction, instruction);
|
elna_instruction_list_concatenate(current_instruction, instruction);
|
||||||
current_instruction := instruction
|
current_instruction := instruction
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
instruction := _elna_tac_label(after_end_label, 0);
|
instruction := elna_tac_label(after_end_label, 0);
|
||||||
elna_instruction_list_concatenate(current_instruction, instruction);
|
elna_instruction_list_concatenate(current_instruction, instruction);
|
||||||
|
|
||||||
return first_instruction
|
return first_instruction
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc _elna_tac_statement(parser_node: ^ElnaTreeNode, symbol_table: Word);
|
proc elna_tac_statement(parser_node: ^ElnaTreeNode, symbol_table: Word);
|
||||||
var
|
var
|
||||||
instruction: Word;
|
instruction: Word;
|
||||||
begin
|
begin
|
||||||
if parser_node^.kind = ElnaTreeKind.goto_statement then
|
if parser_node^.kind = ElnaTreeKind.goto_statement then
|
||||||
instruction := _elna_tac_goto_statement(parser_node)
|
instruction := elna_tac_goto_statement(parser_node)
|
||||||
elsif parser_node^.kind = ElnaTreeKind.if_statement then
|
elsif parser_node^.kind = ElnaTreeKind.if_statement then
|
||||||
instruction := _elna_tac_if_statement(parser_node, symbol_table)
|
instruction := elna_tac_if_statement(parser_node, symbol_table)
|
||||||
elsif parser_node^.kind = ElnaTreeKind.return_statement then
|
elsif parser_node^.kind = ElnaTreeKind.return_statement then
|
||||||
instruction := _elna_tac_return_statement(parser_node, symbol_table)
|
instruction := elna_tac_return_statement(parser_node, symbol_table)
|
||||||
elsif parser_node^.kind = ElnaTreeKind.label_declaration then
|
elsif parser_node^.kind = ElnaTreeKind.label_declaration then
|
||||||
instruction := _elna_tac_label_declaration(parser_node)
|
instruction := elna_tac_label_declaration(parser_node)
|
||||||
elsif parser_node^.kind = ElnaTreeKind.call then
|
elsif parser_node^.kind = ElnaTreeKind.call then
|
||||||
instruction := _elna_tac_call(parser_node, symbol_table)
|
instruction := elna_tac_call(parser_node, symbol_table)
|
||||||
elsif parser_node^.kind = ElnaTreeKind.assign_statement then
|
elsif parser_node^.kind = ElnaTreeKind.assign_statement then
|
||||||
instruction := _elna_tac_assign_statement(parser_node, symbol_table)
|
instruction := elna_tac_assign_statement(parser_node, symbol_table)
|
||||||
else
|
else
|
||||||
instruction := nil
|
instruction := nil
|
||||||
end;
|
end;
|
||||||
@@ -3495,7 +3565,7 @@ begin
|
|||||||
return result
|
return result
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc _elna_tac_parameters(ast_list: ^ElnaTreeDeclaration, parameter_count: ^Word);
|
proc elna_tac_parameters(ast_list: ^ElnaTreeDeclaration, parameter_count: ^Word);
|
||||||
var
|
var
|
||||||
ast_parameter: ^ElnaTreeDeclaration;
|
ast_parameter: ^ElnaTreeDeclaration;
|
||||||
parameter_index: Word;
|
parameter_index: Word;
|
||||||
@@ -3605,7 +3675,7 @@ begin
|
|||||||
return result
|
return result
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc _elna_tac_procedure_declaration(parser_node: ElnaTreeProcedureDeclaration);
|
proc elna_tac_procedure_declaration(parser_node: ElnaTreeProcedureDeclaration);
|
||||||
var
|
var
|
||||||
symbol_info: ^ElnaSymbolProcedureInfo;
|
symbol_info: ^ElnaSymbolProcedureInfo;
|
||||||
result: ^ElnaInstructionDeclaration;
|
result: ^ElnaInstructionDeclaration;
|
||||||
@@ -3621,9 +3691,9 @@ begin
|
|||||||
|
|
||||||
symbol_info := _symbol_table_lookup(@symbol_table_global, parser_node^.name, parser_node^.length);
|
symbol_info := _symbol_table_lookup(@symbol_table_global, parser_node^.name, parser_node^.length);
|
||||||
|
|
||||||
result^.parameters := _elna_tac_parameters(parser_node^.parameters, @parameter_count);
|
result^.parameters := elna_tac_parameters(parser_node^.parameters, @parameter_count);
|
||||||
result^.count := parameter_count;
|
result^.count := parameter_count;
|
||||||
result^.body := _elna_tac_statements(parser_node^.body, symbol_info^.symbol_table);
|
result^.body := elna_tac_statements(parser_node^.body, symbol_info^.symbol_table);
|
||||||
|
|
||||||
return result
|
return result
|
||||||
end;
|
end;
|
||||||
@@ -3715,7 +3785,7 @@ begin
|
|||||||
return first_copy
|
return first_copy
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc _elna_tac_procedures(parser_node: ^ElnaTreeDeclaration);
|
proc elna_tac_procedures(parser_node: ^ElnaTreeDeclaration);
|
||||||
var
|
var
|
||||||
result: Word;
|
result: Word;
|
||||||
current_procedure: ^ElnaInstructionList;
|
current_procedure: ^ElnaInstructionList;
|
||||||
@@ -3727,7 +3797,7 @@ begin
|
|||||||
if parser_node = 0 then
|
if parser_node = 0 then
|
||||||
goto elna_tac_procedures_end
|
goto elna_tac_procedures_end
|
||||||
end;
|
end;
|
||||||
result := _elna_tac_procedure_declaration(parser_node);
|
result := elna_tac_procedure_declaration(parser_node);
|
||||||
if first_procedure = nil then
|
if first_procedure = nil then
|
||||||
first_procedure := result
|
first_procedure := result
|
||||||
else
|
else
|
||||||
@@ -3874,7 +3944,7 @@ begin
|
|||||||
return result
|
return result
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc _elna_tac_variable_declaration(parser_tree: ^ElnaTreeVariableDeclaration);
|
proc elna_tac_variable_declaration(parser_tree: ^ElnaTreeVariableDeclaration);
|
||||||
var
|
var
|
||||||
name: Word;
|
name: Word;
|
||||||
name_length: Word;
|
name_length: Word;
|
||||||
@@ -3904,7 +3974,7 @@ begin
|
|||||||
return result
|
return result
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc _elna_tac_type_record(name_pointer: Word, name_length: Word, type_representation: ^ElnaTypeRecord, current_result: Word);
|
proc elna_tac_type_record(name_pointer: Word, name_length: Word, type_representation: ^ElnaTypeRecord, current_result: Word);
|
||||||
var
|
var
|
||||||
result: ^ElnaInstructionDeclaration;
|
result: ^ElnaInstructionDeclaration;
|
||||||
instruction: Word;
|
instruction: Word;
|
||||||
@@ -3934,7 +4004,7 @@ begin
|
|||||||
return result
|
return result
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc _elna_tac_type_part(parser_node: ^ElnaTreeDeclaration);
|
proc elna_tac_type_part(parser_node: ^ElnaTreeDeclaration);
|
||||||
var
|
var
|
||||||
result: Word;
|
result: Word;
|
||||||
first_result: Word;
|
first_result: Word;
|
||||||
@@ -3956,7 +4026,7 @@ begin
|
|||||||
type_kind := info_type^.kind;
|
type_kind := info_type^.kind;
|
||||||
|
|
||||||
if type_kind = ElnaTypeKind._record then
|
if type_kind = ElnaTypeKind._record then
|
||||||
result := _elna_tac_type_record(parser_node^.name, parser_node^.length, info_type, @out_result)
|
result := elna_tac_type_record(parser_node^.name, parser_node^.length, info_type, @out_result)
|
||||||
else
|
else
|
||||||
result := 0;
|
result := 0;
|
||||||
out_result := 0
|
out_result := 0
|
||||||
@@ -4015,7 +4085,7 @@ begin
|
|||||||
return result
|
return result
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc _elna_tac_var_part(parser_node: ^ElnaTreeDeclaration);
|
proc elna_tac_var_part(parser_node: ^ElnaTreeDeclaration);
|
||||||
var
|
var
|
||||||
node: Word;
|
node: Word;
|
||||||
current_variable: ^ElnaInstructionList;
|
current_variable: ^ElnaInstructionList;
|
||||||
@@ -4027,7 +4097,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
.elna_tac_var_part_loop;
|
.elna_tac_var_part_loop;
|
||||||
node := _elna_tac_variable_declaration(parser_node);
|
node := elna_tac_variable_declaration(parser_node);
|
||||||
if first_variable = 0 then
|
if first_variable = 0 then
|
||||||
first_variable := node
|
first_variable := node
|
||||||
else
|
else
|
||||||
@@ -4079,7 +4149,7 @@ end;
|
|||||||
(**
|
(**
|
||||||
* Process the source code and print the generated code.
|
* Process the source code and print the generated code.
|
||||||
*)
|
*)
|
||||||
proc _elna_tac_module_declaration(parser_node: ^ElnaTreeModuleDeclaration);
|
proc elna_tac_module_declaration(parser_node: ^ElnaTreeModuleDeclaration);
|
||||||
var
|
var
|
||||||
data_part: Word;
|
data_part: Word;
|
||||||
code_part: Word;
|
code_part: Word;
|
||||||
@@ -4087,9 +4157,9 @@ var
|
|||||||
current_declaration: ^ElnaInstructionList;
|
current_declaration: ^ElnaInstructionList;
|
||||||
next_declaration: Word;
|
next_declaration: Word;
|
||||||
begin
|
begin
|
||||||
type_part := _elna_tac_type_part(parser_node^.types);
|
type_part := elna_tac_type_part(parser_node^.types);
|
||||||
data_part := _elna_tac_var_part(parser_node^.globals);
|
data_part := elna_tac_var_part(parser_node^.globals);
|
||||||
code_part := _elna_tac_procedures(parser_node^.procedures);
|
code_part := elna_tac_procedures(parser_node^.procedures);
|
||||||
|
|
||||||
current_declaration := code_part;
|
current_declaration := code_part;
|
||||||
|
|
||||||
@@ -4466,10 +4536,10 @@ begin
|
|||||||
if compiled then
|
if compiled then
|
||||||
elna_name_module_declaration(parser_node);
|
elna_name_module_declaration(parser_node);
|
||||||
elna_type_module_declaration(parser_node);
|
elna_type_module_declaration(parser_node);
|
||||||
tac := _elna_tac_module_declaration(parser_node);
|
tac := elna_tac_module_declaration(parser_node);
|
||||||
rtl := elna_rtl_module_declaration(tac);
|
rtl := elna_rtl_module_declaration(tac);
|
||||||
elna_alloc_module(rtl);
|
elna_alloc_module(rtl);
|
||||||
_elna_writer_module(rtl);
|
elna_riscv_module(rtl);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
return compiled
|
return compiled
|
||||||
|
|||||||
Reference in New Issue
Block a user