Implement copy_to_offset and copy_from_offset TAC instructions
This commit is contained in:
+147
-46
@@ -1142,6 +1142,46 @@ begin
|
|||||||
elna_list_append(instructions, instruction)
|
elna_list_append(instructions, instruction)
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
proc elna_rtl_copy_to_offset(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction, variable_map: ^ElnaSymbolTable);
|
||||||
|
var
|
||||||
|
pseudo_symbol: ^ElnaRtlInfo;
|
||||||
|
instruction: ^ElnaRtlInstruction;
|
||||||
|
target_operand: ElnaRtlOperand;
|
||||||
|
source_operand: ElnaRtlOperand;
|
||||||
|
begin
|
||||||
|
target_operand.kind := ElnaRtlKind.pseudo;
|
||||||
|
elna_rtl_generate_pseudo(@target_operand.value, @target_operand.length, variable_map);
|
||||||
|
|
||||||
|
pseudo_symbol := elna_symbol_table_lookup(variable_map,
|
||||||
|
tac_instruction^.operands[2].value, tac_instruction^.operands[2].length);
|
||||||
|
instruction := elna_rtl_instruction_create(ElnaRtlOperator.la);
|
||||||
|
|
||||||
|
elna_rtl_instruction_set_operand(instruction, 1, target_operand.kind,
|
||||||
|
target_operand.value, target_operand.length, 0);
|
||||||
|
|
||||||
|
if pseudo_symbol = nil then
|
||||||
|
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.symbol,
|
||||||
|
tac_instruction^.operands[2].value, tac_instruction^.operands[2].length, 0)
|
||||||
|
else
|
||||||
|
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.pseudo,
|
||||||
|
tac_instruction^.operands[2].value, tac_instruction^.operands[2].length, 0)
|
||||||
|
end;
|
||||||
|
elna_list_append(instructions, instruction);
|
||||||
|
|
||||||
|
instruction := elna_rtl_instruction_create(ElnaRtlOperator.addi);
|
||||||
|
elna_rtl_instruction_set_operand(instruction, 1, target_operand.kind, target_operand.value, target_operand.length, 0);
|
||||||
|
elna_rtl_instruction_set_operand(instruction, 2, target_operand.kind, target_operand.value, target_operand.length, 0);
|
||||||
|
elna_rtl_instruction_set_operand(instruction, 3, ElnaRtlKind.immediate, tac_instruction^.operands[3].value, 0, 0);
|
||||||
|
elna_list_append(instructions, instruction);
|
||||||
|
|
||||||
|
elna_rtl_operand_value(instructions, @tac_instruction^.operands[1], variable_map, @source_operand);
|
||||||
|
instruction := elna_rtl_instruction_create(ElnaRtlOperator.sw);
|
||||||
|
|
||||||
|
elna_rtl_instruction_set_operand(instruction, 1, source_operand.kind, source_operand.value, source_operand.length, 0);
|
||||||
|
elna_rtl_instruction_set_operand(instruction, 2, target_operand.kind, target_operand.value, target_operand.length, 0);
|
||||||
|
elna_list_append(instructions, instruction)
|
||||||
|
end;
|
||||||
|
|
||||||
proc elna_rtl_load(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction, variable_map: ^ElnaSymbolTable);
|
proc elna_rtl_load(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction, variable_map: ^ElnaSymbolTable);
|
||||||
var
|
var
|
||||||
instruction: ^ElnaRtlInstruction;
|
instruction: ^ElnaRtlInstruction;
|
||||||
@@ -1150,9 +1190,44 @@ begin
|
|||||||
elna_rtl_operand_value(instructions, @tac_instruction^.operands[1], variable_map, @rtl_operand);
|
elna_rtl_operand_value(instructions, @tac_instruction^.operands[1], variable_map, @rtl_operand);
|
||||||
instruction := elna_rtl_instruction_create(ElnaRtlOperator.lw);
|
instruction := elna_rtl_instruction_create(ElnaRtlOperator.lw);
|
||||||
|
|
||||||
elna_rtl_instruction_set_operand(instruction, 2, rtl_operand.kind, rtl_operand.value, rtl_operand.length, 0);
|
|
||||||
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.pseudo,
|
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.pseudo,
|
||||||
tac_instruction^.operands[2].value, tac_instruction^.operands[2].length, 0);
|
tac_instruction^.operands[2].value, tac_instruction^.operands[2].length, 0);
|
||||||
|
elna_rtl_instruction_set_operand(instruction, 2, rtl_operand.kind, rtl_operand.value, rtl_operand.length, 0);
|
||||||
|
elna_list_append(instructions, instruction)
|
||||||
|
end;
|
||||||
|
|
||||||
|
proc elna_rtl_copy_from_offset(instructions: ^ElnaList, tac_instruction: ^ElnaTacInstruction, variable_map: ^ElnaSymbolTable);
|
||||||
|
var
|
||||||
|
instruction: ^ElnaRtlInstruction;
|
||||||
|
pseudo_symbol: ^ElnaRtlInfo;
|
||||||
|
begin
|
||||||
|
pseudo_symbol := elna_symbol_table_lookup(variable_map,
|
||||||
|
tac_instruction^.operands[1].value, tac_instruction^.operands[1].length);
|
||||||
|
instruction := elna_rtl_instruction_create(ElnaRtlOperator.la);
|
||||||
|
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.pseudo,
|
||||||
|
tac_instruction^.operands[3].value, tac_instruction^.operands[3].length, 0);
|
||||||
|
if pseudo_symbol = nil then
|
||||||
|
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.symbol,
|
||||||
|
tac_instruction^.operands[1].value, tac_instruction^.operands[1].length, 0)
|
||||||
|
else
|
||||||
|
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.pseudo,
|
||||||
|
tac_instruction^.operands[1].value, tac_instruction^.operands[1].length, 0)
|
||||||
|
end;
|
||||||
|
elna_list_append(instructions, instruction);
|
||||||
|
|
||||||
|
instruction := elna_rtl_instruction_create(ElnaRtlOperator.addi);
|
||||||
|
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.pseudo,
|
||||||
|
tac_instruction^.operands[3].value, tac_instruction^.operands[3].length, 0);
|
||||||
|
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.pseudo,
|
||||||
|
tac_instruction^.operands[3].value, tac_instruction^.operands[3].length, 0);
|
||||||
|
elna_rtl_instruction_set_operand(instruction, 3, ElnaRtlKind.immediate, tac_instruction^.operands[2].value, 0, 0);
|
||||||
|
elna_list_append(instructions, instruction);
|
||||||
|
|
||||||
|
instruction := elna_rtl_instruction_create(ElnaRtlOperator.lw);
|
||||||
|
elna_rtl_instruction_set_operand(instruction, 1, ElnaRtlKind.pseudo,
|
||||||
|
tac_instruction^.operands[3].value, tac_instruction^.operands[3].length, 0);
|
||||||
|
elna_rtl_instruction_set_operand(instruction, 2, ElnaRtlKind.pseudo,
|
||||||
|
tac_instruction^.operands[3].value, tac_instruction^.operands[3].length, 0);
|
||||||
elna_list_append(instructions, instruction)
|
elna_list_append(instructions, instruction)
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@@ -1203,8 +1278,12 @@ begin
|
|||||||
elna_rtl_binary_arithmetic(instructions, tac_instruction, ElnaRtlOperator.add, variable_map)
|
elna_rtl_binary_arithmetic(instructions, tac_instruction, ElnaRtlOperator.add, variable_map)
|
||||||
elsif tac_instruction^.operator = ElnaTacOperator.load then
|
elsif tac_instruction^.operator = ElnaTacOperator.load then
|
||||||
elna_rtl_load(instructions, tac_instruction, variable_map)
|
elna_rtl_load(instructions, tac_instruction, variable_map)
|
||||||
|
elsif tac_instruction^.operator = ElnaTacOperator.copy_from_offset then
|
||||||
|
elna_rtl_copy_from_offset(instructions, tac_instruction, variable_map)
|
||||||
elsif tac_instruction^.operator = ElnaTacOperator.store then
|
elsif tac_instruction^.operator = ElnaTacOperator.store then
|
||||||
elna_rtl_store(instructions, tac_instruction, variable_map)
|
elna_rtl_store(instructions, tac_instruction, variable_map)
|
||||||
|
elsif tac_instruction^.operator = ElnaTacOperator.copy_to_offset then
|
||||||
|
elna_rtl_copy_to_offset(instructions, tac_instruction, variable_map)
|
||||||
elsif tac_instruction^.operator = ElnaTacOperator.proc_call then
|
elsif tac_instruction^.operator = ElnaTacOperator.proc_call then
|
||||||
elna_rtl_call(instructions, tac_instruction, variable_map)
|
elna_rtl_call(instructions, tac_instruction, variable_map)
|
||||||
elsif tac_instruction^.operator = ElnaTacOperator.subtract then
|
elsif tac_instruction^.operator = ElnaTacOperator.subtract then
|
||||||
@@ -1257,10 +1336,10 @@ begin
|
|||||||
elna_rtl_copy(instructions, tac_instruction, variable_map)
|
elna_rtl_copy(instructions, tac_instruction, variable_map)
|
||||||
elsif tac_instruction^.operator = ElnaTacOperator.nop then
|
elsif tac_instruction^.operator = ElnaTacOperator.nop then
|
||||||
instruction := elna_rtl_instruction_create(ElnaRtlOperator.nop);
|
instruction := elna_rtl_instruction_create(ElnaRtlOperator.nop);
|
||||||
elna_tac_instruction_set_operand(instruction, 1, tac_instruction^.operands[1].kind,
|
elna_rtl_instruction_set_operand(instruction, 1, tac_instruction^.operands[1].kind,
|
||||||
tac_instruction^.operands[1].value, tac_instruction^.operands[1].length);
|
tac_instruction^.operands[1].value, tac_instruction^.operands[1].length, 0);
|
||||||
elna_tac_instruction_set_operand(instruction, 2, tac_instruction^.operands[2].kind,
|
elna_rtl_instruction_set_operand(instruction, 2, tac_instruction^.operands[2].kind,
|
||||||
tac_instruction^.operands[2].value, tac_instruction^.operands[2].length);
|
tac_instruction^.operands[2].value, tac_instruction^.operands[2].length, 0);
|
||||||
elna_list_append(instructions, instruction)
|
elna_list_append(instructions, instruction)
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
@@ -2021,7 +2100,7 @@ proc elna_tac_string_literal(instructions: ^ElnaList, string_literal_node: ^Elna
|
|||||||
symbol_table: ^ElnaSymbolTable, operand: ^ElnaTacOperand);
|
symbol_table: ^ElnaSymbolTable, operand: ^ElnaTacOperand);
|
||||||
var
|
var
|
||||||
offset: Word;
|
offset: Word;
|
||||||
instruction: Word;
|
instruction: ^ElnaTacInstruction;
|
||||||
begin
|
begin
|
||||||
offset := _add_string(string_literal_node^.value);
|
offset := _add_string(string_literal_node^.value);
|
||||||
|
|
||||||
@@ -2198,21 +2277,32 @@ begin
|
|||||||
return result
|
return result
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc elna_tac_copy_address(instructions: ^ElnaList, operand_type: ElnaTacOperandType, from: ^ElnaTacOperand, to: ^ElnaTacOperand);
|
proc elna_tac_copy_address(instructions: ^ElnaList, operand_result: ^ElnaTacOperandResult, from: ^ElnaTacOperand, to: ^ElnaTacOperand);
|
||||||
var
|
var
|
||||||
instruction: Word;
|
instruction: ^ElnaTacInstruction;
|
||||||
begin
|
begin
|
||||||
if operand_type = ElnaTacOperandType.dereferenced_pointer then
|
if operand_result^.kind = ElnaTacOperandType.dereferenced_pointer then
|
||||||
instruction := elna_tac_instruction_create(ElnaTacOperator.copy)
|
instruction := elna_tac_instruction_create(ElnaTacOperator.copy);
|
||||||
elsif operand_type = ElnaTacOperandType.sub_object then
|
|
||||||
instruction := elna_tac_instruction_create(ElnaTacOperator.copy)
|
|
||||||
else
|
|
||||||
instruction := elna_tac_instruction_create(ElnaTacOperator.get_address)
|
|
||||||
end;
|
|
||||||
elna_tac_instruction_set_operand(instruction, 1, from^.kind, from^.value, from^.length);
|
elna_tac_instruction_set_operand(instruction, 1, from^.kind, from^.value, from^.length);
|
||||||
elna_tac_instruction_set_operand(instruction, 2, to^.kind, to^.value, to^.length);
|
elna_tac_instruction_set_operand(instruction, 2, to^.kind, to^.value, to^.length);
|
||||||
|
|
||||||
elna_list_append(instructions, instruction)
|
elna_list_append(instructions, instruction)
|
||||||
|
elsif operand_result^.kind = ElnaTacOperandType.sub_object then
|
||||||
|
instruction := elna_tac_instruction_create(ElnaTacOperator.get_address);
|
||||||
|
elna_tac_instruction_set_operand(instruction, 1, from^.kind, from^.value, from^.length);
|
||||||
|
elna_tac_instruction_set_operand(instruction, 2, to^.kind, to^.value, to^.length);
|
||||||
|
elna_list_append(instructions, instruction);
|
||||||
|
|
||||||
|
instruction := elna_tac_instruction_create(ElnaTacOperator.add);
|
||||||
|
elna_tac_instruction_set_operand(instruction, 1, to^.kind, to^.value, to^.length);
|
||||||
|
elna_tac_instruction_set_operand(instruction, 2, ElnaTacKind.constant, operand_result^.offset, 0);
|
||||||
|
elna_tac_instruction_set_operand(instruction, 3, to^.kind, to^.value, to^.length);
|
||||||
|
elna_list_append(instructions, instruction)
|
||||||
|
else (* ElnaTacOperandType.plain_object *)
|
||||||
|
instruction := elna_tac_instruction_create(ElnaTacOperator.get_address);
|
||||||
|
elna_tac_instruction_set_operand(instruction, 1, from^.kind, from^.value, from^.length);
|
||||||
|
elna_tac_instruction_set_operand(instruction, 2, to^.kind, to^.value, to^.length);
|
||||||
|
elna_list_append(instructions, instruction)
|
||||||
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc elna_tac_unary_expression(instructions: ^ElnaList, parser_node: ^ElnaTreeUnaryExpression, symbol_table: ^ElnaSymbolTable, operand: ^ElnaTacOperand);
|
proc elna_tac_unary_expression(instructions: ^ElnaList, parser_node: ^ElnaTreeUnaryExpression, symbol_table: ^ElnaSymbolTable, operand: ^ElnaTacOperand);
|
||||||
@@ -2235,7 +2325,7 @@ begin
|
|||||||
|
|
||||||
if operator = '@' then
|
if operator = '@' then
|
||||||
elna_tac_generate_pseudo(@operand^.kind, @operand^.value, @operand^.length, symbol_table);
|
elna_tac_generate_pseudo(@operand^.kind, @operand^.value, @operand^.length, symbol_table);
|
||||||
elna_tac_copy_address(instructions, operand_result.kind, @base, operand)
|
elna_tac_copy_address(instructions, @operand_result, @base, operand)
|
||||||
elsif operator = '-' then
|
elsif operator = '-' then
|
||||||
elna_tac_generate_pseudo(@operand^.kind, @operand^.value, @operand^.length, symbol_table);
|
elna_tac_generate_pseudo(@operand^.kind, @operand^.value, @operand^.length, symbol_table);
|
||||||
|
|
||||||
@@ -2260,9 +2350,10 @@ begin
|
|||||||
elsif operand_result.kind = ElnaTacOperandType.sub_object then
|
elsif operand_result.kind = ElnaTacOperandType.sub_object then
|
||||||
elna_tac_generate_pseudo(@operand^.kind, @operand^.value, @operand^.length, symbol_table);
|
elna_tac_generate_pseudo(@operand^.kind, @operand^.value, @operand^.length, symbol_table);
|
||||||
|
|
||||||
instruction := elna_tac_instruction_create(ElnaTacOperator.load);
|
instruction := elna_tac_instruction_create(ElnaTacOperator.copy_from_offset);
|
||||||
elna_tac_instruction_set_operand(instruction, 1, base.kind, base.value, base.length);
|
elna_tac_instruction_set_operand(instruction, 1, base.kind, base.value, base.length);
|
||||||
elna_tac_instruction_set_operand(instruction, 2, operand^.kind, operand^.value, operand^.length);
|
elna_tac_instruction_set_operand(instruction, 2, ElnaTacKind.constant, operand_result.offset, 0);
|
||||||
|
elna_tac_instruction_set_operand(instruction, 3, operand^.kind, operand^.value, operand^.length);
|
||||||
elna_list_append(instructions, instruction)
|
elna_list_append(instructions, instruction)
|
||||||
else
|
else
|
||||||
operand^.kind := base.kind;
|
operand^.kind := base.kind;
|
||||||
@@ -2341,7 +2432,7 @@ end;
|
|||||||
|
|
||||||
proc elna_tac_binary_expression(instructions: ^ElnaList, parser_node: ^ElnaTreeBinaryExpression, symbol_table: ^ElnaSymbolTable, operand: ^ElnaTacOperand);
|
proc elna_tac_binary_expression(instructions: ^ElnaList, parser_node: ^ElnaTreeBinaryExpression, symbol_table: ^ElnaSymbolTable, operand: ^ElnaTacOperand);
|
||||||
var
|
var
|
||||||
instruction: Word;
|
instruction: ^ElnaTacInstruction;
|
||||||
lhs: ElnaTacOperand;
|
lhs: ElnaTacOperand;
|
||||||
rhs: ElnaTacOperand;
|
rhs: ElnaTacOperand;
|
||||||
begin
|
begin
|
||||||
@@ -2442,7 +2533,7 @@ proc elna_tac_call(instructions: ^ElnaList, parsed_call: ^ElnaTreeCall, symbol_t
|
|||||||
var
|
var
|
||||||
parsed_expression: ^ElnaTreeVariableExpression;
|
parsed_expression: ^ElnaTreeVariableExpression;
|
||||||
arguments_operand: ^ElnaTacOperand;
|
arguments_operand: ^ElnaTacOperand;
|
||||||
call_instruction: Word;
|
call_instruction: ^ElnaTacInstruction;
|
||||||
argument_entry: ^ElnaTreeExpressionList;
|
argument_entry: ^ElnaTreeExpressionList;
|
||||||
begin
|
begin
|
||||||
parsed_expression := parsed_call^.callee;
|
parsed_expression := parsed_call^.callee;
|
||||||
@@ -2489,7 +2580,7 @@ proc elna_tac_goto_statement(instructions: ^ElnaList, parser_node: ^ElnaTreeGoto
|
|||||||
var
|
var
|
||||||
label_length: Word;
|
label_length: Word;
|
||||||
label_with_dot: Word;
|
label_with_dot: Word;
|
||||||
instruction: Word;
|
instruction: ^ElnaTacInstruction;
|
||||||
begin
|
begin
|
||||||
label_length := parser_node^.length + 1;
|
label_length := parser_node^.length + 1;
|
||||||
label_with_dot := malloc(label_length);
|
label_with_dot := malloc(label_length);
|
||||||
@@ -2606,7 +2697,7 @@ end;
|
|||||||
proc elna_tac_dereference_expression(instructions: ^ElnaList, dereference_expression: ^ElnaTreeDereferenceExpression,
|
proc elna_tac_dereference_expression(instructions: ^ElnaList, dereference_expression: ^ElnaTreeDereferenceExpression,
|
||||||
symbol_table: ^ElnaSymbolTable, operand: ^ElnaTacOperand);
|
symbol_table: ^ElnaSymbolTable, operand: ^ElnaTacOperand);
|
||||||
var
|
var
|
||||||
load_instruction: Word;
|
load_instruction: ^ElnaTacInstruction;
|
||||||
operand_result: ElnaTacOperandResult;
|
operand_result: ElnaTacOperandResult;
|
||||||
begin
|
begin
|
||||||
elna_tac_designator(instructions, dereference_expression^.pointer, symbol_table, @operand_result, operand);
|
elna_tac_designator(instructions, dereference_expression^.pointer, symbol_table, @operand_result, operand);
|
||||||
@@ -2618,10 +2709,10 @@ begin
|
|||||||
|
|
||||||
elna_list_append(instructions, load_instruction)
|
elna_list_append(instructions, load_instruction)
|
||||||
elsif operand_result.kind = ElnaTacOperandType.sub_object then
|
elsif operand_result.kind = ElnaTacOperandType.sub_object then
|
||||||
load_instruction := elna_tac_instruction_create(ElnaTacOperator.load);
|
load_instruction := elna_tac_instruction_create(ElnaTacOperator.copy_from_offset);
|
||||||
elna_tac_instruction_set_operand(load_instruction, 1, operand^.kind, operand^.value, operand^.length);
|
elna_tac_instruction_set_operand(load_instruction, 1, operand^.kind, operand^.value, operand^.length);
|
||||||
elna_tac_instruction_set_operand(load_instruction, 2, operand^.kind, operand^.value, operand^.length);
|
elna_tac_instruction_set_operand(load_instruction, 2, ElnaTacKind.constant, operand_result.offset, 0);
|
||||||
|
elna_tac_instruction_set_operand(load_instruction, 3, operand^.kind, operand^.value, operand^.length);
|
||||||
elna_list_append(instructions, load_instruction)
|
elna_list_append(instructions, load_instruction)
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
@@ -2645,9 +2736,8 @@ begin
|
|||||||
if designator_base^.type_decoration = nil then
|
if designator_base^.type_decoration = nil then
|
||||||
elna_tac_enumeration_value(field_access_expression, operand)
|
elna_tac_enumeration_value(field_access_expression, operand)
|
||||||
else
|
else
|
||||||
operand_result^.offset := elna_tac_field_access_expression(instructions,
|
elna_tac_field_access_expression(instructions,
|
||||||
field_access_expression, symbol_table, operand);
|
field_access_expression, symbol_table, operand_result, operand)
|
||||||
operand_result^.kind := ElnaTacOperandType.sub_object
|
|
||||||
end
|
end
|
||||||
elsif parser_node^.kind = ElnaTreeKind.array_access_expression then
|
elsif parser_node^.kind = ElnaTreeKind.array_access_expression then
|
||||||
elna_tac_array_access_expression(instructions, parser_node, symbol_table, operand);
|
elna_tac_array_access_expression(instructions, parser_node, symbol_table, operand);
|
||||||
@@ -2660,22 +2750,21 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
proc elna_tac_field_access_expression(instructions: ^ElnaList, field_access_expression: ^ElnaTreeFieldAccessExpression,
|
proc elna_tac_field_access_expression(instructions: ^ElnaList, field_access_expression: ^ElnaTreeFieldAccessExpression,
|
||||||
symbol_table: ^ElnaSymbolTable, operand: ^ElnaTacOperand) -> Word;
|
symbol_table: ^ElnaSymbolTable, operand_result: ^ElnaTacOperandResult, operand: ^ElnaTacOperand);
|
||||||
var
|
var
|
||||||
field_type: ^ElnaType;
|
field_type: ^ElnaType;
|
||||||
instruction: Word;
|
instruction: ^ElnaTacInstruction;
|
||||||
designator_base: ^ElnaTreeExpression;
|
designator_base: ^ElnaTreeExpression;
|
||||||
aggregate_type: ^ElnaTypeRecord;
|
aggregate_type: ^ElnaTypeRecord;
|
||||||
field_count: Word;
|
field_count: Word;
|
||||||
current_field: ^ElnaTypeField;
|
current_field: ^ElnaTypeField;
|
||||||
field_offset: Word;
|
field_offset: Word;
|
||||||
operand_result: ElnaTacOperandResult;
|
|
||||||
base: ElnaTacOperand;
|
base: ElnaTacOperand;
|
||||||
begin
|
begin
|
||||||
designator_base := field_access_expression^.aggregate;
|
designator_base := field_access_expression^.aggregate;
|
||||||
aggregate_type := designator_base^.type_decoration;
|
aggregate_type := designator_base^.type_decoration;
|
||||||
|
|
||||||
elna_tac_designator(instructions, designator_base, symbol_table, @operand_result, @base);
|
elna_tac_designator(instructions, designator_base, symbol_table, operand_result, @base);
|
||||||
|
|
||||||
field_count := aggregate_type^.length;
|
field_count := aggregate_type^.length;
|
||||||
current_field := aggregate_type^.members;
|
current_field := aggregate_type^.members;
|
||||||
@@ -2690,22 +2779,29 @@ begin
|
|||||||
field_offset := field_offset + field_type^.size;
|
field_offset := field_offset + field_type^.size;
|
||||||
goto elna_tac_field_access_expression_field
|
goto elna_tac_field_access_expression_field
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
if operand_result^.kind = ElnaTacOperandType.dereferenced_pointer then
|
||||||
elna_tac_generate_pseudo(@operand^.kind, @operand^.value, @operand^.length, symbol_table);
|
elna_tac_generate_pseudo(@operand^.kind, @operand^.value, @operand^.length, symbol_table);
|
||||||
elna_tac_copy_address(instructions, operand_result.kind, @base, operand);
|
|
||||||
|
|
||||||
instruction := elna_tac_instruction_create(ElnaTacOperator.add);
|
instruction := elna_tac_instruction_create(ElnaTacOperator.add);
|
||||||
elna_tac_instruction_set_operand(instruction, 1, operand^.kind, operand^.value, operand^.length);
|
elna_tac_instruction_set_operand(instruction, 1, operand^.kind, operand^.value, operand^.length);
|
||||||
elna_tac_instruction_set_operand(instruction, 2, ElnaTacKind.constant, field_offset, 0);
|
elna_tac_instruction_set_operand(instruction, 2, base.kind, base.value, base.length);
|
||||||
elna_tac_instruction_set_operand(instruction, 3, operand^.kind, operand^.value, operand^.length);
|
elna_tac_instruction_set_operand(instruction, 3, ElnaTacKind.constant, field_offset, 0);
|
||||||
elna_list_append(instructions, instruction);
|
elna_list_append(instructions, instruction)
|
||||||
|
elsif operand_result^.kind = ElnaTacOperandType.sub_object then
|
||||||
return field_offset
|
memcpy(operand, @base, #size(ElnaTacOperand));
|
||||||
|
operand_result^.offset := operand_result^.offset + field_offset
|
||||||
|
else (* ElnaTacOperandType.plain_object *)
|
||||||
|
memcpy(operand, @base, #size(ElnaTacOperand));
|
||||||
|
operand_result^.kind := ElnaTacOperandType.sub_object;
|
||||||
|
operand_result^.offset := field_offset
|
||||||
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
proc elna_tac_array_access_expression(instructions: ^ElnaList, array_access_expression: ^ElnaTreeArrayAccessExpression,
|
proc elna_tac_array_access_expression(instructions: ^ElnaList, array_access_expression: ^ElnaTreeArrayAccessExpression,
|
||||||
symbol_table: ^ElnaSymbolTable, operand: ^ElnaTacOperand);
|
symbol_table: ^ElnaSymbolTable, operand: ^ElnaTacOperand);
|
||||||
var
|
var
|
||||||
instruction: Word;
|
instruction: ^ElnaTacInstruction;
|
||||||
operand_result: ElnaTacOperandResult;
|
operand_result: ElnaTacOperandResult;
|
||||||
inter_operand: ElnaTacOperand;
|
inter_operand: ElnaTacOperand;
|
||||||
index_type: Word;
|
index_type: Word;
|
||||||
@@ -2738,7 +2834,7 @@ begin
|
|||||||
symbol_table, @operand_result, @inter_operand);
|
symbol_table, @operand_result, @inter_operand);
|
||||||
elna_tac_generate_pseudo(@operand^.kind, @operand^.value, @operand^.length, symbol_table);
|
elna_tac_generate_pseudo(@operand^.kind, @operand^.value, @operand^.length, symbol_table);
|
||||||
|
|
||||||
elna_tac_copy_address(instructions, operand_result.kind, @inter_operand, operand);
|
elna_tac_copy_address(instructions, @operand_result, @inter_operand, operand);
|
||||||
|
|
||||||
instruction := elna_tac_instruction_create(ElnaTacOperator.add);
|
instruction := elna_tac_instruction_create(ElnaTacOperator.add);
|
||||||
elna_tac_instruction_set_operand(instruction, 1, operand^.kind, operand^.value, operand^.length);
|
elna_tac_instruction_set_operand(instruction, 1, operand^.kind, operand^.value, operand^.length);
|
||||||
@@ -2768,9 +2864,10 @@ end;
|
|||||||
proc elna_tac_assign_statement(instructions: ^ElnaList, parser_tree: ^ElnaTreeAssignStatement, symbol_table: ^ElnaSymbolTable);
|
proc elna_tac_assign_statement(instructions: ^ElnaList, parser_tree: ^ElnaTreeAssignStatement, symbol_table: ^ElnaSymbolTable);
|
||||||
var
|
var
|
||||||
operand_result: ElnaTacOperandResult;
|
operand_result: ElnaTacOperandResult;
|
||||||
instruction: Word;
|
instruction: ^ElnaTacInstruction;
|
||||||
assignment_operand: ElnaTacOperand;
|
assignment_operand: ElnaTacOperand;
|
||||||
assignee: ElnaTacOperand;
|
assignee: ElnaTacOperand;
|
||||||
|
operand: ElnaTacOperand;
|
||||||
symbol_info: ^ElnaSymbolInfo;
|
symbol_info: ^ElnaSymbolInfo;
|
||||||
begin
|
begin
|
||||||
elna_tac_designator(instructions, parser_tree^.assignee, symbol_table, @operand_result, @assignee);
|
elna_tac_designator(instructions, parser_tree^.assignee, symbol_table, @operand_result, @assignee);
|
||||||
@@ -2784,10 +2881,14 @@ begin
|
|||||||
assignment_operand.value, assignment_operand.length);
|
assignment_operand.value, assignment_operand.length);
|
||||||
elna_tac_instruction_set_operand(instruction, 2, assignee.kind, assignee.value, assignee.length)
|
elna_tac_instruction_set_operand(instruction, 2, assignee.kind, assignee.value, assignee.length)
|
||||||
elsif operand_result.kind = ElnaTacOperandType.sub_object then
|
elsif operand_result.kind = ElnaTacOperandType.sub_object then
|
||||||
instruction := elna_tac_instruction_create(ElnaTacOperator.store);
|
elna_tac_generate_pseudo(@operand.kind, @operand.value, @operand.length, symbol_table);
|
||||||
|
|
||||||
|
instruction := elna_tac_instruction_create(ElnaTacOperator.copy_to_offset);
|
||||||
elna_tac_instruction_set_operand(instruction, 1, assignment_operand.kind,
|
elna_tac_instruction_set_operand(instruction, 1, assignment_operand.kind,
|
||||||
assignment_operand.value, assignment_operand.length);
|
assignment_operand.value, assignment_operand.length);
|
||||||
elna_tac_instruction_set_operand(instruction, 2, assignee.kind, assignee.value, assignee.length)
|
elna_tac_instruction_set_operand(instruction, 2, assignee.kind, assignee.value, assignee.length);
|
||||||
|
elna_tac_instruction_set_operand(instruction, 3, ElnaTacKind.constant, operand_result.offset, 0);
|
||||||
|
elna_list_append(instructions, instruction)
|
||||||
else
|
else
|
||||||
instruction := elna_tac_instruction_create(ElnaTacOperator.copy);
|
instruction := elna_tac_instruction_create(ElnaTacOperator.copy);
|
||||||
elna_tac_instruction_set_operand(instruction, 1, assignment_operand.kind,
|
elna_tac_instruction_set_operand(instruction, 1, assignment_operand.kind,
|
||||||
@@ -2818,7 +2919,7 @@ end;
|
|||||||
|
|
||||||
proc elna_tac_return_statement(instructions: ^ElnaList, parser_node: ^ElnaTreeReturnStatement, symbol_table: ^ElnaSymbolTable);
|
proc elna_tac_return_statement(instructions: ^ElnaList, parser_node: ^ElnaTreeReturnStatement, symbol_table: ^ElnaSymbolTable);
|
||||||
var
|
var
|
||||||
instruction: Word;
|
instruction: ^ElnaTacInstruction;
|
||||||
operand: ElnaTacOperand;
|
operand: ElnaTacOperand;
|
||||||
begin
|
begin
|
||||||
elna_tac_binary_expression(instructions, parser_node^.returned, symbol_table, @operand);
|
elna_tac_binary_expression(instructions, parser_node^.returned, symbol_table, @operand);
|
||||||
@@ -2869,7 +2970,7 @@ proc elna_tac_conditional_statements(instructions: ^ElnaList, parser_node: ^Elna
|
|||||||
after_end_label: Word, symbol_table: ^ElnaSymbolTable);
|
after_end_label: Word, symbol_table: ^ElnaSymbolTable);
|
||||||
var
|
var
|
||||||
condition_label: Word;
|
condition_label: Word;
|
||||||
instruction: Word;
|
instruction: ^ElnaTacInstruction;
|
||||||
operand: ElnaTacOperand;
|
operand: ElnaTacOperand;
|
||||||
begin
|
begin
|
||||||
(* Compile condition. *)
|
(* Compile condition. *)
|
||||||
|
|||||||
Reference in New Issue
Block a user