mirror of https://github.com/lua/lua
new functions `dofile' and `pairs'; correct way to check proxies
This commit is contained in:
parent
78c507b7b8
commit
25dc9b7faf
72
lbaselib.c
72
lbaselib.c
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
** $Id: lbaselib.c,v 1.83 2002/06/20 20:41:46 roberto Exp roberto $
|
** $Id: lbaselib.c,v 1.84 2002/06/24 17:23:16 roberto Exp roberto $
|
||||||
** Basic library
|
** Basic library
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
|
@ -34,7 +34,7 @@ static int luaB_print (lua_State *L) {
|
||||||
const char *s;
|
const char *s;
|
||||||
lua_pushvalue(L, -1); /* function to be called */
|
lua_pushvalue(L, -1); /* function to be called */
|
||||||
lua_pushvalue(L, i); /* value to print */
|
lua_pushvalue(L, i); /* value to print */
|
||||||
lua_upcall(L, 1, 1);
|
lua_call(L, 1, 1);
|
||||||
s = lua_tostring(L, -1); /* get result */
|
s = lua_tostring(L, -1); /* get result */
|
||||||
if (s == NULL)
|
if (s == NULL)
|
||||||
return luaL_error(L, "`tostring' must return a string to `print'");
|
return luaL_error(L, "`tostring' must return a string to `print'");
|
||||||
|
@ -83,8 +83,10 @@ static int luaB_error (lua_State *L) {
|
||||||
|
|
||||||
static int luaB_getmetatable (lua_State *L) {
|
static int luaB_getmetatable (lua_State *L) {
|
||||||
luaL_check_any(L, 1);
|
luaL_check_any(L, 1);
|
||||||
if (!lua_getmetatable(L, 1))
|
if (!lua_getmetatable(L, 1)) {
|
||||||
return 0; /* no metatable */
|
lua_pushnil(L);
|
||||||
|
return 1; /* no metatable */
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
lua_pushliteral(L, "__metatable");
|
lua_pushliteral(L, "__metatable");
|
||||||
lua_rawget(L, -2);
|
lua_rawget(L, -2);
|
||||||
|
@ -182,11 +184,20 @@ static int luaB_next (lua_State *L) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int luaB_nexti (lua_State *L) {
|
static int luaB_pairs (lua_State *L) {
|
||||||
|
luaL_check_type(L, 1, LUA_TTABLE);
|
||||||
|
lua_getglobal(L, "next"); /* return generator, */
|
||||||
|
lua_pushvalue(L, 1); /* state, */
|
||||||
|
lua_pushnil(L); /* and initial value */
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int luaB_ipairs (lua_State *L) {
|
||||||
lua_Number i = lua_tonumber(L, 2);
|
lua_Number i = lua_tonumber(L, 2);
|
||||||
luaL_check_type(L, 1, LUA_TTABLE);
|
luaL_check_type(L, 1, LUA_TTABLE);
|
||||||
if (i == 0 && lua_isnull(L, 2)) { /* `for' start? */
|
if (i == 0 && lua_isnull(L, 2)) { /* `for' start? */
|
||||||
lua_getglobal(L, "nexti"); /* return generator, */
|
lua_getglobal(L, "ipairs"); /* return generator, */
|
||||||
lua_pushvalue(L, 1); /* state, */
|
lua_pushvalue(L, 1); /* state, */
|
||||||
lua_pushnumber(L, 0); /* and initial value */
|
lua_pushnumber(L, 0); /* and initial value */
|
||||||
return 3;
|
return 3;
|
||||||
|
@ -225,6 +236,15 @@ static int luaB_loadfile (lua_State *L) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int luaB_dofile (lua_State *L) {
|
||||||
|
const char *fname = luaL_opt_string(L, 1, NULL);
|
||||||
|
int status = luaL_loadfile(L, fname);
|
||||||
|
if (status != 0) lua_error(L);
|
||||||
|
lua_call(L, 0, LUA_MULTRET);
|
||||||
|
return lua_gettop(L) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int luaB_assert (lua_State *L) {
|
static int luaB_assert (lua_State *L) {
|
||||||
luaL_check_any(L, 1);
|
luaL_check_any(L, 1);
|
||||||
if (!lua_toboolean(L, 1))
|
if (!lua_toboolean(L, 1))
|
||||||
|
@ -294,21 +314,27 @@ static int luaB_tostring (lua_State *L) {
|
||||||
|
|
||||||
|
|
||||||
static int luaB_newproxy (lua_State *L) {
|
static int luaB_newproxy (lua_State *L) {
|
||||||
void *u;
|
static const char dummy = '\0';
|
||||||
lua_pushnil(L); /* default argument (if there is nothing at stack[1]) */
|
lua_settop(L, 1);
|
||||||
u = lua_newuserdata(L, sizeof(lua_CFunction)); /* create proxy */
|
luaL_weakregistry(L); /* get weak registry */
|
||||||
*(lua_CFunction *)u = luaB_newproxy; /* mark it as a proxy */
|
lua_newuserdata(L, 0); /* create proxy */
|
||||||
if (lua_toboolean(L, 1) == 0)
|
if (lua_toboolean(L, 1) == 0)
|
||||||
return 1; /* no metatable */
|
return 1; /* no metatable */
|
||||||
else if ((u = lua_touserdata(L, 1)) != NULL) {
|
else if (lua_isboolean(L, 1)) {
|
||||||
luaL_arg_check(L, *(lua_CFunction *)u == luaB_newproxy, 1, "invalid proxy");
|
lua_newtable(L); /* create a new metatable `m' ... */
|
||||||
lua_getmetatable(L, 1); /* reuse metatable */
|
lua_pushvalue(L, -1); /* ... and mark `m' as a valid metatable */
|
||||||
|
lua_pushudataval(L, (void *)&dummy);
|
||||||
|
lua_rawset(L, 2); /* weakregistry[m] = &dummy */
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
luaL_check_type(L, 1, LUA_TBOOLEAN);
|
if (lua_getmetatable(L, 1)) /* check whether registry[m] == &dummy */
|
||||||
lua_newtable(L); /* create a new metatable */
|
lua_rawget(L, 2);
|
||||||
|
luaL_arg_check(L, (char *)lua_touserdata(L, -1) == &dummy, 1,
|
||||||
|
"boolean/proxy expected");
|
||||||
|
lua_getmetatable(L, 1); /* metatable is valid */
|
||||||
}
|
}
|
||||||
lua_setmetatable(L, -2);
|
lua_setmetatable(L, 3);
|
||||||
|
lua_pushvalue(L, 3);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -380,7 +406,7 @@ static int luaB_require (lua_State *L) {
|
||||||
if (!lua_istable(L, 2)) return luaL_error(L, REQTAB " is not a table");
|
if (!lua_istable(L, 2)) return luaL_error(L, REQTAB " is not a table");
|
||||||
path = getpath(L);
|
path = getpath(L);
|
||||||
lua_pushvalue(L, 1); /* check package's name in book-keeping table */
|
lua_pushvalue(L, 1); /* check package's name in book-keeping table */
|
||||||
lua_gettable(L, 2);
|
lua_rawget(L, 2);
|
||||||
if (!lua_isnil(L, -1)) /* is it there? */
|
if (!lua_isnil(L, -1)) /* is it there? */
|
||||||
return 0; /* package is already loaded */
|
return 0; /* package is already loaded */
|
||||||
else { /* must load it */
|
else { /* must load it */
|
||||||
|
@ -393,10 +419,10 @@ static int luaB_require (lua_State *L) {
|
||||||
}
|
}
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case 0: {
|
case 0: {
|
||||||
lua_upcall(L, 0, 0); /* run loaded module */
|
lua_call(L, 0, 0); /* run loaded module */
|
||||||
lua_pushvalue(L, 1);
|
lua_pushvalue(L, 1);
|
||||||
lua_pushboolean(L, 1);
|
lua_pushboolean(L, 1);
|
||||||
lua_settable(L, 2); /* mark it as loaded */
|
lua_rawset(L, 2); /* mark it as loaded */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
case LUA_ERRFILE: { /* file not found */
|
case LUA_ERRFILE: { /* file not found */
|
||||||
|
@ -419,7 +445,8 @@ static const luaL_reg base_funcs[] = {
|
||||||
{"getglobals", luaB_getglobals},
|
{"getglobals", luaB_getglobals},
|
||||||
{"setglobals", luaB_setglobals},
|
{"setglobals", luaB_setglobals},
|
||||||
{"next", luaB_next},
|
{"next", luaB_next},
|
||||||
{"nexti", luaB_nexti},
|
{"ipairs", luaB_ipairs},
|
||||||
|
{"pairs", luaB_pairs},
|
||||||
{"print", luaB_print},
|
{"print", luaB_print},
|
||||||
{"tonumber", luaB_tonumber},
|
{"tonumber", luaB_tonumber},
|
||||||
{"tostring", luaB_tostring},
|
{"tostring", luaB_tostring},
|
||||||
|
@ -434,6 +461,7 @@ static const luaL_reg base_funcs[] = {
|
||||||
{"collectgarbage", luaB_collectgarbage},
|
{"collectgarbage", luaB_collectgarbage},
|
||||||
{"gcinfo", luaB_gcinfo},
|
{"gcinfo", luaB_gcinfo},
|
||||||
{"loadfile", luaB_loadfile},
|
{"loadfile", luaB_loadfile},
|
||||||
|
{"dofile", luaB_dofile},
|
||||||
{"loadstring", luaB_loadstring},
|
{"loadstring", luaB_loadstring},
|
||||||
{"require", luaB_require},
|
{"require", luaB_require},
|
||||||
{NULL, NULL}
|
{NULL, NULL}
|
||||||
|
@ -531,8 +559,8 @@ static void base_open (lua_State *L) {
|
||||||
luaL_openlib(L, base_funcs, 0); /* open lib into global table */
|
luaL_openlib(L, base_funcs, 0); /* open lib into global table */
|
||||||
lua_pushliteral(L, "_VERSION");
|
lua_pushliteral(L, "_VERSION");
|
||||||
lua_pushliteral(L, LUA_VERSION);
|
lua_pushliteral(L, LUA_VERSION);
|
||||||
lua_settable(L, -3); /* set global _VERSION */
|
lua_rawset(L, -3); /* set global _VERSION */
|
||||||
lua_settable(L, -1); /* set global _G */
|
lua_rawset(L, -1); /* set global _G */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue