summaryrefslogtreecommitdiff
path: root/dist
diff options
context:
space:
mode:
authorZefram <zefram@fysh.org>2010-10-19 21:16:11 +0100
committerFather Chrysostomos <sprout@cpan.org>2010-10-25 12:29:46 -0700
commiteae48c8938e50ebb341a72c2886c5ae8587092a5 (patch)
treea581082ad6e284de2600033f738b631b475e702e /dist
parentff0c75af8a61dcd9e5fa0e07c8c01e142cadd899 (diff)
downloadperl-eae48c8938e50ebb341a72c2886c5ae8587092a5.tar.gz
refactor and regularise label/statement grammar
Refactoring of the grammar around statements. New production <barestmt> encompasses a statement without label. It includes all statement types, including declarations, with no unnecessary intermediate non-terminals. It generates an op tree for the statement's content, with no leading state op. The <fullstmt> production has just one rule, consisting of optional label followed by <barestmt>. It puts a state op on the front of the statement's content ops. To support the regular statement op structure, the op sequence for for(;;) loops no longer has a second state op between the initialisation and the loop. Instead, the unstack op type is slightly adapted to achieve the stack clearing without a state op. The newFOROP() constructor function no longer generates a state op, that now being the job of the <fullstmt> production. Consequently it no longer takes a parameter stating what label is to go in the state op. This brings it in line with the other op constructors.
Diffstat (limited to 'dist')
-rw-r--r--dist/B-Deparse/Deparse.pm20
1 files changed, 14 insertions, 6 deletions
diff --git a/dist/B-Deparse/Deparse.pm b/dist/B-Deparse/Deparse.pm
index 7ea543716b..9bf6606aa6 100644
--- a/dist/B-Deparse/Deparse.pm
+++ b/dist/B-Deparse/Deparse.pm
@@ -23,7 +23,7 @@ use B qw(class main_root main_start main_cv svref_2object opnumber perlstring
PMf_MULTILINE PMf_SINGLELINE PMf_FOLD PMf_EXTENDED),
($] < 5.009 ? 'PMf_SKIPWHITE' : 'RXf_SKIPWHITE'),
($] < 5.011 ? 'CVf_LOCKED' : ());
-$VERSION = 0.99;
+$VERSION = 1.00;
use strict;
use vars qw/$AUTOLOAD/;
use warnings ();
@@ -958,14 +958,19 @@ sub is_for_loop {
my $op = shift;
# This OP might be almost anything, though it won't be a
# nextstate. (It's the initialization, so in the canonical case it
- # will be an sassign.) The sibling is a lineseq whose first child
- # is a nextstate and whose second is a leaveloop.
+ # will be an sassign.) The sibling is (old style) a lineseq whose
+ # first child is a nextstate and whose second is a leaveloop, or
+ # (new style) an unstack whose sibling is a leaveloop.
my $lseq = $op->sibling;
- if (!is_state $op and !null($lseq) and $lseq->name eq "lineseq") {
+ return 0 unless !is_state($op) and !null($lseq);
+ if ($lseq->name eq "lineseq") {
if ($lseq->first && !null($lseq->first) && is_state($lseq->first)
&& (my $sib = $lseq->first->sibling)) {
return (!null($sib) && $sib->name eq "leaveloop");
}
+ } elsif ($lseq->name eq "unstack" && ($lseq->flags & OPf_SPECIAL)) {
+ my $sib = $lseq->sibling;
+ return $sib && !null($sib) && $sib->name eq "leaveloop";
}
return 0;
}
@@ -1215,7 +1220,8 @@ sub walk_lineseq {
}
}
if (is_for_loop($kids[$i])) {
- $callback->($expr . $self->for_loop($kids[$i], 0), $i++);
+ $callback->($expr . $self->for_loop($kids[$i], 0),
+ $i += $kids[$i]->sibling->name eq "unstack" ? 2 : 1);
next;
}
$expr .= $self->deparse($kids[$i], (@kids != 1)/2);
@@ -2757,7 +2763,9 @@ sub for_loop {
my $self = shift;
my($op, $cx) = @_;
my $init = $self->deparse($op, 1);
- return $self->loop_common($op->sibling->first->sibling, $cx, $init);
+ my $s = $op->sibling;
+ my $ll = $s->name eq "unstack" ? $s->sibling : $s->first->sibling;
+ return $self->loop_common($ll, $cx, $init);
}
sub pp_leavetry {