diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2000-08-31 13:52:06 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2000-08-31 13:52:06 -0300 |
| commit | fb5e6d5ac498649b8e1b6bf068d18078ef70d523 (patch) | |
| tree | 8f21741bec6abd4fac609561c22c5af721f25374 | |
| parent | d63afba9d3310131a6db65cbac541704f8aad61a (diff) | |
| download | lua-fb5e6d5ac498649b8e1b6bf068d18078ef70d523.tar.gz lua-fb5e6d5ac498649b8e1b6bf068d18078ef70d523.tar.bz2 lua-fb5e6d5ac498649b8e1b6bf068d18078ef70d523.zip | |
more functions implemented through the official API
| -rw-r--r-- | lbuiltin.c | 153 |
1 files changed, 78 insertions, 75 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lbuiltin.c,v 1.124 2000/08/29 14:41:56 roberto Exp roberto $ | 2 | ** $Id: lbuiltin.c,v 1.125 2000/08/31 14:08:27 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 | */ |
| @@ -21,19 +21,8 @@ | |||
| 21 | 21 | ||
| 22 | #include "lua.h" | 22 | #include "lua.h" |
| 23 | 23 | ||
| 24 | #include "lapi.h" | ||
| 25 | #include "lauxlib.h" | 24 | #include "lauxlib.h" |
| 26 | #include "lbuiltin.h" | 25 | #include "lbuiltin.h" |
| 27 | #include "ldo.h" | ||
| 28 | #include "lfunc.h" | ||
| 29 | #include "lmem.h" | ||
| 30 | #include "lobject.h" | ||
| 31 | #include "lstate.h" | ||
| 32 | #include "lstring.h" | ||
| 33 | #include "ltable.h" | ||
| 34 | #include "ltm.h" | ||
| 35 | #include "lundump.h" | ||
| 36 | #include "lvm.h" | ||
| 37 | 26 | ||
| 38 | 27 | ||
| 39 | 28 | ||
| @@ -44,40 +33,6 @@ void luaB_opentests (lua_State *L); | |||
| 44 | 33 | ||
| 45 | 34 | ||
| 46 | 35 | ||
| 47 | /* | ||
| 48 | ** {====================================================== | ||
| 49 | ** Auxiliary functions | ||
| 50 | ** ======================================================= | ||
| 51 | */ | ||
| 52 | |||
| 53 | static Number getsize (const Hash *h) { | ||
| 54 | Number max = 0; | ||
| 55 | int i = h->size; | ||
| 56 | Node *n = h->node; | ||
| 57 | while (i--) { | ||
| 58 | if (ttype(key(n)) == TAG_NUMBER && | ||
| 59 | ttype(val(n)) != TAG_NIL && | ||
| 60 | nvalue(key(n)) > max) | ||
| 61 | max = nvalue(key(n)); | ||
| 62 | n++; | ||
| 63 | } | ||
| 64 | return max; | ||
| 65 | } | ||
| 66 | |||
| 67 | |||
| 68 | static Number getnarg (lua_State *L, const Hash *a) { | ||
| 69 | const TObject *value = luaH_getstr(a, luaS_new(L, "n")); /* value = a.n */ | ||
| 70 | return (ttype(value) == TAG_NUMBER) ? nvalue(value) : getsize(a); | ||
| 71 | } | ||
| 72 | |||
| 73 | |||
| 74 | static Hash *gettable (lua_State *L, int arg) { | ||
| 75 | luaL_checktype(L, arg, "table"); | ||
| 76 | return hvalue(luaA_index(L, arg)); | ||
| 77 | } | ||
| 78 | |||
| 79 | /* }====================================================== */ | ||
| 80 | |||
| 81 | 36 | ||
| 82 | /* | 37 | /* |
| 83 | ** {====================================================== | 38 | ** {====================================================== |
| @@ -156,7 +111,7 @@ int luaB_tonumber (lua_State *L) { | |||
| 156 | else { | 111 | else { |
| 157 | const char *s1 = luaL_check_string(L, 1); | 112 | const char *s1 = luaL_check_string(L, 1); |
| 158 | char *s2; | 113 | char *s2; |
| 159 | Number n; | 114 | unsigned long n; |
| 160 | luaL_arg_check(L, 2 <= base && base <= 36, 2, "base out of range"); | 115 | luaL_arg_check(L, 2 <= base && base <= 36, 2, "base out of range"); |
| 161 | n = strtoul(s1, &s2, base); | 116 | n = strtoul(s1, &s2, base); |
| 162 | if (s1 != s2) { /* at least one valid digit? */ | 117 | if (s1 != s2) { /* at least one valid digit? */ |
| @@ -243,8 +198,10 @@ int luaB_settagmethod (lua_State *L) { | |||
| 243 | const char *event = luaL_check_string(L, 2); | 198 | const char *event = luaL_check_string(L, 2); |
| 244 | luaL_arg_check(L, lua_isfunction(L, 3) || lua_isnil(L, 3), 3, | 199 | luaL_arg_check(L, lua_isfunction(L, 3) || lua_isnil(L, 3), 3, |
| 245 | "function or nil expected"); | 200 | "function or nil expected"); |
| 246 | if (strcmp(event, "gc") == 0 && tag != TAG_NIL) | 201 | lua_pushnil(L); /* to get its tag */ |
| 202 | if (strcmp(event, "gc") == 0 && tag != lua_tag(L, -1)) | ||
| 247 | lua_error(L, "deprecated use: cannot set the `gc' tag method from Lua"); | 203 | lua_error(L, "deprecated use: cannot set the `gc' tag method from Lua"); |
| 204 | lua_settop(L, -1); /* remove the nil */ | ||
| 248 | lua_settagmethod(L, tag, event); | 205 | lua_settagmethod(L, tag, event); |
| 249 | return 1; | 206 | return 1; |
| 250 | } | 207 | } |
| @@ -279,16 +236,6 @@ int luaB_next (lua_State *L) { | |||
| 279 | } | 236 | } |
| 280 | } | 237 | } |
| 281 | 238 | ||
| 282 | /* }====================================================== */ | ||
| 283 | |||
| 284 | |||
| 285 | /* | ||
| 286 | ** {====================================================== | ||
| 287 | ** Functions that could use only the official API but | ||
| 288 | ** do not, for efficiency. | ||
| 289 | ** ======================================================= | ||
| 290 | */ | ||
| 291 | |||
| 292 | 239 | ||
| 293 | static int passresults (lua_State *L, int status, int oldtop) { | 240 | static int passresults (lua_State *L, int status, int oldtop) { |
| 294 | if (status == 0) { | 241 | if (status == 0) { |
| @@ -311,7 +258,7 @@ int luaB_dostring (lua_State *L) { | |||
| 311 | int oldtop = lua_gettop(L); | 258 | int oldtop = lua_gettop(L); |
| 312 | size_t l; | 259 | size_t l; |
| 313 | const char *s = luaL_check_lstr(L, 1, &l); | 260 | const char *s = luaL_check_lstr(L, 1, &l); |
| 314 | if (*s == ID_CHUNK) | 261 | if (*s == '\27') /* binary files start with ESC... */ |
| 315 | lua_error(L, "`dostring' cannot run pre-compiled code"); | 262 | lua_error(L, "`dostring' cannot run pre-compiled code"); |
| 316 | return passresults(L, lua_dobuffer(L, s, l, luaL_opt_string(L, 2, s)), oldtop); | 263 | return passresults(L, lua_dobuffer(L, s, l, luaL_opt_string(L, 2, s)), oldtop); |
| 317 | } | 264 | } |
| @@ -323,6 +270,63 @@ int luaB_dofile (lua_State *L) { | |||
| 323 | return passresults(L, lua_dofile(L, fname), oldtop); | 270 | return passresults(L, lua_dofile(L, fname), oldtop); |
| 324 | } | 271 | } |
| 325 | 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 | |||
| 326 | 330 | ||
| 327 | int luaB_call (lua_State *L) { | 331 | int luaB_call (lua_State *L) { |
| 328 | int oldtop; | 332 | int oldtop; |
| @@ -387,8 +391,7 @@ int luaB_tostring (lua_State *L) { | |||
| 387 | sprintf(buff, "function: %p", clvalue(o)); | 391 | sprintf(buff, "function: %p", clvalue(o)); |
| 388 | break; | 392 | break; |
| 389 | case TAG_USERDATA: | 393 | case TAG_USERDATA: |
| 390 | sprintf(buff, "userdata(%d): %p", tsvalue(o)->u.d.tag, | 394 | sprintf(buff, "userdata(%d): %p", lua_tag(L, 1), lua_touserdata(L, 1)); |
| 391 | tsvalue(o)->u.d.value); | ||
| 392 | break; | 395 | break; |
| 393 | case TAG_NIL: | 396 | case TAG_NIL: |
| 394 | lua_pushstring(L, "nil"); | 397 | lua_pushstring(L, "nil"); |
| @@ -485,25 +488,25 @@ static int luaB_foreachi (lua_State *L) { | |||
| 485 | 488 | ||
| 486 | 489 | ||
| 487 | static int luaB_foreach (lua_State *L) { | 490 | static int luaB_foreach (lua_State *L) { |
| 488 | const Hash *a = gettable(L, 1); | 491 | luaL_checktype(L, 1, "table"); |
| 489 | int i; | ||
| 490 | luaL_checktype(L, 2, "function"); | 492 | luaL_checktype(L, 2, "function"); |
| 491 | for (i=0; i<a->size; i++) { | 493 | lua_pushobject(L, 1); /* put table at top */ |
| 492 | const Node *nd = &(a->node[i]); | 494 | lua_pushnil(L); /* first index */ |
| 493 | if (ttype(val(nd)) != TAG_NIL) { | 495 | for (;;) { |
| 494 | lua_pushobject(L, 2); | 496 | if (lua_next(L) == 0) |
| 495 | *(L->top++) = *key(nd); | 497 | return 0; |
| 496 | *(L->top++) = *val(nd); | 498 | lua_pushobject(L, 2); /* function */ |
| 497 | luaD_call(L, L->top-3, 1); | 499 | lua_pushobject(L, -3); /* key */ |
| 498 | if (ttype(L->top-1) != TAG_NIL) | 500 | lua_pushobject(L, -3); /* value */ |
| 499 | return 1; | 501 | if (lua_call(L, 2, 1) != 0) lua_error(L, NULL); |
| 500 | L->top--; /* remove result */ | 502 | if (!lua_isnil(L, -1)) |
| 501 | } | 503 | return 1; |
| 504 | lua_settop(L, -2); /* remove value and result */ | ||
| 502 | } | 505 | } |
| 503 | return 0; | ||
| 504 | } | 506 | } |
| 505 | 507 | ||
| 506 | 508 | ||
| 509 | |||
| 507 | /* | 510 | /* |
| 508 | ** {====================================================== | 511 | ** {====================================================== |
| 509 | ** Quicksort | 512 | ** Quicksort |
