develooper Front page | perl.perl5.changes | Postings from August 2012

[perl.git] branch blead, updated. v5.17.2-261-g7ef3083

From:
Father Chrysostomos
Date:
August 8, 2012 12:26
Subject:
[perl.git] branch blead, updated. v5.17.2-261-g7ef3083
Message ID:
E1SzBtC-0003G4-7a@camel.ams6.corp.booking.com
In perl.git, the branch blead has been updated

<http://perl5.git.perl.org/perl.git/commitdiff/7ef3083086f16586f909089ba7d9cc1468ffe2c5?hp=513b1ee2ffc66290ce706625c54422114d634f98>

- Log -----------------------------------------------------------------
commit 7ef3083086f16586f909089ba7d9cc1468ffe2c5
Author: Father Chrysostomos <sprout@cpan.org>
Date:   Wed Aug 8 10:00:52 2012 -0700

    [perl #114018] Let eval close over stale vars in active sub
    
    See also commit cae5dbbe30.
    
    These two lines should never produce different values:
    
        print $x, "\n";
        print eval '$x', "\n";
    
    But they were producing different values if $x happened to have the
    tale flag set.  Even if my in false conditional is not supported (this
    was the cause of the bug report), it should still work; and it is
    not the only way to get a stale lexical in an active sub (just the
    easiest way).
    
    As long as the sub containing the eval is active, the eval should be
    able to see the same variables, stale or not.
    
    However, this does get a bit tricky in cases like this, which legiti-
    mately warn (from t/lib/warnings/pad):
    
    {
        my $x = 1;
        $y = \$x; # force abandonment rather than clear-in-place at scope exit
        sub f2 { eval '$x' }
    }
    f2();
    
    In this case the f2 sub does not explicitly close over the $x, so by
    the time the eval is reached the ‘right’ $x is gone.
    
    It is only in those cases where the sub containing the eval has
    the stale variable in its own pad that we can safely ignore the
    stale flag.

M	pad.c
M	pad.h
M	t/op/closure.t

commit 710ba57483decc7a3b32692be6933c6ba9518234
Author: Father Chrysostomos <sprout@cpan.org>
Date:   Wed Aug 8 06:15:24 2012 -0700

    B::Concise: Document formats

M	ext/B/B/Concise.pm

commit 705fe0e5f8a324e10c292190237cac35c5af4109
Author: Father Chrysostomos <sprout@cpan.org>
Date:   Wed Aug 8 00:36:57 2012 -0700

    Don’t let format arguments ‘leak out’ of formline
    
    When parsing formats, the lexer invents tokens to feed to the parser.
    
    So when the lexer dissects this:
    
    format =
    @<<<< @>>>>
    $foo, $bar, $baz
    .
    
    The parser actually sees this (the parser knows that = . is like { }):
    
    format =
    ; formline "@<<<< @>>>>\n", $foo, $bar, $baz;
    .
    
    The lexer makes no effort to make sure that the argument line is con-
    tained within formline’s arguments.  To make
    
    { do_stuff; $foo, bar }
    
    work, the lexer supplies a ‘do’ before the block, if it is
    inside a format.
    
    This means that
    
    $a, $b; $c, $d
    
    feeds ($a, $b) to formline, wheras
    
    { $a, $b; $c, $d }
    
    feeds ($c, $d) to formline.  It also has various other
    strange effects:
    
    This script prints "# 0" as I would expect:
    
    print "# ";
    format =
    @
    (0 and die)
    .
    write
    
    This one, locking parentheses, dies because ‘and’ has low precedence:
    
    print "# ";
    format =
    @
    0 and die
    .
    write
    
    This does not work:
    
    my $day = "Wed";
    format =
    @<<<<<<<<<<
    ({qw[ Sun 0 Mon 1 Tue 2 Wed 3 Thu 4 Fri 5 Sat 6 ]}->{$day})
    .
    write
    
    You have to do this:
    
    my $day = "Wed";
    format =
    @<<<<<<<<<<
    ({my %d = qw[ Sun 0 Mon 1 Tue 2 Wed 3 Thu 4 Fri 5 Sat 6 ]; \%d}->{$day})
    .
    write
    
    which is very strange and shouldn’t even be valid syntax.
    
    This does not work, because ‘no’ is not allowed in an expression:
    
    use strict;
    $::foo = "bar"
    format =
    @<<<<<<<<<<<
    no strict; $foo
    .
    write;
    
    Putting a block around it makes it work.  Putting a semicolon before
    ‘no’ stop it from being a syntax error, but it silently does the
    wrong thing.
    
    I thought I could fix all these by putting an implicit do { ... }
    around the argument line and removing the special-casing for an open-
    ing brace, allowing anonymous hashrefs to work in formats, such
    that this:
    
    format =
    @<<<< @>>>>
    $foo, $bar, $baz
    .
    
    would turn into this:
    
    format =
    ; formline "@<<<< @>>>>\n", do { $foo, $bar, $baz; };
    .
    
    But that will lead to madness like this ‘working’:
    
    format =
    @
    }+do{
    .
    
    It would also stop lexicals declared in one format line from being
    visible in another.
    
    So instead this commit starts being honest with the parser.  We still
    have some ‘invented’ tokens, to indicate the start and end of a format
    line, but now it is the parser itself that understands a sequence of
    format lines, instead of being fed generated code.
    
    So the example above is now presented to the parser like this:
    
    format = ; FORMRBRACK
    "@<<<< @>>>>\n" FORMLBRACK $foo, $bar, $baz ; FORMRBRACK
    ; .
    
    Note about the semicolons:  The parser expects to see a semicolon at
    the end of each statement.  So the lexer has to supply one before
    FORMRBRACK.  The final dot goes through the same code that handles
    closing braces, which generates a semicolon for the same reason.  It’s
    easier to make the parser expect a semicolon before the final dot than
    to change the } code in the lexer.  We use the } code for . because it
    handles the internal variables that keep track of how many nested lev-
    els there, what kind, etc.
    
    The extra ;FORMRBRACK after the = is there also to keep the lexer sim-
    ple (ahem).  When a newline is encountered during ‘normal’ (as opposed
    to format picture) parsing inside a format, that’s when the semicolon
    and FORMRBRACK are emitted.  (There was already a semicolon there
    before this commit.  I have just added FORMRBRACK in the same spot.)

M	embed.fnc
M	embed.h
M	op.c
M	perly.act
M	perly.h
M	perly.tab
M	perly.y
M	proto.h
M	t/op/write.t
M	toke.c

commit 35f7559499c4a614ddae483553149a29d9c78c13
Author: Father Chrysostomos <sprout@cpan.org>
Date:   Tue Aug 7 23:16:46 2012 -0700

    B::Concise: Dump formats upon request

M	ext/B/B/Concise.pm
M	ext/B/t/optree_misc.t

commit 35fc9e3b896a3f92cdb1d1dc1f7d8250a830b3bc
Author: Father Chrysostomos <sprout@cpan.org>
Date:   Tue Aug 7 22:50:19 2012 -0700

    B::Concise: Fix -nobanner
    
    It was only working when B::Concise was passed a code ref.

M	ext/B/B/Concise.pm
M	ext/B/t/concise.t

commit 483171d404245647cff3d48314fefbcd8bf28ac6
Author: Father Chrysostomos <sprout@cpan.org>
Date:   Tue Aug 7 22:45:08 2012 -0700

    Increase $B::Concise::VERSION to 0.92

M	ext/B/B/Concise.pm

commit 771675e4aa9544ae11782e155c2d568afd958c2d
Author: Father Chrysostomos <sprout@cpan.org>
Date:   Tue Aug 7 13:34:45 2012 -0700

    toke.c: Remove unnecessary assignment
    
    This was made unnecessary in commit 64a408986cf3d, which changed the
    enclosing if block’s protasis to PL_expect == XBLOCK (and also made
    sure that PL_expect is set to XBLOCK when a format’s special = delim-
    iter is expected).

M	toke.c

commit 6c7ae946aa60721f014be4f2a95bdd91470cf3d9
Author: Father Chrysostomos <sprout@cpan.org>
Date:   Tue Aug 7 13:25:24 2012 -0700

    Prevent double frees/crashes with format syntax errs
    
    This was brought up in ticket #43425.
    
    The new slab allocator for ops (8be227ab5e) makes a CV responsible for
    cleaning up its ops if it is freed prematurely (before the root is
    attached).
    
    Certain syntax errors involving formats can cause the parser to free
    the CV owning an op when that op is on the PL_nextval stack.
    
    This happens in these cases:
    
    format =
    @
    use; format
    strict
    .
    
    format =
    @
    ;use
    strict
    .
    
    format foo require bar
    
    In the first two cases it is the line containing ‘strict’ that is
    being interpreted as a format picture line and being fed through
    force_next by S_scan_formline.
    
    Then the error condition kicks in after the force, causing a
    LEAVE_SCOPE in the parser (perly.c) which frees the sub owning the
    const op for the format picture.  Then a token with a freed op is fed
    to the parser.
    
    To make this clearer, when the second case above is parsed, the tokens
    produced are as follows:
    
    format =
    [;] [formline] "@\n" [,]
    ; use [<word>]
    [;] [formline] <freed>
    [;] .
    
    Notice how there is an implicit semicolon before each (implicit)
    formline.  Notice also how there is an implicit semicolon before the
    final dot.
    
    The <freed> thing represents the "strict\n" constant after it has been
    freed.  (-DT displays it as THING(opval=op_freed).)
    
    When the implicit semicolon is emitted before a formline, the next two
    tokens (formline and the string constant for this format picture line)
    are put on to the PL_nextval stack via force_next.
    
    It is when the implicit semicolon before "strict\n" is emitted that
    the parser sees the error (there is only one path through the gram-
    mar that uses the USE token, and it must have two WORDs following it;
    therefore a semicolon after one WORD is an immediate error), calling
    LEAVE_SCOPE, which frees the sub created by ‘use’, which owns the
    const op on the PL_nextval stack containing the word "strict" and con-
    sequently frees it.
    
    I thought I could fix this by putting an implicit do { ... } around
    the argument line.  (This would fix another bug, whereby the argument
    line in a format can ‘leak out’ of the formline(...).)  But this does
    not solve anything, as we end up with four tokens ( } ; formline
    const ) on the PL_nextval stack when we emit the implicit semicolon
    after ‘use’, instead of two.
    
    format=
    @
    ;use
    strict
    .
    
    will turn into
    
    format =
    [;] [formline] "@\n" [,]
    [do] [{] ; use [<word>] [;] [}]
    [;] [formline] "strict\n"/<freed>
    [;] .
    
    It is when the lexer reaches "strict" that it will emit the semicolon
    after the use.  So we will be in the same situation as before.
    
    So fixing the fact that the argument line can ‘leak out’ of the
    formline and start a new statement won’t solve this particu-
    lar problem.
    
    I tried eliminating the LEAVE_SCOPE.  (See
    <https://rt.perl.org/rt3/Ticket/Display.html?id=43425#txn-273447>
    where Dave Mitchell explains that the LEAVE_SCOPE is not strictly nec-
    essary, but it is ‘still good to ensure that the savestack gets cor-
    rectly popped during error recovery’.)  That does not help, because
    the lexer itself does ENTER/LEAVE to make sure form_lex_state and
    lex_formbrack get restored properly after the lexer exits the format
    (see 583c9d5cccf and 64a408986cf).
    
    So when the final dot is reached, the ‘use’ CV is freed.  Then an op
    tree that includes the now-freed "strict\n" const op is passed to
    newFORM, which tries to do op_free(block) (as of 3 commits ago; before
    that the errors were more catastrophic), and ends up freeing an op
    belonging to a freed slab.
    
    Removing LEAVE_SCOPE did actually fix ‘format foo require bar’,
    because there is no ENTER/LEAVE involved there, as the = (ENTER) has
    not been reached yet.  It was failing because ‘require bar’ would call
    force_next for "bar", and then feed a REQUIRE token to the parser,
    which would immediately see the error and call LEAVE_SCOPE (free-
    ing the format), with the "bar" (belonging to the format’s slab)
    still pending.
    
    The final solution I came up with was to reuse an mechanism I came up
    with earlier.  Since the savestack may cause ops to outlive their CVs
    due to SAVEFREEOP, opslab_force_free (called when an incomplete CV is
    freed prematurely) will skip any op with o->op_savestack set.  The
    nextval stack can use the same flag.  To make sure nothing goes awry
    (we don’t want the same op on the nextval stack and the savestack at
    the same time), I added a few assertions.

M	perly.act
M	perly.h
M	perly.tab
M	regen_perly.pl
M	scope.h
M	t/op/write.t
M	toke.c

commit aeaef3491d1eee1a07d91d03608fa86baf9dde40
Author: Father Chrysostomos <sprout@cpan.org>
Date:   Tue Aug 7 05:51:35 2012 -0700

    toke.c: Remove TOKENTYPE_GVVAL
    
    It has been unused since it was added in bbf60fe6.

M	toke.c

commit f3f204dc630d5b7c057cde6dea93f281cb29251a
Author: Father Chrysostomos <sprout@cpan.org>
Date:   Mon Aug 6 23:20:14 2012 -0700

    toke.c: Add missing debug tokens

M	toke.c

commit 2c658e55bf9e8acf7cc0207ea3db8f7064cb3ad7
Author: Father Chrysostomos <sprout@cpan.org>
Date:   Mon Aug 6 21:59:17 2012 -0700

    Don’t create formats after compilation errors
    
    Otherwise you can end up with a format that has nonsensical op tree,
    but it gets attached and you can call it anyway.

M	op.c
M	perly.act
M	perly.h
M	perly.tab
M	perly.y
M	t/op/write.t

commit a33a81d07c9c0cb0ab9ba85fab5a519c4b3b710b
Author: Father Chrysostomos <sprout@cpan.org>
Date:   Mon Aug 6 17:52:10 2012 -0700

    Add freed ops to PL_op_(name|desc)
    
    This is useful for debugging, especially with -DT.

M	opcode.h
M	regen/opcode.pl

commit b27dce25d7618d1797015079eaecd1913f133d47
Author: Father Chrysostomos <sprout@cpan.org>
Date:   Mon Aug 6 14:34:25 2012 -0700

    toke.c: Fix confused interp-in-format parsing
    
    The lexer keeps track of how many levels of brackets it is currently
    in (including the = and . delimiting formats, which count as brackets)
    in PL_lex_brackets.
    
    When parsing a format, the lexer sets lex_formbrack to the form’s
    bracket number.  Whitespace parsing takes note of this, and avoids
    reading beyond the end of the current line inside a format, unless it
    is in an inner bracketed construct.  So this:
    
    format =
    @
    $a
     + $b
    .
    
    treats ‘ + $b’ as a literal string, which becomes the second line
    of output.
    
    But this:
    
    format =
    @
    { $a
       + $b }
    .
    
    treats the whole {...} block as the argument for the first format pic-
    ture line.
    
    For interpolating (i.e., quoted) constructs, the lexer temporarily
    resets the bracket count.  This is so that when it reaches the final
    brace in "${...}foo()" it can parse the rest (foo()) as a constant,
    rather than a sub call.
    
    When the bracket count was reset, lex_formbrack was left as it was,
    resulting in confusion:
    
    # ok
    format =
    @
    ${; use
        strict}
    .
    
    # also ok
    format =
    @
    "${; {use
          strict} }"
    .
    
    # syntax error (or crash)
    format =
    @
    "${; use
         strict }"
    .
    
    # crash
    format =
    @
    "${ use
        strict }"
    .
    
    When the bracket count is localised and reset at the start of a quoted
    construct, we now do the same with lex_formbrack.

M	t/op/write.t
M	toke.c
-----------------------------------------------------------------------

Summary of changes:
 embed.fnc             |    1 +
 embed.h               |    1 +
 ext/B/B/Concise.pm    |   27 +-
 ext/B/t/concise.t     |    9 +-
 ext/B/t/optree_misc.t |   48 ++-
 op.c                  |   27 +-
 opcode.h              |    2 +
 pad.c                 |    9 +-
 pad.h                 |    2 +
 perly.act             |  843 ++++++++++++++------------
 perly.h               |  118 +++--
 perly.tab             | 1620 ++++++++++++++++++++++++-------------------------
 perly.y               |   51 ++-
 proto.h               |    1 +
 regen/opcode.pl       |    2 +
 regen_perly.pl        |   32 +-
 scope.h               |    2 +
 t/op/closure.t        |   11 +
 t/op/write.t          |   71 +++-
 toke.c                |   61 ++-
 20 files changed, 1631 insertions(+), 1307 deletions(-)

diff --git a/embed.fnc b/embed.fnc
index b65e41c..2b25b3c 100644
--- a/embed.fnc
+++ b/embed.fnc
@@ -966,6 +966,7 @@ p	|PerlIO*|nextargv	|NN GV* gv
 AnpP	|char*	|ninstr		|NN const char* big|NN const char* bigend \
 				|NN const char* little|NN const char* lend
 Ap	|void	|op_free	|NULLOK OP* arg
+Mp	|OP*	|op_unscope	|NULLOK OP* o
 #ifdef PERL_CORE
 p	|void	|opslab_free	|NN OPSLAB *slab
 p	|void	|opslab_free_nopad|NN OPSLAB *slab
diff --git a/embed.h b/embed.h
index 2eb01b9..fd03e8a 100644
--- a/embed.h
+++ b/embed.h
@@ -1171,6 +1171,7 @@
 #define oopsAV(a)		Perl_oopsAV(aTHX_ a)
 #define oopsHV(a)		Perl_oopsHV(aTHX_ a)
 #define op_const_sv(a,b)	Perl_op_const_sv(aTHX_ a,b)
+#define op_unscope(a)		Perl_op_unscope(aTHX_ a)
 #define package_version(a)	Perl_package_version(aTHX_ a)
 #define pad_block_start(a)	Perl_pad_block_start(aTHX_ a)
 #define pad_fixup_inner_anons(a,b,c)	Perl_pad_fixup_inner_anons(aTHX_ a,b,c)
diff --git a/ext/B/B/Concise.pm b/ext/B/B/Concise.pm
index 0dd9670..946b489 100644
--- a/ext/B/B/Concise.pm
+++ b/ext/B/B/Concise.pm
@@ -14,7 +14,7 @@ use warnings; # uses #3 and #4, since warnings uses Carp
 
 use Exporter (); # use #5
 
-our $VERSION   = "0.91";
+our $VERSION   = "0.92";
 our @ISA       = qw(Exporter);
 our @EXPORT_OK = qw( set_style set_style_standard add_callback
 		     concise_subref concise_cv concise_main
@@ -137,7 +137,7 @@ sub concise_subref {
     my $codeobj = svref_2object($coderef);
 
     return concise_stashref(@_)
-	unless ref $codeobj eq 'B::CV';
+	unless ref($codeobj) =~ '^B::(?:CV|FM)\z';
     concise_cv_obj($order, $codeobj, $name);
 }
 
@@ -357,21 +357,31 @@ sub compile {
 	    else {
 		# convert function names to subrefs
 		my $objref;
+		my $objref2;
 		if (ref $objname) {
 		    print $walkHandle "B::Concise::compile($objname)\n"
 			if $banner;
-		    $objref = $objname;
+		    concise_subref($order, ($objname)x2);
+		    next;
 		} else {
 		    $objname = "main::" . $objname unless $objname =~ /::/;
-		    print $walkHandle "$objname:\n";
 		    no strict 'refs';
-		    unless (exists &$objname) {
+		    my $glob = \*$objname;
+		    unless (*$glob{CODE} || *$glob{FORMAT}) {
+			print $walkHandle "$objname:\n" if $banner;
 			print $walkHandle "err: unknown function ($objname)\n";
 			return;
 		    }
-		    $objref = \&$objname;
+		    if (my $objref = *$glob{CODE}) {
+			print $walkHandle "$objname:\n" if $banner;
+			concise_subref($order, $objref, $objname);
+		    }
+		    if (my $objref = *$glob{FORMAT}) {
+			print $walkHandle "$objname (FORMAT):\n"
+			    if $banner;
+			concise_subref($order, $objref, $objname);
+		    }
 		}
-		concise_subref($order, $objref, $objname);
 	    }
 	}
 	for my $pkg (@render_packs) {
@@ -1129,7 +1139,8 @@ on threaded and un-threaded perls.
 =head1 OPTIONS
 
 Arguments that don't start with a hyphen are taken to be the names of
-subroutines to render; if no such functions are specified, the main
+subroutines or formats to render; if no
+such functions are specified, the main
 body of the program (outside any subroutines, and not including use'd
 or require'd files) is rendered.  Passing C<BEGIN>, C<UNITCHECK>,
 C<CHECK>, C<INIT>, or C<END> will cause all of the corresponding
diff --git a/ext/B/t/concise.t b/ext/B/t/concise.t
index faff8a3..ec911a0 100644
--- a/ext/B/t/concise.t
+++ b/ext/B/t/concise.t
@@ -10,7 +10,7 @@ BEGIN {
     require 'test.pl';		# we use runperl from 'test.pl', so can't use Test::More
 }
 
-plan tests => 159;
+plan tests => 160;
 
 require_ok("B::Concise");
 
@@ -448,4 +448,11 @@ ok index $out=~s/\r\n/\n/gr=~s/gvsv\(\*_\)/gvsv[*_]/r, <<'end'=~s/\r\n/\n/gr =>>
                            `-ex-rv2sv---<4>gvsv[*_]
 end
 
+# -nobanner
+$out =
+ runperl(
+  switches => ["-MO=Concise,-nobanner,foo"], prog=>'sub foo{}', stderr => 1
+ );
+unlike $out, 'main::foo', '-nobanner';
+
 __END__
diff --git a/ext/B/t/optree_misc.t b/ext/B/t/optree_misc.t
index 0af382a..2d9ad77 100644
--- a/ext/B/t/optree_misc.t
+++ b/ext/B/t/optree_misc.t
@@ -10,7 +10,7 @@ BEGIN {
 }
 use OptreeCheck;
 use Config;
-plan tests => 6;
+plan tests => 8;
 
 SKIP: {
 skip "no perlio in this build", 4 unless $Config::Config{useperlio};
@@ -123,3 +123,49 @@ checkOptree ( name      => 'index and PVBM',
 	      prog	=> '$_ = index q(foo), q(foo)',
 	      strip_open_hints => 1,
 	      expect	=> $t,  expect_nt => $nt);
+
+checkOptree ( name      => 'formats',
+	      bcopts    => 'STDOUT',
+	      prog	=> "no warnings;format =\n@<<<\n\$a\n@>>>\n\@b\n.",
+	      strip_open_hints => 1,
+	      expect	=> <<'EOT_EOT', expect_nt => <<'EONT_EONT');
+# main::STDOUT (FORMAT):
+# c  <1> leavewrite[1 ref] K/REFC,1 ->(end)
+# -     <@> lineseq KP ->c
+# 1        <;> nextstate(main 1 -:4) v ->2
+# 5        <@> formline vK/2 ->6
+# 2           <0> pushmark s ->3
+# 3           <$> const[PV "@<<<\n"] s ->4
+# -           <@> lineseq lK ->5
+# -              <0> ex-nextstate v ->4
+# -              <1> ex-rv2sv sK/1 ->-
+# 4                 <#> gvsv[*a] s ->5
+# 6        <;> nextstate(main 1 -:6) v ->7
+# b        <@> formline sK/2 ->c
+# 7           <0> pushmark s ->8
+# 8           <$> const[PV "@>>>\n"] s ->9
+# -           <@> lineseq lK ->b
+# -              <0> ex-nextstate v ->9
+# a              <1> rv2av[t3] lK/1 ->b
+# 9                 <#> gv[*b] s ->a
+EOT_EOT
+# main::STDOUT (FORMAT):
+# c  <1> leavewrite[1 ref] K/REFC,1 ->(end)
+# -     <@> lineseq KP ->c
+# 1        <;> nextstate(main 1 -:4) v ->2
+# 5        <@> formline vK/2 ->6
+# 2           <0> pushmark s ->3
+# 3           <$> const(PV "@<<<\n") s ->4
+# -           <@> lineseq lK ->5
+# -              <0> ex-nextstate v ->4
+# -              <1> ex-rv2sv sK/1 ->-
+# 4                 <$> gvsv(*a) s ->5
+# 6        <;> nextstate(main 1 -:6) v ->7
+# b        <@> formline sK/2 ->c
+# 7           <0> pushmark s ->8
+# 8           <$> const(PV "@>>>\n") s ->9
+# -           <@> lineseq lK ->b
+# -              <0> ex-nextstate v ->9
+# a              <1> rv2av[t3] lK/1 ->b
+# 9                 <$> gv(*b) s ->a
+EONT_EONT
diff --git a/op.c b/op.c
index 6cfff4f..3aacc83 100644
--- a/op.c
+++ b/op.c
@@ -2843,6 +2843,18 @@ Perl_op_scope(pTHX_ OP *o)
     return o;
 }
 
+OP *
+Perl_op_unscope(pTHX_ OP *o)
+{
+    if (o && o->op_type == OP_LINESEQ) {
+	OP *kid = cLISTOPo->op_first;
+	for(; kid; kid = kid->op_sibling)
+	    if (kid->op_type == OP_NEXTSTATE || kid->op_type == OP_DBSTATE)
+		op_null(kid);
+    }
+    return o;
+}
+
 int
 Perl_block_start(pTHX_ int full)
 {
@@ -7504,7 +7516,14 @@ Perl_newFORM(pTHX_ I32 floor, OP *o, OP *block)
     OP* pegop = newOP(OP_NULL, 0);
 #endif
 
-    GV * const gv = o
+    GV *gv;
+
+    if (PL_parser && PL_parser->error_count) {
+	op_free(block);
+	goto finish;
+    }
+
+    gv = o
 	? gv_fetchsv(cSVOPo->op_sv, GV_ADD, SVt_PVFM)
 	: gv_fetchpvs("STDOUT", GV_ADD|GV_NOTQUAL, SVt_PVFM);
 
@@ -7527,7 +7546,7 @@ Perl_newFORM(pTHX_ I32 floor, OP *o, OP *block)
 	SvREFCNT_dec(cv);
     }
     cv = PL_compcv;
-    GvFORM(gv) = cv;
+    GvFORM(gv) = (CV *)SvREFCNT_inc_simple_NN(cv);
     CvGV_set(cv, gv);
     CvFILE_set_from_cop(cv, PL_curcop);
 
@@ -7540,13 +7559,15 @@ Perl_newFORM(pTHX_ I32 floor, OP *o, OP *block)
     CvROOT(cv)->op_next = 0;
     CALL_PEEP(CvSTART(cv));
     finalize_optree(CvROOT(cv));
+    cv_forget_slab(cv);
+
+  finish:
 #ifdef PERL_MAD
     op_getmad(o,pegop,'n');
     op_getmad_weak(block, pegop, 'b');
 #else
     op_free(o);
 #endif
-    cv_forget_slab(cv);
     if (PL_parser)
 	PL_parser->copline = NOLINE;
     LEAVE_SCOPE(floor);
diff --git a/opcode.h b/opcode.h
index 10dc22a..ec82a29 100644
--- a/opcode.h
+++ b/opcode.h
@@ -522,6 +522,7 @@ EXTCONST char* const PL_op_name[] = {
 	"coreargs",
 	"runcv",
 	"fc",
+	"freed",
 };
 #endif
 
@@ -903,6 +904,7 @@ EXTCONST char* const PL_op_desc[] = {
 	"CORE:: subroutine",
 	"__SUB__",
 	"fc",
+	"freed op",
 };
 #endif
 
diff --git a/pad.c b/pad.c
index 01813f8..e8f8a43 100644
--- a/pad.c
+++ b/pad.c
@@ -1123,12 +1123,14 @@ S_pad_findlex(pTHX_ const char *namepv, STRLEN namelen, U32 flags, const CV* cv,
     SV *new_capture;
     SV **new_capturep;
     const AV * const padlist = CvPADLIST(cv);
+    const bool staleok = !!(flags & padadd_STALEOK);
 
     PERL_ARGS_ASSERT_PAD_FINDLEX;
 
-    if (flags & ~padadd_UTF8_NAME)
+    if (flags & ~(padadd_UTF8_NAME|padadd_STALEOK))
 	Perl_croak(aTHX_ "panic: pad_findlex illegal flag bits 0x%" UVxf,
 		   (UV)flags);
+    flags &= ~ padadd_STALEOK; /* one-shot flag */
 
     *out_flags = 0;
 
@@ -1279,6 +1281,7 @@ S_pad_findlex(pTHX_ const char *namepv, STRLEN namelen, U32 flags, const CV* cv,
 			PTR2UV(cv), PTR2UV(*out_capture)));
 
 		    if (SvPADSTALE(*out_capture)
+			&& (!CvDEPTH(cv) || !staleok)
 			&& !SvPAD_STATE(name_svp[offset]))
 		    {
 			Perl_ck_warner(aTHX_ packWARN(WARN_CLOSURE),
@@ -1313,7 +1316,9 @@ S_pad_findlex(pTHX_ const char *namepv, STRLEN namelen, U32 flags, const CV* cv,
     new_capturep = out_capture ? out_capture :
 		CvLATE(cv) ? NULL : &new_capture;
 
-    offset = pad_findlex(namepv, namelen, flags, CvOUTSIDE(cv), CvOUTSIDE_SEQ(cv), 1,
+    offset = pad_findlex(namepv, namelen,
+		flags | padadd_STALEOK*(new_capturep == &new_capture),
+		CvOUTSIDE(cv), CvOUTSIDE_SEQ(cv), 1,
 		new_capturep, out_name_sv, out_flags);
     if ((PADOFFSET)offset == NOT_IN_PAD)
 	return NOT_IN_PAD;
diff --git a/pad.h b/pad.h
index 139cb06..712bdab 100644
--- a/pad.h
+++ b/pad.h
@@ -126,6 +126,8 @@ typedef enum {
 #define padadd_OUR		0x01	   /* our declaration. */
 #define padadd_STATE		0x02	   /* state declaration. */
 #define padadd_NO_DUP_CHECK	0x04	   /* skip warning on dups. */
+#define padadd_STALEOK		0x08	   /* allow stale lexical in active
+					    * sub, but only one level up */
 #define padadd_UTF8_NAME	SVf_UTF8   /* name is UTF-8 encoded. */
 
 /* ASSERT_CURPAD_LEGAL and ASSERT_CURPAD_ACTIVE respectively determine
diff --git a/perly.act b/perly.act
index 9b39e92..270d617 100644
--- a/perly.act
+++ b/perly.act
@@ -5,14 +5,14 @@
  */
 
 case 2:
-#line 140 "perly.y"
+#line 141 "perly.y"
     {
 			  PL_parser->expect = XSTATE;
 			;}
     break;
 
   case 3:
-#line 144 "perly.y"
+#line 145 "perly.y"
     {
 			  newPROG(block_end((ps[(3) - (4)].val.ival),(ps[(4) - (4)].val.opval)));
 			  (yyval.ival) = 0;
@@ -20,14 +20,14 @@ case 2:
     break;
 
   case 4:
-#line 149 "perly.y"
+#line 150 "perly.y"
     {
 			  parser->expect = XTERM;
 			;}
     break;
 
   case 5:
-#line 153 "perly.y"
+#line 154 "perly.y"
     {
 			  PL_eval_root = (ps[(3) - (3)].val.opval);
 			  (yyval.ival) = 0;
@@ -35,14 +35,14 @@ case 2:
     break;
 
   case 6:
-#line 158 "perly.y"
+#line 159 "perly.y"
     {
 			  parser->expect = XBLOCK;
 			;}
     break;
 
   case 7:
-#line 162 "perly.y"
+#line 163 "perly.y"
     {
 			  PL_pad_reset_pending = TRUE;
 			  PL_eval_root = (ps[(3) - (3)].val.opval);
@@ -53,14 +53,14 @@ case 2:
     break;
 
   case 8:
-#line 170 "perly.y"
+#line 171 "perly.y"
     {
 			  parser->expect = XSTATE;
 			;}
     break;
 
   case 9:
-#line 174 "perly.y"
+#line 175 "perly.y"
     {
 			  PL_pad_reset_pending = TRUE;
 			  PL_eval_root = (ps[(3) - (3)].val.opval);
@@ -71,14 +71,14 @@ case 2:
     break;
 
   case 10:
-#line 182 "perly.y"
+#line 183 "perly.y"
     {
 			  parser->expect = XSTATE;
 			;}
     break;
 
   case 11:
-#line 186 "perly.y"
+#line 187 "perly.y"
     {
 			  PL_pad_reset_pending = TRUE;
 			  PL_eval_root = (ps[(3) - (3)].val.opval);
@@ -89,14 +89,14 @@ case 2:
     break;
 
   case 12:
-#line 194 "perly.y"
+#line 195 "perly.y"
     {
 			  parser->expect = XSTATE;
 			;}
     break;
 
   case 13:
-#line 198 "perly.y"
+#line 199 "perly.y"
     {
 			  PL_eval_root = (ps[(3) - (3)].val.opval);
 			  (yyval.ival) = 0;
@@ -104,7 +104,7 @@ case 2:
     break;
 
   case 14:
-#line 206 "perly.y"
+#line 207 "perly.y"
     { if (PL_parser->copline > (line_t)IVAL((ps[(1) - (4)].val.i_tkval)))
 			      PL_parser->copline = (line_t)IVAL((ps[(1) - (4)].val.i_tkval));
 			  (yyval.opval) = block_end((ps[(2) - (4)].val.ival), (ps[(3) - (4)].val.opval));
@@ -114,22 +114,22 @@ case 2:
     break;
 
   case 15:
-#line 216 "perly.y"
-    { if (PL_parser->copline > (line_t)IVAL((ps[(1) - (4)].val.i_tkval)))
-			      PL_parser->copline = (line_t)IVAL((ps[(1) - (4)].val.i_tkval));
-			  (yyval.opval) = block_end((ps[(2) - (4)].val.ival), (ps[(3) - (4)].val.opval));
-			  TOKEN_GETMAD((ps[(1) - (4)].val.i_tkval),(yyval.opval),'{');
-			  TOKEN_GETMAD((ps[(4) - (4)].val.i_tkval),(yyval.opval),'}');
+#line 217 "perly.y"
+    { if (PL_parser->copline > (line_t)IVAL((ps[(1) - (7)].val.i_tkval)))
+			      PL_parser->copline = (line_t)IVAL((ps[(1) - (7)].val.i_tkval));
+			  (yyval.opval) = block_end((ps[(2) - (7)].val.ival), (ps[(5) - (7)].val.opval));
+			  TOKEN_GETMAD((ps[(1) - (7)].val.i_tkval),(yyval.opval),'{');
+			  TOKEN_GETMAD((ps[(7) - (7)].val.i_tkval),(yyval.opval),'}');
 			;}
     break;
 
   case 16:
-#line 225 "perly.y"
+#line 226 "perly.y"
     { (yyval.ival) = block_start(TRUE); ;}
     break;
 
   case 17:
-#line 229 "perly.y"
+#line 230 "perly.y"
     { if (PL_parser->copline > (line_t)IVAL((ps[(1) - (4)].val.i_tkval)))
 			      PL_parser->copline = (line_t)IVAL((ps[(1) - (4)].val.i_tkval));
 			  (yyval.opval) = block_end((ps[(2) - (4)].val.ival), (ps[(3) - (4)].val.opval));
@@ -139,17 +139,17 @@ case 2:
     break;
 
   case 18:
-#line 238 "perly.y"
+#line 239 "perly.y"
     { (yyval.ival) = block_start(FALSE); ;}
     break;
 
   case 19:
-#line 243 "perly.y"
+#line 244 "perly.y"
     { (yyval.opval) = (OP*)NULL; ;}
     break;
 
   case 20:
-#line 245 "perly.y"
+#line 246 "perly.y"
     {   (yyval.opval) = op_append_list(OP_LINESEQ, (ps[(1) - (2)].val.opval), (ps[(2) - (2)].val.opval));
 			    PL_pad_reset_pending = TRUE;
 			    if ((ps[(1) - (2)].val.opval) && (ps[(2) - (2)].val.opval))
@@ -158,7 +158,21 @@ case 2:
     break;
 
   case 21:
-#line 254 "perly.y"
+#line 255 "perly.y"
+    { (yyval.opval) = (OP*)NULL; ;}
+    break;
+
+  case 22:
+#line 257 "perly.y"
+    {   (yyval.opval) = op_append_list(OP_LINESEQ, (ps[(1) - (2)].val.opval), (ps[(2) - (2)].val.opval));
+			    PL_pad_reset_pending = TRUE;
+			    if ((ps[(1) - (2)].val.opval) && (ps[(2) - (2)].val.opval))
+				PL_hints |= HINT_BLOCK_SCOPE;
+			;}
+    break;
+
+  case 23:
+#line 266 "perly.y"
     {
 			  if((ps[(1) - (1)].val.opval)) {
 			      (yyval.opval) = newSTATEOP(0, NULL, (ps[(1) - (1)].val.opval));
@@ -168,13 +182,13 @@ case 2:
 			;}
     break;
 
-  case 22:
-#line 262 "perly.y"
+  case 24:
+#line 274 "perly.y"
     { (yyval.opval) = (ps[(1) - (1)].val.opval); ;}
     break;
 
-  case 23:
-#line 266 "perly.y"
+  case 25:
+#line 278 "perly.y"
     {
 			  (yyval.opval) = newSTATEOP(SvUTF8(((SVOP*)(ps[(1) - (2)].val.p_tkval))->op_sv),
                                         savepv(SvPVX(((SVOP*)(ps[(1) - (2)].val.p_tkval))->op_sv)), (ps[(2) - (2)].val.opval));
@@ -183,8 +197,8 @@ case 2:
 			;}
     break;
 
-  case 24:
-#line 273 "perly.y"
+  case 26:
+#line 285 "perly.y"
     {
 			  (yyval.opval) = newSTATEOP(SvUTF8(((SVOP*)(ps[(1) - (2)].val.p_tkval))->op_sv),
                                         savepv(SvPVX(((SVOP*)(ps[(1) - (2)].val.p_tkval))->op_sv)), (ps[(2) - (2)].val.opval));
@@ -192,24 +206,23 @@ case 2:
 			;}
     break;
 
-  case 25:
-#line 282 "perly.y"
+  case 27:
+#line 294 "perly.y"
     { (yyval.opval) = (ps[(1) - (1)].val.opval); ;}
     break;
 
-  case 26:
-#line 284 "perly.y"
+  case 28:
+#line 296 "perly.y"
     {
 			  (yyval.opval) = newOP(OP_NULL,0);
 			  TOKEN_GETMAD((ps[(1) - (1)].val.i_tkval),(yyval.opval),'p');
 			;}
     break;
 
-  case 27:
-#line 289 "perly.y"
+  case 29:
+#line 301 "perly.y"
     {
 			  CV *fmtcv = PL_compcv;
-			  SvREFCNT_inc_simple_void(PL_compcv);
 #ifdef MAD
 			  (yyval.opval) = newFORM((ps[(2) - (4)].val.ival), (ps[(3) - (4)].val.opval), (ps[(4) - (4)].val.opval));
 			  prepend_madprops((ps[(1) - (4)].val.i_tkval)->tk_mad, (yyval.opval), 'F');
@@ -226,8 +239,8 @@ case 2:
 			;}
     break;
 
-  case 28:
-#line 307 "perly.y"
+  case 30:
+#line 318 "perly.y"
     {
 			  SvREFCNT_inc_simple_void(PL_compcv);
 #ifdef MAD
@@ -250,8 +263,8 @@ case 2:
 			;}
     break;
 
-  case 29:
-#line 328 "perly.y"
+  case 31:
+#line 339 "perly.y"
     {
 			  /* Unimplemented "my sub foo { }" */
 			  SvREFCNT_inc_simple_void(PL_compcv);
@@ -265,8 +278,8 @@ case 2:
 			;}
     break;
 
-  case 30:
-#line 340 "perly.y"
+  case 32:
+#line 351 "perly.y"
     {
 #ifdef MAD
 			  (yyval.opval) = package((ps[(3) - (4)].val.opval));
@@ -283,13 +296,13 @@ case 2:
 			;}
     break;
 
-  case 31:
-#line 355 "perly.y"
+  case 33:
+#line 366 "perly.y"
     { CvSPECIAL_on(PL_compcv); /* It's a BEGIN {} */ ;}
     break;
 
-  case 32:
-#line 357 "perly.y"
+  case 34:
+#line 368 "perly.y"
     {
 			  SvREFCNT_inc_simple_void(PL_compcv);
 #ifdef MAD
@@ -306,8 +319,8 @@ case 2:
 			;}
     break;
 
-  case 33:
-#line 372 "perly.y"
+  case 35:
+#line 383 "perly.y"
     {
 			  (yyval.opval) = block_end((ps[(3) - (7)].val.ival),
 			      newCONDOP(0, (ps[(4) - (7)].val.opval), op_scope((ps[(6) - (7)].val.opval)), (ps[(7) - (7)].val.opval)));
@@ -318,8 +331,8 @@ case 2:
 			;}
     break;
 
-  case 34:
-#line 381 "perly.y"
+  case 36:
+#line 392 "perly.y"
     {
 			  (yyval.opval) = block_end((ps[(3) - (7)].val.ival),
 			      newCONDOP(0, (ps[(4) - (7)].val.opval), op_scope((ps[(6) - (7)].val.opval)), (ps[(7) - (7)].val.opval)));
@@ -330,8 +343,8 @@ case 2:
 			;}
     break;
 
-  case 35:
-#line 390 "perly.y"
+  case 37:
+#line 401 "perly.y"
     {
 			  const PADOFFSET offset = pad_findmy_pvs("$_", 0);
 			  (yyval.opval) = block_end((ps[(3) - (6)].val.ival),
@@ -344,18 +357,18 @@ case 2:
 			;}
     break;
 
-  case 36:
-#line 401 "perly.y"
+  case 38:
+#line 412 "perly.y"
     { (yyval.opval) = block_end((ps[(3) - (6)].val.ival), newWHENOP((ps[(4) - (6)].val.opval), op_scope((ps[(6) - (6)].val.opval)))); ;}
     break;
 
-  case 37:
-#line 403 "perly.y"
+  case 39:
+#line 414 "perly.y"
     { (yyval.opval) = newWHENOP(0, op_scope((ps[(2) - (2)].val.opval))); ;}
     break;
 
-  case 38:
-#line 405 "perly.y"
+  case 40:
+#line 416 "perly.y"
     {
 			  (yyval.opval) = block_end((ps[(3) - (8)].val.ival),
 				  newWHILEOP(0, 1, (LOOP*)(OP*)NULL,
@@ -367,8 +380,8 @@ case 2:
 			;}
     break;
 
-  case 39:
-#line 415 "perly.y"
+  case 41:
+#line 426 "perly.y"
     {
 			  (yyval.opval) = block_end((ps[(3) - (8)].val.ival),
 				  newWHILEOP(0, 1, (LOOP*)(OP*)NULL,
@@ -380,8 +393,8 @@ case 2:
 			;}
     break;
 
-  case 40:
-#line 426 "perly.y"
+  case 42:
+#line 437 "perly.y"
     {
 			  OP *initop = IF_MAD((ps[(4) - (11)].val.opval) ? (ps[(4) - (11)].val.opval) : newOP(OP_NULL, 0), (ps[(4) - (11)].val.opval));
 			  OP *forop = newWHILEOP(0, 1, (LOOP*)(OP*)NULL,
@@ -403,8 +416,8 @@ case 2:
 			;}
     break;
 
-  case 41:
-#line 446 "perly.y"
+  case 43:
+#line 457 "perly.y"
     {
 			  (yyval.opval) = block_end((ps[(3) - (9)].val.ival), newFOROP(0, (ps[(4) - (9)].val.opval), (ps[(6) - (9)].val.opval), (ps[(8) - (9)].val.opval), (ps[(9) - (9)].val.opval)));
 			  TOKEN_GETMAD((ps[(1) - (9)].val.i_tkval),(yyval.opval),'W');
@@ -415,8 +428,8 @@ case 2:
 			;}
     break;
 
-  case 42:
-#line 455 "perly.y"
+  case 44:
+#line 466 "perly.y"
     {
 			  (yyval.opval) = block_end((ps[(4) - (8)].val.ival), newFOROP(0,
 				      op_lvalue((ps[(2) - (8)].val.opval), OP_ENTERLOOP), (ps[(5) - (8)].val.opval), (ps[(7) - (8)].val.opval), (ps[(8) - (8)].val.opval)));
@@ -427,8 +440,8 @@ case 2:
 			;}
     break;
 
-  case 43:
-#line 464 "perly.y"
+  case 45:
+#line 475 "perly.y"
     {
 			  (yyval.opval) = block_end((ps[(3) - (7)].val.ival),
 				  newFOROP(0, (OP*)NULL, (ps[(4) - (7)].val.opval), (ps[(6) - (7)].val.opval), (ps[(7) - (7)].val.opval)));
@@ -439,8 +452,8 @@ case 2:
 			;}
     break;
 
-  case 44:
-#line 473 "perly.y"
+  case 46:
+#line 484 "perly.y"
     {
 			  /* a block is a loop that happens once */
 			  (yyval.opval) = newWHILEOP(0, 1, (LOOP*)(OP*)NULL,
@@ -448,8 +461,8 @@ case 2:
 			;}
     break;
 
-  case 45:
-#line 479 "perly.y"
+  case 47:
+#line 490 "perly.y"
     {
 			  package((ps[(3) - (5)].val.opval));
 			  if ((ps[(2) - (5)].val.opval)) {
@@ -458,8 +471,8 @@ case 2:
 			;}
     break;
 
-  case 46:
-#line 486 "perly.y"
+  case 48:
+#line 497 "perly.y"
     {
 			  /* a block is a loop that happens once */
 			  (yyval.opval) = newWHILEOP(0, 1, (LOOP*)(OP*)NULL,
@@ -471,8 +484,8 @@ case 2:
 			;}
     break;
 
-  case 47:
-#line 496 "perly.y"
+  case 49:
+#line 507 "perly.y"
     {
 			  PL_parser->expect = XSTATE;
 			  (yyval.opval) = (ps[(1) - (2)].val.opval);
@@ -480,8 +493,8 @@ case 2:
 			;}
     break;
 
-  case 48:
-#line 502 "perly.y"
+  case 50:
+#line 513 "perly.y"
     {
 			  PL_parser->expect = XSTATE;
 			  (yyval.opval) = IF_MAD(newOP(OP_NULL, 0), (OP*)NULL);
@@ -490,64 +503,98 @@ case 2:
 			;}
     break;
 
-  case 49:
-#line 512 "perly.y"
+  case 51:
+#line 523 "perly.y"
+    { OP *list;
+			  if ((ps[(2) - (2)].val.opval)) {
+			      OP *term = (ps[(2) - (2)].val.opval);
+			      DO_MAD(term = newUNOP(OP_NULL, 0, term));
+			      list = op_append_elem(OP_LIST, (ps[(1) - (2)].val.opval), term);
+			  }
+			  else {
+#ifdef MAD
+			      OP *op = newNULLLIST();
+			      list = op_append_elem(OP_LIST, (ps[(1) - (2)].val.opval), op);
+#else
+			      list = (ps[(1) - (2)].val.opval);
+#endif
+			  }
+			  if (PL_parser->copline == NOLINE)
+			       PL_parser->copline = CopLINE(PL_curcop)-1;
+			  else PL_parser->copline--;
+			  (yyval.opval) = newSTATEOP(0, NULL,
+					  convert(OP_FORMLINE, 0, list));
+			;}
+    break;
+
+  case 52:
+#line 546 "perly.y"
+    { (yyval.opval) = NULL; ;}
+    break;
+
+  case 53:
+#line 548 "perly.y"
+    { (yyval.opval) = op_unscope((ps[(2) - (3)].val.opval)); ;}
+    break;
+
+  case 54:
+#line 553 "perly.y"
     { (yyval.opval) = (OP*)NULL; ;}
     break;
 
-  case 50:
-#line 514 "perly.y"
+  case 55:
+#line 555 "perly.y"
     { (yyval.opval) = (ps[(1) - (1)].val.opval); ;}
     break;
 
-  case 51:
-#line 516 "perly.y"
+  case 56:
+#line 557 "perly.y"
     { (yyval.opval) = newLOGOP(OP_AND, 0, (ps[(3) - (3)].val.opval), (ps[(1) - (3)].val.opval));
 			  TOKEN_GETMAD((ps[(2) - (3)].val.i_tkval),(yyval.opval),'i');
 			;}
     break;
 
-  case 52:
-#line 520 "perly.y"
+  case 57:
+#line 561 "perly.y"
     { (yyval.opval) = newLOGOP(OP_OR, 0, (ps[(3) - (3)].val.opval), (ps[(1) - (3)].val.opval));
 			  TOKEN_GETMAD((ps[(2) - (3)].val.i_tkval),(yyval.opval),'i');
 			;}
     break;
 
-  case 53:
-#line 524 "perly.y"
+  case 58:
+#line 565 "perly.y"
     { (yyval.opval) = newLOOPOP(OPf_PARENS, 1, scalar((ps[(3) - (3)].val.opval)), (ps[(1) - (3)].val.opval));
 			  TOKEN_GETMAD((ps[(2) - (3)].val.i_tkval),(yyval.opval),'w');
 			;}
     break;
 
-  case 54:
-#line 528 "perly.y"
+  case 59:
+#line 569 "perly.y"
     { (yyval.opval) = newLOOPOP(OPf_PARENS, 1, (ps[(3) - (3)].val.opval), (ps[(1) - (3)].val.opval));
 			  TOKEN_GETMAD((ps[(2) - (3)].val.i_tkval),(yyval.opval),'w');
 			;}
     break;
 
-  case 55:
-#line 532 "perly.y"
+  case 60:
+#line 573 "perly.y"
     { (yyval.opval) = newFOROP(0, (OP*)NULL, (ps[(3) - (3)].val.opval), (ps[(1) - (3)].val.opval), (OP*)NULL);
 			  TOKEN_GETMAD((ps[(2) - (3)].val.i_tkval),(yyval.opval),'w');
 			  PL_parser->copline = (line_t)IVAL((ps[(2) - (3)].val.i_tkval));
 			;}
     break;
 
-  case 56:
-#line 537 "perly.y"
+  case 61:
+#line 578 "perly.y"
     { (yyval.opval) = newWHENOP((ps[(3) - (3)].val.opval), op_scope((ps[(1) - (3)].val.opval))); ;}
     break;
 
-  case 57:
-#line 542 "perly.y"
+  case 62:
+#line 583 "perly.y"
     { (yyval.opval) = (OP*)NULL; ;}
     break;
 
-  case 58:
-#line 544 "perly.y"
+  case 63:
+#line 585 "perly.y"
     {
 			  ((ps[(2) - (2)].val.opval))->op_flags |= OPf_PARENS;
 			  (yyval.opval) = op_scope((ps[(2) - (2)].val.opval));
@@ -555,8 +602,8 @@ case 2:
 			;}
     break;
 
-  case 59:
-#line 550 "perly.y"
+  case 64:
+#line 591 "perly.y"
     { PL_parser->copline = (line_t)IVAL((ps[(1) - (6)].val.i_tkval));
 			    (yyval.opval) = newCONDOP(0,
 				newSTATEOP(OPf_SPECIAL,NULL,(ps[(3) - (6)].val.opval)),
@@ -568,88 +615,88 @@ case 2:
 			;}
     break;
 
-  case 60:
-#line 563 "perly.y"
+  case 65:
+#line 604 "perly.y"
     { (yyval.opval) = (OP*)NULL; ;}
     break;
 
-  case 61:
-#line 565 "perly.y"
+  case 66:
+#line 606 "perly.y"
     {
 			  (yyval.opval) = op_scope((ps[(2) - (2)].val.opval));
 			  TOKEN_GETMAD((ps[(1) - (2)].val.i_tkval),(yyval.opval),'o');
 			;}
     break;
 
-  case 62:
-#line 573 "perly.y"
+  case 67:
+#line 614 "perly.y"
     { (yyval.ival) = (PL_min_intro_pending &&
 			    PL_max_intro_pending >=  PL_min_intro_pending);
 			  intro_my(); ;}
     break;
 
-  case 63:
-#line 579 "perly.y"
+  case 68:
+#line 620 "perly.y"
     { (yyval.opval) = (OP*)NULL; ;}
     break;
 
-  case 65:
-#line 585 "perly.y"
+  case 70:
+#line 626 "perly.y"
     { YYSTYPE tmplval;
 			  (void)scan_num("1", &tmplval);
 			  (yyval.opval) = tmplval.opval; ;}
     break;
 
-  case 67:
-#line 593 "perly.y"
+  case 72:
+#line 634 "perly.y"
     { (yyval.opval) = invert(scalar((ps[(1) - (1)].val.opval))); ;}
     break;
 
-  case 68:
-#line 598 "perly.y"
+  case 73:
+#line 639 "perly.y"
     { (yyval.opval) = (ps[(1) - (1)].val.opval); intro_my(); ;}
     break;
 
-  case 69:
-#line 602 "perly.y"
+  case 74:
+#line 643 "perly.y"
     { (yyval.opval) = (ps[(1) - (1)].val.opval); intro_my(); ;}
     break;
 
-  case 70:
-#line 606 "perly.y"
+  case 75:
+#line 647 "perly.y"
     { (yyval.opval) = (ps[(1) - (1)].val.opval); intro_my(); ;}
     break;
 
-  case 71:
-#line 609 "perly.y"
+  case 76:
+#line 650 "perly.y"
     { (yyval.opval) = (ps[(1) - (1)].val.opval); ;}
     break;
 
-  case 72:
-#line 610 "perly.y"
+  case 77:
+#line 651 "perly.y"
     { (yyval.opval) = (OP*)NULL; ;}
     break;
 
-  case 73:
-#line 614 "perly.y"
+  case 78:
+#line 655 "perly.y"
     { (yyval.ival) = start_subparse(FALSE, 0);
 			    SAVEFREESV(PL_compcv); ;}
     break;
 
-  case 74:
-#line 620 "perly.y"
+  case 79:
+#line 661 "perly.y"
     { (yyval.ival) = start_subparse(FALSE, CVf_ANON);
 			    SAVEFREESV(PL_compcv); ;}
     break;
 
-  case 75:
-#line 625 "perly.y"
+  case 80:
+#line 666 "perly.y"
     { (yyval.ival) = start_subparse(TRUE, 0);
 			    SAVEFREESV(PL_compcv); ;}
     break;
 
-  case 76:
-#line 630 "perly.y"
+  case 81:
+#line 671 "perly.y"
     { const char *const name = SvPV_nolen_const(((SVOP*)(ps[(1) - (1)].val.opval))->op_sv);
 			  if (strEQ(name, "BEGIN") || strEQ(name, "END")
 			      || strEQ(name, "INIT") || strEQ(name, "CHECK")
@@ -658,25 +705,25 @@ case 2:
 			  (yyval.opval) = (ps[(1) - (1)].val.opval); ;}
     break;
 
-  case 77:
-#line 640 "perly.y"
+  case 82:
+#line 681 "perly.y"
     { (yyval.opval) = (OP*)NULL; ;}
     break;
 
-  case 79:
-#line 646 "perly.y"
+  case 84:
+#line 687 "perly.y"
     { (yyval.opval) = (OP*)NULL; ;}
     break;
 
-  case 80:
-#line 648 "perly.y"
+  case 85:
+#line 689 "perly.y"
     { (yyval.opval) = (ps[(2) - (2)].val.opval);
 			  TOKEN_GETMAD((ps[(1) - (2)].val.i_tkval),(yyval.opval),':');
 			;}
     break;
 
-  case 81:
-#line 652 "perly.y"
+  case 86:
+#line 693 "perly.y"
     { (yyval.opval) = IF_MAD(
 				    newOP(OP_NULL, 0),
 				    (OP*)NULL
@@ -685,15 +732,15 @@ case 2:
 			;}
     break;
 
-  case 82:
-#line 662 "perly.y"
+  case 87:
+#line 703 "perly.y"
     { (yyval.opval) = (ps[(2) - (2)].val.opval);
 			  TOKEN_GETMAD((ps[(1) - (2)].val.i_tkval),(yyval.opval),':');
 			;}
     break;
 
-  case 83:
-#line 666 "perly.y"
+  case 88:
+#line 707 "perly.y"
     { (yyval.opval) = IF_MAD(
 				    newOP(OP_NULL, 0),
 				    (OP*)NULL
@@ -702,13 +749,13 @@ case 2:
 			;}
     break;
 
-  case 84:
-#line 675 "perly.y"
+  case 89:
+#line 716 "perly.y"
     { (yyval.opval) = (ps[(1) - (1)].val.opval); ;}
     break;
 
-  case 85:
-#line 676 "perly.y"
+  case 90:
+#line 717 "perly.y"
     { (yyval.opval) = IF_MAD(
 				    newOP(OP_NULL,0),
 				    (OP*)NULL
@@ -718,29 +765,29 @@ case 2:
 			;}
     break;
 
-  case 86:
-#line 687 "perly.y"
+  case 91:
+#line 728 "perly.y"
     { (yyval.opval) = newLOGOP(OP_AND, 0, (ps[(1) - (3)].val.opval), (ps[(3) - (3)].val.opval));
 			  TOKEN_GETMAD((ps[(2) - (3)].val.i_tkval),(yyval.opval),'o');
 			;}
     break;
 
-  case 87:
-#line 691 "perly.y"
+  case 92:
+#line 732 "perly.y"
     { (yyval.opval) = newLOGOP(IVAL((ps[(2) - (3)].val.i_tkval)), 0, (ps[(1) - (3)].val.opval), (ps[(3) - (3)].val.opval));
 			  TOKEN_GETMAD((ps[(2) - (3)].val.i_tkval),(yyval.opval),'o');
 			;}
     break;
 
-  case 88:
-#line 695 "perly.y"
+  case 93:
+#line 736 "perly.y"
     { (yyval.opval) = newLOGOP(OP_DOR, 0, (ps[(1) - (3)].val.opval), (ps[(3) - (3)].val.opval));
 			  TOKEN_GETMAD((ps[(2) - (3)].val.i_tkval),(yyval.opval),'o');
 			;}
     break;
 
-  case 90:
-#line 703 "perly.y"
+  case 95:
+#line 744 "perly.y"
     {
 #ifdef MAD
 			  OP* op = newNULLLIST();
@@ -752,8 +799,8 @@ case 2:
 			;}
     break;
 
-  case 91:
-#line 713 "perly.y"
+  case 96:
+#line 754 "perly.y"
     { 
 			  OP* term = (ps[(3) - (3)].val.opval);
 			  DO_MAD(
@@ -764,16 +811,16 @@ case 2:
 			;}
     break;
 
-  case 93:
-#line 726 "perly.y"
+  case 98:
+#line 767 "perly.y"
     { (yyval.opval) = convert(IVAL((ps[(1) - (3)].val.i_tkval)), OPf_STACKED,
 				op_prepend_elem(OP_LIST, newGVREF(IVAL((ps[(1) - (3)].val.i_tkval)),(ps[(2) - (3)].val.opval)), (ps[(3) - (3)].val.opval)) );
 			  TOKEN_GETMAD((ps[(1) - (3)].val.i_tkval),(yyval.opval),'o');
 			;}
     break;
 
-  case 94:
-#line 731 "perly.y"
+  case 99:
+#line 772 "perly.y"
     { (yyval.opval) = convert(IVAL((ps[(1) - (5)].val.i_tkval)), OPf_STACKED,
 				op_prepend_elem(OP_LIST, newGVREF(IVAL((ps[(1) - (5)].val.i_tkval)),(ps[(3) - (5)].val.opval)), (ps[(4) - (5)].val.opval)) );
 			  TOKEN_GETMAD((ps[(1) - (5)].val.i_tkval),(yyval.opval),'o');
@@ -782,8 +829,8 @@ case 2:
 			;}
     break;
 
-  case 95:
-#line 738 "perly.y"
+  case 100:
+#line 779 "perly.y"
     { (yyval.opval) = convert(OP_ENTERSUB, OPf_STACKED,
 				op_append_elem(OP_LIST,
 				    op_prepend_elem(OP_LIST, scalar((ps[(1) - (6)].val.opval)), (ps[(5) - (6)].val.opval)),
@@ -794,8 +841,8 @@ case 2:
 			;}
     break;
 
-  case 96:
-#line 747 "perly.y"
+  case 101:
+#line 788 "perly.y"
     { (yyval.opval) = convert(OP_ENTERSUB, OPf_STACKED,
 				op_append_elem(OP_LIST, scalar((ps[(1) - (3)].val.opval)),
 				    newUNOP(OP_METHOD, 0, (ps[(3) - (3)].val.opval))));
@@ -803,8 +850,8 @@ case 2:
 			;}
     break;
 
-  case 97:
-#line 753 "perly.y"
+  case 102:
+#line 794 "perly.y"
     { (yyval.opval) = convert(OP_ENTERSUB, OPf_STACKED,
 				op_append_elem(OP_LIST,
 				    op_prepend_elem(OP_LIST, (ps[(2) - (3)].val.opval), (ps[(3) - (3)].val.opval)),
@@ -812,8 +859,8 @@ case 2:
 			;}
     break;
 
-  case 98:
-#line 759 "perly.y"
+  case 103:
+#line 800 "perly.y"
     { (yyval.opval) = convert(OP_ENTERSUB, OPf_STACKED,
 				op_append_elem(OP_LIST,
 				    op_prepend_elem(OP_LIST, (ps[(2) - (5)].val.opval), (ps[(4) - (5)].val.opval)),
@@ -823,15 +870,15 @@ case 2:
 			;}
     break;
 
-  case 99:
-#line 767 "perly.y"
+  case 104:
+#line 808 "perly.y"
     { (yyval.opval) = convert(IVAL((ps[(1) - (2)].val.i_tkval)), 0, (ps[(2) - (2)].val.opval));
 			  TOKEN_GETMAD((ps[(1) - (2)].val.i_tkval),(yyval.opval),'o');
 			;}
     break;
 
-  case 100:
-#line 771 "perly.y"
+  case 105:
+#line 812 "perly.y"
     { (yyval.opval) = convert(IVAL((ps[(1) - (4)].val.i_tkval)), 0, (ps[(3) - (4)].val.opval));
 			  TOKEN_GETMAD((ps[(1) - (4)].val.i_tkval),(yyval.opval),'o');
 			  TOKEN_GETMAD((ps[(2) - (4)].val.i_tkval),(yyval.opval),'(');
@@ -839,22 +886,22 @@ case 2:
 			;}
     break;
 
-  case 101:
-#line 777 "perly.y"
+  case 106:
+#line 818 "perly.y"
     { SvREFCNT_inc_simple_void(PL_compcv);
 			  (yyval.opval) = newANONATTRSUB((ps[(2) - (3)].val.ival), 0, (OP*)NULL, (ps[(3) - (3)].val.opval)); ;}
     break;
 
-  case 102:
-#line 780 "perly.y"
+  case 107:
+#line 821 "perly.y"
     { (yyval.opval) = newUNOP(OP_ENTERSUB, OPf_STACKED,
 				 op_append_elem(OP_LIST,
 				   op_prepend_elem(OP_LIST, (ps[(4) - (5)].val.opval), (ps[(5) - (5)].val.opval)), (ps[(1) - (5)].val.opval)));
 			;}
     break;
 
-  case 105:
-#line 795 "perly.y"
+  case 110:
+#line 836 "perly.y"
     { (yyval.opval) = newBINOP(OP_GELEM, 0, (ps[(1) - (5)].val.opval), scalar((ps[(3) - (5)].val.opval)));
 			    PL_parser->expect = XOPERATOR;
 			  TOKEN_GETMAD((ps[(2) - (5)].val.i_tkval),(yyval.opval),'{');
@@ -863,16 +910,16 @@ case 2:
 			;}
     break;
 
-  case 106:
-#line 802 "perly.y"
+  case 111:
+#line 843 "perly.y"
     { (yyval.opval) = newBINOP(OP_AELEM, 0, oopsAV((ps[(1) - (4)].val.opval)), scalar((ps[(3) - (4)].val.opval)));
 			  TOKEN_GETMAD((ps[(2) - (4)].val.i_tkval),(yyval.opval),'[');
 			  TOKEN_GETMAD((ps[(4) - (4)].val.i_tkval),(yyval.opval),']');
 			;}
     break;
 
-  case 107:
-#line 807 "perly.y"
+  case 112:
+#line 848 "perly.y"
     { (yyval.opval) = newBINOP(OP_AELEM, 0,
 					ref(newAVREF((ps[(1) - (5)].val.opval)),OP_RV2AV),
 					scalar((ps[(4) - (5)].val.opval)));
@@ -882,8 +929,8 @@ case 2:
 			;}
     break;
 
-  case 108:
-#line 815 "perly.y"
+  case 113:
+#line 856 "perly.y"
     { (yyval.opval) = newBINOP(OP_AELEM, 0,
 					ref(newAVREF((ps[(1) - (4)].val.opval)),OP_RV2AV),
 					scalar((ps[(3) - (4)].val.opval)));
@@ -892,8 +939,8 @@ case 2:
 			;}
     break;
 
-  case 109:
-#line 822 "perly.y"
+  case 114:
+#line 863 "perly.y"
     { (yyval.opval) = newBINOP(OP_HELEM, 0, oopsHV((ps[(1) - (5)].val.opval)), jmaybe((ps[(3) - (5)].val.opval)));
 			    PL_parser->expect = XOPERATOR;
 			  TOKEN_GETMAD((ps[(2) - (5)].val.i_tkval),(yyval.opval),'{');
@@ -902,8 +949,8 @@ case 2:
 			;}
     break;
 
-  case 110:
-#line 829 "perly.y"
+  case 115:
+#line 870 "perly.y"
     { (yyval.opval) = newBINOP(OP_HELEM, 0,
 					ref(newHVREF((ps[(1) - (6)].val.opval)),OP_RV2HV),
 					jmaybe((ps[(4) - (6)].val.opval)));
@@ -915,8 +962,8 @@ case 2:
 			;}
     break;
 
-  case 111:
-#line 839 "perly.y"
+  case 116:
+#line 880 "perly.y"
     { (yyval.opval) = newBINOP(OP_HELEM, 0,
 					ref(newHVREF((ps[(1) - (5)].val.opval)),OP_RV2HV),
 					jmaybe((ps[(3) - (5)].val.opval)));
@@ -927,8 +974,8 @@ case 2:
 			;}
     break;
 
-  case 112:
-#line 848 "perly.y"
+  case 117:
+#line 889 "perly.y"
     { (yyval.opval) = newUNOP(OP_ENTERSUB, OPf_STACKED,
 				   newCVREF(0, scalar((ps[(1) - (4)].val.opval))));
 			  TOKEN_GETMAD((ps[(2) - (4)].val.i_tkval),(yyval.opval),'a');
@@ -937,8 +984,8 @@ case 2:
 			;}
     break;
 
-  case 113:
-#line 855 "perly.y"
+  case 118:
+#line 896 "perly.y"
     { (yyval.opval) = newUNOP(OP_ENTERSUB, OPf_STACKED,
 				   op_append_elem(OP_LIST, (ps[(4) - (5)].val.opval),
 				       newCVREF(0, scalar((ps[(1) - (5)].val.opval)))));
@@ -948,8 +995,8 @@ case 2:
 			;}
     break;
 
-  case 114:
-#line 864 "perly.y"
+  case 119:
+#line 905 "perly.y"
     { (yyval.opval) = newUNOP(OP_ENTERSUB, OPf_STACKED,
 				   op_append_elem(OP_LIST, (ps[(3) - (4)].val.opval),
 					       newCVREF(0, scalar((ps[(1) - (4)].val.opval)))));
@@ -958,8 +1005,8 @@ case 2:
 			;}
     break;
 
-  case 115:
-#line 871 "perly.y"
+  case 120:
+#line 912 "perly.y"
     { (yyval.opval) = newUNOP(OP_ENTERSUB, OPf_STACKED,
 				   newCVREF(0, scalar((ps[(1) - (3)].val.opval))));
 			  TOKEN_GETMAD((ps[(2) - (3)].val.i_tkval),(yyval.opval),'(');
@@ -967,8 +1014,8 @@ case 2:
 			;}
     break;
 
-  case 116:
-#line 877 "perly.y"
+  case 121:
+#line 918 "perly.y"
     { (yyval.opval) = newSLICEOP(0, (ps[(5) - (6)].val.opval), (ps[(2) - (6)].val.opval));
 			  TOKEN_GETMAD((ps[(1) - (6)].val.i_tkval),(yyval.opval),'(');
 			  TOKEN_GETMAD((ps[(3) - (6)].val.i_tkval),(yyval.opval),')');
@@ -977,16 +1024,16 @@ case 2:
 			;}
     break;
 
-  case 117:
-#line 884 "perly.y"
+  case 122:
+#line 925 "perly.y"
     { (yyval.opval) = newSLICEOP(0, (ps[(3) - (4)].val.opval), (ps[(1) - (4)].val.opval));
 			  TOKEN_GETMAD((ps[(2) - (4)].val.i_tkval),(yyval.opval),'[');
 			  TOKEN_GETMAD((ps[(4) - (4)].val.i_tkval),(yyval.opval),']');
 			;}
     break;
 
-  case 118:
-#line 889 "perly.y"
+  case 123:
+#line 930 "perly.y"
     { (yyval.opval) = newSLICEOP(0, (ps[(4) - (5)].val.opval), (OP*)NULL);
 			  TOKEN_GETMAD((ps[(1) - (5)].val.i_tkval),(yyval.opval),'(');
 			  TOKEN_GETMAD((ps[(2) - (5)].val.i_tkval),(yyval.opval),')');
@@ -995,22 +1042,22 @@ case 2:
 			;}
     break;
 
-  case 119:
-#line 899 "perly.y"
+  case 124:
+#line 940 "perly.y"
     { (yyval.opval) = newASSIGNOP(OPf_STACKED, (ps[(1) - (3)].val.opval), IVAL((ps[(2) - (3)].val.i_tkval)), (ps[(3) - (3)].val.opval));
 			  TOKEN_GETMAD((ps[(2) - (3)].val.i_tkval),(yyval.opval),'o');
 			;}
     break;
 
-  case 120:
-#line 903 "perly.y"
+  case 125:
+#line 944 "perly.y"
     { (yyval.opval) = newBINOP(IVAL((ps[(2) - (3)].val.i_tkval)), 0, scalar((ps[(1) - (3)].val.opval)), scalar((ps[(3) - (3)].val.opval)));
 			  TOKEN_GETMAD((ps[(2) - (3)].val.i_tkval),(yyval.opval),'o');
 			;}
     break;
 
-  case 121:
-#line 907 "perly.y"
+  case 126:
+#line 948 "perly.y"
     {   if (IVAL((ps[(2) - (3)].val.i_tkval)) != OP_REPEAT)
 				scalar((ps[(1) - (3)].val.opval));
 			    (yyval.opval) = newBINOP(IVAL((ps[(2) - (3)].val.i_tkval)), 0, (ps[(1) - (3)].val.opval), scalar((ps[(3) - (3)].val.opval)));
@@ -1018,50 +1065,50 @@ case 2:
 			;}
     break;
 
-  case 122:
-#line 913 "perly.y"
+  case 127:
+#line 954 "perly.y"
     { (yyval.opval) = newBINOP(IVAL((ps[(2) - (3)].val.i_tkval)), 0, scalar((ps[(1) - (3)].val.opval)), scalar((ps[(3) - (3)].val.opval)));
 			  TOKEN_GETMAD((ps[(2) - (3)].val.i_tkval),(yyval.opval),'o');
 			;}
     break;
 
-  case 123:
-#line 917 "perly.y"
+  case 128:
+#line 958 "perly.y"
     { (yyval.opval) = newBINOP(IVAL((ps[(2) - (3)].val.i_tkval)), 0, scalar((ps[(1) - (3)].val.opval)), scalar((ps[(3) - (3)].val.opval)));
 			  TOKEN_GETMAD((ps[(2) - (3)].val.i_tkval),(yyval.opval),'o');
 			;}
     break;
 
-  case 124:
-#line 921 "perly.y"
+  case 129:
+#line 962 "perly.y"
     { (yyval.opval) = newBINOP(IVAL((ps[(2) - (3)].val.i_tkval)), 0, scalar((ps[(1) - (3)].val.opval)), scalar((ps[(3) - (3)].val.opval)));
 			  TOKEN_GETMAD((ps[(2) - (3)].val.i_tkval),(yyval.opval),'o');
 			;}
     break;
 
-  case 125:
-#line 925 "perly.y"
+  case 130:
+#line 966 "perly.y"
     { (yyval.opval) = newBINOP(IVAL((ps[(2) - (3)].val.i_tkval)), 0, scalar((ps[(1) - (3)].val.opval)), scalar((ps[(3) - (3)].val.opval)));
 			  TOKEN_GETMAD((ps[(2) - (3)].val.i_tkval),(yyval.opval),'o');
 			;}
     break;
 
-  case 126:
-#line 929 "perly.y"
+  case 131:
+#line 970 "perly.y"
     { (yyval.opval) = newBINOP(IVAL((ps[(2) - (3)].val.i_tkval)), 0, scalar((ps[(1) - (3)].val.opval)), scalar((ps[(3) - (3)].val.opval)));
 			  TOKEN_GETMAD((ps[(2) - (3)].val.i_tkval),(yyval.opval),'o');
 			;}
     break;
 
-  case 127:
-#line 933 "perly.y"
+  case 132:
+#line 974 "perly.y"
     { (yyval.opval) = newBINOP(IVAL((ps[(2) - (3)].val.i_tkval)), 0, scalar((ps[(1) - (3)].val.opval)), scalar((ps[(3) - (3)].val.opval)));
 			  TOKEN_GETMAD((ps[(2) - (3)].val.i_tkval),(yyval.opval),'o');
 			;}
     break;
 
-  case 128:
-#line 937 "perly.y"
+  case 133:
+#line 978 "perly.y"
     {
 			  (yyval.opval) = newRANGE(IVAL((ps[(2) - (3)].val.i_tkval)), scalar((ps[(1) - (3)].val.opval)), scalar((ps[(3) - (3)].val.opval)));
 			  DO_MAD({
@@ -1075,29 +1122,29 @@ case 2:
 			;}
     break;
 
-  case 129:
-#line 949 "perly.y"
+  case 134:
+#line 990 "perly.y"
     { (yyval.opval) = newLOGOP(OP_AND, 0, (ps[(1) - (3)].val.opval), (ps[(3) - (3)].val.opval));
 			  TOKEN_GETMAD((ps[(2) - (3)].val.i_tkval),(yyval.opval),'o');
 			;}
     break;
 
-  case 130:
-#line 953 "perly.y"
+  case 135:
+#line 994 "perly.y"
     { (yyval.opval) = newLOGOP(OP_OR, 0, (ps[(1) - (3)].val.opval), (ps[(3) - (3)].val.opval));
 			  TOKEN_GETMAD((ps[(2) - (3)].val.i_tkval),(yyval.opval),'o');
 			;}
     break;
 
-  case 131:
-#line 957 "perly.y"
+  case 136:
+#line 998 "perly.y"
     { (yyval.opval) = newLOGOP(OP_DOR, 0, (ps[(1) - (3)].val.opval), (ps[(3) - (3)].val.opval));
 			  TOKEN_GETMAD((ps[(2) - (3)].val.i_tkval),(yyval.opval),'o');
 			;}
     break;
 
-  case 132:
-#line 961 "perly.y"
+  case 137:
+#line 1002 "perly.y"
     { (yyval.opval) = bind_match(IVAL((ps[(2) - (3)].val.i_tkval)), (ps[(1) - (3)].val.opval), (ps[(3) - (3)].val.opval));
 			  TOKEN_GETMAD((ps[(2) - (3)].val.i_tkval),
 				((yyval.opval)->op_type == OP_NOT
@@ -1106,15 +1153,15 @@ case 2:
 			;}
     break;
 
-  case 133:
-#line 971 "perly.y"
+  case 138:
+#line 1012 "perly.y"
     { (yyval.opval) = newUNOP(OP_NEGATE, 0, scalar((ps[(2) - (2)].val.opval)));
 			  TOKEN_GETMAD((ps[(1) - (2)].val.i_tkval),(yyval.opval),'o');
 			;}
     break;
 
-  case 134:
-#line 975 "perly.y"
+  case 139:
+#line 1016 "perly.y"
     { (yyval.opval) = IF_MAD(
 				    newUNOP(OP_NULL, 0, (ps[(2) - (2)].val.opval)),
 				    (ps[(2) - (2)].val.opval)
@@ -1123,70 +1170,70 @@ case 2:
 			;}
     break;
 
-  case 135:
-#line 982 "perly.y"
+  case 140:
+#line 1023 "perly.y"
     { (yyval.opval) = newUNOP(OP_NOT, 0, scalar((ps[(2) - (2)].val.opval)));
 			  TOKEN_GETMAD((ps[(1) - (2)].val.i_tkval),(yyval.opval),'o');
 			;}
     break;
 
-  case 136:
-#line 986 "perly.y"
+  case 141:
+#line 1027 "perly.y"
     { (yyval.opval) = newUNOP(OP_COMPLEMENT, 0, scalar((ps[(2) - (2)].val.opval)));
 			  TOKEN_GETMAD((ps[(1) - (2)].val.i_tkval),(yyval.opval),'o');
 			;}
     break;
 
-  case 137:
-#line 990 "perly.y"
+  case 142:
+#line 1031 "perly.y"
     { (yyval.opval) = newUNOP(OP_POSTINC, 0,
 					op_lvalue(scalar((ps[(1) - (2)].val.opval)), OP_POSTINC));
 			  TOKEN_GETMAD((ps[(2) - (2)].val.i_tkval),(yyval.opval),'o');
 			;}
     break;
 
-  case 138:
-#line 995 "perly.y"
+  case 143:
+#line 1036 "perly.y"
     { (yyval.opval) = newUNOP(OP_POSTDEC, 0,
 					op_lvalue(scalar((ps[(1) - (2)].val.opval)), OP_POSTDEC));
 			  TOKEN_GETMAD((ps[(2) - (2)].val.i_tkval),(yyval.opval),'o');
 			;}
     break;
 
-  case 139:
-#line 1000 "perly.y"
+  case 144:
+#line 1041 "perly.y"
     { (yyval.opval) = newUNOP(OP_PREINC, 0,
 					op_lvalue(scalar((ps[(2) - (2)].val.opval)), OP_PREINC));
 			  TOKEN_GETMAD((ps[(1) - (2)].val.i_tkval),(yyval.opval),'o');
 			;}
     break;
 
-  case 140:
-#line 1005 "perly.y"
+  case 145:
+#line 1046 "perly.y"
     { (yyval.opval) = newUNOP(OP_PREDEC, 0,
 					op_lvalue(scalar((ps[(2) - (2)].val.opval)), OP_PREDEC));
 			  TOKEN_GETMAD((ps[(1) - (2)].val.i_tkval),(yyval.opval),'o');
 			;}
     break;
 
-  case 141:
-#line 1014 "perly.y"
+  case 146:
+#line 1055 "perly.y"
     { (yyval.opval) = newANONLIST((ps[(2) - (3)].val.opval));
 			  TOKEN_GETMAD((ps[(1) - (3)].val.i_tkval),(yyval.opval),'[');
 			  TOKEN_GETMAD((ps[(3) - (3)].val.i_tkval),(yyval.opval),']');
 			;}
     break;
 
-  case 142:
-#line 1019 "perly.y"
+  case 147:
+#line 1060 "perly.y"
     { (yyval.opval) = newANONLIST((OP*)NULL);
 			  TOKEN_GETMAD((ps[(1) - (2)].val.i_tkval),(yyval.opval),'[');
 			  TOKEN_GETMAD((ps[(2) - (2)].val.i_tkval),(yyval.opval),']');
 			;}
     break;
 
-  case 143:
-#line 1024 "perly.y"
+  case 148:
+#line 1065 "perly.y"
     { (yyval.opval) = newANONHASH((ps[(2) - (4)].val.opval));
 			  TOKEN_GETMAD((ps[(1) - (4)].val.i_tkval),(yyval.opval),'{');
 			  TOKEN_GETMAD((ps[(3) - (4)].val.i_tkval),(yyval.opval),';');
@@ -1194,8 +1241,8 @@ case 2:
 			;}
     break;
 
-  case 144:
-#line 1030 "perly.y"
+  case 149:
+#line 1071 "perly.y"
     { (yyval.opval) = newANONHASH((OP*)NULL);
 			  TOKEN_GETMAD((ps[(1) - (3)].val.i_tkval),(yyval.opval),'{');
 			  TOKEN_GETMAD((ps[(2) - (3)].val.i_tkval),(yyval.opval),';');
@@ -1203,8 +1250,8 @@ case 2:
 			;}
     break;
 
-  case 145:
-#line 1036 "perly.y"
+  case 150:
+#line 1077 "perly.y"
     { SvREFCNT_inc_simple_void(PL_compcv);
 			  (yyval.opval) = newANONATTRSUB((ps[(2) - (5)].val.ival), (ps[(3) - (5)].val.opval), (ps[(4) - (5)].val.opval), (ps[(5) - (5)].val.opval));
 			  TOKEN_GETMAD((ps[(1) - (5)].val.i_tkval),(yyval.opval),'o');
@@ -1213,22 +1260,22 @@ case 2:
 			;}
     break;
 
-  case 146:
-#line 1047 "perly.y"
+  case 151:
+#line 1088 "perly.y"
     { (yyval.opval) = dofile((ps[(2) - (2)].val.opval), IVAL((ps[(1) - (2)].val.i_tkval)));
 			  TOKEN_GETMAD((ps[(1) - (2)].val.i_tkval),(yyval.opval),'o');
 			;}
     break;
 
-  case 147:
-#line 1051 "perly.y"
+  case 152:
+#line 1092 "perly.y"
     { (yyval.opval) = newUNOP(OP_NULL, OPf_SPECIAL, op_scope((ps[(2) - (2)].val.opval)));
 			  TOKEN_GETMAD((ps[(1) - (2)].val.i_tkval),(yyval.opval),'D');
 			;}
     break;
 
-  case 148:
-#line 1055 "perly.y"
+  case 153:
+#line 1096 "perly.y"
     { (yyval.opval) = newUNOP(OP_ENTERSUB,
 			    OPf_SPECIAL|OPf_STACKED,
 			    op_prepend_elem(OP_LIST,
@@ -1242,8 +1289,8 @@ case 2:
 			;}
     break;
 
-  case 149:
-#line 1067 "perly.y"
+  case 154:
+#line 1108 "perly.y"
     { (yyval.opval) = newUNOP(OP_ENTERSUB,
 			    OPf_SPECIAL|OPf_STACKED,
 			    op_append_elem(OP_LIST,
@@ -1258,8 +1305,8 @@ case 2:
 			;}
     break;
 
-  case 150:
-#line 1080 "perly.y"
+  case 155:
+#line 1121 "perly.y"
     { (yyval.opval) = newUNOP(OP_ENTERSUB, OPf_SPECIAL|OPf_STACKED,
 			    op_prepend_elem(OP_LIST,
 				scalar(newCVREF(0,scalar((ps[(2) - (4)].val.opval)))), (OP*)NULL)); dep();
@@ -1269,8 +1316,8 @@ case 2:
 			;}
     break;
 
-  case 151:
-#line 1088 "perly.y"
+  case 156:
+#line 1129 "perly.y"
     { (yyval.opval) = newUNOP(OP_ENTERSUB, OPf_SPECIAL|OPf_STACKED,
 			    op_prepend_elem(OP_LIST,
 				(ps[(4) - (5)].val.opval),
@@ -1281,86 +1328,86 @@ case 2:
 			;}
     break;
 
-  case 156:
-#line 1104 "perly.y"
+  case 161:
+#line 1145 "perly.y"
     { (yyval.opval) = newCONDOP(0, (ps[(1) - (5)].val.opval), (ps[(3) - (5)].val.opval), (ps[(5) - (5)].val.opval));
 			  TOKEN_GETMAD((ps[(2) - (5)].val.i_tkval),(yyval.opval),'?');
 			  TOKEN_GETMAD((ps[(4) - (5)].val.i_tkval),(yyval.opval),':');
 			;}
     break;
 
-  case 157:
-#line 1109 "perly.y"
+  case 162:
+#line 1150 "perly.y"
     { (yyval.opval) = newUNOP(OP_REFGEN, 0, op_lvalue((ps[(2) - (2)].val.opval),OP_REFGEN));
 			  TOKEN_GETMAD((ps[(1) - (2)].val.i_tkval),(yyval.opval),'o');
 			;}
     break;
 
-  case 158:
-#line 1113 "perly.y"
+  case 163:
+#line 1154 "perly.y"
     { (yyval.opval) = (ps[(1) - (1)].val.opval); ;}
     break;
 
-  case 159:
-#line 1115 "perly.y"
+  case 164:
+#line 1156 "perly.y"
     { (yyval.opval) = localize((ps[(2) - (2)].val.opval),IVAL((ps[(1) - (2)].val.i_tkval)));
 			  TOKEN_GETMAD((ps[(1) - (2)].val.i_tkval),(yyval.opval),'k');
 			;}
     break;
 
-  case 160:
-#line 1119 "perly.y"
+  case 165:
+#line 1160 "perly.y"
     { (yyval.opval) = sawparens(IF_MAD(newUNOP(OP_NULL,0,(ps[(2) - (3)].val.opval)), (ps[(2) - (3)].val.opval)));
 			  TOKEN_GETMAD((ps[(1) - (3)].val.i_tkval),(yyval.opval),'(');
 			  TOKEN_GETMAD((ps[(3) - (3)].val.i_tkval),(yyval.opval),')');
 			;}
     break;
 
-  case 161:
-#line 1124 "perly.y"
+  case 166:
+#line 1165 "perly.y"
     { (yyval.opval) = IF_MAD(newUNOP(OP_NULL,0,(ps[(1) - (1)].val.opval)), (ps[(1) - (1)].val.opval)); ;}
     break;
 
-  case 162:
-#line 1126 "perly.y"
+  case 167:
+#line 1167 "perly.y"
     { (yyval.opval) = sawparens(newNULLLIST());
 			  TOKEN_GETMAD((ps[(1) - (2)].val.i_tkval),(yyval.opval),'(');
 			  TOKEN_GETMAD((ps[(2) - (2)].val.i_tkval),(yyval.opval),')');
 			;}
     break;
 
-  case 163:
-#line 1131 "perly.y"
+  case 168:
+#line 1172 "perly.y"
     { (yyval.opval) = (ps[(1) - (1)].val.opval); ;}
     break;
 
-  case 164:
-#line 1133 "perly.y"
+  case 169:
+#line 1174 "perly.y"
     { (yyval.opval) = (ps[(1) - (1)].val.opval); ;}
     break;
 
-  case 165:
-#line 1135 "perly.y"
+  case 170:
+#line 1176 "perly.y"
     { (yyval.opval) = (ps[(1) - (1)].val.opval); ;}
     break;
 
-  case 166:
-#line 1137 "perly.y"
+  case 171:
+#line 1178 "perly.y"
     { (yyval.opval) = (ps[(1) - (1)].val.opval); ;}
     break;
 
-  case 167:
-#line 1139 "perly.y"
+  case 172:
+#line 1180 "perly.y"
     { (yyval.opval) = newUNOP(OP_AV2ARYLEN, 0, ref((ps[(1) - (1)].val.opval), OP_AV2ARYLEN));;}
     break;
 
-  case 168:
-#line 1141 "perly.y"
+  case 173:
+#line 1182 "perly.y"
     { (yyval.opval) = (ps[(1) - (1)].val.opval); ;}
     break;
 
-  case 169:
-#line 1143 "perly.y"
+  case 174:
+#line 1184 "perly.y"
     { (yyval.opval) = op_prepend_elem(OP_ASLICE,
 				newOP(OP_PUSHMARK, 0),
 				    newLISTOP(OP_ASLICE, 0,
@@ -1371,8 +1418,8 @@ case 2:
 			;}
     break;
 
-  case 170:
-#line 1152 "perly.y"
+  case 175:
+#line 1193 "perly.y"
     { (yyval.opval) = op_prepend_elem(OP_HSLICE,
 				newOP(OP_PUSHMARK, 0),
 				    newLISTOP(OP_HSLICE, 0,
@@ -1385,26 +1432,26 @@ case 2:
 			;}
     break;
 
-  case 171:
-#line 1163 "perly.y"
+  case 176:
+#line 1204 "perly.y"
     { (yyval.opval) = (ps[(1) - (1)].val.opval); ;}
     break;
 
-  case 172:
-#line 1165 "perly.y"
+  case 177:
+#line 1206 "perly.y"
     { (yyval.opval) = newUNOP(OP_ENTERSUB, 0, scalar((ps[(1) - (1)].val.opval))); ;}
     break;
 
-  case 173:
-#line 1167 "perly.y"
+  case 178:
+#line 1208 "perly.y"
     { (yyval.opval) = newUNOP(OP_ENTERSUB, OPf_STACKED, scalar((ps[(1) - (3)].val.opval)));
 			  TOKEN_GETMAD((ps[(2) - (3)].val.i_tkval),(yyval.opval),'(');
 			  TOKEN_GETMAD((ps[(3) - (3)].val.i_tkval),(yyval.opval),')');
 			;}
     break;
 
-  case 174:
-#line 1172 "perly.y"
+  case 179:
+#line 1213 "perly.y"
     {
 			  (yyval.opval) = newUNOP(OP_ENTERSUB, OPf_STACKED,
 				op_append_elem(OP_LIST, (ps[(3) - (4)].val.opval), scalar((ps[(1) - (4)].val.opval))));
@@ -1419,91 +1466,91 @@ case 2:
 			;}
     break;
 
-  case 175:
-#line 1185 "perly.y"
+  case 180:
+#line 1226 "perly.y"
     { (yyval.opval) = newUNOP(OP_ENTERSUB, OPf_STACKED,
 			    op_append_elem(OP_LIST, (ps[(3) - (3)].val.opval), scalar((ps[(2) - (3)].val.opval))));
 			  TOKEN_GETMAD((ps[(1) - (3)].val.i_tkval),(yyval.opval),'o');
 			;}
     break;
 
-  case 176:
-#line 1190 "perly.y"
+  case 181:
+#line 1231 "perly.y"
     { (yyval.opval) = newOP(IVAL((ps[(1) - (1)].val.i_tkval)), OPf_SPECIAL);
 			    PL_hints |= HINT_BLOCK_SCOPE;
 			  TOKEN_GETMAD((ps[(1) - (1)].val.i_tkval),(yyval.opval),'o');
 			;}
     break;
 
-  case 177:
-#line 1195 "perly.y"
+  case 182:
+#line 1236 "perly.y"
     { (yyval.opval) = newLOOPEX(IVAL((ps[(1) - (2)].val.i_tkval)),(ps[(2) - (2)].val.opval));
 			  TOKEN_GETMAD((ps[(1) - (2)].val.i_tkval),(yyval.opval),'o');
 			;}
     break;
 
-  case 178:
-#line 1199 "perly.y"
+  case 183:
+#line 1240 "perly.y"
     { (yyval.opval) = newUNOP(OP_NOT, 0, scalar((ps[(2) - (2)].val.opval)));
 			  TOKEN_GETMAD((ps[(1) - (2)].val.i_tkval),(yyval.opval),'o');
 			;}
     break;
 
-  case 179:
-#line 1203 "perly.y"
+  case 184:
+#line 1244 "perly.y"
     { (yyval.opval) = newOP(IVAL((ps[(1) - (1)].val.i_tkval)), 0);
 			  TOKEN_GETMAD((ps[(1) - (1)].val.i_tkval),(yyval.opval),'o');
 			;}
     break;
 
-  case 180:
-#line 1207 "perly.y"
+  case 185:
+#line 1248 "perly.y"
     { (yyval.opval) = newUNOP(IVAL((ps[(1) - (2)].val.i_tkval)), 0, (ps[(2) - (2)].val.opval));
 			  TOKEN_GETMAD((ps[(1) - (2)].val.i_tkval),(yyval.opval),'o');
 			;}
     break;
 
-  case 181:
-#line 1211 "perly.y"
+  case 186:
+#line 1252 "perly.y"
     { (yyval.opval) = newUNOP(IVAL((ps[(1) - (2)].val.i_tkval)), 0, (ps[(2) - (2)].val.opval));
 			  TOKEN_GETMAD((ps[(1) - (2)].val.i_tkval),(yyval.opval),'o');
 			;}
     break;
 
-  case 182:
-#line 1215 "perly.y"
+  case 187:
+#line 1256 "perly.y"
     { (yyval.opval) = newOP(OP_REQUIRE, (ps[(1) - (1)].val.i_tkval) ? OPf_SPECIAL : 0);
 			  TOKEN_GETMAD((ps[(1) - (1)].val.i_tkval),(yyval.opval),'o');
 			;}
     break;
 
-  case 183:
-#line 1219 "perly.y"
+  case 188:
+#line 1260 "perly.y"
     { (yyval.opval) = newUNOP(OP_REQUIRE, (ps[(1) - (2)].val.i_tkval) ? OPf_SPECIAL : 0, (ps[(2) - (2)].val.opval));
 			  TOKEN_GETMAD((ps[(1) - (2)].val.i_tkval),(yyval.opval),'o');
 			;}
     break;
 
-  case 184:
-#line 1223 "perly.y"
+  case 189:
+#line 1264 "perly.y"
     { (yyval.opval) = newUNOP(OP_ENTERSUB, OPf_STACKED, scalar((ps[(1) - (1)].val.opval))); ;}
     break;
 
-  case 185:
-#line 1225 "perly.y"
+  case 190:
+#line 1266 "perly.y"
     { (yyval.opval) = newUNOP(OP_ENTERSUB, OPf_STACKED,
 			    op_append_elem(OP_LIST, (ps[(2) - (2)].val.opval), scalar((ps[(1) - (2)].val.opval)))); ;}
     break;
 
**** PATCH TRUNCATED AT 2000 LINES -- 2841 NOT SHOWN ****

--
Perl5 Master Repository



nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About