github.com/arnodel/golua@v0.0.0-20230215163904-e0b5347eaaa1/lib/coroutine/lua/coroutine.lua (about) 1 -- Some general checks 2 do 3 local function cof(x) 4 print("in cof", x) 5 print("in cof", coroutine.yield(x + 2)) 6 return "from cof" 7 end 8 9 local co = coroutine.create(cof) 10 11 print(pcall(coroutine.resume, {})) 12 --> ~false\t.*#1 must be a thread 13 14 print("out", coroutine.resume(co, 1)) 15 print("out", coroutine.resume(co, "two")) 16 17 --> =in cof 1 18 --> =out true 3 19 --> =in cof two 20 --> =out true from cof 21 22 print(coroutine.status(co)) 23 --> =dead 24 25 print(pcall(coroutine.status, cof)) 26 --> ~false\t.*#1 must be a thread 27 28 print(pcall(coroutine.create, 1)) 29 --> ~false\t.*#1 must be a callable 30 end 31 32 -- Check the main coroutine is correctly identified 33 print(coroutine.running()) 34 --> ~^thread:.*\ttrue$ 35 36 do 37 -- Check the main coroutine is not yieldable 38 print(coroutine.isyieldable()) 39 --> =false 40 41 print(pcall(coroutine.yield, 1)) 42 --> ~false\t.*cannot yield from main thread 43 44 print(pcall(coroutine.isyieldable, 1)) 45 --> ~false\t.*must be a thread 46 end 47 48 -- Check that coroutine.running() returns true as second argument when 49 -- called from a non-main coroutine and that a non main coroutine is 50 -- yieldable. 51 do 52 local function cof() 53 print("yieldable", coroutine.isyieldable()) 54 return coroutine.running() 55 end 56 local co = coroutine.create(cof) 57 58 print(coroutine.isyieldable(co)) 59 --> =true 60 61 print(coroutine.resume(co)) 62 --> =yieldable true 63 --> ~^true\tthread:.*\tfalse$ 64 end 65 66 -- Test error in coroutine 67 do 68 local function cof() 69 error("boo") 70 end 71 local co = coroutine.create(cof) 72 print(coroutine.resume(co)) 73 --> ~^false\t.* boo$ 74 print(coroutine.status(co)) 75 --> =dead 76 end 77 78 -- Check various statuses of coroutines 79 do 80 local main = coroutine.running() 81 local function cof(co) 82 coroutine.yield(coroutine.status(co)) 83 return coroutine.status(main) 84 end 85 co = coroutine.create(cof) 86 87 print("main/main", coroutine.status(main)) 88 --> =main/main running 89 90 print("co/main", coroutine.status(co)) 91 --> =co/main suspended 92 93 print("co/co", coroutine.resume(co, co)) 94 --> =co/co true running 95 96 print("main/co", coroutine.resume(co)) 97 --> =main/co true normal 98 99 print("co", coroutine.status(co)) 100 --> =co dead 101 end 102 103 -- Test coroutine.wrap() 104 do 105 local function cofib() 106 local a, b = 0, 1 107 while true do 108 coroutine.yield(a) 109 a, b = b, a+b 110 end 111 end 112 local fib = coroutine.wrap(cofib) 113 print(fib(), fib(), fib(), fib(), fib()) 114 --> =0 1 1 2 3 115 116 print(pcall(coroutine.wrap)) 117 --> ~false\t.*value needed 118 119 print(pcall(coroutine.wrap, "not a function")) 120 --> ~false\t.*must be a callable 121 122 local werr = coroutine.wrap(function(x, y) 123 coroutine.yield(x) 124 error(y) 125 end) 126 print(werr("abc", "def")) 127 --> =abc 128 129 print(pcall(werr)) 130 --> ~false\t.*def 131 132 print(pcall(werr)) 133 --> ~false\t.*cannot resume dead thread 134 end 135 136 -- Test coroutine.close() (5.4) 137 do 138 print(pcall(coroutine.close)) 139 --> ~false\t.*value needed 140 141 print(pcall(coroutine.close, 1)) 142 --> ~false\t.*must be a thread 143 144 print(pcall(coroutine.close, coroutine.running())) 145 --> ~false\t.*cannot close running thread 146 147 local co = coroutine.create(function() 148 coroutine.yield() 149 end) 150 151 coroutine.resume(co) 152 print(coroutine.close(co)) 153 --> =true 154 print(coroutine.status(co)) 155 --> =dead 156 local co = coroutine.create(function() 157 local t = {} 158 setmetatable(t, {__close=function() error("ERR") end}) 159 local x <close> = t 160 coroutine.yield() 161 end) 162 coroutine.resume(co) 163 pcall(function() print(coroutine.close(co)) end) 164 --> ~false\t.*ERR 165 166 print(coroutine.status(co)) 167 --> =dead 168 end