diff options
| -rw-r--r-- | lbuiltin.c | 198 |
1 files changed, 127 insertions, 71 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lbuiltin.c,v 1.79 1999/12/01 19:50:08 roberto Exp roberto $ | 2 | ** $Id: lbuiltin.c,v 1.80 1999/12/02 16:24:45 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 | */ |
| @@ -664,86 +664,143 @@ static void query_strings (lua_State *L) { | |||
| 664 | } | 664 | } |
| 665 | 665 | ||
| 666 | 666 | ||
| 667 | static void extra_services (lua_State *L) { | 667 | static const char *delimits = " \t\n,;"; |
| 668 | const char *service = luaL_check_string(L, 1); | ||
| 669 | switch (*service) { | ||
| 670 | case 'U': /* create a userdata with a given value/tag */ | ||
| 671 | lua_pushusertag(L, (void *)luaL_check_int(L, 2), luaL_check_int(L, 3)); | ||
| 672 | break; | ||
| 673 | 668 | ||
| 674 | case 'u': /* return the value of a userdata */ | 669 | static void skip (const char **pc) { |
| 675 | lua_pushnumber(L, (int)lua_getuserdata(L, lua_getparam(L, 2))); | 670 | while (**pc != '\0' && strchr(delimits, **pc)) (*pc)++; |
| 676 | break; | 671 | } |
| 677 | 672 | ||
| 678 | case 't': /* set `gc' tag method */ | 673 | static int getnum (const char **pc) { |
| 679 | lua_pushobject(L, lua_getparam(L, 3)); | 674 | int res = 0; |
| 680 | lua_settagmethod(L, luaL_check_int(L, 2), "gc"); | 675 | skip(pc); |
| 681 | break; | 676 | while (isdigit(**pc)) res = res*10 + (*(*pc)++) - '0'; |
| 677 | return res; | ||
| 678 | } | ||
| 679 | |||
| 680 | static int getreg (lua_State *L, const char **pc) { | ||
| 681 | skip(pc); | ||
| 682 | if (*(*pc)++ != 'r') lua_error(L, "`testC' expecting a register"); | ||
| 683 | return getnum(pc); | ||
| 684 | } | ||
| 682 | 685 | ||
| 683 | default: luaL_argerror(L, 1, "invalid service"); | 686 | static const char *getname (const char **pc) { |
| 684 | } | 687 | static char buff[30]; |
| 688 | int i = 0; | ||
| 689 | skip(pc); | ||
| 690 | while (**pc != '\0' && !strchr(delimits, **pc)) | ||
| 691 | buff[i++] = *(*pc)++; | ||
| 692 | buff[i] = '\0'; | ||
| 693 | return buff; | ||
| 685 | } | 694 | } |
| 686 | 695 | ||
| 687 | 696 | ||
| 688 | static void testC (lua_State *L) { | 697 | #define EQ(s1) (strcmp(s1, inst) == 0) |
| 689 | #define getnum(L, s) ((*s++) - '0') | ||
| 690 | #define getname(L, s) (nome[0] = *s++, nome) | ||
| 691 | 698 | ||
| 699 | static void testC (lua_State *L) { | ||
| 692 | lua_Object reg[10]; | 700 | lua_Object reg[10]; |
| 693 | char nome[2]; | 701 | const char *pc = luaL_check_string(L, 1); |
| 694 | const char *s = luaL_check_string(L, 1); | ||
| 695 | nome[1] = 0; | ||
| 696 | for (;;) { | 702 | for (;;) { |
| 697 | switch (*s++) { | 703 | const char *inst = getname(&pc); |
| 698 | case '0': case '1': case '2': case '3': case '4': | 704 | if EQ("") return; |
| 699 | case '5': case '6': case '7': case '8': case '9': | 705 | else if EQ("pushnum") { |
| 700 | lua_pushnumber(L, *(s-1) - '0'); | 706 | lua_pushnumber(L, getnum(&pc)); |
| 701 | break; | 707 | } |
| 702 | 708 | else if EQ("createtable") { | |
| 703 | case 'c': reg[getnum(L, s)] = lua_createtable(L); break; | 709 | reg[getreg(L, &pc)] = lua_createtable(L); |
| 704 | case 'C': { lua_CFunction f = lua_getcfunction(L, lua_getglobal(L, getname(L, s))); | 710 | } |
| 705 | lua_pushcclosure(L, f, getnum(L, s)); | 711 | else if EQ("closure") { |
| 706 | break; | 712 | lua_CFunction f = lua_getcfunction(L, lua_getglobal(L, getname(&pc))); |
| 707 | } | 713 | lua_pushcclosure(L, f, getnum(&pc)); |
| 708 | case 'P': reg[getnum(L, s)] = lua_pop(L); break; | 714 | } |
| 709 | case 'g': { int n=getnum(L, s); reg[n]=lua_getglobal(L, getname(L, s)); break; } | 715 | else if EQ("pop") { |
| 710 | case 'G': { int n = getnum(L, s); | 716 | reg[getreg(L, &pc)] = lua_pop(L); |
| 711 | reg[n] = lua_rawgetglobal(L, getname(L, s)); | 717 | } |
| 712 | break; | 718 | else if EQ("getglobal") { |
| 713 | } | 719 | int n = getreg(L, &pc); |
| 714 | case 'l': lua_pushnumber(L, lua_ref(L, 1)); reg[getnum(L, s)] = lua_pop(L); break; | 720 | reg[n] = lua_getglobal(L, getname(&pc)); |
| 715 | case 'L': lua_pushnumber(L, lua_ref(L, 0)); reg[getnum(L, s)] = lua_pop(L); break; | 721 | } |
| 716 | case 'r': { int n=getnum(L, s); | 722 | else if EQ("rawgetglobal") { |
| 717 | reg[n]=lua_getref(L, (int)lua_getnumber(L, reg[getnum(L, s)])); | 723 | int n = getreg(L, &pc); |
| 718 | break; | 724 | reg[n] = lua_rawgetglobal(L, getname(&pc)); |
| 719 | } | 725 | } |
| 720 | case 'u': lua_unref(L, (int)lua_getnumber(L, reg[getnum(L, s)])); | 726 | else if EQ("ref") { |
| 721 | break; | 727 | lua_pushnumber(L, lua_ref(L, 0)); |
| 722 | case 'p': { int n = getnum(L, s); reg[n] = lua_getparam(L, getnum(L, s)); break; } | 728 | reg[getreg(L, &pc)] = lua_pop(L); |
| 723 | case '=': lua_setglobal(L, getname(L, s)); break; | 729 | } |
| 724 | case 's': lua_pushstring(L, getname(L, s)); break; | 730 | else if EQ("reflock") { |
| 725 | case 'o': lua_pushobject(L, reg[getnum(L, s)]); break; | 731 | lua_pushnumber(L, lua_ref(L, 1)); |
| 726 | case 'f': lua_call(L, getname(L, s)); break; | 732 | reg[getreg(L, &pc)] = lua_pop(L); |
| 727 | case 'i': reg[getnum(L, s)] = lua_gettable(L); break; | 733 | } |
| 728 | case 'I': reg[getnum(L, s)] = lua_rawgettable(L); break; | 734 | else if EQ("getref") { |
| 729 | case 't': lua_settable(L); break; | 735 | int n = getreg(L, &pc); |
| 730 | case 'T': lua_rawsettable(L); break; | 736 | reg[n] = lua_getref(L, (int)lua_getnumber(L, reg[getreg(L, &pc)])); |
| 731 | case 'N' : lua_pushstring(L, lua_nextvar(L, lua_getstring(L, reg[getnum(L, s)]))); | 737 | } |
| 732 | break; | 738 | else if EQ("unref") { |
| 733 | case 'n' : { int n=getnum(L, s); | 739 | lua_unref(L, (int)lua_getnumber(L, reg[getreg(L, &pc)])); |
| 734 | n=lua_next(L, reg[n], (int)lua_getnumber(L, reg[getnum(L, s)])); | 740 | } |
| 735 | lua_pushnumber(L, n); break; | 741 | else if (EQ("getparam") || EQ("getresult")) { |
| 736 | } | 742 | int n = getreg(L, &pc); |
| 737 | case 'q' : { int n1=getnum(L, s); int n2=getnum(L, s); | 743 | reg[n] = lua_getparam(L, getnum(&pc)); |
| 738 | lua_pushnumber(L, lua_equal(L, reg[n1], reg[n2])); | 744 | } |
| 739 | break; | 745 | else if EQ("setglobal") { |
| 740 | } | 746 | lua_setglobal(L, getname(&pc)); |
| 741 | default: luaL_verror(L, "unknown command in `testC': %c", *(s-1)); | 747 | } |
| 742 | } | 748 | else if EQ("rawsetglobal") { |
| 743 | if (*s == 0) return; | 749 | lua_rawsetglobal(L, getname(&pc)); |
| 744 | if (*s++ != ' ') lua_error(L, "missing ` ' between commands in `testC'"); | 750 | } |
| 751 | else if EQ("pushstring") { | ||
| 752 | lua_pushstring(L, getname(&pc)); | ||
| 753 | } | ||
| 754 | else if EQ("pushreg") { | ||
| 755 | lua_pushobject(L, reg[getreg(L, &pc)]); | ||
| 756 | } | ||
| 757 | else if EQ("call") { | ||
| 758 | lua_call(L, getname(&pc)); | ||
| 759 | } | ||
| 760 | else if EQ("gettable") { | ||
| 761 | reg[getreg(L, &pc)] = lua_gettable(L); | ||
| 762 | } | ||
| 763 | else if EQ("rawgettable") { | ||
| 764 | reg[getreg(L, &pc)] = lua_rawgettable(L); | ||
| 765 | } | ||
| 766 | else if EQ("settable") { | ||
| 767 | lua_settable(L); | ||
| 768 | } | ||
| 769 | else if EQ("rawsettable") { | ||
| 770 | lua_rawsettable(L); | ||
| 771 | } | ||
| 772 | else if EQ("nextvar") { | ||
| 773 | lua_pushstring(L, lua_nextvar(L, lua_getstring(L, reg[getreg(L, &pc)]))); | ||
| 774 | } | ||
| 775 | else if EQ("next") { | ||
| 776 | int n = getreg(L, &pc); | ||
| 777 | n = lua_next(L, reg[n], (int)lua_getnumber(L, reg[getreg(L, &pc)])); | ||
| 778 | lua_pushnumber(L, n); | ||
| 779 | } | ||
| 780 | else if EQ("equal") { | ||
| 781 | int n1 = getreg(L, &pc); | ||
| 782 | int n2 = getreg(L, &pc); | ||
| 783 | lua_pushnumber(L, lua_equal(L, reg[n1], reg[n2])); | ||
| 784 | } | ||
| 785 | else if EQ("pushusertag") { | ||
| 786 | int val = getreg(L, &pc); | ||
| 787 | int tag = getreg(L, &pc); | ||
| 788 | lua_pushusertag(L, (void *)(int)lua_getnumber(L, reg[val]), | ||
| 789 | lua_getnumber(L, reg[tag])); | ||
| 790 | } | ||
| 791 | else if EQ("udataval") { | ||
| 792 | int n = getreg(L, &pc); | ||
| 793 | lua_pushnumber(L, (int)lua_getuserdata(L, reg[getreg(L, &pc)])); | ||
| 794 | reg[n] = lua_pop(L); | ||
| 795 | } | ||
| 796 | else if EQ("settagmethod") { | ||
| 797 | int n = getreg(L, &pc); | ||
| 798 | lua_settagmethod(L, lua_getnumber(L, reg[n]), getname(&pc)); | ||
| 799 | } | ||
| 800 | else luaL_verror(L, "unknown command in `testC': %.20s", inst); | ||
| 745 | } | 801 | } |
| 746 | } | 802 | } |
| 803 | |||
| 747 | 804 | ||
| 748 | /* }====================================================== */ | 805 | /* }====================================================== */ |
| 749 | #endif | 806 | #endif |
| @@ -752,7 +809,6 @@ static void testC (lua_State *L) { | |||
| 752 | 809 | ||
| 753 | static const struct luaL_reg builtin_funcs[] = { | 810 | static const struct luaL_reg builtin_funcs[] = { |
| 754 | #ifdef DEBUG | 811 | #ifdef DEBUG |
| 755 | {"extra", extra_services}, | ||
| 756 | {"hash", hash_query}, | 812 | {"hash", hash_query}, |
| 757 | {"querystr", query_strings}, | 813 | {"querystr", query_strings}, |
| 758 | {"querytab", table_query}, | 814 | {"querytab", table_query}, |
