Fix short-circuiting operators

This commit is contained in:
Nikita Lisitsa 2026-03-30 20:02:13 +03:00
parent 75f1cea3f3
commit 86216e8cf3

View file

@ -131,27 +131,31 @@ namespace pslang::ir
if (node.type == ast::binary_operation_type::logical_and) if (node.type == ast::binary_operation_type::logical_and)
{ {
mcontext.nodes->emplace_back(jump_if_zero{arg1}); mcontext.nodes->emplace_back(copy{arg1});
auto result = last();
mcontext.nodes->emplace_back(jump_if_zero{result});
auto jump = last(); auto jump = last();
auto arg2 = apply(*node.arg2); auto arg2 = apply(*node.arg2);
mcontext.nodes->emplace_back(binary_operation{ast::binary_operation_type::binary_and, arg1, arg2}, node.inferred_type); mcontext.nodes->emplace_back(binary_operation{ast::binary_operation_type::binary_and, result, arg2}, node.inferred_type);
mcontext.nodes->emplace_back(assignment{arg1, last()}); mcontext.nodes->emplace_back(assignment{result, last()});
mcontext.nodes->emplace_back(label{}); mcontext.nodes->emplace_back(label{});
std::get<jump_if_zero>(jump->instruction).target = last(); std::get<jump_if_zero>(jump->instruction).target = last();
return arg1; return result;
} }
if (node.type == ast::binary_operation_type::logical_or) if (node.type == ast::binary_operation_type::logical_or)
{ {
mcontext.nodes->emplace_back(unary_operation{ast::unary_operation_type::logical_not, arg1}, node.inferred_type); mcontext.nodes->emplace_back(copy{arg1});
auto result = last();
mcontext.nodes->emplace_back(unary_operation{ast::unary_operation_type::logical_not, result}, node.inferred_type);
mcontext.nodes->emplace_back(jump_if_zero{last()}); mcontext.nodes->emplace_back(jump_if_zero{last()});
auto jump = last(); auto jump = last();
auto arg2 = apply(*node.arg2); auto arg2 = apply(*node.arg2);
mcontext.nodes->emplace_back(binary_operation{ast::binary_operation_type::binary_or, arg1, arg2}, node.inferred_type); mcontext.nodes->emplace_back(binary_operation{ast::binary_operation_type::binary_or, result, arg2}, node.inferred_type);
mcontext.nodes->emplace_back(assignment{arg1, last()}); mcontext.nodes->emplace_back(assignment{result, last()});
mcontext.nodes->emplace_back(label{}); mcontext.nodes->emplace_back(label{});
std::get<jump_if_zero>(jump->instruction).target = last(); std::get<jump_if_zero>(jump->instruction).target = last();
return arg1; return result;
} }
// Pointer arithmetic // Pointer arithmetic