Allow compound types on the stack
This commit is contained in:
@@ -7,6 +7,8 @@ program;
|
|||||||
|
|
||||||
(* Stage 19 compiler. *)
|
(* Stage 19 compiler. *)
|
||||||
|
|
||||||
|
(* - Aggregates can be allocated on the stack. *)
|
||||||
|
|
||||||
type
|
type
|
||||||
(**
|
(**
|
||||||
* List of intermediate representation items.
|
* List of intermediate representation items.
|
||||||
@@ -18,14 +20,6 @@ type
|
|||||||
data: Word;
|
data: Word;
|
||||||
code: Word
|
code: Word
|
||||||
end;
|
end;
|
||||||
ElnaInstructionDeclaration = record
|
|
||||||
next: Word;
|
|
||||||
name: Word;
|
|
||||||
length: Word;
|
|
||||||
body: Word;
|
|
||||||
parameters: Word;
|
|
||||||
count: Word
|
|
||||||
end;
|
|
||||||
|
|
||||||
(* Type representation. *)
|
(* Type representation. *)
|
||||||
ElnaTypeKind = (primitive, enumeration, _record, pointer, array);
|
ElnaTypeKind = (primitive, enumeration, _record, pointer, array);
|
||||||
@@ -540,6 +534,19 @@ type
|
|||||||
value: Word;
|
value: Word;
|
||||||
length: Word
|
length: Word
|
||||||
end;
|
end;
|
||||||
|
ElnaRtlStaticVariable = record
|
||||||
|
next: Word;
|
||||||
|
name: Word;
|
||||||
|
length: Word;
|
||||||
|
body: Word
|
||||||
|
end;
|
||||||
|
ElnaRtlProcedure = record
|
||||||
|
next: Word;
|
||||||
|
name: Word;
|
||||||
|
length: Word;
|
||||||
|
body: Word;
|
||||||
|
variable_map: ^ElnaSymbolTable
|
||||||
|
end;
|
||||||
ElnaRtlInstruction = record
|
ElnaRtlInstruction = record
|
||||||
next: Word;
|
next: Word;
|
||||||
operator: ElnaRtlOperator;
|
operator: ElnaRtlOperator;
|
||||||
@@ -579,13 +586,27 @@ type
|
|||||||
t5,
|
t5,
|
||||||
t6
|
t6
|
||||||
);
|
);
|
||||||
|
ElnaRtlTypeKind = (long_word, byte_array);
|
||||||
|
ElnaRtlType = record
|
||||||
|
kind: ElnaRtlTypeKind;
|
||||||
|
size: Word
|
||||||
|
end;
|
||||||
|
ElnaRtlTypeWord = record
|
||||||
|
kind: ElnaRtlTypeKind;
|
||||||
|
size: Word
|
||||||
|
end;
|
||||||
|
ElnaRtlTypeByteArray = record
|
||||||
|
kind: ElnaRtlTypeKind;
|
||||||
|
size: Word
|
||||||
|
end;
|
||||||
ElnaRtlInfo = record
|
ElnaRtlInfo = record
|
||||||
counter: Word
|
counter: Word;
|
||||||
|
rtl_type: ^ElnaRtlType;
|
||||||
|
allocated: Word
|
||||||
end;
|
end;
|
||||||
|
|
||||||
var
|
var
|
||||||
symbol_table_global: [1024]Word;
|
symbol_table_global: [1024]Word;
|
||||||
variable_map: [1024]Word;
|
|
||||||
compiler_strings: [1024]Word;
|
compiler_strings: [1024]Word;
|
||||||
|
|
||||||
classification: [256]Word;
|
classification: [256]Word;
|
||||||
@@ -1232,18 +1253,6 @@ begin
|
|||||||
return result
|
return result
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc elna_instruction_module_create(data: Word, code: Word);
|
|
||||||
var
|
|
||||||
result: ^ElnaInstructionModule;
|
|
||||||
begin
|
|
||||||
result := malloc(#size(ElnaInstructionModule));
|
|
||||||
|
|
||||||
result^.data := data;
|
|
||||||
result^.code := code;
|
|
||||||
|
|
||||||
return result
|
|
||||||
end;
|
|
||||||
|
|
||||||
proc elna_tac_label(counter: Word, length: Word);
|
proc elna_tac_label(counter: Word, length: Word);
|
||||||
var
|
var
|
||||||
result: Word;
|
result: Word;
|
||||||
@@ -1368,17 +1377,16 @@ begin
|
|||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc elna_alloc_variable(operand_value: Word, operand_length: Word);
|
proc elna_alloc_variable(operand_value: Word, operand_length: Word, variable_map: ^ElnaSymbolTable);
|
||||||
var
|
var
|
||||||
pseudo_symbol: ^ElnaRtlInfo;
|
pseudo_symbol: ^ElnaRtlInfo;
|
||||||
begin
|
begin
|
||||||
pseudo_symbol := elna_symbol_table_lookup(@variable_map, operand_value, operand_length);
|
pseudo_symbol := elna_symbol_table_lookup(variable_map, operand_value, operand_length);
|
||||||
if pseudo_symbol = nil then
|
if pseudo_symbol^.allocated = false then
|
||||||
pseudo_symbol := malloc(#size(ElnaRtlInfo));
|
pseudo_symbol^.allocated := true;
|
||||||
pseudo_symbol^.counter := temporary_variable_counter;
|
pseudo_symbol^.counter := temporary_variable_counter;
|
||||||
|
|
||||||
elna_symbol_table_enter(@variable_map, operand_value, operand_length, pseudo_symbol);
|
temporary_variable_counter := temporary_variable_counter + pseudo_symbol^.rtl_type^.size
|
||||||
temporary_variable_counter := temporary_variable_counter + 4
|
|
||||||
end;
|
end;
|
||||||
return pseudo_symbol
|
return pseudo_symbol
|
||||||
end;
|
end;
|
||||||
@@ -1388,7 +1396,7 @@ end;
|
|||||||
* to be a register, but is not a register, then this procedure rewrites it
|
* 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.
|
* to a temporary register and preserves its value in the following instruction.
|
||||||
*)
|
*)
|
||||||
proc elna_alloc_operation_target(instruction: ^ElnaRtlInstruction);
|
proc elna_alloc_operation_target(instruction: ^ElnaRtlInstruction, variable_map: ^ElnaSymbolTable);
|
||||||
var
|
var
|
||||||
pseudo_symbol: ^ElnaRtlInfo;
|
pseudo_symbol: ^ElnaRtlInfo;
|
||||||
store_instruction: ^ElnaRtlInstruction;
|
store_instruction: ^ElnaRtlInstruction;
|
||||||
@@ -1397,7 +1405,8 @@ begin
|
|||||||
store_instruction := elna_rtl_instruction_create(ElnaRtlOperator.sw);
|
store_instruction := elna_rtl_instruction_create(ElnaRtlOperator.sw);
|
||||||
store_instruction^.next := instruction^.next;
|
store_instruction^.next := instruction^.next;
|
||||||
|
|
||||||
pseudo_symbol := elna_alloc_variable(instruction^.operands[1].value, instruction^.operands[1].length);
|
pseudo_symbol := elna_alloc_variable(instruction^.operands[1].value, instruction^.operands[1].length,
|
||||||
|
variable_map);
|
||||||
elna_rtl_instruction_set_operand(store_instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.t0, 0);
|
elna_rtl_instruction_set_operand(store_instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.t0, 0);
|
||||||
elna_rtl_instruction_set_operand(store_instruction, 2, ElnaRtlKind.offset, ElnaRtlRegister.sp, pseudo_symbol^.counter);
|
elna_rtl_instruction_set_operand(store_instruction, 2, ElnaRtlKind.offset, ElnaRtlRegister.sp, pseudo_symbol^.counter);
|
||||||
|
|
||||||
@@ -1406,23 +1415,24 @@ begin
|
|||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc elna_alloc_load_address(instruction: ^ElnaRtlInstruction);
|
proc elna_alloc_load_address(instruction: ^ElnaRtlInstruction, variable_map: ^ElnaSymbolTable);
|
||||||
var
|
var
|
||||||
pseudo_symbol: ^ElnaRtlInfo;
|
pseudo_symbol: ^ElnaRtlInfo;
|
||||||
begin
|
begin
|
||||||
if instruction^.operands[2].kind = ElnaRtlKind.pseudo then
|
if instruction^.operands[2].kind = ElnaRtlKind.pseudo then
|
||||||
pseudo_symbol := elna_alloc_variable(instruction^.operands[2].value, instruction^.operands[2].length);
|
pseudo_symbol := elna_alloc_variable(instruction^.operands[2].value, instruction^.operands[2].length,
|
||||||
|
variable_map);
|
||||||
instruction^.operator := ElnaRtlOperator.addi;
|
instruction^.operator := ElnaRtlOperator.addi;
|
||||||
|
|
||||||
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.register, ElnaRtlRegister.sp, 0);
|
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.register, ElnaRtlRegister.sp, 0);
|
||||||
elna_rtl_instruction_set_operand(instruction, 3, ElnaRtlKind.immediate, pseudo_symbol^.counter, 0)
|
elna_rtl_instruction_set_operand(instruction, 3, ElnaRtlKind.immediate, pseudo_symbol^.counter, 0)
|
||||||
end;
|
end;
|
||||||
if instruction^.operands[1].kind = ElnaRtlKind.pseudo then
|
if instruction^.operands[1].kind = ElnaRtlKind.pseudo then
|
||||||
elna_alloc_operation_target(instruction)
|
elna_alloc_operation_target(instruction, variable_map)
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc elna_alloc_store(instruction: ^ElnaRtlInstruction);
|
proc elna_alloc_store(instruction: ^ElnaRtlInstruction, variable_map: ^ElnaSymbolTable);
|
||||||
var
|
var
|
||||||
old_instruction: ^ElnaRtlInstruction;
|
old_instruction: ^ElnaRtlInstruction;
|
||||||
pseudo_symbol: ^ElnaRtlInfo;
|
pseudo_symbol: ^ElnaRtlInfo;
|
||||||
@@ -1431,7 +1441,8 @@ begin
|
|||||||
old_instruction := malloc(#size(ElnaRtlInstruction));
|
old_instruction := malloc(#size(ElnaRtlInstruction));
|
||||||
memcpy(old_instruction, instruction, #size(ElnaRtlInstruction));
|
memcpy(old_instruction, instruction, #size(ElnaRtlInstruction));
|
||||||
|
|
||||||
pseudo_symbol := elna_alloc_variable(instruction^.operands[2].value, instruction^.operands[2].length);
|
pseudo_symbol := elna_alloc_variable(instruction^.operands[2].value, instruction^.operands[2].length,
|
||||||
|
variable_map);
|
||||||
instruction^.operator := ElnaRtlOperator.lw;
|
instruction^.operator := ElnaRtlOperator.lw;
|
||||||
|
|
||||||
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.t1, 0);
|
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.t1, 0);
|
||||||
@@ -1442,7 +1453,7 @@ begin
|
|||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc elna_alloc_load(instruction: ^ElnaRtlInstruction);
|
proc elna_alloc_load(instruction: ^ElnaRtlInstruction, variable_map: ^ElnaSymbolTable);
|
||||||
var
|
var
|
||||||
old_instruction: ^ElnaRtlInstruction;
|
old_instruction: ^ElnaRtlInstruction;
|
||||||
pseudo_symbol: ^ElnaRtlInfo;
|
pseudo_symbol: ^ElnaRtlInfo;
|
||||||
@@ -1451,7 +1462,8 @@ begin
|
|||||||
old_instruction := malloc(#size(ElnaRtlInstruction));
|
old_instruction := malloc(#size(ElnaRtlInstruction));
|
||||||
memcpy(old_instruction, instruction, #size(ElnaRtlInstruction));
|
memcpy(old_instruction, instruction, #size(ElnaRtlInstruction));
|
||||||
|
|
||||||
pseudo_symbol := elna_alloc_variable(instruction^.operands[1].value, instruction^.operands[1].length);
|
pseudo_symbol := elna_alloc_variable(instruction^.operands[1].value, instruction^.operands[1].length,
|
||||||
|
variable_map);
|
||||||
old_instruction^.operator := ElnaRtlOperator.sw;
|
old_instruction^.operator := ElnaRtlOperator.sw;
|
||||||
|
|
||||||
elna_rtl_instruction_set_operand(old_instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.t1, 0);
|
elna_rtl_instruction_set_operand(old_instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.t1, 0);
|
||||||
@@ -1462,14 +1474,15 @@ begin
|
|||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc elna_alloc_instruction(instruction: ^ElnaRtlInstruction);
|
proc elna_alloc_instruction(instruction: ^ElnaRtlInstruction, variable_map: ^ElnaSymbolTable);
|
||||||
var
|
var
|
||||||
pseudo_symbol: ^ElnaRtlInfo;
|
pseudo_symbol: ^ElnaRtlInfo;
|
||||||
old_instruction: ^ElnaRtlInstruction;
|
old_instruction: ^ElnaRtlInstruction;
|
||||||
begin
|
begin
|
||||||
if instruction^.operator = ElnaRtlOperator.move then
|
if instruction^.operator = ElnaRtlOperator.move then
|
||||||
if instruction^.operands[1].kind = ElnaRtlKind.pseudo then
|
if instruction^.operands[1].kind = ElnaRtlKind.pseudo then
|
||||||
pseudo_symbol := elna_alloc_variable(instruction^.operands[1].value, instruction^.operands[1].length);
|
pseudo_symbol := elna_alloc_variable(instruction^.operands[1].value, instruction^.operands[1].length,
|
||||||
|
variable_map);
|
||||||
instruction^.operator = ElnaRtlOperator.sw;
|
instruction^.operator = ElnaRtlOperator.sw;
|
||||||
|
|
||||||
instruction^.operands[1].kind := instruction^.operands[2].kind;
|
instruction^.operands[1].kind := instruction^.operands[2].kind;
|
||||||
@@ -1480,40 +1493,42 @@ begin
|
|||||||
goto elna_alloc_instruction_end
|
goto elna_alloc_instruction_end
|
||||||
end;
|
end;
|
||||||
if instruction^.operands[2].kind = ElnaRtlKind.pseudo then
|
if instruction^.operands[2].kind = ElnaRtlKind.pseudo then
|
||||||
pseudo_symbol := elna_alloc_variable(instruction^.operands[2].value, instruction^.operands[2].length);
|
pseudo_symbol := elna_alloc_variable(instruction^.operands[2].value, instruction^.operands[2].length,
|
||||||
|
variable_map);
|
||||||
instruction^.operator = ElnaRtlOperator.lw;
|
instruction^.operator = ElnaRtlOperator.lw;
|
||||||
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.offset, ElnaRtlRegister.sp, pseudo_symbol^.counter);
|
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.offset, ElnaRtlRegister.sp, pseudo_symbol^.counter);
|
||||||
|
|
||||||
goto elna_alloc_instruction_end
|
goto elna_alloc_instruction_end
|
||||||
end
|
end
|
||||||
elsif instruction^.operator = ElnaRtlOperator.la then
|
elsif instruction^.operator = ElnaRtlOperator.la then
|
||||||
elna_alloc_load_address(instruction)
|
elna_alloc_load_address(instruction, variable_map)
|
||||||
elsif instruction^.operator = ElnaRtlOperator.lw then
|
elsif instruction^.operator = ElnaRtlOperator.lw then
|
||||||
elna_alloc_load(instruction)
|
elna_alloc_load(instruction, variable_map)
|
||||||
elsif instruction^.operator = ElnaRtlOperator.sw then
|
elsif instruction^.operator = ElnaRtlOperator.sw then
|
||||||
elna_alloc_store(instruction)
|
elna_alloc_store(instruction, variable_map)
|
||||||
elsif instruction^.operator = ElnaRtlOperator._or then
|
elsif instruction^.operator = ElnaRtlOperator._or then
|
||||||
elna_alloc_operation_target(instruction)
|
elna_alloc_operation_target(instruction, variable_map)
|
||||||
elsif instruction^.operator = ElnaRtlOperator.and then
|
elsif instruction^.operator = ElnaRtlOperator.and then
|
||||||
elna_alloc_operation_target(instruction)
|
elna_alloc_operation_target(instruction, variable_map)
|
||||||
elsif instruction^.operator = ElnaRtlOperator.mul then
|
elsif instruction^.operator = ElnaRtlOperator.mul then
|
||||||
elna_alloc_operation_target(instruction)
|
elna_alloc_operation_target(instruction, variable_map)
|
||||||
elsif instruction^.operator = ElnaRtlOperator.sub then
|
elsif instruction^.operator = ElnaRtlOperator.sub then
|
||||||
elna_alloc_operation_target(instruction)
|
elna_alloc_operation_target(instruction, variable_map)
|
||||||
elsif instruction^.operator = ElnaRtlOperator.add then
|
elsif instruction^.operator = ElnaRtlOperator.add then
|
||||||
elna_alloc_operation_target(instruction)
|
elna_alloc_operation_target(instruction, variable_map)
|
||||||
elsif instruction^.operator = ElnaRtlOperator._xor then
|
elsif instruction^.operator = ElnaRtlOperator._xor then
|
||||||
elna_alloc_operation_target(instruction)
|
elna_alloc_operation_target(instruction, variable_map)
|
||||||
elsif instruction^.operator = ElnaRtlOperator.rem then
|
elsif instruction^.operator = ElnaRtlOperator.rem then
|
||||||
elna_alloc_operation_target(instruction)
|
elna_alloc_operation_target(instruction, variable_map)
|
||||||
elsif instruction^.operator = ElnaRtlOperator.slt then
|
elsif instruction^.operator = ElnaRtlOperator.slt then
|
||||||
elna_alloc_operation_target(instruction)
|
elna_alloc_operation_target(instruction, variable_map)
|
||||||
elsif instruction^.operator = ElnaRtlOperator.beqz then
|
elsif instruction^.operator = ElnaRtlOperator.beqz then
|
||||||
if instruction^.operands[1].kind = ElnaRtlKind.pseudo then
|
if instruction^.operands[1].kind = ElnaRtlKind.pseudo then
|
||||||
old_instruction := malloc(#size(ElnaRtlInstruction));
|
old_instruction := malloc(#size(ElnaRtlInstruction));
|
||||||
memcpy(old_instruction, instruction, #size(ElnaRtlInstruction));
|
memcpy(old_instruction, instruction, #size(ElnaRtlInstruction));
|
||||||
|
|
||||||
pseudo_symbol := elna_alloc_variable(instruction^.operands[1].value, instruction^.operands[1].length);
|
pseudo_symbol := elna_alloc_variable(instruction^.operands[1].value, instruction^.operands[1].length,
|
||||||
|
variable_map);
|
||||||
instruction^.operator := ElnaRtlOperator.lw;
|
instruction^.operator := ElnaRtlOperator.lw;
|
||||||
|
|
||||||
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.t0, 0);
|
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.register, ElnaRtlRegister.t0, 0);
|
||||||
@@ -1525,11 +1540,11 @@ begin
|
|||||||
goto elna_alloc_instruction_end
|
goto elna_alloc_instruction_end
|
||||||
end
|
end
|
||||||
elsif instruction^.operator = ElnaRtlOperator.seqz then
|
elsif instruction^.operator = ElnaRtlOperator.seqz then
|
||||||
elna_alloc_operation_target(instruction)
|
elna_alloc_operation_target(instruction, variable_map)
|
||||||
elsif instruction^.operator = ElnaRtlOperator.snez then
|
elsif instruction^.operator = ElnaRtlOperator.snez then
|
||||||
elna_alloc_operation_target(instruction)
|
elna_alloc_operation_target(instruction, variable_map)
|
||||||
elsif instruction^.operator = ElnaRtlOperator.xori then
|
elsif instruction^.operator = ElnaRtlOperator.xori then
|
||||||
elna_alloc_operation_target(instruction)
|
elna_alloc_operation_target(instruction, variable_map)
|
||||||
end;
|
end;
|
||||||
.elna_alloc_instruction_end;
|
.elna_alloc_instruction_end;
|
||||||
end;
|
end;
|
||||||
@@ -1604,12 +1619,12 @@ begin
|
|||||||
return first_copy
|
return first_copy
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc elna_alloc_instructions(instruction: ^ElnaRtlInstruction);
|
proc elna_alloc_instructions(instruction: ^ElnaRtlInstruction, variable_map: ^ElnaSymbolTable);
|
||||||
begin
|
begin
|
||||||
.elna_alloc_instructions_start;
|
.elna_alloc_instructions_start;
|
||||||
|
|
||||||
if instruction <> nil then
|
if instruction <> nil then
|
||||||
elna_alloc_instruction(instruction);
|
elna_alloc_instruction(instruction, variable_map);
|
||||||
instruction := instruction^.next;
|
instruction := instruction^.next;
|
||||||
goto elna_alloc_instructions_start
|
goto elna_alloc_instructions_start
|
||||||
end
|
end
|
||||||
@@ -1625,15 +1640,14 @@ begin
|
|||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc elna_alloc_procedure(rtl_declaration: ^ElnaInstructionDeclaration);
|
proc elna_alloc_procedure(rtl_declaration: ^ElnaRtlProcedure);
|
||||||
var
|
var
|
||||||
stack_instruction: ^ElnaRtlInstruction;
|
stack_instruction: ^ElnaRtlInstruction;
|
||||||
begin
|
begin
|
||||||
.elna_alloc_procedure_loop;
|
.elna_alloc_procedure_loop;
|
||||||
temporary_variable_counter := 0;
|
temporary_variable_counter := 0;
|
||||||
variable_map := 0;
|
|
||||||
|
|
||||||
elna_alloc_instructions(rtl_declaration^.body);
|
elna_alloc_instructions(rtl_declaration^.body, rtl_declaration^.variable_map);
|
||||||
|
|
||||||
stack_instruction := elna_rtl_instruction_create(ElnaRtlOperator.allocate_stack);
|
stack_instruction := elna_rtl_instruction_create(ElnaRtlOperator.allocate_stack);
|
||||||
stack_instruction^.next := rtl_declaration^.body;
|
stack_instruction^.next := rtl_declaration^.body;
|
||||||
@@ -1651,7 +1665,7 @@ begin
|
|||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc elna_riscv_procedure(procedure: ^ElnaInstructionDeclaration);
|
proc elna_riscv_procedure(procedure: ^ElnaRtlProcedure);
|
||||||
begin
|
begin
|
||||||
.elna_riscv_procedure_loop;
|
.elna_riscv_procedure_loop;
|
||||||
|
|
||||||
@@ -1670,7 +1684,7 @@ begin
|
|||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc elna_riscv_variable(variable: ^ElnaInstructionDeclaration);
|
proc elna_riscv_variable(variable: ^ElnaRtlStaticVariable);
|
||||||
begin
|
begin
|
||||||
.elna_riscv_variable_loop;
|
.elna_riscv_variable_loop;
|
||||||
if variable <> 0 then
|
if variable <> 0 then
|
||||||
@@ -1685,13 +1699,13 @@ end;
|
|||||||
|
|
||||||
proc elna_rtl_module_declaration(tac_module: ^ElnaInstructionModule);
|
proc elna_rtl_module_declaration(tac_module: ^ElnaInstructionModule);
|
||||||
var
|
var
|
||||||
code_part: ^ElnaInstructionDeclaration;
|
result: ^ElnaInstructionModule;
|
||||||
data_part: ^ElnaInstructionDeclaration;
|
|
||||||
begin
|
begin
|
||||||
data_part := elna_rtl_globals(tac_module^.data);
|
result := malloc(#size(ElnaInstructionModule));
|
||||||
code_part := elna_rtl_procedures(tac_module^.code);
|
result^.data := elna_rtl_globals(tac_module^.data);
|
||||||
|
result^.code := elna_rtl_procedures(tac_module^.code);
|
||||||
|
|
||||||
return elna_instruction_module_create(data_part, code_part)
|
return result
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc elna_alloc_module(pair: ^ElnaInstructionModule);
|
proc elna_alloc_module(pair: ^ElnaInstructionModule);
|
||||||
@@ -3614,9 +3628,9 @@ end;
|
|||||||
|
|
||||||
proc elna_rtl_global_declaration(tac_declaration: ^ElnaTacStaticVariable);
|
proc elna_rtl_global_declaration(tac_declaration: ^ElnaTacStaticVariable);
|
||||||
var
|
var
|
||||||
result: ^ElnaInstructionDeclaration;
|
result: ^ElnaRtlStaticVariable;
|
||||||
begin
|
begin
|
||||||
result := malloc(#size(ElnaInstructionDeclaration));
|
result := malloc(#size(ElnaRtlStaticVariable));
|
||||||
|
|
||||||
result^.next := nil;
|
result^.next := nil;
|
||||||
result^.name := tac_declaration^.name;
|
result^.name := tac_declaration^.name;
|
||||||
@@ -3663,13 +3677,72 @@ begin
|
|||||||
return result
|
return result
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc elna_rtl_procedure_declaration(tac_declaration: ^ElnaInstructionDeclaration);
|
(* Returns whether the provided type is array or record. *)
|
||||||
|
proc elna_type_is_aggregate(_type: ^ElnaType);
|
||||||
var
|
var
|
||||||
result: ^ElnaInstructionDeclaration;
|
lhs: Word;
|
||||||
|
rhs: Word;
|
||||||
|
begin
|
||||||
|
lhs := _type^.kind = ElnaTypeKind._record;
|
||||||
|
rhs := _type^.kind = ElnaTypeKind.array;
|
||||||
|
|
||||||
|
return lhs or rhs
|
||||||
|
end;
|
||||||
|
|
||||||
|
proc elna_rtl_symbol_table(symbol_table: ^ElnaSymbolTable);
|
||||||
|
var
|
||||||
|
variable_map: ^ElnaSymbolTable;
|
||||||
|
count: Word;
|
||||||
|
current_entry: ^ElnaSymbolEntry;
|
||||||
|
pseudo_symbol: ^ElnaRtlInfo;
|
||||||
|
variable_info: ^ElnaSymbolTemporaryInfo;
|
||||||
|
byte_array: ^ElnaRtlTypeByteArray;
|
||||||
|
long_word: ^ElnaRtlTypeWord;
|
||||||
|
begin
|
||||||
|
variable_map := malloc(16384);
|
||||||
|
variable_map^.count := 0;
|
||||||
|
|
||||||
|
count := symbol_table^.count;
|
||||||
|
current_entry := symbol_table + 4;
|
||||||
|
|
||||||
|
.elna_rtl_symbol_table_loop;
|
||||||
|
if count > 0 then
|
||||||
|
variable_info := current_entry^.symbol_info;
|
||||||
|
|
||||||
|
pseudo_symbol := malloc(#size(ElnaRtlInfo));
|
||||||
|
pseudo_symbol^.allocated := false;
|
||||||
|
|
||||||
|
if elna_type_is_aggregate(variable_info^.variable_type) then
|
||||||
|
long_word := malloc(#size(ElnaRtlTypeWord));
|
||||||
|
long_word^.kind := ElnaRtlTypeKind.long_word;
|
||||||
|
long_word^.size := variable_info^.variable_type^.size;
|
||||||
|
|
||||||
|
pseudo_symbol^.rtl_type = long_word
|
||||||
|
else
|
||||||
|
byte_array := malloc(#size(ElnaRtlTypeByteArray));
|
||||||
|
byte_array^.kind := ElnaRtlTypeKind.byte_array;
|
||||||
|
byte_array^.size := variable_info^.variable_type^.size;
|
||||||
|
|
||||||
|
pseudo_symbol^.rtl_type = byte_array
|
||||||
|
end;
|
||||||
|
elna_symbol_table_enter(variable_map, current_entry^.name, current_entry^.length, pseudo_symbol);
|
||||||
|
|
||||||
|
count := count - 1;
|
||||||
|
current_entry := current_entry + #size(ElnaSymbolEntry);
|
||||||
|
|
||||||
|
goto elna_rtl_symbol_table_loop
|
||||||
|
end;
|
||||||
|
|
||||||
|
return variable_map;
|
||||||
|
end;
|
||||||
|
|
||||||
|
proc elna_rtl_procedure_declaration(tac_declaration: ^ElnaTacProcedure);
|
||||||
|
var
|
||||||
|
result: ^ElnaRtlProcedure;
|
||||||
body: ^ElnaRtlInstruction;
|
body: ^ElnaRtlInstruction;
|
||||||
parameters: ^ElnaRtlInstruction;
|
parameters: ^ElnaRtlInstruction;
|
||||||
begin
|
begin
|
||||||
result := malloc(#size(ElnaInstructionDeclaration));
|
result := malloc(#size(ElnaRtlProcedure));
|
||||||
|
|
||||||
result^.next := nil;
|
result^.next := nil;
|
||||||
result^.name := tac_declaration^.name;
|
result^.name := tac_declaration^.name;
|
||||||
@@ -3678,6 +3751,7 @@ begin
|
|||||||
parameters = elna_rtl_parameters(tac_declaration^.parameters, tac_declaration^.count);
|
parameters = elna_rtl_parameters(tac_declaration^.parameters, tac_declaration^.count);
|
||||||
body := elna_rtl_instructions(tac_declaration^.body);
|
body := elna_rtl_instructions(tac_declaration^.body);
|
||||||
result^.body := elna_instruction_list_concatenate(parameters, body);
|
result^.body := elna_instruction_list_concatenate(parameters, body);
|
||||||
|
result^.variable_map := elna_rtl_symbol_table(tac_declaration^.symbol_table);
|
||||||
|
|
||||||
return result
|
return result
|
||||||
end;
|
end;
|
||||||
@@ -3738,9 +3812,9 @@ end;
|
|||||||
|
|
||||||
proc elna_rtl_globals(tac_procedure: ^ElnaTacStaticVariable);
|
proc elna_rtl_globals(tac_procedure: ^ElnaTacStaticVariable);
|
||||||
var
|
var
|
||||||
current_copy: ^ElnaInstructionDeclaration;
|
current_copy: ^ElnaRtlStaticVariable;
|
||||||
next_copy: ^ElnaInstructionDeclaration;
|
next_copy: ^ElnaRtlStaticVariable;
|
||||||
first_copy: ^ElnaInstructionDeclaration;
|
first_copy: ^ElnaRtlStaticVariable;
|
||||||
begin
|
begin
|
||||||
if tac_procedure <> nil then
|
if tac_procedure <> nil then
|
||||||
first_copy := elna_rtl_global_declaration(tac_procedure);
|
first_copy := elna_rtl_global_declaration(tac_procedure);
|
||||||
@@ -3764,11 +3838,11 @@ begin
|
|||||||
return first_copy
|
return first_copy
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc elna_rtl_procedures(tac_procedure: ^ElnaInstructionDeclaration);
|
proc elna_rtl_procedures(tac_procedure: ^ElnaTacProcedure);
|
||||||
var
|
var
|
||||||
current_copy: ^ElnaInstructionDeclaration;
|
current_copy: ^ElnaRtlProcedure;
|
||||||
next_copy: ^ElnaInstructionDeclaration;
|
next_copy: ^ElnaRtlProcedure;
|
||||||
first_copy: ^ElnaInstructionDeclaration;
|
first_copy: ^ElnaRtlProcedure;
|
||||||
begin
|
begin
|
||||||
if tac_procedure <> nil then
|
if tac_procedure <> nil then
|
||||||
first_copy := elna_rtl_procedure_declaration(tac_procedure);
|
first_copy := elna_rtl_procedure_declaration(tac_procedure);
|
||||||
@@ -3794,9 +3868,9 @@ end;
|
|||||||
|
|
||||||
proc elna_tac_procedures(parser_node: ^ElnaTreeDeclaration);
|
proc elna_tac_procedures(parser_node: ^ElnaTreeDeclaration);
|
||||||
var
|
var
|
||||||
result: ^ElnaInstructionDeclaration;
|
result: ^ElnaTacProcedure;
|
||||||
current_procedure: ^ElnaInstructionDeclaration;
|
current_procedure: ^ElnaTacProcedure;
|
||||||
first_procedure: ^ElnaInstructionDeclaration;
|
first_procedure: ^ElnaTacProcedure;
|
||||||
begin
|
begin
|
||||||
first_procedure := nil;
|
first_procedure := nil;
|
||||||
|
|
||||||
@@ -4068,18 +4142,15 @@ begin
|
|||||||
return result
|
return result
|
||||||
end;
|
end;
|
||||||
|
|
||||||
(**
|
|
||||||
* 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: ^ElnaTacStaticVariable;
|
result: ^ElnaInstructionModule;
|
||||||
code_part: Word;
|
|
||||||
begin
|
begin
|
||||||
data_part := elna_tac_var_part(parser_node^.globals);
|
result := malloc(#size(ElnaInstructionModule));
|
||||||
code_part := elna_tac_procedures(parser_node^.procedures);
|
result^.data := elna_tac_var_part(parser_node^.globals);
|
||||||
|
result^.code := elna_tac_procedures(parser_node^.procedures);
|
||||||
|
|
||||||
return elna_instruction_module_create(data_part, code_part)
|
return result
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc elna_name_procedure_declaration(parser_node: ^ElnaTreeProcedureDeclaration);
|
proc elna_name_procedure_declaration(parser_node: ^ElnaTreeProcedureDeclaration);
|
||||||
|
|||||||
Reference in New Issue
Block a user