📄 lbaselib.c
字号:
static int luaB_dofile (lua_State *L) { const char *fname = luaL_optstring(L, 1, NULL); int n = lua_gettop(L); if (luaL_loadfile(L, fname) != 0) lua_error(L); lua_call(L, 0, LUA_MULTRET); return lua_gettop(L) - n;}static int luaB_assert (lua_State *L) { luaL_checkany(L, 1); if (!lua_toboolean(L, 1)) return luaL_error(L, "%s", luaL_optstring(L, 2, "assertion failed!")); return lua_gettop(L);}static int luaB_unpack (lua_State *L) { int i, e, n; luaL_checktype(L, 1, LUA_TTABLE); i = luaL_optint(L, 2, 1); e = luaL_opt(L, luaL_checkint, 3, luaL_getn(L, 1)); n = e - i + 1; /* number of elements */ if (n <= 0) return 0; /* empty range */ luaL_checkstack(L, n, "table too big to unpack"); for (; i<=e; i++) /* push arg[i...e] */ lua_rawgeti(L, 1, i); return n;}static int luaB_select (lua_State *L) { int n = lua_gettop(L); if (lua_type(L, 1) == LUA_TSTRING && *lua_tostring(L, 1) == '#') { lua_pushinteger(L, n-1); return 1; } else { int i = luaL_checkint(L, 1); if (i < 0) i = n + i; else if (i > n) i = n; luaL_argcheck(L, 1 <= i, 1, "index out of range"); return n - i; }}static int luaB_pcall (lua_State *L) { int status; luaL_checkany(L, 1); status = lua_pcall(L, lua_gettop(L) - 1, LUA_MULTRET, 0); lua_pushboolean(L, (status == 0)); lua_insert(L, 1); return lua_gettop(L); /* return status + all results */}static int luaB_xpcall (lua_State *L) { int status; luaL_checkany(L, 2); lua_settop(L, 2); lua_insert(L, 1); /* put error function under function to be called */ status = lua_pcall(L, 0, LUA_MULTRET, 1); lua_pushboolean(L, (status == 0)); lua_replace(L, 1); return lua_gettop(L); /* return status + all results */}static int luaB_tostring (lua_State *L) { luaL_checkany(L, 1); if (luaL_callmeta(L, 1, "__tostring")) /* is there a metafield? */ return 1; /* use its value */ switch (lua_type(L, 1)) { case LUA_TNUMBER: lua_pushstring(L, lua_tostring(L, 1)); break; case LUA_TSTRING: lua_pushvalue(L, 1); break; case LUA_TBOOLEAN: lua_pushstring(L, (lua_toboolean(L, 1) ? "true" : "false")); break; case LUA_TNIL: lua_pushliteral(L, "nil"); break; default: lua_pushfstring(L, "%s: %p", luaL_typename(L, 1), lua_topointer(L, 1)); break; } return 1;}static int luaB_newproxy (lua_State *L) { lua_settop(L, 1); lua_newuserdata(L, 0); /* create proxy */ if (lua_toboolean(L, 1) == 0) return 1; /* no metatable */ else if (lua_isboolean(L, 1)) { lua_newtable(L); /* create a new metatable `m' ... */ lua_pushvalue(L, -1); /* ... and mark `m' as a valid metatable */ lua_pushboolean(L, 1); lua_rawset(L, lua_upvalueindex(1)); /* weaktable[m] = true */ } else { int validproxy = 0; /* to check if weaktable[metatable(u)] == true */ if (lua_getmetatable(L, 1)) { lua_rawget(L, lua_upvalueindex(1)); validproxy = lua_toboolean(L, -1); lua_pop(L, 1); /* remove value */ } luaL_argcheck(L, validproxy, 1, "boolean or proxy expected"); lua_getmetatable(L, 1); /* metatable is valid; get it */ } lua_setmetatable(L, 2); return 1;}static const luaL_Reg base_funcs[] = { {"assert", luaB_assert}, {"collectgarbage", luaB_collectgarbage}, {"dofile", luaB_dofile}, {"error", luaB_error}, {"gcinfo", luaB_gcinfo}, {"getfenv", luaB_getfenv}, {"getmetatable", luaB_getmetatable}, {"loadfile", luaB_loadfile}, {"load", luaB_load}, {"loadstring", luaB_loadstring}, {"next", luaB_next}, {"pcall", luaB_pcall}, {"print", luaB_print}, {"rawequal", luaB_rawequal}, {"rawget", luaB_rawget}, {"rawset", luaB_rawset}, {"select", luaB_select}, {"setfenv", luaB_setfenv}, {"setmetatable", luaB_setmetatable}, {"tonumber", luaB_tonumber}, {"tostring", luaB_tostring}, {"type", luaB_type}, {"unpack", luaB_unpack}, {"xpcall", luaB_xpcall}, {NULL, NULL}};/*** {======================================================** Coroutine library** =======================================================*/static int auxresume (lua_State *L, lua_State *co, int narg) { int status; if (!lua_checkstack(co, narg)) luaL_error(L, "too many arguments to resume"); if (lua_status(co) == 0 && lua_gettop(co) == 0) { lua_pushliteral(L, "cannot resume dead coroutine"); return -1; /* error flag */ } lua_xmove(L, co, narg); status = lua_resume(co, narg); if (status == 0 || status == LUA_YIELD) { int nres = lua_gettop(co); if (!lua_checkstack(L, nres)) luaL_error(L, "too many results to resume"); lua_xmove(co, L, nres); /* move yielded values */ return nres; } else { lua_xmove(co, L, 1); /* move error message */ return -1; /* error flag */ }}static int luaB_coresume (lua_State *L) { lua_State *co = lua_tothread(L, 1); int r; luaL_argcheck(L, co, 1, "coroutine expected"); r = auxresume(L, co, lua_gettop(L) - 1); if (r < 0) { lua_pushboolean(L, 0); lua_insert(L, -2); return 2; /* return false + error message */ } else { lua_pushboolean(L, 1); lua_insert(L, -(r + 1)); return r + 1; /* return true + `resume' returns */ }}static int luaB_auxwrap (lua_State *L) { lua_State *co = lua_tothread(L, lua_upvalueindex(1)); int r = auxresume(L, co, lua_gettop(L)); if (r < 0) { if (lua_isstring(L, -1)) { /* error object is a string? */ luaL_where(L, 1); /* add extra info */ lua_insert(L, -2); lua_concat(L, 2); } lua_error(L); /* propagate error */ } return r;}static int luaB_cocreate (lua_State *L) { lua_State *NL = lua_newthread(L); luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), 1, "Lua function expected"); lua_pushvalue(L, 1); /* move function to top */ lua_xmove(L, NL, 1); /* move function from L to NL */ return 1;}static int luaB_cowrap (lua_State *L) { luaB_cocreate(L); lua_pushcclosure(L, luaB_auxwrap, 1); return 1;}static int luaB_yield (lua_State *L) { return lua_yield(L, lua_gettop(L));}static int luaB_costatus (lua_State *L) { lua_State *co = lua_tothread(L, 1); luaL_argcheck(L, co, 1, "coroutine expected"); if (L == co) lua_pushliteral(L, "running"); else { switch (lua_status(co)) { case LUA_YIELD: lua_pushliteral(L, "suspended"); break; case 0: { lua_Debug ar; if (lua_getstack(co, 0, &ar) > 0) /* does it have frames? */ lua_pushliteral(L, "normal"); /* it is running */ else if (lua_gettop(co) == 0) lua_pushliteral(L, "dead"); else lua_pushliteral(L, "suspended"); /* initial state */ break; } default: /* some error occured */ lua_pushliteral(L, "dead"); break; } } return 1;}static int luaB_corunning (lua_State *L) { if (lua_pushthread(L)) return 0; /* main thread is not a coroutine */ else return 1;}static const luaL_Reg co_funcs[] = { {"create", luaB_cocreate}, {"resume", luaB_coresume}, {"running", luaB_corunning}, {"status", luaB_costatus}, {"wrap", luaB_cowrap}, {"yield", luaB_yield}, {NULL, NULL}};/* }====================================================== */static void auxopen (lua_State *L, const char *name, lua_CFunction f, lua_CFunction u) { lua_pushcfunction(L, u); lua_pushcclosure(L, f, 1); lua_setfield(L, -2, name);}static void base_open (lua_State *L) { /* set global _G */ lua_pushvalue(L, LUA_GLOBALSINDEX); lua_setglobal(L, "_G"); /* open lib into global table */ luaL_register(L, "_G", base_funcs); lua_pushliteral(L, LUA_VERSION); lua_setglobal(L, "_VERSION"); /* set global _VERSION */ /* `ipairs' and `pairs' need auxliliary functions as upvalues */ auxopen(L, "ipairs", luaB_ipairs, ipairsaux); auxopen(L, "pairs", luaB_pairs, luaB_next); /* `newproxy' needs a weaktable as upvalue */ lua_createtable(L, 0, 1); /* new table `w' */ lua_pushvalue(L, -1); /* `w' will be its own metatable */ lua_setmetatable(L, -2); lua_pushliteral(L, "kv"); lua_setfield(L, -2, "__mode"); /* metatable(w).__mode = "kv" */ lua_pushcclosure(L, luaB_newproxy, 1); lua_setglobal(L, "newproxy"); /* set global `newproxy' */}LUALIB_API int luaopen_base (lua_State *L) { base_open(L); luaL_register(L, LUA_COLIBNAME, co_funcs); return 2;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -