public static function fromExpressions(array $expressions, IEvaluationContext $context = null)
{
$evaluator = new self($context);
$namespace = $evaluator->context->getNamespace();
$contextParameterName = self::CONTEXT_PARAMETER_NAME;
$variableTable = $evaluator->context->getVariableTable();
//Replace any non value types with references in the variable table.
$expressions = (new DynamicExpressionWalker([ValueExpression::getType() => function (ValueExpression $expression) use($evaluator, $variableTable, &$name) {
$value = $expression->getValue();
if (!ValueExpression::isValueType($value)) {
$name = $name !== null ? $name : 0;
do {
$name++;
} while (isset($variableTable['o' . $name]));
$name = 'o' . $name;
$evaluator->extraVariables[$name] = $value;
return Expression::variable(Expression::value($name));
}
return $expression;
}]))->walkAll($expressions);
$bodyCode = '';
foreach ($evaluator->extraVariables + $variableTable as $variable => $value) {
$variableName = Expression::value($variable);
$variableCode = Expression::variable($variableName)->compile();
$bodyCode .= "{$variableCode} =& \${$contextParameterName}" . '[' . $variableName->compile() . '];';
}
$bodyCode .= "unset(\${$contextParameterName});";
$bodyCode .= implode(';', Expression::compileAll($expressions)) . ';';
$evaluator->code = <<<PHP
namespace {$namespace} {
return function (\${$contextParameterName}) {
{$bodyCode}
};
}
PHP;
$evaluator->initializeEvaluator();
return $evaluator;
}