// License: MPL-2.0 // (c) 2022 citrons @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; };