diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-04-09 17:19:06 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-04-09 17:19:06 -0300 |
| commit | 8e1e61860643baeb443efcdbf51bc25b0c006a88 (patch) | |
| tree | 68a66e04c459311cf7d7b13c4f1655d73e9da8e4 | |
| parent | af4721f7a37834e5b5469f342caed0629932a4aa (diff) | |
| download | lua-8e1e61860643baeb443efcdbf51bc25b0c006a88.tar.gz lua-8e1e61860643baeb443efcdbf51bc25b0c006a88.tar.bz2 lua-8e1e61860643baeb443efcdbf51bc25b0c006a88.zip | |
`baselib' splited in `baselib' and `tablib'
| -rw-r--r-- | lbaselib.c | 296 | ||||
| -rw-r--r-- | lua.c | 3 | ||||
| -rw-r--r-- | lualib.h | 3 |
3 files changed, 5 insertions, 297 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lbaselib.c,v 1.64 2002/04/05 18:54:31 roberto Exp roberto $ | 2 | ** $Id: lbaselib.c,v 1.65 2002/04/09 19:46:56 roberto Exp roberto $ |
| 3 | ** Basic library | 3 | ** Basic library |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -432,302 +432,8 @@ static void base_open (lua_State *L) { | |||
| 432 | } | 432 | } |
| 433 | 433 | ||
| 434 | 434 | ||
| 435 | /* | ||
| 436 | ** {====================================================== | ||
| 437 | ** Coroutine library | ||
| 438 | ** ======================================================= | ||
| 439 | */ | ||
| 440 | |||
| 441 | |||
| 442 | static int luaB_resume (lua_State *L) { | ||
| 443 | lua_State *co = (lua_State *)lua_getfrombox(L, lua_upvalueindex(1)); | ||
| 444 | lua_settop(L, 0); | ||
| 445 | if (lua_resume(L, co) != 0) | ||
| 446 | lua_error(L, "error running co-routine"); | ||
| 447 | return lua_gettop(L); | ||
| 448 | } | ||
| 449 | |||
| 450 | |||
| 451 | |||
| 452 | static int gc_coroutine (lua_State *L) { | ||
| 453 | lua_State *co = (lua_State *)lua_getfrombox(L, 1); | ||
| 454 | lua_closethread(L, co); | ||
| 455 | return 0; | ||
| 456 | } | ||
| 457 | |||
| 458 | |||
| 459 | static int luaB_coroutine (lua_State *L) { | ||
| 460 | lua_State *NL; | ||
| 461 | int ref; | ||
| 462 | int i; | ||
| 463 | int n = lua_gettop(L); | ||
| 464 | luaL_arg_check(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), 1, | ||
| 465 | "Lua function expected"); | ||
| 466 | NL = lua_newthread(L); | ||
| 467 | if (NL == NULL) lua_error(L, "unable to create new thread"); | ||
| 468 | /* move function and arguments from L to NL */ | ||
| 469 | for (i=0; i<n; i++) { | ||
| 470 | ref = lua_ref(L, 1); | ||
| 471 | lua_getref(NL, ref); | ||
| 472 | lua_insert(NL, 1); | ||
| 473 | lua_unref(L, ref); | ||
| 474 | } | ||
| 475 | lua_cobegin(NL, n-1); | ||
| 476 | lua_newpointerbox(L, NL); | ||
| 477 | lua_pushliteral(L, "Coroutine"); | ||
| 478 | lua_rawget(L, LUA_REGISTRYINDEX); | ||
| 479 | lua_setmetatable(L, -2); | ||
| 480 | lua_pushcclosure(L, luaB_resume, 1); | ||
| 481 | return 1; | ||
| 482 | } | ||
| 483 | |||
| 484 | |||
| 485 | static int luaB_yield (lua_State *L) { | ||
| 486 | return lua_yield(L, lua_gettop(L)); | ||
| 487 | } | ||
| 488 | |||
| 489 | static const luaL_reg co_funcs[] = { | ||
| 490 | {"create", luaB_coroutine}, | ||
| 491 | {"yield", luaB_yield}, | ||
| 492 | {NULL, NULL} | ||
| 493 | }; | ||
| 494 | |||
| 495 | |||
| 496 | static void co_open (lua_State *L) { | ||
| 497 | luaL_opennamedlib(L, "co", co_funcs, 0); | ||
| 498 | /* create metatable for coroutines */ | ||
| 499 | lua_pushliteral(L, "Coroutine"); | ||
| 500 | lua_newtable(L); | ||
| 501 | lua_pushliteral(L, "__gc"); | ||
| 502 | lua_pushcfunction(L, gc_coroutine); | ||
| 503 | lua_rawset(L, -3); | ||
| 504 | lua_rawset(L, LUA_REGISTRYINDEX); | ||
| 505 | } | ||
| 506 | |||
| 507 | /* }====================================================== */ | ||
| 508 | |||
| 509 | |||
| 510 | /* | ||
| 511 | ** {====================================================== | ||
| 512 | ** Auxiliar table-related functions | ||
| 513 | */ | ||
| 514 | |||
| 515 | static int luaB_foreachi (lua_State *L) { | ||
| 516 | int n, i; | ||
| 517 | luaL_check_type(L, 1, LUA_TTABLE); | ||
| 518 | luaL_check_type(L, 2, LUA_TFUNCTION); | ||
| 519 | n = lua_getn(L, 1); | ||
| 520 | for (i=1; i<=n; i++) { | ||
| 521 | lua_pushvalue(L, 2); /* function */ | ||
| 522 | lua_pushnumber(L, i); /* 1st argument */ | ||
| 523 | lua_rawgeti(L, 1, i); /* 2nd argument */ | ||
| 524 | lua_rawcall(L, 2, 1); | ||
| 525 | if (!lua_isnil(L, -1)) | ||
| 526 | return 1; | ||
| 527 | lua_pop(L, 1); /* remove nil result */ | ||
| 528 | } | ||
| 529 | return 0; | ||
| 530 | } | ||
| 531 | |||
| 532 | |||
| 533 | static int luaB_foreach (lua_State *L) { | ||
| 534 | luaL_check_type(L, 1, LUA_TTABLE); | ||
| 535 | luaL_check_type(L, 2, LUA_TFUNCTION); | ||
| 536 | lua_pushnil(L); /* first key */ | ||
| 537 | for (;;) { | ||
| 538 | if (lua_next(L, 1) == 0) | ||
| 539 | return 0; | ||
| 540 | lua_pushvalue(L, 2); /* function */ | ||
| 541 | lua_pushvalue(L, -3); /* key */ | ||
| 542 | lua_pushvalue(L, -3); /* value */ | ||
| 543 | lua_rawcall(L, 2, 1); | ||
| 544 | if (!lua_isnil(L, -1)) | ||
| 545 | return 1; | ||
| 546 | lua_pop(L, 2); /* remove value and result */ | ||
| 547 | } | ||
| 548 | } | ||
| 549 | |||
| 550 | |||
| 551 | static void aux_setn (lua_State *L, int t, int n) { | ||
| 552 | lua_pushliteral(L, "n"); | ||
| 553 | lua_pushnumber(L, n); | ||
| 554 | lua_rawset(L, t); | ||
| 555 | } | ||
| 556 | |||
| 557 | |||
| 558 | static int luaB_getn (lua_State *L) { | ||
| 559 | luaL_check_type(L, 1, LUA_TTABLE); | ||
| 560 | lua_pushnumber(L, lua_getn(L, 1)); | ||
| 561 | return 1; | ||
| 562 | } | ||
| 563 | |||
| 564 | |||
| 565 | static int luaB_tinsert (lua_State *L) { | ||
| 566 | int v = lua_gettop(L); /* number of arguments */ | ||
| 567 | int n, pos; | ||
| 568 | luaL_check_type(L, 1, LUA_TTABLE); | ||
| 569 | n = lua_getn(L, 1); | ||
| 570 | if (v == 2) /* called with only 2 arguments */ | ||
| 571 | pos = n+1; | ||
| 572 | else { | ||
| 573 | v = 3; /* function may be called with more than 3 args */ | ||
| 574 | pos = luaL_check_int(L, 2); /* 2nd argument is the position */ | ||
| 575 | } | ||
| 576 | if (pos > n+1) n = pos-1; | ||
| 577 | aux_setn(L, 1, n+1); /* t.n = n+1 */ | ||
| 578 | for (; n>=pos; n--) { | ||
| 579 | lua_rawgeti(L, 1, n); | ||
| 580 | lua_rawseti(L, 1, n+1); /* t[n+1] = t[n] */ | ||
| 581 | } | ||
| 582 | lua_pushvalue(L, v); | ||
| 583 | lua_rawseti(L, 1, pos); /* t[pos] = v */ | ||
| 584 | return 0; | ||
| 585 | } | ||
| 586 | |||
| 587 | |||
| 588 | static int luaB_tremove (lua_State *L) { | ||
| 589 | int pos, n; | ||
| 590 | luaL_check_type(L, 1, LUA_TTABLE); | ||
| 591 | n = lua_getn(L, 1); | ||
| 592 | pos = luaL_opt_int(L, 2, n); | ||
| 593 | if (n <= 0) return 0; /* table is `empty' */ | ||
| 594 | aux_setn(L, 1, n-1); /* t.n = n-1 */ | ||
| 595 | lua_rawgeti(L, 1, pos); /* result = t[pos] */ | ||
| 596 | for ( ;pos<n; pos++) { | ||
| 597 | lua_rawgeti(L, 1, pos+1); | ||
| 598 | lua_rawseti(L, 1, pos); /* a[pos] = a[pos+1] */ | ||
| 599 | } | ||
| 600 | lua_pushnil(L); | ||
| 601 | lua_rawseti(L, 1, n); /* t[n] = nil */ | ||
| 602 | return 1; | ||
| 603 | } | ||
| 604 | |||
| 605 | |||
| 606 | |||
| 607 | /* | ||
| 608 | ** {====================================================== | ||
| 609 | ** Quicksort | ||
| 610 | ** (based on `Algorithms in MODULA-3', Robert Sedgewick; | ||
| 611 | ** Addison-Wesley, 1993.) | ||
| 612 | */ | ||
| 613 | |||
| 614 | |||
| 615 | static void set2 (lua_State *L, int i, int j) { | ||
| 616 | lua_rawseti(L, 1, i); | ||
| 617 | lua_rawseti(L, 1, j); | ||
| 618 | } | ||
| 619 | |||
| 620 | static int sort_comp (lua_State *L, int a, int b) { | ||
| 621 | /* WARNING: the caller (auxsort) must ensure stack space */ | ||
| 622 | if (!lua_isnoneornil(L, 2)) { /* function? */ | ||
| 623 | int res; | ||
| 624 | lua_pushvalue(L, 2); | ||
| 625 | lua_pushvalue(L, a-1); /* -1 to compensate function */ | ||
| 626 | lua_pushvalue(L, b-2); /* -2 to compensate function and `a' */ | ||
| 627 | lua_rawcall(L, 2, 1); | ||
| 628 | res = lua_toboolean(L, -1); | ||
| 629 | lua_pop(L, 1); | ||
| 630 | return res; | ||
| 631 | } | ||
| 632 | else /* a < b? */ | ||
| 633 | return lua_lessthan(L, a, b); | ||
| 634 | } | ||
| 635 | |||
| 636 | static void auxsort (lua_State *L, int l, int u) { | ||
| 637 | while (l < u) { /* for tail recursion */ | ||
| 638 | int i, j; | ||
| 639 | /* sort elements a[l], a[(l+u)/2] and a[u] */ | ||
| 640 | lua_rawgeti(L, 1, l); | ||
| 641 | lua_rawgeti(L, 1, u); | ||
| 642 | if (sort_comp(L, -1, -2)) /* a[u] < a[l]? */ | ||
| 643 | set2(L, l, u); /* swap a[l] - a[u] */ | ||
| 644 | else | ||
| 645 | lua_pop(L, 2); | ||
| 646 | if (u-l == 1) break; /* only 2 elements */ | ||
| 647 | i = (l+u)/2; | ||
| 648 | lua_rawgeti(L, 1, i); | ||
| 649 | lua_rawgeti(L, 1, l); | ||
| 650 | if (sort_comp(L, -2, -1)) /* a[i]<a[l]? */ | ||
| 651 | set2(L, i, l); | ||
| 652 | else { | ||
| 653 | lua_pop(L, 1); /* remove a[l] */ | ||
| 654 | lua_rawgeti(L, 1, u); | ||
| 655 | if (sort_comp(L, -1, -2)) /* a[u]<a[i]? */ | ||
| 656 | set2(L, i, u); | ||
| 657 | else | ||
| 658 | lua_pop(L, 2); | ||
| 659 | } | ||
| 660 | if (u-l == 2) break; /* only 3 elements */ | ||
| 661 | lua_rawgeti(L, 1, i); /* Pivot */ | ||
| 662 | lua_pushvalue(L, -1); | ||
| 663 | lua_rawgeti(L, 1, u-1); | ||
| 664 | set2(L, i, u-1); | ||
| 665 | /* a[l] <= P == a[u-1] <= a[u], only need to sort from l+1 to u-2 */ | ||
| 666 | i = l; j = u-1; | ||
| 667 | for (;;) { /* invariant: a[l..i] <= P <= a[j..u] */ | ||
| 668 | /* repeat ++i until a[i] >= P */ | ||
| 669 | while (lua_rawgeti(L, 1, ++i), sort_comp(L, -1, -2)) { | ||
| 670 | if (i>u) lua_error(L, "invalid order function for sorting"); | ||
| 671 | lua_pop(L, 1); /* remove a[i] */ | ||
| 672 | } | ||
| 673 | /* repeat --j until a[j] <= P */ | ||
| 674 | while (lua_rawgeti(L, 1, --j), sort_comp(L, -3, -1)) { | ||
| 675 | if (j<l) lua_error(L, "invalid order function for sorting"); | ||
| 676 | lua_pop(L, 1); /* remove a[j] */ | ||
| 677 | } | ||
| 678 | if (j<i) { | ||
| 679 | lua_pop(L, 3); /* pop pivot, a[i], a[j] */ | ||
| 680 | break; | ||
| 681 | } | ||
| 682 | set2(L, i, j); | ||
| 683 | } | ||
| 684 | lua_rawgeti(L, 1, u-1); | ||
| 685 | lua_rawgeti(L, 1, i); | ||
| 686 | set2(L, u-1, i); /* swap pivot (a[u-1]) with a[i] */ | ||
| 687 | /* a[l..i-1] <= a[i] == P <= a[i+1..u] */ | ||
| 688 | /* adjust so that smaller half is in [j..i] and larger one in [l..u] */ | ||
| 689 | if (i-l < u-i) { | ||
| 690 | j=l; i=i-1; l=i+2; | ||
| 691 | } | ||
| 692 | else { | ||
| 693 | j=i+1; i=u; u=j-2; | ||
| 694 | } | ||
| 695 | auxsort(L, j, i); /* call recursively the smaller one */ | ||
| 696 | } /* repeat the routine for the larger one */ | ||
| 697 | } | ||
| 698 | |||
| 699 | static int luaB_sort (lua_State *L) { | ||
| 700 | int n; | ||
| 701 | luaL_check_type(L, 1, LUA_TTABLE); | ||
| 702 | n = lua_getn(L, 1); | ||
| 703 | if (!lua_isnone(L, 2)) /* is there a 2nd argument? */ | ||
| 704 | luaL_check_type(L, 2, LUA_TFUNCTION); | ||
| 705 | lua_settop(L, 2); /* make sure there is two arguments */ | ||
| 706 | auxsort(L, 1, n); | ||
| 707 | return 0; | ||
| 708 | } | ||
| 709 | |||
| 710 | /* }====================================================== */ | ||
| 711 | |||
| 712 | |||
| 713 | static const luaL_reg array_funcs[] = { | ||
| 714 | {"foreach", luaB_foreach}, | ||
| 715 | {"foreachi", luaB_foreachi}, | ||
| 716 | {"getn", luaB_getn}, | ||
| 717 | {"sort", luaB_sort}, | ||
| 718 | {"insert", luaB_tinsert}, | ||
| 719 | {"remove", luaB_tremove}, | ||
| 720 | {NULL, NULL} | ||
| 721 | }; | ||
| 722 | |||
| 723 | /* }====================================================== */ | ||
| 724 | |||
| 725 | |||
| 726 | |||
| 727 | LUALIB_API int lua_baselibopen (lua_State *L) { | 435 | LUALIB_API int lua_baselibopen (lua_State *L) { |
| 728 | base_open(L); | 436 | base_open(L); |
| 729 | co_open(L); | ||
| 730 | luaL_opennamedlib(L, "tab", array_funcs, 0); | ||
| 731 | /* `require' needs an empty table as upvalue */ | 437 | /* `require' needs an empty table as upvalue */ |
| 732 | lua_newtable(L); | 438 | lua_newtable(L); |
| 733 | lua_pushcclosure(L, luaB_require, 1); | 439 | lua_pushcclosure(L, luaB_require, 1); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lua.c,v 1.80 2002/04/01 14:42:33 roberto Exp roberto $ | 2 | ** $Id: lua.c,v 1.81 2002/04/05 18:54:31 roberto Exp roberto $ |
| 3 | ** Lua stand-alone interpreter | 3 | ** Lua stand-alone interpreter |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -342,6 +342,7 @@ static void register_getargs (char *argv[]) { | |||
| 342 | 342 | ||
| 343 | static void openstdlibs (lua_State *l) { | 343 | static void openstdlibs (lua_State *l) { |
| 344 | lua_baselibopen(l); | 344 | lua_baselibopen(l); |
| 345 | lua_tablibopen(l); | ||
| 345 | lua_iolibopen(l); | 346 | lua_iolibopen(l); |
| 346 | lua_strlibopen(l); | 347 | lua_strlibopen(l); |
| 347 | lua_mathlibopen(l); | 348 | lua_mathlibopen(l); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lualib.h,v 1.20 2001/03/06 20:09:38 roberto Exp roberto $ | 2 | ** $Id: lualib.h,v 1.21 2001/03/26 14:31:49 roberto Exp roberto $ |
| 3 | ** Lua standard libraries | 3 | ** Lua standard libraries |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -19,6 +19,7 @@ | |||
| 19 | #define LUA_ALERT "_ALERT" | 19 | #define LUA_ALERT "_ALERT" |
| 20 | 20 | ||
| 21 | LUALIB_API int lua_baselibopen (lua_State *L); | 21 | LUALIB_API int lua_baselibopen (lua_State *L); |
| 22 | LUALIB_API int lua_tablibopen (lua_State *L); | ||
| 22 | LUALIB_API int lua_iolibopen (lua_State *L); | 23 | LUALIB_API int lua_iolibopen (lua_State *L); |
| 23 | LUALIB_API int lua_strlibopen (lua_State *L); | 24 | LUALIB_API int lua_strlibopen (lua_State *L); |
| 24 | LUALIB_API int lua_mathlibopen (lua_State *L); | 25 | LUALIB_API int lua_mathlibopen (lua_State *L); |
