aboutsummaryrefslogtreecommitdiff
path: root/lbuiltin.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>1999-10-14 17:13:31 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>1999-10-14 17:13:31 -0200
commit4e9f2d13d5b6fa71ca480394e0b7e75463d4aeec (patch)
treed11eee681ce7b01a273e489f47e070494b51de1a /lbuiltin.c
parentb6ebbb2fee13aa223fdd12921cd0411e02db9dd0 (diff)
downloadlua-4e9f2d13d5b6fa71ca480394e0b7e75463d4aeec.tar.gz
lua-4e9f2d13d5b6fa71ca480394e0b7e75463d4aeec.tar.bz2
lua-4e9f2d13d5b6fa71ca480394e0b7e75463d4aeec.zip
new implementation of hash tables.
Diffstat (limited to 'lbuiltin.c')
-rw-r--r--lbuiltin.c73
1 files changed, 49 insertions, 24 deletions
diff --git a/lbuiltin.c b/lbuiltin.c
index f3fbce43..f2821bdb 100644
--- a/lbuiltin.c
+++ b/lbuiltin.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lbuiltin.c,v 1.65 1999/10/07 19:04:30 roberto Exp roberto $ 2** $Id: lbuiltin.c,v 1.66 1999/10/11 16:13:11 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*/
@@ -44,13 +44,13 @@ static void pushtagstring (TaggedString *s) {
44 44
45static real getsize (const Hash *h) { 45static real getsize (const Hash *h) {
46 real max = 0; 46 real max = 0;
47 int i = nhash(h); 47 int i = h->size;
48 Node *n = h->node; 48 Node *n = h->node;
49 while (i--) { 49 while (i--) {
50 if (ttype(ref(n)) == LUA_T_NUMBER && 50 if (ttype(key(n)) == LUA_T_NUMBER &&
51 ttype(val(n)) != LUA_T_NIL && 51 ttype(val(n)) != LUA_T_NIL &&
52 nvalue(ref(n)) > max) 52 nvalue(key(n)) > max)
53 max = nvalue(ref(n)); 53 max = nvalue(key(n));
54 n++; 54 n++;
55 } 55 }
56 return max; 56 return max;
@@ -59,7 +59,7 @@ static real getsize (const Hash *h) {
59 59
60static real getnarg (const Hash *a) { 60static real getnarg (const Hash *a) {
61 TObject index; 61 TObject index;
62 TObject *value; 62 const TObject *value;
63 /* value = table.n */ 63 /* value = table.n */
64 ttype(&index) = LUA_T_STRING; 64 ttype(&index) = LUA_T_STRING;
65 tsvalue(&index) = luaS_new("n"); 65 tsvalue(&index) = luaS_new("n");
@@ -337,7 +337,13 @@ static void luaB_nextvar (void) {
337static void luaB_next (void) { 337static void luaB_next (void) {
338 const Hash *a = gethash(1); 338 const Hash *a = gethash(1);
339 const TObject *k = luaA_Address(luaL_nonnullarg(2)); 339 const TObject *k = luaA_Address(luaL_nonnullarg(2));
340 int i = (ttype(k) == LUA_T_NIL) ? 0 : luaH_pos(a, k)+1; 340 int i; /* will get first element after `i' */
341 if (ttype(k) == LUA_T_NIL)
342 i = 0; /* get first */
343 else {
344 i = luaH_pos(a, k)+1;
345 luaL_arg_check(i != 0, 2, "key not found");
346 }
341 if (luaA_next(a, i) == 0) 347 if (luaA_next(a, i) == 0)
342 lua_pushnil(); 348 lua_pushnil();
343} 349}
@@ -408,7 +414,7 @@ static void luaB_foreachi (void) {
408 stack may be reallocated by the call. Moreover, some C compilers do not 414 stack may be reallocated by the call. Moreover, some C compilers do not
409 initialize structs, so we must do the assignment after the declaration */ 415 initialize structs, so we must do the assignment after the declaration */
410 f = *luaA_Address(luaL_functionarg(2)); 416 f = *luaA_Address(luaL_functionarg(2));
411 luaD_checkstack(3); /* for f, ref, and val */ 417 luaD_checkstack(3); /* for f, key, and val */
412 for (i=1; i<=n; i++) { 418 for (i=1; i<=n; i++) {
413 *(L->stack.top++) = f; 419 *(L->stack.top++) = f;
414 ttype(L->stack.top) = LUA_T_NUMBER; nvalue(L->stack.top++) = i; 420 ttype(L->stack.top) = LUA_T_NUMBER; nvalue(L->stack.top++) = i;
@@ -426,12 +432,12 @@ static void luaB_foreach (void) {
426 int i; 432 int i;
427 TObject f; /* see comment in 'foreachi' */ 433 TObject f; /* see comment in 'foreachi' */
428 f = *luaA_Address(luaL_functionarg(2)); 434 f = *luaA_Address(luaL_functionarg(2));
429 luaD_checkstack(3); /* for f, ref, and val */ 435 luaD_checkstack(3); /* for f, key, and val */
430 for (i=0; i<a->nhash; i++) { 436 for (i=0; i<a->size; i++) {
431 const Node *nd = &(a->node[i]); 437 const Node *nd = &(a->node[i]);
432 if (ttype(val(nd)) != LUA_T_NIL) { 438 if (ttype(val(nd)) != LUA_T_NIL) {
433 *(L->stack.top++) = f; 439 *(L->stack.top++) = f;
434 *(L->stack.top++) = *ref(nd); 440 *(L->stack.top++) = *key(nd);
435 *(L->stack.top++) = *val(nd); 441 *(L->stack.top++) = *val(nd);
436 luaD_calln(2, 1); 442 luaD_calln(2, 1);
437 if (ttype(L->stack.top-1) != LUA_T_NIL) 443 if (ttype(L->stack.top-1) != LUA_T_NIL)
@@ -531,36 +537,37 @@ static int sort_comp (lua_Object f, const TObject *a, const TObject *b) {
531} 537}
532 538
533static void auxsort (Hash *a, int l, int u, lua_Object f) { 539static void auxsort (Hash *a, int l, int u, lua_Object f) {
540 StkId P = L->stack.top - L->stack.stack; /* temporary place for pivot */
541 L->stack.top++;
542 ttype(L->stack.stack+P) = LUA_T_NIL;
534 while (l < u) { /* for tail recursion */ 543 while (l < u) { /* for tail recursion */
535 TObject *P;
536 int i, j; 544 int i, j;
537 /* sort elements a[l], a[(l+u)/2] and a[u] */ 545 /* sort elements a[l], a[(l+u)/2] and a[u] */
538 if (sort_comp(f, luaH_getint(a, u), luaH_getint(a, l))) /* a[l]>a[u]? */ 546 if (sort_comp(f, luaH_getint(a, u), luaH_getint(a, l))) /* a[u]<a[l]? */
539 swap(a, l, u); 547 swap(a, l, u);
540 if (u-l == 1) break; /* only 2 elements */ 548 if (u-l == 1) break; /* only 2 elements */
541 i = (l+u)/2; 549 i = (l+u)/2;
542 P = luaH_getint(a, i); 550 *(L->stack.stack+P) = *luaH_getint(a, i); /* P = a[i] */
543 if (sort_comp(f, P, luaH_getint(a, l))) /* a[l]>a[i]? */ 551 if (sort_comp(f, L->stack.stack+P, luaH_getint(a, l))) /* a[i]<a[l]? */
544 swap(a, l, i); 552 swap(a, l, i);
545 else if (sort_comp(f, luaH_getint(a, u), P)) /* a[i]>a[u]? */ 553 else if (sort_comp(f, luaH_getint(a, u), L->stack.stack+P)) /* a[u]<a[i]? */
546 swap(a, i, u); 554 swap(a, i, u);
547 if (u-l == 2) break; /* only 3 elements */ 555 if (u-l == 2) break; /* only 3 elements */
548 P = L->stack.top++; 556 *(L->stack.stack+P) = *luaH_getint(a, i); /* save pivot on stack (for GC) */
549 *P = *luaH_getint(a, i); /* save pivot on stack (for GC) */
550 swap(a, i, u-1); /* put median element as pivot (a[u-1]) */ 557 swap(a, i, u-1); /* put median element as pivot (a[u-1]) */
551 /* a[l] <= P == a[u-1] <= a[u], only needs to sort from l+1 to u-2 */ 558 /* a[l] <= P == a[u-1] <= a[u], only needs to sort from l+1 to u-2 */
552 i = l; j = u-1; 559 i = l; j = u-1;
553 for (;;) { 560 for (;;) { /* invariant: a[l..i] <= P <= a[j..u] */
554 /* invariant: a[l..i] <= P <= a[j..u] */ 561 /* repeat i++ until a[i] >= P */
555 while (sort_comp(f, luaH_getint(a, ++i), P)) /* stop when a[i] >= P */ 562 while (sort_comp(f, luaH_getint(a, ++i), L->stack.stack+P))
556 if (i>u) lua_error("invalid order function for sorting"); 563 if (i>u) lua_error("invalid order function for sorting");
557 while (sort_comp(f, P, luaH_getint(a, --j))) /* stop when a[j] <= P */ 564 /* repeat j-- until a[j] <= P */
565 while (sort_comp(f, (L->stack.stack+P), luaH_getint(a, --j)))
558 if (j<l) lua_error("invalid order function for sorting"); 566 if (j<l) lua_error("invalid order function for sorting");
559 if (j<i) break; 567 if (j<i) break;
560 swap(a, i, j); 568 swap(a, i, j);
561 } 569 }
562 swap(a, u-1, i); /* swap pivot (a[u-1]) with a[i] */ 570 swap(a, u-1, i); /* swap pivot (a[u-1]) with a[i] */
563 L->stack.top--; /* remove pivot from stack */
564 /* a[l..i-1] <= a[i] == P <= a[i+1..u] */ 571 /* a[l..i-1] <= a[i] == P <= a[i+1..u] */
565 /* adjust so that smaller "half" is in [j..i] and larger one in [l..u] */ 572 /* adjust so that smaller "half" is in [j..i] and larger one in [l..u] */
566 if (i-l < u-i) { 573 if (i-l < u-i) {
@@ -571,6 +578,7 @@ static void auxsort (Hash *a, int l, int u, lua_Object f) {
571 } 578 }
572 auxsort(a, j, i, f); /* call recursively the smaller one */ 579 auxsort(a, j, i, f); /* call recursively the smaller one */
573 } /* repeat the routine for the larger one */ 580 } /* repeat the routine for the larger one */
581 L->stack.top--; /* remove pivot from stack */
574} 582}
575 583
576static void luaB_sort (void) { 584static void luaB_sort (void) {
@@ -608,7 +616,23 @@ static void mem_query (void) {
608 616
609static void hash_query (void) { 617static void hash_query (void) {
610 const TObject *o = luaA_Address(luaL_nonnullarg(1)); 618 const TObject *o = luaA_Address(luaL_nonnullarg(1));
611 lua_pushnumber(luaH_hashindex(o)); 619 luaL_arg_check(ttype(o) == LUA_T_STRING, 1, "string expected");
620 lua_pushnumber(tsvalue(o)->hash);
621}
622
623
624static void table_query (void) {
625 const Hash *t = avalue(luaA_Address(luaL_tablearg(1)));
626 int i = luaL_opt_int(2, -1);
627 if (i == -1) {
628 lua_pushnumber(t->size);
629 lua_pushnumber(t->firstfree - t->node);
630 }
631 else if (i < t->size) {
632 luaA_pushobject(&t->node[i].key);
633 luaA_pushobject(&t->node[i].val);
634 lua_pushnumber(t->node[i].next == NULL ? 0 : t->node[i].next - t->node);
635 }
612} 636}
613 637
614 638
@@ -715,6 +739,7 @@ static const struct luaL_reg builtin_funcs[] = {
715 {"extra", extra_services}, 739 {"extra", extra_services},
716 {"hash", hash_query}, 740 {"hash", hash_query},
717 {"querystr", query_strings}, 741 {"querystr", query_strings},
742 {"querytab", table_query},
718 {"testC", testC}, 743 {"testC", testC},
719 {"totalmem", mem_query}, 744 {"totalmem", mem_query},
720#endif 745#endif