aboutsummaryrefslogtreecommitdiff
path: root/src/NXP/MathExecutor.php
diff options
context:
space:
mode:
Diffstat (limited to 'src/NXP/MathExecutor.php')
-rw-r--r--src/NXP/MathExecutor.php846
1 files changed, 430 insertions, 416 deletions
diff --git a/src/NXP/MathExecutor.php b/src/NXP/MathExecutor.php
index ab550fa..f980270 100644
--- a/src/NXP/MathExecutor.php
+++ b/src/NXP/MathExecutor.php
@@ -31,7 +31,7 @@ class MathExecutor
*
* @var array<string, float|string>
*/
- protected $variables = [];
+ protected array $variables = [];
/**
* @var callable|null
@@ -46,17 +46,17 @@ class MathExecutor
/**
* @var Operator[]
*/
- protected $operators = [];
+ protected array $operators = [];
/**
* @var array<string, CustomFunction>
*/
- protected $functions = [];
+ protected array $functions = [];
/**
* @var array<string, Token[]>
*/
- protected $cache = [];
+ protected array $cache = [];
/**
* Base math operators
@@ -66,386 +66,39 @@ class MathExecutor
$this->addDefaults();
}
- /**
- * Set default operands and functions
- * @throws ReflectionException
- */
- protected function addDefaults(): void
- {
- foreach ($this->defaultOperators() as $name => $operator) {
- [$callable, $priority, $isRightAssoc] = $operator;
- $this->addOperator(new Operator($name, $isRightAssoc, $priority, $callable));
- }
- foreach ($this->defaultFunctions() as $name => $callable) {
- $this->addFunction($name, $callable);
- }
-
- $this->onVarValidation = [$this, 'defaultVarValidation'];
- $this->variables = $this->defaultVars();
- }
-
- /**
- * Get the default operators
- *
- * @return array<string, array{callable, int, bool}>
- */
- protected function defaultOperators(): array
+ public function __clone()
{
- return [
- '+' => [
- function ($a, $b) {
- return $a + $b;
- },
- 170,
- false
- ],
- '-' => [
- function ($a, $b) {
- return $a - $b;
- },
- 170,
- false
- ],
- 'uPos' => [ // unary positive token
- function ($a) {
- return $a;
- },
- 200,
- false
- ],
- 'uNeg' => [ // unary minus token
- function ($a) {
- return 0 - $a;
- },
- 200,
- false
- ],
- '*' => [
- function ($a, $b) {
- return $a * $b;
- },
- 180,
- false
- ],
- '/' => [
- function ($a, $b) {
- if ($b == 0) {
- throw new DivisionByZeroException();
- }
- return $a / $b;
- },
- 180,
- false
- ],
- '^' => [
- function ($a, $b) {
- return pow($a, $b);
- },
- 220,
- true
- ],
- '&&' => [
- function ($a, $b) {
- return $a && $b;
- },
- 100,
- false
- ],
- '||' => [
- function ($a, $b) {
- return $a || $b;
- },
- 90,
- false
- ],
- '==' => [
- function ($a, $b) {
- if (is_string($a) || is_string($b)) {
- return strcmp($a, $b) == 0;
- } else {
- return $a == $b;
- }
- },
- 140,
- false
- ],
- '!=' => [
- function ($a, $b) {
- if (is_string($a) || is_string($b)) {
- return strcmp($a, $b) != 0;
- } else {
- return $a != $b;
- }
- },
- 140,
- false
- ],
- '>=' => [
- function ($a, $b) {
- return $a >= $b;
- },
- 150,
- false
- ],
- '>' => [
- function ($a, $b) {
- return $a > $b;
- },
- 150,
- false
- ],
- '<=' => [
- function ($a, $b) {
- return $a <= $b;
- },
- 150,
- false
- ],
- '<' => [
- function ($a, $b) {
- return $a < $b;
- },
- 150,
- false
- ],
- ];
+ $this->addDefaults();
}
/**
* Add operator to executor
*
- * @param Operator $operator
* @return MathExecutor
*/
- public function addOperator(Operator $operator): self
+ public function addOperator(Operator $operator) : self
{
$this->operators[$operator->operator] = $operator;
- return $this;
- }
- /**
- * Gets the default functions as an array. Key is function name
- * and value is the function as a closure.
- *
- * @return array<callable>
- */
- protected function defaultFunctions(): array
- {
- return [
- 'abs' => function ($arg) {
- return abs($arg);
- },
- 'acos' => function ($arg) {
- return acos($arg);
- },
- 'acosh' => function ($arg) {
- return acosh($arg);
- },
- 'arcsin' => function ($arg) {
- return asin($arg);
- },
- 'arcctg' => function ($arg) {
- return M_PI/2 - atan($arg);
- },
- 'arccot' => function ($arg) {
- return M_PI/2 - atan($arg);
- },
- 'arccotan' => function ($arg) {
- return M_PI/2 - atan($arg);
- },
- 'arcsec' => function ($arg) {
- return acos(1/$arg);
- },
- 'arccosec' => function ($arg) {
- return asin(1/$arg);
- },
- 'arccsc' => function ($arg) {
- return asin(1/$arg);
- },
- 'arccos' => function ($arg) {
- return acos($arg);
- },
- 'arctan' => function ($arg) {
- return atan($arg);
- },
- 'arctg' => function ($arg) {
- return atan($arg);
- },
- 'asin' => function ($arg) {
- return asin($arg);
- },
- 'atan' => function ($arg) {
- return atan($arg);
- },
- 'atan2' => function ($arg1, $arg2) {
- return atan2($arg1, $arg2);
- },
- 'atanh' => function ($arg) {
- return atanh($arg);
- },
- 'atn' => function ($arg) {
- return atan($arg);
- },
- 'avg' => function ($arg1, $arg2) {
- return ($arg1 + $arg2) / 2;
- },
- 'bindec' => function ($arg) {
- return bindec($arg);
- },
- 'ceil' => function ($arg) {
- return ceil($arg);
- },
- 'cos' => function ($arg) {
- return cos($arg);
- },
- 'cosec' => function ($arg) {
- return 1 / sin($arg);
- },
- 'csc' => function ($arg) {
- return 1 / sin($arg);
- },
- 'cosh' => function ($arg) {
- return cosh($arg);
- },
- 'ctg' => function ($arg) {
- return cos($arg) / sin($arg);
- },
- 'cot' => function ($arg) {
- return cos($arg) / sin($arg);
- },
- 'cotan' => function ($arg) {
- return cos($arg) / sin($arg);
- },
- 'cotg' => function ($arg) {
- return cos($arg) / sin($arg);
- },
- 'ctn' => function ($arg) {
- return cos($arg) / sin($arg);
- },
- 'decbin' => function ($arg) {
- return decbin($arg);
- },
- 'dechex' => function ($arg) {
- return dechex($arg);
- },
- 'decoct' => function ($arg) {
- return decoct($arg);
- },
- 'deg2rad' => function ($arg) {
- return deg2rad($arg);
- },
- 'exp' => function ($arg) {
- return exp($arg);
- },
- 'expm1' => function ($arg) {
- return expm1($arg);
- },
- 'floor' => function ($arg) {
- return floor($arg);
- },
- 'fmod' => function ($arg1, $arg2) {
- return fmod($arg1, $arg2);
- },
- 'hexdec' => function ($arg) {
- return hexdec($arg);
- },
- 'hypot' => function ($arg1, $arg2) {
- return hypot($arg1, $arg2);
- },
- 'if' => function ($expr, $trueval, $falseval) {
- if ($expr === true || $expr === false) {
- $exres = $expr;
- } else {
- $exres = $this->execute($expr);
- }
- if ($exres) {
- return $this->execute($trueval);
- } else {
- return $this->execute($falseval);
- }
- },
- 'intdiv' => function ($arg1, $arg2) {
- return intdiv($arg1, $arg2);
- },
- 'ln' => function ($arg) {
- return log($arg);
- },
- 'lg' => function ($arg) {
- return log10($arg);
- },
- 'log' => function ($arg) {
- return log($arg);
- },
- 'log10' => function ($arg) {
- return log10($arg);
- },
- 'log1p' => function ($arg) {
- return log1p($arg);
- },
- 'max' => function ($arg1, $arg2) {
- return max($arg1, $arg2);
- },
- 'min' => function ($arg1, $arg2) {
- return min($arg1, $arg2);
- },
- 'octdec' => function ($arg) {
- return octdec($arg);
- },
- 'pi' => function () {
- return pi();
- },
- 'pow' => function ($arg1, $arg2) {
- return $arg1 ** $arg2;
- },
- 'rad2deg' => function ($arg) {
- return rad2deg($arg);
- },
- 'round' => function ($arg) {
- return round($arg);
- },
- 'sin' => function ($arg) {
- return sin($arg);
- },
- 'sinh' => function ($arg) {
- return sinh($arg);
- },
- 'sec' => function ($arg) {
- return 1 / cos($arg);
- },
- 'sqrt' => function ($arg) {
- return sqrt($arg);
- },
- 'tan' => function ($arg) {
- return tan($arg);
- },
- 'tanh' => function ($arg) {
- return tanh($arg);
- },
- 'tn' => function ($arg) {
- return tan($arg);
- },
- 'tg' => function ($arg) {
- return tan($arg);
- }
- ];
+ return $this;
}
/**
* Execute expression
*
- * @param string $expression
- * @param bool $cache
- * @return number
* @throws Exception\IncorrectBracketsException
* @throws Exception\IncorrectExpressionException
* @throws Exception\UnknownOperatorException
* @throws UnknownVariableException
+ * @return number
*/
public function execute(string $expression, bool $cache = true)
{
$cacheKey = $expression;
- if (!array_key_exists($cacheKey, $this->cache)) {
+
+ if (! \array_key_exists($cacheKey, $this->cache)) {
$tokens = (new Tokenizer($expression, $this->operators))->tokenize()->buildReversePolishNotation();
+
if ($cache) {
$this->cache[$cacheKey] = $tokens;
}
@@ -454,6 +107,7 @@ class MathExecutor
}
$calculator = new Calculator($this->functions, $this->operators);
+
return $calculator->calculate($tokens, $this->variables, $this->onVarNotFound);
}
@@ -463,26 +117,14 @@ class MathExecutor
* @param string $name Name of function
* @param callable $function Function
* @param int $places Count of arguments
- * @return MathExecutor
* @throws ReflectionException
+ * @return MathExecutor
*/
- public function addFunction(string $name, ?callable $function = null, ?int $places = null): self
+ public function addFunction(string $name, ?callable $function = null, ?int $places = null) : self
{
$this->functions[$name] = new CustomFunction($name, $function, $places);
- return $this;
- }
- /**
- * Returns the default variables names as key/value pairs
- *
- * @return array<string, float>
- */
- protected function defaultVars(): array
- {
- return [
- 'pi' => 3.14159265359,
- 'e' => 2.71828182846
- ];
+ return $this;
}
/**
@@ -490,7 +132,7 @@ class MathExecutor
*
* @return array<string, float|string>
*/
- public function getVars(): array
+ public function getVars() : array
{
return $this->variables;
}
@@ -498,61 +140,47 @@ class MathExecutor
/**
* Get a specific var
*
- * @param string $variable
- * @return integer|float
* @throws UnknownVariableException if VarNotFoundHandler is not set
+ * @return int|float
*/
public function getVar(string $variable)
{
- if (!array_key_exists($variable, $this->variables)) {
+ if (! \array_key_exists($variable, $this->variables)) {
if ($this->onVarNotFound) {
- return call_user_func($this->onVarNotFound, $variable);
+ return \call_user_func($this->onVarNotFound, $variable);
}
+
throw new UnknownVariableException("Variable ({$variable}) not set");
}
+
return $this->variables[$variable];
}
/**
* Add variable to executor. To set a custom validator use setVarValidationHandler.
*
- * @param string $variable
* @param $value
- * @return MathExecutor
* @throws MathExecutorException if the value is invalid based on the default or custom validator
+ * @return MathExecutor
*/
- public function setVar(string $variable, $value): self
+ public function setVar(string $variable, $value) : self
{
if ($this->onVarValidation) {
- call_user_func($this->onVarValidation, $variable, $value);
+ \call_user_func($this->onVarValidation, $variable, $value);
}
$this->variables[$variable] = $value;
- return $this;
- }
- /**
- * Default variable validation, ensures that the value is a scalar.
- * @param string $variable
- * @param $value
- * @throws MathExecutorException if the value is not a scalar
- */
- protected function defaultVarValidation(string $variable, $value): void
- {
- if (!is_scalar($value) && $value !== null) {
- $type = gettype($value);
- throw new MathExecutorException("Variable ({$variable}) type ({$type}) is not scalar");
- }
+ return $this;
}
/**
* Test to see if a variable exists
*
- * @param string $variable
*/
- public function varExists(string $variable): bool
+ public function varExists(string $variable) : bool
{
- return array_key_exists($variable, $this->variables);
+ return \array_key_exists($variable, $this->variables);
}
/**
@@ -560,17 +188,19 @@ class MathExecutor
*
* @param array<string, float|int|string> $variables
* @param bool $clear Clear previous variables
- * @return MathExecutor
* @throws \Exception
+ * @return MathExecutor
*/
- public function setVars(array $variables, bool $clear = true): self
+ public function setVars(array $variables, bool $clear = true) : self
{
if ($clear) {
$this->removeVars();
}
+
foreach ($variables as $name => $value) {
$this->setVar($name, $value);
}
+
return $this;
}
@@ -578,13 +208,13 @@ class MathExecutor
* Define a method that will be invoked when a variable is not found.
* The first parameter will be the variable name, and the returned value will be used as the variable value.
*
- * @param callable $handler
*
* @return MathExecutor
*/
- public function setVarNotFoundHandler(callable $handler): self
+ public function setVarNotFoundHandler(callable $handler) : self
{
$this->onVarNotFound = $handler;
+
return $this;
}
@@ -597,21 +227,22 @@ class MathExecutor
*
* @return MathExecutor
*/
- public function setVarValidationHandler(?callable $handler): self
+ public function setVarValidationHandler(?callable $handler) : self
{
$this->onVarValidation = $handler;
+
return $this;
}
/**
* Remove variable from executor
*
- * @param string $variable
* @return MathExecutor
*/
- public function removeVar(string $variable): self
+ public function removeVar(string $variable) : self
{
unset($this->variables[$variable]);
+
return $this;
}
@@ -619,10 +250,11 @@ class MathExecutor
* Remove all variables and the variable not found handler
* @return MathExecutor
*/
- public function removeVars(): self
+ public function removeVars() : self
{
$this->variables = [];
$this->onVarNotFound = null;
+
return $this;
}
@@ -642,7 +274,7 @@ class MathExecutor
* @return array<string, CustomFunction> containing callback and places indexed by
* function name
*/
- public function getFunctions(): array
+ public function getFunctions() : array
{
return $this->functions;
}
@@ -652,14 +284,16 @@ class MathExecutor
*
* @return MathExecutor
*/
- public function setDivisionByZeroIsZero(): self
+ public function setDivisionByZeroIsZero() : self
{
- $this->addOperator(new Operator("/", false, 180, function ($a, $b) {
- if ($b == 0) {
+ $this->addOperator(new Operator('/', false, 180, static function($a, $b) {
+ if (0 == $b) {
return 0;
}
+
return $a / $b;
}));
+
return $this;
}
@@ -667,7 +301,7 @@ class MathExecutor
* Get cache array with tokens
* @return array<string, Token[]>
*/
- public function getCache(): array
+ public function getCache() : array
{
return $this->cache;
}
@@ -675,13 +309,393 @@ class MathExecutor
/**
* Clear token's cache
*/
- public function clearCache(): void
+ public function clearCache() : void
{
$this->cache = [];
}
- public function __clone()
+ /**
+ * Set default operands and functions
+ * @throws ReflectionException
+ */
+ protected function addDefaults() : void
{
- $this->addDefaults();
+ foreach ($this->defaultOperators() as $name => $operator) {
+ [$callable, $priority, $isRightAssoc] = $operator;
+ $this->addOperator(new Operator($name, $isRightAssoc, $priority, $callable));
+ }
+
+ foreach ($this->defaultFunctions() as $name => $callable) {
+ $this->addFunction($name, $callable);
+ }
+
+ $this->onVarValidation = [$this, 'defaultVarValidation'];
+ $this->variables = $this->defaultVars();
+ }
+
+ /**
+ * Get the default operators
+ *
+ * @return array<string, array{callable, int, bool}>
+ */
+ protected function defaultOperators() : array
+ {
+ return [
+ '+' => [
+ static function($a, $b) {
+ return $a + $b;
+ },
+ 170,
+ false
+ ],
+ '-' => [
+ static function($a, $b) {
+ return $a - $b;
+ },
+ 170,
+ false
+ ],
+ 'uPos' => [ // unary positive token
+ static function($a) {
+ return $a;
+ },
+ 200,
+ false
+ ],
+ 'uNeg' => [ // unary minus token
+ static function($a) {
+ return 0 - $a;
+ },
+ 200,
+ false
+ ],
+ '*' => [
+ static function($a, $b) {
+ return $a * $b;
+ },
+ 180,
+ false
+ ],
+ '/' => [
+ static function($a, $b) {
+ if (0 == $b) {
+ throw new DivisionByZeroException();
+ }
+
+ return $a / $b;
+ },
+ 180,
+ false
+ ],
+ '^' => [
+ static function($a, $b) {
+ return \pow($a, $b);
+ },
+ 220,
+ true
+ ],
+ '&&' => [
+ static function($a, $b) {
+ return $a && $b;
+ },
+ 100,
+ false
+ ],
+ '||' => [
+ static function($a, $b) {
+ return $a || $b;
+ },
+ 90,
+ false
+ ],
+ '==' => [
+ static function($a, $b) {
+ if (\is_string($a) || \is_string($b)) {
+ return 0 == \strcmp($a, $b);
+ }
+
+ return $a == $b;
+
+ },
+ 140,
+ false
+ ],
+ '!=' => [
+ static function($a, $b) {
+ if (\is_string($a) || \is_string($b)) {
+ return 0 != \strcmp($a, $b);
+ }
+
+ return $a != $b;
+
+ },
+ 140,
+ false
+ ],
+ '>=' => [
+ static function($a, $b) {
+ return $a >= $b;
+ },
+ 150,
+ false
+ ],
+ '>' => [
+ static function($a, $b) {
+ return $a > $b;
+ },
+ 150,
+ false
+ ],
+ '<=' => [
+ static function($a, $b) {
+ return $a <= $b;
+ },
+ 150,
+ false
+ ],
+ '<' => [
+ static function($a, $b) {
+ return $a < $b;
+ },
+ 150,
+ false
+ ],
+ ];
+ }
+
+ /**
+ * Gets the default functions as an array. Key is function name
+ * and value is the function as a closure.
+ *
+ * @return array<callable>
+ */
+ protected function defaultFunctions() : array
+ {
+ return [
+ 'abs' => static function($arg) {
+ return \abs($arg);
+ },
+ 'acos' => static function($arg) {
+ return \acos($arg);
+ },
+ 'acosh' => static function($arg) {
+ return \acosh($arg);
+ },
+ 'arcsin' => static function($arg) {
+ return \asin($arg);
+ },
+ 'arcctg' => static function($arg) {
+ return M_PI / 2 - \atan($arg);
+ },
+ 'arccot' => static function($arg) {
+ return M_PI / 2 - \atan($arg);
+ },
+ 'arccotan' => static function($arg) {
+ return M_PI / 2 - \atan($arg);
+ },
+ 'arcsec' => static function($arg) {
+ return \acos(1 / $arg);
+ },
+ 'arccosec' => static function($arg) {
+ return \asin(1 / $arg);
+ },
+ 'arccsc' => static function($arg) {
+ return \asin(1 / $arg);
+ },
+ 'arccos' => static function($arg) {
+ return \acos($arg);
+ },
+ 'arctan' => static function($arg) {
+ return \atan($arg);
+ },
+ 'arctg' => static function($arg) {
+ return \atan($arg);
+ },
+ 'asin' => static function($arg) {
+ return \asin($arg);
+ },
+ 'atan' => static function($arg) {
+ return \atan($arg);
+ },
+ 'atan2' => static function($arg1, $arg2) {
+ return \atan2($arg1, $arg2);
+ },
+ 'atanh' => static function($arg) {
+ return \atanh($arg);
+ },
+ 'atn' => static function($arg) {
+ return \atan($arg);
+ },
+ 'avg' => static function($arg1, $arg2) {
+ return ($arg1 + $arg2) / 2;
+ },
+ 'bindec' => static function($arg) {
+ return \bindec($arg);
+ },
+ 'ceil' => static function($arg) {
+ return \ceil($arg);
+ },
+ 'cos' => static function($arg) {
+ return \cos($arg);
+ },
+ 'cosec' => static function($arg) {
+ return 1 / \sin($arg);
+ },
+ 'csc' => static function($arg) {
+ return 1 / \sin($arg);
+ },
+ 'cosh' => static function($arg) {
+ return \cosh($arg);
+ },
+ 'ctg' => static function($arg) {
+ return \cos($arg) / \sin($arg);
+ },
+ 'cot' => static function($arg) {
+ return \cos($arg) / \sin($arg);
+ },
+ 'cotan' => static function($arg) {
+ return \cos($arg) / \sin($arg);
+ },
+ 'cotg' => static function($arg) {
+ return \cos($arg) / \sin($arg);
+ },
+ 'ctn' => static function($arg) {
+ return \cos($arg) / \sin($arg);
+ },
+ 'decbin' => static function($arg) {
+ return \decbin($arg);
+ },
+ 'dechex' => static function($arg) {
+ return \dechex($arg);
+ },
+ 'decoct' => static function($arg) {
+ return \decoct($arg);
+ },
+ 'deg2rad' => static function($arg) {
+ return \deg2rad($arg);
+ },
+ 'exp' => static function($arg) {
+ return \exp($arg);
+ },
+ 'expm1' => static function($arg) {
+ return \expm1($arg);
+ },
+ 'floor' => static function($arg) {
+ return \floor($arg);
+ },
+ 'fmod' => static function($arg1, $arg2) {
+ return \fmod($arg1, $arg2);
+ },
+ 'hexdec' => static function($arg) {
+ return \hexdec($arg);
+ },
+ 'hypot' => static function($arg1, $arg2) {
+ return \hypot($arg1, $arg2);
+ },
+ 'if' => function($expr, $trueval, $falseval) {
+ if (true === $expr || false === $expr) {
+ $exres = $expr;
+ } else {
+ $exres = $this->execute($expr);
+ }
+
+ if ($exres) {
+ return $this->execute($trueval);
+ }
+
+ return $this->execute($falseval);
+
+ },
+ 'intdiv' => static function($arg1, $arg2) {
+ return \intdiv($arg1, $arg2);
+ },
+ 'ln' => static function($arg) {
+ return \log($arg);
+ },
+ 'lg' => static function($arg) {
+ return \log10($arg);
+ },
+ 'log' => static function($arg) {
+ return \log($arg);
+ },
+ 'log10' => static function($arg) {
+ return \log10($arg);
+ },
+ 'log1p' => static function($arg) {
+ return \log1p($arg);
+ },
+ 'max' => static function($arg1, $arg2) {
+ return \max($arg1, $arg2);
+ },
+ 'min' => static function($arg1, $arg2) {
+ return \min($arg1, $arg2);
+ },
+ 'octdec' => static function($arg) {
+ return \octdec($arg);
+ },
+ 'pi' => static function() {
+ return M_PI;
+ },
+ 'pow' => static function($arg1, $arg2) {
+ return $arg1 ** $arg2;
+ },
+ 'rad2deg' => static function($arg) {
+ return \rad2deg($arg);
+ },
+ 'round' => static function($arg) {
+ return \round($arg);
+ },
+ 'sin' => static function($arg) {
+ return \sin($arg);
+ },
+ 'sinh' => static function($arg) {
+ return \sinh($arg);
+ },
+ 'sec' => static function($arg) {
+ return 1 / \cos($arg);
+ },
+ 'sqrt' => static function($arg) {
+ return \sqrt($arg);
+ },
+ 'tan' => static function($arg) {
+ return \tan($arg);
+ },
+ 'tanh' => static function($arg) {
+ return \tanh($arg);
+ },
+ 'tn' => static function($arg) {
+ return \tan($arg);
+ },
+ 'tg' => static function($arg) {
+ return \tan($arg);
+ }
+ ];
+ }
+
+ /**
+ * Returns the default variables names as key/value pairs
+ *
+ * @return array<string, float>
+ */
+ protected function defaultVars() : array
+ {
+ return [
+ 'pi' => 3.14159265359,
+ 'e' => 2.71828182846
+ ];
+ }
+
+ /**
+ * Default variable validation, ensures that the value is a scalar.
+ * @param $value
+ * @throws MathExecutorException if the value is not a scalar
+ */
+ protected function defaultVarValidation(string $variable, $value) : void
+ {
+ if (! \is_scalar($value) && null !== $value) {
+ $type = \gettype($value);
+
+ throw new MathExecutorException("Variable ({$variable}) type ({$type}) is not scalar");
+ }
}
}