aboutsummaryrefslogtreecommitdiff
path: root/lparser.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>1999-02-02 17:41:17 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>1999-02-02 17:41:17 -0200
commit27407fc1f5fc4e0d97dadeda5939efa62fe7e380 (patch)
treea47a3f41547509627999963896b5ce3c8a335bf7 /lparser.c
parent1a17da2ff9dce06a0405f549522a4e08026c3124 (diff)
downloadlua-27407fc1f5fc4e0d97dadeda5939efa62fe7e380.tar.gz
lua-27407fc1f5fc4e0d97dadeda5939efa62fe7e380.tar.bz2
lua-27407fc1f5fc4e0d97dadeda5939efa62fe7e380.zip
new syntax: assignment expressions + better order for opcodes
Diffstat (limited to 'lparser.c')
-rw-r--r--lparser.c54
1 files changed, 41 insertions, 13 deletions
diff --git a/lparser.c b/lparser.c
index 8d632038..a960dc13 100644
--- a/lparser.c
+++ b/lparser.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lparser.c,v 1.12 1999/02/02 13:47:31 roberto Exp roberto $ 2** $Id: lparser.c,v 1.13 1999/02/02 17:57:49 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*/
@@ -114,6 +114,7 @@ static void chunk (LexState *ls);
114static void constructor (LexState *ls); 114static void constructor (LexState *ls);
115static void decinit (LexState *ls, listdesc *d); 115static void decinit (LexState *ls, listdesc *d);
116static void exp0 (LexState *ls, vardesc *v); 116static void exp0 (LexState *ls, vardesc *v);
117static void Gexp (LexState *ls, vardesc *v);
117static void exp1 (LexState *ls); 118static void exp1 (LexState *ls);
118static void exp2 (LexState *ls, vardesc *v); 119static void exp2 (LexState *ls, vardesc *v);
119static void explist (LexState *ls, listdesc *e); 120static 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) {
162 return 2; /* code size (opcode + 1 byte) */ 163 return 2; /* code size (opcode + 1 byte) */
163 } 164 }
164 else if (arg <= MAX_WORD) { 165 else if (arg <= MAX_WORD) {
165 code[pc] = (Byte)(op+1); 166 code[pc] = (Byte)(op-1);
166 code[pc+1] = (Byte)(arg>>8); 167 code[pc+1] = (Byte)(arg>>8);
167 code[pc+2] = (Byte)(arg&0xFF); 168 code[pc+2] = (Byte)(arg&0xFF);
168 return 3; /* code size (opcode + 1 word) */ 169 return 3; /* code size (opcode + 1 word) */
@@ -429,6 +430,15 @@ static void code_args (LexState *ls, int nparams, int dots) {
429} 430}
430 431
431 432
433static void unloaddot (LexState *ls, vardesc *v) {
434 /* dotted variables <a.x> must be stored like regular indexed vars <a["x"]> */
435 if (v->k == VDOT) {
436 code_constant(ls, v->info);
437 v->k = VINDEXED;
438 }
439}
440
441
432static void lua_pushvar (LexState *ls, vardesc *var) { 442static void lua_pushvar (LexState *ls, vardesc *var) {
433 switch (var->k) { 443 switch (var->k) {
434 case VLOCAL: 444 case VLOCAL:
@@ -452,16 +462,16 @@ static void lua_pushvar (LexState *ls, vardesc *var) {
452} 462}
453 463
454 464
455static void storevar (LexState *ls, vardesc *var) { 465static void genstorevar (LexState *ls, vardesc *var, OpCode *codes) {
456 switch (var->k) { 466 switch (var->k) {
457 case VLOCAL: 467 case VLOCAL:
458 code_oparg(ls, SETLOCAL, var->info, -1); 468 code_oparg(ls, codes[0], var->info, -1);
459 break; 469 break;
460 case VGLOBAL: 470 case VGLOBAL:
461 code_oparg(ls, SETGLOBAL, var->info, -1); 471 code_oparg(ls, codes[1], var->info, -1);
462 break; 472 break;
463 case VINDEXED: 473 case VINDEXED:
464 code_opcode(ls, SETTABLE0, -3); 474 code_opcode(ls, codes[2], -3);
465 break; 475 break;
466 default: 476 default:
467 LUA_INTERNALERROR("invalid var kind to store"); 477 LUA_INTERNALERROR("invalid var kind to store");
@@ -469,6 +479,12 @@ static void storevar (LexState *ls, vardesc *var) {
469} 479}
470 480
471 481
482static void storevar (LexState *ls, vardesc *var) {
483 static OpCode codes[] = {SETLOCAL, SETGLOBAL, SETTABLE0};
484 genstorevar(ls, var, codes);
485}
486
487
472static int fix_jump (LexState *ls, int pc, OpCode op, int n) { 488static int fix_jump (LexState *ls, int pc, OpCode op, int n) {
473 /* jump is relative to position following jump instruction */ 489 /* jump is relative to position following jump instruction */
474 return fix_opcode(ls, pc, op, n-(pc+JMPSIZE)); 490 return fix_opcode(ls, pc, op, n-(pc+JMPSIZE));
@@ -932,6 +948,21 @@ static void exp0 (LexState *ls, vardesc *v) {
932} 948}
933 949
934 950
951static void Gexp (LexState *ls, vardesc *v) {
952 /* Gexp -> exp0 | var '=' exp1 */
953 static OpCode codes[] = {SETLOCALDUP, SETGLOBALDUP, SETTABLEDUP};
954 exp0(ls, v);
955 if (ls->token == '=' && v->k != VEXP) { /* assignment expression? */
956 next(ls); /* skip '=' */
957 unloaddot(ls, v);
958 exp1(ls);
959 genstorevar(ls, v, codes);
960 deltastack(ls, 1); /* DUP operations push an extra value */
961 v->k = VEXP; v->info = 0;
962 }
963}
964
965
935static void push (LexState *ls, stack_op *s, int op) { 966static void push (LexState *ls, stack_op *s, int op) {
936 if (s->top == MAXOPS) 967 if (s->top == MAXOPS)
937 luaX_error(ls, "expression too complex"); 968 luaX_error(ls, "expression too complex");
@@ -993,9 +1024,9 @@ static void simpleexp (LexState *ls, vardesc *v, stack_op *s) {
993 ifpart(ls, 1, ls->linenumber); 1024 ifpart(ls, 1, ls->linenumber);
994 break; 1025 break;
995 1026
996 case '(': /* simpleexp -> '(' exp0 ')' */ 1027 case '(': /* simpleexp -> '(' Gexp ')' */
997 next(ls); 1028 next(ls);
998 exp0(ls, v); 1029 Gexp(ls, v);
999 check(ls, ')'); 1030 check(ls, ')');
1000 return; 1031 return;
1001 1032
@@ -1206,13 +1237,10 @@ static void decinit (LexState *ls, listdesc *d) {
1206 } 1237 }
1207} 1238}
1208 1239
1240
1209static int assignment (LexState *ls, vardesc *v, int nvars) { 1241static int assignment (LexState *ls, vardesc *v, int nvars) {
1210 int left = 0; 1242 int left = 0;
1211 /* dotted variables <a.x> must be stored like regular indexed vars <a["x"]> */ 1243 unloaddot(ls, v);
1212 if (v->k == VDOT) {
1213 code_constant(ls, v->info);
1214 v->k = VINDEXED;
1215 }
1216 if (ls->token == ',') { /* assignment -> ',' NAME assignment */ 1244 if (ls->token == ',') { /* assignment -> ',' NAME assignment */
1217 vardesc nv; 1245 vardesc nv;
1218 next(ls); 1246 next(ls);