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 |
