aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lbuiltin.c103
1 files changed, 51 insertions, 52 deletions
diff --git a/lbuiltin.c b/lbuiltin.c
index 13b111de..cd83b732 100644
--- a/lbuiltin.c
+++ b/lbuiltin.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lbuiltin.c,v 1.74 1999/11/22 13:12:07 roberto Exp roberto $ 2** $Id: lbuiltin.c,v 1.75 1999/11/22 17:39:51 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*/
@@ -48,10 +48,10 @@ static real getsize (const Hash *h) {
48 int i = h->size; 48 int i = h->size;
49 Node *n = h->node; 49 Node *n = h->node;
50 while (i--) { 50 while (i--) {
51 if (ttype(key(L, n)) == LUA_T_NUMBER && 51 if (ttype(key(n)) == LUA_T_NUMBER &&
52 ttype(val(L, n)) != LUA_T_NIL && 52 ttype(val(n)) != LUA_T_NIL &&
53 nvalue(key(L, n)) > max) 53 nvalue(key(n)) > max)
54 max = nvalue(key(L, n)); 54 max = nvalue(key(n));
55 n++; 55 n++;
56 } 56 }
57 return max; 57 return max;
@@ -170,7 +170,6 @@ static void luaB_setglobal (lua_State *L) {
170 lua_Object value = luaL_nonnullarg(L, 2); 170 lua_Object value = luaL_nonnullarg(L, 2);
171 lua_pushobject(L, value); 171 lua_pushobject(L, value);
172 lua_setglobal(L, n); 172 lua_setglobal(L, n);
173 lua_pushobject(L, value); /* return given value */
174} 173}
175 174
176static void luaB_rawsetglobal (lua_State *L) { 175static void luaB_rawsetglobal (lua_State *L) {
@@ -178,7 +177,6 @@ static void luaB_rawsetglobal (lua_State *L) {
178 lua_Object value = luaL_nonnullarg(L, 2); 177 lua_Object value = luaL_nonnullarg(L, 2);
179 lua_pushobject(L, value); 178 lua_pushobject(L, value);
180 lua_rawsetglobal(L, n); 179 lua_rawsetglobal(L, n);
181 lua_pushobject(L, value); /* return given value */
182} 180}
183 181
184static void luaB_getglobal (lua_State *L) { 182static void luaB_getglobal (lua_State *L) {
@@ -235,7 +233,8 @@ static void luaB_settagmethod (lua_State *L) {
235} 233}
236 234
237static void luaB_gettagmethod (lua_State *L) { 235static void luaB_gettagmethod (lua_State *L) {
238 lua_pushobject(L, lua_gettagmethod(L, luaL_check_int(L, 1), luaL_check_string(L, 2))); 236 lua_pushobject(L, lua_gettagmethod(L, luaL_check_int(L, 1),
237 luaL_check_string(L, 2)));
239} 238}
240 239
241static void luaB_seterrormethod (lua_State *L) { 240static void luaB_seterrormethod (lua_State *L) {
@@ -252,7 +251,6 @@ static void luaB_collectgarbage (lua_State *L) {
252static void luaB_type (lua_State *L) { 251static void luaB_type (lua_State *L) {
253 lua_Object o = luaL_nonnullarg(L, 1); 252 lua_Object o = luaL_nonnullarg(L, 1);
254 lua_pushstring(L, lua_type(L, o)); 253 lua_pushstring(L, lua_type(L, o));
255 lua_pushnumber(L, lua_tag(L, o));
256} 254}
257 255
258/* }====================================================== */ 256/* }====================================================== */
@@ -416,66 +414,65 @@ static void luaB_assert (lua_State *L) {
416 414
417 415
418static void luaB_foreachi (lua_State *L) { 416static void luaB_foreachi (lua_State *L) {
417 struct Stack *S = &L->stack;
419 const Hash *t = gettable(L, 1); 418 const Hash *t = gettable(L, 1);
420 int i;
421 int n = (int)getnarg(L, t); 419 int n = (int)getnarg(L, t);
422 TObject f; 420 int i;
421 StkId f = luaA_Address(L, luaL_functionarg(L, 2)) - S->stack;
423 /* 'f' cannot be a pointer to TObject, because it is on the stack, and the 422 /* 'f' cannot be a pointer to TObject, because it is on the stack, and the
424 stack may be reallocated by the call. Moreover, some C compilers do not 423 stack may be reallocated by the call. */
425 initialize structs, so we must do the assignment after the declaration */
426 f = *luaA_Address(L, luaL_functionarg(L, 2));
427 luaD_checkstack(L, 3); /* for f, key, and val */ 424 luaD_checkstack(L, 3); /* for f, key, and val */
428 for (i=1; i<=n; i++) { 425 for (i=1; i<=n; i++) {
429 *(L->stack.top++) = f; 426 *(S->top++) = *(S->stack+f);
430 ttype(L->stack.top) = LUA_T_NUMBER; nvalue(L->stack.top++) = i; 427 ttype(S->top) = LUA_T_NUMBER; nvalue(S->top++) = i;
431 *(L->stack.top++) = *luaH_getint(L, t, i); 428 *(S->top++) = *luaH_getint(L, t, i);
432 luaD_calln(L, 2, 1); 429 luaD_call(L, S->top-3, 1);
433 if (ttype(L->stack.top-1) != LUA_T_NIL) 430 if (ttype(S->top-1) != LUA_T_NIL)
434 return; 431 return;
435 L->stack.top--; 432 S->top--;
436 } 433 }
437} 434}
438 435
439 436
440static void luaB_foreach (lua_State *L) { 437static void luaB_foreach (lua_State *L) {
438 struct Stack *S = &L->stack;
441 const Hash *a = gettable(L, 1); 439 const Hash *a = gettable(L, 1);
440 StkId f = luaA_Address(L, luaL_functionarg(L, 2)) - S->stack;
442 int i; 441 int i;
443 TObject f; /* see comment in 'foreachi' */
444 f = *luaA_Address(L, luaL_functionarg(L, 2));
445 luaD_checkstack(L, 3); /* for f, key, and val */ 442 luaD_checkstack(L, 3); /* for f, key, and val */
446 for (i=0; i<a->size; i++) { 443 for (i=0; i<a->size; i++) {
447 const Node *nd = &(a->node[i]); 444 const Node *nd = &(a->node[i]);
448 if (ttype(val(L, nd)) != LUA_T_NIL) { 445 if (ttype(val(nd)) != LUA_T_NIL) {
449 *(L->stack.top++) = f; 446 *(S->top++) = *(S->stack+f);
450 *(L->stack.top++) = *key(L, nd); 447 *(S->top++) = *key(nd);
451 *(L->stack.top++) = *val(L, nd); 448 *(S->top++) = *val(nd);
452 luaD_calln(L, 2, 1); 449 luaD_call(L, S->top-3, 1);
453 if (ttype(L->stack.top-1) != LUA_T_NIL) 450 if (ttype(S->top-1) != LUA_T_NIL)
454 return; 451 return;
455 L->stack.top--; /* remove result */ 452 S->top--; /* remove result */
456 } 453 }
457 } 454 }
458} 455}
459 456
460 457
461static void luaB_foreachvar (lua_State *L) { 458static void luaB_foreachvar (lua_State *L) {
459 struct Stack *S = &L->stack;
460 StkId f = luaA_Address(L, luaL_functionarg(L, 1)) - S->stack;
462 GlobalVar *gv; 461 GlobalVar *gv;
463 TObject f; /* see comment in 'foreachi' */
464 f = *luaA_Address(L, luaL_functionarg(L, 1));
465 luaD_checkstack(L, 4); /* for extra var name, f, var name, and globalval */ 462 luaD_checkstack(L, 4); /* for extra var name, f, var name, and globalval */
466 for (gv = L->rootglobal; gv; gv = gv->next) { 463 for (gv = L->rootglobal; gv; gv = gv->next) {
467 if (gv->value.ttype != LUA_T_NIL) { 464 if (gv->value.ttype != LUA_T_NIL) {
468 pushtagstring(L, gv->name); /* keep (extra) name on stack to avoid GC */ 465 pushtagstring(L, gv->name); /* keep (extra) name on stack to avoid GC */
469 *(L->stack.top++) = f; 466 *(S->top++) = *(S->stack+f);
470 pushtagstring(L, gv->name); 467 pushtagstring(L, gv->name);
471 *(L->stack.top++) = gv->value; 468 *(S->top++) = gv->value;
472 luaD_calln(L, 2, 1); 469 luaD_call(L, S->top-3, 1);
473 if (ttype(L->stack.top-1) != LUA_T_NIL) { 470 if (ttype(S->top-1) != LUA_T_NIL) {
474 L->stack.top--; 471 S->top--;
475 *(L->stack.top-1) = *L->stack.top; /* remove extra name */ 472 *(S->top-1) = *S->top; /* remove extra name */
476 return; 473 return;
477 } 474 }
478 L->stack.top-=2; /* remove result and extra name */ 475 S->top-=2; /* remove result and extra name */
479 } 476 }
480 } 477 }
481} 478}
@@ -529,14 +526,15 @@ static void swap (lua_State *L, Hash *a, int i, int j) {
529 luaH_setint(L, a, j, &temp); 526 luaH_setint(L, a, j, &temp);
530} 527}
531 528
532static int sort_comp (lua_State *L, lua_Object f, const TObject *a, const TObject *b) { 529static int sort_comp (lua_State *L, lua_Object f, const TObject *a,
530 const TObject *b) {
533 /* notice: the caller (auxsort) must check stack space */ 531 /* notice: the caller (auxsort) must check stack space */
534 if (f != LUA_NOOBJECT) { 532 if (f != LUA_NOOBJECT) {
535 *(L->stack.top) = *luaA_Address(L, f); 533 *(L->stack.top) = *luaA_Address(L, f);
536 *(L->stack.top+1) = *a; 534 *(L->stack.top+1) = *a;
537 *(L->stack.top+2) = *b; 535 *(L->stack.top+2) = *b;
538 L->stack.top += 3; 536 L->stack.top += 3;
539 luaD_calln(L, 2, 1); 537 luaD_call(L, L->stack.top-3, 1);
540 } 538 }
541 else { /* a < b? */ 539 else { /* a < b? */
542 *(L->stack.top) = *a; 540 *(L->stack.top) = *a;
@@ -548,32 +546,33 @@ static int sort_comp (lua_State *L, lua_Object f, const TObject *a, const TObjec
548} 546}
549 547
550static void auxsort (lua_State *L, Hash *a, int l, int u, lua_Object f) { 548static void auxsort (lua_State *L, Hash *a, int l, int u, lua_Object f) {
551 StkId P = L->stack.top - L->stack.stack; /* temporary place for pivot */ 549 struct Stack *S = &L->stack;
552 L->stack.top++; 550 StkId P = S->top - S->stack; /* temporary place for pivot */
553 ttype(L->stack.stack+P) = LUA_T_NIL; 551 S->top++;
552 ttype(S->stack+P) = LUA_T_NIL;
554 while (l < u) { /* for tail recursion */ 553 while (l < u) { /* for tail recursion */
555 int i, j; 554 int i, j;
556 /* sort elements a[l], a[(l+u)/2] and a[u] */ 555 /* sort elements a[l], a[(l+u)/2] and a[u] */
557 if (sort_comp(L, f, luaH_getint(L, a, u), luaH_getint(L, a, l))) /* a[u]<a[l]? */ 556 if (sort_comp(L, f, luaH_getint(L, a, u), luaH_getint(L, a, l)))
558 swap(L, a, l, u); 557 swap(L, a, l, u); /* a[u]<a[l] */
559 if (u-l == 1) break; /* only 2 elements */ 558 if (u-l == 1) break; /* only 2 elements */
560 i = (l+u)/2; 559 i = (l+u)/2;
561 *(L->stack.stack+P) = *luaH_getint(L, a, i); /* P = a[i] */ 560 *(S->stack+P) = *luaH_getint(L, a, i); /* P = a[i] */
562 if (sort_comp(L, f, L->stack.stack+P, luaH_getint(L, a, l))) /* a[i]<a[l]? */ 561 if (sort_comp(L, f, S->stack+P, luaH_getint(L, a, l))) /* a[i]<a[l]? */
563 swap(L, a, l, i); 562 swap(L, a, l, i);
564 else if (sort_comp(L, f, luaH_getint(L, a, u), L->stack.stack+P)) /* a[u]<a[i]? */ 563 else if (sort_comp(L, f, luaH_getint(L, a, u), S->stack+P)) /* a[u]<a[i]? */
565 swap(L, a, i, u); 564 swap(L, a, i, u);
566 if (u-l == 2) break; /* only 3 elements */ 565 if (u-l == 2) break; /* only 3 elements */
567 *(L->stack.stack+P) = *luaH_getint(L, a, i); /* save pivot on stack (GC) */ 566 *(S->stack+P) = *luaH_getint(L, a, i); /* save pivot on stack (GC) */
568 swap(L, a, i, u-1); /* put median element as pivot (a[u-1]) */ 567 swap(L, a, i, u-1); /* put median element as pivot (a[u-1]) */
569 /* a[l] <= P == a[u-1] <= a[u], only needs to sort from l+1 to u-2 */ 568 /* a[l] <= P == a[u-1] <= a[u], only needs to sort from l+1 to u-2 */
570 i = l; j = u-1; 569 i = l; j = u-1;
571 for (;;) { /* invariant: a[l..i] <= P <= a[j..u] */ 570 for (;;) { /* invariant: a[l..i] <= P <= a[j..u] */
572 /* repeat i++ until a[i] >= P */ 571 /* repeat i++ until a[i] >= P */
573 while (sort_comp(L, f, luaH_getint(L, a, ++i), L->stack.stack+P)) 572 while (sort_comp(L, f, luaH_getint(L, a, ++i), S->stack+P))
574 if (i>u) lua_error(L, "invalid order function for sorting"); 573 if (i>u) lua_error(L, "invalid order function for sorting");
575 /* repeat j-- until a[j] <= P */ 574 /* repeat j-- until a[j] <= P */
576 while (sort_comp(L, f, (L->stack.stack+P), luaH_getint(L, a, --j))) 575 while (sort_comp(L, f, (S->stack+P), luaH_getint(L, a, --j)))
577 if (j<l) lua_error(L, "invalid order function for sorting"); 576 if (j<l) lua_error(L, "invalid order function for sorting");
578 if (j<i) break; 577 if (j<i) break;
579 swap(L, a, i, j); 578 swap(L, a, i, j);
@@ -589,7 +588,7 @@ static void auxsort (lua_State *L, Hash *a, int l, int u, lua_Object f) {
589 } 588 }
590 auxsort(L, a, j, i, f); /* call recursively the smaller one */ 589 auxsort(L, a, j, i, f); /* call recursively the smaller one */
591 } /* repeat the routine for the larger one */ 590 } /* repeat the routine for the larger one */
592 L->stack.top--; /* remove pivot from stack */ 591 S->top--; /* remove pivot from stack */
593} 592}
594 593
595static void luaB_sort (lua_State *L) { 594static void luaB_sort (lua_State *L) {