aboutsummaryrefslogtreecommitdiff
path: root/lparser.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2000-02-22 11:31:43 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2000-02-22 11:31:43 -0200
commit3bc925138ebcb534f863b3fb32b21eb8d52aa915 (patch)
tree6fcbc3bf92357a5e2e1651bc38c79b9bbea42a51 /lparser.c
parent39e1f079bdf045d64ad6f1b5da1eb48cc79c6c38 (diff)
downloadlua-3bc925138ebcb534f863b3fb32b21eb8d52aa915.tar.gz
lua-3bc925138ebcb534f863b3fb32b21eb8d52aa915.tar.bz2
lua-3bc925138ebcb534f863b3fb32b21eb8d52aa915.zip
first version of code optimizer
Diffstat (limited to 'lparser.c')
-rw-r--r--lparser.c395
1 files changed, 166 insertions, 229 deletions
diff --git a/lparser.c b/lparser.c
index c185b506..4a270267 100644
--- a/lparser.c
+++ b/lparser.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lparser.c,v 1.58 2000/02/11 16:52:54 roberto Exp roberto $ 2** $Id: lparser.c,v 1.59 2000/02/14 16:51:08 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*/
@@ -8,6 +8,9 @@
8#include <stdio.h> 8#include <stdio.h>
9#include <string.h> 9#include <string.h>
10 10
11#define LUA_REENTRANT
12
13#include "lcode.h"
11#include "ldo.h" 14#include "ldo.h"
12#include "lfunc.h" 15#include "lfunc.h"
13#include "llex.h" 16#include "llex.h"
@@ -19,50 +22,6 @@
19#include "lstring.h" 22#include "lstring.h"
20 23
21 24
22
23/* maximum number of local variables */
24#ifndef MAXLOCALS
25#define MAXLOCALS 200 /* arbitrary limit (<MAXARG_B) */
26#endif
27
28
29/* maximum number of upvalues */
30#ifndef MAXUPVALUES
31#define MAXUPVALUES 32 /* arbitrary limit (<MAXARG_B) */
32#endif
33
34
35/* maximum number of variables in the left side of an assignment */
36#ifndef MAXVARSLH
37#define MAXVARSLH 100 /* arbitrary limit (<MAXARG_B) */
38#endif
39
40
41/* maximum number of parameters in a function */
42#ifndef MAXPARAMS
43#define MAXPARAMS 100 /* arbitrary limit (<MAXLOCALS) */
44#endif
45
46
47/*
48** Variable descriptor:
49** must include an `exp' option because LL(1) cannot distinguish
50** between variables, upvalues and function calls on first sight.
51*/
52typedef enum {
53 VGLOBAL, /* info is constant index of global name */
54 VLOCAL, /* info is stack index */
55 VDOT, /* info is constant index of index name */
56 VINDEXED, /* no info (table and index are on the stack) */
57 VEXP /* info is pc index of a call (or 0 if exp is closed) */
58} varkind;
59
60typedef struct vardesc {
61 varkind k;
62 int info;
63} vardesc;
64
65
66/* 25/*
67** Expression List descriptor: 26** Expression List descriptor:
68** tells number of expressions in the list, 27** tells number of expressions in the list,
@@ -87,19 +46,6 @@ typedef struct constdesc {
87} constdesc; 46} constdesc;
88 47
89 48
90/* state needed to generate code for a given function */
91typedef struct FuncState {
92 TProtoFunc *f; /* current function header */
93 struct FuncState *prev; /* enclosing function */
94 int pc; /* next position to code */
95 int stacksize; /* number of values on activation register */
96 int nlocalvar; /* number of active local variables */
97 int nupvalues; /* number of upvalues */
98 int nvars; /* number of entries in f->locvars (-1 if no debug information) */
99 int lastsetline; /* line where last SETLINE was issued */
100 vardesc upvalues[MAXUPVALUES]; /* upvalues */
101 TaggedString *localvar[MAXLOCALS]; /* store local variable names */
102} FuncState;
103 49
104 50
105/* 51/*
@@ -112,40 +58,74 @@ static void expr (LexState *ls, vardesc *v);
112static void exp1 (LexState *ls); 58static void exp1 (LexState *ls);
113 59
114 60
61static void next (LexState *ls) {
62 ls->token = luaX_lex(ls);
63}
64
115 65
116static void luaY_error (LexState *ls, const char *msg) { 66static void luaY_error (LexState *ls, const char *msg) {
117 luaX_error(ls, msg, ls->token); 67 luaX_error(ls, msg, ls->token);
118} 68}
119 69
120 70
121static void checklimit (LexState *ls, int val, int limit, const char *msg) { 71static void error_expected (LexState *ls, int token) {
122 if (val > limit) { 72 char buff[100], t[TOKEN_LEN];
73 luaX_token2str(token, t);
74 sprintf(buff, "`%.20s' expected", t);
75 luaY_error(ls, buff);
76}
77
78
79static void error_unexpected (LexState *ls) {
80 luaY_error(ls, "unexpected token");
81}
82
83
84static void error_unmatched (LexState *ls, int what, int who, int where) {
85 if (where == ls->linenumber)
86 error_expected(ls, what);
87 else {
123 char buff[100]; 88 char buff[100];
124 sprintf(buff, "too many %.50s (limit=%d)", msg, limit); 89 char t_what[TOKEN_LEN], t_who[TOKEN_LEN];
90 luaX_token2str(what, t_what);
91 luaX_token2str(who, t_who);
92 sprintf(buff, "`%.20s' expected (to close `%.20s' at line %d)",
93 t_what, t_who, where);
125 luaY_error(ls, buff); 94 luaY_error(ls, buff);
126 } 95 }
127} 96}
128 97
98static void check (LexState *ls, int c) {
99 if (ls->token != c)
100 error_expected(ls, c);
101 next(ls);
102}
103
129 104
130static int code_instruction (LexState *ls, Instruction i) { 105static int optional (LexState *ls, int c) {
131 FuncState *fs = ls->fs; 106 if (ls->token == c) {
132 luaM_growvector(ls->L, fs->f->code, fs->pc, 1, Instruction, codeEM, MAXARG_S); 107 next(ls);
133 fs->f->code[fs->pc] = i; 108 return 1;
134 return fs->pc++; 109 }
110 else return 0;
135} 111}
136 112
137 113
138static void fix_jump (LexState *ls, int pc, int dest) { 114static void checklimit (LexState *ls, int val, int limit, const char *msg) {
139 Instruction *jmp = &ls->fs->f->code[pc]; 115 if (val > limit) {
140 /* jump is relative to position following jump instruction */ 116 char buff[100];
141 *jmp = SETARG_S(*jmp, dest-(pc+1)); 117 sprintf(buff, "too many %.50s (limit=%d)", msg, limit);
118 luaY_error(ls, buff);
119 }
142} 120}
143 121
144 122
123
145static void deltastack (LexState *ls, int delta) { 124static void deltastack (LexState *ls, int delta) {
146 FuncState *fs = ls->fs; 125 FuncState *fs = ls->fs;
147 fs->stacksize += delta; 126 fs->stacksize += delta;
148 if (delta > 0 && fs->stacksize > fs->f->maxstacksize) { 127 if (delta > 0 && fs->stacksize > fs->f->maxstacksize) {
128 checklimit(ls, fs->stacksize, MAXSTACK, "temporaries or local variables");
149 fs->f->maxstacksize = fs->stacksize; 129 fs->f->maxstacksize = fs->stacksize;
150 } 130 }
151} 131}
@@ -153,7 +133,7 @@ static void deltastack (LexState *ls, int delta) {
153 133
154static int aux_code (LexState *ls, OpCode op, Instruction i, int delta) { 134static int aux_code (LexState *ls, OpCode op, Instruction i, int delta) {
155 deltastack(ls, delta); 135 deltastack(ls, delta);
156 return code_instruction(ls, SET_OPCODE(i, op)); 136 return luaK_code(ls, SET_OPCODE(i, op));
157} 137}
158 138
159 139
@@ -182,6 +162,22 @@ static int code_AB (LexState *ls, OpCode op, int a, int b, int delta) {
182} 162}
183 163
184 164
165static void check_debugline (LexState *ls) {
166 if (ls->L->debug && ls->linenumber != ls->fs->lastsetline) {
167 code_U(ls, SETLINE, ls->linenumber, 0);
168 ls->fs->lastsetline = ls->linenumber;
169 }
170}
171
172
173static void check_match (LexState *ls, int what, int who, int where) {
174 if (ls->token != what)
175 error_unmatched(ls, what, who, where);
176 check_debugline(ls); /* to `mark' the `what' */
177 next(ls);
178}
179
180
185static void code_kstr (LexState *ls, int c) { 181static void code_kstr (LexState *ls, int c) {
186 code_U(ls, PUSHSTRING, c, 1); 182 code_U(ls, PUSHSTRING, c, 1);
187} 183}
@@ -228,10 +224,26 @@ static int real_constant (LexState *ls, real r) {
228 224
229 225
230static void code_number (LexState *ls, real f) { 226static void code_number (LexState *ls, real f) {
231 if ((real)(-MAXARG_S) <= f && f <= (real)MAXARG_S && (int)f == f) 227 if (f <= (real)MAXARG_S && (int)f == f)
232 code_S(ls, PUSHINT, (int)f, 1); /* f has a short integer value */ 228 code_S(ls, PUSHINT, (int)f, 1); /* f has a short integer value */
233 else 229 else
234 code_U(ls, PUSHNUMBER, real_constant(ls, f), 1); 230 code_U(ls, PUSHNUM, real_constant(ls, f), 1);
231}
232
233
234static int checkname (LexState *ls) {
235 int sc;
236 if (ls->token != NAME)
237 luaY_error(ls, "<name> expected");
238 sc = string_constant(ls, ls->fs, ls->seminfo.ts);
239 next(ls);
240 return sc;
241}
242
243
244static TaggedString *str_checkname (LexState *ls) {
245 int i = checkname(ls); /* this call may realloc `f->consts' */
246 return ls->fs->f->kstr[i];
235} 247}
236 248
237 249
@@ -327,15 +339,6 @@ static void pushupvalue (LexState *ls, TaggedString *n) {
327} 339}
328 340
329 341
330
331static void check_debugline (LexState *ls) {
332 if (ls->L->debug && ls->linenumber != ls->fs->lastsetline) {
333 code_U(ls, SETLINE, ls->linenumber, 0);
334 ls->fs->lastsetline = ls->linenumber;
335 }
336}
337
338
339static void adjuststack (LexState *ls, int n) { 342static void adjuststack (LexState *ls, int n) {
340 if (n > 0) 343 if (n > 0)
341 code_U(ls, POP, n, -n); 344 code_U(ls, POP, n, -n);
@@ -344,7 +347,7 @@ static void adjuststack (LexState *ls, int n) {
344} 347}
345 348
346 349
347static void close_exp (LexState *ls, int pc, int nresults) { 350static void close_call (LexState *ls, int pc, int nresults) {
348 if (pc > 0) { /* expression is an open function call? */ 351 if (pc > 0) { /* expression is an open function call? */
349 Instruction *i = &ls->fs->f->code[pc]; 352 Instruction *i = &ls->fs->f->code[pc];
350 *i = SETARG_B(*i, nresults); /* set nresults */ 353 *i = SETARG_B(*i, nresults); /* set nresults */
@@ -364,10 +367,10 @@ static void adjust_mult_assign (LexState *ls, int nvars, listdesc *d) {
364 diff--; /* do not count function call itself */ 367 diff--; /* do not count function call itself */
365 if (diff <= 0) { /* more variables than values? */ 368 if (diff <= 0) { /* more variables than values? */
366 /* function call must provide extra values */ 369 /* function call must provide extra values */
367 close_exp(ls, d->pc, -diff); 370 close_call(ls, d->pc, -diff);
368 } 371 }
369 else { /* more values than variables */ 372 else { /* more values than variables */
370 close_exp(ls, d->pc, 0); /* call should provide no value */ 373 close_call(ls, d->pc, 0); /* call should provide no value */
371 adjuststack(ls, diff); /* pop eventual extra values */ 374 adjuststack(ls, diff); /* pop eventual extra values */
372 } 375 }
373 } 376 }
@@ -390,16 +393,21 @@ static void code_args (LexState *ls, int nparams, int dots) {
390} 393}
391 394
392 395
393static void unloaddot (LexState *ls, vardesc *v) { 396static int getvarname (LexState *ls, vardesc *var) {
394 /* dotted variables <a.x> must be stored as regular indexed vars <a["x"]> */ 397 switch (var->k) {
395 if (v->k == VDOT) { 398 case VGLOBAL:
396 code_kstr(ls, v->info); 399 return var->info;
397 v->k = VINDEXED; 400 case VLOCAL:
401 return string_constant(ls, ls->fs, ls->fs->localvar[var->info]);
402 break;
403 default:
404 error_unexpected(ls); /* there is no `var name' */
405 return 0; /* to avoid warnings */
398 } 406 }
399} 407}
400 408
401 409
402static void lua_pushvar (LexState *ls, vardesc *var) { 410static void close_exp (LexState *ls, vardesc *var) {
403 switch (var->k) { 411 switch (var->k) {
404 case VLOCAL: 412 case VLOCAL:
405 code_U(ls, PUSHLOCAL, var->info, 1); 413 code_U(ls, PUSHLOCAL, var->info, 1);
@@ -408,14 +416,11 @@ static void lua_pushvar (LexState *ls, vardesc *var) {
408 code_U(ls, GETGLOBAL, var->info, 1); 416 code_U(ls, GETGLOBAL, var->info, 1);
409 assertglobal(ls, var->info); /* make sure that there is a global */ 417 assertglobal(ls, var->info); /* make sure that there is a global */
410 break; 418 break;
411 case VDOT:
412 code_U(ls, GETDOTTED, var->info, 0);
413 break;
414 case VINDEXED: 419 case VINDEXED:
415 code_0(ls, GETTABLE, -1); 420 code_0(ls, GETTABLE, -1);
416 break; 421 break;
417 case VEXP: 422 case VEXP:
418 close_exp(ls, var->info, 1); /* function must return 1 value */ 423 close_call(ls, var->info, 1); /* call must return 1 value */
419 break; 424 break;
420 } 425 }
421 var->k = VEXP; 426 var->k = VEXP;
@@ -445,7 +450,7 @@ static void func_onstack (LexState *ls, FuncState *func) {
445 TProtoFunc *f = ls->fs->f; 450 TProtoFunc *f = ls->fs->f;
446 int i; 451 int i;
447 for (i=0; i<func->nupvalues; i++) 452 for (i=0; i<func->nupvalues; i++)
448 lua_pushvar(ls, &func->upvalues[i]); 453 close_exp(ls, &func->upvalues[i]);
449 luaM_growvector(ls->L, f->kproto, f->nkproto, 1, TProtoFunc *, 454 luaM_growvector(ls->L, f->kproto, f->nkproto, 1, TProtoFunc *,
450 constantEM, MAXARG_A); 455 constantEM, MAXARG_A);
451 f->kproto[f->nkproto++] = func->f; 456 f->kproto[f->nkproto++] = func->f;
@@ -466,6 +471,7 @@ static void init_state (LexState *ls, FuncState *fs, TaggedString *source) {
466 fs->f = f; 471 fs->f = f;
467 f->source = source; 472 f->source = source;
468 fs->pc = 0; 473 fs->pc = 0;
474 fs->last_pc = -1; /* invalid index to signal no last instruction */
469 f->code = NULL; 475 f->code = NULL;
470 f->maxstacksize = 0; 476 f->maxstacksize = 0;
471 f->numparams = 0; /* default for main chunk */ 477 f->numparams = 0; /* default for main chunk */
@@ -495,76 +501,6 @@ static void close_func (LexState *ls) {
495} 501}
496 502
497 503
498static void next (LexState *ls) {
499 ls->token = luaX_lex(ls);
500}
501
502
503static void error_expected (LexState *ls, int token) {
504 char buff[100], t[TOKEN_LEN];
505 luaX_token2str(token, t);
506 sprintf(buff, "`%.20s' expected", t);
507 luaY_error(ls, buff);
508}
509
510
511static void error_unexpected (LexState *ls) {
512 luaY_error(ls, "unexpected token");
513}
514
515
516static void error_unmatched (LexState *ls, int what, int who, int where) {
517 if (where == ls->linenumber)
518 error_expected(ls, what);
519 else {
520 char buff[100];
521 char t_what[TOKEN_LEN], t_who[TOKEN_LEN];
522 luaX_token2str(what, t_what);
523 luaX_token2str(who, t_who);
524 sprintf(buff, "`%.20s' expected (to close `%.20s' at line %d)",
525 t_what, t_who, where);
526 luaY_error(ls, buff);
527 }
528}
529
530static void check (LexState *ls, int c) {
531 if (ls->token != c)
532 error_expected(ls, c);
533 next(ls);
534}
535
536static void check_match (LexState *ls, int what, int who, int where) {
537 if (ls->token != what)
538 error_unmatched(ls, what, who, where);
539 check_debugline(ls); /* to `mark' the `what' */
540 next(ls);
541}
542
543static int checkname (LexState *ls) {
544 int sc;
545 if (ls->token != NAME)
546 luaY_error(ls, "<name> expected");
547 sc = string_constant(ls, ls->fs, ls->seminfo.ts);
548 next(ls);
549 return sc;
550}
551
552
553static TaggedString *str_checkname (LexState *ls) {
554 int i = checkname(ls); /* this call may realloc `f->consts' */
555 return ls->fs->f->kstr[i];
556}
557
558
559static int optional (LexState *ls, int c) {
560 if (ls->token == c) {
561 next(ls);
562 return 1;
563 }
564 else return 0;
565}
566
567
568TProtoFunc *luaY_parser (lua_State *L, ZIO *z) { 504TProtoFunc *luaY_parser (lua_State *L, ZIO *z) {
569 struct LexState lexstate; 505 struct LexState lexstate;
570 struct FuncState funcstate; 506 struct FuncState funcstate;
@@ -591,14 +527,14 @@ static void explist1 (LexState *ls, listdesc *d) {
591 d->n = 1; 527 d->n = 1;
592 while (ls->token == ',') { 528 while (ls->token == ',') {
593 d->n++; 529 d->n++;
594 lua_pushvar(ls, &v); 530 close_exp(ls, &v);
595 next(ls); 531 next(ls);
596 expr(ls, &v); 532 expr(ls, &v);
597 } 533 }
598 if (v.k == VEXP) 534 if (v.k == VEXP)
599 d->pc = v.info; 535 d->pc = v.info;
600 else { 536 else {
601 lua_pushvar(ls, &v); 537 close_exp(ls, &v);
602 d->pc = 0; 538 d->pc = 0;
603 } 539 }
604} 540}
@@ -628,7 +564,7 @@ static int funcparams (LexState *ls, int slf) {
628 next(ls); 564 next(ls);
629 explist(ls, &e); 565 explist(ls, &e);
630 check_match(ls, ')', '(', line); 566 check_match(ls, ')', '(', line);
631 close_exp(ls, e.pc, MULT_RET); /* close 1 for old semantics */ 567 close_call(ls, e.pc, MULT_RET); /* close 1 for old semantics */
632 break; 568 break;
633 } 569 }
634 570
@@ -655,14 +591,14 @@ static void var_or_func_tail (LexState *ls, vardesc *v) {
655 switch (ls->token) { 591 switch (ls->token) {
656 case '.': /* var_or_func_tail -> '.' NAME */ 592 case '.': /* var_or_func_tail -> '.' NAME */
657 next(ls); 593 next(ls);
658 lua_pushvar(ls, v); /* `v' must be on stack */ 594 close_exp(ls, v); /* `v' must be on stack */
659 v->k = VDOT; 595 code_kstr(ls, checkname(ls));
660 v->info = checkname(ls); 596 v->k = VINDEXED;
661 break; 597 break;
662 598
663 case '[': /* var_or_func_tail -> '[' exp1 ']' */ 599 case '[': /* var_or_func_tail -> '[' exp1 ']' */
664 next(ls); 600 next(ls);
665 lua_pushvar(ls, v); /* `v' must be on stack */ 601 close_exp(ls, v); /* `v' must be on stack */
666 exp1(ls); 602 exp1(ls);
667 check(ls, ']'); 603 check(ls, ']');
668 v->k = VINDEXED; 604 v->k = VINDEXED;
@@ -672,7 +608,7 @@ static void var_or_func_tail (LexState *ls, vardesc *v) {
672 int name; 608 int name;
673 next(ls); 609 next(ls);
674 name = checkname(ls); 610 name = checkname(ls);
675 lua_pushvar(ls, v); /* `v' must be on stack */ 611 close_exp(ls, v); /* `v' must be on stack */
676 code_U(ls, PUSHSELF, name, 1); 612 code_U(ls, PUSHSELF, name, 1);
677 v->k = VEXP; 613 v->k = VEXP;
678 v->info = funcparams(ls, 1); 614 v->info = funcparams(ls, 1);
@@ -680,7 +616,7 @@ static void var_or_func_tail (LexState *ls, vardesc *v) {
680 } 616 }
681 617
682 case '(': case STRING: case '{': /* var_or_func_tail -> funcparams */ 618 case '(': case STRING: case '{': /* var_or_func_tail -> funcparams */
683 lua_pushvar(ls, v); /* `v' must be on stack */ 619 close_exp(ls, v); /* `v' must be on stack */
684 v->k = VEXP; 620 v->k = VEXP;
685 v->info = funcparams(ls, 0); 621 v->info = funcparams(ls, 0);
686 break; 622 break;
@@ -711,6 +647,7 @@ static void var_or_func (LexState *ls, vardesc *v) {
711** ======================================================================= 647** =======================================================================
712*/ 648*/
713 649
650
714static void recfield (LexState *ls) { 651static void recfield (LexState *ls) {
715 /* recfield -> (NAME | '['exp1']') = exp1 */ 652 /* recfield -> (NAME | '['exp1']') = exp1 */
716 switch (ls->token) { 653 switch (ls->token) {
@@ -788,23 +725,14 @@ static void constructor_part (LexState *ls, constdesc *cd) {
788 vardesc v; 725 vardesc v;
789 expr(ls, &v); 726 expr(ls, &v);
790 if (ls->token == '=') { 727 if (ls->token == '=') {
791 switch (v.k) { 728 code_kstr(ls, getvarname(ls, &v));
792 case VGLOBAL: 729 next(ls); /* skip '=' */
793 code_kstr(ls, v.info); 730 exp1(ls);
794 break;
795 case VLOCAL:
796 code_string(ls, ls->fs->localvar[v.info]);
797 break;
798 default:
799 error_unexpected(ls);
800 }
801 next(ls);
802 exp1(ls);
803 cd->n = recfields(ls); 731 cd->n = recfields(ls);
804 cd->k = 1; /* record */ 732 cd->k = 1; /* record */
805 } 733 }
806 else { 734 else {
807 lua_pushvar(ls, &v); 735 close_exp(ls, &v);
808 cd->n = listfields(ls); 736 cd->n = listfields(ls);
809 cd->k = 0; /* list */ 737 cd->k = 0; /* list */
810 } 738 }
@@ -923,18 +851,12 @@ static void pop_to (LexState *ls, stack_op *s, int prio) {
923 } 851 }
924} 852}
925 853
926static void simpleexp (LexState *ls, vardesc *v, stack_op *s) { 854static void simpleexp (LexState *ls, vardesc *v) {
927 check_debugline(ls); 855 check_debugline(ls);
928 switch (ls->token) { 856 switch (ls->token) {
929 case NUMBER: { /* simpleexp -> NUMBER */ 857 case NUMBER: { /* simpleexp -> NUMBER */
930 real r = ls->seminfo.r; 858 real r = ls->seminfo.r;
931 next(ls); 859 next(ls);
932 /* dirty trick: check whether it is a -NUMBER not followed by '^' */
933 /* (because the priority of '^' is higher than the priority of '-') */
934 if (s->top > 0 && s->ops[s->top-1] == INDMINUS && ls->token != '^') {
935 s->top--; /* remove '-' from stack */
936 r = -r;
937 }
938 code_number(ls, r); 860 code_number(ls, r);
939 break; 861 break;
940 } 862 }
@@ -982,7 +904,7 @@ static void prefixexp (LexState *ls, vardesc *v, stack_op *s) {
982 push(ls, s, (ls->token==NOT)?INDNOT:INDMINUS); 904 push(ls, s, (ls->token==NOT)?INDNOT:INDMINUS);
983 next(ls); 905 next(ls);
984 } 906 }
985 simpleexp(ls, v, s); 907 simpleexp(ls, v);
986} 908}
987 909
988 910
@@ -992,16 +914,16 @@ static void arith_exp (LexState *ls, vardesc *v) {
992 s.top = 0; 914 s.top = 0;
993 prefixexp(ls, v, &s); 915 prefixexp(ls, v, &s);
994 while ((op = binop(ls->token)) >= 0) { 916 while ((op = binop(ls->token)) >= 0) {
995 lua_pushvar(ls, v); 917 close_exp(ls, v);
996 /* '^' is right associative, so must 'simulate' a higher priority */ 918 /* '^' is right associative, so must 'simulate' a higher priority */
997 pop_to(ls, &s, (op == POW)?priority[op]+1:priority[op]); 919 pop_to(ls, &s, (op == POW)?priority[op]+1:priority[op]);
998 push(ls, &s, op); 920 push(ls, &s, op);
999 next(ls); 921 next(ls);
1000 prefixexp(ls, v, &s); 922 prefixexp(ls, v, &s);
1001 lua_pushvar(ls, v); 923 close_exp(ls, v);
1002 } 924 }
1003 if (s.top > 0) { 925 if (s.top > 0) {
1004 lua_pushvar(ls, v); 926 close_exp(ls, v);
1005 pop_to(ls, &s, 0); 927 pop_to(ls, &s, 0);
1006 } 928 }
1007} 929}
@@ -1010,7 +932,7 @@ static void arith_exp (LexState *ls, vardesc *v) {
1010static void exp1 (LexState *ls) { 932static void exp1 (LexState *ls) {
1011 vardesc v; 933 vardesc v;
1012 expr(ls, &v); 934 expr(ls, &v);
1013 lua_pushvar(ls, &v); 935 close_exp(ls, &v);
1014} 936}
1015 937
1016 938
@@ -1020,12 +942,12 @@ static void expr (LexState *ls, vardesc *v) {
1020 while (ls->token == AND || ls->token == OR) { 942 while (ls->token == AND || ls->token == OR) {
1021 OpCode op = (ls->token == AND) ? ONFJMP : ONTJMP; 943 OpCode op = (ls->token == AND) ? ONFJMP : ONTJMP;
1022 int pc; 944 int pc;
1023 lua_pushvar(ls, v); 945 close_exp(ls, v);
1024 next(ls); 946 next(ls);
1025 pc = code_S(ls, op, 0, -1); 947 pc = code_S(ls, op, 0, -1);
1026 arith_exp(ls, v); 948 arith_exp(ls, v);
1027 lua_pushvar(ls, v); 949 close_exp(ls, v);
1028 fix_jump(ls, pc, ls->fs->pc); 950 luaK_fixjump(ls, pc, ls->fs->pc);
1029 } 951 }
1030} 952}
1031 953
@@ -1054,7 +976,6 @@ static void block (LexState *ls) {
1054static int assignment (LexState *ls, vardesc *v, int nvars) { 976static int assignment (LexState *ls, vardesc *v, int nvars) {
1055 int left = 0; 977 int left = 0;
1056 checklimit(ls, nvars, MAXVARSLH, "variables in a multiple assignment"); 978 checklimit(ls, nvars, MAXVARSLH, "variables in a multiple assignment");
1057 unloaddot(ls, v);
1058 if (ls->token == ',') { /* assignment -> ',' NAME assignment */ 979 if (ls->token == ',') { /* assignment -> ',' NAME assignment */
1059 vardesc nv; 980 vardesc nv;
1060 next(ls); 981 next(ls);
@@ -1083,19 +1004,37 @@ static int assignment (LexState *ls, vardesc *v, int nvars) {
1083} 1004}
1084 1005
1085 1006
1007/* maximum size of a while condition */
1008#ifndef MAX_WHILE_EXP
1009#define MAX_WHILE_EXP 200 /* arbitrary limit */
1010#endif
1011
1086static void whilestat (LexState *ls, int line) { 1012static void whilestat (LexState *ls, int line) {
1087 /* whilestat -> WHILE exp1 DO block END */ 1013 /* whilestat -> WHILE exp1 DO block END */
1014 Instruction buffer[MAX_WHILE_EXP];
1088 FuncState *fs = ls->fs; 1015 FuncState *fs = ls->fs;
1089 int while_init = fs->pc; 1016 int while_init = fs->pc;
1090 int j1; 1017 int cond_size;
1091 next(ls); 1018 int i;
1092 exp1(ls); 1019 next(ls); /* skip WHILE */
1093 j1 = code_U(ls, IFFJMP, 0, -1); /* jump to exit loop */ 1020 exp1(ls); /* read condition */
1021 cond_size = fs->pc - while_init;
1022 /* save condition (to move it to after body) */
1023 if (cond_size > MAX_WHILE_EXP)
1024 luaY_error(ls, "while condition too complex");
1025 for (i=0; i<cond_size; i++) buffer[i] = fs->f->code[while_init+i];
1026 /* go back to state prior condition */
1027 fs->pc = while_init;
1028 deltastack(ls, -1);
1029 code_S(ls, JMP, 0, 0); /* initial jump to condition */
1094 check(ls, DO); 1030 check(ls, DO);
1095 block(ls); 1031 block(ls);
1096 check_match(ls, END, WHILE, line); 1032 check_match(ls, END, WHILE, line);
1097 fix_jump(ls, code_U(ls, JMP, 0, 0), while_init); /* jump to keep loop */ 1033 luaK_fixjump(ls, while_init, fs->pc);
1098 fix_jump(ls, j1, fs->pc); 1034 /* copy condition to new position, and correct stack */
1035 for (i=0; i<cond_size; i++) luaK_primitivecode(ls, buffer[i]);
1036 deltastack(ls, 1);
1037 luaK_fixjump(ls, code_S(ls, IFTJMP, 0, -1), while_init+1);
1099} 1038}
1100 1039
1101 1040
@@ -1107,7 +1046,7 @@ static void repeatstat (LexState *ls, int line) {
1107 block(ls); 1046 block(ls);
1108 check_match(ls, UNTIL, REPEAT, line); 1047 check_match(ls, UNTIL, REPEAT, line);
1109 exp1(ls); 1048 exp1(ls);
1110 fix_jump(ls, code_U(ls, IFFJMP, 0, -1), repeat_init); 1049 luaK_fixjump(ls, code_S(ls, IFFJMP, 0, -1), repeat_init);
1111} 1050}
1112 1051
1113 1052
@@ -1157,7 +1096,7 @@ static int funcname (LexState *ls, vardesc *v) {
1157 if (ls->token == ':' || ls->token == '.') { 1096 if (ls->token == ':' || ls->token == '.') {
1158 needself = (ls->token == ':'); 1097 needself = (ls->token == ':');
1159 next(ls); 1098 next(ls);
1160 lua_pushvar(ls, v); 1099 close_exp(ls, v);
1161 code_kstr(ls, checkname(ls)); 1100 code_kstr(ls, checkname(ls));
1162 v->k = VINDEXED; 1101 v->k = VINDEXED;
1163 } 1102 }
@@ -1188,7 +1127,7 @@ static void namestat (LexState *ls) {
1188 if (v.k == VEXP) { /* stat -> func */ 1127 if (v.k == VEXP) { /* stat -> func */
1189 if (v.info == 0) /* is just an upper value? */ 1128 if (v.info == 0) /* is just an upper value? */
1190 luaY_error(ls, "syntax error"); 1129 luaY_error(ls, "syntax error");
1191 close_exp(ls, v.info, 0); 1130 close_call(ls, v.info, 0); /* call statement uses no results */
1192 } 1131 }
1193 else { /* stat -> ['%'] NAME assignment */ 1132 else { /* stat -> ['%'] NAME assignment */
1194 int left = assignment(ls, &v, 1); 1133 int left = assignment(ls, &v, 1);
@@ -1200,14 +1139,16 @@ static void namestat (LexState *ls) {
1200static void ifpart (LexState *ls, int line) { 1139static void ifpart (LexState *ls, int line) {
1201 /* ifpart -> cond THEN block [ELSE block | ELSEIF ifpart] */ 1140 /* ifpart -> cond THEN block [ELSE block | ELSEIF ifpart] */
1202 FuncState *fs = ls->fs; 1141 FuncState *fs = ls->fs;
1203 int c; 1142 int c; /* address of the conditional jump */
1204 int je; 1143 int je; /* address of the unconditional jump (to skip `else' part) */
1144 int elseinit;
1205 next(ls); /* skip IF or ELSEIF */ 1145 next(ls); /* skip IF or ELSEIF */
1206 exp1(ls); /* cond */ 1146 exp1(ls); /* cond */
1207 c = code_U(ls, IFFJMP, 0, -1); /* jump `then' if `cond' is false */ 1147 c = code_S(ls, IFFJMP, 0, -1); /* jump `then' if `cond' is false */
1208 check(ls, THEN); 1148 check(ls, THEN);
1209 block(ls); /* `then' part */ 1149 block(ls); /* `then' part */
1210 je = code_U(ls, JMP, 0, 0); /* jump `else' part after `then' */ 1150 je = code_S(ls, JMP, 0, 0); /* jump `else' part after `then' */
1151 elseinit = fs->pc;
1211 if (ls->token == ELSEIF) 1152 if (ls->token == ELSEIF)
1212 ifpart(ls, line); 1153 ifpart(ls, line);
1213 else { 1154 else {
@@ -1215,13 +1156,14 @@ static void ifpart (LexState *ls, int line) {
1215 block(ls); /* `else' part */ 1156 block(ls); /* `else' part */
1216 check_match(ls, END, IF, line); 1157 check_match(ls, END, IF, line);
1217 } 1158 }
1218 if (fs->pc == je+1) { /* `else' part empty? */ 1159 if (fs->pc > elseinit) /* is there an `else' part? */
1160 luaK_fixjump(ls, je, fs->pc); /* last jump jumps over it */
1161 else {
1219 fs->pc--; /* remove last jump */ 1162 fs->pc--; /* remove last jump */
1220 je--; /* first jump will be smaller */ 1163 elseinit--; /* first jump will be smaller */
1164 LUA_ASSERT(L, fs->pc == je, "jump out of place");
1221 } 1165 }
1222 else 1166 luaK_fixjump(ls, c, elseinit); /* fix first jump to `else' part */
1223 fix_jump(ls, je, fs->pc); /* fix last jump */
1224 fix_jump(ls, c, je+1); /* fix first jump to beginning of `else' part */
1225} 1167}
1226 1168
1227 1169
@@ -1329,13 +1271,8 @@ static void ret (LexState *ls) {
1329 check_debugline(ls); 1271 check_debugline(ls);
1330 next(ls); 1272 next(ls);
1331 explist(ls, &e); 1273 explist(ls, &e);
1332 if (e.pc > 0) { /* expression is an open function call? */ 1274 close_call(ls, e.pc, MULT_RET);
1333 Instruction *i = &ls->fs->f->code[e.pc]; 1275 code_U(ls, RETCODE, ls->fs->nlocalvar, 0);
1334 *i = SET_OPCODE(*i, TAILCALL); /* instead of a conventional CALL */
1335 *i = SETARG_B(*i, ls->fs->nlocalvar);
1336 }
1337 else
1338 code_U(ls, RETCODE, ls->fs->nlocalvar, 0);
1339 ls->fs->stacksize = ls->fs->nlocalvar; /* removes all temp values */ 1276 ls->fs->stacksize = ls->fs->nlocalvar; /* removes all temp values */
1340 optional(ls, ';'); 1277 optional(ls, ';');
1341 } 1278 }