/**
* @param CompilationContext $compilationContext
*/
public function compile(CompilationContext $compilationContext)
{
$exprRaw = $this->_statement['expr'];
$expr = new EvalExpression();
$condition = $expr->optimize($exprRaw, $compilationContext);
/**
* This pass tries to move dynamic variable initialization out of the if/else branch
*/
if (isset($this->_statement['statements']) && (isset($this->_statement['else_statements']) || isset($this->_statement['elseif_statements']))) {
$readDetector = new ReadDetector();
$skipVariantInit = new SkipVariantInit();
$skipVariantInit->setVariablesToSkip(0, $expr->getUsedVariables());
$skipVariantInit->pass(0, new StatementsBlock($this->_statement['statements']));
$lastBranchId = 0;
if (isset($this->_statement['else_statements'])) {
++$lastBranchId;
$skipVariantInit->setVariablesToSkip($lastBranchId, $expr->getUsedVariables());
$skipVariantInit->pass($lastBranchId, new StatementsBlock($this->_statement['else_statements']));
}
if (isset($this->_statement['elseif_statements'])) {
foreach ($this->_statement['elseif_statements'] as $key => $statement) {
$this->_statement['elseif_statements'][$key]['condition'] = $expr->optimize($statement['expr'], $compilationContext);
$lastBranchId++;
$skipVariantInit->setVariablesToSkip($lastBranchId, $expr->getUsedVariables());
if (!isset($statement['statements'])) {
continue;
}
$skipVariantInit->pass($lastBranchId, new StatementsBlock($statement));
}
}
$symbolTable = $compilationContext->symbolTable;
foreach ($skipVariantInit->getVariables() as $variable) {
if ($symbolTable->hasVariable($variable)) {
$symbolVariable = $symbolTable->getVariable($variable);
if ($symbolVariable->getType() == 'variable') {
if (!$readDetector->detect($variable, $exprRaw)) {
$symbolVariable->initVariant($compilationContext);
$symbolVariable->skipInitVariant(2);
}
}
}
}
}
$compilationContext->codePrinter->output('if (' . $condition . ') {');
$this->_evalExpression = $expr;
/**
* Try to mark latest temporary variable used as idle
*/
$evalVariable = $expr->getEvalVariable();
if (is_object($evalVariable)) {
if ($evalVariable->isTemporal()) {
$evalVariable->setIdle(true);
}
}
/**
* Compile statements in the 'if' block
*/
if (isset($this->_statement['statements'])) {
$st = new StatementsBlock($this->_statement['statements']);
$branch = $st->compile($compilationContext, $expr->isUnreachable(), Branch::TYPE_CONDITIONAL_TRUE);
$branch->setRelatedStatement($this);
}
/**
* Compile statements in the 'elseif' block
*/
if (isset($this->_statement['elseif_statements'])) {
foreach ($this->_statement['elseif_statements'] as $key => $statement) {
if (!isset($statement['statements'])) {
continue;
}
$st = new StatementsBlock($statement['statements']);
$compilationContext->codePrinter->output('} else if (' . $statement['condition'] . ') {');
$branch = $st->compile($compilationContext, $expr->isUnreachable(), Branch::TYPE_CONDITIONAL_TRUE);
$branch->setRelatedStatement($this);
}
}
/**
* Compile statements in the 'else' block
*/
if (isset($this->_statement['else_statements'])) {
$compilationContext->codePrinter->output('} else {');
$st = new StatementsBlock($this->_statement['else_statements']);
$branch = $st->compile($compilationContext, $expr->isUnreachableElse(), Branch::TYPE_CONDITIONAL_FALSE);
$branch->setRelatedStatement($this);
}
$compilationContext->codePrinter->output('}');
}