Support for unary positive expressions (#85)
* Support for unary positive operator
This commit is contained in:
parent
17cc5b9dc4
commit
d99491c1f4
3 changed files with 41 additions and 23 deletions
|
@ -150,11 +150,11 @@ class Tokenizer
|
||||||
$this->tokens[] = new Token(Token::ParamSeparator, '');
|
$this->tokens[] = new Token(Token::ParamSeparator, '');
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// special case for unary minus
|
// special case for unary operations
|
||||||
if ($ch == '-') {
|
if ($ch == '-' || $ch == '+') {
|
||||||
if ($this->allowNegative) {
|
if ($this->allowNegative) {
|
||||||
$this->allowNegative = false;
|
$this->allowNegative = false;
|
||||||
$this->tokens[] = new Token(Token::Operator, '`');
|
$this->tokens[] = new Token(Token::Operator, $ch == '-' ? 'uNeg' : 'uPos');
|
||||||
continue 2;
|
continue 2;
|
||||||
}
|
}
|
||||||
// could be in exponent, in which case negative should be added to the numberBuffer
|
// could be in exponent, in which case negative should be added to the numberBuffer
|
||||||
|
|
|
@ -16,8 +16,8 @@ use NXP\Classes\CustomFunction;
|
||||||
use NXP\Classes\Operator;
|
use NXP\Classes\Operator;
|
||||||
use NXP\Classes\Tokenizer;
|
use NXP\Classes\Tokenizer;
|
||||||
use NXP\Exception\DivisionByZeroException;
|
use NXP\Exception\DivisionByZeroException;
|
||||||
use NXP\Exception\UnknownVariableException;
|
|
||||||
use NXP\Exception\MathExecutorException;
|
use NXP\Exception\MathExecutorException;
|
||||||
|
use NXP\Exception\UnknownVariableException;
|
||||||
use ReflectionException;
|
use ReflectionException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -85,35 +85,42 @@ class MathExecutor
|
||||||
protected function defaultOperators() : array
|
protected function defaultOperators() : array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'+' => [
|
'+' => [
|
||||||
function ($a, $b) {
|
function ($a, $b) {
|
||||||
return $a + $b;
|
return $a + $b;
|
||||||
},
|
},
|
||||||
170,
|
170,
|
||||||
false
|
false
|
||||||
],
|
],
|
||||||
'-' => [
|
'-' => [
|
||||||
function ($a, $b) {
|
function ($a, $b) {
|
||||||
return $a - $b;
|
return $a - $b;
|
||||||
},
|
},
|
||||||
170,
|
170,
|
||||||
false
|
false
|
||||||
],
|
],
|
||||||
'`' => [ // unary minus token
|
'uPos' => [ // unary positive token
|
||||||
function ($a) {
|
function ($a) {
|
||||||
return 0 - $a;
|
return $a;
|
||||||
},
|
},
|
||||||
200,
|
200,
|
||||||
false
|
false
|
||||||
],
|
],
|
||||||
'*' => [
|
'uNeg' => [ // unary minus token
|
||||||
|
function ($a) {
|
||||||
|
return 0 - $a;
|
||||||
|
},
|
||||||
|
200,
|
||||||
|
false
|
||||||
|
],
|
||||||
|
'*' => [
|
||||||
function ($a, $b) {
|
function ($a, $b) {
|
||||||
return $a * $b;
|
return $a * $b;
|
||||||
},
|
},
|
||||||
180,
|
180,
|
||||||
false
|
false
|
||||||
],
|
],
|
||||||
'/' => [
|
'/' => [
|
||||||
function ($a, $b) {
|
function ($a, $b) {
|
||||||
if ($b == 0) {
|
if ($b == 0) {
|
||||||
throw new DivisionByZeroException();
|
throw new DivisionByZeroException();
|
||||||
|
@ -123,28 +130,28 @@ class MathExecutor
|
||||||
180,
|
180,
|
||||||
false
|
false
|
||||||
],
|
],
|
||||||
'^' => [
|
'^' => [
|
||||||
function ($a, $b) {
|
function ($a, $b) {
|
||||||
return pow($a, $b);
|
return pow($a, $b);
|
||||||
},
|
},
|
||||||
220,
|
220,
|
||||||
true
|
true
|
||||||
],
|
],
|
||||||
'&&' => [
|
'&&' => [
|
||||||
function ($a, $b) {
|
function ($a, $b) {
|
||||||
return $a && $b;
|
return $a && $b;
|
||||||
},
|
},
|
||||||
100,
|
100,
|
||||||
false
|
false
|
||||||
],
|
],
|
||||||
'||' => [
|
'||' => [
|
||||||
function ($a, $b) {
|
function ($a, $b) {
|
||||||
return $a || $b;
|
return $a || $b;
|
||||||
},
|
},
|
||||||
90,
|
90,
|
||||||
false
|
false
|
||||||
],
|
],
|
||||||
'==' => [
|
'==' => [
|
||||||
function ($a, $b) {
|
function ($a, $b) {
|
||||||
if (is_string($a) || is_string($b)) {
|
if (is_string($a) || is_string($b)) {
|
||||||
return strcmp($a, $b) == 0;
|
return strcmp($a, $b) == 0;
|
||||||
|
@ -155,7 +162,7 @@ class MathExecutor
|
||||||
140,
|
140,
|
||||||
false
|
false
|
||||||
],
|
],
|
||||||
'!=' => [
|
'!=' => [
|
||||||
function ($a, $b) {
|
function ($a, $b) {
|
||||||
if (is_string($a) || is_string($b)) {
|
if (is_string($a) || is_string($b)) {
|
||||||
return strcmp($a, $b) != 0;
|
return strcmp($a, $b) != 0;
|
||||||
|
@ -166,28 +173,28 @@ class MathExecutor
|
||||||
140,
|
140,
|
||||||
false
|
false
|
||||||
],
|
],
|
||||||
'>=' => [
|
'>=' => [
|
||||||
function ($a, $b) {
|
function ($a, $b) {
|
||||||
return $a >= $b;
|
return $a >= $b;
|
||||||
},
|
},
|
||||||
150,
|
150,
|
||||||
false
|
false
|
||||||
],
|
],
|
||||||
'>' => [
|
'>' => [
|
||||||
function ($a, $b) {
|
function ($a, $b) {
|
||||||
return $a > $b;
|
return $a > $b;
|
||||||
},
|
},
|
||||||
150,
|
150,
|
||||||
false
|
false
|
||||||
],
|
],
|
||||||
'<=' => [
|
'<=' => [
|
||||||
function ($a, $b) {
|
function ($a, $b) {
|
||||||
return $a <= $b;
|
return $a <= $b;
|
||||||
},
|
},
|
||||||
150,
|
150,
|
||||||
false
|
false
|
||||||
],
|
],
|
||||||
'<' => [
|
'<' => [
|
||||||
function ($a, $b) {
|
function ($a, $b) {
|
||||||
return $a < $b;
|
return $a < $b;
|
||||||
},
|
},
|
||||||
|
|
|
@ -252,6 +252,17 @@ class MathTest extends TestCase
|
||||||
$this->assertEquals(0, $calculator->execute('10 / 0'));
|
$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()
|
public function testZeroDivisionException()
|
||||||
{
|
{
|
||||||
$calculator = new MathExecutor();
|
$calculator = new MathExecutor();
|
||||||
|
|
Loading…
Reference in a new issue