diff options
-rw-r--r-- | lbuiltin.c | 103 |
1 files changed, 51 insertions, 52 deletions
@@ -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 | ||
176 | static void luaB_rawsetglobal (lua_State *L) { | 175 | static 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 | ||
184 | static void luaB_getglobal (lua_State *L) { | 182 | static void luaB_getglobal (lua_State *L) { |
@@ -235,7 +233,8 @@ static void luaB_settagmethod (lua_State *L) { | |||
235 | } | 233 | } |
236 | 234 | ||
237 | static void luaB_gettagmethod (lua_State *L) { | 235 | static 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 | ||
241 | static void luaB_seterrormethod (lua_State *L) { | 240 | static void luaB_seterrormethod (lua_State *L) { |
@@ -252,7 +251,6 @@ static void luaB_collectgarbage (lua_State *L) { | |||
252 | static void luaB_type (lua_State *L) { | 251 | static 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 | ||
418 | static void luaB_foreachi (lua_State *L) { | 416 | static 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 | ||
440 | static void luaB_foreach (lua_State *L) { | 437 | static 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 | ||
461 | static void luaB_foreachvar (lua_State *L) { | 458 | static 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 | ||
532 | static int sort_comp (lua_State *L, lua_Object f, const TObject *a, const TObject *b) { | 529 | static 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 | ||
550 | static void auxsort (lua_State *L, Hash *a, int l, int u, lua_Object f) { | 548 | static 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 | ||
595 | static void luaB_sort (lua_State *L) { | 594 | static void luaB_sort (lua_State *L) { |