From: Vincent Pit Date: Fri, 8 Aug 2008 21:18:41 +0000 (+0200) Subject: for/while (...) { return if } should be interpreted as 'list' X-Git-Tag: v0.03~5 X-Git-Url: http://git.vpit.fr/?p=perl%2Fmodules%2FSub-Nary.git;a=commitdiff_plain;h=3b10ab9a7a01f579892a98a1ffc53202d6adc8d6 for/while (...) { return if } should be interpreted as 'list' --- diff --git a/lib/Sub/Nary.pm b/lib/Sub/Nary.pm index 8af7cd6..14b8822 100644 --- a/lib/Sub/Nary.pm +++ b/lib/Sub/Nary.pm @@ -484,21 +484,30 @@ sub pp_leaveloop { $op = $op->first; my ($r1, $l1); - if (name($op) eq 'enteriter') { + my $for; + if (name($op) eq 'enteriter') { # for loop ? + $for = 1; ($r1, $l1) = $self->inspect($op); - return $r1, $l1 if $r1 and zero $l1; + return $r1, $l1 if defined $r1 and zero $l1; } $op = $op->sibling; - my $r; + my ($r2, $l2); if (name($op->first) eq 'and') { - ($r, my $l) = ($self->inspect($op->first->first))[0]; - return $r, $l if $r and zero $l; - $r = ($self->inspect($op->first->first->sibling))[0]; + ($r2, $l2) = $self->inspect($op->first->first); + return $r2, $l2 if defined $r2 and zero $l2; + my $c = count $l2; + return { list => 1 }, undef if !$for and defined $r2; + my ($r3, $l3) = $self->inspect($op->first->first->sibling); + return { list => 1 }, undef if defined $r3 and defined $l3; + $r2 = add $r2, scale $c, $r3; } else { - $r = ($self->inspect($op))[0]; + ($r2, $l2) = $self->inspect($op); + return { list => 1 }, undef if defined $r2 and defined $l2; } + my $r = (defined $r1) ? add $r1, scale +(1 - count $r1), $r2 + : $r2; my $c = 1 - count $r; diag "& leaveloop $c" if $DEBUG; return $r, $c ? { 0 => $c } : undef; diff --git a/t/20-return.t b/t/20-return.t index e08fdba..e17deda 100644 --- a/t/20-return.t +++ b/t/20-return.t @@ -3,7 +3,7 @@ use strict; use warnings; -use Test::More tests => 63; +use Test::More tests => 66; use Sub::Nary; @@ -63,6 +63,7 @@ my @tests = ( [ sub { for (1, 2, 3) { return } }, 0 ], [ sub { for (1, 2, 3) { } return 1, 2; }, 2 ], [ sub { for (do { return 1, 2, 3 }) { } return 1, 2; }, 3 ], + [ sub { for (do { return 2, 3 if $x }) { } }, { 2 => 0.5, 0 => 0.5 } ], [ sub { for ($x, 1, $y) { return 1, 2 } }, 2 ], [ sub { for (@a) { return 1, do { $x } } }, 2 ], [ sub { for (keys %h) { return do { 1 }, do { return @a[0, 2] } } }, 2 ], @@ -70,12 +71,14 @@ my @tests = ( [ sub { for (my $i; $i < 10; ++$i) { return 1, @a[do{return 2, 3}] } }, 2 ], [ sub { return 1, 2 for 1 .. 4 }, 2 ], - [ sub { while (1) { return } }, 0 ], - [ sub { while (1) { } return 1, 2 }, 2 ], - [ sub { while (1) { return 1, 2 } }, 2 ], - [ sub { while (1) { last; return 1, 2 } }, 2 ], - [ sub { return 1, 2 while 1 }, 2 ], - [ sub { while (do { return 2, 3 }) { } }, 2 ], + [ sub { while (1) { return } }, 0 ], + [ sub { while (1) { } return 1, 2 }, 2 ], + [ sub { while (1) { return 1, 2 } }, 2 ], + [ sub { while (1) { return 1, 2 if $x } }, 'list' ], + [ sub { while (1) { last; return 1, 2 } }, 2 ], + [ sub { return 1, 2 while 1 }, 2 ], + [ sub { while (do { return 2, 3 }) { } }, 2 ], + [ sub { while (do { return 2, 3 if $x }) { } }, 'list' ], [ sub { eval { return } }, 0 ], [ sub { eval { return 1, 2 } }, 2 ],