From a2f5c28a802ae99f2045ab96585fade2c65b2037 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Fri, 26 Apr 2013 10:08:29 -0300 Subject: [PATCH] new operation '//' (integer division) --- lcode.c | 9 +++++---- lcode.h | 4 ++-- ldebug.c | 3 ++- llex.c | 9 +++++++-- llex.h | 5 +++-- lopcodes.c | 4 +++- lopcodes.h | 3 ++- lparser.c | 6 ++++-- ltests.c | 4 ++-- ltm.c | 4 ++-- ltm.h | 3 ++- lua.h | 9 +++++---- luaconf.h | 3 ++- lvm.c | 17 +++++++++++++++-- 14 files changed, 56 insertions(+), 27 deletions(-) diff --git a/lcode.c b/lcode.c index 8a4b2ba9..8aa18b49 100644 --- a/lcode.c +++ b/lcode.c @@ -1,5 +1,5 @@ /* -** $Id: lcode.c,v 2.64 2013/04/16 18:46:28 roberto Exp roberto $ +** $Id: lcode.c,v 2.65 2013/04/25 19:35:19 roberto Exp $ ** Code generator for Lua ** See Copyright Notice in lua.h */ @@ -732,7 +732,7 @@ void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) { static int constfolding (OpCode op, expdesc *e1, expdesc *e2) { lua_Number r; if (!isnumeral(e1) || !isnumeral(e2)) return 0; - if ((op == OP_DIV || op == OP_MOD) && e2->u.nval == 0) + if ((op == OP_DIV || op == OP_IDIV || op == OP_MOD) && e2->u.nval == 0) return 0; /* do not attempt to divide by 0 */ r = luaO_arith(op - OP_ADD + LUA_OPADD, e1->u.nval, e2->u.nval); e1->u.nval = r; @@ -816,7 +816,8 @@ void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) { luaK_exp2nextreg(fs, v); /* operand must be on the `stack' */ break; } - case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV: + case OPR_ADD: case OPR_SUB: + case OPR_MUL: case OPR_DIV: case OPR_IDIV: case OPR_MOD: case OPR_POW: { if (!isnumeral(v)) luaK_exp2RK(fs, v); break; @@ -861,7 +862,7 @@ void luaK_posfix (FuncState *fs, BinOpr op, break; } case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV: - case OPR_MOD: case OPR_POW: { + case OPR_IDIV: case OPR_MOD: case OPR_POW: { codearith(fs, cast(OpCode, op - OPR_ADD + OP_ADD), e1, e2, line); break; } diff --git a/lcode.h b/lcode.h index e151c436..ddf4094c 100644 --- a/lcode.h +++ b/lcode.h @@ -1,5 +1,5 @@ /* -** $Id: lcode.h,v 1.58 2011/08/30 16:26:41 roberto Exp roberto $ +** $Id: lcode.h,v 1.59 2013/04/25 19:35:19 roberto Exp roberto $ ** Code generator for Lua ** See Copyright Notice in lua.h */ @@ -24,7 +24,7 @@ ** grep "ORDER OPR" if you change these enums (ORDER OP) */ typedef enum BinOpr { - OPR_ADD, OPR_SUB, OPR_MUL, OPR_DIV, OPR_MOD, OPR_POW, + OPR_ADD, OPR_SUB, OPR_MUL, OPR_DIV, OPR_IDIV, OPR_MOD, OPR_POW, OPR_CONCAT, OPR_EQ, OPR_LT, OPR_LE, OPR_NE, OPR_GT, OPR_GE, diff --git a/ldebug.c b/ldebug.c index 17baf27c..96d47085 100644 --- a/ldebug.c +++ b/ldebug.c @@ -1,5 +1,5 @@ /* -** $Id: ldebug.c,v 2.90 2012/08/16 17:34:28 roberto Exp roberto $ +** $Id: ldebug.c,v 2.91 2013/04/25 15:59:42 roberto Exp roberto $ ** Debug Interface ** See Copyright Notice in lua.h */ @@ -453,6 +453,7 @@ static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) { case OP_SUB: tm = TM_SUB; break; case OP_MUL: tm = TM_MUL; break; case OP_DIV: tm = TM_DIV; break; + case OP_IDIV: tm = TM_IDIV; break; case OP_MOD: tm = TM_MOD; break; case OP_POW: tm = TM_POW; break; case OP_UNM: tm = TM_UNM; break; diff --git a/llex.c b/llex.c index bb5f36ab..9544de4f 100644 --- a/llex.c +++ b/llex.c @@ -1,5 +1,5 @@ /* -** $Id: llex.c,v 2.63 2013/03/16 21:10:18 roberto Exp roberto $ +** $Id: llex.c,v 2.64 2013/04/16 18:46:28 roberto Exp roberto $ ** Lexical Analyzer ** See Copyright Notice in lua.h */ @@ -38,7 +38,7 @@ static const char *const luaX_tokens [] = { "end", "false", "for", "function", "goto", "if", "in", "local", "nil", "not", "or", "repeat", "return", "then", "true", "until", "while", - "..", "...", "==", ">=", "<=", "~=", "::", "", + "//", "..", "...", "==", ">=", "<=", "~=", "::", "", "", "", "", "" }; @@ -464,6 +464,11 @@ static int llex (LexState *ls, SemInfo *seminfo) { if (ls->current != '=') return '>'; else { next(ls); return TK_GE; } } + case '/': { + next(ls); + if (ls->current != '/') return '/'; + else { next(ls); return TK_IDIV; } + } case '~': { next(ls); if (ls->current != '=') return '~'; diff --git a/llex.h b/llex.h index 14eb548d..d1667ad7 100644 --- a/llex.h +++ b/llex.h @@ -1,5 +1,5 @@ /* -** $Id: llex.h,v 1.72 2011/11/30 12:43:51 roberto Exp roberto $ +** $Id: llex.h,v 1.73 2013/04/16 18:46:28 roberto Exp roberto $ ** Lexical Analyzer ** See Copyright Notice in lua.h */ @@ -26,7 +26,8 @@ enum RESERVED { TK_GOTO, TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT, TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE, /* other terminal symbols */ - TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, TK_DBCOLON, TK_EOS, + TK_IDIV, TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, + TK_DBCOLON, TK_EOS, TK_FLT, TK_INT, TK_NAME, TK_STRING }; diff --git a/lopcodes.c b/lopcodes.c index 91221368..64a637b8 100644 --- a/lopcodes.c +++ b/lopcodes.c @@ -1,5 +1,5 @@ /* -** $Id: lopcodes.c,v 1.48 2011/04/19 16:22:13 roberto Exp roberto $ +** $Id: lopcodes.c,v 1.49 2012/05/14 13:34:18 roberto Exp roberto $ ** Opcodes for Lua virtual machine ** See Copyright Notice in lua.h */ @@ -32,6 +32,7 @@ LUAI_DDEF const char *const luaP_opnames[NUM_OPCODES+1] = { "SUB", "MUL", "DIV", + "IDIV", "MOD", "POW", "UNM", @@ -80,6 +81,7 @@ LUAI_DDEF const lu_byte luaP_opmodes[NUM_OPCODES] = { ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SUB */ ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MUL */ ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_DIV */ + ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_IDIV */ ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MOD */ ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_POW */ ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_UNM */ diff --git a/lopcodes.h b/lopcodes.h index 886cdbcc..e427ce49 100644 --- a/lopcodes.h +++ b/lopcodes.h @@ -1,5 +1,5 @@ /* -** $Id: lopcodes.h,v 1.141 2011/04/19 16:22:13 roberto Exp roberto $ +** $Id: lopcodes.h,v 1.142 2011/07/15 12:50:29 roberto Exp roberto $ ** Opcodes for Lua virtual machine ** See Copyright Notice in lua.h */ @@ -188,6 +188,7 @@ OP_ADD,/* A B C R(A) := RK(B) + RK(C) */ OP_SUB,/* A B C R(A) := RK(B) - RK(C) */ OP_MUL,/* A B C R(A) := RK(B) * RK(C) */ OP_DIV,/* A B C R(A) := RK(B) / RK(C) */ +OP_IDIV,/* A B C R(A) := RK(B) // RK(C) */ OP_MOD,/* A B C R(A) := RK(B) % RK(C) */ OP_POW,/* A B C R(A) := RK(B) ^ RK(C) */ OP_UNM,/* A B R(A) := -R(B) */ diff --git a/lparser.c b/lparser.c index c6605762..2cc226d4 100644 --- a/lparser.c +++ b/lparser.c @@ -1,5 +1,5 @@ /* -** $Id: lparser.c,v 2.131 2013/04/16 18:46:28 roberto Exp roberto $ +** $Id: lparser.c,v 2.132 2013/04/25 19:35:19 roberto Exp roberto $ ** Lua Parser ** See Copyright Notice in lua.h */ @@ -1005,6 +1005,7 @@ static BinOpr getbinopr (int op) { case '-': return OPR_SUB; case '*': return OPR_MUL; case '/': return OPR_DIV; + case TK_IDIV: return OPR_IDIV; case '%': return OPR_MOD; case '^': return OPR_POW; case TK_CONCAT: return OPR_CONCAT; @@ -1025,7 +1026,8 @@ static const struct { lu_byte left; /* left priority for each binary operator */ lu_byte right; /* right priority */ } priority[] = { /* ORDER OPR */ - {6, 6}, {6, 6}, {7, 7}, {7, 7}, {7, 7}, /* `+' `-' `*' `/' `%' */ + {6, 6}, {6, 6}, /* '+' '-' */ + {7, 7}, {7, 7}, {7, 7}, {7, 7}, /* '*' '/' '//' '%' */ {10, 9}, {5, 4}, /* ^, .. (right associative) */ {3, 3}, {3, 3}, {3, 3}, /* ==, <, <= */ {3, 3}, {3, 3}, {3, 3}, /* ~=, >, >= */ diff --git a/ltests.c b/ltests.c index 241c1366..c20085a0 100644 --- a/ltests.c +++ b/ltests.c @@ -1,5 +1,5 @@ /* -** $Id: ltests.c,v 2.135 2013/03/16 21:10:18 roberto Exp roberto $ +** $Id: ltests.c,v 2.136 2013/04/24 19:41:48 roberto Exp roberto $ ** Internal Module for Debugging of the Lua Implementation ** See Copyright Notice in lua.h */ @@ -1198,7 +1198,7 @@ static int runC (lua_State *L, lua_State *L1, const char *pc) { } } else if EQ("arith") { - static char ops[] = "+-*/%^_"; + static char ops[] = "+-*/\\%^_"; /* '\' -> '//'; '_' -> '..' */ int op; skip(&pc); op = strchr(ops, *pc++) - ops; diff --git a/ltm.c b/ltm.c index d4151da4..a016cc42 100644 --- a/ltm.c +++ b/ltm.c @@ -1,5 +1,5 @@ /* -** $Id: ltm.c,v 2.16 2013/04/25 15:59:42 roberto Exp roberto $ +** $Id: ltm.c,v 2.17 2013/04/25 16:07:52 roberto Exp roberto $ ** Tag methods ** See Copyright Notice in lua.h */ @@ -35,7 +35,7 @@ void luaT_init (lua_State *L) { static const char *const luaT_eventname[] = { /* ORDER TM */ "__index", "__newindex", "__gc", "__mode", "__len", "__eq", - "__add", "__sub", "__mul", "__div", "__mod", + "__add", "__sub", "__mul", "__div", "__idiv", "__mod", "__pow", "__unm", "__lt", "__le", "__concat", "__call" }; diff --git a/ltm.h b/ltm.h index 3ff68cc7..8f088528 100644 --- a/ltm.h +++ b/ltm.h @@ -1,5 +1,5 @@ /* -** $Id: ltm.h,v 2.13 2013/04/25 15:59:42 roberto Exp roberto $ +** $Id: ltm.h,v 2.14 2013/04/25 16:07:52 roberto Exp roberto $ ** Tag methods ** See Copyright Notice in lua.h */ @@ -26,6 +26,7 @@ typedef enum { TM_SUB, TM_MUL, TM_DIV, + TM_IDIV, TM_MOD, TM_POW, TM_UNM, diff --git a/lua.h b/lua.h index c1efd9a1..eecb810c 100644 --- a/lua.h +++ b/lua.h @@ -1,5 +1,5 @@ /* -** $Id: lua.h,v 1.285 2013/03/15 13:04:22 roberto Exp roberto $ +** $Id: lua.h,v 1.286 2013/04/25 13:52:49 roberto Exp roberto $ ** Lua - A Scripting Language ** Lua.org, PUC-Rio, Brazil (http://www.lua.org) ** See Copyright Notice at the end of this file @@ -186,9 +186,10 @@ LUA_API const void *(lua_topointer) (lua_State *L, int idx); #define LUA_OPSUB 1 #define LUA_OPMUL 2 #define LUA_OPDIV 3 -#define LUA_OPMOD 4 -#define LUA_OPPOW 5 -#define LUA_OPUNM 6 +#define LUA_OPIDIV 4 +#define LUA_OPMOD 5 +#define LUA_OPPOW 6 +#define LUA_OPUNM 7 LUA_API void (lua_arith) (lua_State *L, int op); diff --git a/luaconf.h b/luaconf.h index bb68289e..8a65efba 100644 --- a/luaconf.h +++ b/luaconf.h @@ -1,5 +1,5 @@ /* -** $Id: luaconf.h,v 1.176 2013/03/16 21:10:18 roberto Exp roberto $ +** $Id: luaconf.h,v 1.177 2013/04/25 13:52:13 roberto Exp roberto $ ** Configuration file for Lua ** See Copyright Notice in lua.h */ @@ -435,6 +435,7 @@ /* the following operations need the math library */ #if defined(lobject_c) || defined(lvm_c) #include +#define luai_numidiv(L,a,b) (l_mathop(floor)((a)/(b))) #define luai_nummod(L,a,b) ((a) - l_mathop(floor)((a)/(b))*(b)) #define luai_numpow(L,a,b) (l_mathop(pow)(a,b)) #endif diff --git a/lvm.c b/lvm.c index e129438d..d772590d 100644 --- a/lvm.c +++ b/lvm.c @@ -1,5 +1,5 @@ /* -** $Id: lvm.c,v 2.161 2013/04/25 19:12:41 roberto Exp roberto $ +** $Id: lvm.c,v 2.162 2013/04/25 19:50:02 roberto Exp roberto $ ** Lua virtual machine ** See Copyright Notice in lua.h */ @@ -404,7 +404,7 @@ void luaV_finishOp (lua_State *L) { Instruction inst = *(ci->u.l.savedpc - 1); /* interrupted instruction */ OpCode op = GET_OPCODE(inst); switch (op) { /* finish its execution */ - case OP_ADD: case OP_SUB: case OP_MUL: case OP_DIV: + case OP_ADD: case OP_SUB: case OP_MUL: case OP_DIV: case OP_IDIV: case OP_MOD: case OP_POW: case OP_UNM: case OP_LEN: case OP_GETTABUP: case OP_GETTABLE: case OP_SELF: { setobjs2s(L, base + GETARG_A(inst), --L->top); @@ -640,6 +640,19 @@ void luaV_execute (lua_State *L) { } else { Protect(luaV_arith(L, ra, rb, rc, TM_DIV)); } ) + vmcase(OP_IDIV, /* integer division */ + TValue *rb = RKB(i); + TValue *rc = RKC(i); + if (ttisinteger(rb) && ttisinteger(rc)) { + lua_Integer ib = ivalue(rb); lua_Integer ic = ivalue(rc); + setivalue(ra, luaV_div(L, ib, ic)); + } + else if (ttisnumber(rb) && ttisnumber(rc)) { + lua_Number nb = nvalue(rb); lua_Number nc = nvalue(rc); + setnvalue(ra, luai_numidiv(L, nb, nc)); + } + else { Protect(luaV_arith(L, ra, rb, rc, TM_IDIV)); } + ) vmcase(OP_MOD, TValue *rb = RKB(i); TValue *rc = RKC(i);