source: branches/0.4/web/addons/job_monarch/dwoo/plugins/builtin/functions/math.php @ 755

Last change on this file since 755 was 755, checked in by ramonb, 11 years ago
  • add Dwoo
File size: 3.7 KB
Line 
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 */
31function 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}
Note: See TracBrowser for help on using the repository browser.