Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
132 changes: 105 additions & 27 deletions S04-statements/label.t
Original file line number Diff line number Diff line change
Expand Up @@ -89,41 +89,119 @@ throws-like { EVAL q[label1: say "OH HAI"; label1: say "OH NOES"] }, X::Redeclar
# NB(bartolin) As of 2020-04-13 Rakudo has different classes for different loop
# types. The tests resemble Rakudo's current internal structure,
# but the code should work for all implementations.
# Please note that each type of loop comes in two versions: not
# within parens and within parens. Accordings to the old design
# documents the second version should be lazy:
# https://github.com/Raku/old-design-docs/blob/a4c36c683d/S04-control.pod#loops-at-the-statementlist-level-vs-the-statement-level
# The tests explicitly don't test this aspect. They are about the
# crash described in the mentioned bug report.
{
my $ignore;
my @res;
@ = (L1: while True { while True { @res.push: "WhileLoop"; last L1 } });
@ = (L2: until False { until False { @res.push: "WhileLoop"; last L2 } });
@ = (L3: Seq.from-loop(
{ loop { @res.push: "WhileLoop"; last L3 } },
{ True },
:label(L3)
));
is-deeply @res, ["WhileLoop", "WhileLoop", "WhileLoop"],
'nested loop with labeled last (1)';
sub while-loop() {
L: while True { while True { @res.push: 1; last L } }
}
sub while-loop-in-parens() {
(L: while True { while True { @res.push: 3; last L } })
}
sub until-loop() {
L: until False { until False { @res.push: 5; last L } }
}
sub until-loop-in-parens() {
(L: until False { until False { @res.push: 7; last L } })
}
# Make sure that loops are run (in case they are lazy).
$ignore = while-loop()[2];
$ignore = while-loop-in-parens()[2];
$ignore = until-loop()[2];
$ignore = until-loop-in-parens()[2];
is-deeply @res, [1, 3, 5, 7], 'no crash: nested loops and labeled last (1)';

@res = [];
@ = (L4: Seq.from-loop(
{ loop { @res.push: "RepeatLoop"; last L4 } },
{ True },
:label(L4),
:repeat(1)
));
is-deeply @res, ["RepeatLoop"], 'nested loop with labeled last (2)';
sub seq-from-loop-while() {
L: Seq.from-loop(
{ loop { @res.push: 9; last L } },
{ True },
:label(L)
)
}
sub seq-from-loop-while-in-parens() {
(L: Seq.from-loop(
{ loop { @res.push: 11; last L } },
{ True },
:label(L)
))
}
sub seq-from-loop-repeat() {
L: Seq.from-loop(
{ loop { @res.push: 13; last L } },
{ True },
:label(L),
:repeat(1)
)
}
sub seq-from-loop-repeat-in-parens() {
(L: Seq.from-loop(
{ loop { @res.push: 15; last L } },
{ True },
:label(L),
:repeat(1)
))
}
# Make sure that loops are run (in case they are lazy).
$ignore = seq-from-loop-while()[0];
$ignore = seq-from-loop-while-in-parens()[0];
$ignore = seq-from-loop-repeat()[0];
$ignore = seq-from-loop-repeat-in-parens()[0];
is-deeply @res, [9, 11, 13, 15], 'no crash: nested loops and labeled last (2)';

@res = [];
@ = (L5: loop { loop { @res.push: "CStyleLoop"; last L5 } });
@ = (L6: Seq.from-loop(
{ loop { @res.push: "CStyleLoop"; last L6 } },
{ True },
{ my $foo = 47 },
:label(L6)
));
is-deeply @res, ["CStyleLoop", "CStyleLoop"],
'nested loop with labeled last (3)';
sub c-style-loop() {
L: loop { loop { @res.push: 0; last L } }
}
sub c-style-loop-in-parens() {
(L: loop { loop { @res.push: 2; last L } })
}
sub seq-from-loop-c-style() {
L: Seq.from-loop(
{ loop { @res.push: 4; last L } },
{ True },
{ my $foo = 47 },
:label(L)
)
}
sub seq-from-loop-c-style-in-parens() {
(L: Seq.from-loop(
{ loop { @res.push: 6; last L } },
{ True },
{ my $foo = 47 },
:label(L)
))
}
# Make sure that loops are run (in case they are lazy).
$ignore = c-style-loop()[0];
$ignore = c-style-loop-in-parens()[0];
$ignore = seq-from-loop-c-style()[0];
$ignore = seq-from-loop-c-style-in-parens()[0];
is-deeply @res, [0, 2, 4, 6], 'no crash: nested loops and labeled last (3)';

@res = [];
L7: Seq.from-loop( { loop { @res.push: "Loop"; last L7 } }, :label(L7));
is-deeply @res, ["Loop"], 'nested loop with labeled last (4)';
sub seq-from-loop-plain() {
L: Seq.from-loop(
{ loop { @res.push: 8; last L } },
:label(L)
)
}
sub seq-from-loop-plain-in-parens() {
(L: Seq.from-loop(
{ loop { @res.push: 10; last L } },
:label(L)
))
}
# Make sure that loops are run (in case they are lazy).
$ignore = seq-from-loop-plain()[0];
$ignore = seq-from-loop-plain-in-parens()[0];
is-deeply @res, [8, 10], 'no crash: nested loops and labeled last (4)';
}

# https://github.com/rakudo/rakudo/issues/4456
Expand Down