Exemple #1
0
 static function eval_expression($args, $context)
 {
     $op_stack = array();
     $num_stack = array();
     $expression_pos = 0;
     // Tracks position in the expression for better error reporting.
     $back_track_pos = 0;
     // Tracks position in the expression when backtracking for better error reporting.
     foreach ($args as $arg) {
         $expression_pos++;
         if (is_array($arg) && isset($arg['operator'])) {
             $back_track_pos = $expression_pos;
             while (Evaluator::higher_op_on_stack($arg['operator'], $op_stack)) {
                 $val = Evaluator::eval_op_stack($op_stack, $num_stack, $back_track_pos);
                 $num_stack[] = $val;
             }
             $op_stack[] = $arg['operator'];
         } else {
             if (is_array($arg) && isset($arg['parentheses'])) {
                 if ($arg['parentheses'] === '(') {
                     $op_stack[] = '(';
                 } else {
                     $back_track_pos = $expression_pos;
                     while ($op = array_pop($op_stack)) {
                         if ($op === '(') {
                             break;
                         }
                         $op_stack[] = $op;
                         $num_stack[] = Evaluator::eval_op_stack($op_stack, $num_stack, $back_track_pos);
                     }
                     if (is_null($op)) {
                         throw new Exception("No opening paren for ')' at {$expression_pos}");
                     }
                 }
             } else {
                 $num_stack[] = $context->resolve($arg);
             }
         }
     }
     $back_track_pos = $expression_pos;
     while (count($op_stack) > 0) {
         $num_stack[] = Evaluator::eval_op_stack($op_stack, $num_stack, $back_track_pos);
     }
     return array_pop($num_stack);
 }