diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1998-11-13 14:39:18 -0200 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1998-11-13 14:39:18 -0200 |
| commit | 8e3bd752bbd9a629cb6367db4a4237514709ca75 (patch) | |
| tree | 3030d70162530089592562a6df162a7096f5cb9e | |
| parent | a84bca67fcf74241570d7f6d51243aecce9e71a6 (diff) | |
| download | lua-8e3bd752bbd9a629cb6367db4a4237514709ca75.tar.gz lua-8e3bd752bbd9a629cb6367db4a4237514709ca75.tar.bz2 lua-8e3bd752bbd9a629cb6367db4a4237514709ca75.zip | |
small optimization in "sort" + new functions "getn" and "foreachi"
Diffstat (limited to '')
| -rw-r--r-- | lbuiltin.c | 96 |
1 files changed, 63 insertions, 33 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lbuiltin.c,v 1.33 1998/07/12 16:16:43 roberto Exp roberto $ | 2 | ** $Id: lbuiltin.c,v 1.34 1998/08/21 17:43:44 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 | */ |
| @@ -36,6 +36,35 @@ static void pushstring (TaggedString *s) | |||
| 36 | } | 36 | } |
| 37 | 37 | ||
| 38 | 38 | ||
| 39 | static int getsize (TObject *t) { | ||
| 40 | int max = 0; | ||
| 41 | int i; | ||
| 42 | Hash *h = avalue(t); | ||
| 43 | LUA_ASSERT(ttype(t) == LUA_T_ARRAY, "table expected"); | ||
| 44 | for (i = 0; i<nhash(h); i++) { | ||
| 45 | Node *n = h->node+i; | ||
| 46 | if (ttype(ref(n)) == LUA_T_NUMBER && ttype(val(n)) != LUA_T_NIL && | ||
| 47 | (int)nvalue(ref(n)) > max) | ||
| 48 | max = nvalue(ref(n)); | ||
| 49 | } | ||
| 50 | return max; | ||
| 51 | } | ||
| 52 | |||
| 53 | |||
| 54 | static int getnarg (lua_Object table) { | ||
| 55 | lua_Object temp; | ||
| 56 | /* temp = table.n */ | ||
| 57 | lua_pushobject(table); lua_pushstring("n"); temp = lua_rawgettable(); | ||
| 58 | return (lua_isnumber(temp) ? lua_getnumber(temp) : | ||
| 59 | getsize(luaA_Address(table))); | ||
| 60 | } | ||
| 61 | |||
| 62 | |||
| 63 | static void getn (void) { | ||
| 64 | lua_pushnumber(getnarg(luaL_tablearg(1))); | ||
| 65 | } | ||
| 66 | |||
| 67 | |||
| 39 | static void nextvar (void) { | 68 | static void nextvar (void) { |
| 40 | TObject *o = luaA_Address(luaL_nonnullarg(1)); | 69 | TObject *o = luaA_Address(luaL_nonnullarg(1)); |
| 41 | TaggedString *g; | 70 | TaggedString *g; |
| @@ -113,6 +142,26 @@ static void foreach (void) { | |||
| 113 | } | 142 | } |
| 114 | 143 | ||
| 115 | 144 | ||
| 145 | static void foreachi (void) { | ||
| 146 | lua_Object ot = luaL_tablearg(1); | ||
| 147 | Hash *t = avalue(luaA_Address(ot)); | ||
| 148 | TObject f = *luaA_Address(luaL_functionarg(2)); | ||
| 149 | int i; | ||
| 150 | int n = getnarg(ot); | ||
| 151 | luaD_checkstack(3); /* for f, ref, and val */ | ||
| 152 | for (i=1; i<=n; i++) { | ||
| 153 | *(L->stack.top++) = f; | ||
| 154 | ttype(L->stack.top) = LUA_T_NUMBER; | ||
| 155 | nvalue(L->stack.top++) = i; | ||
| 156 | *(L->stack.top++) = *luaH_getint(t, i); | ||
| 157 | luaD_calln(2, 1); | ||
| 158 | if (ttype(L->stack.top-1) != LUA_T_NIL) | ||
| 159 | return; | ||
| 160 | L->stack.top--; | ||
| 161 | } | ||
| 162 | } | ||
| 163 | |||
| 164 | |||
| 116 | static void internaldostring (void) | 165 | static void internaldostring (void) |
| 117 | { | 166 | { |
| 118 | long l; | 167 | long l; |
| @@ -281,29 +330,6 @@ static void luatag (void) | |||
| 281 | } | 330 | } |
| 282 | 331 | ||
| 283 | 332 | ||
| 284 | static int getsize (TObject *t) { | ||
| 285 | int max = 0; | ||
| 286 | int i; | ||
| 287 | Hash *h = avalue(t); | ||
| 288 | LUA_ASSERT(ttype(t) == LUA_T_ARRAY, "table expected"); | ||
| 289 | for (i = 0; i<nhash(h); i++) { | ||
| 290 | Node *n = h->node+i; | ||
| 291 | if (ttype(ref(n)) == LUA_T_NUMBER && ttype(val(n)) != LUA_T_NIL && | ||
| 292 | (int)nvalue(ref(n)) > max) | ||
| 293 | max = nvalue(ref(n)); | ||
| 294 | } | ||
| 295 | return max; | ||
| 296 | } | ||
| 297 | |||
| 298 | |||
| 299 | static int getnarg (lua_Object table) { | ||
| 300 | lua_Object temp; | ||
| 301 | /* temp = table.n */ | ||
| 302 | lua_pushobject(table); lua_pushstring("n"); temp = lua_rawgettable(); | ||
| 303 | return (lua_isnumber(temp) ? lua_getnumber(temp) : | ||
| 304 | getsize(luaA_Address(table))); | ||
| 305 | } | ||
| 306 | |||
| 307 | static void luaI_call (void) { | 333 | static void luaI_call (void) { |
| 308 | lua_Object f = luaL_nonnullarg(1); | 334 | lua_Object f = luaL_nonnullarg(1); |
| 309 | lua_Object arg = luaL_tablearg(2); | 335 | lua_Object arg = luaL_tablearg(2); |
| @@ -440,6 +466,7 @@ static int sort_comp (TObject *f, TObject *a, TObject *b) { | |||
| 440 | ** quicksort algorithm from "Programming Pearls", pg. 112 | 466 | ** quicksort algorithm from "Programming Pearls", pg. 112 |
| 441 | */ | 467 | */ |
| 442 | static void auxsort (Hash *a, int l, int u, TObject *f) { | 468 | static void auxsort (Hash *a, int l, int u, TObject *f) { |
| 469 | init: | ||
| 443 | if (u <= l) return; /* 0 or 1 element */ | 470 | if (u <= l) return; /* 0 or 1 element */ |
| 444 | luaD_checkstack(4); /* for pivot, f, a, b (sort_comp) */ | 471 | luaD_checkstack(4); /* for pivot, f, a, b (sort_comp) */ |
| 445 | if (u-l == 1) { /* only two elements? */ | 472 | if (u-l == 1) { /* only two elements? */ |
| @@ -461,8 +488,14 @@ static void auxsort (Hash *a, int l, int u, TObject *f) { | |||
| 461 | L->stack.top--; /* remove pivot from stack */ | 488 | L->stack.top--; /* remove pivot from stack */ |
| 462 | swap(a, l, m); | 489 | swap(a, l, m); |
| 463 | /* a[l..m-1] < a[m] <= a[m+1..u] */ | 490 | /* a[l..m-1] < a[m] <= a[m+1..u] */ |
| 464 | auxsort(a, l, m-1, f); | 491 | if (m-l < u-m) { /* check which "half" is bigger */ |
| 465 | auxsort(a, m+1, u, f); | 492 | auxsort(a, l, m-1, f); /* call recursively the smaller one */ |
| 493 | l = m+1; goto init; /* auxsort(a, m+1, u, f); */ | ||
| 494 | } | ||
| 495 | else { | ||
| 496 | auxsort(a, m+1, u, f); | ||
| 497 | u = m-1; goto init; /* auxsort(a, l, m-1, f); */ | ||
| 498 | } | ||
| 466 | } | 499 | } |
| 467 | } | 500 | } |
| 468 | 501 | ||
| @@ -471,13 +504,8 @@ static void luaB_sort (void) { | |||
| 471 | int n = getnarg(t); | 504 | int n = getnarg(t); |
| 472 | Hash *a = avalue(luaA_Address(t)); | 505 | Hash *a = avalue(luaA_Address(t)); |
| 473 | lua_Object func = lua_getparam(2); | 506 | lua_Object func = lua_getparam(2); |
| 474 | TObject *f; | 507 | TObject *f = luaA_Address(func); |
| 475 | if (func == LUA_NOOBJECT) | 508 | luaL_arg_check(!f || lua_isfunction(func), 2, "function expected"); |
| 476 | f = NULL; | ||
| 477 | else { | ||
| 478 | luaL_arg_check(lua_isfunction(func), 2, "function expected"); | ||
| 479 | f = luaA_Address(func); | ||
| 480 | } | ||
| 481 | auxsort(a, 1, n, f); | 509 | auxsort(a, 1, n, f); |
| 482 | lua_pushobject(t); | 510 | lua_pushobject(t); |
| 483 | } | 511 | } |
| @@ -583,7 +611,9 @@ static struct luaL_reg int_funcs[] = { | |||
| 583 | {"error", luaI_error}, | 611 | {"error", luaI_error}, |
| 584 | {"_ERRORMESSAGE", error_message}, | 612 | {"_ERRORMESSAGE", error_message}, |
| 585 | {"foreach", foreach}, | 613 | {"foreach", foreach}, |
| 614 | {"foreachi", foreachi}, | ||
| 586 | {"foreachvar", foreachvar}, | 615 | {"foreachvar", foreachvar}, |
| 616 | {"getn", getn}, | ||
| 587 | {"getglobal", getglobal}, | 617 | {"getglobal", getglobal}, |
| 588 | {"newtag", newtag}, | 618 | {"newtag", newtag}, |
| 589 | {"next", next}, | 619 | {"next", next}, |
