From 27407fc1f5fc4e0d97dadeda5939efa62fe7e380 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Tue, 2 Feb 1999 17:41:17 -0200 Subject: [PATCH] new syntax: assignment expressions + better order for opcodes --- lopcodes.h | 46 +++++++++++++++++--------------- lparser.c | 54 ++++++++++++++++++++++++++++--------- lvm.c | 78 ++++++++++++++++++++++++++++++++---------------------- 3 files changed, 111 insertions(+), 67 deletions(-) diff --git a/lopcodes.h b/lopcodes.h index 810d1ebe..66af79f1 100644 --- a/lopcodes.h +++ b/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 (xy)? 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; diff --git a/lparser.c b/lparser.c index 8d632038..a960dc13 100644 --- a/lparser.c +++ b/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 must be stored like regular indexed vars */ + 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 must be stored like regular indexed vars */ - 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); diff --git a/lvm.c b/lvm.c index 082c7e8f..d10dae92 100644 --- a/lvm.c +++ b/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 } } }