mod macros; test!( coroutine_base, r#" function foo (a) print("foo", a) return coroutine.yield(2*a) end co = coroutine.create(function (a,b) print("co-body", a, b) local r = foo(a+1) print("co-body", r) local r, s = coroutine.yield(a+b, a-b) print("co-body", r, s) return b, "end" end) print("main", coroutine.resume(co, 1, 10)) print("main", coroutine.resume(co, "r")) print("main", coroutine.resume(co, "x", "y")) print("main", coroutine.resume(co, "x", "y")) "#, " co-body\t1\t10 foo\t2 main\ttrue\t4 co-body\tr main\ttrue\t11\t-9 co-body\tx\ty main\ttrue\t10\tend main\tfalse\tcannot resume dead coroutine " ); test!( coroutine_resume_non_suspended, r#" function a() print("+a") print("->b") print("res b", coroutine.resume(tb)) print("<-b") print("-a") end function b() print("+b") print("->a") print("res a", coroutine.resume(ta)) print("<-a") print("-b") end ta = coroutine.create(a) tb = coroutine.create(b) print("start") coroutine.resume(ta) print("end") "#, " start +a ->b +b ->a res a\tfalse\tcannot resume non-suspended coroutine <-a -b res b\ttrue <-b -a end " ); test!( coroutine_yield_xpcall_main, r#" print(xpcall(coroutine.yield, function(e) print("handle", e); return 33 end)) "#, " handle\tattempt to yield from outside a coroutine false\t33 " ); test!( coroutine_yield_xpcall_across, r#" function f() return xpcall( string.gsub, function(e) print("handle", e) return 33 end, "abc", "a", function() coroutine.yield() end ) end co = coroutine.create(f) print(coroutine.resume(co)) "#, " handle\tattempt to yield across a Rust-call boundary true\tfalse\t33 " );