Subtract a number from a pointer
This commit is contained in:
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user