aboutsummaryrefslogtreecommitdiff
path: root/lparser.c
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 /lparser.c
parentfb1cf6ab2d12bd61e3d429830ab20d4ff3c39fd9 (diff)
downloadlua-8b2d97d1871147c730a986656907837458b601f8.tar.gz
lua-8b2d97d1871147c730a986656907837458b601f8.tar.bz2
lua-8b2d97d1871147c730a986656907837458b601f8.zip
assignment expression may be multiple
Diffstat (limited to 'lparser.c')
-rw-r--r--lparser.c45
1 files changed, 22 insertions, 23 deletions
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;