• Модуль: 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);
}