This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Deparse nested (($x .= ...) .= ...) correctly.
authorDavid Mitchell <davem@iabyn.com>
Fri, 17 Nov 2017 12:47:07 +0000 (12:47 +0000)
committerDavid Mitchell <davem@iabyn.com>
Thu, 23 Nov 2017 08:52:16 +0000 (08:52 +0000)
It was sometimes outputting '.=' as '.'.

Now that the OPpCONCAT_NESTED flag has been added to indicate
that OPf_STACKED has been set on a concat op as an optimisation rather than
indictating .=, it's easier to deparse CONCAT/OPf_STACKED correctly.

lib/B/Deparse.pm
lib/B/Deparse.t

index a0ccf23..1107303 100644 (file)
@@ -19,6 +19,7 @@ use B qw(class main_root main_start main_cv svref_2object opnumber perlstring
         OPpSORT_REVERSE OPpMULTIDEREF_EXISTS OPpMULTIDEREF_DELETE
          OPpSPLIT_ASSIGN OPpSPLIT_LEX
          OPpPADHV_ISKEYS OPpRV2HV_ISKEYS
+         OPpCONCAT_NESTED
          OPpMULTICONCAT_APPEND OPpMULTICONCAT_STRINGIFY OPpMULTICONCAT_FAKE
          OPpTRUEBOOL OPpINDEX_BOOLNEG
         SVf_IOK SVf_NOK SVf_ROK SVf_POK SVpad_OUR SVf_FAKE SVs_RMG SVs_SMG
@@ -3033,7 +3034,8 @@ sub real_concat {
     my $right = $op->last;
     my $eq = "";
     my $prec = 18;
-    if ($op->flags & OPf_STACKED and $op->first->name ne "concat") {
+    if (($op->flags & OPf_STACKED) and !($op->private & OPpCONCAT_NESTED)) {
+        # '.=' rather than optimised '.'
        $eq = "=";
        $prec = 7;
     }
index 471cf60..fe176e1 100644 (file)
@@ -2962,3 +2962,8 @@ $res = CORE::keys(%h1) / 2 - 1;
 $res = CORE::keys(%h2) / 2 - 1;
 $res = CORE::keys(%$r1) / 2 - 1;
 $res = CORE::keys(%$r2) / 2 - 1;
+####
+# concat: STACKED: ambiguity between .= and optimised nested
+my($a, $b);
+$b = $a . $a . $a;
+(($a .= $a) .= $a) .= $a;