aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJavier Marín <javier@marinros.com>2021-03-05 03:42:01 +0300
committerGitHub <noreply@github.com>2021-03-05 03:42:01 +0300
commitd99491c1f45d091cfe80227671336455b20b897e (patch)
tree6a924c8daba04fa21c99504aba957fb07ea4af77
parent17cc5b9dc48b19e0dee1937080601a9fc2890af4 (diff)
Support for unary positive expressions (#85)
* Support for unary positive operator
-rw-r--r--src/NXP/Classes/Tokenizer.php6
-rw-r--r--src/NXP/MathExecutor.php47
-rw-r--r--tests/MathTest.php11
3 files changed, 41 insertions, 23 deletions
diff --git a/src/NXP/Classes/Tokenizer.php b/src/NXP/Classes/Tokenizer.php
index bb6fa15..f8056c3 100644
--- a/src/NXP/Classes/Tokenizer.php
+++ b/src/NXP/Classes/Tokenizer.php
@@ -150,11 +150,11 @@ class Tokenizer
$this->tokens[] = new Token(Token::ParamSeparator, '');
break;
default:
- // special case for unary minus
- if ($ch == '-') {
+ // special case for unary operations
+ if ($ch == '-' || $ch == '+') {
if ($this->allowNegative) {
$this->allowNegative = false;
- $this->tokens[] = new Token(Token::Operator, '`');
+ $this->tokens[] = new Token(Token::Operator, $ch == '-' ? 'uNeg' : 'uPos');
continue 2;
}
// could be in exponent, in which case negative should be added to the numberBuffer
diff --git a/src/NXP/MathExecutor.php b/src/NXP/MathExecutor.php
index b8e8a65..a774561 100644
--- a/src/NXP/MathExecutor.php
+++ b/src/NXP/MathExecutor.php
@@ -16,8 +16,8 @@ use NXP\Classes\CustomFunction;
use NXP\Classes\Operator;
use NXP\Classes\Tokenizer;
use NXP\Exception\DivisionByZeroException;
-use NXP\Exception\UnknownVariableException;
use NXP\Exception\MathExecutorException;
+use NXP\Exception\UnknownVariableException;
use ReflectionException;
/**
@@ -85,35 +85,42 @@ class MathExecutor
protected function defaultOperators() : array
{
return [
- '+' => [
+ '+' => [
function ($a, $b) {
return $a + $b;
},
170,
false
],
- '-' => [
+ '-' => [
function ($a, $b) {
return $a - $b;
},
170,
false
],
- '`' => [ // unary minus token
- function ($a) {
- return 0 - $a;
- },
- 200,
- 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();
@@ -123,28 +130,28 @@ class MathExecutor
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;
@@ -155,7 +162,7 @@ class MathExecutor
140,
false
],
- '!=' => [
+ '!=' => [
function ($a, $b) {
if (is_string($a) || is_string($b)) {
return strcmp($a, $b) != 0;
@@ -166,28 +173,28 @@ class MathExecutor
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;
},
diff --git a/tests/MathTest.php b/tests/MathTest.php
index a843db5..dee3f39 100644
--- a/tests/MathTest.php
+++ b/tests/MathTest.php
@@ -252,6 +252,17 @@ class MathTest extends TestCase
$this->assertEquals(0, $calculator->execute('10 / 0'));
}
+ public function testUnaryOperators()
+ {
+ $calculator = new MathExecutor();
+ $this->assertEquals(5, $calculator->execute('+5'));
+ $this->assertEquals(5, $calculator->execute('+(3+2)'));
+ $this->assertEquals(-5, $calculator->execute('-5'));
+ $this->assertEquals(5, $calculator->execute('-(-5)'));
+ $this->assertEquals(-5, $calculator->execute('+(-5)'));
+ $this->assertEquals(-5, $calculator->execute('-(3+2)'));
+ }
+
public function testZeroDivisionException()
{
$calculator = new MathExecutor();