Subtract a number from a pointer

This commit is contained in:
2026-04-10 10:19:49 +02:00
parent 5bff8c38a4
commit 2e27f78cff

View File

@@ -2431,30 +2431,49 @@ begin
return result return result
end; 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; rhs: ^ElnaTacOperand, symbol_table: ^ElnaSymbolTable, operand: ^ElnaTacOperand) -> ^ElnaTacInstruction;
var var
instruction: ^ElnaTacInstruction; instruction: ^ElnaTacInstruction;
pointer_type: ^ElnaTypePointer; pointer_type: ^ElnaTypePointer;
variable_expression: ^ElnaTreeVariableExpression;
begin begin
pointer_type := parser_node^.lhs^.type_decoration; pointer_type := parser_node^.type_decoration;
if pointer_type^.kind = ElnaTypeKind.pointer then instruction := elna_tac_instruction_create(ElnaTacOperator.add_ptr);
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 return instruction
end; end;
proc elna_tac_binary_create(operator: ElnaTacOperator, lhs: ^ElnaTacOperand, rhs: ^ElnaTacOperand, proc elna_tac_subtract_create(instructions: ^ElnaList, parser_node: ^ElnaTreeBinaryExpression, lhs: ^ElnaTacOperand,
symbol_table: ^ElnaSymbolTable, operand: ^ElnaTacOperand) -> ^ElnaTacInstruction; 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 var
instruction: ^ElnaTacInstruction; instruction: ^ElnaTacInstruction;
begin 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, 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, 2, rhs^.kind, rhs^.value, rhs^.length);
elna_tac_instruction_set_operand(instruction, 3, operand^.kind, operand^.value, operand^.length); elna_tac_instruction_set_operand(instruction, 3, operand^.kind, operand^.value, operand^.length);
elna_list_append(instructions, instruction)
return instruction
end; end;
proc elna_tac_binary_expression(instructions: ^ElnaList, parser_node: ^ElnaTreeBinaryExpression, 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); elna_tac_unary_expression(instructions, parser_node^.rhs, symbol_table, @rhs);
if parser_node^.operator = ElnaLexerKind.plus then 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 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 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 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 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 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 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 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 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 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 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 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 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 elsif parser_node^.operator = ElnaLexerKind.not_equal then
instruction := elna_tac_binary_create(ElnaTacOperator.not_equal, @lhs, @rhs, symbol_table, operand) elna_tac_binary_create(instructions, ElnaTacOperator.not_equal, @lhs, @rhs, symbol_table, operand)
end; end
elna_list_append(instructions, instruction)
end end
end; end;