Re: [abigail@foad.org: [ID 20000901.065] -MO=Deparse and $^W and $[ in same string.]
Robin Houston [Fri, 20 Apr 2001 14:29:22 +0000 (15:29 +0100)]
Message-ID: <20010420142921.A14960@puffinry.freeserve.co.uk>

p4raw-id: //depot/perl@9765

ext/B/B.pm
ext/B/B/Deparse.pm

index a33ff2b..d00f512 100644 (file)
@@ -80,6 +80,10 @@ sub B::IV::int_value {
   return (($self->FLAGS() & SVf_IVisUV()) ? $self->UVX : $self->IV);
 }
 
+sub B::NULL::as_string() {""}
+sub B::IV::as_string()   {goto &B::IV::int_value}
+sub B::PV::as_string()   {goto &B::PV::PV}
+
 my $debug;
 my $op_count = 0;
 my @parents = ();
index 47e8e99..d3cda82 100644 (file)
@@ -2647,16 +2647,17 @@ sub dq {
     my $op = shift;
     my $type = $op->name;
     if ($type eq "const") {
-       if ($op->private & OPpCONST_ARYBASE) {
-           return '$[';
-       }
-       return uninterp(escape_str(unback(const($self->const_sv($op)))));
+       return '$[' if $op->private & OPpCONST_ARYBASE;
+       return uninterp(escape_str(unback($self->const_sv($op)->as_string)));
     } elsif ($type eq "concat") {
        my $first = $self->dq($op->first);
        my $last  = $self->dq($op->last);
        # Disambiguate "${foo}bar", "${foo}{bar}", "${foo}[1]"
-        if ($last =~ /^[{\[\w]/) {
-           $first =~ s/([%\$@])([A-Za-z_]\w*)$/${1}{$2}/;
+       if ($last =~ /^[A-Z\\\^\[\]_?]/) {
+           $first =~ s/([\$@])\^$/${1}{^}/;  # "${^}W" etc
+        }
+       elsif ($last =~ /^[{\[\w]/) {
+           $first =~ s/([\$@])([A-Za-z_]\w*)$/${1}{$2}/;
        }
        return $first . $last;
     } elsif ($type eq "uc") {
@@ -2945,13 +2946,17 @@ sub re_dq {
     my $op = shift;
     my $type = $op->name;
     if ($type eq "const") {
-       return re_uninterp(escape_str(re_unback($self->const_sv($op)->PV)));
+       return '$[' if $op->private & OPpCONST_ARYBASE;
+       return re_uninterp(escape_str(re_unback($self->const_sv($op)->as_string)));
     } elsif ($type eq "concat") {
        my $first = $self->re_dq($op->first);
        my $last  = $self->re_dq($op->last);
        # Disambiguate "${foo}bar", "${foo}{bar}", "${foo}[1]"
-       if ($last =~ /^[{\[\w]/) {
-           $first =~ s/([%\$@])([A-Za-z_]\w*)$/${1}{$2}/;
+       if ($last =~ /^[A-Z\\\^\[\]_?]/) {
+           $first =~ s/([\$@])\^$/${1}{^}/;
+       }
+       elsif ($last =~ /^[{\[\w]/) {
+           $first =~ s/([\$@])([A-Za-z_]\w*)$/${1}{$2}/;
        }
        return $first . $last;
     } elsif ($type eq "uc") {