[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: How to re-start a coroutine?
- From: Xavier Wang <weasley.wx@...>
- Date: Sat, 16 Mar 2013 18:50:49 +0800
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.