private function parseShortCircuiting(AstBinaryOp $expr, $isOr) { $result = new Temporary(); $longBlock = new Block(); $endBlock = new Block(); $left = $this->readVariable($this->parseExprNode($expr->left)); $if = $isOr ? $endBlock : $longBlock; $else = $isOr ? $longBlock : $endBlock; $this->block->children[] = new JumpIf($left, $if, $else); $longBlock->addParent($this->block); $endBlock->addParent($this->block); $this->block = $longBlock; $right = $this->readVariable($this->parseExprNode($expr->right)); $boolCast = new Op\Expr\Cast\Bool_($right); $this->block->children[] = $boolCast; $this->block->children[] = new Jump($endBlock); $endBlock->addParent($this->block); $this->block = $endBlock; $phi = new Op\Phi($result, ['block' => $this->block]); $phi->addOperand(new Literal($isOr)); $phi->addOperand($boolCast->result); $this->block->phi[] = $phi; $mode = $isOr ? Assertion::MODE_UNION : Assertion::MODE_INTERSECTION; foreach ($left->assertions as $assert) { $result->addAssertion($assert['var'], $assert['assertion'], $mode); } foreach ($right->assertions as $assert) { $result->addAssertion($assert['var'], $assert['assertion'], $mode); } return $result; }