浏览代码

new operation *t (for size of t) (may yet be removed...)

Roberto Ierusalimschy 20 年之前
父节点
当前提交
04bbd01171
共有 6 个文件被更改,包括 47 次插入15 次删除
  1. 22 9
      lcode.c
  2. 2 2
      lcode.h
  3. 3 1
      lopcodes.c
  4. 2 1
      lopcodes.h
  5. 2 1
      lparser.c
  6. 16 1
      lvm.c

+ 22 - 9
lcode.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lcode.c,v 2.10 2005/03/08 20:10:05 roberto Exp roberto $
+** $Id: lcode.c,v 2.11 2005/03/09 16:28:07 roberto Exp roberto $
 ** Code generator for Lua
 ** See Copyright Notice in lua.h
 */
@@ -603,19 +603,32 @@ void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) {
 
 
 void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e) {
-  if (op == OPR_MINUS) {
-    luaK_exp2val(fs, e);
-    if (e->k == VK && ttisnumber(&fs->f->k[e->info]))
-      e->info = luaK_numberK(fs, luai_numunm(nvalue(&fs->f->k[e->info])));
-    else {
+  switch (op) {
+    case OPR_MINUS: {
+      luaK_exp2val(fs, e);
+      if (e->k == VK && ttisnumber(&fs->f->k[e->info]))
+        e->info = luaK_numberK(fs, luai_numunm(nvalue(&fs->f->k[e->info])));
+      else {
+        luaK_exp2anyreg(fs, e);
+        freeexp(fs, e);
+        e->info = luaK_codeABC(fs, OP_UNM, 0, e->info, 0);
+        e->k = VRELOCABLE;
+      }
+      break;
+    }
+    case OPR_NOT: {
+      codenot(fs, e);
+      break;
+    }
+    case OPR_SIZE: {
       luaK_exp2anyreg(fs, e);
       freeexp(fs, e);
-      e->info = luaK_codeABC(fs, OP_UNM, 0, e->info, 0);
+      e->info = luaK_codeABC(fs, OP_SIZ, 0, e->info, 0);
       e->k = VRELOCABLE;
+      break;
     }
+    default: lua_assert(0);
   }
-  else  /* op == NOT */
-    codenot(fs, e);
 }
 
 

+ 2 - 2
lcode.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lcode.h,v 1.40 2004/10/04 19:01:53 roberto Exp roberto $
+** $Id: lcode.h,v 1.41 2005/03/08 18:00:16 roberto Exp roberto $
 ** Code generator for Lua
 ** See Copyright Notice in lua.h
 */
@@ -34,7 +34,7 @@ typedef enum BinOpr {
 
 #define binopistest(op)	((op) >= OPR_NE)
 
-typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_NOUNOPR } UnOpr;
+typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_SIZE, OPR_NOUNOPR } UnOpr;
 
 
 #define getcode(fs,e)	((fs)->f->code[(e)->info])

+ 3 - 1
lopcodes.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lopcodes.c,v 1.30 2004/12/02 12:59:10 roberto Exp roberto $
+** $Id: lopcodes.c,v 1.31 2005/03/08 18:00:16 roberto Exp roberto $
 ** See Copyright Notice in lua.h
 */
 
@@ -36,6 +36,7 @@ const char *const luaP_opnames[NUM_OPCODES+1] = {
   "POW",
   "UNM",
   "NOT",
+  "SIZ",
   "CONCAT",
   "JMP",
   "EQ",
@@ -81,6 +82,7 @@ const lu_byte luaP_opmodes[NUM_OPCODES] = {
  ,opmode(0, 1, OpArgK, OpArgK, iABC)		/* OP_POW */
  ,opmode(0, 1, OpArgR, OpArgN, iABC)		/* OP_UNM */
  ,opmode(0, 1, OpArgR, OpArgN, iABC)		/* OP_NOT */
+ ,opmode(0, 1, OpArgR, OpArgN, iABC)		/* OP_SIZ */
  ,opmode(0, 1, OpArgR, OpArgR, iABC)		/* OP_CONCAT */
  ,opmode(0, 0, OpArgR, OpArgN, iAsBx)		/* OP_JMP */
  ,opmode(1, 0, OpArgK, OpArgK, iABC)		/* OP_EQ */

+ 2 - 1
lopcodes.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lopcodes.h,v 1.116 2005/03/08 20:10:05 roberto Exp roberto $
+** $Id: lopcodes.h,v 1.117 2005/03/09 16:28:07 roberto Exp roberto $
 ** Opcodes for Lua virtual machine
 ** See Copyright Notice in lua.h
 */
@@ -176,6 +176,7 @@ 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)					*/
 OP_NOT,/*	A B	R(A) := not R(B)				*/
+OP_SIZ,/*	A B	R(A) := size of R(B)				*/
 
 OP_CONCAT,/*	A B C	R(A) := R(B).. ... ..R(C)			*/
 

+ 2 - 1
lparser.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lparser.c,v 2.17 2005/03/08 20:10:05 roberto Exp roberto $
+** $Id: lparser.c,v 2.18 2005/03/09 16:28:07 roberto Exp roberto $
 ** Lua Parser
 ** See Copyright Notice in lua.h
 */
@@ -788,6 +788,7 @@ static UnOpr getunopr (int op) {
   switch (op) {
     case TK_NOT: return OPR_NOT;
     case '-': return OPR_MINUS;
+    case '*': return OPR_SIZE;
     default: return OPR_NOUNOPR;
   }
 }

+ 16 - 1
lvm.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lvm.c,v 2.31 2005/03/08 20:10:05 roberto Exp roberto $
+** $Id: lvm.c,v 2.32 2005/03/09 16:28:07 roberto Exp roberto $
 ** Lua virtual machine
 ** See Copyright Notice in lua.h
 */
@@ -562,6 +562,21 @@ StkId luaV_execute (lua_State *L, int nexeccalls) {
         setbvalue(ra, res);
         continue;
       }
+      case OP_SIZ: {
+        const TValue *rb = RB(i);
+        switch (ttype(rb)) {
+          case LUA_TTABLE:
+            setnvalue(ra, cast(lua_Number, luaH_getn(hvalue(rb))));
+            break;
+          case LUA_TSTRING:
+            setnvalue(ra, cast(lua_Number, tsvalue(rb)->len));
+            break;
+          default:  /* no metamethod?? */
+            L->ci->savedpc = pc;
+            luaG_typeerror(L, rb, "get the size of");
+        }
+        continue;
+      }
       case OP_CONCAT: {
         int b = GETARG_B(i);
         int c = GETARG_C(i);