diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1994-11-07 13:20:56 -0200 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1994-11-07 13:20:56 -0200 |
| commit | 9ffba7a3dbdfa68595cd8cec26bd99689ce5fd08 (patch) | |
| tree | b9563a506ebd0d6fbc0c99a7966953abe63cb48d | |
| parent | de4e2305c512e23263842c82896bd0a96d960b6f (diff) | |
| download | lua-9ffba7a3dbdfa68595cd8cec26bd99689ce5fd08.tar.gz lua-9ffba7a3dbdfa68595cd8cec26bd99689ce5fd08.tar.bz2 lua-9ffba7a3dbdfa68595cd8cec26bd99689ce5fd08.zip | |
first implementation of 'fallbacks'
| -rw-r--r-- | opcode.c | 317 |
1 files changed, 202 insertions, 115 deletions
| @@ -3,7 +3,7 @@ | |||
| 3 | ** TecCGraf - PUC-Rio | 3 | ** TecCGraf - PUC-Rio |
| 4 | */ | 4 | */ |
| 5 | 5 | ||
| 6 | char *rcs_opcode="$Id: opcode.c,v 3.1 1994/11/02 20:30:53 roberto Exp roberto $"; | 6 | char *rcs_opcode="$Id: opcode.c,v 3.2 1994/11/04 10:47:49 roberto Exp roberto $"; |
| 7 | 7 | ||
| 8 | #include <stdio.h> | 8 | #include <stdio.h> |
| 9 | #include <stdlib.h> | 9 | #include <stdlib.h> |
| @@ -19,6 +19,7 @@ char *rcs_opcode="$Id: opcode.c,v 3.1 1994/11/02 20:30:53 roberto Exp roberto $" | |||
| 19 | #include "inout.h" | 19 | #include "inout.h" |
| 20 | #include "table.h" | 20 | #include "table.h" |
| 21 | #include "lua.h" | 21 | #include "lua.h" |
| 22 | #include "fallback.h" | ||
| 22 | 23 | ||
| 23 | #define tonumber(o) ((tag(o) != LUA_T_NUMBER) && (lua_tonumber(o) != 0)) | 24 | #define tonumber(o) ((tag(o) != LUA_T_NUMBER) && (lua_tonumber(o) != 0)) |
| 24 | #define tostring(o) ((tag(o) != LUA_T_STRING) && (lua_tostring(o) != 0)) | 25 | #define tostring(o) ((tag(o) != LUA_T_STRING) && (lua_tostring(o) != 0)) |
| @@ -26,9 +27,9 @@ char *rcs_opcode="$Id: opcode.c,v 3.1 1994/11/02 20:30:53 roberto Exp roberto $" | |||
| 26 | 27 | ||
| 27 | #define STACK_BUFFER (STACKGAP+128) | 28 | #define STACK_BUFFER (STACKGAP+128) |
| 28 | 29 | ||
| 29 | static Long maxstack; | 30 | static Long maxstack = 0L; |
| 30 | static Object *stack=NULL; | 31 | static Object *stack = NULL; |
| 31 | static Object *top; | 32 | static Object *top = NULL; |
| 32 | 33 | ||
| 33 | 34 | ||
| 34 | static int CBase = 0; /* when Lua calls C or C calls Lua, points to the */ | 35 | static int CBase = 0; /* when Lua calls C or C calls Lua, points to the */ |
| @@ -40,11 +41,69 @@ static jmp_buf *errorJmp = NULL; /* current error recover point */ | |||
| 40 | 41 | ||
| 41 | 42 | ||
| 42 | static int lua_execute (Byte *pc, int base); | 43 | static int lua_execute (Byte *pc, int base); |
| 44 | static void do_call (Object *func, int base, int nResults, int whereRes); | ||
| 43 | 45 | ||
| 44 | 46 | ||
| 47 | /* | ||
| 48 | ** Fallbacks | ||
| 49 | */ | ||
| 50 | |||
| 51 | static struct FB { | ||
| 52 | char *kind; | ||
| 53 | Object function; | ||
| 54 | } fallBacks[] = { | ||
| 55 | #define FB_ERROR 0 | ||
| 56 | {"error", {LUA_T_CFUNCTION, luaI_errorFB}}, | ||
| 57 | #define FB_INDEX 1 | ||
| 58 | {"index", {LUA_T_CFUNCTION, luaI_indexFB}}, | ||
| 59 | #define FB_GETTABLE 2 | ||
| 60 | {"gettable", {LUA_T_CFUNCTION, luaI_gettableFB}}, | ||
| 61 | #define FB_ARITH 3 | ||
| 62 | {"arith", {LUA_T_CFUNCTION, luaI_arithFB}}, | ||
| 63 | #define FB_ORDER 4 | ||
| 64 | {"order", {LUA_T_CFUNCTION, luaI_orderFB}}, | ||
| 65 | #define FB_CONCAT 5 | ||
| 66 | {"concat", {LUA_T_CFUNCTION, luaI_concatFB}}, | ||
| 67 | #define FB_UNMINUS 6 | ||
| 68 | {"unminus", {LUA_T_CFUNCTION, luaI_arithFB}}, | ||
| 69 | #define FB_SETTABLE 7 | ||
| 70 | {"settable", {LUA_T_CFUNCTION, luaI_gettableFB}} | ||
| 71 | }; | ||
| 72 | |||
| 73 | #define N_FB (sizeof(fallBacks)/sizeof(struct FB)) | ||
| 74 | |||
| 75 | |||
| 76 | void luaI_setfallback (void) | ||
| 77 | { | ||
| 78 | int i; | ||
| 79 | char *name = lua_getstring(lua_getparam(1)); | ||
| 80 | lua_Object func = lua_getparam(2); | ||
| 81 | if (name == NULL || !(lua_isfunction(func) || lua_iscfunction(func))) | ||
| 82 | { | ||
| 83 | lua_pushnil(); | ||
| 84 | return; | ||
| 85 | } | ||
| 86 | for (i=0; i<N_FB; i++) | ||
| 87 | { | ||
| 88 | if (strcmp(fallBacks[i].kind, name) == 0) | ||
| 89 | { | ||
| 90 | lua_pushobject(&fallBacks[i].function); | ||
| 91 | fallBacks[i].function = *func; | ||
| 92 | return; | ||
| 93 | } | ||
| 94 | } | ||
| 95 | /* name not found */ | ||
| 96 | lua_pushnil(); | ||
| 97 | } | ||
| 98 | |||
| 99 | /* | ||
| 100 | ** Error messages | ||
| 101 | */ | ||
| 102 | |||
| 45 | static void lua_message (char *s) | 103 | static void lua_message (char *s) |
| 46 | { | 104 | { |
| 47 | fprintf (stderr, "lua: %s\n", s); | 105 | lua_pushstring(s); |
| 106 | do_call(&fallBacks[FB_ERROR].function, (top-stack)-1, 0, (top-stack)-1); | ||
| 48 | } | 107 | } |
| 49 | 108 | ||
| 50 | /* | 109 | /* |
| @@ -81,11 +140,12 @@ static void lua_initstack (void) | |||
| 81 | */ | 140 | */ |
| 82 | static void lua_checkstack (Word n) | 141 | static void lua_checkstack (Word n) |
| 83 | { | 142 | { |
| 84 | if (stack == NULL) | ||
| 85 | lua_initstack(); | ||
| 86 | if (n > maxstack) | 143 | if (n > maxstack) |
| 87 | { | 144 | { |
| 88 | int t = top-stack; | 145 | int t; |
| 146 | if (stack == NULL) | ||
| 147 | lua_initstack(); | ||
| 148 | t = top-stack; | ||
| 89 | maxstack *= 2; | 149 | maxstack *= 2; |
| 90 | stack = (Object *)realloc(stack, maxstack*sizeof(Object)); | 150 | stack = (Object *)realloc(stack, maxstack*sizeof(Object)); |
| 91 | if (stack == NULL) | 151 | if (stack == NULL) |
| @@ -101,11 +161,22 @@ static void lua_checkstack (Word n) | |||
| 101 | */ | 161 | */ |
| 102 | static char *lua_strconc (char *l, char *r) | 162 | static char *lua_strconc (char *l, char *r) |
| 103 | { | 163 | { |
| 104 | static char buffer[1024]; | 164 | static char *buffer = NULL; |
| 165 | static int buffer_size = 0; | ||
| 105 | int n = strlen(l)+strlen(r)+1; | 166 | int n = strlen(l)+strlen(r)+1; |
| 106 | if (n > 1024) | 167 | if (n > buffer_size) |
| 107 | lua_error ("string too large"); | 168 | { |
| 108 | return strcat(strcpy(buffer,l),r); | 169 | buffer_size = n; |
| 170 | if (buffer != NULL) | ||
| 171 | free(buffer); | ||
| 172 | buffer = (char *)malloc(buffer_size); | ||
| 173 | if (buffer == NULL) | ||
| 174 | { | ||
| 175 | buffer_size = 0; | ||
| 176 | lua_error("concat - not enough memory"); | ||
| 177 | } | ||
| 178 | } | ||
| 179 | return strcat(strcpy(buffer,l),r); | ||
| 109 | } | 180 | } |
| 110 | 181 | ||
| 111 | 182 | ||
| @@ -138,11 +209,11 @@ static int lua_tostring (Object *obj) | |||
| 138 | { | 209 | { |
| 139 | static char s[256]; | 210 | static char s[256]; |
| 140 | if (tag(obj) != LUA_T_NUMBER) | 211 | if (tag(obj) != LUA_T_NUMBER) |
| 141 | lua_reportbug ("unexpected type at conversion to string"); | 212 | return 1; |
| 142 | if ((int) nvalue(obj) == nvalue(obj)) | 213 | if ((int) nvalue(obj) == nvalue(obj)) |
| 143 | sprintf (s, "%d", (int) nvalue(obj)); | 214 | sprintf (s, "%d", (int) nvalue(obj)); |
| 144 | else | 215 | else |
| 145 | sprintf (s, "%g", nvalue(obj)); | 216 | sprintf (s, "%g", nvalue(obj)); |
| 146 | svalue(obj) = lua_createstring(s); | 217 | svalue(obj) = lua_createstring(s); |
| 147 | if (svalue(obj) == NULL) | 218 | if (svalue(obj) == NULL) |
| 148 | return 1; | 219 | return 1; |
| @@ -217,32 +288,35 @@ static void do_call (Object *func, int base, int nResults, int whereRes) | |||
| 217 | */ | 288 | */ |
| 218 | static void pushsubscript (void) | 289 | static void pushsubscript (void) |
| 219 | { | 290 | { |
| 220 | Object *h; | ||
| 221 | if (tag(top-2) != LUA_T_ARRAY) | 291 | if (tag(top-2) != LUA_T_ARRAY) |
| 222 | lua_reportbug ("indexed expression not a table"); | 292 | do_call(&fallBacks[FB_GETTABLE].function, (top-stack)-2, 1, (top-stack)-2); |
| 223 | h = lua_hashget (avalue(top-2), top-1); | 293 | else |
| 224 | --top; | 294 | { |
| 225 | *(top-1) = *h; | 295 | Object *h = lua_hashget(avalue(top-2), top-1); |
| 296 | if (h == NULL) | ||
| 297 | do_call(&fallBacks[FB_INDEX].function, (top-stack)-2, 1, (top-stack)-2); | ||
| 298 | else | ||
| 299 | { | ||
| 300 | --top; | ||
| 301 | *(top-1) = *h; | ||
| 302 | } | ||
| 303 | } | ||
| 226 | } | 304 | } |
| 227 | 305 | ||
| 228 | 306 | ||
| 229 | /* | 307 | /* |
| 230 | ** Function to store indexed based on values at the top | 308 | ** Function to store indexed based on values at the top |
| 231 | */ | 309 | */ |
| 232 | int lua_storesubscript (void) | 310 | static void storesubscript (void) |
| 233 | { | 311 | { |
| 234 | if (tag(top-3) != LUA_T_ARRAY) | 312 | if (tag(top-3) != LUA_T_ARRAY) |
| 235 | { | 313 | do_call(&fallBacks[FB_SETTABLE].function, (top-stack)-3, 0, (top-stack)-3); |
| 236 | lua_reportbug ("indexed expression not a table"); | 314 | else |
| 237 | return 1; | ||
| 238 | } | ||
| 239 | { | 315 | { |
| 240 | Object *h = lua_hashdefine (avalue(top-3), top-2); | 316 | Object *h = lua_hashdefine (avalue(top-3), top-2); |
| 241 | if (h == NULL) return 1; | ||
| 242 | *h = *(top-1); | 317 | *h = *(top-1); |
| 318 | top -= 3; | ||
| 243 | } | 319 | } |
| 244 | top -= 3; | ||
| 245 | return 0; | ||
| 246 | } | 320 | } |
| 247 | 321 | ||
| 248 | 322 | ||
| @@ -273,10 +347,12 @@ static int do_protectedrun (Object *function, int nResults) | |||
| 273 | { | 347 | { |
| 274 | if (function == NULL) | 348 | if (function == NULL) |
| 275 | { | 349 | { |
| 350 | tag(&f) = LUA_T_FUNCTION; | ||
| 351 | bvalue(&f) = lua_parse(); | ||
| 276 | function = &f; | 352 | function = &f; |
| 277 | tag(function) = LUA_T_FUNCTION; | ||
| 278 | bvalue(function) = lua_parse(); | ||
| 279 | } | 353 | } |
| 354 | else | ||
| 355 | tag(&f) = LUA_T_NIL; | ||
| 280 | do_call(function, CBase, nResults, CBase); | 356 | do_call(function, CBase, nResults, CBase); |
| 281 | CnResults = (top-stack) - CBase; /* number of results */ | 357 | CnResults = (top-stack) - CBase; /* number of results */ |
| 282 | CBase += CnResults; /* incorporate results on the stack */ | 358 | CBase += CnResults; /* incorporate results on the stack */ |
| @@ -288,6 +364,8 @@ static int do_protectedrun (Object *function, int nResults) | |||
| 288 | top = stack+CBase; | 364 | top = stack+CBase; |
| 289 | status = 1; | 365 | status = 1; |
| 290 | } | 366 | } |
| 367 | if (tag(&f) == LUA_T_FUNCTION) | ||
| 368 | free(bvalue(&f)); | ||
| 291 | errorJmp = oldErr; | 369 | errorJmp = oldErr; |
| 292 | return status; | 370 | return status; |
| 293 | } | 371 | } |
| @@ -402,16 +480,6 @@ void *lua_getuserdata (Object *object) | |||
| 402 | } | 480 | } |
| 403 | 481 | ||
| 404 | /* | 482 | /* |
| 405 | ** Given an object handle, return its table. On error, return NULL. | ||
| 406 | */ | ||
| 407 | void *lua_gettable (Object *object) | ||
| 408 | { | ||
| 409 | if (object == NULL) return NULL; | ||
| 410 | if (tag(object) != LUA_T_ARRAY) return NULL; | ||
| 411 | else return (avalue(object)); | ||
| 412 | } | ||
| 413 | |||
| 414 | /* | ||
| 415 | ** Get a global object. Return the object handle or NULL on error. | 483 | ** Get a global object. Return the object handle or NULL on error. |
| 416 | */ | 484 | */ |
| 417 | Object *lua_getglobal (char *name) | 485 | Object *lua_getglobal (char *name) |
| @@ -473,16 +541,6 @@ int lua_pushuserdata (void *u) | |||
| 473 | } | 541 | } |
| 474 | 542 | ||
| 475 | /* | 543 | /* |
| 476 | ** Push an object (tag=userdata) to stack. Return 0 on success or 1 on error. | ||
| 477 | */ | ||
| 478 | int lua_pushtable (void *t) | ||
| 479 | { | ||
| 480 | lua_checkstack(top-stack+1); | ||
| 481 | tag(top) = LUA_T_ARRAY; avalue(top++) = t; | ||
| 482 | return 0; | ||
| 483 | } | ||
| 484 | |||
| 485 | /* | ||
| 486 | ** Push an object to stack. | 544 | ** Push an object to stack. |
| 487 | */ | 545 | */ |
| 488 | int lua_pushobject (Object *o) | 546 | int lua_pushobject (Object *o) |
| @@ -557,6 +615,35 @@ int lua_type (lua_Object o) | |||
| 557 | } | 615 | } |
| 558 | 616 | ||
| 559 | 617 | ||
| 618 | static void call_arith (char *op) | ||
| 619 | { | ||
| 620 | lua_pushstring(op); | ||
| 621 | do_call(&fallBacks[FB_ARITH].function, (top-stack)-3, 1, (top-stack)-3); | ||
| 622 | } | ||
| 623 | |||
| 624 | static void comparison (lua_Type tag_less, lua_Type tag_equal, | ||
| 625 | lua_Type tag_great, char *op) | ||
| 626 | { | ||
| 627 | Object *l = top-2; | ||
| 628 | Object *r = top-1; | ||
| 629 | int result; | ||
| 630 | if (tag(l) == LUA_T_NUMBER && tag(r) == LUA_T_NUMBER) | ||
| 631 | result = (nvalue(l) < nvalue(r)) ? -1 : (nvalue(l) == nvalue(r)) ? 0 : 1; | ||
| 632 | else if (tostring(l) || tostring(r)) | ||
| 633 | { | ||
| 634 | lua_pushstring(op); | ||
| 635 | do_call(&fallBacks[FB_ORDER].function, (top-stack)-3, 1, (top-stack)-3); | ||
| 636 | return; | ||
| 637 | } | ||
| 638 | else | ||
| 639 | result = strcmp(svalue(l), svalue(r)); | ||
| 640 | top--; | ||
| 641 | nvalue(top-1) = 1; | ||
| 642 | tag(top-1) = (result < 0) ? tag_less : (result == 0) ? tag_equal : tag_great; | ||
| 643 | } | ||
| 644 | |||
| 645 | |||
| 646 | |||
| 560 | /* | 647 | /* |
| 561 | ** Execute the given opcode, until a RET. Parameters are between | 648 | ** Execute the given opcode, until a RET. Parameters are between |
| 562 | ** [stack+base,top). Returns n such that the the results are between | 649 | ** [stack+base,top). Returns n such that the the results are between |
| @@ -656,23 +743,26 @@ static int lua_execute (Byte *pc, int base) | |||
| 656 | break; | 743 | break; |
| 657 | 744 | ||
| 658 | case STOREINDEXED0: | 745 | case STOREINDEXED0: |
| 659 | { | 746 | storesubscript(); |
| 660 | int s = lua_storesubscript(); | 747 | break; |
| 661 | if (s == 1) return 1; | ||
| 662 | } | ||
| 663 | break; | ||
| 664 | 748 | ||
| 665 | case STOREINDEXED: | 749 | case STOREINDEXED: |
| 666 | { | 750 | { |
| 667 | int n = *pc++; | 751 | int n = *pc++; |
| 668 | if (tag(top-3-n) != LUA_T_ARRAY) | 752 | if (tag(top-3-n) != LUA_T_ARRAY) |
| 669 | lua_reportbug ("indexed expression not a table"); | 753 | { |
| 754 | *(top+1) = *(top-1); | ||
| 755 | *(top) = *(top-2-n); | ||
| 756 | *(top-1) = *(top-3-n); | ||
| 757 | top += 2; | ||
| 758 | do_call(&fallBacks[FB_SETTABLE].function, (top-stack)-3, 0, (top-stack)-3); | ||
| 759 | } | ||
| 760 | else | ||
| 670 | { | 761 | { |
| 671 | Object *h = lua_hashdefine (avalue(top-3-n), top-2-n); | 762 | Object *h = lua_hashdefine (avalue(top-3-n), top-2-n); |
| 672 | if (h == NULL) return 1; | ||
| 673 | *h = *(top-1); | 763 | *h = *(top-1); |
| 764 | top--; | ||
| 674 | } | 765 | } |
| 675 | top--; | ||
| 676 | } | 766 | } |
| 677 | break; | 767 | break; |
| 678 | 768 | ||
| @@ -766,48 +856,33 @@ static int lua_execute (Byte *pc, int base) | |||
| 766 | } | 856 | } |
| 767 | break; | 857 | break; |
| 768 | 858 | ||
| 769 | case LTOP: | 859 | case LTOP: |
| 770 | { | 860 | comparison(LUA_T_NUMBER, LUA_T_NIL, LUA_T_NIL, "<"); |
| 771 | Object *l = top-2; | 861 | break; |
| 772 | Object *r = top-1; | ||
| 773 | --top; | ||
| 774 | if (tag(l) == LUA_T_NUMBER && tag(r) == LUA_T_NUMBER) | ||
| 775 | tag(top-1) = (nvalue(l) < nvalue(r)) ? LUA_T_NUMBER : LUA_T_NIL; | ||
| 776 | else | ||
| 777 | { | ||
| 778 | if (tostring(l) || tostring(r)) | ||
| 779 | return 1; | ||
| 780 | tag(top-1) = (strcmp (svalue(l), svalue(r)) < 0) ? LUA_T_NUMBER : LUA_T_NIL; | ||
| 781 | } | ||
| 782 | nvalue(top-1) = 1; | ||
| 783 | } | ||
| 784 | break; | ||
| 785 | 862 | ||
| 786 | case LEOP: | 863 | case LEOP: |
| 787 | { | 864 | comparison(LUA_T_NUMBER, LUA_T_NUMBER, LUA_T_NIL, "<="); |
| 788 | Object *l = top-2; | 865 | break; |
| 789 | Object *r = top-1; | 866 | |
| 790 | --top; | 867 | case GTOP: |
| 791 | if (tag(l) == LUA_T_NUMBER && tag(r) == LUA_T_NUMBER) | 868 | comparison(LUA_T_NIL, LUA_T_NIL, LUA_T_NUMBER, ">"); |
| 792 | tag(top-1) = (nvalue(l) <= nvalue(r)) ? LUA_T_NUMBER : LUA_T_NIL; | 869 | break; |
| 793 | else | 870 | |
| 794 | { | 871 | case GEOP: |
| 795 | if (tostring(l) || tostring(r)) | 872 | comparison(LUA_T_NIL, LUA_T_NUMBER, LUA_T_NUMBER, ">="); |
| 796 | return 1; | 873 | break; |
| 797 | tag(top-1) = (strcmp (svalue(l), svalue(r)) <= 0) ? LUA_T_NUMBER : LUA_T_NIL; | ||
| 798 | } | ||
| 799 | nvalue(top-1) = 1; | ||
| 800 | } | ||
| 801 | break; | ||
| 802 | 874 | ||
| 803 | case ADDOP: | 875 | case ADDOP: |
| 804 | { | 876 | { |
| 805 | Object *l = top-2; | 877 | Object *l = top-2; |
| 806 | Object *r = top-1; | 878 | Object *r = top-1; |
| 807 | if (tonumber(r) || tonumber(l)) | 879 | if (tonumber(r) || tonumber(l)) |
| 808 | return 1; | 880 | call_arith("+"); |
| 809 | nvalue(l) += nvalue(r); | 881 | else |
| 810 | --top; | 882 | { |
| 883 | nvalue(l) += nvalue(r); | ||
| 884 | --top; | ||
| 885 | } | ||
| 811 | } | 886 | } |
| 812 | break; | 887 | break; |
| 813 | 888 | ||
| @@ -816,9 +891,12 @@ static int lua_execute (Byte *pc, int base) | |||
| 816 | Object *l = top-2; | 891 | Object *l = top-2; |
| 817 | Object *r = top-1; | 892 | Object *r = top-1; |
| 818 | if (tonumber(r) || tonumber(l)) | 893 | if (tonumber(r) || tonumber(l)) |
| 819 | return 1; | 894 | call_arith("-"); |
| 820 | nvalue(l) -= nvalue(r); | 895 | else |
| 821 | --top; | 896 | { |
| 897 | nvalue(l) -= nvalue(r); | ||
| 898 | --top; | ||
| 899 | } | ||
| 822 | } | 900 | } |
| 823 | break; | 901 | break; |
| 824 | 902 | ||
| @@ -827,9 +905,12 @@ static int lua_execute (Byte *pc, int base) | |||
| 827 | Object *l = top-2; | 905 | Object *l = top-2; |
| 828 | Object *r = top-1; | 906 | Object *r = top-1; |
| 829 | if (tonumber(r) || tonumber(l)) | 907 | if (tonumber(r) || tonumber(l)) |
| 830 | return 1; | 908 | call_arith("*"); |
| 831 | nvalue(l) *= nvalue(r); | 909 | else |
| 832 | --top; | 910 | { |
| 911 | nvalue(l) *= nvalue(r); | ||
| 912 | --top; | ||
| 913 | } | ||
| 833 | } | 914 | } |
| 834 | break; | 915 | break; |
| 835 | 916 | ||
| @@ -838,9 +919,12 @@ static int lua_execute (Byte *pc, int base) | |||
| 838 | Object *l = top-2; | 919 | Object *l = top-2; |
| 839 | Object *r = top-1; | 920 | Object *r = top-1; |
| 840 | if (tonumber(r) || tonumber(l)) | 921 | if (tonumber(r) || tonumber(l)) |
| 841 | return 1; | 922 | call_arith("/"); |
| 842 | nvalue(l) /= nvalue(r); | 923 | else |
| 843 | --top; | 924 | { |
| 925 | nvalue(l) /= nvalue(r); | ||
| 926 | --top; | ||
| 927 | } | ||
| 844 | } | 928 | } |
| 845 | break; | 929 | break; |
| 846 | 930 | ||
| @@ -849,9 +933,12 @@ static int lua_execute (Byte *pc, int base) | |||
| 849 | Object *l = top-2; | 933 | Object *l = top-2; |
| 850 | Object *r = top-1; | 934 | Object *r = top-1; |
| 851 | if (tonumber(r) || tonumber(l)) | 935 | if (tonumber(r) || tonumber(l)) |
| 852 | return 1; | 936 | call_arith("^"); |
| 853 | nvalue(l) = pow(nvalue(l), nvalue(r)); | 937 | else |
| 854 | --top; | 938 | { |
| 939 | nvalue(l) = pow(nvalue(l), nvalue(r)); | ||
| 940 | --top; | ||
| 941 | } | ||
| 855 | } | 942 | } |
| 856 | break; | 943 | break; |
| 857 | 944 | ||
| @@ -860,22 +947,24 @@ static int lua_execute (Byte *pc, int base) | |||
| 860 | Object *l = top-2; | 947 | Object *l = top-2; |
| 861 | Object *r = top-1; | 948 | Object *r = top-1; |
| 862 | if (tostring(r) || tostring(l)) | 949 | if (tostring(r) || tostring(l)) |
| 863 | return 1; | 950 | do_call(&fallBacks[FB_CONCAT].function, (top-stack)-2, 1, (top-stack)-2); |
| 864 | svalue(l) = lua_createstring (lua_strconc(svalue(l),svalue(r))); | 951 | else |
| 865 | if (svalue(l) == NULL) | 952 | { |
| 866 | return 1; | 953 | svalue(l) = lua_createstring (lua_strconc(svalue(l),svalue(r))); |
| 867 | --top; | 954 | --top; |
| 955 | } | ||
| 868 | } | 956 | } |
| 869 | break; | 957 | break; |
| 870 | 958 | ||
| 871 | case MINUSOP: | 959 | case MINUSOP: |
| 872 | if (tonumber(top-1)) | 960 | if (tonumber(top-1)) |
| 873 | return 1; | 961 | do_call(&fallBacks[FB_UNMINUS].function, (top-stack)-1, 1, (top-stack)-1); |
| 874 | nvalue(top-1) = - nvalue(top-1); | 962 | else |
| 963 | nvalue(top-1) = - nvalue(top-1); | ||
| 875 | break; | 964 | break; |
| 876 | 965 | ||
| 877 | case NOTOP: | 966 | case NOTOP: |
| 878 | tag(top-1) = tag(top-1) == LUA_T_NIL ? LUA_T_NUMBER : LUA_T_NIL; | 967 | tag(top-1) = (tag(top-1) == LUA_T_NIL) ? LUA_T_NUMBER : LUA_T_NIL; |
| 879 | break; | 968 | break; |
| 880 | 969 | ||
| 881 | case ONTJMP: | 970 | case ONTJMP: |
| @@ -952,8 +1041,7 @@ static int lua_execute (Byte *pc, int base) | |||
| 952 | CodeWord func; | 1041 | CodeWord func; |
| 953 | get_code(file,pc); | 1042 | get_code(file,pc); |
| 954 | get_word(func,pc); | 1043 | get_word(func,pc); |
| 955 | if (lua_pushfunction ((char *)file.b, func.w)) | 1044 | lua_pushfunction ((char *)file.b, func.w); |
| 956 | return 1; | ||
| 957 | } | 1045 | } |
| 958 | break; | 1046 | break; |
| 959 | 1047 | ||
| @@ -971,7 +1059,6 @@ static int lua_execute (Byte *pc, int base) | |||
| 971 | 1059 | ||
| 972 | default: | 1060 | default: |
| 973 | lua_error ("internal error - opcode doesn't match"); | 1061 | lua_error ("internal error - opcode doesn't match"); |
| 974 | return 1; | ||
| 975 | } | 1062 | } |
| 976 | } | 1063 | } |
| 977 | } | 1064 | } |
