Skip to content

Commit 66c9ead

Browse files
author
Stefan Ackermann
committed
make null handling configurable, static interface, typed exception
1 parent 318c34f commit 66c9ead

16 files changed

+493
-201
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace MathParser\Exceptions;
6+
7+
use RuntimeException;
8+
9+
class InvalidSyntaxException extends RuntimeException
10+
{
11+
}

lib/MathParser/Expression.php

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
<?php
22

3+
declare(strict_types=1);
4+
35
namespace MathParser;
46

57
use MathParser\Expressions\Addition;
@@ -21,58 +23,58 @@ public function __construct($value)
2123
$this->value = $value;
2224
}
2325

24-
public static function factory($value)
26+
public static function factory($value): Expression
2527
{
2628
if (is_object($value) && $value instanceof self) {
2729
return $value;
2830
} elseif (is_numeric($value)) {
2931
// +0 => to number conversion (int or float)
3032
return new Number($value + 0);
31-
} elseif ($value == 'u') {
33+
} elseif ($value === 'u') {
3234
return new Unary($value);
33-
} elseif ($value == '+') {
35+
} elseif ($value === '+') {
3436
return new Addition($value);
35-
} elseif ($value == '-') {
37+
} elseif ($value === '-') {
3638
return new Subtraction($value);
37-
} elseif ($value == '*') {
39+
} elseif ($value === '*') {
3840
return new Multiplication($value);
39-
} elseif ($value == '/') {
41+
} elseif ($value === '/') {
4042
return new Division($value);
41-
} elseif (in_array($value, array('(', ')'))) {
43+
} elseif (in_array($value, ['(', ')'], true)) {
4244
return new Parenthesis($value);
43-
} elseif ($value == '^') {
45+
} elseif ($value === '^') {
4446
return new Power($value);
45-
} elseif ($value == '%') {
47+
} elseif ($value === '%') {
4648
return new Modulo($value);
47-
} elseif (strlen($value) >= 2 && $value[0] == '$') {
49+
} elseif (strlen($value) >= 2 && $value[0] === '$') {
4850
return new Variable(substr($value, 1));
4951
}
5052
throw new \RuntimeException('Undefined Value ' . $value);
5153
}
5254

53-
abstract public function operate(array &$stack);
55+
abstract public function operate(array &$stack, array $options);
5456

55-
public function isOperator()
57+
public function isOperator(): bool
5658
{
5759
return false;
5860
}
5961

60-
public function isUnary()
62+
public function isUnary(): bool
6163
{
6264
return false;
6365
}
6466

65-
public function isParenthesis()
67+
public function isParenthesis(): bool
6668
{
6769
return false;
6870
}
6971

70-
public function isNoOp()
72+
public function isNoOp(): bool
7173
{
7274
return false;
7375
}
7476

75-
public function isVariable()
77+
public function isVariable(): bool
7678
{
7779
return false;
7880
}
Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,26 @@
11
<?php
22

3+
declare(strict_types=1);
4+
35
namespace MathParser\Expressions;
46

7+
use MathParser\Options\NullHandling;
8+
59
class Addition extends Operator
610
{
7-
protected $precedence = 4;
11+
public function getPrecedence(): int
12+
{
13+
return 4;
14+
}
815

9-
public function operate(array &$stack)
16+
public function operate(array &$stack, array $options)
1017
{
11-
$left = array_pop($stack)->operate($stack);
12-
$right = array_pop($stack)->operate($stack);
13-
14-
if ($left === null || $right === null) {
15-
return null;
16-
}
17-
18-
return $left + $right;
18+
return NullHandling::withNullHandling(
19+
$stack,
20+
$options,
21+
static function ($left, $right) {
22+
return $left + $right;
23+
}
24+
);
1925
}
2026
}
Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,30 @@
11
<?php
22

3+
declare(strict_types=1);
4+
35
namespace MathParser\Expressions;
46

7+
use MathParser\Options\NullHandling;
8+
59
class Division extends Operator
610
{
7-
protected $precedence = 5;
11+
public function getPrecedence(): int
12+
{
13+
return 5;
14+
}
815

9-
public function operate(array &$stack)
16+
public function operate(array &$stack, $options)
1017
{
11-
$left = array_pop($stack)->operate($stack);
12-
$right = array_pop($stack)->operate($stack);
13-
14-
if ($left === null || $right === null) {
15-
return null;
16-
}
17-
18-
if ($left === 0) {
19-
return null;
20-
}
21-
22-
return $right / $left;
18+
return NullHandling::withNullHandling(
19+
$stack,
20+
$options,
21+
static function ($left, $right) {
22+
if ($right === 0) {
23+
return null;
24+
}
25+
26+
return $left / $right;
27+
}
28+
);
2329
}
2430
}

lib/MathParser/Expressions/Modulo.php

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,30 @@
11
<?php
22

3+
declare(strict_types=1);
4+
35
namespace MathParser\Expressions;
46

7+
use MathParser\Options\NullHandling;
8+
59
class Modulo extends Operator
610
{
7-
protected $precedence = 5;
11+
public function getPrecedence(): int
12+
{
13+
return 5;
14+
}
815

9-
public function operate(array &$stack)
16+
public function operate(array &$stack, array $options)
1017
{
11-
$left = array_pop($stack)->operate($stack);
12-
$right = array_pop($stack)->operate($stack);
13-
14-
if ($left === null || $right === null) {
15-
return null;
16-
}
17-
18-
if ($left === 0) {
19-
return null;
20-
} else {
21-
return $right % $left;
22-
}
18+
return NullHandling::withNullHandling(
19+
$stack,
20+
$options,
21+
static function ($left, $right) {
22+
if ($right === 0) {
23+
return null;
24+
} else {
25+
return $left % $right;
26+
}
27+
}
28+
);
2329
}
2430
}
Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,26 @@
11
<?php
22

3+
declare(strict_types=1);
4+
35
namespace MathParser\Expressions;
46

7+
use MathParser\Options\NullHandling;
8+
59
class Multiplication extends Operator
610
{
7-
protected $precedence = 5;
8-
9-
public function operate(array &$stack)
11+
public function getPrecedence(): int
12+
{
13+
return 5;
14+
}
15+
16+
public function operate(array &$stack, array $options)
1017
{
11-
$left = array_pop($stack)->operate($stack);
12-
$right = array_pop($stack)->operate($stack);
13-
if ($left === null || $right === null) {
14-
return null;
15-
}
16-
return $left * $right;
18+
return NullHandling::withNullHandling(
19+
$stack,
20+
$options,
21+
static function ($left, $right) {
22+
return $left * $right;
23+
}
24+
);
1725
}
1826
}

lib/MathParser/Expressions/Number.php

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,14 @@
11
<?php
22

3+
declare(strict_types=1);
4+
35
namespace MathParser\Expressions;
46

57
use MathParser\Expression;
68

79
class Number extends Expression
810
{
9-
public function __construct($value)
10-
{
11-
parent::__construct($value);
12-
}
13-
14-
public function operate(array &$stack)
11+
public function operate(array &$stack, $options)
1512
{
1613
return $this->value;
1714
}

lib/MathParser/Expressions/Operator.php

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,23 @@
11
<?php
22

3+
declare(strict_types=1);
4+
35
namespace MathParser\Expressions;
46

57
use MathParser\Expression;
68

79
abstract class Operator extends Expression
810
{
9-
protected $precedence = 0;
1011
protected $leftAssoc = true;
1112

12-
public function getPrecedence()
13-
{
14-
return $this->precedence;
15-
}
13+
abstract public function getPrecedence(): int;
1614

17-
public function isLeftAssoc()
15+
public function isLeftAssoc(): bool
1816
{
1917
return $this->leftAssoc;
2018
}
2119

22-
public function isOperator()
20+
public function isOperator(): bool
2321
{
2422
return true;
2523
}
Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,35 @@
11
<?php
22

3+
declare(strict_types=1);
4+
35
namespace MathParser\Expressions;
46

57
use MathParser\Expression;
68

79
class Parenthesis extends Expression
810
{
9-
protected $precedence = 6;
1011

11-
public function operate(array &$stack)
12+
public function operate(array &$stack, array $options = [])
1213
{
1314
}
1415

15-
public function getPrecedence()
16+
public function getPrecedence(): int
1617
{
17-
return $this->precedence;
18+
return 6;
1819
}
1920

20-
public function isNoOp()
21+
public function isNoOp(): bool
2122
{
2223
return true;
2324
}
2425

25-
public function isParenthesis()
26+
public function isParenthesis(): bool
2627
{
2728
return true;
2829
}
2930

30-
public function isOpen()
31+
public function isOpen(): bool
3132
{
32-
return $this->value == '(';
33+
return $this->value === '(';
3334
}
3435
}

lib/MathParser/Expressions/Power.php

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,32 @@
11
<?php
22

3+
declare(strict_types=1);
4+
35
namespace MathParser\Expressions;
46

7+
use MathParser\Options\NullHandling;
8+
59
class Power extends Operator
610
{
7-
protected $precedence = 6;
811

9-
public function operate(array &$stack)
12+
public function getPrecedence(): int
13+
{
14+
return 6;
15+
}
16+
17+
public function isLeftAssoc(): bool
18+
{
19+
return false;
20+
}
21+
22+
public function operate(array &$stack, array $options)
1023
{
11-
$right = array_pop($stack)->operate($stack);
12-
$left = array_pop($stack)->operate($stack);
13-
14-
if ($left === null || $right === null) {
15-
return null;
16-
}
17-
return pow($left, $right);
24+
return NullHandling::withNullHandling(
25+
$stack,
26+
$options,
27+
static function ($left, $right) {
28+
return $left ** $right;
29+
}
30+
);
1831
}
1932
}

0 commit comments

Comments
 (0)