lua-users home
lua-l archive

How to re-start a coroutine?

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Hi list,
I'm studying coroutine's usage. it implemented with C's
setjmp/longjmp. In C, after we do a longjmp, we will return setjmp,
and can try again. to run a same routine. like this:
int a = 1;
setjmp(jbuf, 0);
if (a == 1) {
 a == 2;
 longjmp(jbuf);
}
assert(a == 2);
the if statement can eval twice. each setjmp has the ability to re-try
remain programs, this is the ability that implement a "amb"[1]
function.
the question is: how can I do this in Lua?
local f = amb_func(function()
 local a = amb(1,2,3,4,5)
 if a ~= 3 then amb() end
 print(a)
end)
f()
in amb_func, function will put into a coroutine. in the call
amb(1,2,3,4,5), amb will set a "longjmp point", and resume coroutine,
if we reach amb(), the coroutine can "re-try" from the resume point,
like this:
local function amb(...)
 return coroutine.yield(...)
end
local function amb_try(cb, co, ...)
 local r = {coroutine.resume(co, ...)}
 if not table.remove(r, 1) then return end
 for _, v in ipairs(r) do
 local newco = coroutine.clone(co) -- HERE!
 local res, errmsg = pcall(amb_try, cb, newco, v)
 if res then
 cb(true, errmsg)
 elseif errmsg ~= 'no more tree' then
 cb(false, errmsg)
 end
 end
 error "no more tree"
end
local function amb_func(f)
 local co = coroutine.create(f)
 return coroutine.wrap(function(...)
 amb_try(coroutine.yield, co, ...)
 end)
end
but this idea need a way to "clone" a coroutine to prepare next retry.
is that a way to make coroutine retried from previous resume? or are
there any other way to implement this?
--
regards,
Xavier Wang.

AltStyle によって変換されたページ (->オリジナル) /