This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Perl_scalar(): doc and reorganise complex bool
authorDavid Mitchell <davem@iabyn.com>
Wed, 29 May 2019 09:32:41 +0000 (10:32 +0100)
committerDavid Mitchell <davem@iabyn.com>
Mon, 24 Jun 2019 10:40:07 +0000 (11:40 +0100)
The if statement that scans children applying void context to all except
the last child:

1) document what it does;
2) reorganise it (without changing its logical meaning) to make it
simpler to understand, and to make the next commit easier.

op.c

diff --git a/op.c b/op.c
index a710cdb..6522239 100644 (file)
--- a/op.c
+++ b/op.c
@@ -1856,13 +1856,29 @@ Perl_scalar(pTHX_ OP *o)
         do_kids:
             while (kid) {
                 OP *sib = OpSIBLING(kid);
-                if (sib && kid->op_type != OP_LEAVEWHEN
-                 && (  OpHAS_SIBLING(sib) || sib->op_type != OP_NULL
-                    || (  sib->op_targ != OP_NEXTSTATE
-                       && sib->op_targ != OP_DBSTATE  )))
-                    scalarvoid(kid);
-                else
+                /* Apply void context to all kids except the last, which
+                 * is scalar (ignoring a trailing ex-nextstate in determining
+                 * if it's the last kid). E.g.
+                 *      $scalar = do { void; void; scalar }
+                 * Except that 'when's are always scalar, e.g.
+                 *      $scalar = do { given(..) {
+                    *                 when (..) { scalar }
+                    *                 when (..) { scalar }
+                    *                 ...
+                    *                }}
+                    */
+                if (!sib
+                     || (  !OpHAS_SIBLING(sib)
+                         && sib->op_type == OP_NULL
+                         && (   sib->op_targ == OP_NEXTSTATE
+                             || sib->op_targ == OP_DBSTATE  )
+                        )
+                )
+                    scalar(kid);
+                else if (kid->op_type == OP_LEAVEWHEN)
                     scalar(kid);
+                else
+                    scalarvoid(kid);
                 kid = sib;
             }
             PL_curcop = &PL_compiling;