From a53229760cd904d90043d65bab4fa648cf56f232 Mon Sep 17 00:00:00 2001 From: Timm Friebe Date: Wed, 27 Mar 2024 13:30:25 +0100 Subject: [PATCH 1/4] Add syntactical support for pipelines with `|>` and `?|>` --- src/main/php/lang/ast/Tokens.class.php | 4 ++-- .../lang/ast/nodes/PipeExpression.class.php | 19 +++++++++++++++++++ src/main/php/lang/ast/syntax/PHP.class.php | 11 +++++++++++ 3 files changed, 32 insertions(+), 2 deletions(-) create mode 100755 src/main/php/lang/ast/nodes/PipeExpression.class.php diff --git a/src/main/php/lang/ast/Tokens.class.php b/src/main/php/lang/ast/Tokens.class.php index 179b4c7..19c71e8 100755 --- a/src/main/php/lang/ast/Tokens.class.php +++ b/src/main/php/lang/ast/Tokens.class.php @@ -17,7 +17,7 @@ class Tokens { '=' => ['===', '=>', '=='], '!' => ['!==', '!='], '&' => ['&&=', '&&', '&='], - '|' => ['||=', '||', '|='], + '|' => ['||=', '||', '|=', '|>'], '^' => ['^='], '+' => ['+=', '++'], '-' => ['-=', '--', '->'], @@ -25,7 +25,7 @@ class Tokens { '/' => ['/='], '~' => ['~='], '%' => ['%='], - '?' => ['?->', '??=', '?:', '??'], + '?' => ['?->', '?|>', '??=', '?:', '??'], '.' => ['...', '.='], ':' => ['::'], '[' => [], diff --git a/src/main/php/lang/ast/nodes/PipeExpression.class.php b/src/main/php/lang/ast/nodes/PipeExpression.class.php new file mode 100755 index 0000000..43c4d44 --- /dev/null +++ b/src/main/php/lang/ast/nodes/PipeExpression.class.php @@ -0,0 +1,19 @@ +expression= $expression; + $this->target= $target; + $this->line= $line; + } + + /** @return iterable */ + public function children() { + return [$this->expression, $this->target]; + } +} \ No newline at end of file diff --git a/src/main/php/lang/ast/syntax/PHP.class.php b/src/main/php/lang/ast/syntax/PHP.class.php index 25e5823..ae52935 100755 --- a/src/main/php/lang/ast/syntax/PHP.class.php +++ b/src/main/php/lang/ast/syntax/PHP.class.php @@ -42,6 +42,7 @@ NullSafeInstanceExpression, OffsetExpression, Parameter, + PipeExpression, Property, ReturnStatement, ScopeExpression, @@ -173,6 +174,16 @@ public function __construct() { return new ScopeExpression($scope, $expr, $left->line); }); + $this->infix('|>', 90, function($parse, $token, $left) { + return new PipeExpression($left, $this->expression($parse, 90), $left->line); + }); + + $this->infix('?|>', 90, function($parse, $node, $left) { + $value= new PipeExpression($left, $this->expression($parse, 90), $left->line); + $value->kind= 'nullsafepipe'; + return $value; + }); + $this->infix('(', 100, function($parse, $token, $left) { // Resolve ambiguity by looking ahead: `func(...)` which is a first-class From 7368aa7697ff59d8623764d9593a1a3321c8032c Mon Sep 17 00:00:00 2001 From: Timm Friebe Date: Sat, 8 Feb 2025 10:01:57 +0100 Subject: [PATCH 2/4] Adhere to https://wiki.php.net/rfc/pipe-operator-v3#precedence --- src/main/php/lang/ast/syntax/PHP.class.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/php/lang/ast/syntax/PHP.class.php b/src/main/php/lang/ast/syntax/PHP.class.php index a716883..492a00b 100755 --- a/src/main/php/lang/ast/syntax/PHP.class.php +++ b/src/main/php/lang/ast/syntax/PHP.class.php @@ -175,12 +175,12 @@ public function __construct() { return new ScopeExpression($scope, $expr, $token->line); }); - $this->infix('|>', 90, function($parse, $token, $left) { - return new PipeExpression($left, $this->expression($parse, 90), $left->line); + $this->infix('|>', 20, function($parse, $token, $left) { + return new PipeExpression($left, $this->expression($parse, 20), $left->line); }); - $this->infix('?|>', 90, function($parse, $node, $left) { - $value= new PipeExpression($left, $this->expression($parse, 90), $left->line); + $this->infix('?|>', 20, function($parse, $node, $left) { + $value= new PipeExpression($left, $this->expression($parse, 20), $left->line); $value->kind= 'nullsafepipe'; return $value; }); From abdf78bc0145c06fe0ac6729c3c52cce6a041a39 Mon Sep 17 00:00:00 2001 From: Timm Friebe Date: Sun, 18 May 2025 11:21:36 +0200 Subject: [PATCH 3/4] Adjust operator precedence to bind higher See https://wiki.php.net/rfc/pipe-operator-v3#precedence --- src/main/php/lang/ast/syntax/PHP.class.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/php/lang/ast/syntax/PHP.class.php b/src/main/php/lang/ast/syntax/PHP.class.php index b2ed115..c65cd5d 100755 --- a/src/main/php/lang/ast/syntax/PHP.class.php +++ b/src/main/php/lang/ast/syntax/PHP.class.php @@ -175,12 +175,12 @@ public function __construct() { return new ScopeExpression($scope, $expr, $token->line); }); - $this->infix('|>', 20, function($parse, $token, $left) { - return new PipeExpression($left, $this->expression($parse, 20), $left->line); + $this->infix('|>', 40, function($parse, $token, $left) { + return new PipeExpression($left, $this->expression($parse, 40), $left->line); }); - $this->infix('?|>', 20, function($parse, $node, $left) { - $value= new PipeExpression($left, $this->expression($parse, 20), $left->line); + $this->infix('?|>', 40, function($parse, $node, $left) { + $value= new PipeExpression($left, $this->expression($parse, 40), $left->line); $value->kind= 'nullsafepipe'; return $value; }); From 3a7f1580aef3e31a71011a967c73d0a96fbc410a Mon Sep 17 00:00:00 2001 From: Timm Friebe Date: Sun, 18 May 2025 12:26:06 +0200 Subject: [PATCH 4/4] Fix ternary precedence to match its short form, `?:` --- src/main/php/lang/ast/syntax/PHP.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/php/lang/ast/syntax/PHP.class.php b/src/main/php/lang/ast/syntax/PHP.class.php index c65cd5d..8aa88ab 100755 --- a/src/main/php/lang/ast/syntax/PHP.class.php +++ b/src/main/php/lang/ast/syntax/PHP.class.php @@ -218,7 +218,7 @@ public function __construct() { return new OffsetExpression($left, $expr, $left->line); }); - $this->infix('?', 80, function($parse, $token, $left) { + $this->infix('?', 30, function($parse, $token, $left) { $when= $this->expression($parse, 0); $parse->expecting(':', 'ternary'); $else= $this->expression($parse, 0);