diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-06-25 16:19:33 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-06-25 16:19:33 -0300 |
commit | 25dc9b7fafe608c428a0950986ea8a1cb4dd7fa9 (patch) | |
tree | 6ef74ba74e88237b0ed2619b5c9a797b8758e7c7 | |
parent | 78c507b7b83a85c106b619ce2050725a80627a25 (diff) | |
download | lua-25dc9b7fafe608c428a0950986ea8a1cb4dd7fa9.tar.gz lua-25dc9b7fafe608c428a0950986ea8a1cb4dd7fa9.tar.bz2 lua-25dc9b7fafe608c428a0950986ea8a1cb4dd7fa9.zip |
new functions `dofile' and `pairs'; correct way to check proxies
-rw-r--r-- | lbaselib.c | 72 |
1 files changed, 50 insertions, 22 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lbaselib.c,v 1.83 2002/06/20 20:41:46 roberto Exp roberto $ | 2 | ** $Id: lbaselib.c,v 1.84 2002/06/24 17:23:16 roberto Exp roberto $ |
3 | ** Basic library | 3 | ** Basic library |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -34,7 +34,7 @@ static int luaB_print (lua_State *L) { | |||
34 | const char *s; | 34 | const char *s; |
35 | lua_pushvalue(L, -1); /* function to be called */ | 35 | lua_pushvalue(L, -1); /* function to be called */ |
36 | lua_pushvalue(L, i); /* value to print */ | 36 | lua_pushvalue(L, i); /* value to print */ |
37 | lua_upcall(L, 1, 1); | 37 | lua_call(L, 1, 1); |
38 | s = lua_tostring(L, -1); /* get result */ | 38 | s = lua_tostring(L, -1); /* get result */ |
39 | if (s == NULL) | 39 | if (s == NULL) |
40 | return luaL_error(L, "`tostring' must return a string to `print'"); | 40 | return luaL_error(L, "`tostring' must return a string to `print'"); |
@@ -83,8 +83,10 @@ static int luaB_error (lua_State *L) { | |||
83 | 83 | ||
84 | static int luaB_getmetatable (lua_State *L) { | 84 | static int luaB_getmetatable (lua_State *L) { |
85 | luaL_check_any(L, 1); | 85 | luaL_check_any(L, 1); |
86 | if (!lua_getmetatable(L, 1)) | 86 | if (!lua_getmetatable(L, 1)) { |
87 | return 0; /* no metatable */ | 87 | lua_pushnil(L); |
88 | return 1; /* no metatable */ | ||
89 | } | ||
88 | else { | 90 | else { |
89 | lua_pushliteral(L, "__metatable"); | 91 | lua_pushliteral(L, "__metatable"); |
90 | lua_rawget(L, -2); | 92 | lua_rawget(L, -2); |
@@ -182,11 +184,20 @@ static int luaB_next (lua_State *L) { | |||
182 | } | 184 | } |
183 | 185 | ||
184 | 186 | ||
185 | static int luaB_nexti (lua_State *L) { | 187 | static int luaB_pairs (lua_State *L) { |
188 | luaL_check_type(L, 1, LUA_TTABLE); | ||
189 | lua_getglobal(L, "next"); /* return generator, */ | ||
190 | lua_pushvalue(L, 1); /* state, */ | ||
191 | lua_pushnil(L); /* and initial value */ | ||
192 | return 3; | ||
193 | } | ||
194 | |||
195 | |||
196 | static int luaB_ipairs (lua_State *L) { | ||
186 | lua_Number i = lua_tonumber(L, 2); | 197 | lua_Number i = lua_tonumber(L, 2); |
187 | luaL_check_type(L, 1, LUA_TTABLE); | 198 | luaL_check_type(L, 1, LUA_TTABLE); |
188 | if (i == 0 && lua_isnull(L, 2)) { /* `for' start? */ | 199 | if (i == 0 && lua_isnull(L, 2)) { /* `for' start? */ |
189 | lua_getglobal(L, "nexti"); /* return generator, */ | 200 | lua_getglobal(L, "ipairs"); /* return generator, */ |
190 | lua_pushvalue(L, 1); /* state, */ | 201 | lua_pushvalue(L, 1); /* state, */ |
191 | lua_pushnumber(L, 0); /* and initial value */ | 202 | lua_pushnumber(L, 0); /* and initial value */ |
192 | return 3; | 203 | return 3; |
@@ -225,6 +236,15 @@ static int luaB_loadfile (lua_State *L) { | |||
225 | } | 236 | } |
226 | 237 | ||
227 | 238 | ||
239 | static int luaB_dofile (lua_State *L) { | ||
240 | const char *fname = luaL_opt_string(L, 1, NULL); | ||
241 | int status = luaL_loadfile(L, fname); | ||
242 | if (status != 0) lua_error(L); | ||
243 | lua_call(L, 0, LUA_MULTRET); | ||
244 | return lua_gettop(L) - 1; | ||
245 | } | ||
246 | |||
247 | |||
228 | static int luaB_assert (lua_State *L) { | 248 | static int luaB_assert (lua_State *L) { |
229 | luaL_check_any(L, 1); | 249 | luaL_check_any(L, 1); |
230 | if (!lua_toboolean(L, 1)) | 250 | if (!lua_toboolean(L, 1)) |
@@ -294,21 +314,27 @@ static int luaB_tostring (lua_State *L) { | |||
294 | 314 | ||
295 | 315 | ||
296 | static int luaB_newproxy (lua_State *L) { | 316 | static int luaB_newproxy (lua_State *L) { |
297 | void *u; | 317 | static const char dummy = '\0'; |
298 | lua_pushnil(L); /* default argument (if there is nothing at stack[1]) */ | 318 | lua_settop(L, 1); |
299 | u = lua_newuserdata(L, sizeof(lua_CFunction)); /* create proxy */ | 319 | luaL_weakregistry(L); /* get weak registry */ |
300 | *(lua_CFunction *)u = luaB_newproxy; /* mark it as a proxy */ | 320 | lua_newuserdata(L, 0); /* create proxy */ |
301 | if (lua_toboolean(L, 1) == 0) | 321 | if (lua_toboolean(L, 1) == 0) |
302 | return 1; /* no metatable */ | 322 | return 1; /* no metatable */ |
303 | else if ((u = lua_touserdata(L, 1)) != NULL) { | 323 | else if (lua_isboolean(L, 1)) { |
304 | luaL_arg_check(L, *(lua_CFunction *)u == luaB_newproxy, 1, "invalid proxy"); | 324 | lua_newtable(L); /* create a new metatable `m' ... */ |
305 | lua_getmetatable(L, 1); /* reuse metatable */ | 325 | lua_pushvalue(L, -1); /* ... and mark `m' as a valid metatable */ |
326 | lua_pushudataval(L, (void *)&dummy); | ||
327 | lua_rawset(L, 2); /* weakregistry[m] = &dummy */ | ||
306 | } | 328 | } |
307 | else { | 329 | else { |
308 | luaL_check_type(L, 1, LUA_TBOOLEAN); | 330 | if (lua_getmetatable(L, 1)) /* check whether registry[m] == &dummy */ |
309 | lua_newtable(L); /* create a new metatable */ | 331 | lua_rawget(L, 2); |
332 | luaL_arg_check(L, (char *)lua_touserdata(L, -1) == &dummy, 1, | ||
333 | "boolean/proxy expected"); | ||
334 | lua_getmetatable(L, 1); /* metatable is valid */ | ||
310 | } | 335 | } |
311 | lua_setmetatable(L, -2); | 336 | lua_setmetatable(L, 3); |
337 | lua_pushvalue(L, 3); | ||
312 | return 1; | 338 | return 1; |
313 | } | 339 | } |
314 | 340 | ||
@@ -380,7 +406,7 @@ static int luaB_require (lua_State *L) { | |||
380 | if (!lua_istable(L, 2)) return luaL_error(L, REQTAB " is not a table"); | 406 | if (!lua_istable(L, 2)) return luaL_error(L, REQTAB " is not a table"); |
381 | path = getpath(L); | 407 | path = getpath(L); |
382 | lua_pushvalue(L, 1); /* check package's name in book-keeping table */ | 408 | lua_pushvalue(L, 1); /* check package's name in book-keeping table */ |
383 | lua_gettable(L, 2); | 409 | lua_rawget(L, 2); |
384 | if (!lua_isnil(L, -1)) /* is it there? */ | 410 | if (!lua_isnil(L, -1)) /* is it there? */ |
385 | return 0; /* package is already loaded */ | 411 | return 0; /* package is already loaded */ |
386 | else { /* must load it */ | 412 | else { /* must load it */ |
@@ -393,10 +419,10 @@ static int luaB_require (lua_State *L) { | |||
393 | } | 419 | } |
394 | switch (status) { | 420 | switch (status) { |
395 | case 0: { | 421 | case 0: { |
396 | lua_upcall(L, 0, 0); /* run loaded module */ | 422 | lua_call(L, 0, 0); /* run loaded module */ |
397 | lua_pushvalue(L, 1); | 423 | lua_pushvalue(L, 1); |
398 | lua_pushboolean(L, 1); | 424 | lua_pushboolean(L, 1); |
399 | lua_settable(L, 2); /* mark it as loaded */ | 425 | lua_rawset(L, 2); /* mark it as loaded */ |
400 | return 0; | 426 | return 0; |
401 | } | 427 | } |
402 | case LUA_ERRFILE: { /* file not found */ | 428 | case LUA_ERRFILE: { /* file not found */ |
@@ -419,7 +445,8 @@ static const luaL_reg base_funcs[] = { | |||
419 | {"getglobals", luaB_getglobals}, | 445 | {"getglobals", luaB_getglobals}, |
420 | {"setglobals", luaB_setglobals}, | 446 | {"setglobals", luaB_setglobals}, |
421 | {"next", luaB_next}, | 447 | {"next", luaB_next}, |
422 | {"nexti", luaB_nexti}, | 448 | {"ipairs", luaB_ipairs}, |
449 | {"pairs", luaB_pairs}, | ||
423 | {"print", luaB_print}, | 450 | {"print", luaB_print}, |
424 | {"tonumber", luaB_tonumber}, | 451 | {"tonumber", luaB_tonumber}, |
425 | {"tostring", luaB_tostring}, | 452 | {"tostring", luaB_tostring}, |
@@ -434,6 +461,7 @@ static const luaL_reg base_funcs[] = { | |||
434 | {"collectgarbage", luaB_collectgarbage}, | 461 | {"collectgarbage", luaB_collectgarbage}, |
435 | {"gcinfo", luaB_gcinfo}, | 462 | {"gcinfo", luaB_gcinfo}, |
436 | {"loadfile", luaB_loadfile}, | 463 | {"loadfile", luaB_loadfile}, |
464 | {"dofile", luaB_dofile}, | ||
437 | {"loadstring", luaB_loadstring}, | 465 | {"loadstring", luaB_loadstring}, |
438 | {"require", luaB_require}, | 466 | {"require", luaB_require}, |
439 | {NULL, NULL} | 467 | {NULL, NULL} |
@@ -531,8 +559,8 @@ static void base_open (lua_State *L) { | |||
531 | luaL_openlib(L, base_funcs, 0); /* open lib into global table */ | 559 | luaL_openlib(L, base_funcs, 0); /* open lib into global table */ |
532 | lua_pushliteral(L, "_VERSION"); | 560 | lua_pushliteral(L, "_VERSION"); |
533 | lua_pushliteral(L, LUA_VERSION); | 561 | lua_pushliteral(L, LUA_VERSION); |
534 | lua_settable(L, -3); /* set global _VERSION */ | 562 | lua_rawset(L, -3); /* set global _VERSION */ |
535 | lua_settable(L, -1); /* set global _G */ | 563 | lua_rawset(L, -1); /* set global _G */ |
536 | } | 564 | } |
537 | 565 | ||
538 | 566 | ||