aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>1998-11-13 14:39:18 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>1998-11-13 14:39:18 -0200
commit8e3bd752bbd9a629cb6367db4a4237514709ca75 (patch)
tree3030d70162530089592562a6df162a7096f5cb9e
parenta84bca67fcf74241570d7f6d51243aecce9e71a6 (diff)
downloadlua-8e3bd752bbd9a629cb6367db4a4237514709ca75.tar.gz
lua-8e3bd752bbd9a629cb6367db4a4237514709ca75.tar.bz2
lua-8e3bd752bbd9a629cb6367db4a4237514709ca75.zip
small optimization in "sort" + new functions "getn" and "foreachi"
-rw-r--r--lbuiltin.c96
1 files changed, 63 insertions, 33 deletions
diff --git a/lbuiltin.c b/lbuiltin.c
index 58c9509c..0707ea26 100644
--- a/lbuiltin.c
+++ b/lbuiltin.c
@@ -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
39static 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
54static 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
63static void getn (void) {
64 lua_pushnumber(getnarg(luaL_tablearg(1)));
65}
66
67
39static void nextvar (void) { 68static 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
145static 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
116static void internaldostring (void) 165static 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
284static 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
299static 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
307static void luaI_call (void) { 333static 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*/
442static void auxsort (Hash *a, int l, int u, TObject *f) { 468static 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},