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 | ||