blob: 1ac5217acbf6926894109a9213ee8c3263c6c3ba (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
|
// License: MPL-2.0
// (c) 2022 citrons <citrons@mondecitronne.com>
@test fn coroutine() void = {
let test: int = 0;
let co1 = new(&test_coroutine);
let co2 = new(&test_coroutine);
defer destroy(co1);
defer destroy(co2);
for (co1.status != status::dead || co2.status != status::dead) {
let val = test;
test = *(resume(co1, &val) as *int);
val = test;
test = *(resume(co2, &val) as *int);
};
assert(test == 100);
};
fn test_coroutine(arg: nullable *void) nullable *void = {
let i = *(arg as *int);
let v: nullable *void = null;
for (let j = 0; j < 50; j += 1) {
v = suspend(&(i + 1));
i = *(v as *int);
};
return v;
};
let test: int = 0;
@test fn nested_coroutine() void = {
let co1 = new(&nested);
defer destroy(co1);
resume(co1, null);
for (co1.status != status::dead) {
let co2 = new(&nested);
defer destroy(co2);
resume(co1, co2);
assert(co2.status == status::dead);
};
assert(test == 2500);
};
fn nested(arg: nullable *void) nullable *void = {
for (let i = 0; i < 50; i += 1) {
let co = suspend(null):
nullable *coroutine;
match (co) {
case null =>
test += 1;
case let co: *coroutine =>
for (co.status != status::dead)
resume(co, null);
};
};
return null;
};
|