summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--boot/stage21/cl.elna91
1 files changed, 58 insertions, 33 deletions
diff --git a/boot/stage21/cl.elna b/boot/stage21/cl.elna
index b7cb3de..a05f494 100644
--- a/boot/stage21/cl.elna
+++ b/boot/stage21/cl.elna
@@ -2431,30 +2431,49 @@ begin
return result
end;
-proc elna_tac_sum_create(parser_node: ^ElnaTreeBinaryExpression, lhs: ^ElnaTacOperand,
+proc elna_tac_add_pointer(parser_node: ^ElnaTreeExpression, lhs: ^ElnaTacOperand,
rhs: ^ElnaTacOperand, symbol_table: ^ElnaSymbolTable, operand: ^ElnaTacOperand) -> ^ElnaTacInstruction;
var
instruction: ^ElnaTacInstruction;
pointer_type: ^ElnaTypePointer;
- variable_expression: ^ElnaTreeVariableExpression;
begin
- pointer_type := parser_node^.lhs^.type_decoration;
- if pointer_type^.kind = ElnaTypeKind.pointer then
- instruction := elna_tac_instruction_create(ElnaTacOperator.add_ptr);
+ pointer_type := parser_node^.type_decoration;
+ instruction := elna_tac_instruction_create(ElnaTacOperator.add_ptr);
+
+ elna_tac_make_variable(@operand^.kind, @operand^.value, @operand^.length, symbol_table);
+ elna_tac_instruction_set_operand(instruction, 1, lhs^.kind, lhs^.value, lhs^.length);
+ elna_tac_instruction_set_operand(instruction, 2, rhs^.kind, rhs^.value, rhs^.length);
+ elna_tac_instruction_set_operand(instruction, 3, ElnaTacKind.constant, pointer_type^.base^.size, 0);
+ elna_tac_instruction_set_operand(instruction, 4, operand^.kind, operand^.value, operand^.length);
- elna_tac_make_variable(@operand^.kind, @operand^.value, @operand^.length, symbol_table);
- elna_tac_instruction_set_operand(instruction, 1, lhs^.kind, lhs^.value, lhs^.length);
- elna_tac_instruction_set_operand(instruction, 2, rhs^.kind, rhs^.value, rhs^.length);
- elna_tac_instruction_set_operand(instruction, 3, ElnaTacKind.constant, pointer_type^.base^.size, 0);
- elna_tac_instruction_set_operand(instruction, 4, operand^.kind, operand^.value, operand^.length)
- else
- instruction := elna_tac_binary_create(ElnaTacOperator.add, lhs, rhs, symbol_table, operand)
- end;
return instruction
end;
-proc elna_tac_binary_create(operator: ElnaTacOperator, lhs: ^ElnaTacOperand, rhs: ^ElnaTacOperand,
- symbol_table: ^ElnaSymbolTable, operand: ^ElnaTacOperand) -> ^ElnaTacInstruction;
+proc elna_tac_subtract_create(instructions: ^ElnaList, parser_node: ^ElnaTreeBinaryExpression, lhs: ^ElnaTacOperand,
+ rhs: ^ElnaTacOperand, symbol_table: ^ElnaSymbolTable, operand: ^ElnaTacOperand);
+var
+ instruction: ^ElnaTacInstruction;
+ lhs_is_pointer: Word;
+ rhs_is_not_pointer: Word;
+begin
+ lhs_is_pointer := parser_node^.lhs^.type_decoration^.kind = ElnaTypeKind.pointer;
+ rhs_is_not_pointer := parser_node^.rhs^.type_decoration^.kind <> ElnaTypeKind.pointer;
+
+ if lhs_is_pointer & rhs_is_not_pointer then
+ instruction := elna_tac_instruction_create(ElnaTacOperator.negate);
+ elna_tac_instruction_set_operand(instruction, 1, rhs^.kind, rhs^.value, rhs^.length);
+ elna_tac_instruction_set_operand(instruction, 2, operand^.kind, operand^.value, operand^.length);
+ elna_list_append(instructions, instruction);
+
+ instruction := elna_tac_add_pointer(parser_node^.lhs, lhs, operand, symbol_table, operand);
+ elna_list_append(instructions, instruction)
+ else
+ elna_tac_binary_create(instructions, ElnaTacOperator.subtract, lhs, rhs, symbol_table, operand)
+ end
+end;
+
+proc elna_tac_binary_create(instructions: ^ElnaList, operator: ElnaTacOperator, lhs: ^ElnaTacOperand,
+ rhs: ^ElnaTacOperand, symbol_table: ^ElnaSymbolTable, operand: ^ElnaTacOperand);
var
instruction: ^ElnaTacInstruction;
begin
@@ -2464,8 +2483,7 @@ begin
elna_tac_instruction_set_operand(instruction, 1, lhs^.kind, lhs^.value, lhs^.length);
elna_tac_instruction_set_operand(instruction, 2, rhs^.kind, rhs^.value, rhs^.length);
elna_tac_instruction_set_operand(instruction, 3, operand^.kind, operand^.value, operand^.length);
-
- return instruction
+ elna_list_append(instructions, instruction)
end;
proc elna_tac_binary_expression(instructions: ^ElnaList, parser_node: ^ElnaTreeBinaryExpression,
@@ -2482,35 +2500,42 @@ begin
elna_tac_unary_expression(instructions, parser_node^.rhs, symbol_table, @rhs);
if parser_node^.operator = ElnaLexerKind.plus then
- instruction := elna_tac_sum_create(parser_node, @lhs, @rhs, symbol_table, operand)
+ if parser_node^.lhs^.type_decoration^.kind = ElnaTypeKind.pointer then
+ instruction := elna_tac_add_pointer(parser_node^.lhs, @lhs, @rhs, symbol_table, operand);
+ elna_list_append(instructions, instruction)
+ elsif parser_node^.rhs^.type_decoration^.kind = ElnaTypeKind.pointer then
+ instruction := elna_tac_add_pointer(parser_node^.rhs, @rhs, @lhs, symbol_table, operand);
+ elna_list_append(instructions, instruction)
+ else
+ elna_tac_binary_create(instructions, ElnaTacOperator.add, @lhs, @rhs, symbol_table, operand)
+ end
elsif parser_node^.operator = ElnaLexerKind.minus then
- instruction := elna_tac_binary_create(ElnaTacOperator.subtract, @lhs, @rhs, symbol_table, operand)
+ elna_tac_subtract_create(instructions, parser_node, @lhs, @rhs, symbol_table, operand)
elsif parser_node^.operator = ElnaLexerKind.multiplication then
- instruction := elna_tac_binary_create(ElnaTacOperator.multiply, @lhs, @rhs, symbol_table, operand)
+ elna_tac_binary_create(instructions, ElnaTacOperator.multiply, @lhs, @rhs, symbol_table, operand)
elsif parser_node^.operator = ElnaLexerKind.and then
- instruction := elna_tac_binary_create(ElnaTacOperator.and, @lhs, @rhs, symbol_table, operand)
+ elna_tac_binary_create(instructions, ElnaTacOperator.and, @lhs, @rhs, symbol_table, operand)
elsif parser_node^.operator = ElnaLexerKind._or then
- instruction := elna_tac_binary_create(ElnaTacOperator._or, @lhs, @rhs, symbol_table, operand)
+ elna_tac_binary_create(instructions, ElnaTacOperator._or, @lhs, @rhs, symbol_table, operand)
elsif parser_node^.operator = ElnaLexerKind._xor then
- instruction := elna_tac_binary_create(ElnaTacOperator._xor, @lhs, @rhs, symbol_table, operand)
+ elna_tac_binary_create(instructions, ElnaTacOperator._xor, @lhs, @rhs, symbol_table, operand)
elsif parser_node^.operator = ElnaLexerKind.equals then
- instruction := elna_tac_binary_create(ElnaTacOperator.equal, @lhs, @rhs, symbol_table, operand)
+ elna_tac_binary_create(instructions, ElnaTacOperator.equal, @lhs, @rhs, symbol_table, operand)
elsif parser_node^.operator = ElnaLexerKind.remainder then
- instruction := elna_tac_binary_create(ElnaTacOperator.remainder, @lhs, @rhs, symbol_table, operand)
+ elna_tac_binary_create(instructions, ElnaTacOperator.remainder, @lhs, @rhs, symbol_table, operand)
elsif parser_node^.operator = ElnaLexerKind.division then
- instruction := elna_tac_binary_create(ElnaTacOperator.divide, @lhs, @rhs, symbol_table, operand)
+ elna_tac_binary_create(instructions, ElnaTacOperator.divide, @lhs, @rhs, symbol_table, operand)
elsif parser_node^.operator = ElnaLexerKind.less_than then
- instruction := elna_tac_binary_create(ElnaTacOperator.less_than, @lhs, @rhs, symbol_table, operand)
+ elna_tac_binary_create(instructions, ElnaTacOperator.less_than, @lhs, @rhs, symbol_table, operand)
elsif parser_node^.operator = ElnaLexerKind.greater_than then
- instruction := elna_tac_binary_create(ElnaTacOperator.greater_than, @lhs, @rhs, symbol_table, operand)
+ elna_tac_binary_create(instructions, ElnaTacOperator.greater_than, @lhs, @rhs, symbol_table, operand)
elsif parser_node^.operator = ElnaLexerKind.less_equal then
- instruction := elna_tac_binary_create(ElnaTacOperator.less_or_equal, @lhs, @rhs, symbol_table, operand)
+ elna_tac_binary_create(instructions, ElnaTacOperator.less_or_equal, @lhs, @rhs, symbol_table, operand)
elsif parser_node^.operator = ElnaLexerKind.greater_equal then
- instruction := elna_tac_binary_create(ElnaTacOperator.greater_or_equal, @lhs, @rhs, symbol_table, operand)
+ elna_tac_binary_create(instructions, ElnaTacOperator.greater_or_equal, @lhs, @rhs, symbol_table, operand)
elsif parser_node^.operator = ElnaLexerKind.not_equal then
- instruction := elna_tac_binary_create(ElnaTacOperator.not_equal, @lhs, @rhs, symbol_table, operand)
- end;
- elna_list_append(instructions, instruction)
+ elna_tac_binary_create(instructions, ElnaTacOperator.not_equal, @lhs, @rhs, symbol_table, operand)
+ end
end
end;