Deparse: don't parenthesise state @a = ...
authorDavid Mitchell <davem@iabyn.com>
Wed, 22 Nov 2017 13:32:03 +0000 (13:32 +0000)
committerDavid Mitchell <davem@iabyn.com>
Thu, 23 Nov 2017 08:52:16 +0000 (08:52 +0000)
It was deparsing

    state @a = ...

as

    (state(@a)) = ...

(and similarly for CORE::state(...))

However, a list assign of a state array/hash is currently only legal
in the absence of parens.

lib/B/Deparse-core.t
lib/B/Deparse.pm
lib/B/Deparse.t

index 2ed797a..6ee935f 100644 (file)
@@ -80,21 +80,23 @@ sub testit {
        $desc .= " (lex sub)" if $lexsub;
 
 
+        my $code;
        my $code_ref;
        if ($lexsub) {
            package lexsubtest;
            no warnings 'experimental::lexical_subs';
            use feature 'lexical_subs';
            no strict 'vars';
-           $code_ref =
-               eval "sub { state sub $keyword; ${vars}() = $expr }"
-                           || die "$@ in $expr";
+            $code = "sub { state sub $keyword; ${vars}() = $expr }";
+           $code_ref = eval $code
+                           or die "$@ in $expr";
        }
        else {
            package test;
            use subs ();
            import subs $keyword;
-           $code_ref = eval "no strict 'vars'; sub { ${vars}() = $expr }"
+           $code = "no strict 'vars'; sub { ${vars}() = $expr }";
+           $code_ref = eval $code
                            or die "$@ in $expr";
        }
 
@@ -115,7 +117,8 @@ sub testit {
        }
 
        my $got_expr = $1;
-       is $got_expr, $expected_expr, $desc;
+       is $got_expr, $expected_expr, $desc
+            or ::diag("ORIGINAL CODE:\n$code");;
     }
 }
 
@@ -639,7 +642,7 @@ sprintf          123   p
 sqrt             01    $
 srand            01    -
 stat             01    $
-state            123   p+ # skip with 0 args, as state() => ()
+state            123   p1+ # skip with 0 args, as state() => ()
 study            01    $+
 # sub handled specially
 substr           234   p
index b19b40f..b70941c 100644 (file)
@@ -2965,7 +2965,7 @@ sub binop {
     my $leftop = $left;
     $left = $self->deparse_binop_left($op, $left, $prec);
     $left = "($left)" if $flags & LIST_CONTEXT
-                    and    $left !~ /^(my|our|local|)[\@\(]/
+                    and    $left !~ /^(my|our|local|state|)\s*[\@%\(]/
                         || do {
                                # Parenthesize if the left argument is a
                                # lone repeat op.
@@ -3739,6 +3739,10 @@ sub pp_list {
        push @exprs, $expr;
     }
     if ($local) {
+        if (@exprs == 1 && ($local eq 'state' || $local eq 'CORE::state')) {
+            # 'state @a = ...' is legal, while 'state(@a) = ...' currently isn't
+            return "$local $exprs[0]";
+        }
        return "$local(" . join(", ", @exprs) . ")";
     } else {
        return $self->maybe_parens( join(", ", @exprs), $cx, 6);        
index 83e46e8..7d5f3ca 100644 (file)
@@ -2988,3 +2988,8 @@ $b = $a . $a . $a;
 my($a, $x);
 $x = "${$}abc";
 $x = "\$$a";
+####
+# single state aggregate assignment
+# CONTEXT use feature "state";
+state @a = (1, 2, 3);
+state %h = ('a', 1, 'b', 2);