We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
There was an error while loading. Please reload this page.
2 parents a34eaf4 + c2a81d8 commit fc65d71Copy full SHA for fc65d71
CHANGELOG.md
@@ -1,6 +1,11 @@
1
CHANGELOG
2
=========
3
4
+4.4.0
5
+-----
6
+
7
+ * add `xor` operator
8
9
4.0.0
10
-----
11
Lexer.php
@@ -71,7 +71,7 @@ public function tokenize(string $expression)
71
// strings
72
$tokens[] = new Token(Token::STRING_TYPE, stripcslashes(substr($match[0], 1, -1)), $cursor + 1);
73
$cursor += \strlen($match[0]);
74
- } elseif (preg_match('/not in(?=[\s(])|\!\=\=|not(?=[\s(])|and(?=[\s(])|\=\=\=|\>\=|or(?=[\s(])|\<\=|\*\*|\.\.|in(?=[\s(])|&&|\|\||matches|\=\=|\!\=|\*|~|%|\/|\>|\||\!|\^|&|\+|\<|\-/A', $expression, $match, 0, $cursor)) {
+ } elseif (preg_match('/not in(?=[\s(])|\!\=\=|not(?=[\s(])|and(?=[\s(])|\=\=\=|\>\=|or(?=[\s(])|xor(?=[\s(])|\<\=|\*\*|\.\.|in(?=[\s(])|&&|\|\||matches|\=\=|\!\=|\*|~|%|\/|\>|\||\!|\^|&|\+|\<|\-/A', $expression, $match, 0, $cursor)) {
75
// operators
76
$tokens[] = new Token(Token::OPERATOR_TYPE, $match[0], $cursor + 1);
77
Node/BinaryNode.php
@@ -104,6 +104,8 @@ public function evaluate(array $functions, array $values)
104
case 'or':
105
case '||':
106
return $left || $this->nodes['right']->evaluate($functions, $values);
107
+ case 'xor':
108
+ return $left xor $this->nodes['right']->evaluate($functions, $values);
109
case 'and':
110
case '&&':
111
return $left && $this->nodes['right']->evaluate($functions, $values);
Parser.php
@@ -45,6 +45,7 @@ public function __construct(array $functions)
45
$this->binaryOperators = [
46
'or' => ['precedence' => 10, 'associativity' => self::OPERATOR_LEFT],
47
'||' => ['precedence' => 10, 'associativity' => self::OPERATOR_LEFT],
48
+ 'xor' => ['precedence' => 13, 'associativity' => self::OPERATOR_LEFT],
49
'and' => ['precedence' => 15, 'associativity' => self::OPERATOR_LEFT],
50
'&&' => ['precedence' => 15, 'associativity' => self::OPERATOR_LEFT],
51
'|' => ['precedence' => 16, 'associativity' => self::OPERATOR_LEFT],
Tests/ExpressionLanguageTest.php
@@ -256,4 +256,35 @@ function (ExpressionLanguage $el) {
256
],
257
];
258
}
259
260
+ /**
261
+ * @dataProvider getLogicalOperators
262
+ */
263
+ public function testLogicalOperators($expression, $expected)
264
+ {
265
+ $this->assertSame($expected, (new ExpressionLanguage())->evaluate($expression));
266
+ }
267
268
+ public function getLogicalOperators()
269
270
+ return [
271
+ // AND
272
+ ['true and true', true],
273
+ ['true and false', false],
274
+ ['false and true', false],
275
+ ['false and false', false],
276
277
+ // OR
278
+ ['true or true', true],
279
+ ['true or false', true],
280
+ ['false or true', true],
281
+ ['false or false', false],
282
283
+ // XOR
284
+ ['true xor true', false],
285
+ ['true xor false', true],
286
+ ['false xor true', true],
287
+ ['false xor false', false],
288
+ ];
289
290
Tests/LexerTest.php
@@ -114,6 +114,14 @@ public function getTokenizeData()
114
[new Token('string', '#foo', 1)],
115
'"#foo"',
116
117
+ [
118
119
+ new Token('name', 'a', 1),
120
+ new Token('operator', 'xor', 3),
121
+ new Token('name', 'b', 7),
122
+ ],
123
+ 'a xor b',
124
125
126
127
Tests/ParserTest.php
@@ -151,6 +151,11 @@ public function getParseData()
151
'bar',
152
['foo' => 'bar'],
153
154
155
156
+ new Node\BinaryNode('xor', new Node\ConstantNode(true), new Node\ConstantNode(false)),
157
+ 'true xor false',
158
159
160
161
0 commit comments