mirror of
https://github.com/slawkens/myaac.git
synced 2025-04-26 17:29:21 +02:00
131 lines
3.7 KiB
PHP
131 lines
3.7 KiB
PHP
<?php
|
|
|
|
/**
|
|
* Computes a mathematical equation
|
|
* <pre>
|
|
* * equation : the equation to compute, it can include normal variables with $foo or special math variables without the dollar sign
|
|
* * format : output format, see {@link http://php.net/sprintf} for details
|
|
* * assign : if set, the output is assigned into the given variable name instead of being output
|
|
* * rest : all math specific variables that you use must be defined, see the example
|
|
* </pre>
|
|
* Example :
|
|
*
|
|
* <code>
|
|
* {$c=2}
|
|
* {math "(a+b)*$c/4" a=3 b=5}
|
|
*
|
|
* output is : 4 ( = (3+5)*2/4)
|
|
* </code>
|
|
*
|
|
* This software is provided 'as-is', without any express or implied warranty.
|
|
* In no event will the authors be held liable for any damages arising from the use of this software.
|
|
*
|
|
* @author Jordi Boggiano <j.boggiano@seld.be>
|
|
* @copyright Copyright (c) 2008, Jordi Boggiano
|
|
* @license http://dwoo.org/LICENSE Modified BSD License
|
|
* @link http://dwoo.org/
|
|
* @version 1.0.0
|
|
* @date 2008-10-23
|
|
* @package Dwoo
|
|
*/
|
|
function Dwoo_Plugin_math_compile(Dwoo_Compiler $compiler, $equation, $format='', $assign='', array $rest=array())
|
|
{
|
|
/**
|
|
* Holds the allowed function, characters, operators and constants
|
|
*/
|
|
$allowed = array
|
|
(
|
|
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
|
|
'+', '-', '/', '*', '.', ' ', '<<', '>>', '%', '&', '^', '|', '~',
|
|
'abs(', 'ceil(', 'floor(', 'exp(', 'log10(',
|
|
'cos(', 'sin(', 'sqrt(', 'tan(',
|
|
'M_PI', 'INF', 'M_E',
|
|
);
|
|
|
|
/**
|
|
* Holds the functions that can accept multiple arguments
|
|
*/
|
|
$funcs = array
|
|
(
|
|
'round(', 'log(', 'pow(',
|
|
'max(', 'min(', 'rand(',
|
|
);
|
|
|
|
$equation = $equationSrc = str_ireplace(array('pi', 'M_PI()', 'inf', ' e '), array('M_PI', 'M_PI', 'INF', ' M_E '), $equation);
|
|
|
|
$delim = $equation[0];
|
|
$open = $delim.'.';
|
|
$close = '.'.$delim;
|
|
$equation = substr($equation, 1, -1);
|
|
$out = '';
|
|
$ptr = 1;
|
|
$allowcomma = 0;
|
|
while (strlen($equation) > 0) {
|
|
$substr = substr($equation, 0, $ptr);
|
|
if (array_search($substr, $allowed) !== false) {
|
|
// allowed string
|
|
$out.=$substr;
|
|
$equation = substr($equation, $ptr);
|
|
$ptr = 0;
|
|
} elseif (array_search($substr, $funcs) !== false) {
|
|
// allowed func
|
|
$out.=$substr;
|
|
$equation = substr($equation, $ptr);
|
|
$ptr = 0;
|
|
$allowcomma++;
|
|
if ($allowcomma === 1) {
|
|
$allowed[] = ',';
|
|
}
|
|
} elseif (isset($rest[$substr])) {
|
|
// variable
|
|
$out.=$rest[$substr];
|
|
$equation = substr($equation, $ptr);
|
|
$ptr = 0;
|
|
} elseif ($substr === $open) {
|
|
// pre-replaced variable
|
|
preg_match('#.*\((?:[^()]*?|(?R))\)'.str_replace('.', '\\.', $close).'#', substr($equation, 2), $m);
|
|
if (empty($m)) {
|
|
preg_match('#.*?'.str_replace('.', '\\.', $close).'#', substr($equation, 2), $m);
|
|
}
|
|
$out.=substr($m[0], 0, -2);
|
|
$equation = substr($equation, strlen($m[0])+2);
|
|
$ptr = 0;
|
|
} elseif ($substr==='(') {
|
|
// opening parenthesis
|
|
if ($allowcomma>0) {
|
|
$allowcomma++;
|
|
}
|
|
|
|
$out.=$substr;
|
|
$equation = substr($equation, $ptr);
|
|
$ptr = 0;
|
|
} elseif ($substr===')') {
|
|
// closing parenthesis
|
|
if ($allowcomma>0) {
|
|
$allowcomma--;
|
|
if ($allowcomma===0) {
|
|
array_pop($allowed);
|
|
}
|
|
}
|
|
|
|
$out.=$substr;
|
|
$equation = substr($equation, $ptr);
|
|
$ptr = 0;
|
|
} elseif ($ptr >= strlen($equation)) {
|
|
// parse error if we've consumed the entire equation without finding anything valid
|
|
throw new Dwoo_Compilation_Exception($compiler, 'Math : Syntax error or variable undefined in equation '.$equationSrc.' at '.$substr);
|
|
return;
|
|
} else {
|
|
// nothing special, advance
|
|
$ptr++;
|
|
}
|
|
}
|
|
if ($format !== '\'\'') {
|
|
$out = 'sprintf('.$format.', '.$out.')';
|
|
}
|
|
if ($assign !== '\'\'') {
|
|
return '($this->assignInScope('.$out.', '.$assign.'))';
|
|
}
|
|
return '('.$out.')';
|
|
}
|