compiler
compiler copied to clipboard
Logical Operators and Assignment Expressions:
Add ||= and &&= operators accompanying the ??= operator:
$a ||= $b; // equivalent of $a || ($a= $b);
$a &&= $b; // equivalent of $a && ($a= $b);
$a ??= $b; // equivalent of $a ?? ($a= $b); - EXISTS in PHP!
https://github.com/tc39/proposal-logical-assignment https://github.com/dotnet/csharplang/issues/1718
Implementation:
diff --git a/src/main/php/lang/ast/emit/PHP.class.php b/src/main/php/lang/ast/emit/PHP.class.php
index ac3d93a..79cf654 100755
--- a/src/main/php/lang/ast/emit/PHP.class.php
+++ b/src/main/php/lang/ast/emit/PHP.class.php
@@ -789,7 +789,15 @@ abstract class PHP extends Emitter {
protected function emitAssignment($result, $assignment) {
$this->emitAssign($result, $assignment->variable);
- $result->out->write($assignment->operator);
+
+ if ('||=' === $assignment->operator || '&&=' === $assignment->operator) {
+ $result->out->write(substr($assignment->operator, 0, 2));
+ $this->emitOne($result, $assignment->variable);
+ $result->out->write('=');
+ } else {
+ $result->out->write($assignment->operator);
+ }
+
$this->emitOne($result, $assignment->expression);
}
diff --git a/src/test/php/lang/ast/unittest/emit/OperatorTest.class.php b/src/test/php/lang/ast/unittest/emit/OperatorTest.class.php
index 0e1833b..7c87653 100755
--- a/src/test/php/lang/ast/unittest/emit/OperatorTest.class.php
+++ b/src/test/php/lang/ast/unittest/emit/OperatorTest.class.php
@@ -65,4 +65,28 @@ class OperatorTest extends EmittingTest {
Assert::equals($expected, $r[0]);
}
+
+ #[Test, Values([[false, true], [true, true]])]
+ public function logical_or_assignment($value, $expected) {
+ $r= $this->run('class %T {
+ public function run($arg) {
+ $arg||= true;
+ return $arg;
+ }
+ }', $value);
+
+ Assert::equals($expected, $r);
+ }
+
+ #[Test, Values([[true, false], [false, false]])]
+ public function logical_and_assignment($value, $expected) {
+ $r= $this->run('class %T {
+ public function run($arg) {
+ $arg&&= false;
+ return $arg;
+ }
+ }', $value);
+
+ Assert::equals($expected, $r);
+ }
}
\ No newline at end of file