Skip to content

Commit b815a16

Browse files
committed
Add support for pipe operator
1 parent c1f6c4c commit b815a16

File tree

11 files changed

+1105
-990
lines changed

11 files changed

+1105
-990
lines changed

grammar/php.y

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
%left '+' '-' '.'
2727
#endif
2828
#if PHP8
29+
%left T_PIPE
2930
%left '.'
3031
%left T_SL T_SR
3132
%left '+' '-'
@@ -1085,6 +1086,9 @@ expr:
10851086
| expr T_IS_SMALLER_OR_EQUAL expr { $$ = Expr\BinaryOp\SmallerOrEqual[$1, $3]; }
10861087
| expr '>' expr { $$ = Expr\BinaryOp\Greater [$1, $3]; }
10871088
| expr T_IS_GREATER_OR_EQUAL expr { $$ = Expr\BinaryOp\GreaterOrEqual[$1, $3]; }
1089+
#if PHP8
1090+
| expr T_PIPE expr { $$ = Expr\BinaryOp\Pipe[$1, $3]; }
1091+
#endif
10881092
| expr T_INSTANCEOF class_name_reference { $$ = Expr\Instanceof_[$1, $3]; }
10891093
| '(' expr ')' { $$ = $2; }
10901094
| expr '?' expr ':' expr { $$ = Expr\Ternary[$1, $3, $5]; }

lib/PhpParser/ConstExprEvaluator.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,9 @@ private function evaluateBinaryOp(Expr\BinaryOp $expr) {
215215
case '<': return $this->evaluate($l) < $this->evaluate($r);
216216
case '<=': return $this->evaluate($l) <= $this->evaluate($r);
217217
case '<=>': return $this->evaluate($l) <=> $this->evaluate($r);
218+
case '|>':
219+
$lval = $this->evaluate($l);
220+
return $this->evaluate($r)($lval);
218221
}
219222

220223
throw new \Exception('Should not happen');

lib/PhpParser/Lexer/TokenEmulator/PipeOperatorEmulator.php

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@
66
use PhpParser\PhpVersion;
77
use PhpParser\Token;
88

9-
class PipeOperatorEmulator extends TokenEmulator
10-
{
9+
class PipeOperatorEmulator extends TokenEmulator {
1110
public function getPhpVersion(): PhpVersion {
1211
return PhpVersion::fromComponents(8, 5);
1312
}
@@ -16,8 +15,7 @@ public function isEmulationNeeded(string $code): bool {
1615
return \strpos($code, '|>') !== false;
1716
}
1817

19-
public function emulate(string $code, array $tokens): array
20-
{
18+
public function emulate(string $code, array $tokens): array {
2119
for ($i = 0, $c = count($tokens); $i < $c; ++$i) {
2220
$token = $tokens[$i];
2321
if ($token->text === '|' && isset($tokens[$i + 1]) && $tokens[$i + 1]->text === '>') {
@@ -30,8 +28,7 @@ public function emulate(string $code, array $tokens): array
3028
return $tokens;
3129
}
3230

33-
public function reverseEmulate(string $code, array $tokens): array
34-
{
31+
public function reverseEmulate(string $code, array $tokens): array {
3532
for ($i = 0, $c = count($tokens); $i < $c; ++$i) {
3633
$token = $tokens[$i];
3734
if ($token->id === \T_PIPE) {
@@ -45,4 +42,4 @@ public function reverseEmulate(string $code, array $tokens): array
4542
}
4643
return $tokens;
4744
}
48-
}
45+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace PhpParser\Node\Expr\BinaryOp;
4+
5+
use PhpParser\Node\Expr\BinaryOp;
6+
7+
class Pipe extends BinaryOp {
8+
public function getOperatorSigil(): string {
9+
return '|>';
10+
}
11+
12+
public function getType(): string {
13+
return 'Expr_BinaryOp_Pipe';
14+
}
15+
}

0 commit comments

Comments
 (0)