# coroutine.nas by ValKmjolnir # 2022/5/19 use std.coroutine; use std.process_bar; use std.padding; if (os.platform()=="windows") { system("chcp 65001"); system("color"); } var fib = func() { var (a,b)=(1,1); coroutine.yield(a); coroutine.yield(b); while(1) { (a,b)=(b,a+b); coroutine.yield(b); } return; } var co=[coroutine.create(fib),coroutine.create(fib)]; for(var i=0;i<45;i+=1) { var res=[coroutine.resume(co[0]),coroutine.resume(co[1])]; if (res[0]==nil or res[1]==nil or res[0][0]!=res[1][0]) die("different coroutines don't share the same local scope"); } # test if coroutine can get upvalues func() { var x=1; var co=coroutine.create(func() { for(var j=0;j<128;j+=1) { coroutine.yield(x,i,j); x+=1; } }); for(var i=0;i<16;i+=1) { var res=coroutine.resume(co); if (res==nil or res[0]!=x or res[1]!=i) die("coroutine should have the ability to get upvalues"); } }(); # test coroutine.resume passing arguments to coroutine func { var co=coroutine.create(func() { var (a,b)=coroutine.yield(a+b); println("coroutine.yield get ",a," ",b); (a,b)=coroutine.yield(a+b); println("coroutine.yield get ",a," ",b); return "end"; }); for(var i=0;i<5;i+=1) println("coroutine.resume get ",coroutine.resume(co,i,i+1)); }(); # test crash in coroutines var co=coroutine.create(func { var b = func() {b()} coroutine.yield(b); b(); coroutine.yield(0); }); println("coroutine yield: ",coroutine.resume(co)); println("coroutine state:\e[32m ",coroutine.status(co),"\e[0m"); println("coroutine error: ",coroutine.resume(co)); println("coroutine state:\e[91m ",coroutine.status(co),"\e[0m"); println("coroutine yield: ",coroutine.resume(co)); println("coroutine state:\e[91m ",coroutine.status(co),"\e[0m"); var co=coroutine.create(func { var a=1; var b = func() { b(); } coroutine.yield(b); coroutine.yield(b()); }); println("coroutine yield: ",coroutine.resume(co)); println("coroutine state:\e[32m ",coroutine.status(co),"\e[0m"); println("coroutine error: ",coroutine.resume(co)); println("coroutine state:\e[91m ",coroutine.status(co),"\e[0m"); println("coroutine yield: ",coroutine.resume(co)); println("coroutine state:\e[91m ",coroutine.status(co),"\e[0m"); println("ok"); # pressure test for(var t=0;t<10;t+=1) { var productor = func() { while(1) { coroutine.yield(i); } } var co=coroutine.create(productor); var tm=maketimestamp(); var counter=0; var bar=process_bar.high_resolution_bar(40); var consumer = func() { counter+=1; for(var i=0;i