94     var 
$v = array(
'e'=>2.71,
'pi'=>3.14); 
 
   96     var 
$vb = array(
'e', 
'pi'); 
 
   98         'sin',
'sinh',
'arcsin',
'asin',
'arcsinh',
'asinh',
 
   99         'cos',
'cosh',
'arccos',
'acos',
'arccosh',
'acosh',
 
  100         'tan',
'tanh',
'arctan',
'atan',
'arctanh',
'atanh',
 
  101         'sqrt',
'abs',
'ln',
'log');
 
  105         $this->v[
'pi'] = pi();
 
  106         $this->v[
'exp'] = exp(1);
 
  115                         $expr = preg_replace(
"/(\\d{0,1})e(-{0,1}\\d+)/eis", 
"'\\1'.((strlen('\\1')) ? '*' : '').'10^(\\2)'", $expr);
 
  117         $this->last_error = null;
 
  119         if (substr($expr, -1, 1) == 
';') $expr = substr($expr, 0, strlen($expr)-1); 
 
  122         if (preg_match(
'/^\s*([a-z]\w*)\s*=\s*(.+)$/', $expr, $matches)) {
 
  123             if (in_array($matches[1], $this->vb)) { 
 
  124                 return $this->
trigger(
"cannot assign to constant '$matches[1]'");
 
  126             if (($tmp = $this->
pfx($this->
nfx($matches[2]))) === 
false) 
return false; 
 
  127             $this->v[$matches[1]] = $tmp; 
 
  128             return $this->v[$matches[1]]; 
 
  131         } elseif (preg_match(
'/^\s*([a-z]\w*)\s*\(\s*([a-z]\w*(?:\s*,\s*[a-z]\w*)*)\s*\)\s*=\s*(.+)$/', $expr, $matches)) {
 
  133             if (in_array($matches[1], $this->fb)) { 
 
  134                 return $this->
trigger(
"cannot redefine built-in function '$matches[1]()'");
 
  136             $args = explode(
",", preg_replace(
"/\s+/", 
"", $matches[2])); 
 
  137             if (($stack = $this->
nfx($matches[3])) === 
false) 
return false; 
 
  138             for ($i = 0; $i<count($stack); $i++) { 
 
  140                 if (preg_match(
'/^[a-z]\w*$/', $token) and !in_array($token, $args)) {
 
  141                     if (array_key_exists($token, $this->v)) {
 
  142                         $stack[$i] = $this->v[$token];
 
  144                         return $this->
trigger(
"undefined variable '$token' in function definition");
 
  148             $this->f[$fnn] = array(
'args'=>$args, 
'func'=>$stack);
 
  152             return $this->
pfx($this->
nfx($expr)); 
 
  158         unset($output[
'pi']);
 
  165         foreach ($this->f as $fnn=>$dat)
 
  166             $output[] = $fnn . 
'(' . implode(
',', $dat[
'args']) . 
')';
 
  178         $expr = trim(strtolower($expr));
 
  180         $ops   = array(
'+', 
'-', 
'*', 
'/', 
'^', 
'_');
 
  181         $ops_r = array(
'+'=>0,
'-'=>0,
'*'=>0,
'/'=>0,
'^'=>1); 
 
  182         $ops_p = array(
'+'=>0,
'-'=>0,
'*'=>1,
'/'=>1,
'_'=>1,
'^'=>2); 
 
  184         $expecting_op = 
false; 
 
  187         if (preg_match(
"/[^\w\s+*^\/()\.,-]/", $expr, $matches)) { 
 
  188             return $this->
trigger(
"illegal character '{$matches[0]}'");
 
  192             $op = substr($expr, $index, 1); 
 
  194             $ex = preg_match(
'/^([01]+[bB]|[\da-fA-F]+[hH]|[a-z]\w*\(?|\d+(?:\.\d*)?|\.\d+|\()/', substr($expr, $index), $match);
 
  196             if ($op == 
'-' and !$expecting_op) { 
 
  199             } elseif ($op == 
'_') { 
 
  200                 return $this->
trigger(
"illegal character '_'"); 
 
  202             } elseif ((in_array($op, $ops) or $ex) and $expecting_op) { 
 
  207                 while($stack->count > 0 and ($o2 = $stack->last()) and in_array($o2, $ops) and ($ops_r[$op] ? $ops_p[$op] < $ops_p[$o2] : $ops_p[$op] <= $ops_p[$o2])) {
 
  208                     $output[] = $stack->pop(); 
 
  213                 $expecting_op = 
false;
 
  215             } elseif ($op == 
')' and $expecting_op) { 
 
  216                 while (($o2 = $stack->pop()) != 
'(') { 
 
  217                     if (is_null($o2)) 
return $this->
trigger(
"unexpected ')'");
 
  218                     else $output[] = $o2;
 
  220                 if (preg_match(
"/^([a-z]\w*)\($/", $stack->last(2), $matches)) { 
 
  222                     $arg_count = $stack->pop(); 
 
  223                     $output[] = $stack->pop(); 
 
  224                     if (in_array($fnn, $this->fb)) { 
 
  226                             return $this->
trigger(
"too many arguments ($arg_count given, 1 expected)");
 
  227                     } elseif (array_key_exists($fnn, $this->f)) {
 
  228                         if ($arg_count != count($this->f[$fnn][
'args']))
 
  229                             return $this->
trigger(
"wrong number of arguments ($arg_count given, " . count($this->f[$fnn][
'args']) . 
" expected)");
 
  231                         return $this->
trigger(
"internal error");
 
  236             } elseif ($op == 
',' and $expecting_op) { 
 
  237                 while (($o2 = $stack->pop()) != 
'(') { 
 
  238                     if (is_null($o2)) 
return $this->
trigger(
"unexpected ','"); 
 
  239                     else $output[] = $o2; 
 
  242                 if (!preg_match(
"/^([a-z]\w*)\($/", $stack->last(2), $matches))
 
  243                     return $this->
trigger(
"unexpected ','");
 
  244                 $stack->push($stack->pop()+1); 
 
  247                 $expecting_op = 
false;
 
  249             } elseif ($op == 
'(' and !$expecting_op) {
 
  254             } elseif ($ex and !$expecting_op) { 
 
  255                 $expecting_op = 
true;
 
  257                 if (preg_match(
"/^([a-z]\w*)\($/", $val, $matches)) { 
 
  258                     if (in_array($matches[1], $this->fb) or array_key_exists($matches[1], $this->f)) { 
 
  262                         $expecting_op = 
false;
 
  270                 $index += strlen($val);
 
  272             } elseif ($op == 
')') { 
 
  273                 return $this->
trigger(
"unexpected ')'");
 
  274             } elseif (in_array($op, $ops) and !$expecting_op) {
 
  275                 return $this->
trigger(
"unexpected operator '$op'");
 
  277                 return $this->
trigger(
"an unexpected error occured");
 
  279             if ($index == strlen($expr)) {
 
  280                 if (in_array($op, $ops)) { 
 
  281                     return $this->
trigger(
"operator '$op' lacks operand");
 
  286             while (substr($expr, $index, 1) == 
' ') { 
 
  291         while (!is_null($op = $stack->pop())) { 
 
  292             if ($op == 
'(') 
return $this->
trigger(
"expecting ')'"); 
 
  299     function pfx($tokens, $vars = array()) {
 
  301         if ($tokens == 
false) 
return false;
 
  305         foreach ($tokens as $token) { 
 
  307             if (in_array($token, array(
'+', 
'-', 
'*', 
'/', 
'^'))) {
 
  308                 if (is_null($op2 = $stack->pop())) 
return $this->
trigger(
"internal error");
 
  309                 if (is_null($op1 = $stack->pop())) 
return $this->
trigger(
"internal error");
 
  310                                                                 include_once 
"class.ilMath.php";
 
  319                                                                                         if ($op2 == 0) 
return $this->
trigger(
"division by zero");
 
  325             } elseif ($token == 
"_") {
 
  326                 $stack->push(-1*$stack->pop());
 
  328             } elseif (preg_match(
"/^([a-z]\w*)\($/", $token, $matches)) { 
 
  330                 if (in_array($fnn, $this->fb)) { 
 
  331                     if (is_null($op1 = $stack->pop())) 
return $this->
trigger(
"internal error");
 
  332                     $fnn = preg_replace(
"/^arc/", 
"a", $fnn); 
 
  333                     if ($fnn == 
'ln') $fnn = 
'log';
 
  334                     eval(
'$stack->push(' . $fnn . 
'($op1));'); 
 
  335                 } elseif (array_key_exists($fnn, $this->f)) { 
 
  338                     for ($i = count($this->f[$fnn][
'args'])-1; $i >= 0; $i--) {
 
  339                         if (is_null($args[$this->f[$fnn][
'args'][$i]] = $stack->pop())) 
return $this->
trigger(
"internal error");
 
  341                     $stack->push($this->
pfx($this->f[$fnn][
'func'], $args)); 
 
  345                 if (is_numeric($token)) {
 
  346                     $stack->push($token);
 
  347                 } elseif (($hex=$this->
from_hexbin($token))!==FALSE) {
 
  349                 } elseif (array_key_exists($token, $this->v)) {
 
  350                     $stack->push($this->v[$token]);
 
  351                 } elseif (array_key_exists($token, $vars)) {
 
  352                     $stack->push($vars[$token]);
 
  354                     return $this->
trigger(
"undefined variable '$token'");
 
  359         if ($stack->count != 1) 
return $this->
trigger(
"internal error");
 
  360         return $stack->pop();
 
  365         $this->last_error = $msg;
 
  366         if (!$this->suppress_errors) trigger_error($msg, E_USER_WARNING);
 
  373       if (strtoupper(substr($token, -1, 1))==
'H')  
return hexdec($token);
 
  374       if (strtoupper(substr($token, -1, 1))==
'B')  
return bindec($token);
 
  391         if ($this->count > 0) {
 
  399         return $this->stack[$this->count-
$n];