diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1999-03-10 11:09:45 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1999-03-10 11:09:45 -0300 |
commit | 26794616374fee54532d0030ae006abb77dfb7ba (patch) | |
tree | ebc4595695eb616e66b4f63779404e8ea6644b48 | |
parent | 0870a2d1d8a1434eecae1923886ba219c4e699c7 (diff) | |
download | lua-26794616374fee54532d0030ae006abb77dfb7ba.tar.gz lua-26794616374fee54532d0030ae006abb77dfb7ba.tar.bz2 lua-26794616374fee54532d0030ae006abb77dfb7ba.zip |
no more assignment expressions (they don't fit in Lua...)
-rw-r--r-- | lopcodes.h | 8 | ||||
-rw-r--r-- | lparser.c | 51 | ||||
-rw-r--r-- | lvm.c | 32 | ||||
-rw-r--r-- | manual.tex | 12 |
4 files changed, 20 insertions, 83 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lopcodes.h,v 1.30 1999/03/04 21:15:50 roberto Exp roberto $ | 2 | ** $Id: lopcodes.h,v 1.31 1999/03/05 21:16:07 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 | */ |
@@ -26,7 +26,6 @@ TAILCALL,/* b c v_c...v_1 f (return) f(v1,...,v_c) */ | |||
26 | 26 | ||
27 | PUSHNIL,/* b - nil_0...nil_b */ | 27 | PUSHNIL,/* b - nil_0...nil_b */ |
28 | POP,/* b a_b...a_1 - */ | 28 | POP,/* b a_b...a_1 - */ |
29 | POPDUP,/* b v a_b...a_1 v */ | ||
30 | 29 | ||
31 | PUSHNUMBERW,/* w - (float)w */ | 30 | PUSHNUMBERW,/* w - (float)w */ |
32 | PUSHNUMBER,/* b - (float)b */ | 31 | PUSHNUMBER,/* b - (float)b */ |
@@ -56,18 +55,13 @@ CREATEARRAYW,/* w - newarray(size = w) */ | |||
56 | CREATEARRAY,/* b - newarray(size = b) */ | 55 | CREATEARRAY,/* b - newarray(size = b) */ |
57 | 56 | ||
58 | SETLOCAL,/* b x - LOC[b]=x */ | 57 | SETLOCAL,/* b x - LOC[b]=x */ |
59 | SETLOCALDUP,/* b x x LOC[b]=x */ | ||
60 | 58 | ||
61 | SETGLOBALW,/* w x - VAR[CNST[w]]=x */ | 59 | SETGLOBALW,/* w x - VAR[CNST[w]]=x */ |
62 | SETGLOBAL,/* b x - VAR[CNST[b]]=x */ | 60 | SETGLOBAL,/* b x - VAR[CNST[b]]=x */ |
63 | SETGLOBALDUPW,/*w x x VAR[CNST[w]]=x */ | ||
64 | SETGLOBALDUP,/* b x x VAR[CNST[b]]=x */ | ||
65 | 61 | ||
66 | SETTABLEPOP,/* - v i t - t[i]=v */ | 62 | SETTABLEPOP,/* - v i t - t[i]=v */ |
67 | SETTABLEPOPDUP,/* - v i t v t[i]=v */ | ||
68 | 63 | ||
69 | SETTABLE,/* b v a_b...a_1 i t a_b...a_1 i t t[i]=v */ | 64 | SETTABLE,/* b v a_b...a_1 i t a_b...a_1 i t t[i]=v */ |
70 | SETTABLEDUP,/* b v a_b...a_1 i t v a_b...a_1 i t t[i]=v */ | ||
71 | 65 | ||
72 | SETLISTW,/* w c v_c...v_1 t t t[i+w*FPF]=v_i */ | 66 | SETLISTW,/* w c v_c...v_1 t t t[i+w*FPF]=v_i */ |
73 | SETLIST,/* b c v_c...v_1 t t t[i+b*FPF]=v_i */ | 67 | SETLIST,/* b c v_c...v_1 t t t[i+b*FPF]=v_i */ |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lparser.c,v 1.26 1999/03/04 21:17:26 roberto Exp roberto $ | 2 | ** $Id: lparser.c,v 1.27 1999/03/05 21:16:07 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 | */ |
@@ -99,7 +99,7 @@ typedef struct FuncState { | |||
99 | /* | 99 | /* |
100 | ** prototypes for non-terminal functions | 100 | ** prototypes for non-terminal functions |
101 | */ | 101 | */ |
102 | static int assignment (LexState *ls, vardesc *v, int nvars, OpCode *codes); | 102 | static int assignment (LexState *ls, vardesc *v, int nvars); |
103 | static int cond (LexState *ls); | 103 | static int cond (LexState *ls); |
104 | static int funcname (LexState *ls, vardesc *v); | 104 | static int funcname (LexState *ls, vardesc *v); |
105 | static int funcparams (LexState *ls, int slf); | 105 | static int funcparams (LexState *ls, int slf); |
@@ -114,7 +114,6 @@ 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); | ||
118 | static void exp1 (LexState *ls); | 117 | static void exp1 (LexState *ls); |
119 | static void exp2 (LexState *ls, vardesc *v); | 118 | static void exp2 (LexState *ls, vardesc *v); |
120 | static void explist (LexState *ls, listdesc *e); | 119 | static void explist (LexState *ls, listdesc *e); |
@@ -467,22 +466,16 @@ static void lua_pushvar (LexState *ls, vardesc *var) { | |||
467 | } | 466 | } |
468 | 467 | ||
469 | 468 | ||
470 | /* to be used by "storevar" and assignment */ | 469 | static void storevar (LexState *ls, vardesc *var) { |
471 | static OpCode set_pop[] = {SETLOCAL, SETGLOBAL, SETTABLEPOP, SETTABLE}; | ||
472 | static OpCode set_dup[] = {SETLOCALDUP, SETGLOBALDUP, SETTABLEPOPDUP, | ||
473 | SETTABLEDUP}; | ||
474 | |||
475 | |||
476 | static void storevar (LexState *ls, vardesc *var, OpCode *codes) { | ||
477 | switch (var->k) { | 470 | switch (var->k) { |
478 | case VLOCAL: | 471 | case VLOCAL: |
479 | code_oparg(ls, codes[0], var->info, -1); | 472 | code_oparg(ls, SETLOCAL, var->info, -1); |
480 | break; | 473 | break; |
481 | case VGLOBAL: | 474 | case VGLOBAL: |
482 | code_oparg(ls, codes[1], var->info, -1); | 475 | code_oparg(ls, SETGLOBAL, var->info, -1); |
483 | break; | 476 | break; |
484 | case VINDEXED: | 477 | case VINDEXED: |
485 | code_opcode(ls, codes[2], -3); | 478 | code_opcode(ls, SETTABLEPOP, -3); |
486 | break; | 479 | break; |
487 | default: | 480 | default: |
488 | LUA_INTERNALERROR("invalid var kind to store"); | 481 | LUA_INTERNALERROR("invalid var kind to store"); |
@@ -739,7 +732,7 @@ static int stat (LexState *ls) { | |||
739 | next(ls); | 732 | next(ls); |
740 | needself = funcname(ls, &v); | 733 | needself = funcname(ls, &v); |
741 | body(ls, needself, line); | 734 | body(ls, needself, line); |
742 | storevar(ls, &v, set_pop); | 735 | storevar(ls, &v); |
743 | return 1; | 736 | return 1; |
744 | } | 737 | } |
745 | 738 | ||
@@ -765,7 +758,7 @@ static int stat (LexState *ls) { | |||
765 | close_exp(ls, v.info, 0); | 758 | close_exp(ls, v.info, 0); |
766 | } | 759 | } |
767 | else { /* stat -> ['%'] NAME assignment */ | 760 | else { /* stat -> ['%'] NAME assignment */ |
768 | int left = assignment(ls, &v, 1, set_pop); | 761 | int left = assignment(ls, &v, 1); |
769 | adjuststack(ls, left); /* remove eventual 'garbage' left on stack */ | 762 | adjuststack(ls, left); /* remove eventual 'garbage' left on stack */ |
770 | } | 763 | } |
771 | return 1; | 764 | return 1; |
@@ -948,19 +941,6 @@ static void exp0 (LexState *ls, vardesc *v) { | |||
948 | } | 941 | } |
949 | 942 | ||
950 | 943 | ||
951 | static void Gexp (LexState *ls, vardesc *v) { | ||
952 | /* Gexp -> exp0 | assignment */ | ||
953 | exp0(ls, v); | ||
954 | if (v->k != VEXP && (ls->token == '=' || ls->token == ',')) { | ||
955 | int left = assignment(ls, v, 1, set_dup); | ||
956 | deltastack(ls, 1); /* DUP operations push an extra value */ | ||
957 | if (left > 0) | ||
958 | code_oparg(ls, POPDUP, left, -left); | ||
959 | v->k = VEXP; v->info = 0; /* this expression is closed now */ | ||
960 | } | ||
961 | } | ||
962 | |||
963 | |||
964 | static void push (LexState *ls, stack_op *s, int op) { | 944 | static void push (LexState *ls, stack_op *s, int op) { |
965 | if (s->top >= MAXOPS) | 945 | if (s->top >= MAXOPS) |
966 | luaX_error(ls, "expression too complex"); | 946 | luaX_error(ls, "expression too complex"); |
@@ -1015,9 +995,9 @@ static void simpleexp (LexState *ls, vardesc *v, stack_op *s) { | |||
1015 | ifpart(ls, 1, ls->linenumber); | 995 | ifpart(ls, 1, ls->linenumber); |
1016 | break; | 996 | break; |
1017 | 997 | ||
1018 | case '(': /* simpleexp -> '(' Gexp ')' */ | 998 | case '(': /* simpleexp -> '(' exp0 ')' */ |
1019 | next(ls); | 999 | next(ls); |
1020 | Gexp(ls, v); | 1000 | exp0(ls, v); |
1021 | check(ls, ')'); | 1001 | check(ls, ')'); |
1022 | return; | 1002 | return; |
1023 | 1003 | ||
@@ -1239,7 +1219,7 @@ static void decinit (LexState *ls, listdesc *d) { | |||
1239 | } | 1219 | } |
1240 | 1220 | ||
1241 | 1221 | ||
1242 | static int assignment (LexState *ls, vardesc *v, int nvars, OpCode *codes) { | 1222 | static int assignment (LexState *ls, vardesc *v, int nvars) { |
1243 | int left = 0; | 1223 | int left = 0; |
1244 | unloaddot(ls, v); | 1224 | unloaddot(ls, v); |
1245 | if (ls->token == ',') { /* assignment -> ',' NAME assignment */ | 1225 | if (ls->token == ',') { /* assignment -> ',' NAME assignment */ |
@@ -1248,7 +1228,7 @@ static int assignment (LexState *ls, vardesc *v, int nvars, OpCode *codes) { | |||
1248 | var_or_func(ls, &nv); | 1228 | var_or_func(ls, &nv); |
1249 | if (nv.k == VEXP) | 1229 | if (nv.k == VEXP) |
1250 | luaX_error(ls, "syntax error"); | 1230 | luaX_error(ls, "syntax error"); |
1251 | left = assignment(ls, &nv, nvars+1, set_pop); | 1231 | left = assignment(ls, &nv, nvars+1); |
1252 | } | 1232 | } |
1253 | else { /* assignment -> '=' explist1 */ | 1233 | else { /* assignment -> '=' explist1 */ |
1254 | listdesc d; | 1234 | listdesc d; |
@@ -1258,15 +1238,16 @@ static int assignment (LexState *ls, vardesc *v, int nvars, OpCode *codes) { | |||
1258 | } | 1238 | } |
1259 | if (v->k != VINDEXED || left+(nvars-1) == 0) { | 1239 | if (v->k != VINDEXED || left+(nvars-1) == 0) { |
1260 | /* global/local var or indexed var without values in between */ | 1240 | /* global/local var or indexed var without values in between */ |
1261 | storevar(ls, v, codes); | 1241 | storevar(ls, v); |
1262 | } | 1242 | } |
1263 | else { /* indexed var with values in between*/ | 1243 | else { /* indexed var with values in between*/ |
1264 | code_oparg(ls, codes[3], left+(nvars-1), -1); | 1244 | code_oparg(ls, SETTABLE, left+(nvars-1), -1); |
1265 | left += 2; /* table/index are not popped, because they aren't on top */ | 1245 | left += 2; /* table&index are not popped, because they aren't on top */ |
1266 | } | 1246 | } |
1267 | return left; | 1247 | return left; |
1268 | } | 1248 | } |
1269 | 1249 | ||
1250 | |||
1270 | static void constructor (LexState *ls) { | 1251 | static void constructor (LexState *ls) { |
1271 | /* constructor -> '{' part [';' part] '}' */ | 1252 | /* constructor -> '{' part [';' part] '}' */ |
1272 | int line = ls->linenumber; | 1253 | int line = ls->linenumber; |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lvm.c,v 1.52 1999/03/04 21:15:50 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 1.53 1999/03/05 21:16:07 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 | */ |
@@ -356,11 +356,6 @@ StkId luaV_execute (Closure *cl, TProtoFunc *tf, StkId base) { | |||
356 | S->top -= aux; | 356 | S->top -= aux; |
357 | break; | 357 | break; |
358 | 358 | ||
359 | case POPDUP: aux = *pc++; | ||
360 | *(S->top-aux-1) = *(S->top-1); | ||
361 | S->top -= aux; | ||
362 | break; | ||
363 | |||
364 | case PUSHNUMBERW: aux += highbyte(*pc++); | 359 | case PUSHNUMBERW: aux += highbyte(*pc++); |
365 | case PUSHNUMBER: aux += *pc++; | 360 | case PUSHNUMBER: aux += *pc++; |
366 | ttype(S->top) = LUA_T_NUMBER; | 361 | ttype(S->top) = LUA_T_NUMBER; |
@@ -424,45 +419,20 @@ StkId luaV_execute (Closure *cl, TProtoFunc *tf, StkId base) { | |||
424 | *((S->stack+base) + aux) = *(--S->top); | 419 | *((S->stack+base) + aux) = *(--S->top); |
425 | break; | 420 | break; |
426 | 421 | ||
427 | case SETLOCALDUP: aux = *pc++; | ||
428 | *((S->stack+base) + aux) = *(S->top-1); | ||
429 | break; | ||
430 | |||
431 | case SETGLOBALW: aux += highbyte(*pc++); | 422 | case SETGLOBALW: aux += highbyte(*pc++); |
432 | case SETGLOBAL: aux += *pc++; | 423 | case SETGLOBAL: aux += *pc++; |
433 | luaV_setglobal(tsvalue(&consts[aux])); | 424 | luaV_setglobal(tsvalue(&consts[aux])); |
434 | break; | 425 | break; |
435 | 426 | ||
436 | case SETGLOBALDUPW: aux += highbyte(*pc++); | ||
437 | case SETGLOBALDUP: aux += *pc++; | ||
438 | *S->top = *(S->top-1); | ||
439 | S->top++; | ||
440 | luaV_setglobal(tsvalue(&consts[aux])); | ||
441 | break; | ||
442 | |||
443 | case SETTABLEPOP: | 427 | case SETTABLEPOP: |
444 | luaV_settable(S->top-3); | 428 | luaV_settable(S->top-3); |
445 | S->top -= 2; /* pop table and index */ | 429 | S->top -= 2; /* pop table and index */ |
446 | break; | 430 | break; |
447 | 431 | ||
448 | case SETTABLEPOPDUP: { | ||
449 | TObject temp = *(S->top-1); | ||
450 | luaV_settable(S->top-3); | ||
451 | S->top--; /* pop index (temp goes into "table" position) */ | ||
452 | *(S->top-1) = temp; | ||
453 | break; | ||
454 | } | ||
455 | |||
456 | case SETTABLE: | 432 | case SETTABLE: |
457 | luaV_settable(S->top-3-(*pc++)); | 433 | luaV_settable(S->top-3-(*pc++)); |
458 | break; | 434 | break; |
459 | 435 | ||
460 | case SETTABLEDUP: | ||
461 | *S->top = *(S->top-1); | ||
462 | S->top++; | ||
463 | luaV_settable(S->top-(3+1)-(*pc++)); | ||
464 | break; | ||
465 | |||
466 | case SETLISTW: aux += highbyte(*pc++); | 436 | case SETLISTW: aux += highbyte(*pc++); |
467 | case SETLIST: aux += *pc++; { | 437 | case SETLIST: aux += *pc++; { |
468 | int n = *(pc++); | 438 | int n = *(pc++); |
@@ -1,4 +1,4 @@ | |||
1 | % $Id: manual.tex,v 1.24 1999/02/25 19:13:56 roberto Exp roberto $ | 1 | % $Id: manual.tex,v 1.25 1999/03/04 21:23:39 roberto Exp roberto $ |
2 | 2 | ||
3 | \documentclass[11pt]{article} | 3 | \documentclass[11pt]{article} |
4 | \usepackage{fullpage,bnf} | 4 | \usepackage{fullpage,bnf} |
@@ -41,7 +41,7 @@ Waldemar Celes | |||
41 | \tecgraf\ --- Computer Science Department --- PUC-Rio | 41 | \tecgraf\ --- Computer Science Department --- PUC-Rio |
42 | } | 42 | } |
43 | 43 | ||
44 | %\date{\small \verb$Date: 1999/02/25 19:13:56 $} | 44 | %\date{\small \verb$Date: 1999/03/04 21:23:39 $} |
45 | 45 | ||
46 | \maketitle | 46 | \maketitle |
47 | 47 | ||
@@ -697,14 +697,6 @@ according to its condition. | |||
697 | Its final value is the value of the chosen expression. | 697 | Its final value is the value of the chosen expression. |
698 | An absent else-part is equivalent to \verb|else nil|. | 698 | An absent else-part is equivalent to \verb|else nil|. |
699 | 699 | ||
700 | \subsubsection{Assignment Expressions} | ||
701 | \begin{Produc} | ||
702 | \produc{exp}{\ter{(} varlist1 \ter{=} explist1 \ter{)}} | ||
703 | \end{Produc}% | ||
704 | An \Index{assignment expression} executes a multiple assignment, | ||
705 | and results in the final value of its first right hand expression | ||
706 | (that is, the value assigned to the first variable in the variable list). | ||
707 | |||
708 | \subsubsection{Table Constructors} \label{tableconstructor} | 700 | \subsubsection{Table Constructors} \label{tableconstructor} |
709 | Table \Index{constructors} are expressions that create tables; | 701 | Table \Index{constructors} are expressions that create tables; |
710 | every time a constructor is evaluated, a new table is created. | 702 | every time a constructor is evaluated, a new table is created. |