aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJavier Marín <javier@marinros.com>2020-07-26 05:27:26 +0300
committerBruce Wells <brucekwells@gmail.com>2020-09-16 04:14:44 +0300
commit462d6e4ddc5c6f463a618a0e3ef8691673c67995 (patch)
treeb7ff2fa4c478a9ccc2fd0d17c64d54732f3391fb /src
parenta0e0f405a9ffa11482e53a87eed95d962b8839f6 (diff)
Handler for not found variables (#68)
* Added handler to define not found variables Added support for string variables Fixed strings and ints comparison error * Check if variables have scalar types (int, float, string and bool) Better $onVarNotFound logic
Diffstat (limited to 'src')
-rw-r--r--src/NXP/Classes/Calculator.php14
-rw-r--r--src/NXP/Exception/MathExecutorException.php2
-rw-r--r--src/NXP/MathExecutor.php48
3 files changed, 50 insertions, 14 deletions
diff --git a/src/NXP/Classes/Calculator.php b/src/NXP/Classes/Calculator.php
index bcb4b4e..49142df 100644
--- a/src/NXP/Classes/Calculator.php
+++ b/src/NXP/Classes/Calculator.php
@@ -49,7 +49,7 @@ class Calculator
* @throws IncorrectExpressionException
* @throws UnknownVariableException
*/
- public function calculate(array $tokens, array $variables)
+ public function calculate(array $tokens, array $variables, callable $onVarNotFound = null)
{
/** @var Token[] $stack */
$stack = [];
@@ -58,10 +58,18 @@ class Calculator
$stack[] = $token;
} elseif ($token->type === Token::Variable) {
$variable = $token->value;
- if (!array_key_exists($variable, $variables)) {
+
+ $value = null;
+ if (array_key_exists($variable, $variables)) {
+ $value = $variables[$variable];
+ } elseif ($onVarNotFound) {
+ $value = call_user_func($onVarNotFound, $variable);
+ }
+
+ if (!isset($value)) {
throw new UnknownVariableException($variable);
}
- $value = $variables[$variable];
+
$stack[] = new Token(Token::Literal, $value);
} elseif ($token->type === Token::Function) {
if (!array_key_exists($token->value, $this->functions)) {
diff --git a/src/NXP/Exception/MathExecutorException.php b/src/NXP/Exception/MathExecutorException.php
index 0e3ea84..4405f85 100644
--- a/src/NXP/Exception/MathExecutorException.php
+++ b/src/NXP/Exception/MathExecutorException.php
@@ -14,6 +14,6 @@ namespace NXP\Exception;
/**
* @author Vitaliy Zhuk <zhuk2205@gmail.com>
*/
-abstract class MathExecutorException extends \Exception
+class MathExecutorException extends \Exception
{
}
diff --git a/src/NXP/MathExecutor.php b/src/NXP/MathExecutor.php
index 8f876dc..d23ba80 100644
--- a/src/NXP/MathExecutor.php
+++ b/src/NXP/MathExecutor.php
@@ -15,9 +15,9 @@ use NXP\Classes\Calculator;
use NXP\Classes\CustomFunction;
use NXP\Classes\Operator;
use NXP\Classes\Tokenizer;
-use NXP\Exception\MathExecutorException;
use NXP\Exception\DivisionByZeroException;
use NXP\Exception\UnknownVariableException;
+use NXP\Exception\MathExecutorException;
use ReflectionException;
/**
@@ -34,6 +34,11 @@ class MathExecutor
private $variables = [];
/**
+ * @var callable
+ */
+ private $onVarNotFound = null;
+
+ /**
* @var Operator[]
*/
private $operators = [];
@@ -134,14 +139,22 @@ class MathExecutor
],
'==' => [
function ($a, $b) {
- return $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;
+ if (is_string($a) || is_string($b)) {
+ return strcmp($a, $b) != 0;
+ } else {
+ return $a != $b;
+ }
},
140,
false
@@ -353,7 +366,7 @@ class MathExecutor
$tokens = $this->cache[$cachekey];
}
$calculator = new Calculator($this->functions, $this->operators);
- return $calculator->calculate($tokens, $this->variables);
+ return $calculator->calculate($tokens, $this->variables, $this->onVarNotFound);
}
/**
@@ -415,13 +428,13 @@ class MathExecutor
* @param string $variable
* @param integer|float $value
* @return MathExecutor
- * @throws MathExecutorException
*/
public function setVar(string $variable, $value) : self
{
- if (!is_numeric($value)) {
- throw new MathExecutorException("Variable ({$variable}) value must be a number ({$value}) type ({gettype($value)})");
+ if (!is_scalar($value)) {
+ throw new MathExecutorException("Variable ({$variable}) value must be a scalar type ({gettype($value)})");
}
+
$this->variables[$variable] = $value;
return $this;
}
@@ -446,6 +459,20 @@ 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
+ {
+ $this->onVarNotFound = $handler;
+ return $this;
+ }
+
+ /**
* Remove variable from executor
*
* @param string $variable
@@ -458,12 +485,13 @@ class MathExecutor
}
/**
- * Remove all variables
+ * Remove all variables and the variable not found handler
* @return MathExecutor
*/
public function removeVars() : self
{
$this->variables = [];
+ $this->onVarNotFound = null;
return $this;
}
@@ -474,7 +502,7 @@ class MathExecutor
*/
public function getOperators()
{
- return $this->tokenFactory->getOperators();
+ return $this->operators;
}
/**
@@ -485,7 +513,7 @@ class MathExecutor
*/
public function getFunctions() : array
{
- return $this->tokenFactory->getFunctions();
+ return $this->functions;
}
/**