Selaa lähdekoodia

new syntax: assignment expressions + better order for opcodes

Roberto Ierusalimschy 26 vuotta sitten
vanhempi
commit
27407fc1f5
3 muutettua tiedostoa jossa 111 lisäystä ja 67 poistoa
  1. 24 22
      lopcodes.h
  2. 41 13
      lparser.c
  3. 46 32
      lvm.c

+ 24 - 22
lopcodes.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lopcodes.h,v 1.18 1998/06/25 14:37:00 roberto Exp roberto $
+** $Id: lopcodes.h,v 1.19 1999/02/02 17:57:49 roberto Exp roberto $
 ** Opcodes for Lua virtual machine
 ** See Copyright Notice in lua.h
 */
@@ -12,7 +12,7 @@
 
 /*
 ** NOTICE: variants of the same opcode must be consecutive: First, those
-** with byte parameter, then with word parameter.
+** with word parameter, then with byte parameter.
 */
 
 
@@ -20,49 +20,55 @@ typedef enum {
 /* name          parm    before          after           side effect
 -----------------------------------------------------------------------------*/
 ENDCODE,/*	-	-		-  */
+RETCODE,/*	b	-		-  */
 
 PUSHNIL,/*	b	-		nil_0...nil_b  */
+POP,/*		b	-		-		TOP-=(b+1)  */
 
-PUSHNUMBER,/*	b	-		(float)(b-NUMOFFSET)  */
 PUSHNUMBERW,/*	w	-		(float)(w-NUMOFFSET)  */
+PUSHNUMBER,/*	b	-		(float)(b-NUMOFFSET)  */
 
-PUSHCONSTANT,/*	b	-		CNST[b] */
 PUSHCONSTANTW,/*w	-		CNST[w] */
+PUSHCONSTANT,/*	b	-		CNST[b] */
 
 PUSHUPVALUE,/*	b	-		Closure[b] */
 
 PUSHLOCAL,/*	b	-		LOC[b]  */
 
-GETGLOBAL,/*	b 	-		VAR[CNST[b]]  */
 GETGLOBALW,/*	w	-		VAR[CNST[w]]  */
+GETGLOBAL,/*	b 	-		VAR[CNST[b]]  */
 
 GETTABLE,/*	-	i t		t[i]  */
 
-GETDOTTED,/*	b	t		t[CNST[b]]  */
 GETDOTTEDW,/*	w	t		t[CNST[w]]  */
+GETDOTTED,/*	b	t		t[CNST[b]]  */
 
-PUSHSELF,/*	b	t		t t[CNST[b]]  */
 PUSHSELFW,/*	w	t		t t[CNST[w]]  */
+PUSHSELF,/*	b	t		t t[CNST[b]]  */
 
-CREATEARRAY,/*	b	-		newarray(size = b)  */
 CREATEARRAYW,/*	w	-		newarray(size = w)  */
+CREATEARRAY,/*	b	-		newarray(size = b)  */
 
 SETLOCAL,/*	b	x		-		LOC[b]=x  */
+SETLOCALDUP,/*	b	x		x		LOC[b]=x  */
 
-SETGLOBAL,/*	b	x		-		VAR[CNST[b]]=x  */
 SETGLOBALW,/*	w	x		-		VAR[CNST[w]]=x  */
+SETGLOBAL,/*	b	x		-		VAR[CNST[b]]=x  */
+SETGLOBALDUPW,/*w	x		x		VAR[CNST[w]]=x  */
+SETGLOBALDUP,/*	b	x		x		VAR[CNST[b]]=x  */
 
 SETTABLE0,/*	-	v i t		-		t[i]=v  */
+SETTABLEDUP,/*	-	v i t		v		t[i]=v  */
 
 SETTABLE,/*	b	v a_b...a_1 i t	a_b...a_1 i t	t[i]=v  */
 
-SETLIST,/*	b c	v_c...v_1 t	-		t[i+b*FPF]=v_i  */
 SETLISTW,/*	w c	v_c...v_1 t	-		t[i+w*FPF]=v_i  */
+SETLIST,/*	b c	v_c...v_1 t	-		t[i+b*FPF]=v_i  */
 
 SETMAP,/*	b	v_b k_b ...v_0 k_0 t	t	t[k_i]=v_i  */
 
-EQOP,/*		-	y x		(x==y)? 1 : nil  */
 NEQOP,/*	-	y x		(x~=y)? 1 : nil  */
+EQOP,/*		-	y x		(x==y)? 1 : nil  */
 LTOP,/*		-	y x		(x<y)? 1 : nil  */
 LEOP,/*		-	y x		(x<y)? 1 : nil  */
 GTOP,/*		-	y x		(x>y)? 1 : nil  */
@@ -76,29 +82,25 @@ CONCOP,/*	-	y x		x..y  */
 MINUSOP,/*	-	x		-x  */
 NOTOP,/*	-	x		(x==nil)? 1 : nil  */
 
-ONTJMP,/*	b	x		(x!=nil)? x : -	(x!=nil)? PC+=b  */
 ONTJMPW,/*	w	x		(x!=nil)? x : -	(x!=nil)? PC+=w  */
-ONFJMP,/*	b	x		(x==nil)? x : -	(x==nil)? PC+=b  */
+ONTJMP,/*	b	x		(x!=nil)? x : -	(x!=nil)? PC+=b  */
 ONFJMPW,/*	w	x		(x==nil)? x : -	(x==nil)? PC+=w  */
-JMP,/*		b	-		-		PC+=b  */
+ONFJMP,/*	b	x		(x==nil)? x : -	(x==nil)? PC+=b  */
 JMPW,/*		w	-		-		PC+=w  */
-IFFJMP,/*	b	x		-		(x==nil)? PC+=b  */
+JMP,/*		b	-		-		PC+=b  */
 IFFJMPW,/*	w	x		-		(x==nil)? PC+=w  */
-IFTUPJMP,/*	b	x		-		(x!=nil)? PC-=b  */
+IFFJMP,/*	b	x		-		(x==nil)? PC+=b  */
 IFTUPJMPW,/*	w	x		-		(x!=nil)? PC-=w  */
-IFFUPJMP,/*	b	x		-		(x==nil)? PC-=b  */
+IFTUPJMP,/*	b	x		-		(x!=nil)? PC-=b  */
 IFFUPJMPW,/*	w	x		-		(x==nil)? PC-=w  */
+IFFUPJMP,/*	b	x		-		(x==nil)? PC-=b  */
 
 CLOSURE,/*	b c	v_c...v_1	closure(CNST[b], v_c...v_1) */
 
 CALLFUNC,/*	b c	v_c...v_1 f	r_b...r_1	f(v1,...,v_c)  */
 
-RETCODE,/*	b	-		-  */
-
-SETLINE,/*	b	-		-		LINE=b  */
 SETLINEW,/*	w	-		-		LINE=w  */
-
-POP /*		b	-		-		TOP-=(b+1)  */
+SETLINE /*	b	-		-		LINE=b  */
 
 } OpCode;
 

+ 41 - 13
lparser.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lparser.c,v 1.12 1999/02/02 13:47:31 roberto Exp roberto $
+** $Id: lparser.c,v 1.13 1999/02/02 17:57:49 roberto Exp roberto $
 ** LL(1) Parser and code generator for Lua
 ** See Copyright Notice in lua.h
 */
@@ -114,6 +114,7 @@ static void chunk (LexState *ls);
 static void constructor (LexState *ls);
 static void decinit (LexState *ls, listdesc *d);
 static void exp0 (LexState *ls, vardesc *v);
+static void Gexp (LexState *ls, vardesc *v);
 static void exp1 (LexState *ls);
 static void exp2 (LexState *ls, vardesc *v);
 static void explist (LexState *ls, listdesc *e);
@@ -162,7 +163,7 @@ static int code_oparg_at (LexState *ls, int pc, OpCode op, int arg, int delta) {
     return 2;  /* code size (opcode + 1 byte) */
   }
   else if (arg <= MAX_WORD) {
-    code[pc] = (Byte)(op+1);
+    code[pc] = (Byte)(op-1);
     code[pc+1] = (Byte)(arg>>8);
     code[pc+2] = (Byte)(arg&0xFF);
     return 3;  /* code size (opcode + 1 word) */
@@ -429,6 +430,15 @@ static void code_args (LexState *ls, int nparams, int dots) {
 }
 
 
+static void unloaddot (LexState *ls, vardesc *v) {
+  /* dotted variables <a.x> must be stored like regular indexed vars <a["x"]> */
+  if (v->k == VDOT) {
+    code_constant(ls, v->info);
+    v->k = VINDEXED;
+  }
+}
+
+
 static void lua_pushvar (LexState *ls, vardesc *var) {
   switch (var->k) {
     case VLOCAL:
@@ -452,16 +462,16 @@ static void lua_pushvar (LexState *ls, vardesc *var) {
 }
 
 
-static void storevar (LexState *ls, vardesc *var) {
+static void genstorevar (LexState *ls, vardesc *var, OpCode *codes) {
   switch (var->k) {
     case VLOCAL:
-      code_oparg(ls, SETLOCAL, var->info, -1);
+      code_oparg(ls, codes[0], var->info, -1);
       break;
     case VGLOBAL:
-      code_oparg(ls, SETGLOBAL, var->info, -1);
+      code_oparg(ls, codes[1], var->info, -1);
       break;
     case VINDEXED:
-      code_opcode(ls, SETTABLE0, -3);
+      code_opcode(ls, codes[2], -3);
       break;
     default:
       LUA_INTERNALERROR("invalid var kind to store");
@@ -469,6 +479,12 @@ static void storevar (LexState *ls, vardesc *var) {
 }
 
 
+static void storevar (LexState *ls, vardesc *var) {
+  static OpCode codes[] = {SETLOCAL, SETGLOBAL, SETTABLE0};
+  genstorevar(ls, var, codes);
+}
+
+
 static int fix_jump (LexState *ls, int pc, OpCode op, int n) {
   /* jump is relative to position following jump instruction */
   return fix_opcode(ls, pc, op, n-(pc+JMPSIZE));
@@ -932,6 +948,21 @@ static void exp0 (LexState *ls, vardesc *v) {
 }
 
 
+static void Gexp (LexState *ls, vardesc *v) {
+  /* Gexp -> exp0 | var '=' exp1 */
+  static OpCode codes[] = {SETLOCALDUP, SETGLOBALDUP, SETTABLEDUP};
+  exp0(ls, v);
+  if (ls->token == '=' && v->k != VEXP) {  /* assignment expression? */
+    next(ls);  /* skip '=' */
+    unloaddot(ls, v);
+    exp1(ls);
+    genstorevar(ls, v, codes);
+    deltastack(ls, 1);  /* DUP operations push an extra value */
+    v->k = VEXP; v->info = 0;
+  }
+}
+
+
 static void push (LexState *ls, stack_op *s, int op) {
   if (s->top == MAXOPS)
     luaX_error(ls, "expression too complex");
@@ -993,9 +1024,9 @@ static void simpleexp (LexState *ls, vardesc *v, stack_op *s) {
       ifpart(ls, 1, ls->linenumber);
       break;
 
-    case '(':  /* simpleexp -> '(' exp0 ')' */
+    case '(':  /* simpleexp -> '(' Gexp ')' */
       next(ls);
-      exp0(ls, v);
+      Gexp(ls, v);
       check(ls, ')');
       return;
 
@@ -1206,13 +1237,10 @@ static void decinit (LexState *ls, listdesc *d) {
   }
 }
 
+
 static int assignment (LexState *ls, vardesc *v, int nvars) {
   int left = 0;
-  /* dotted variables <a.x> must be stored like regular indexed vars <a["x"]> */
-  if (v->k == VDOT) {
-    code_constant(ls, v->info);
-    v->k = VINDEXED;
-  }
+  unloaddot(ls, v);
   if (ls->token == ',') {  /* assignment -> ',' NAME assignment */
     vardesc nv;
     next(ls);

+ 46 - 32
lvm.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lvm.c,v 1.41 1999/01/25 17:39:28 roberto Exp roberto $
+** $Id: lvm.c,v 1.42 1999/02/02 17:57:49 roberto Exp roberto $
 ** Lua virtual machine
 ** See Copyright Notice in lua.h
 */
@@ -330,12 +330,24 @@ StkId luaV_execute (Closure *cl, TProtoFunc *tf, StkId base) {
     register int aux = 0;
     switch ((OpCode)*pc++) {
 
+      case ENDCODE: aux = 1;
+        S->top = S->stack + base;
+        /* goes through */
+      case RETCODE:
+        if (lua_callhook)
+          luaD_callHook(base, NULL, 1);
+        return base + (aux ? 0 : *pc);
+
       case PUSHNIL: aux = *pc++;
         do {
           ttype(S->top++) = LUA_T_NIL;
         } while (aux--);
         break;
 
+      case POP: aux = *pc++;
+        S->top -= (aux+1);
+        break;
+
       case PUSHNUMBERW: aux = highbyte(*pc++);
       case PUSHNUMBER:  aux += *pc++;
         ttype(S->top) = LUA_T_NUMBER;
@@ -343,6 +355,15 @@ StkId luaV_execute (Closure *cl, TProtoFunc *tf, StkId base) {
         S->top++;
         break;
 
+      case PUSHCONSTANTW: aux = highbyte(*pc++);
+      case PUSHCONSTANT:  aux += *pc++;
+        *S->top++ = consts[aux];
+        break;
+
+      case PUSHUPVALUE: aux = *pc++;
+        *S->top++ = cl->consts[aux+1];
+        break;
+
       case PUSHLOCAL: aux = *pc++;
         *S->top++ = *((S->stack+base) + aux);
         break;
@@ -371,28 +392,45 @@ StkId luaV_execute (Closure *cl, TProtoFunc *tf, StkId base) {
         break;
       }
 
-      case PUSHCONSTANTW: aux = highbyte(*pc++);
-      case PUSHCONSTANT:  aux += *pc++;
-        *S->top++ = consts[aux];
-        break;
-
-      case PUSHUPVALUE: aux = *pc++;
-        *S->top++ = cl->consts[aux+1];
+      case CREATEARRAYW: aux = highbyte(*pc++);
+      case CREATEARRAY:  aux += *pc++;
+        luaC_checkGC();
+        avalue(S->top) = luaH_new(aux);
+        ttype(S->top) = LUA_T_ARRAY;
+        S->top++;
         break;
 
       case SETLOCAL: aux = *pc++;
         *((S->stack+base) + aux) = *(--S->top);
         break;
 
+      case SETLOCALDUP: aux = *pc++;
+        *((S->stack+base) + aux) = *(S->top-1);
+        break;
+
       case SETGLOBALW: aux = highbyte(*pc++);
       case SETGLOBAL:  aux += *pc++;
         luaV_setglobal(tsvalue(&consts[aux]));
         break;
 
+      case SETGLOBALDUPW: aux = highbyte(*pc++);
+      case SETGLOBALDUP:  aux += *pc++;
+        *S->top = *(S->top-1);
+        S->top++;
+        luaV_setglobal(tsvalue(&consts[aux]));
+        break;
+
       case SETTABLE0:
        luaV_settable(S->top-3, 0);
        break;
 
+      case SETTABLEDUP: {
+       TObject temp = *(S->top-1);
+       luaV_settable(S->top-3, 0);
+       *(S->top++) = temp;
+       break;
+     }
+
       case SETTABLE:
         luaV_settable(S->top-3-(*pc++), 1);
         break;
@@ -416,18 +454,6 @@ StkId luaV_execute (Closure *cl, TProtoFunc *tf, StkId base) {
         break;
       }
 
-      case POP: aux = *pc++;
-        S->top -= (aux+1);
-        break;
-
-      case CREATEARRAYW: aux = highbyte(*pc++);
-      case CREATEARRAY:  aux += *pc++;
-        luaC_checkGC();
-        avalue(S->top) = luaH_new(aux);
-        ttype(S->top) = LUA_T_ARRAY;
-        S->top++;
-        break;
-
       case NEQOP: aux = 1;
       case EQOP: {
         int res = luaO_equalObj(S->top-2, S->top-1);
@@ -579,14 +605,6 @@ StkId luaV_execute (Closure *cl, TProtoFunc *tf, StkId base) {
         break;
       }
 
-      case ENDCODE: aux = 1;
-        S->top = S->stack + base;
-        /* goes through */
-      case RETCODE:
-        if (lua_callhook)
-          luaD_callHook(base, NULL, 1);
-        return base + (aux ? 0 : *pc);
-
       case SETLINEW: aux = highbyte(*pc++);
       case SETLINE:  aux += *pc++;
         if ((S->stack+base-1)->ttype != LUA_T_LINE) {
@@ -600,10 +618,6 @@ StkId luaV_execute (Closure *cl, TProtoFunc *tf, StkId base) {
           luaD_lineHook(aux);
         break;
 
-#ifdef DEBUG
-      default:
-        LUA_INTERNALERROR("opcode doesn't match");
-#endif
     }
   }
 }