Esempio n. 1
0
 public function evaluate(AST\Node $expression, array $environment) : float
 {
     if ($expression instanceof AST\Constant) {
         return $expression->getValue();
     } else {
         if ($expression instanceof AST\Variable) {
             if (!isset($environment[$expression->getName()])) {
                 throw new \Exception("'{$expression->getName()} must be defined!");
             }
             return $environment[$expression->getName()];
         } else {
             if ($expression instanceof AST\Operator) {
                 static $cachedOperators = [];
                 if (!isset($cachedOperators[$expression->getKind()])) {
                     $operatorFunction = create_function('$a, $b', 'return ' . OPERATORS[$expression->getKind()]['expression'] . ';');
                     $cachedOperators[$expression->getKind()] = $operatorFunction;
                 } else {
                     $operatorFunction = $cachedOperators[$expression->getKind()];
                 }
                 $left = $this->evaluate($expression->getLeftOperand(), $environment);
                 $right = $this->evaluate($expression->getRightOperand(), $environment);
                 return $operatorFunction($left, $right);
             } else {
                 if ($expression instanceof AST\FunctionCall) {
                     $arguments = array_map(function ($argument) use($environment) {
                         return $this->evaluate($argument, $environment);
                     }, $expression->getArguments());
                     return FUNCTIONS[$expression->getName()]['phpFunction'](...$arguments);
                 } else {
                     throw new \Exception("Unexpected node type " . get_class($expression));
                 }
             }
         }
     }
 }
Esempio n. 2
0
 private function compileExpression(AST\Node $expression) : string
 {
     if ($expression instanceof AST\Constant) {
         return var_export($expression->getValue(), true);
     } else {
         if ($expression instanceof AST\Variable) {
             return '$' . $expression->getName();
         } else {
             if ($expression instanceof AST\Operator) {
                 $operatorTemplate = OPERATORS[$expression->getKind()]['expression'];
                 $leftString = $this->compileExpression($expression->getLeftOperand());
                 $rightString = $this->compileExpression($expression->getRightOperand());
                 $string = preg_replace(['/\\$a/', '/\\$b/'], [$leftString, $rightString], $operatorTemplate);
                 return '(' . $string . ')';
             } else {
                 if ($expression instanceof AST\FunctionCall) {
                     $argumentStrings = array_map([$this, 'compileExpression'], $expression->getArguments());
                     $string = FUNCTIONS[$expression->getName()]['phpFunction'] . '(' . implode(',', $argumentStrings) . ')';
                     return $string;
                 } else {
                     throw new \Exception("Unexpected node type: {getclass({$expression})}");
                 }
             }
         }
     }
 }