From 8b2d97d1871147c730a986656907837458b601f8 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Mon, 8 Feb 1999 16:54:19 -0200 Subject: assignment expression may be multiple --- lopcodes.h | 4 +++- lparser.c | 45 ++++++++++++++++++++++----------------------- lvm.c | 33 ++++++++++++++++++++++----------- 3 files changed, 47 insertions(+), 35 deletions(-) diff --git a/lopcodes.h b/lopcodes.h index e58f3f79..9a2ef6a5 100644 --- a/lopcodes.h +++ b/lopcodes.h @@ -1,5 +1,5 @@ /* -** $Id: lopcodes.h,v 1.21 1999/02/04 16:36:16 roberto Exp roberto $ +** $Id: lopcodes.h,v 1.22 1999/02/08 17:07:59 roberto Exp roberto $ ** Opcodes for Lua virtual machine ** See Copyright Notice in lua.h */ @@ -22,6 +22,7 @@ RETCODE,/* b - - */ PUSHNIL,/* b - nil_0...nil_b */ POP,/* b - - TOP-=(b+1) */ +POPDUP,/* b v v TOP-=(b+1) */ PUSHNUMBERW,/* w - (float)(w-NUMOFFSET) */ PUSHNUMBER,/* b - (float)(b-NUMOFFSET) */ @@ -59,6 +60,7 @@ SETTABLEPOP,/* - v i t - t[i]=v */ SETTABPPDUP,/* - 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 */ +SETTABLEDUP,/* b v a_b...a_1 i t v a_b...a_1 i t t[i]=v */ 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 */ diff --git a/lparser.c b/lparser.c index 297eebd6..be44c693 100644 --- a/lparser.c +++ b/lparser.c @@ -1,5 +1,5 @@ /* -** $Id: lparser.c,v 1.16 1999/02/04 17:47:59 roberto Exp roberto $ +** $Id: lparser.c,v 1.17 1999/02/08 17:07:59 roberto Exp roberto $ ** LL(1) Parser and code generator for Lua ** See Copyright Notice in lua.h */ @@ -102,7 +102,7 @@ typedef struct FuncState { /* ** prototypes for non-terminal functions */ -static int assignment (LexState *ls, vardesc *v, int nvars); +static int assignment (LexState *ls, vardesc *v, int nvars, OpCode *codes); static int cond (LexState *ls); static int funcname (LexState *ls, vardesc *v); static int funcparams (LexState *ls, int slf); @@ -387,7 +387,7 @@ static void check_debugline (LexState *ls) { static void adjuststack (LexState *ls, int n) { if (n > 0) - code_oparg(ls, POP, n-1, -n); + code_oparg(ls, POP, n, -n); else if (n < 0) code_oparg(ls, PUSHNIL, (-n)-1, -n); } @@ -472,7 +472,13 @@ static void lua_pushvar (LexState *ls, vardesc *var) { } -static void genstorevar (LexState *ls, vardesc *var, OpCode *codes) { +/* to be used by "storevar" and assignment */ +static OpCode set_pop[] = {SETLOCAL, SETGLOBAL, SETTABLEPOP, SETTABLE}; +static OpCode set_dup[] = {SETLOCALDUP, SETGLOBALDUP, SETTABPPDUP, + SETTABLEDUP}; + + +static void storevar (LexState *ls, vardesc *var, OpCode *codes) { switch (var->k) { case VLOCAL: code_oparg(ls, codes[0], var->info, -1); @@ -489,12 +495,6 @@ static void genstorevar (LexState *ls, vardesc *var, OpCode *codes) { } -static void storevar (LexState *ls, vardesc *var) { - static OpCode codes[] = {SETLOCAL, SETGLOBAL, SETTABLEPOP}; - 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)); @@ -748,7 +748,7 @@ static int stat (LexState *ls) { next(ls); needself = funcname(ls, &v); body(ls, needself, line); - storevar(ls, &v); + storevar(ls, &v, set_pop); return 1; } @@ -773,8 +773,8 @@ static int stat (LexState *ls) { luaX_error(ls, "syntax error"); close_exp(ls, v.info, 0); } - else { - int left = assignment(ls, &v, 1); /* stat -> ['%'] NAME assignment */ + else { /* stat -> ['%'] NAME assignment */ + int left = assignment(ls, &v, 1, set_pop); adjuststack(ls, left); /* remove eventual 'garbage' left on stack */ } return 1; @@ -953,14 +953,13 @@ static void exp0 (LexState *ls, vardesc *v) { static void Gexp (LexState *ls, vardesc *v) { - /* Gexp -> exp0 | var '=' exp1 */ - static OpCode codes[] = {SETLOCALDUP, SETGLOBALDUP, SETTABPPDUP}; + /* Gexp -> exp0 | assignment */ exp0(ls, v); - if (v->k != VEXP && optional(ls, '=')) { /* assignment expression? */ - unloaddot(ls, v); - exp1(ls); - genstorevar(ls, v, codes); + if (v->k != VEXP && (ls->token == '=' || ls->token == ',')) { + int left = assignment(ls, v, 1, set_dup); deltastack(ls, 1); /* DUP operations push an extra value */ + if (left > 0) + code_oparg(ls, POPDUP, left, -left); v->k = VEXP; v->info = 0; /* this expression is closed now */ } } @@ -1244,7 +1243,7 @@ static void decinit (LexState *ls, listdesc *d) { } -static int assignment (LexState *ls, vardesc *v, int nvars) { +static int assignment (LexState *ls, vardesc *v, int nvars, OpCode *codes) { int left = 0; unloaddot(ls, v); if (ls->token == ',') { /* assignment -> ',' NAME assignment */ @@ -1253,7 +1252,7 @@ static int assignment (LexState *ls, vardesc *v, int nvars) { var_or_func(ls, &nv); if (nv.k == VEXP) luaX_error(ls, "syntax error"); - left = assignment(ls, &nv, nvars+1); + left = assignment(ls, &nv, nvars+1, set_pop); } else { /* assignment -> '=' explist1 */ listdesc d; @@ -1263,10 +1262,10 @@ static int assignment (LexState *ls, vardesc *v, int nvars) { } if (v->k != VINDEXED || left+(nvars-1) == 0) { /* global/local var or indexed var without values in between */ - storevar(ls, v); + storevar(ls, v, codes); } else { /* indexed var with values in between*/ - code_oparg(ls, SETTABLE, left+(nvars-1), -1); + code_oparg(ls, codes[3], left+(nvars-1), -1); left += 2; /* table/index are not popped, because they aren't on top */ } return left; diff --git a/lvm.c b/lvm.c index 6dc34dd4..f321cb83 100644 --- a/lvm.c +++ b/lvm.c @@ -1,5 +1,5 @@ /* -** $Id: lvm.c,v 1.45 1999/02/04 17:47:59 roberto Exp roberto $ +** $Id: lvm.c,v 1.46 1999/02/08 17:07:59 roberto Exp roberto $ ** Lua virtual machine ** See Copyright Notice in lua.h */ @@ -344,7 +344,12 @@ StkId luaV_execute (Closure *cl, TProtoFunc *tf, StkId base) { break; case POP: aux = *pc++; - S->top -= (aux+1); + S->top -= aux; + break; + + case POPDUP: aux = *pc++; + *(S->top-aux-1) = *(S->top-1); + S->top -= aux; break; case PUSHNUMBERW: aux += highbyte(*pc++); @@ -420,22 +425,28 @@ StkId luaV_execute (Closure *cl, TProtoFunc *tf, StkId base) { break; case SETTABLEPOP: - luaV_settable(S->top-3); - S->top -= 2; /* pop table and index */ - break; + luaV_settable(S->top-3); + S->top -= 2; /* pop table and index */ + break; case SETTABPPDUP: { - TObject temp = *(S->top-1); - luaV_settable(S->top-3); - S->top--; /* pop index (temp goes into "table" position) */ - *(S->top-1) = temp; - break; - } + TObject temp = *(S->top-1); + luaV_settable(S->top-3); + S->top--; /* pop index (temp goes into "table" position) */ + *(S->top-1) = temp; + break; + } case SETTABLE: luaV_settable(S->top-3-(*pc++)); break; + case SETTABLEDUP: + *S->top = *(S->top-1); + S->top++; + luaV_settable(S->top-(3+1)-(*pc++)); + break; + case SETLISTW: aux += highbyte(*pc++); case SETLIST: aux += *pc++; { int n = *(pc++); -- cgit v1.2.3-55-g6feb