aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2002-06-25 16:19:33 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2002-06-25 16:19:33 -0300
commit25dc9b7fafe608c428a0950986ea8a1cb4dd7fa9 (patch)
tree6ef74ba74e88237b0ed2619b5c9a797b8758e7c7
parent78c507b7b83a85c106b619ce2050725a80627a25 (diff)
downloadlua-25dc9b7fafe608c428a0950986ea8a1cb4dd7fa9.tar.gz
lua-25dc9b7fafe608c428a0950986ea8a1cb4dd7fa9.tar.bz2
lua-25dc9b7fafe608c428a0950986ea8a1cb4dd7fa9.zip
new functions `dofile' and `pairs'; correct way to check proxies
-rw-r--r--lbaselib.c72
1 files changed, 50 insertions, 22 deletions
diff --git a/lbaselib.c b/lbaselib.c
index 343e0b48..85f658db 100644
--- a/lbaselib.c
+++ b/lbaselib.c
@@ -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
84static int luaB_getmetatable (lua_State *L) { 84static 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
185static int luaB_nexti (lua_State *L) { 187static 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
196static 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
239static 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
228static int luaB_assert (lua_State *L) { 248static 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
296static int luaB_newproxy (lua_State *L) { 316static 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