diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1999-02-02 17:41:17 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1999-02-02 17:41:17 -0200 |
commit | 27407fc1f5fc4e0d97dadeda5939efa62fe7e380 (patch) | |
tree | a47a3f41547509627999963896b5ce3c8a335bf7 /lparser.c | |
parent | 1a17da2ff9dce06a0405f549522a4e08026c3124 (diff) | |
download | lua-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.c | 54 |
1 files changed, 41 insertions, 13 deletions
@@ -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); | |||
114 | static void constructor (LexState *ls); | 114 | static void constructor (LexState *ls); |
115 | static void decinit (LexState *ls, listdesc *d); | 115 | static void decinit (LexState *ls, listdesc *d); |
116 | static void exp0 (LexState *ls, vardesc *v); | 116 | static void exp0 (LexState *ls, vardesc *v); |
117 | static void Gexp (LexState *ls, vardesc *v); | ||
117 | static void exp1 (LexState *ls); | 118 | static void exp1 (LexState *ls); |
118 | static void exp2 (LexState *ls, vardesc *v); | 119 | static void exp2 (LexState *ls, vardesc *v); |
119 | static void explist (LexState *ls, listdesc *e); | 120 | 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) { | |||
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 | ||
433 | static 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 | |||
432 | static void lua_pushvar (LexState *ls, vardesc *var) { | 442 | static 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 | ||
455 | static void storevar (LexState *ls, vardesc *var) { | 465 | static 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 | ||
482 | static void storevar (LexState *ls, vardesc *var) { | ||
483 | static OpCode codes[] = {SETLOCAL, SETGLOBAL, SETTABLE0}; | ||
484 | genstorevar(ls, var, codes); | ||
485 | } | ||
486 | |||
487 | |||
472 | static int fix_jump (LexState *ls, int pc, OpCode op, int n) { | 488 | static 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 | ||
951 | static 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 | |||
935 | static void push (LexState *ls, stack_op *s, int op) { | 966 | static 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 | |||
1209 | static int assignment (LexState *ls, vardesc *v, int nvars) { | 1241 | static 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); |