From 2e27f78cffa52900b2bae25cff2d4cc05f85a132 Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Fri, 10 Apr 2026 10:19:49 +0200 Subject: [PATCH] Subtract a number from a pointer --- boot/stage21/cl.elna | 91 ++++++++++++++++++++++++++++---------------- 1 file 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;