- Модуль: bizproc
- Путь к файлу: ~/bitrix/modules/bizproc/classes/general/calc.php
- Класс: CBPCalc
- Вызов: CBPCalc::calculate
public function calculate($text)
{
if (!$arPolishNotation = $this->GetPolishNotation($text))
return null;
$stack = [];
foreach ($arPolishNotation as $item)
{
switch ($item[1])
{
case self::Constant:
array_unshift($stack, $item[0]);
break;
case self::Variable:
array_unshift($stack, $this->GetVariableValue($item[0]));
break;
case self::Operation:
switch ($item[0])
{
case ';':
$arg2 = array_shift($stack);
$arg1 = array_shift($stack);
if (!is_array($arg1) || !isset($arg1[0]))
$arg1 = [$arg1];
$arg1[] = $arg2;
array_unshift($stack, $arg1);
break;
case '=':
$arg2 = array_shift($stack);
$arg1 = array_shift($stack);
array_unshift($stack, $arg1 == $arg2);
break;
case '<=':
$arg2 = array_shift($stack);
$arg1 = array_shift($stack);
array_unshift($stack, $arg1 <= $arg2);
break;
case '>=':
$arg2 = array_shift($stack);
$arg1 = array_shift($stack);
array_unshift($stack, $arg1 >= $arg2);
break;
case '<>':
$arg2 = array_shift($stack);
$arg1 = array_shift($stack);
array_unshift($stack, $arg1 != $arg2);
break;
case '<':
$arg2 = array_shift($stack);
$arg1 = array_shift($stack);
array_unshift($stack, $arg1 < $arg2);
break;
case '>':
$arg2 = array_shift($stack);
$arg1 = array_shift($stack);
array_unshift($stack, $arg1 > $arg2);
break;
case '&':
$arg2 = (string) array_shift($stack);
$arg1 = (string) array_shift($stack);
array_unshift($stack, $arg1 . $arg2);
break;
case '+':
$arg2 = (float) array_shift($stack);
$arg1 = (float) array_shift($stack);
array_unshift($stack, $arg1 + $arg2);
break;
case '-':
$arg2 = (float) array_shift($stack);
$arg1 = (float) array_shift($stack);
array_unshift($stack, $arg1 - $arg2);
break;
case '+m':
$arg = (float) array_shift($stack);
array_unshift($stack, $arg);
break;
case '-m':
$arg = (float) array_shift($stack);
array_unshift($stack, (-$arg));
break;
case '*':
$arg2 = (float) array_shift($stack);
$arg1 = (float) array_shift($stack);
array_unshift($stack, $arg1 * $arg2);
break;
case '/':
$arg2 = (float) array_shift($stack);
$arg1 = (float) array_shift($stack);
if (0 == $arg2)
{
$this->SetError(6);
return null;
}
array_unshift($stack, $arg1 / $arg2);
break;
case '^':
$arg2 = (float) array_shift($stack);
$arg1 = (float) array_shift($stack);
array_unshift($stack, pow($arg1, $arg2));
break;
case '%':
$arg = (float) array_shift($stack);
array_unshift($stack, $arg / 100);
break;
default:
$func = $this->arAvailableFunctions[$item[0]]['func'];
if ($this->arAvailableFunctions[$item[0]]['args'])
{
$arg = array_shift($stack);
$val = $this->$func($arg);
}
else
{
$val = $this->$func();
}
$error = is_float($val) && (is_nan($val) || is_infinite($val));
if ($error)
{
$this->SetError(8, $item[0]);
return null;
}
array_unshift($stack, $val);
}
}
}
if (count($stack) > 1)
{
$this->SetError(7);
return null;
}
return array_shift($stack);
}