diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1999-12-01 17:50:08 -0200 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1999-12-01 17:50:08 -0200 |
| commit | fe237ad8085f34e89fcd3610a9771215af63f03f (patch) | |
| tree | f7ee5d8f7d1ffb74e94f049aa6f31eb03606cdf6 /lbuiltin.c | |
| parent | 3181dfefee40b9a424b80aa779c671f5f458904c (diff) | |
| download | lua-fe237ad8085f34e89fcd3610a9771215af63f03f.tar.gz lua-fe237ad8085f34e89fcd3610a9771215af63f03f.tar.bz2 lua-fe237ad8085f34e89fcd3610a9771215af63f03f.zip | |
fixed stack; first version.
Diffstat (limited to '')
| -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) { |
