diff options
-rw-r--r-- | lapi.c | 8 | ||||
-rw-r--r-- | lcode.c | 16 | ||||
-rw-r--r-- | lcode.h | 5 | ||||
-rw-r--r-- | llex.c | 15 | ||||
-rw-r--r-- | llex.h | 3 | ||||
-rw-r--r-- | lobject.c | 8 | ||||
-rw-r--r-- | lopcodes.c | 8 | ||||
-rw-r--r-- | lopcodes.h | 5 | ||||
-rw-r--r-- | lparser.c | 18 | ||||
-rw-r--r-- | ltests.c | 13 | ||||
-rw-r--r-- | ltm.c | 23 | ||||
-rw-r--r-- | ltm.h | 5 | ||||
-rw-r--r-- | lua.h | 7 | ||||
-rw-r--r-- | lvm.c | 51 | ||||
-rw-r--r-- | lvm.h | 3 |
15 files changed, 139 insertions, 49 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lapi.c,v 2.190 2013/09/13 16:21:52 roberto Exp roberto $ | 2 | ** $Id: lapi.c,v 2.191 2013/12/04 12:15:22 roberto Exp roberto $ |
3 | ** Lua API | 3 | ** Lua API |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -299,9 +299,9 @@ LUA_API int lua_rawequal (lua_State *L, int index1, int index2) { | |||
299 | 299 | ||
300 | LUA_API void lua_arith (lua_State *L, int op) { | 300 | LUA_API void lua_arith (lua_State *L, int op) { |
301 | lua_lock(L); | 301 | lua_lock(L); |
302 | if (op != LUA_OPUNM) /* all other operations expect two operands */ | 302 | if (op != LUA_OPUNM && op != LUA_OPBNOT) |
303 | api_checknelems(L, 2); | 303 | api_checknelems(L, 2); /* all other operations expect two operands */ |
304 | else { /* for unary minus, add fake 2nd operand */ | 304 | else { /* for unary operations, add fake 2nd operand */ |
305 | api_checknelems(L, 1); | 305 | api_checknelems(L, 1); |
306 | setobjs2s(L, L->top, L->top - 1); | 306 | setobjs2s(L, L->top, L->top - 1); |
307 | L->top++; | 307 | L->top++; |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lcode.c,v 2.75 2013/12/18 14:12:03 roberto Exp roberto $ | 2 | ** $Id: lcode.c,v 2.76 2013/12/18 18:44:42 roberto Exp roberto $ |
3 | ** Code generator for Lua | 3 | ** Code generator for Lua |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -756,7 +756,8 @@ static int validop (OpCode op, TValue *v1, TValue *v2) { | |||
756 | switch (op) { | 756 | switch (op) { |
757 | case OP_IDIV: /* division by 0 and conversion errors */ | 757 | case OP_IDIV: /* division by 0 and conversion errors */ |
758 | return (tointeger(v1, &i) && tointeger(v2, &i) && i != 0); | 758 | return (tointeger(v1, &i) && tointeger(v2, &i) && i != 0); |
759 | case OP_BAND: case OP_BOR: case OP_BXOR: /* conversion errors */ | 759 | case OP_BAND: case OP_BOR: case OP_BXOR: |
760 | case OP_SHL: case OP_SHR: case OP_BNOT: /* conversion errors */ | ||
760 | return (tointeger(v1, &i) && tointeger(v2, &i)); | 761 | return (tointeger(v1, &i) && tointeger(v2, &i)); |
761 | case OP_MOD: /* integer module by 0 */ | 762 | case OP_MOD: /* integer module by 0 */ |
762 | return !(ttisinteger(v1) && ttisinteger(v2) && ivalue(v2) == 0); | 763 | return !(ttisinteger(v1) && ttisinteger(v2) && ivalue(v2) == 0); |
@@ -771,7 +772,6 @@ static int constfolding (OpCode op, expdesc *e1, expdesc *e2) { | |||
771 | TValue v1, v2, res; | 772 | TValue v1, v2, res; |
772 | if (!tonumeral(e1, &v1) || !tonumeral(e2, &v2) || !validop(op, &v1, &v2)) | 773 | if (!tonumeral(e1, &v1) || !tonumeral(e2, &v2) || !validop(op, &v1, &v2)) |
773 | return 0; /* non-numeric operands or not safe to fold */ | 774 | return 0; /* non-numeric operands or not safe to fold */ |
774 | lua_assert(OP_IDIV - OP_ADD + LUA_OPADD == LUA_OPIDIV); | ||
775 | luaO_arith(NULL, op - OP_ADD + LUA_OPADD, &v1, &v2, &res); | 775 | luaO_arith(NULL, op - OP_ADD + LUA_OPADD, &v1, &v2, &res); |
776 | if (ttisinteger(&res)) { | 776 | if (ttisinteger(&res)) { |
777 | e1->k = VKINT; | 777 | e1->k = VKINT; |
@@ -792,7 +792,7 @@ static void codearith (FuncState *fs, OpCode op, | |||
792 | expdesc *e1, expdesc *e2, int line) { | 792 | expdesc *e1, expdesc *e2, int line) { |
793 | if (!constfolding(op, e1, e2)) { /* could not fold operation? */ | 793 | if (!constfolding(op, e1, e2)) { /* could not fold operation? */ |
794 | int o1, o2; | 794 | int o1, o2; |
795 | if (op == OP_UNM || op == OP_LEN) { | 795 | if (op == OP_UNM || op == OP_BNOT || op == OP_LEN) { |
796 | o2 = 0; | 796 | o2 = 0; |
797 | o1 = luaK_exp2anyreg(fs, e1); /* cannot operate on constants */ | 797 | o1 = luaK_exp2anyreg(fs, e1); /* cannot operate on constants */ |
798 | } | 798 | } |
@@ -835,7 +835,7 @@ void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e, int line) { | |||
835 | expdesc e2; | 835 | expdesc e2; |
836 | e2.t = e2.f = NO_JUMP; e2.k = VKINT; e2.u.ival = 0; | 836 | e2.t = e2.f = NO_JUMP; e2.k = VKINT; e2.u.ival = 0; |
837 | switch (op) { | 837 | switch (op) { |
838 | case OPR_MINUS: case OPR_LEN: { | 838 | case OPR_MINUS: case OPR_BNOT: case OPR_LEN: { |
839 | codearith(fs, op - OPR_MINUS + OP_UNM, e, &e2, line); | 839 | codearith(fs, op - OPR_MINUS + OP_UNM, e, &e2, line); |
840 | break; | 840 | break; |
841 | } | 841 | } |
@@ -862,7 +862,8 @@ void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) { | |||
862 | case OPR_ADD: case OPR_SUB: | 862 | case OPR_ADD: case OPR_SUB: |
863 | case OPR_MUL: case OPR_DIV: case OPR_IDIV: | 863 | case OPR_MUL: case OPR_DIV: case OPR_IDIV: |
864 | case OPR_MOD: case OPR_POW: | 864 | case OPR_MOD: case OPR_POW: |
865 | case OPR_BAND: case OPR_BOR: case OPR_BXOR: { | 865 | case OPR_BAND: case OPR_BOR: case OPR_BXOR: |
866 | case OPR_SHL: case OPR_SHR: { | ||
866 | if (!tonumeral(v, NULL)) luaK_exp2RK(fs, v); | 867 | if (!tonumeral(v, NULL)) luaK_exp2RK(fs, v); |
867 | break; | 868 | break; |
868 | } | 869 | } |
@@ -907,7 +908,8 @@ void luaK_posfix (FuncState *fs, BinOpr op, | |||
907 | } | 908 | } |
908 | case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV: | 909 | case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV: |
909 | case OPR_IDIV: case OPR_MOD: case OPR_POW: | 910 | case OPR_IDIV: case OPR_MOD: case OPR_POW: |
910 | case OPR_BAND: case OPR_BOR: case OPR_BXOR: { | 911 | case OPR_BAND: case OPR_BOR: case OPR_BXOR: |
912 | case OPR_SHL: case OPR_SHR: { | ||
911 | codearith(fs, cast(OpCode, op - OPR_ADD + OP_ADD), e1, e2, line); | 913 | codearith(fs, cast(OpCode, op - OPR_ADD + OP_ADD), e1, e2, line); |
912 | break; | 914 | break; |
913 | } | 915 | } |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lcode.h,v 1.61 2013/12/16 19:06:52 roberto Exp roberto $ | 2 | ** $Id: lcode.h,v 1.62 2013/12/18 14:12:03 roberto Exp roberto $ |
3 | ** Code generator for Lua | 3 | ** Code generator for Lua |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -28,6 +28,7 @@ typedef enum BinOpr { | |||
28 | OPR_DIV, | 28 | OPR_DIV, |
29 | OPR_IDIV, | 29 | OPR_IDIV, |
30 | OPR_BAND, OPR_BOR, OPR_BXOR, | 30 | OPR_BAND, OPR_BOR, OPR_BXOR, |
31 | OPR_SHL, OPR_SHR, | ||
31 | OPR_CONCAT, | 32 | OPR_CONCAT, |
32 | OPR_EQ, OPR_LT, OPR_LE, | 33 | OPR_EQ, OPR_LT, OPR_LE, |
33 | OPR_NE, OPR_GT, OPR_GE, | 34 | OPR_NE, OPR_GT, OPR_GE, |
@@ -36,7 +37,7 @@ typedef enum BinOpr { | |||
36 | } BinOpr; | 37 | } BinOpr; |
37 | 38 | ||
38 | 39 | ||
39 | typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr; | 40 | typedef enum UnOpr { OPR_MINUS, OPR_BNOT, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr; |
40 | 41 | ||
41 | 42 | ||
42 | #define getcode(fs,e) ((fs)->f->code[(e)->u.info]) | 43 | #define getcode(fs,e) ((fs)->f->code[(e)->u.info]) |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: llex.c,v 2.68 2013/08/21 20:09:51 roberto Exp roberto $ | 2 | ** $Id: llex.c,v 2.69 2013/08/30 16:01:37 roberto Exp roberto $ |
3 | ** Lexical Analyzer | 3 | ** Lexical Analyzer |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -39,7 +39,8 @@ static const char *const luaX_tokens [] = { | |||
39 | "end", "false", "for", "function", "goto", "if", | 39 | "end", "false", "for", "function", "goto", "if", |
40 | "in", "local", "nil", "not", "or", "repeat", | 40 | "in", "local", "nil", "not", "or", "repeat", |
41 | "return", "then", "true", "until", "while", | 41 | "return", "then", "true", "until", "while", |
42 | "//", "..", "...", "==", ">=", "<=", "~=", "::", "<eof>", | 42 | "//", "..", "...", "==", ">=", "<=", "~=", |
43 | "<<", ">>", "::", "<eof>", | ||
43 | "<number>", "<number>", "<name>", "<string>" | 44 | "<number>", "<number>", "<name>", "<string>" |
44 | }; | 45 | }; |
45 | 46 | ||
@@ -462,13 +463,15 @@ static int llex (LexState *ls, SemInfo *seminfo) { | |||
462 | } | 463 | } |
463 | case '<': { | 464 | case '<': { |
464 | next(ls); | 465 | next(ls); |
465 | if (ls->current != '=') return '<'; | 466 | if (ls->current == '=') { next(ls); return TK_LE; } |
466 | else { next(ls); return TK_LE; } | 467 | if (ls->current == '<') { next(ls); return TK_SHL; } |
468 | return '<'; | ||
467 | } | 469 | } |
468 | case '>': { | 470 | case '>': { |
469 | next(ls); | 471 | next(ls); |
470 | if (ls->current != '=') return '>'; | 472 | if (ls->current == '=') { next(ls); return TK_GE; } |
471 | else { next(ls); return TK_GE; } | 473 | if (ls->current == '>') { next(ls); return TK_SHR; } |
474 | return '>'; | ||
472 | } | 475 | } |
473 | case '/': { | 476 | case '/': { |
474 | next(ls); | 477 | next(ls); |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: llex.h,v 1.74 2013/04/26 13:07:53 roberto Exp roberto $ | 2 | ** $Id: llex.h,v 1.75 2013/08/30 16:01:37 roberto Exp roberto $ |
3 | ** Lexical Analyzer | 3 | ** Lexical Analyzer |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -27,6 +27,7 @@ enum RESERVED { | |||
27 | TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE, | 27 | TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE, |
28 | /* other terminal symbols */ | 28 | /* other terminal symbols */ |
29 | TK_IDIV, TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, | 29 | TK_IDIV, TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, |
30 | TK_SHL, TK_SHR, | ||
30 | TK_DBCOLON, TK_EOS, | 31 | TK_DBCOLON, TK_EOS, |
31 | TK_FLT, TK_INT, TK_NAME, TK_STRING | 32 | TK_FLT, TK_INT, TK_NAME, TK_STRING |
32 | }; | 33 | }; |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lobject.c,v 2.69 2013/12/16 14:30:22 roberto Exp roberto $ | 2 | ** $Id: lobject.c,v 2.70 2013/12/18 14:12:03 roberto Exp roberto $ |
3 | ** Some generic functions over Lua objects | 3 | ** Some generic functions over Lua objects |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -82,7 +82,10 @@ static lua_Integer intarith (lua_State *L, int op, lua_Integer v1, | |||
82 | case LUA_OPBAND: return intop(&, v1, v2); | 82 | case LUA_OPBAND: return intop(&, v1, v2); |
83 | case LUA_OPBOR: return intop(|, v1, v2); | 83 | case LUA_OPBOR: return intop(|, v1, v2); |
84 | case LUA_OPBXOR: return intop(^, v1, v2); | 84 | case LUA_OPBXOR: return intop(^, v1, v2); |
85 | case LUA_OPSHL: return luaV_shiftl(v1, v2); | ||
86 | case LUA_OPSHR: return luaV_shiftl(v1, -v2); | ||
85 | case LUA_OPUNM: return intop(-, 0, v1); | 87 | case LUA_OPUNM: return intop(-, 0, v1); |
88 | case LUA_OPBNOT: return intop(^, cast_integer(-1), v1); | ||
86 | default: lua_assert(0); return 0; | 89 | default: lua_assert(0); return 0; |
87 | } | 90 | } |
88 | } | 91 | } |
@@ -106,7 +109,8 @@ void luaO_arith (lua_State *L, int op, const TValue *p1, const TValue *p2, | |||
106 | TValue *res) { | 109 | TValue *res) { |
107 | switch (op) { | 110 | switch (op) { |
108 | case LUA_OPIDIV: case LUA_OPBAND: case LUA_OPBOR: | 111 | case LUA_OPIDIV: case LUA_OPBAND: case LUA_OPBOR: |
109 | case LUA_OPBXOR: { /* operates only on integers */ | 112 | case LUA_OPBXOR: case LUA_OPSHL: case LUA_OPSHR: |
113 | case LUA_OPBNOT: { /* operates only on integers */ | ||
110 | lua_Integer i1; lua_Integer i2; | 114 | lua_Integer i1; lua_Integer i2; |
111 | if (tointeger(p1, &i1) && tointeger(p2, &i2)) { | 115 | if (tointeger(p1, &i1) && tointeger(p2, &i2)) { |
112 | setivalue(res, intarith(L, op, i1, i2)); | 116 | setivalue(res, intarith(L, op, i1, i2)); |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lopcodes.c,v 1.51 2013/12/16 19:06:52 roberto Exp roberto $ | 2 | ** $Id: lopcodes.c,v 1.52 2013/12/18 14:12:03 roberto Exp roberto $ |
3 | ** Opcodes for Lua virtual machine | 3 | ** Opcodes for Lua virtual machine |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -38,7 +38,10 @@ LUAI_DDEF const char *const luaP_opnames[NUM_OPCODES+1] = { | |||
38 | "BAND", | 38 | "BAND", |
39 | "BOR", | 39 | "BOR", |
40 | "BXOR", | 40 | "BXOR", |
41 | "SHL", | ||
42 | "SHR", | ||
41 | "UNM", | 43 | "UNM", |
44 | "BNOT", | ||
42 | "NOT", | 45 | "NOT", |
43 | "LEN", | 46 | "LEN", |
44 | "CONCAT", | 47 | "CONCAT", |
@@ -90,7 +93,10 @@ LUAI_DDEF const lu_byte luaP_opmodes[NUM_OPCODES] = { | |||
90 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_BAND */ | 93 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_BAND */ |
91 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_BOR */ | 94 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_BOR */ |
92 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_BXOR */ | 95 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_BXOR */ |
96 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SHL */ | ||
97 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SHR */ | ||
93 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_UNM */ | 98 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_UNM */ |
99 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_BNOT */ | ||
94 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_NOT */ | 100 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_NOT */ |
95 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LEN */ | 101 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LEN */ |
96 | ,opmode(0, 1, OpArgR, OpArgR, iABC) /* OP_CONCAT */ | 102 | ,opmode(0, 1, OpArgR, OpArgR, iABC) /* OP_CONCAT */ |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lopcodes.h,v 1.144 2013/12/16 19:06:52 roberto Exp roberto $ | 2 | ** $Id: lopcodes.h,v 1.145 2013/12/18 14:12:03 roberto Exp roberto $ |
3 | ** Opcodes for Lua virtual machine | 3 | ** Opcodes for Lua virtual machine |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -194,7 +194,10 @@ OP_IDIV,/* A B C R(A) := RK(B) // RK(C) */ | |||
194 | OP_BAND,/* A B C R(A) := RK(B) & RK(C) */ | 194 | OP_BAND,/* A B C R(A) := RK(B) & RK(C) */ |
195 | OP_BOR,/* A B C R(A) := RK(B) | RK(C) */ | 195 | OP_BOR,/* A B C R(A) := RK(B) | RK(C) */ |
196 | OP_BXOR,/* A B C R(A) := RK(B) ~ RK(C) */ | 196 | OP_BXOR,/* A B C R(A) := RK(B) ~ RK(C) */ |
197 | OP_SHL,/* A B C R(A) := RK(B) << RK(C) */ | ||
198 | OP_SHR,/* A B C R(A) := RK(B) >> RK(C) */ | ||
197 | OP_UNM,/* A B R(A) := -R(B) */ | 199 | OP_UNM,/* A B R(A) := -R(B) */ |
200 | OP_BNOT,/* A B R(A) := ~R(B) */ | ||
198 | OP_NOT,/* A B R(A) := not R(B) */ | 201 | OP_NOT,/* A B R(A) := not R(B) */ |
199 | OP_LEN,/* A B R(A) := length of R(B) */ | 202 | OP_LEN,/* A B R(A) := length of R(B) */ |
200 | 203 | ||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lparser.c,v 2.136 2013/12/16 19:06:52 roberto Exp roberto $ | 2 | ** $Id: lparser.c,v 2.137 2013/12/18 14:12:03 roberto Exp roberto $ |
3 | ** Lua Parser | 3 | ** Lua Parser |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -979,6 +979,7 @@ static UnOpr getunopr (int op) { | |||
979 | switch (op) { | 979 | switch (op) { |
980 | case TK_NOT: return OPR_NOT; | 980 | case TK_NOT: return OPR_NOT; |
981 | case '-': return OPR_MINUS; | 981 | case '-': return OPR_MINUS; |
982 | case '~': return OPR_BNOT; | ||
982 | case '#': return OPR_LEN; | 983 | case '#': return OPR_LEN; |
983 | default: return OPR_NOUNOPR; | 984 | default: return OPR_NOUNOPR; |
984 | } | 985 | } |
@@ -997,6 +998,8 @@ static BinOpr getbinopr (int op) { | |||
997 | case '&': return OPR_BAND; | 998 | case '&': return OPR_BAND; |
998 | case '|': return OPR_BOR; | 999 | case '|': return OPR_BOR; |
999 | case '~': return OPR_BXOR; | 1000 | case '~': return OPR_BXOR; |
1001 | case TK_SHL: return OPR_SHL; | ||
1002 | case TK_SHR: return OPR_SHR; | ||
1000 | case TK_CONCAT: return OPR_CONCAT; | 1003 | case TK_CONCAT: return OPR_CONCAT; |
1001 | case TK_NE: return OPR_NE; | 1004 | case TK_NE: return OPR_NE; |
1002 | case TK_EQ: return OPR_EQ; | 1005 | case TK_EQ: return OPR_EQ; |
@@ -1015,18 +1018,19 @@ static const struct { | |||
1015 | lu_byte left; /* left priority for each binary operator */ | 1018 | lu_byte left; /* left priority for each binary operator */ |
1016 | lu_byte right; /* right priority */ | 1019 | lu_byte right; /* right priority */ |
1017 | } priority[] = { /* ORDER OPR */ | 1020 | } priority[] = { /* ORDER OPR */ |
1018 | {8, 8}, {8, 8}, /* '+' '-' */ | 1021 | {10, 10}, {10, 10}, /* '+' '-' */ |
1019 | {9, 9}, {9, 9}, /* '*' '%' */ | 1022 | {11, 11}, {11, 11}, /* '*' '%' */ |
1020 | {12, 11}, /* '^' (right associative) */ | 1023 | {14, 13}, /* '^' (right associative) */ |
1021 | {9, 9}, {9, 9}, /* '/' '//' */ | 1024 | {11, 11}, {11, 11}, /* '/' '//' */ |
1022 | {6, 6}, {4, 4}, {5, 5}, /* '&' '|' '~' */ | 1025 | {6, 6}, {4, 4}, {5, 5}, /* '&' '|' '~' */ |
1023 | {7, 6}, /* '..' (right associative) */ | 1026 | {7, 7}, {7, 7}, /* '<<' '>>' */ |
1027 | {9, 8}, /* '..' (right associative) */ | ||
1024 | {3, 3}, {3, 3}, {3, 3}, /* ==, <, <= */ | 1028 | {3, 3}, {3, 3}, {3, 3}, /* ==, <, <= */ |
1025 | {3, 3}, {3, 3}, {3, 3}, /* ~=, >, >= */ | 1029 | {3, 3}, {3, 3}, {3, 3}, /* ~=, >, >= */ |
1026 | {2, 2}, {1, 1} /* and, or */ | 1030 | {2, 2}, {1, 1} /* and, or */ |
1027 | }; | 1031 | }; |
1028 | 1032 | ||
1029 | #define UNARY_PRIORITY 10 /* priority for unary operators */ | 1033 | #define UNARY_PRIORITY 12 /* priority for unary operators */ |
1030 | 1034 | ||
1031 | 1035 | ||
1032 | /* | 1036 | /* |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ltests.c,v 2.160 2013/12/16 19:06:52 roberto Exp roberto $ | 2 | ** $Id: ltests.c,v 2.161 2013/12/18 14:12:03 roberto Exp roberto $ |
3 | ** Internal Module for Debugging of the Lua Implementation | 3 | ** Internal Module for Debugging of the Lua Implementation |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -1023,6 +1023,16 @@ static void pushcode (lua_State *L, int code) { | |||
1023 | static int testC (lua_State *L); | 1023 | static int testC (lua_State *L); |
1024 | static int Cfunck (lua_State *L); | 1024 | static int Cfunck (lua_State *L); |
1025 | 1025 | ||
1026 | /* | ||
1027 | ** arithmetic operation encoding for 'arith' instruction | ||
1028 | ** LUA_OPIDIV -> \ | ||
1029 | ** LUA_OPSHL -> < | ||
1030 | ** LUA_OPSHR -> > | ||
1031 | ** LUA_OPUNM -> _ | ||
1032 | ** LUA_OPBNOT -> ! | ||
1033 | */ | ||
1034 | static char ops[] = "+-*%^/\\&|~<>_!"; | ||
1035 | |||
1026 | static int runC (lua_State *L, lua_State *L1, const char *pc) { | 1036 | static int runC (lua_State *L, lua_State *L1, const char *pc) { |
1027 | char buff[300]; | 1037 | char buff[300]; |
1028 | int status = 0; | 1038 | int status = 0; |
@@ -1198,7 +1208,6 @@ static int runC (lua_State *L, lua_State *L1, const char *pc) { | |||
1198 | } | 1208 | } |
1199 | } | 1209 | } |
1200 | else if EQ("arith") { | 1210 | else if EQ("arith") { |
1201 | static char ops[] = "+-*%^/\\&|~_"; /* '\' -> '//'; '_' -> '..' */ | ||
1202 | int op; | 1211 | int op; |
1203 | skip(&pc); | 1212 | skip(&pc); |
1204 | op = strchr(ops, *pc++) - ops; | 1213 | op = strchr(ops, *pc++) - ops; |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ltm.c,v 2.23 2013/12/16 19:06:52 roberto Exp roberto $ | 2 | ** $Id: ltm.c,v 2.24 2013/12/18 14:12:03 roberto Exp roberto $ |
3 | ** Tag methods | 3 | ** Tag methods |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -38,8 +38,8 @@ void luaT_init (lua_State *L) { | |||
38 | "__gc", "__mode", "__len", "__eq", | 38 | "__gc", "__mode", "__len", "__eq", |
39 | "__add", "__sub", "__mul", "__mod", "__pow", | 39 | "__add", "__sub", "__mul", "__mod", "__pow", |
40 | "__div", "__idiv", | 40 | "__div", "__idiv", |
41 | "__band", "__bor", "__bxor", | 41 | "__band", "__bor", "__bxor", "__shl", "__shr", |
42 | "__unm", "__lt", "__le", | 42 | "__unm", "__bnot", "__lt", "__le", |
43 | "__concat", "__call" | 43 | "__concat", "__call" |
44 | }; | 44 | }; |
45 | int i; | 45 | int i; |
@@ -112,12 +112,17 @@ int luaT_callbinTM (lua_State *L, const TValue *p1, const TValue *p2, | |||
112 | void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2, | 112 | void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2, |
113 | StkId res, TMS event) { | 113 | StkId res, TMS event) { |
114 | if (!luaT_callbinTM(L, p1, p2, res, event)) { | 114 | if (!luaT_callbinTM(L, p1, p2, res, event)) { |
115 | if (event == TM_CONCAT) | 115 | switch (event) { |
116 | luaG_concaterror(L, p1, p2); | 116 | case TM_CONCAT: |
117 | else if (event == TM_IDIV && ttisnumber(p1) && ttisnumber(p2)) | 117 | luaG_concaterror(L, p1, p2); |
118 | luaG_tointerror(L, p1, p2); | 118 | case TM_IDIV: case TM_BAND: case TM_BOR: case TM_BXOR: |
119 | else | 119 | case TM_SHL: case TM_SHR: case TM_BNOT: |
120 | luaG_aritherror(L, p1, p2); | 120 | if (ttisnumber(p1) && ttisnumber(p2)) |
121 | luaG_tointerror(L, p1, p2); | ||
122 | /* else go through */ | ||
123 | default: | ||
124 | luaG_aritherror(L, p1, p2); | ||
125 | } | ||
121 | } | 126 | } |
122 | } | 127 | } |
123 | 128 | ||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ltm.h,v 2.17 2013/12/16 19:06:52 roberto Exp roberto $ | 2 | ** $Id: ltm.h,v 2.18 2013/12/18 14:12:03 roberto Exp roberto $ |
3 | ** Tag methods | 3 | ** Tag methods |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -32,7 +32,10 @@ typedef enum { | |||
32 | TM_BAND, | 32 | TM_BAND, |
33 | TM_BOR, | 33 | TM_BOR, |
34 | TM_BXOR, | 34 | TM_BXOR, |
35 | TM_SHL, | ||
36 | TM_SHR, | ||
35 | TM_UNM, | 37 | TM_UNM, |
38 | TM_BNOT, | ||
36 | TM_LT, | 39 | TM_LT, |
37 | TM_LE, | 40 | TM_LE, |
38 | TM_CONCAT, | 41 | TM_CONCAT, |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lua.h,v 1.296 2013/12/16 19:06:52 roberto Exp roberto $ | 2 | ** $Id: lua.h,v 1.297 2013/12/18 14:12:03 roberto Exp roberto $ |
3 | ** Lua - A Scripting Language | 3 | ** Lua - A Scripting Language |
4 | ** Lua.org, PUC-Rio, Brazil (http://www.lua.org) | 4 | ** Lua.org, PUC-Rio, Brazil (http://www.lua.org) |
5 | ** See Copyright Notice at the end of this file | 5 | ** See Copyright Notice at the end of this file |
@@ -192,7 +192,10 @@ LUA_API const void *(lua_topointer) (lua_State *L, int idx); | |||
192 | #define LUA_OPBAND 7 | 192 | #define LUA_OPBAND 7 |
193 | #define LUA_OPBOR 8 | 193 | #define LUA_OPBOR 8 |
194 | #define LUA_OPBXOR 9 | 194 | #define LUA_OPBXOR 9 |
195 | #define LUA_OPUNM 10 | 195 | #define LUA_OPSHL 10 |
196 | #define LUA_OPSHR 11 | ||
197 | #define LUA_OPUNM 12 | ||
198 | #define LUA_OPBNOT 13 | ||
196 | 199 | ||
197 | LUA_API void (lua_arith) (lua_State *L, int op); | 200 | LUA_API void (lua_arith) (lua_State *L, int op); |
198 | 201 | ||
@@ -1,10 +1,11 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lvm.c,v 2.181 2013/12/16 14:30:22 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 2.182 2013/12/18 14:12:03 roberto Exp roberto $ |
3 | ** Lua virtual machine | 3 | ** Lua virtual machine |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
6 | 6 | ||
7 | 7 | ||
8 | #include <limits.h> | ||
8 | #include <stdio.h> | 9 | #include <stdio.h> |
9 | #include <stdlib.h> | 10 | #include <stdlib.h> |
10 | #include <string.h> | 11 | #include <string.h> |
@@ -379,6 +380,21 @@ lua_Integer luaV_pow (lua_State *L, lua_Integer x, lua_Integer y) { | |||
379 | } | 380 | } |
380 | 381 | ||
381 | 382 | ||
383 | /* number of bits in an integer */ | ||
384 | #define NBITS cast_int(sizeof(lua_Integer) * CHAR_BIT) | ||
385 | |||
386 | LUAI_FUNC lua_Integer luaV_shiftl (lua_Integer x, lua_Integer y) { | ||
387 | if (y < 0) { /* shift right? */ | ||
388 | if (y <= -NBITS) return 0; | ||
389 | else return cast_integer(cast_unsigned(x) >> (-y)); | ||
390 | } | ||
391 | else { /* shift left */ | ||
392 | if (y >= NBITS) return 0; | ||
393 | else return x << y; | ||
394 | } | ||
395 | } | ||
396 | |||
397 | |||
382 | /* | 398 | /* |
383 | ** check whether cached closure in prototype 'p' may be reused, that is, | 399 | ** check whether cached closure in prototype 'p' may be reused, that is, |
384 | ** whether there is a cached closure with the same upvalues needed by | 400 | ** whether there is a cached closure with the same upvalues needed by |
@@ -437,8 +453,9 @@ void luaV_finishOp (lua_State *L) { | |||
437 | OpCode op = GET_OPCODE(inst); | 453 | OpCode op = GET_OPCODE(inst); |
438 | switch (op) { /* finish its execution */ | 454 | switch (op) { /* finish its execution */ |
439 | case OP_ADD: case OP_SUB: case OP_MUL: case OP_DIV: case OP_IDIV: | 455 | case OP_ADD: case OP_SUB: case OP_MUL: case OP_DIV: case OP_IDIV: |
440 | case OP_BAND: case OP_BOR: case OP_BXOR: | 456 | case OP_BAND: case OP_BOR: case OP_BXOR: case OP_SHL: case OP_SHR: |
441 | case OP_MOD: case OP_POW: case OP_UNM: case OP_LEN: | 457 | case OP_MOD: case OP_POW: |
458 | case OP_UNM: case OP_BNOT: case OP_LEN: | ||
442 | case OP_GETTABUP: case OP_GETTABLE: case OP_SELF: { | 459 | case OP_GETTABUP: case OP_GETTABLE: case OP_SELF: { |
443 | setobjs2s(L, base + GETARG_A(inst), --L->top); | 460 | setobjs2s(L, base + GETARG_A(inst), --L->top); |
444 | break; | 461 | break; |
@@ -699,6 +716,24 @@ void luaV_execute (lua_State *L) { | |||
699 | } | 716 | } |
700 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_BXOR)); } | 717 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_BXOR)); } |
701 | ) | 718 | ) |
719 | vmcase(OP_SHL, | ||
720 | TValue *rb = RKB(i); | ||
721 | TValue *rc = RKC(i); | ||
722 | lua_Integer ib; lua_Integer ic; | ||
723 | if (tointeger(rb, &ib) && tointeger(rc, &ic)) { | ||
724 | setivalue(ra, luaV_shiftl(ib, ic)); | ||
725 | } | ||
726 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_SHL)); } | ||
727 | ) | ||
728 | vmcase(OP_SHR, | ||
729 | TValue *rb = RKB(i); | ||
730 | TValue *rc = RKC(i); | ||
731 | lua_Integer ib; lua_Integer ic; | ||
732 | if (tointeger(rb, &ib) && tointeger(rc, &ic)) { | ||
733 | setivalue(ra, luaV_shiftl(ib, -ic)); | ||
734 | } | ||
735 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_SHR)); } | ||
736 | ) | ||
702 | vmcase(OP_MOD, | 737 | vmcase(OP_MOD, |
703 | TValue *rb = RKB(i); | 738 | TValue *rb = RKB(i); |
704 | TValue *rc = RKC(i); | 739 | TValue *rc = RKC(i); |
@@ -739,6 +774,16 @@ void luaV_execute (lua_State *L) { | |||
739 | Protect(luaT_trybinTM(L, rb, rb, ra, TM_UNM)); | 774 | Protect(luaT_trybinTM(L, rb, rb, ra, TM_UNM)); |
740 | } | 775 | } |
741 | ) | 776 | ) |
777 | vmcase(OP_BNOT, | ||
778 | TValue *rb = RB(i); | ||
779 | lua_Integer ib; | ||
780 | if (tointeger(rb, &ib)) { | ||
781 | setivalue(ra, intop(^, cast_integer(-1), ib)); | ||
782 | } | ||
783 | else { | ||
784 | Protect(luaT_trybinTM(L, rb, rb, ra, TM_BNOT)); | ||
785 | } | ||
786 | ) | ||
742 | vmcase(OP_NOT, | 787 | vmcase(OP_NOT, |
743 | TValue *rb = RB(i); | 788 | TValue *rb = RB(i); |
744 | int res = l_isfalse(rb); /* next assignment may change this value */ | 789 | int res = l_isfalse(rb); /* next assignment may change this value */ |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lvm.h,v 2.23 2013/05/02 12:31:26 roberto Exp roberto $ | 2 | ** $Id: lvm.h,v 2.24 2013/12/16 14:30:22 roberto Exp roberto $ |
3 | ** Lua virtual machine | 3 | ** Lua virtual machine |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -44,6 +44,7 @@ LUAI_FUNC void luaV_concat (lua_State *L, int total); | |||
44 | LUAI_FUNC lua_Integer luaV_div (lua_State *L, lua_Integer x, lua_Integer y); | 44 | LUAI_FUNC lua_Integer luaV_div (lua_State *L, lua_Integer x, lua_Integer y); |
45 | LUAI_FUNC lua_Integer luaV_mod (lua_State *L, lua_Integer x, lua_Integer y); | 45 | LUAI_FUNC lua_Integer luaV_mod (lua_State *L, lua_Integer x, lua_Integer y); |
46 | LUAI_FUNC lua_Integer luaV_pow (lua_State *L, lua_Integer x, lua_Integer y); | 46 | LUAI_FUNC lua_Integer luaV_pow (lua_State *L, lua_Integer x, lua_Integer y); |
47 | LUAI_FUNC lua_Integer luaV_shiftl (lua_Integer x, lua_Integer y); | ||
47 | LUAI_FUNC void luaV_objlen (lua_State *L, StkId ra, const TValue *rb); | 48 | LUAI_FUNC void luaV_objlen (lua_State *L, StkId ra, const TValue *rb); |
48 | 49 | ||
49 | #endif | 50 | #endif |