Explorar o código

new operation '//' (integer division)

Roberto Ierusalimschy %!s(int64=12) %!d(string=hai) anos
pai
achega
a2f5c28a80
Modificáronse 14 ficheiros con 56 adicións e 27 borrados
  1. 5 4
      lcode.c
  2. 2 2
      lcode.h
  3. 2 1
      ldebug.c
  4. 7 2
      llex.c
  5. 3 2
      llex.h
  6. 3 1
      lopcodes.c
  7. 2 1
      lopcodes.h
  8. 4 2
      lparser.c
  9. 2 2
      ltests.c
  10. 2 2
      ltm.c
  11. 2 1
      ltm.h
  12. 5 4
      lua.h
  13. 2 1
      luaconf.h
  14. 15 2
      lvm.c

+ 5 - 4
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;
     }

+ 2 - 2
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,

+ 2 - 1
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;

+ 7 - 2
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",
-    "..", "...", "==", ">=", "<=", "~=", "::", "<eof>",
+    "//", "..", "...", "==", ">=", "<=", "~=", "::", "<eof>",
     "<number>", "<number>", "<name>", "<string>"
 };
 
@@ -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 '~';

+ 3 - 2
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
 };
 

+ 3 - 1
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 */

+ 2 - 1
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)					*/

+ 4 - 2
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},          /* ~=, >, >= */

+ 2 - 2
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;

+ 2 - 2
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"
   };

+ 2 - 1
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,

+ 5 - 4
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);
 

+ 2 - 1
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 <math.h>
+#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

+ 15 - 2
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);