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 | } |