Esempio n. 1
0
 public function testInsertAndRemove()
 {
     $Stack = new Stack();
     $Stack->push('Radig');
     $this->assertIdentical($Stack->size(), 1);
     $this->assertIdentical($Stack->nth(), 'Radig');
     $Stack->push('CakePHP');
     $this->assertIdentical($Stack->size(), 2);
     // testa com 1-lookahead
     $this->assertIdentical($Stack->nth(), 'CakePHP');
     // teste com 2-lookahead
     $this->assertIdentical($Stack->nth(2), 'Radig');
     $this->assertIdentical($Stack->pop(), 'CakePHP');
     $this->assertIdentical($Stack->pop(), 'Radig');
     $this->assertIdentical($Stack->pop(), null);
     unset($Stack);
 }
Esempio n. 2
0
 /**
  * Evaluate postfix notation
  *
  * @param array $tokens
  * @param array $vars
  *
  * @return mixed boolean *false* in failures and *numeric* value in success
  */
 protected function pfx($tokens, $vars = array())
 {
     bcscale($this->precision);
     if ($tokens === false) {
         return false;
     }
     $stack = new Stack();
     foreach ($tokens as $token) {
         // if the token is a binary operator, pop two values off the stack, do the operation, and push the result back on
         if (in_array($token, array('+', '-', '*', '/', '^'))) {
             if (is_null($op2 = $stack->pop()) || is_null($op1 = $stack->pop())) {
                 return $this->error("Internal error");
             }
             switch ($token) {
                 case '+':
                     $stack->push(bcadd($op1, $op2));
                     break;
                 case '-':
                     $stack->push(bcsub($op1, $op2));
                     break;
                 case '*':
                     $stack->push(bcmul($op1, $op2));
                     break;
                 case '/':
                     if ($op2 == 0) {
                         return $this->error("Division by zero");
                     }
                     $stack->push(bcdiv($op1, $op2));
                     break;
                 case '^':
                     $stack->push(bcpow($op1, $op2));
                     break;
             }
             // if the token is a unary operator, pop one value off the stack, do the operation, and push it back on
         } elseif ($token == "_") {
             // if the token is a function, pop arguments off the stack, hand them to the function, and push the result back on
             $stack->push(-1 * $stack->pop());
         } elseif (preg_match("/^([a-z]\\w*)\\(\$/", $token, $matches)) {
             // it's a function!
             $fnn = $matches[1];
             // built-in function:
             if (in_array($fnn, $this->fb)) {
                 if (is_null($op1 = $stack->pop())) {
                     return $this->error("Internal error");
                 }
                 // for the 'arc' trig synonyms
                 $fnn = preg_replace("/^arc/", "a", $fnn);
                 if ($fnn == 'ln') {
                     $fnn = 'log';
                 }
                 if ($fnn == 'sqrt') {
                     $fnn = 'bcsqrt';
                 }
                 $val = $this->strictPrecision(call_user_func($fnn, $op1));
                 $stack->push($val);
             } elseif (array_key_exists($fnn, $this->f)) {
                 // get args
                 $args = array();
                 for ($i = count($this->f[$fnn]['args']) - 1; $i >= 0; $i--) {
                     if (is_null($args[$this->f[$fnn]['args'][$i]] = $stack->pop())) {
                         return $this->error("Internal error");
                     }
                 }
                 $stack->push($this->pfx($this->f[$fnn]['func'], $args));
                 // yay... recursion!!!!
             }
         } else {
             if (is_numeric($token)) {
                 $stack->push($this->strictPrecision($token));
             } elseif (array_key_exists($token, $this->v)) {
                 $stack->push($this->strictPrecision($this->v[$token]));
             } elseif (array_key_exists($token, $vars)) {
                 $stack->push($this->strictPrecision($vars[$token]));
             } else {
                 return $this->error("Undefined variable '{$token}'");
             }
         }
     }
     // when we're out of tokens, the stack should have a single element, the final result
     if ($stack->size() != 1) {
         return $this->error("Internal error");
     }
     return $stack->pop();
 }