Source for file math.php

Documentation is available at math.php

  1. <?php
  2.  
  3. /**
  4.  * Computes a mathematical equation
  5.  * <pre>
  6.  *  * equation : the equation to compute, it can include normal variables with $foo or special math variables without the dollar sign
  7.  *  * format : output format, see {@link http://php.net/sprintf} for details
  8.  *  * assign : if set, the output is assigned into the given variable name instead of being output
  9.  *  * rest : all math specific variables that you use must be defined, see the example
  10.  * </pre>
  11.  * Example :
  12.  *
  13.  * <code>
  14.  * {$c=2}
  15.  * {math "(a+b)*$c/4" a=3 b=5}
  16.  *
  17.  * output is : 4 ( = (3+5)*2/4)
  18.  * </code>
  19.  *
  20.  * This software is provided 'as-is', without any express or implied warranty.
  21.  * In no event will the authors be held liable for any damages arising from the use of this software.
  22.  *
  23.  * @author     Jordi Boggiano <j.boggiano@seld.be>
  24.  * @copyright  Copyright (c) 2008, Jordi Boggiano
  25.  * @license    http://dwoo.org/LICENSE   Modified BSD License
  26.  * @link       http://dwoo.org/
  27.  * @version    1.0.0
  28.  * @date       2008-10-23
  29.  * @package    Dwoo
  30.  */
  31. function Dwoo_Plugin_math_compile(Dwoo_Compiler $compiler, $equation, $format='', $assign='', array $rest=array())
  32. {
  33.     /**
  34.      * Holds the allowed function, characters, operators and constants
  35.      */
  36.     $allowed = array
  37.     (
  38.         '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
  39.         '+', '-', '/', '*', '.', ' ', '<<', '>>', '%', '&', '^', '|', '~',
  40.         'abs(', 'ceil(', 'floor(', 'exp(', 'log10(',
  41.         'cos(', 'sin(', 'sqrt(', 'tan(',
  42.         'M_PI', 'INF', 'M_E',
  43.     );
  44.  
  45.     /**
  46.      * Holds the functions that can accept multiple arguments
  47.      */
  48.     $funcs = array
  49.     (
  50.          'round(', 'log(', 'pow(',
  51.         'max(', 'min(', 'rand(',
  52.      );
  53.  
  54.     $equation = $equationSrc = str_ireplace(array('pi', 'M_PI()', 'inf', ' e '), array('M_PI', 'M_PI', 'INF', ' M_E '), $equation);
  55.  
  56.     $delim = $equation[0];
  57.     $open = $delim.'.';
  58.     $close = '.'.$delim;
  59.     $equation = substr($equation, 1, -1);
  60.     $out = '';
  61.     $ptr = 1;
  62.     $allowcomma = 0;
  63.     while (strlen($equation) > 0) {
  64.         $substr = substr($equation, 0, $ptr);
  65.         if (array_search($substr, $allowed) !== false) {
  66.             // allowed string
  67.             $out.=$substr;
  68.             $equation = substr($equation, $ptr);
  69.             $ptr = 0;
  70.         } elseif (array_search($substr, $funcs) !== false) {
  71.             // allowed func
  72.             $out.=$substr;
  73.             $equation = substr($equation, $ptr);
  74.             $ptr = 0;
  75.             $allowcomma++;
  76.             if ($allowcomma === 1) {
  77.                 $allowed[] = ',';
  78.             }
  79.         } elseif (isset($rest[$substr])) {
  80.             // variable
  81.             $out.=$rest[$substr];
  82.             $equation = substr($equation, $ptr);
  83.             $ptr = 0;
  84.         } elseif ($substr === $open) {
  85.             // pre-replaced variable
  86.             preg_match('#.*\((?:[^()]*?|(?R))\)'.str_replace('.', '\\.', $close).'#', substr($equation, 2), $m);
  87.             if (empty($m)) {
  88.                 preg_match('#.*?'.str_replace('.', '\\.', $close).'#', substr($equation, 2), $m);
  89.             }
  90.             $out.=substr($m[0], 0, -2);
  91.             $equation = substr($equation, strlen($m[0])+2);
  92.             $ptr = 0;
  93.         } elseif ($substr==='(') {
  94.             // opening parenthesis
  95.             if ($allowcomma>0) {
  96.                 $allowcomma++;
  97.             }
  98.  
  99.             $out.=$substr;
  100.             $equation = substr($equation, $ptr);
  101.             $ptr = 0;
  102.         } elseif ($substr===')') {
  103.             // closing parenthesis
  104.             if ($allowcomma>0) {
  105.                 $allowcomma--;
  106.                 if ($allowcomma===0) {
  107.                     array_pop($allowed);
  108.                 }
  109.             }
  110.  
  111.             $out.=$substr;
  112.             $equation = substr($equation, $ptr);
  113.             $ptr = 0;
  114.         } elseif ($ptr >= strlen($equation)) {
  115.             // parse error if we've consumed the entire equation without finding anything valid
  116.             throw new Dwoo_Compilation_Exception($compiler, 'Math : Syntax error or variable undefined in equation '.$equationSrc.' at '.$substr);
  117.             return;
  118.         } else {
  119.             // nothing special, advance
  120.             $ptr++;
  121.         }
  122.     }
  123.     if ($format !== '\'\'') {
  124.         $out = 'sprintf('.$format.', '.$out.')';
  125.     }
  126.     if ($assign !== '\'\'') {
  127.         return '($this->assignInScope('.$out.', '.$assign.'))';
  128.     }
  129.     return '('.$out.')';
  130. }

Documentation generated on Sun, 07 Feb 2010 17:53:53 +0000 by phpDocumentor 1.4.0