diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2000-08-31 18:01:43 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2000-08-31 18:01:43 -0300 |
| commit | 9a21e81907e49b79ec44677660acf9e35ad308bb (patch) | |
| tree | b9abf9711461f3c0d798f8b9e23a4926961b6713 | |
| parent | f0b3cd1d6f35ba34091450d5e3057269114a17b6 (diff) | |
| download | lua-9a21e81907e49b79ec44677660acf9e35ad308bb.tar.gz lua-9a21e81907e49b79ec44677660acf9e35ad308bb.tar.bz2 lua-9a21e81907e49b79ec44677660acf9e35ad308bb.zip | |
more builtin functions using official API
| -rw-r--r-- | lapi.c | 48 | ||||
| -rw-r--r-- | lbuiltin.c | 159 | ||||
| -rw-r--r-- | lua.h | 4 |
3 files changed, 115 insertions, 96 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lapi.c,v 1.91 2000/08/31 14:08:27 roberto Exp roberto $ | 2 | ** $Id: lapi.c,v 1.92 2000/08/31 20:23:40 roberto Exp roberto $ |
| 3 | ** Lua API | 3 | ** Lua API |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -167,6 +167,23 @@ void *lua_touserdata (lua_State *L, int index) { | |||
| 167 | access(L, index, (ttype(o) == TAG_USERDATA), NULL, tsvalue(o)->u.d.value); | 167 | access(L, index, (ttype(o) == TAG_USERDATA), NULL, tsvalue(o)->u.d.value); |
| 168 | } | 168 | } |
| 169 | 169 | ||
| 170 | const void *lua_topointer (lua_State *L, int index) { | ||
| 171 | const TObject *o = Index(L, index); | ||
| 172 | switch (ttype(o)) { | ||
| 173 | case TAG_NUMBER: case TAG_NIL: | ||
| 174 | return NULL; | ||
| 175 | case TAG_STRING: | ||
| 176 | return tsvalue(o)->str; | ||
| 177 | case TAG_USERDATA: | ||
| 178 | return tsvalue(o)->u.d.value; | ||
| 179 | case TAG_TABLE: | ||
| 180 | return hvalue(o); | ||
| 181 | case TAG_CCLOSURE: case TAG_LCLOSURE: | ||
| 182 | return clvalue(o); | ||
| 183 | default: return NULL; | ||
| 184 | } | ||
| 185 | } | ||
| 186 | |||
| 170 | 187 | ||
| 171 | 188 | ||
| 172 | /* | 189 | /* |
| @@ -236,7 +253,7 @@ void lua_gettable (lua_State *L) { | |||
| 236 | 253 | ||
| 237 | 254 | ||
| 238 | void lua_rawget (lua_State *L) { | 255 | void lua_rawget (lua_State *L) { |
| 239 | LUA_ASSERT(ttype(L->top-2) == TAG_TABLE, "not a table"); | 256 | LUA_ASSERT(ttype(L->top-2) == TAG_TABLE, "table expected"); |
| 240 | *(L->top - 2) = *luaH_get(L, hvalue(L->top - 2), L->top - 1); | 257 | *(L->top - 2) = *luaH_get(L, hvalue(L->top - 2), L->top - 1); |
| 241 | L->top--; | 258 | L->top--; |
| 242 | } | 259 | } |
| @@ -295,7 +312,7 @@ void lua_settable (lua_State *L) { | |||
| 295 | 312 | ||
| 296 | 313 | ||
| 297 | void lua_rawset (lua_State *L) { | 314 | void lua_rawset (lua_State *L) { |
| 298 | LUA_ASSERT(ttype(L->top-3) == TAG_TABLE, "not a table"); | 315 | LUA_ASSERT(ttype(L->top-3) == TAG_TABLE, "table expected"); |
| 299 | *luaH_set(L, hvalue(L->top-3), L->top-2) = *(L->top-1); | 316 | *luaH_set(L, hvalue(L->top-3), L->top-2) = *(L->top-1); |
| 300 | L->top -= 3; | 317 | L->top -= 3; |
| 301 | } | 318 | } |
| @@ -303,7 +320,7 @@ void lua_rawset (lua_State *L) { | |||
| 303 | 320 | ||
| 304 | void lua_setglobals (lua_State *L) { | 321 | void lua_setglobals (lua_State *L) { |
| 305 | TObject *newtable = --L->top; | 322 | TObject *newtable = --L->top; |
| 306 | LUA_ASSERT(ttype(newtable) == TAG_TABLE, "not a table"); | 323 | LUA_ASSERT(ttype(newtable) == TAG_TABLE, "table expected"); |
| 307 | L->gt = hvalue(newtable); | 324 | L->gt = hvalue(newtable); |
| 308 | } | 325 | } |
| 309 | 326 | ||
| @@ -375,7 +392,7 @@ void lua_unref (lua_State *L, int ref) { | |||
| 375 | int lua_next (lua_State *L) { | 392 | int lua_next (lua_State *L) { |
| 376 | const TObject *t = Index(L, -2); | 393 | const TObject *t = Index(L, -2); |
| 377 | Node *n; | 394 | Node *n; |
| 378 | LUA_ASSERT(ttype(t) == TAG_TABLE, "object is not a table in `lua_next'"); | 395 | LUA_ASSERT(ttype(t) == TAG_TABLE, "table expected"); |
| 379 | n = luaH_next(L, hvalue(t), Index(L, -1)); | 396 | n = luaH_next(L, hvalue(t), Index(L, -1)); |
| 380 | if (n) { | 397 | if (n) { |
| 381 | *(L->top-1) = *key(n); | 398 | *(L->top-1) = *key(n); |
| @@ -389,3 +406,24 @@ int lua_next (lua_State *L) { | |||
| 389 | } | 406 | } |
| 390 | } | 407 | } |
| 391 | 408 | ||
| 409 | |||
| 410 | int lua_getn (lua_State *L, int index) { | ||
| 411 | Hash *h = hvalue(Index(L, index)); | ||
| 412 | const TObject *value = luaH_getstr(h, luaS_new(L, "n")); /* value = h.n */ | ||
| 413 | if (ttype(value) == TAG_NUMBER) | ||
| 414 | return (int)nvalue(value); | ||
| 415 | else { | ||
| 416 | Number max = 0; | ||
| 417 | int i = h->size; | ||
| 418 | Node *n = h->node; | ||
| 419 | while (i--) { | ||
| 420 | if (ttype(key(n)) == TAG_NUMBER && | ||
| 421 | ttype(val(n)) != TAG_NIL && | ||
| 422 | nvalue(key(n)) > max) | ||
| 423 | max = nvalue(key(n)); | ||
| 424 | n++; | ||
| 425 | } | ||
| 426 | return (int)max; | ||
| 427 | } | ||
| 428 | } | ||
| 429 | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lbuiltin.c,v 1.126 2000/08/31 16:52:06 roberto Exp roberto $ | 2 | ** $Id: lbuiltin.c,v 1.127 2000/08/31 20:23:40 roberto Exp roberto $ |
| 3 | ** Built-in functions | 3 | ** Built-in functions |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -270,71 +270,15 @@ int luaB_dofile (lua_State *L) { | |||
| 270 | return passresults(L, lua_dofile(L, fname), oldtop); | 270 | return passresults(L, lua_dofile(L, fname), oldtop); |
| 271 | } | 271 | } |
| 272 | 272 | ||
| 273 | /* }====================================================== */ | ||
| 274 | |||
| 275 | |||
| 276 | /* | ||
| 277 | ** {====================================================== | ||
| 278 | ** Functions that could use only the official API but | ||
| 279 | ** do not, for efficiency. | ||
| 280 | ** ======================================================= | ||
| 281 | */ | ||
| 282 | |||
| 283 | #include "lapi.h" | ||
| 284 | #include "ldo.h" | ||
| 285 | #include "lmem.h" | ||
| 286 | #include "lobject.h" | ||
| 287 | #include "lstate.h" | ||
| 288 | #include "lstring.h" | ||
| 289 | #include "ltable.h" | ||
| 290 | #include "ltm.h" | ||
| 291 | #include "lvm.h" | ||
| 292 | |||
| 293 | |||
| 294 | /* | ||
| 295 | ** {====================================================== | ||
| 296 | ** Auxiliary functions | ||
| 297 | ** ======================================================= | ||
| 298 | */ | ||
| 299 | |||
| 300 | static Number getsize (const Hash *h) { | ||
| 301 | Number max = 0; | ||
| 302 | int i = h->size; | ||
| 303 | Node *n = h->node; | ||
| 304 | while (i--) { | ||
| 305 | if (ttype(key(n)) == TAG_NUMBER && | ||
| 306 | ttype(val(n)) != TAG_NIL && | ||
| 307 | nvalue(key(n)) > max) | ||
| 308 | max = nvalue(key(n)); | ||
| 309 | n++; | ||
| 310 | } | ||
| 311 | return max; | ||
| 312 | } | ||
| 313 | |||
| 314 | |||
| 315 | static Number getnarg (lua_State *L, const Hash *a) { | ||
| 316 | const TObject *value = luaH_getstr(a, luaS_new(L, "n")); /* value = a.n */ | ||
| 317 | return (ttype(value) == TAG_NUMBER) ? nvalue(value) : getsize(a); | ||
| 318 | } | ||
| 319 | |||
| 320 | |||
| 321 | static Hash *gettable (lua_State *L, int arg) { | ||
| 322 | luaL_checktype(L, arg, "table"); | ||
| 323 | return hvalue(luaA_index(L, arg)); | ||
| 324 | } | ||
| 325 | |||
| 326 | /* }====================================================== */ | ||
| 327 | |||
| 328 | |||
| 329 | |||
| 330 | 273 | ||
| 331 | int luaB_call (lua_State *L) { | 274 | int luaB_call (lua_State *L) { |
| 332 | int oldtop; | 275 | int oldtop; |
| 333 | const Hash *arg = gettable(L, 2); | ||
| 334 | const char *options = luaL_opt_string(L, 3, ""); | 276 | const char *options = luaL_opt_string(L, 3, ""); |
| 335 | int err = 0; /* index of old error method */ | 277 | int err = 0; /* index of old error method */ |
| 336 | int n = (int)getnarg(L, arg); | ||
| 337 | int i, status; | 278 | int i, status; |
| 279 | int n; | ||
| 280 | luaL_checktype(L, 2, "table"); | ||
| 281 | n = lua_getn(L, 2); | ||
| 338 | if (!lua_isnull(L, 4)) { /* set new error method */ | 282 | if (!lua_isnull(L, 4)) { /* set new error method */ |
| 339 | lua_getglobal(L, LUA_ERRORMESSAGE); | 283 | lua_getglobal(L, LUA_ERRORMESSAGE); |
| 340 | err = lua_gettop(L); /* get index */ | 284 | err = lua_gettop(L); /* get index */ |
| @@ -345,9 +289,12 @@ int luaB_call (lua_State *L) { | |||
| 345 | /* push function */ | 289 | /* push function */ |
| 346 | lua_pushobject(L, 1); | 290 | lua_pushobject(L, 1); |
| 347 | /* push arg[1...n] */ | 291 | /* push arg[1...n] */ |
| 348 | luaD_checkstack(L, n); | 292 | luaL_checkstack(L, n, "too many arguments"); |
| 349 | for (i=0; i<n; i++) | 293 | for (i=0; i<n; i++) { |
| 350 | *(L->top++) = *luaH_getnum(arg, i+1); | 294 | lua_pushobject(L, 2); |
| 295 | lua_pushnumber(L, i+1); | ||
| 296 | lua_rawget(L); | ||
| 297 | } | ||
| 351 | status = lua_call(L, n, LUA_MULTRET); | 298 | status = lua_call(L, n, LUA_MULTRET); |
| 352 | if (err != 0) { /* restore old error method */ | 299 | if (err != 0) { /* restore old error method */ |
| 353 | lua_pushobject(L, err); | 300 | lua_pushobject(L, err); |
| @@ -360,44 +307,35 @@ int luaB_call (lua_State *L) { | |||
| 360 | lua_error(L, NULL); /* propagate error without additional messages */ | 307 | lua_error(L, NULL); /* propagate error without additional messages */ |
| 361 | return 1; | 308 | return 1; |
| 362 | } | 309 | } |
| 363 | else { /* no errors */ | 310 | if (strchr(options, 'p')) /* pack results? */ |
| 364 | if (strchr(options, 'p')) { /* pack results? */ | 311 | lua_error(L, "deprecated option `p' in `call'"); |
| 365 | luaV_pack(L, luaA_index(L, oldtop+1)); | 312 | return lua_gettop(L) - oldtop; /* results are already on the stack */ |
| 366 | return 1; /* only table is returned */ | ||
| 367 | } | ||
| 368 | else | ||
| 369 | return lua_gettop(L) - oldtop; /* results are already on the stack */ | ||
| 370 | } | ||
| 371 | } | 313 | } |
| 372 | 314 | ||
| 373 | 315 | ||
| 374 | |||
| 375 | int luaB_tostring (lua_State *L) { | 316 | int luaB_tostring (lua_State *L) { |
| 376 | char buff[64]; | 317 | char buff[64]; |
| 377 | const TObject *o; | 318 | switch (lua_type(L, 1)[2]) { |
| 378 | luaL_checktype(L, 1, "any"); | 319 | case 'm': /* nuMber */ |
| 379 | o = luaA_index(L, 1); | ||
| 380 | switch (ttype(o)) { | ||
| 381 | case TAG_NUMBER: | ||
| 382 | lua_pushstring(L, lua_tostring(L, 1)); | 320 | lua_pushstring(L, lua_tostring(L, 1)); |
| 383 | return 1; | 321 | return 1; |
| 384 | case TAG_STRING: | 322 | case 'r': /* stRing */ |
| 385 | lua_pushobject(L, 1); | 323 | lua_pushobject(L, 1); |
| 386 | return 1; | 324 | return 1; |
| 387 | case TAG_TABLE: | 325 | case 'b': /* taBle */ |
| 388 | sprintf(buff, "table: %p", hvalue(o)); | 326 | sprintf(buff, "table: %p", lua_topointer(L, 1)); |
| 389 | break; | 327 | break; |
| 390 | case TAG_LCLOSURE: case TAG_CCLOSURE: | 328 | case 'n': /* fuNction */ |
| 391 | sprintf(buff, "function: %p", clvalue(o)); | 329 | sprintf(buff, "function: %p", lua_topointer(L, 1)); |
| 392 | break; | 330 | break; |
| 393 | case TAG_USERDATA: | 331 | case 'e': /* usErdata */ |
| 394 | sprintf(buff, "userdata(%d): %p", lua_tag(L, 1), lua_touserdata(L, 1)); | 332 | sprintf(buff, "userdata(%d): %p", lua_tag(L, 1), lua_touserdata(L, 1)); |
| 395 | break; | 333 | break; |
| 396 | case TAG_NIL: | 334 | case 'l': /* niL */ |
| 397 | lua_pushstring(L, "nil"); | 335 | lua_pushstring(L, "nil"); |
| 398 | return 1; | 336 | return 1; |
| 399 | default: | 337 | default: |
| 400 | LUA_INTERNALERROR("invalid type"); | 338 | luaL_argerror(L, 1, "value expected"); |
| 401 | } | 339 | } |
| 402 | lua_pushstring(L, buff); | 340 | lua_pushstring(L, buff); |
| 403 | return 1; | 341 | return 1; |
| @@ -406,6 +344,46 @@ int luaB_tostring (lua_State *L) { | |||
| 406 | /* }====================================================== */ | 344 | /* }====================================================== */ |
| 407 | 345 | ||
| 408 | 346 | ||
| 347 | /* | ||
| 348 | ** {====================================================== | ||
| 349 | ** Functions that could use only the official API but | ||
| 350 | ** do not, for efficiency. | ||
| 351 | ** ======================================================= | ||
| 352 | */ | ||
| 353 | |||
| 354 | #include "lapi.h" | ||
| 355 | #include "ldo.h" | ||
| 356 | #include "lmem.h" | ||
| 357 | #include "lobject.h" | ||
| 358 | #include "lstate.h" | ||
| 359 | #include "lstring.h" | ||
| 360 | #include "ltable.h" | ||
| 361 | #include "ltm.h" | ||
| 362 | #include "lvm.h" | ||
| 363 | |||
| 364 | |||
| 365 | /* | ||
| 366 | ** {====================================================== | ||
| 367 | ** Auxiliary functions | ||
| 368 | ** ======================================================= | ||
| 369 | */ | ||
| 370 | |||
| 371 | |||
| 372 | static Hash *gettable (lua_State *L, int arg) { | ||
| 373 | luaL_checktype(L, arg, "table"); | ||
| 374 | return hvalue(luaA_index(L, arg)); | ||
| 375 | } | ||
| 376 | |||
| 377 | /* }====================================================== */ | ||
| 378 | |||
| 379 | |||
| 380 | |||
| 381 | |||
| 382 | |||
| 383 | |||
| 384 | /* }====================================================== */ | ||
| 385 | |||
| 386 | |||
| 409 | 387 | ||
| 410 | /* | 388 | /* |
| 411 | ** {====================================================== | 389 | ** {====================================================== |
| @@ -426,7 +404,8 @@ int luaB_assert (lua_State *L) { | |||
| 426 | 404 | ||
| 427 | 405 | ||
| 428 | int luaB_getn (lua_State *L) { | 406 | int luaB_getn (lua_State *L) { |
| 429 | lua_pushnumber(L, getnarg(L, gettable(L, 1))); | 407 | luaL_checktype(L, 1, "table"); |
| 408 | lua_pushnumber(L, lua_getn(L, 1)); | ||
| 430 | return 1; | 409 | return 1; |
| 431 | } | 410 | } |
| 432 | 411 | ||
| @@ -440,7 +419,7 @@ static void t_move (lua_State *L, Hash *t, int from, int to) { | |||
| 440 | 419 | ||
| 441 | int luaB_tinsert (lua_State *L) { | 420 | int luaB_tinsert (lua_State *L) { |
| 442 | Hash *a = gettable(L, 1); | 421 | Hash *a = gettable(L, 1); |
| 443 | int n = (int)getnarg(L, a); | 422 | int n = lua_getn(L, 1); |
| 444 | int v = lua_gettop(L); /* last argument: to be inserted */ | 423 | int v = lua_gettop(L); /* last argument: to be inserted */ |
| 445 | int pos; | 424 | int pos; |
| 446 | if (v == 2) /* called with only 2 arguments */ | 425 | if (v == 2) /* called with only 2 arguments */ |
| @@ -457,7 +436,7 @@ int luaB_tinsert (lua_State *L) { | |||
| 457 | 436 | ||
| 458 | int luaB_tremove (lua_State *L) { | 437 | int luaB_tremove (lua_State *L) { |
| 459 | Hash *a = gettable(L, 1); | 438 | Hash *a = gettable(L, 1); |
| 460 | int n = (int)getnarg(L, a); | 439 | int n = lua_getn(L, 1); |
| 461 | int pos = luaL_opt_int(L, 2, n); | 440 | int pos = luaL_opt_int(L, 2, n); |
| 462 | if (n <= 0) return 0; /* table is "empty" */ | 441 | if (n <= 0) return 0; /* table is "empty" */ |
| 463 | luaA_pushobject(L, luaH_getnum(a, pos)); /* result = a[pos] */ | 442 | luaA_pushobject(L, luaH_getnum(a, pos)); /* result = a[pos] */ |
| @@ -471,7 +450,7 @@ int luaB_tremove (lua_State *L) { | |||
| 471 | 450 | ||
| 472 | static int luaB_foreachi (lua_State *L) { | 451 | static int luaB_foreachi (lua_State *L) { |
| 473 | const Hash *t = gettable(L, 1); | 452 | const Hash *t = gettable(L, 1); |
| 474 | int n = (int)getnarg(L, t); | 453 | int n = lua_getn(L, 1); |
| 475 | int i; | 454 | int i; |
| 476 | luaL_checktype(L, 2, "function"); | 455 | luaL_checktype(L, 2, "function"); |
| 477 | for (i=1; i<=n; i++) { | 456 | for (i=1; i<=n; i++) { |
| @@ -584,7 +563,7 @@ static void auxsort (lua_State *L, Hash *a, int l, int u, const TObject *f) { | |||
| 584 | 563 | ||
| 585 | int luaB_sort (lua_State *L) { | 564 | int luaB_sort (lua_State *L) { |
| 586 | Hash *a = gettable(L, 1); | 565 | Hash *a = gettable(L, 1); |
| 587 | int n = (int)getnarg(L, a); | 566 | int n = lua_getn(L, 1); |
| 588 | const TObject *func = NULL; | 567 | const TObject *func = NULL; |
| 589 | if (!lua_isnull(L, 2)) { /* is there a 2nd argument? */ | 568 | if (!lua_isnull(L, 2)) { /* is there a 2nd argument? */ |
| 590 | luaL_checktype(L, 2, "function"); | 569 | luaL_checktype(L, 2, "function"); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lua.h,v 1.63 2000/08/31 14:08:27 roberto Exp roberto $ | 2 | ** $Id: lua.h,v 1.64 2000/08/31 20:23:40 roberto Exp roberto $ |
| 3 | ** Lua - An Extensible Extension Language | 3 | ** Lua - An Extensible Extension Language |
| 4 | ** TeCGraf: Grupo de Tecnologia em Computacao Grafica, PUC-Rio, Brazil | 4 | ** TeCGraf: Grupo de Tecnologia em Computacao Grafica, PUC-Rio, Brazil |
| 5 | ** e-mail: lua@tecgraf.puc-rio.br | 5 | ** e-mail: lua@tecgraf.puc-rio.br |
| @@ -83,6 +83,7 @@ const char *lua_tostring (lua_State *L, int index); | |||
| 83 | size_t lua_strlen (lua_State *L, int index); | 83 | size_t lua_strlen (lua_State *L, int index); |
| 84 | lua_CFunction lua_tocfunction (lua_State *L, int index); | 84 | lua_CFunction lua_tocfunction (lua_State *L, int index); |
| 85 | void *lua_touserdata (lua_State *L, int index); | 85 | void *lua_touserdata (lua_State *L, int index); |
| 86 | const void *lua_topointer (lua_State *L, int index); | ||
| 86 | 87 | ||
| 87 | 88 | ||
| 88 | /* | 89 | /* |
| @@ -145,6 +146,7 @@ void lua_unref (lua_State *L, int ref); | |||
| 145 | long lua_collectgarbage (lua_State *L, long limit); | 146 | long lua_collectgarbage (lua_State *L, long limit); |
| 146 | 147 | ||
| 147 | int lua_next (lua_State *L); | 148 | int lua_next (lua_State *L); |
| 149 | int lua_getn (lua_State *L, int index); | ||
| 148 | 150 | ||
| 149 | 151 | ||
| 150 | 152 | ||
