Skip to content

Commit

Permalink
Add. try.co module that implement protect function for coroutine.
Browse files Browse the repository at this point in the history
  • Loading branch information
moteus committed Nov 11, 2014
1 parent 4653c2a commit 60af1d7
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 5 deletions.
2 changes: 1 addition & 1 deletion lakefile
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ target('build', try)

install = target('install', {
file.group{odir=LIBDIR; src = try };
-- file.group{odir=LIBDIR; src = J("src", "lua") ; recurse = true };
file.group{odir=LIBDIR; src = J("src", "lua") ; recurse = true };
-- file.group{odir=J(ROOT, 'examples'); src = 'examples'; recurse = true };
file.group{odir=TESTDIR; src = 'test'; recurse = true };
})
Expand Down
1 change: 1 addition & 0 deletions rockspecs/try-scm-0.rockspec
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,6 @@ build = {
try = {
sources = { "src/try.c" },
},
["try.co"] = "src/lua/try/co.lua",
}
}
31 changes: 31 additions & 0 deletions src/lua/try/co.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
local try = require "try"

local function _protect(co, status, ...)
if not status then
local msg = ...
if type(msg) == 'table' then
local k, v = next(msg)
if k == try.NIL then
if v == try.NIL then v = nil end
return nil, v
end
end
return error(msg, 0)
end
if coroutine.status(co) == "suspended" then
return _protect(co, coroutine.resume(co, coroutine.yield(...)))
else
return ...
end
end

local function protect(f)
return function(...)
local co = coroutine.create(f)
return _protect(co, coroutine.resume(co, ...))
end
end

return setmetatable({
protect = protect
},{__index = try})
8 changes: 5 additions & 3 deletions src/try.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
# define EXPORT_API LUALIB_API
#endif

static const char *TRY_ERROR_IDX = "Dummy";
static const char *TRY_ERROR_NIL = "NIL";

/*=========================================================================*\
Expand Down Expand Up @@ -57,7 +56,7 @@ void lua_rawsetp (lua_State *L, int index, const void *p){
\*-------------------------------------------------------------------------*/
static int try_check_error(lua_State *L) {
if(lua_istable(L, -1)){
lua_rawgetp(L, -1, TRY_ERROR_IDX);
lua_rawgetp(L, -1, TRY_ERROR_NIL);

if(lua_isnil(L, -1)){ /*not try error*/
lua_pop(L, 1);
Expand Down Expand Up @@ -85,7 +84,7 @@ static int try_error(lua_State *L){
else{
lua_pushvalue(L, -2);
}
lua_rawsetp(L, -2, TRY_ERROR_IDX);
lua_rawsetp(L, -2, TRY_ERROR_NIL);
return lua_error(L);
}

Expand Down Expand Up @@ -198,5 +197,8 @@ EXPORT_API int luaopen_try(lua_State *L) {
lua_pushcclosure(L, try_assert, 1);
lua_setfield(L, -2, "assert");

lua_pushlightuserdata(L, (void*)TRY_ERROR_NIL);
lua_setfield(L, -2, "NIL");

return 1;
}
6 changes: 5 additions & 1 deletion test/test.lua
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,11 @@ end)

end

local _ENV = TEST_CASE'try.coro' if ENABLE and not IS_LUA_51 then
local _ENV = TEST_CASE'try.coro' if ENABLE then

local try = try

if IS_LUA_51 then try = require "try.co" end

local it = setmetatable(_ENV or _M, {__call = function(self, describe, fn)
self["test " .. describe] = fn
Expand Down

0 comments on commit 60af1d7

Please sign in to comment.