commit 04bbd0117174911a489ca7d2603c1e8717565405
parent 9ffae705ee8894d68bbc07a1a5f77a112c40efad
Author: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
Date: Wed, 16 Mar 2005 13:58:59 -0300
new operation *t (for size of t) (may yet be removed...)
Diffstat:
6 files changed, 47 insertions(+), 15 deletions(-)
diff --git a/lcode.c b/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);
}
diff --git a/lcode.h b/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])
diff --git a/lopcodes.c b/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 */
diff --git a/lopcodes.h b/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) */
diff --git a/lparser.c b/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;
}
}
diff --git a/lvm.c b/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);