#!/usr/bin/pugs
use v6;
use Test;
=kwid
Test basic escape continuations obtained from &?CALLER_CONTINUATION
=cut
plan 12;
sub simple1() returns Int {
&?CALLER_CONTINUATION(2);
return 1;
}
is(simple1(), 2, 'using ec instead of return');
sub simple2(Num $n) {
if ($n == 5) {
&?CALLER_CONTINUATION(1);
}
return 0;
}
ok(simple2(5), 'ec used to escape ($n = 5)');
ok(!simple2(1), 'ec not used');
sub closure1 () returns Int {
my $cont = &?CALLER_CONTINUATION;
my $a = sub { $cont(5) };
$a();
return 6;
}
is(closure1(), 5, 'closure uses ec to escape', :todo);
sub call_argument(Code $f, $arg) {
return $f($arg);
}
sub foo(Code $f) returns Int {
call_argument($f, 8);
return 3;
}
sub passing1 () returns Int {
foo(&?CALLER_CONTINUATION);
return 2;
}
is(try { passing1() }, 8, 'ec passed as an argument', :todo);
sub is_five(Num $n, Code $f) {
if ($n == 5) {
$f(1);
}
return 0;
}
sub passing2_not_cont(Num $n) {
my $a = 9;
is_five($n, sub { $a = 1 });
return $a;
}
sub passing2(Num $n) {
is_five($n, &?CALLER_CONTINUATION);
return 9;
}
sub passing2_closure(Num $n) {
my $c = &?CALLER_CONTINUATION;
is_five($n, sub { $c(1) });
return 9;
}
is(passing2_not_cont(5), 1, 'is_five w/o ec (1)');
is(passing2_not_cont(2), 9, 'is_five w/o ec (2)');
is(passing2(5), 1, 'is_five passing ec itself (1)', :todo);
is(passing2(2), 9, 'is_five passing ec itself (2)');
is(passing2_closure(5), 1, 'is_five passing ec via closure (1)', :todo);
is(passing2_closure(2), 9, 'is_five passing ec via closure (2)');
sub callconty() {
conty(&?CALLER_CONTINUATION);
return 1;
}
sub conty(Code $c) {
$c(2);
return 3;
}
is(callconty(), 2, 'continuation bug', :todo<bug>);
# Now test complicated full continuations got from the same place.
{
sub callcc (Code &block) { &block(&?CALLER_CONTINUATION) }
my $cont;
my $counter = 0;
callcc -> $cc { $cont = $cc };
$counter++;
$cont(undef) unless $counter == 3;
is($counter, 3, "Looping with a full continuation", :todo<feature>);
}
# Really evil: Store continuations in an aggregate
{
my %conts;
my $foo = sub { %conts<foo> = &?CALLER_CONTINUATION; return "normalfoo" };
my $bar = sub { %conts<bar> = &?CALLER_CONTINUATION; return "normalbar" };
my $history;
my $counter = 0;
$history ~= $foo(); $history ~= "foo$counter"; $counter++;
$history ~= $bar(); $history ~= "bar$counter"; $counter++;
%conts<foo>("secondfoo") if $counter <= 2;
%conts<bar>("secondbar") if $counter <= 4;
is
$history,
"normalfoofoo0normalbarbar1secondfoofoo2normalbarbar3secondbarbar4",
"continuations stored in an aggregate with loops";
}