aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md20
-rw-r--r--src/NXP/Classes/Tokenizer.php11
-rw-r--r--src/NXP/MathExecutor.php3
-rw-r--r--tests/MathTest.php16
4 files changed, 43 insertions, 7 deletions
diff --git a/README.md b/README.md
index 0c085c8..faeeb11 100644
--- a/README.md
+++ b/README.md
@@ -40,6 +40,7 @@ Default functions:
* arcctg (arccot, arccotan)
* arcsec
* arccsc (arccosec)
+* array
* asin (arcsin)
* atan (atn, arctan, arctg)
* atan2
@@ -84,7 +85,10 @@ Add custom function to executor:
```php
$executor->addFunction('abs', function($arg) {return abs($arg);});
```
-Function default parameters are not supported at this time.
+Function default parameters (optional parameters) are also supported.
+```php
+$executor->addFunction('round', function($num, int $precision = 0) {return round($num, $precision);});
+```
## Operators:
Default operators: `+ - * / ^`
@@ -139,12 +143,20 @@ $executor->setVar('var1', 0.15)->setVar('var2', 0.22);
echo $executor->execute("$var1 + var2");
```
-By default, variables must be scalar values (int, float, bool or string). If you would like to support another type, use **setVarValidationHandler**
+Arrays are also supported (as variables, as func params or can be returned in user defined funcs):
+```php
+$executor->setVar('monthly_salaries', [1800, 1900, 1200, 1600]);
+
+echo $executor->execute("avg(monthly_salaries) * min([1.1, 1.3])");
+```
+
+
+By default, variables must be scalar values (int, float, bool or string) or array. If you would like to support another type, use **setVarValidationHandler**
```php
$executor->setVarValidationHandler(function (string $name, $variable) {
- // allow all scalars and null
- if (is_scalar($variable) || $variable === null) {
+ // allow all scalars, array and null
+ if (is_scalar($variable) || is_array($variable) || $variable === null) {
return;
}
// Allow variables of type DateTime, but not others
diff --git a/src/NXP/Classes/Tokenizer.php b/src/NXP/Classes/Tokenizer.php
index 23e1cc9..c8b415d 100644
--- a/src/NXP/Classes/Tokenizer.php
+++ b/src/NXP/Classes/Tokenizer.php
@@ -76,6 +76,13 @@ class Tokenizer
continue 2;
+ case '[' === $ch:
+ $this->tokens[] = new Token(Token::Function, 'array');
+ $this->allowNegative = true;
+ $this->tokens[] = new Token(Token::LeftParenthesis, '');
+
+ continue 2;
+
case ' ' == $ch || "\n" == $ch || "\r" == $ch || "\t" == $ch:
$this->tokens[] = new Token(Token::Space, '');
@@ -140,7 +147,7 @@ class Tokenizer
break;
- case $this->isRP($ch):
+ case $this->isRP($ch) || ']' === $ch :
$this->emptyNumberBufferAsLiteral();
$this->emptyStrBufferAsVariable();
$this->allowNegative = false;
@@ -196,8 +203,8 @@ class Tokenizer
}
/**
- * @throws UnknownOperatorException
* @throws IncorrectBracketsException
+ * @throws UnknownOperatorException
* @return Token[] Array of tokens in revers polish notation
*/
public function buildReversePolishNotation() : array
diff --git a/src/NXP/MathExecutor.php b/src/NXP/MathExecutor.php
index e7e8259..dd90e22 100644
--- a/src/NXP/MathExecutor.php
+++ b/src/NXP/MathExecutor.php
@@ -469,7 +469,8 @@ class MathExecutor
'tan' => static fn($arg) => \tan($arg),
'tanh' => static fn($arg) => \tanh($arg),
'tn' => static fn($arg) => \tan($arg),
- 'tg' => static fn($arg) => \tan($arg)
+ 'tg' => static fn($arg) => \tan($arg),
+ 'array' => static fn(...$args) => [...$args]
];
}
diff --git a/tests/MathTest.php b/tests/MathTest.php
index c39eec7..382d67d 100644
--- a/tests/MathTest.php
+++ b/tests/MathTest.php
@@ -305,6 +305,22 @@ class MathTest extends TestCase
$this->assertEquals(100, $calculator->execute('10 ^ 2'));
}
+ public function testArrays() : void
+ {
+ $calculator = new MathExecutor();
+ $this->assertEquals([1, 5, 2], $calculator->execute('array(1, 5, 2)'));
+ $this->assertEquals([1, 5, 2], $calculator->execute('[1, 5, 2]'));
+ $this->assertEquals(\max([1, 5, 2]), $calculator->execute('max([1, 5, 2])'));
+ $this->assertEquals(\max([1, 5, 2]), $calculator->execute('max(array(1, 5, 2))'));
+ $calculator->addFunction('arr_with_max_elements', static function($arg1, ...$args) {
+ $args = \is_array($arg1) ? $arg1 : [$arg1, ...$args];
+ \usort($args, static fn($arr1, $arr2) => \count($arr2) <=> \count($arr1));
+
+ return $args[0];
+ });
+ $this->assertEquals([3, 3, 3], $calculator->execute('arr_with_max_elements([[1],array(2,2),[3,3,3]])'));
+ }
+
public function testFunctionParameterOrder() : void
{
$calculator = new MathExecutor();