aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore3
-rw-r--r--README.md10
-rw-r--r--phpunit.xml.dist1
-rw-r--r--src/NXP/Classes/Lexer.php20
-rw-r--r--tests/MathTest.php23
5 files changed, 50 insertions, 7 deletions
diff --git a/.gitignore b/.gitignore
index 83436db..c3b38ab 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
vendor/
.idea/
-composer.lock \ No newline at end of file
+composer.lock
+.phpunit.result.cache
diff --git a/README.md b/README.md
index 81d9475..7238a0b 100644
--- a/README.md
+++ b/README.md
@@ -45,6 +45,8 @@ $executor->addFunction('abs', function($arg) {return abs($arg);});
```
Function default parameters are not supported at this time.
+Default parameters are not currently supported.
+
## Operators:
Default operators: `+ - * / ^`
@@ -112,7 +114,7 @@ Default variables:
```
$pi = 3.14159265359
-$e = 2.71828182846
+$e = 2.71828182846
```
You can add your own variables to executor:
@@ -138,7 +140,7 @@ try {
```
## Unary Minus Operator:
-Negative numbers are supported via the unary minus operator, but need to have a space before the minus sign. `-1+ -3` is legal, while `-1+-3` will produce an error due to the way the parser works. Positive numbers are not explicitly supported as unsigned numbers are assumed positive.
+Negative numbers are supported via the unary minus operator. Positive numbers are not explicitly supported as unsigned numbers are assumed positive.
## String Support:
Expressions can contain double or single quoted strings that are evaluated the same way as PHP evalutes strings as numbers. You can also pass strings to functions.
@@ -156,3 +158,7 @@ You can add operators, functions and variables with the public methods in MathEx
This will allow you to remove functions and operators if needed, or implement different types more simply.
Also note that you can replace an existing default operator by adding a new operator with the same regular expression string. For example if you just need to redefine TokenPlus, you can just add a new operator with the same regex string, in this case '\\+'.
+
+## Future Enhancements
+
+At some point this package will be upgraded to a currently supported version of PHP.
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
index bfe1846..d515f51 100644
--- a/phpunit.xml.dist
+++ b/phpunit.xml.dist
@@ -8,7 +8,6 @@
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false"
- syntaxCheck="false"
bootstrap="./tests/bootstrap.php"
>
diff --git a/src/NXP/Classes/Lexer.php b/src/NXP/Classes/Lexer.php
index 898d8c1..73c25ac 100644
--- a/src/NXP/Classes/Lexer.php
+++ b/src/NXP/Classes/Lexer.php
@@ -15,11 +15,12 @@ use NXP\Classes\Token\InterfaceOperator;
use NXP\Classes\Token\TokenComma;
use NXP\Classes\Token\TokenFunction;
use NXP\Classes\Token\TokenLeftBracket;
+use NXP\Classes\Token\TokenMinus;
use NXP\Classes\Token\TokenNumber;
use NXP\Classes\Token\TokenRightBracket;
+use NXP\Classes\Token\TokenStringDoubleQuoted;
use NXP\Classes\Token\TokenStringSingleQuoted;
use NXP\Classes\Token\TokenVariable;
-use NXP\Classes\Token\TokenStringDoubleQuoted;
use NXP\Exception\IncorrectBracketsException;
use NXP\Exception\IncorrectExpressionException;
@@ -66,6 +67,7 @@ class Lexer
{
$output = [];
$stack = [];
+ $lastToken = null;
foreach ($tokensStream as $token) {
if ($token instanceof TokenStringDoubleQuoted) {
@@ -73,7 +75,20 @@ class Lexer
} elseif ($token instanceof TokenStringSingleQuoted) {
$output[] = $token;
} elseif ($token instanceof TokenNumber) {
- $output[] = $token;
+ // if the number starts with a minus sign, it could be a negative number, or it could be an operator grabbed by the greedy regex
+ // if previous token is an operator, then it negative, otherwise remove the minus sign and put a negative operator on the stack
+ if ($lastToken !== null) {
+ $value = (int)$token->getValue();
+ if ($value < 0 && ! ($lastToken instanceof AbstractOperator)) {
+ $token = new TokenNumber(abs($value));
+ $output[] = $token;
+ $output[] = new TokenMinus('-');
+ } else {
+ $output[] = $token;
+ }
+ } else {
+ $output[] = $token;
+ }
} elseif ($token instanceof TokenVariable) {
$output[] = $token;
} elseif ($token instanceof TokenFunction) {
@@ -118,6 +133,7 @@ class Lexer
$output[] = array_pop($stack);
}
}
+ $lastToken = $token;
}
while (!empty($stack)) {
$token = array_pop($stack);
diff --git a/tests/MathTest.php b/tests/MathTest.php
index 3cf4dbd..7f5ce9b 100644
--- a/tests/MathTest.php
+++ b/tests/MathTest.php
@@ -41,6 +41,15 @@ class MathTest extends \PHPUnit_Framework_TestCase
public function providerExpressions()
{
return [
+ ['-5'],
+ ['-5+10'],
+ ['4-5'],
+ ['4 -5'],
+ ['(4*2)-5'],
+ ['(4*2) - 5'],
+ ['4*-5'],
+ ['4 * -5'],
+
['0.1 + 0.2'],
['1 + 2'],
@@ -80,7 +89,6 @@ class MathTest extends \PHPUnit_Framework_TestCase
['1 + 2 * 3 / (3 * min(1, 5) * 2 + 1)'],
['1 + 2 * 3 / (3 / min(1, 5) / 2 + 1)'],
-
['sin(10) * cos(50) / min(10, 20/2)'],
['sin(10) * cos(50) / min(10, (20/2))'],
['sin(10) * cos(50) / min(10, (max(10,20)/2))'],
@@ -97,6 +105,11 @@ class MathTest extends \PHPUnit_Framework_TestCase
['-1- -2'],
['-1/-2'],
['-1*-2'],
+
+ ['(1+2+3+4-5)*7/100'],
+ ['(1+2+3+4- 5)*7/100'],
+ ['( 1 + 2 + 3 + 4 - 5 ) * 7 / 100'],
+
];
}
@@ -166,6 +179,14 @@ class MathTest extends \PHPUnit_Framework_TestCase
$this->assertEquals($phpResult, $calculator->execute($expression));
}
+ public function testFunctionsWithQuotes()
+ {
+ $calculator = new MathExecutor();
+ $calculator->addFunction('concat', function($first, $second){return $first.$second;});
+ $this->assertEquals('testing', $calculator->execute('concat("test", "ing")'));
+ $this->assertEquals('testing', $calculator->execute("concat('test', 'ing')"));
+ }
+
public function testQuotes()
{
$calculator = new MathExecutor();