diff --git a/lakefile b/lakefile index 3e5b31f..44e01d5 100644 --- a/lakefile +++ b/lakefile @@ -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 }; }) diff --git a/rockspecs/try-scm-0.rockspec b/rockspecs/try-scm-0.rockspec index 1694465..4632787 100644 --- a/rockspecs/try-scm-0.rockspec +++ b/rockspecs/try-scm-0.rockspec @@ -28,5 +28,6 @@ build = { try = { sources = { "src/try.c" }, }, + ["try.co"] = "src/lua/try/co.lua", } } diff --git a/src/lua/try/co.lua b/src/lua/try/co.lua new file mode 100644 index 0000000..23cb92f --- /dev/null +++ b/src/lua/try/co.lua @@ -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}) diff --git a/src/try.c b/src/try.c index da412b9..c8072a9 100644 --- a/src/try.c +++ b/src/try.c @@ -14,7 +14,6 @@ # define EXPORT_API LUALIB_API #endif -static const char *TRY_ERROR_IDX = "Dummy"; static const char *TRY_ERROR_NIL = "NIL"; /*=========================================================================*\ @@ -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); @@ -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); } @@ -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; } diff --git a/test/test.lua b/test/test.lua index bc97c07..1020cf5 100644 --- a/test/test.lua +++ b/test/test.lua @@ -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