]> git.vpit.fr Git - perl/modules/Sub-Nary.git/commitdiff
for/while (...) { return if } should be interpreted as 'list'
authorVincent Pit <vince@profvince.com>
Fri, 8 Aug 2008 21:18:41 +0000 (23:18 +0200)
committerVincent Pit <vince@profvince.com>
Fri, 8 Aug 2008 21:18:41 +0000 (23:18 +0200)
lib/Sub/Nary.pm
t/20-return.t

index 8af7cd6671c8662ca7e09e3ea02fb6933ab9a814..14b882285723a2e3d20bbb7472c8502df1166d8a 100644 (file)
@@ -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;
index e08fdbacd8049a314a08baf1b18fbac2d1ec1830..e17deda4511f4559f138d05fe38b32413b913521 100644 (file)
@@ -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 ],