/** * Creates a new compiled evaluator from the supplied expressions. * * @param Expression[] $expressions * @param IEvaluationContext $context * * @return CompiledEvaluator */ 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; }
/** * @return VariableExpression */ public function asVariable() { return Expression::variable(Expression::value($this->name)); }