summaryrefslogtreecommitdiff
path: root/coroutine/+test.ha
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;
};