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...)
Diffstat (limited to '')
| -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. |
