aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>1999-02-08 16:54:19 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>1999-02-08 16:54:19 -0200
commit8b2d97d1871147c730a986656907837458b601f8 (patch)
treed555c67380642b973a43d04fcfbbfdb3588e12da
parentfb1cf6ab2d12bd61e3d429830ab20d4ff3c39fd9 (diff)
downloadlua-8b2d97d1871147c730a986656907837458b601f8.tar.gz
lua-8b2d97d1871147c730a986656907837458b601f8.tar.bz2
lua-8b2d97d1871147c730a986656907837458b601f8.zip
assignment expression may be multiple
-rw-r--r--lopcodes.h4
-rw-r--r--lparser.c45
-rw-r--r--lvm.c33
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 @@
1/* 1/*
2** $Id: lopcodes.h,v 1.21 1999/02/04 16:36:16 roberto Exp roberto $ 2** $Id: lopcodes.h,v 1.22 1999/02/08 17:07:59 roberto Exp roberto $
3** Opcodes for Lua virtual machine 3** Opcodes for Lua virtual machine
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -22,6 +22,7 @@ RETCODE,/* b - - */
22 22
23PUSHNIL,/* b - nil_0...nil_b */ 23PUSHNIL,/* b - nil_0...nil_b */
24POP,/* b - - TOP-=(b+1) */ 24POP,/* b - - TOP-=(b+1) */
25POPDUP,/* b v v TOP-=(b+1) */
25 26
26PUSHNUMBERW,/* w - (float)(w-NUMOFFSET) */ 27PUSHNUMBERW,/* w - (float)(w-NUMOFFSET) */
27PUSHNUMBER,/* b - (float)(b-NUMOFFSET) */ 28PUSHNUMBER,/* b - (float)(b-NUMOFFSET) */
@@ -59,6 +60,7 @@ SETTABLEPOP,/* - v i t - t[i]=v */
59SETTABPPDUP,/* - v i t v t[i]=v */ 60SETTABPPDUP,/* - v i t v t[i]=v */
60 61
61SETTABLE,/* b v a_b...a_1 i t a_b...a_1 i t t[i]=v */ 62SETTABLE,/* b v a_b...a_1 i t a_b...a_1 i t t[i]=v */
63SETTABLEDUP,/* b v a_b...a_1 i t v a_b...a_1 i t t[i]=v */
62 64
63SETLISTW,/* w c v_c...v_1 t - t[i+w*FPF]=v_i */ 65SETLISTW,/* w c v_c...v_1 t - t[i+w*FPF]=v_i */
64SETLIST,/* b c v_c...v_1 t - t[i+b*FPF]=v_i */ 66SETLIST,/* 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 @@
1/* 1/*
2** $Id: lparser.c,v 1.16 1999/02/04 17:47:59 roberto Exp roberto $ 2** $Id: lparser.c,v 1.17 1999/02/08 17:07:59 roberto Exp roberto $
3** LL(1) Parser and code generator for Lua 3** LL(1) Parser and code generator for Lua
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -102,7 +102,7 @@ typedef struct FuncState {
102/* 102/*
103** prototypes for non-terminal functions 103** prototypes for non-terminal functions
104*/ 104*/
105static int assignment (LexState *ls, vardesc *v, int nvars); 105static int assignment (LexState *ls, vardesc *v, int nvars, OpCode *codes);
106static int cond (LexState *ls); 106static int cond (LexState *ls);
107static int funcname (LexState *ls, vardesc *v); 107static int funcname (LexState *ls, vardesc *v);
108static int funcparams (LexState *ls, int slf); 108static int funcparams (LexState *ls, int slf);
@@ -387,7 +387,7 @@ static void check_debugline (LexState *ls) {
387 387
388static void adjuststack (LexState *ls, int n) { 388static void adjuststack (LexState *ls, int n) {
389 if (n > 0) 389 if (n > 0)
390 code_oparg(ls, POP, n-1, -n); 390 code_oparg(ls, POP, n, -n);
391 else if (n < 0) 391 else if (n < 0)
392 code_oparg(ls, PUSHNIL, (-n)-1, -n); 392 code_oparg(ls, PUSHNIL, (-n)-1, -n);
393} 393}
@@ -472,7 +472,13 @@ static void lua_pushvar (LexState *ls, vardesc *var) {
472} 472}
473 473
474 474
475static void genstorevar (LexState *ls, vardesc *var, OpCode *codes) { 475/* to be used by "storevar" and assignment */
476static OpCode set_pop[] = {SETLOCAL, SETGLOBAL, SETTABLEPOP, SETTABLE};
477static OpCode set_dup[] = {SETLOCALDUP, SETGLOBALDUP, SETTABPPDUP,
478 SETTABLEDUP};
479
480
481static void storevar (LexState *ls, vardesc *var, OpCode *codes) {
476 switch (var->k) { 482 switch (var->k) {
477 case VLOCAL: 483 case VLOCAL:
478 code_oparg(ls, codes[0], var->info, -1); 484 code_oparg(ls, codes[0], var->info, -1);
@@ -489,12 +495,6 @@ static void genstorevar (LexState *ls, vardesc *var, OpCode *codes) {
489} 495}
490 496
491 497
492static void storevar (LexState *ls, vardesc *var) {
493 static OpCode codes[] = {SETLOCAL, SETGLOBAL, SETTABLEPOP};
494 genstorevar(ls, var, codes);
495}
496
497
498static int fix_jump (LexState *ls, int pc, OpCode op, int n) { 498static int fix_jump (LexState *ls, int pc, OpCode op, int n) {
499 /* jump is relative to position following jump instruction */ 499 /* jump is relative to position following jump instruction */
500 return fix_opcode(ls, pc, op, n-(pc+JMPSIZE)); 500 return fix_opcode(ls, pc, op, n-(pc+JMPSIZE));
@@ -748,7 +748,7 @@ static int stat (LexState *ls) {
748 next(ls); 748 next(ls);
749 needself = funcname(ls, &v); 749 needself = funcname(ls, &v);
750 body(ls, needself, line); 750 body(ls, needself, line);
751 storevar(ls, &v); 751 storevar(ls, &v, set_pop);
752 return 1; 752 return 1;
753 } 753 }
754 754
@@ -773,8 +773,8 @@ static int stat (LexState *ls) {
773 luaX_error(ls, "syntax error"); 773 luaX_error(ls, "syntax error");
774 close_exp(ls, v.info, 0); 774 close_exp(ls, v.info, 0);
775 } 775 }
776 else { 776 else { /* stat -> ['%'] NAME assignment */
777 int left = assignment(ls, &v, 1); /* stat -> ['%'] NAME assignment */ 777 int left = assignment(ls, &v, 1, set_pop);
778 adjuststack(ls, left); /* remove eventual 'garbage' left on stack */ 778 adjuststack(ls, left); /* remove eventual 'garbage' left on stack */
779 } 779 }
780 return 1; 780 return 1;
@@ -953,14 +953,13 @@ static void exp0 (LexState *ls, vardesc *v) {
953 953
954 954
955static void Gexp (LexState *ls, vardesc *v) { 955static void Gexp (LexState *ls, vardesc *v) {
956 /* Gexp -> exp0 | var '=' exp1 */ 956 /* Gexp -> exp0 | assignment */
957 static OpCode codes[] = {SETLOCALDUP, SETGLOBALDUP, SETTABPPDUP};
958 exp0(ls, v); 957 exp0(ls, v);
959 if (v->k != VEXP && optional(ls, '=')) { /* assignment expression? */ 958 if (v->k != VEXP && (ls->token == '=' || ls->token == ',')) {
960 unloaddot(ls, v); 959 int left = assignment(ls, v, 1, set_dup);
961 exp1(ls);
962 genstorevar(ls, v, codes);
963 deltastack(ls, 1); /* DUP operations push an extra value */ 960 deltastack(ls, 1); /* DUP operations push an extra value */
961 if (left > 0)
962 code_oparg(ls, POPDUP, left, -left);
964 v->k = VEXP; v->info = 0; /* this expression is closed now */ 963 v->k = VEXP; v->info = 0; /* this expression is closed now */
965 } 964 }
966} 965}
@@ -1244,7 +1243,7 @@ static void decinit (LexState *ls, listdesc *d) {
1244} 1243}
1245 1244
1246 1245
1247static int assignment (LexState *ls, vardesc *v, int nvars) { 1246static int assignment (LexState *ls, vardesc *v, int nvars, OpCode *codes) {
1248 int left = 0; 1247 int left = 0;
1249 unloaddot(ls, v); 1248 unloaddot(ls, v);
1250 if (ls->token == ',') { /* assignment -> ',' NAME assignment */ 1249 if (ls->token == ',') { /* assignment -> ',' NAME assignment */
@@ -1253,7 +1252,7 @@ static int assignment (LexState *ls, vardesc *v, int nvars) {
1253 var_or_func(ls, &nv); 1252 var_or_func(ls, &nv);
1254 if (nv.k == VEXP) 1253 if (nv.k == VEXP)
1255 luaX_error(ls, "syntax error"); 1254 luaX_error(ls, "syntax error");
1256 left = assignment(ls, &nv, nvars+1); 1255 left = assignment(ls, &nv, nvars+1, set_pop);
1257 } 1256 }
1258 else { /* assignment -> '=' explist1 */ 1257 else { /* assignment -> '=' explist1 */
1259 listdesc d; 1258 listdesc d;
@@ -1263,10 +1262,10 @@ static int assignment (LexState *ls, vardesc *v, int nvars) {
1263 } 1262 }
1264 if (v->k != VINDEXED || left+(nvars-1) == 0) { 1263 if (v->k != VINDEXED || left+(nvars-1) == 0) {
1265 /* global/local var or indexed var without values in between */ 1264 /* global/local var or indexed var without values in between */
1266 storevar(ls, v); 1265 storevar(ls, v, codes);
1267 } 1266 }
1268 else { /* indexed var with values in between*/ 1267 else { /* indexed var with values in between*/
1269 code_oparg(ls, SETTABLE, left+(nvars-1), -1); 1268 code_oparg(ls, codes[3], left+(nvars-1), -1);
1270 left += 2; /* table/index are not popped, because they aren't on top */ 1269 left += 2; /* table/index are not popped, because they aren't on top */
1271 } 1270 }
1272 return left; 1271 return left;
diff --git a/lvm.c b/lvm.c
index 6dc34dd4..f321cb83 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.c,v 1.45 1999/02/04 17:47:59 roberto Exp roberto $ 2** $Id: lvm.c,v 1.46 1999/02/08 17:07:59 roberto Exp roberto $
3** Lua virtual machine 3** Lua virtual machine
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -344,7 +344,12 @@ StkId luaV_execute (Closure *cl, TProtoFunc *tf, StkId base) {
344 break; 344 break;
345 345
346 case POP: aux = *pc++; 346 case POP: aux = *pc++;
347 S->top -= (aux+1); 347 S->top -= aux;
348 break;
349
350 case POPDUP: aux = *pc++;
351 *(S->top-aux-1) = *(S->top-1);
352 S->top -= aux;
348 break; 353 break;
349 354
350 case PUSHNUMBERW: aux += highbyte(*pc++); 355 case PUSHNUMBERW: aux += highbyte(*pc++);
@@ -420,22 +425,28 @@ StkId luaV_execute (Closure *cl, TProtoFunc *tf, StkId base) {
420 break; 425 break;
421 426
422 case SETTABLEPOP: 427 case SETTABLEPOP:
423 luaV_settable(S->top-3); 428 luaV_settable(S->top-3);
424 S->top -= 2; /* pop table and index */ 429 S->top -= 2; /* pop table and index */
425 break; 430 break;
426 431
427 case SETTABPPDUP: { 432 case SETTABPPDUP: {
428 TObject temp = *(S->top-1); 433 TObject temp = *(S->top-1);
429 luaV_settable(S->top-3); 434 luaV_settable(S->top-3);
430 S->top--; /* pop index (temp goes into "table" position) */ 435 S->top--; /* pop index (temp goes into "table" position) */
431 *(S->top-1) = temp; 436 *(S->top-1) = temp;
432 break; 437 break;
433 } 438 }
434 439
435 case SETTABLE: 440 case SETTABLE:
436 luaV_settable(S->top-3-(*pc++)); 441 luaV_settable(S->top-3-(*pc++));
437 break; 442 break;
438 443
444 case SETTABLEDUP:
445 *S->top = *(S->top-1);
446 S->top++;
447 luaV_settable(S->top-(3+1)-(*pc++));
448 break;
449
439 case SETLISTW: aux += highbyte(*pc++); 450 case SETLISTW: aux += highbyte(*pc++);
440 case SETLIST: aux += *pc++; { 451 case SETLIST: aux += *pc++; {
441 int n = *(pc++); 452 int n = *(pc++);