Skip to content

Commit

Permalink
B::Concise now handles n-at-a-time for.
Browse files Browse the repository at this point in the history
  • Loading branch information
nwc10 committed Jun 28, 2021
1 parent 4909d02 commit 2caf176
Show file tree
Hide file tree
Showing 2 changed files with 133 additions and 2 deletions.
7 changes: 6 additions & 1 deletion ext/B/B/Concise.pm
Expand Up @@ -852,9 +852,14 @@ sub concise_op {
# targ holds a reference count
my $refs = "ref" . ($h{targ} != 1 ? "s" : "");
$h{targarglife} = $h{targarg} = "$h{targ} $refs";
} elsif ($h{targ}) {
} elsif ($h{targ} && $h{name} ne 'iter') {
# for my ($q, $r, $s) () {} syntax hijacks the targ of the iter op,
# (which is the ->next of the enteriter) hence the special cases above
# and just below:
my $count = $h{name} eq 'padrange'
? ($op->private & $B::Op_private::defines{'OPpPADRANGE_COUNTMASK'})
: $h{name} eq 'enteriter'
? $op->next->targ + 1
: 1;
my (@targarg, @targarglife);
for my $i (0..$count-1) {
Expand Down
128 changes: 127 additions & 1 deletion ext/B/t/optree_for.t
Expand Up @@ -14,7 +14,7 @@ BEGIN {
}
use OptreeCheck;
use Config;
plan tests => 11;
plan tests => 19;

pass("FOR LOOPS");

Expand Down Expand Up @@ -189,3 +189,129 @@ b <|> and(other->8) K/1
c <2> leaveloop K/2
d <1> leavesub[1 ref] K/REFC,1
EONT_EONT

checkOptree ( name => 'for my ($var) (@a)',
code => sub {for my ($var) (@a) {}},
bcopts => '-exec',
strip_open_hints => 1,
expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
1 <;> nextstate(main 1466 optree_for.t:100) v
2 <0> pushmark sM
3 <#> gv[*a] s
4 <1> rv2av[t3] sKRM/1
5 <{> enteriter(next->7 last->a redo->6)[$var:1474,1477] KS
8 <0> iter s
9 <|> and(other->6) K/1
6 <0> stub v
7 <0> unstack s
goto 8
a <2> leaveloop K/2
b <1> leavesub[1 ref] K/REFC,1
EOT_EOT
1 <;> nextstate(main 424 optree_for.t:111) v:>,<,%
2 <0> pushmark sM
3 <$> gv(*a) s
4 <1> rv2av[t2] sKRM/1
5 <{> enteriter(next->7 last->a redo->6)[$var:1474,1477] KS
8 <0> iter s
9 <|> and(other->6) K/1
6 <0> stub v
7 <0> unstack s
goto 8
a <2> leaveloop K/2
b <1> leavesub[1 ref] K/REFC,1
EONT_EONT

checkOptree ( name => 'for my ($var) (@lexical)',
code => sub {for my ($var) (@lexical) {}},
bcopts => '-exec',
strip_open_hints => 1,
expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
1 <;> nextstate(main 1466 optree_for.t:100) v
2 <0> pushmark sM
3 <0> padav[@lexical:FAKE::7] sRM
4 <{> enteriter(next->6 last->9 redo->5)[$var:1481,1484] KS
7 <0> iter s
8 <|> and(other->5) K/1
5 <0> stub v
6 <0> unstack s
goto 7
9 <2> leaveloop K/2
a <1> leavesub[2 refs] K/REFC,1
EOT_EOT
1 <;> nextstate(main 424 optree_for.t:111) v:>,<,%
2 <0> pushmark sM
3 <0> padav[@lexical:FAKE::2] sRM
4 <{> enteriter(next->6 last->9 redo->5)[$var:1481,1484] KS
7 <0> iter s
8 <|> and(other->5) K/1
5 <0> stub v
6 <0> unstack s
goto 7
9 <2> leaveloop K/2
a <1> leavesub[2 refs] K/REFC,1
EONT_EONT

checkOptree ( name => 'for my ($key, $value) (%h)',
code => sub {for my ($key, $value) (%h) {}},
bcopts => '-exec',
strip_open_hints => 1,
expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
1 <;> nextstate(main 1466 optree_for.t:100) v
2 <0> pushmark sM
3 <#> gv[*h] s
4 <1> rv2hv[t4] lKM
5 <{> enteriter(next->7 last->a redo->6)[$key:1488,1491; $value:1488,1491] K/LVINTRO
8 <0> iter s
9 <|> and(other->6) K/1
6 <0> stub v
7 <0> unstack s
goto 8
a <2> leaveloop K/2
b <1> leavesub[1 ref] K/REFC,1
EOT_EOT
1 <;> nextstate(main 424 optree_for.t:111) v:>,<,%
2 <0> pushmark sM
3 <$> gv(*h) s
4 <1> rv2hv[t3] lKM
5 <{> enteriter(next->7 last->a redo->6)[$key:1488,1491; $value:1488,1491] K/LVINTRO
8 <0> iter s
9 <|> and(other->6) K/1
6 <0> stub v
7 <0> unstack s
goto 8
a <2> leaveloop K/2
b <1> leavesub[1 ref] K/REFC,1
EONT_EONT

checkOptree ( name => 'for my ($foo, $bar, $baz) (@a)',
code => sub {for my ($foo, $bar, $baz) (@a) {}},
bcopts => '-exec',
strip_open_hints => 1,
expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
1 <;> nextstate(main 1466 optree_for.t:100) v
2 <0> pushmark sM
3 <#> gv[*a] s
4 <1> rv2av[t5] sKRM/1
5 <{> enteriter(next->7 last->a redo->6)[$foo:1495,1498; $bar:1495,1498; $baz:1495,1498] KS/LVINTRO
8 <0> iter s
9 <|> and(other->6) K/1
6 <0> stub v
7 <0> unstack s
goto 8
a <2> leaveloop K/2
b <1> leavesub[1 ref] K/REFC,1
EOT_EOT
1 <;> nextstate(main 424 optree_for.t:111) v:>,<,%
2 <0> pushmark sM
3 <$> gv(*a) s
4 <1> rv2av[t4] sKRM/1
5 <{> enteriter(next->7 last->a redo->6)[$foo:1495,1498; $bar:1495,1498; $baz:1495,1498] KS/LVINTRO
8 <0> iter s
9 <|> and(other->6) K/1
6 <0> stub v
7 <0> unstack s
goto 8
a <2> leaveloop K/2
b <1> leavesub[1 ref] K/REFC,1
EONT_EONT

0 comments on commit 2caf176

Please sign in to comment.