/home/techb158/ileadtechnology.com/SSM/app/Helper
Edit: /home/techb158/ileadtechnology.com/SSM/app/Helper/MathExpression.php (6149B)
pos;
$ist = ($this->text[$this->pos] ?? false) == '"';
if ($ist) $this->pos++;
while ((($char = $this->text[$this->pos] ?? false) !== false) && (($ist && ($char != '"')) || ctype_alnum($char) || in_array($char, ['_', '.'])))
$this->pos++;
if (!$len = $this->pos - $ops) return false;
$str = substr($this->text, $ops, $len);
if ($ist) {
if ($char != '"') return false;
$this->pos++;
$value = substr($str, 1);
$kind = 4;
return true;
}
if (is_numeric($str)) $kind = 1;
else {
if (ctype_digit($str[0]) || (strpos($str, '.') !== false)) return false;
$kind = $char == '(' ? 3 : 2;
}
$value = $str;
return true;
}
private function getVariable(string $name): float {
$value = $this->variables[$name] ?? null;
if (!isset($value) && isset($this->onVariable)) {
call_user_func_array($this->onVariable, [$name, &$value]);
$this->variables[$name] = $value;
}
if (!isset($value))
throw new Exception('Unknown variable: '.$name, 5);
return $value;
}
private function addArgument(&$arguments, $argument) {
if ($argument == '')
throw new Exception('Empty argument', 4);
$arguments[] = $argument;
}
private function getArguments(&$arguments = []): bool {
$b = 1;
$this->pos++;
$mark = $this->pos;
while ((($char = $this->text[$this->pos] ?? false) !== false) && ($b > 0)) {
if (($char == ',') && ($b == 1)) {
$this->addArgument($arguments, substr($this->text, $mark, $this->pos - $mark));
$mark = $this->pos + 1;
}
elseif ($char == ')') $b--;
elseif ($char == '(') $b++;
$this->pos++;
}
if (!in_array($char, [false, '+', '-', '/', '*', '^', ')']))
return false;
$this->addArgument($arguments, substr($this->text, $mark, $this->pos - $mark - 1));
return true;
}
private function proArguments($arguments) {
$ops = $this->pos;
$otx = $this->text;
$result = [];
foreach ($arguments as $argument)
$result[] = $this->perform($argument);
$this->pos = $ops;
$this->text = $otx;
return $result;
}
private function getFunction(string $name) {
$routine = $this->functions[$name] ?? null;
if (!isset($routine) && isset($this->onFunction)) {
call_user_func_array($this->onFunction, [$name, &$routine]);
$this->functions[$name] = $routine;
}
if (!isset($routine))
throw new Exception('Unknown function: '.$name, 6);
if (!$this->getArguments($arguments))
throw new Exception('Syntax error', 1);
if (isset($routine['arc']) && ($routine['arc'] != count($arguments)))
throw new Exception('Invalid argument count', 3);
return call_user_func_array($routine['ref'], $this->proArguments($arguments));
}
private function term() {
if ($this->text[$this->pos] == '(') {
$this->pos++;
$value = $this->calculate();
$this->pos++;
if (!in_array($this->text[$this->pos] ?? false, [false, '+', '-', '/', '*', '^', ')']))
throw new Exception('Syntax error', 1);
return $value;
}
if (!$this->getIdentity($kind, $name))
throw new Exception('Syntax error', 1);
switch ($kind) {
case 1: return (float) $name;
case 2: return $this->getVariable($name);
case 3: return $this->getFunction($name);
case 4: return $name; // string
}
}
private function subTerm() {
$value = $this->term();
while (in_array($char = $this->text[$this->pos] ?? false, ['*', '^', '/'])) {
$this->pos++;
$term = $this->term();
switch ($char) {
case '*':
$value = $value * $term;
break;
case '/':
if ($term == 0)
throw new Exception('Division by zero', 7);
$value = $value / $term;
break;
case '^':
$value = pow($value, $term);
break;
}
}
return $value;
}
private function calculate() {
$value = $this->subTerm();
while (in_array($char = $this->text[$this->pos] ?? false, ['+', '-'])) {
$this->pos++;
$subTerm = $this->subTerm();
if (($char == '+') && is_string($value)) {
$value .= $subTerm;
continue;
}
if ($char == '-') $subTerm = -$subTerm;
$value += $subTerm;
}
return $value;
}
private function perform(string $formula) {
$this->pos = 0;
if (in_array($formula[0], ['-', '+']))
$formula = '0'.$formula;
$this->text = $formula;
return $this->calculate();
}
public function execute(string $formula) {
$b = 0;
for ($i = 0; $i < strlen($formula); $i++) {
switch ($formula[$i]) {
case '(': $b++; break;
case ')': $b--; break;
}
}
if ($b != 0)
throw new Exception('Unmatched brackets', 2);
$i = strpos($formula, '"');
if ($i === false)
$formula = str_replace(' ', '', strtolower($formula));
else {
$cleaned = '';
$l = strlen($formula);
$s = 0;
$b = false;
do {
if ($b) $i++;
$part = substr($formula, $s, $i - $s);
if (!$b) $part = str_replace(' ', '', strtolower($part));
$s = $i;
$b = !$b;
$cleaned .= $part;
$d = $s + 1;
if ($l < $d) break;
} while (($i = strpos($formula, '"', $d)) !== false);
if ($l != $s)
$cleaned .= str_replace(' ', '', strtolower(substr($formula, $s)));
$formula = $cleaned;
}
return $this->perform($formula);
}
}