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