aboutsummaryrefslogtreecommitdiff
path: root/lbuiltin.c
diff options
context:
space:
mode:
Diffstat (limited to 'lbuiltin.c')
-rw-r--r--lbuiltin.c99
1 files changed, 46 insertions, 53 deletions
diff --git a/lbuiltin.c b/lbuiltin.c
index c9fefa35..28b64270 100644
--- a/lbuiltin.c
+++ b/lbuiltin.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lbuiltin.c,v 1.77 1999/11/29 19:11:36 roberto Exp roberto $ 2** $Id: lbuiltin.c,v 1.78 1999/11/30 13:06:50 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*/
@@ -37,8 +37,8 @@
37 37
38 38
39static void pushtagstring (lua_State *L, TaggedString *s) { 39static void pushtagstring (lua_State *L, TaggedString *s) {
40 ttype(L->stack.top) = LUA_T_STRING; 40 ttype(L->top) = LUA_T_STRING;
41 tsvalue(L->stack.top) = s; 41 tsvalue(L->top) = s;
42 incr_top; 42 incr_top;
43} 43}
44 44
@@ -303,7 +303,7 @@ static void luaB_call (lua_State *L) {
303 /* push arg[1...n] */ 303 /* push arg[1...n] */
304 luaD_checkstack(L, narg); 304 luaD_checkstack(L, narg);
305 for (i=0; i<narg; i++) 305 for (i=0; i<narg; i++)
306 *(L->stack.top++) = *luaH_getint(L, arg, i+1); 306 *(L->top++) = *luaH_getint(L, arg, i+1);
307 status = lua_callfunction(L, f); 307 status = lua_callfunction(L, f);
308 if (err != LUA_NOOBJECT) { /* restore old error method */ 308 if (err != LUA_NOOBJECT) { /* restore old error method */
309 lua_pushobject(L, err); 309 lua_pushobject(L, err);
@@ -319,7 +319,7 @@ static void luaB_call (lua_State *L) {
319 } 319 }
320 else { /* no errors */ 320 else { /* no errors */
321 if (strchr(options, 'p')) { /* pack results? */ 321 if (strchr(options, 'p')) { /* pack results? */
322 luaV_pack(L, L->Cstack.lua2C, L->Cstack.num, L->stack.top); 322 luaV_pack(L, L->Cstack.lua2C, L->Cstack.num, L->top);
323 incr_top; 323 incr_top;
324 } 324 }
325 else 325 else
@@ -414,65 +414,60 @@ static void luaB_assert (lua_State *L) {
414 414
415 415
416static void luaB_foreachi (lua_State *L) { 416static void luaB_foreachi (lua_State *L) {
417 struct Stack *S = &L->stack;
418 const Hash *t = gettable(L, 1); 417 const Hash *t = gettable(L, 1);
419 int n = (int)getnarg(L, t); 418 int n = (int)getnarg(L, t);
420 int i; 419 int i;
421 StkId f = luaA_Address(L, luaL_functionarg(L, 2)) - S->stack; 420 StkId f = luaA_Address(L, luaL_functionarg(L, 2));
422 /* 'f' cannot be a pointer to TObject, because it is on the stack, and the
423 stack may be reallocated by the call. */
424 luaD_checkstack(L, 3); /* for f, key, and val */ 421 luaD_checkstack(L, 3); /* for f, key, and val */
425 for (i=1; i<=n; i++) { 422 for (i=1; i<=n; i++) {
426 *(S->top++) = *(S->stack+f); 423 *(L->top++) = *f;
427 ttype(S->top) = LUA_T_NUMBER; nvalue(S->top++) = i; 424 ttype(L->top) = LUA_T_NUMBER; nvalue(L->top++) = i;
428 *(S->top++) = *luaH_getint(L, t, i); 425 *(L->top++) = *luaH_getint(L, t, i);
429 luaD_call(L, S->top-3, 1); 426 luaD_call(L, L->top-3, 1);
430 if (ttype(S->top-1) != LUA_T_NIL) 427 if (ttype(L->top-1) != LUA_T_NIL)
431 return; 428 return;
432 S->top--; 429 L->top--;
433 } 430 }
434} 431}
435 432
436 433
437static void luaB_foreach (lua_State *L) { 434static void luaB_foreach (lua_State *L) {
438 struct Stack *S = &L->stack;
439 const Hash *a = gettable(L, 1); 435 const Hash *a = gettable(L, 1);
440 StkId f = luaA_Address(L, luaL_functionarg(L, 2)) - S->stack; 436 StkId f = luaA_Address(L, luaL_functionarg(L, 2));
441 int i; 437 int i;
442 luaD_checkstack(L, 3); /* for f, key, and val */ 438 luaD_checkstack(L, 3); /* for f, key, and val */
443 for (i=0; i<a->size; i++) { 439 for (i=0; i<a->size; i++) {
444 const Node *nd = &(a->node[i]); 440 const Node *nd = &(a->node[i]);
445 if (ttype(val(nd)) != LUA_T_NIL) { 441 if (ttype(val(nd)) != LUA_T_NIL) {
446 *(S->top++) = *(S->stack+f); 442 *(L->top++) = *f;
447 *(S->top++) = *key(nd); 443 *(L->top++) = *key(nd);
448 *(S->top++) = *val(nd); 444 *(L->top++) = *val(nd);
449 luaD_call(L, S->top-3, 1); 445 luaD_call(L, L->top-3, 1);
450 if (ttype(S->top-1) != LUA_T_NIL) 446 if (ttype(L->top-1) != LUA_T_NIL)
451 return; 447 return;
452 S->top--; /* remove result */ 448 L->top--; /* remove result */
453 } 449 }
454 } 450 }
455} 451}
456 452
457 453
458static void luaB_foreachvar (lua_State *L) { 454static void luaB_foreachvar (lua_State *L) {
459 struct Stack *S = &L->stack; 455 StkId f = luaA_Address(L, luaL_functionarg(L, 1));
460 StkId f = luaA_Address(L, luaL_functionarg(L, 1)) - S->stack;
461 GlobalVar *gv; 456 GlobalVar *gv;
462 luaD_checkstack(L, 4); /* for extra var name, f, var name, and globalval */ 457 luaD_checkstack(L, 4); /* for extra var name, f, var name, and globalval */
463 for (gv = L->rootglobal; gv; gv = gv->next) { 458 for (gv = L->rootglobal; gv; gv = gv->next) {
464 if (gv->value.ttype != LUA_T_NIL) { 459 if (gv->value.ttype != LUA_T_NIL) {
465 pushtagstring(L, gv->name); /* keep (extra) name on stack to avoid GC */ 460 pushtagstring(L, gv->name); /* keep (extra) name on stack to avoid GC */
466 *(S->top++) = *(S->stack+f); 461 *(L->top++) = *f;
467 pushtagstring(L, gv->name); 462 pushtagstring(L, gv->name);
468 *(S->top++) = gv->value; 463 *(L->top++) = gv->value;
469 luaD_call(L, S->top-3, 1); 464 luaD_call(L, L->top-3, 1);
470 if (ttype(S->top-1) != LUA_T_NIL) { 465 if (ttype(L->top-1) != LUA_T_NIL) {
471 S->top--; 466 L->top--;
472 *(S->top-1) = *S->top; /* remove extra name */ 467 *(L->top-1) = *L->top; /* remove extra name */
473 return; 468 return;
474 } 469 }
475 S->top-=2; /* remove result and extra name */ 470 L->top-=2; /* remove result and extra name */
476 } 471 }
477 } 472 }
478} 473}
@@ -530,26 +525,24 @@ static int sort_comp (lua_State *L, lua_Object f, const TObject *a,
530 const TObject *b) { 525 const TObject *b) {
531 /* notice: the caller (auxsort) must check stack space */ 526 /* notice: the caller (auxsort) must check stack space */
532 if (f != LUA_NOOBJECT) { 527 if (f != LUA_NOOBJECT) {
533 *(L->stack.top) = *luaA_Address(L, f); 528 *(L->top) = *luaA_Address(L, f);
534 *(L->stack.top+1) = *a; 529 *(L->top+1) = *a;
535 *(L->stack.top+2) = *b; 530 *(L->top+2) = *b;
536 L->stack.top += 3; 531 L->top += 3;
537 luaD_call(L, L->stack.top-3, 1); 532 luaD_call(L, L->top-3, 1);
538 } 533 }
539 else { /* a < b? */ 534 else { /* a < b? */
540 *(L->stack.top) = *a; 535 *(L->top) = *a;
541 *(L->stack.top+1) = *b; 536 *(L->top+1) = *b;
542 L->stack.top += 2; 537 luaV_comparison(L, L->top+2, LUA_T_NUMBER, LUA_T_NIL, LUA_T_NIL, IM_LT);
543 luaV_comparison(L, LUA_T_NUMBER, LUA_T_NIL, LUA_T_NIL, IM_LT); 538 L->top++; /* result of comparison */
544 } 539 }
545 return ttype(--(L->stack.top)) != LUA_T_NIL; 540 return ttype(--(L->top)) != LUA_T_NIL;
546} 541}
547 542
548static void auxsort (lua_State *L, Hash *a, int l, int u, lua_Object f) { 543static void auxsort (lua_State *L, Hash *a, int l, int u, lua_Object f) {
549 struct Stack *S = &L->stack; 544 StkId P = L->top++; /* temporary place for pivot */
550 StkId P = S->top - S->stack; /* temporary place for pivot */ 545 ttype(P) = LUA_T_NIL;
551 S->top++;
552 ttype(S->stack+P) = LUA_T_NIL;
553 while (l < u) { /* for tail recursion */ 546 while (l < u) { /* for tail recursion */
554 int i, j; 547 int i, j;
555 /* sort elements a[l], a[(l+u)/2] and a[u] */ 548 /* sort elements a[l], a[(l+u)/2] and a[u] */
@@ -557,22 +550,22 @@ static void auxsort (lua_State *L, Hash *a, int l, int u, lua_Object f) {
557 swap(L, a, l, u); /* a[u]<a[l] */ 550 swap(L, a, l, u); /* a[u]<a[l] */
558 if (u-l == 1) break; /* only 2 elements */ 551 if (u-l == 1) break; /* only 2 elements */
559 i = (l+u)/2; 552 i = (l+u)/2;
560 *(S->stack+P) = *luaH_getint(L, a, i); /* P = a[i] */ 553 *P = *luaH_getint(L, a, i); /* P = a[i] */
561 if (sort_comp(L, f, S->stack+P, luaH_getint(L, a, l))) /* a[i]<a[l]? */ 554 if (sort_comp(L, f, P, luaH_getint(L, a, l))) /* a[i]<a[l]? */
562 swap(L, a, l, i); 555 swap(L, a, l, i);
563 else if (sort_comp(L, f, luaH_getint(L, a, u), S->stack+P)) /* a[u]<a[i]? */ 556 else if (sort_comp(L, f, luaH_getint(L, a, u), P)) /* a[u]<a[i]? */
564 swap(L, a, i, u); 557 swap(L, a, i, u);
565 if (u-l == 2) break; /* only 3 elements */ 558 if (u-l == 2) break; /* only 3 elements */
566 *(S->stack+P) = *luaH_getint(L, a, i); /* save pivot on stack (GC) */ 559 *P = *luaH_getint(L, a, i); /* save pivot on stack (GC) */
567 swap(L, a, i, u-1); /* put median element as pivot (a[u-1]) */ 560 swap(L, a, i, u-1); /* put median element as pivot (a[u-1]) */
568 /* a[l] <= P == a[u-1] <= a[u], only needs to sort from l+1 to u-2 */ 561 /* a[l] <= P == a[u-1] <= a[u], only needs to sort from l+1 to u-2 */
569 i = l; j = u-1; 562 i = l; j = u-1;
570 for (;;) { /* invariant: a[l..i] <= P <= a[j..u] */ 563 for (;;) { /* invariant: a[l..i] <= P <= a[j..u] */
571 /* repeat i++ until a[i] >= P */ 564 /* repeat i++ until a[i] >= P */
572 while (sort_comp(L, f, luaH_getint(L, a, ++i), S->stack+P)) 565 while (sort_comp(L, f, luaH_getint(L, a, ++i), P))
573 if (i>u) lua_error(L, "invalid order function for sorting"); 566 if (i>u) lua_error(L, "invalid order function for sorting");
574 /* repeat j-- until a[j] <= P */ 567 /* repeat j-- until a[j] <= P */
575 while (sort_comp(L, f, (S->stack+P), luaH_getint(L, a, --j))) 568 while (sort_comp(L, f, P, luaH_getint(L, a, --j)))
576 if (j<l) lua_error(L, "invalid order function for sorting"); 569 if (j<l) lua_error(L, "invalid order function for sorting");
577 if (j<i) break; 570 if (j<i) break;
578 swap(L, a, i, j); 571 swap(L, a, i, j);
@@ -588,7 +581,7 @@ static void auxsort (lua_State *L, Hash *a, int l, int u, lua_Object f) {
588 } 581 }
589 auxsort(L, a, j, i, f); /* call recursively the smaller one */ 582 auxsort(L, a, j, i, f); /* call recursively the smaller one */
590 } /* repeat the routine for the larger one */ 583 } /* repeat the routine for the larger one */
591 S->top--; /* remove pivot from stack */ 584 L->top--; /* remove pivot from stack */
592} 585}
593 586
594static void luaB_sort (lua_State *L) { 587static void luaB_sort (lua_State *L) {