diff options
Diffstat (limited to 'lbuiltin.c')
-rw-r--r-- | lbuiltin.c | 99 |
1 files changed, 46 insertions, 53 deletions
@@ -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 | ||
39 | static void pushtagstring (lua_State *L, TaggedString *s) { | 39 | static 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 | ||
416 | static void luaB_foreachi (lua_State *L) { | 416 | static 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 | ||
437 | static void luaB_foreach (lua_State *L) { | 434 | static 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 | ||
458 | static void luaB_foreachvar (lua_State *L) { | 454 | static 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 | ||
548 | static void auxsort (lua_State *L, Hash *a, int l, int u, lua_Object f) { | 543 | static 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 | ||
594 | static void luaB_sort (lua_State *L) { | 587 | static void luaB_sort (lua_State *L) { |