AutorÃa | Ultima modificación | Ver Log |
<?php// This file is part of Moodle - http://moodle.org///// Moodle is free software: you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation, either version 3 of the License, or// (at your option) any later version.//// Moodle is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the// GNU General Public License for more details.//// You should have received a copy of the GNU General Public License// along with Moodle. If not, see <http://www.gnu.org/licenses/>./*** Configurable Reports* A Moodle block for creating customizable reports* @package blocks* @author: Juan leyva <http://www.twitter.com/jleyvadelgado>* @date: 2009*//*evaluate postfix notationmodified to perform bitwise-like operations in arrays* => & => array_intersect+ => | => array_merge- => ^ => array_diff*/class EvalWise extends EvalMath {public $data = array();public $index = 0;public function set_data($data) {$this->data = $data;$this->index = count($this->data);}public function pfx($tokens, $vars = array()) {if ($tokens == false) {return false;}$stack = new \EvalMathStack;foreach ($tokens as $token) {// If the token is a function, pop arguments off the stack, hand them to the function, and push the result back on.if (is_array($token)) { // It's a function!$fnn = $token['fnn'];$count = $token['argcount'];if (in_array($fnn, $this->fb)) { // Built-in function.if (is_null($op1 = $stack->pop())) {return $this->trigger("internal error");}$fnn = preg_replace("/^arc/", "a", $fnn); // For the 'arc' trig synonyms.if ($fnn == 'ln') {$fnn = 'log';}eval('$stack->push(' . $fnn . '($op1));'); // Perfectly safe eval().} else if (array_key_exists($fnn, $this->fc)) { // Calc emulation function.// Get args.$args = array();for ($i = $count - 1; $i >= 0; $i--) {if (is_null($args[] = $stack->pop())) {return $this->trigger('internal error');}}$res = call_user_func(array('EvalMathCalcEmul', $fnn), $args);if ($res === false) {return $this->trigger("internal error");}$stack->push($res);} else if (array_key_exists($fnn, $this->f)) { // User function.// 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->trigger('internal error');}}$stack->push($this->pfx($this->f[$fnn]['func'], $args)); // Yay... recursion!!!!}} else if (in_array($token, array('+', '-', '*', '/', '^'), true)) {// If the token is a binary operator, pop two values off the stack, do the operation, and push the result back on.if (is_null($op2 = $stack->pop())) {return $this->trigger('internal error');}if (is_null($op1 = $stack->pop())) {return $this->trigger('internal error');}switch ($token) {case '+':$this->index += 1;$stack->push($this->index);$this->data[$this->index] = array_merge($this->data[$op1], $this->data[$op2]);break;case '-':$this->index += 1;$stack->push($this->index);$this->data[$this->index] = array_diff($this->data[$op1], $this->data[$op2]);break;case '*':$this->index += 1;$stack->push($this->index);$this->data[$this->index] = array_intersect($this->data[$op1], $this->data[$op2]);break;}} else if ($token == "_") {// If the token is a unary operator, pop one value off the stack, do the operation, and push it back on.$stack->push(-1 * $stack->pop());} else {// If the token is a number or variable, push it on the stack.if (is_numeric($token)) {$stack->push($token);} else if (array_key_exists($token, $this->v)) {$stack->push($this->v[$token]);} else if (array_key_exists($token, $vars)) {$stack->push($vars[$token]);} else {return $this->trigger("undefined variable '$token'");}}}// When we're out of tokens, the stack should have a single element, the final result.if ($stack->count != 1) {return $this->trigger("internal error");}$last = $stack->pop();if (isset($this->data[$last])) {return $this->data[$last];} else {return false;}}}