diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2000-02-22 11:31:43 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2000-02-22 11:31:43 -0200 |
commit | 3bc925138ebcb534f863b3fb32b21eb8d52aa915 (patch) | |
tree | 6fcbc3bf92357a5e2e1651bc38c79b9bbea42a51 /lparser.c | |
parent | 39e1f079bdf045d64ad6f1b5da1eb48cc79c6c38 (diff) | |
download | lua-3bc925138ebcb534f863b3fb32b21eb8d52aa915.tar.gz lua-3bc925138ebcb534f863b3fb32b21eb8d52aa915.tar.bz2 lua-3bc925138ebcb534f863b3fb32b21eb8d52aa915.zip |
first version of code optimizer
Diffstat (limited to 'lparser.c')
-rw-r--r-- | lparser.c | 395 |
1 files changed, 166 insertions, 229 deletions
@@ -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 | */ | ||
52 | typedef 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 | |||
60 | typedef 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 */ | ||
91 | typedef 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); | |||
112 | static void exp1 (LexState *ls); | 58 | static void exp1 (LexState *ls); |
113 | 59 | ||
114 | 60 | ||
61 | static void next (LexState *ls) { | ||
62 | ls->token = luaX_lex(ls); | ||
63 | } | ||
64 | |||
115 | 65 | ||
116 | static void luaY_error (LexState *ls, const char *msg) { | 66 | static 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 | ||
121 | static void checklimit (LexState *ls, int val, int limit, const char *msg) { | 71 | static 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 | |||
79 | static void error_unexpected (LexState *ls) { | ||
80 | luaY_error(ls, "unexpected token"); | ||
81 | } | ||
82 | |||
83 | |||
84 | static 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 | ||
98 | static void check (LexState *ls, int c) { | ||
99 | if (ls->token != c) | ||
100 | error_expected(ls, c); | ||
101 | next(ls); | ||
102 | } | ||
103 | |||
129 | 104 | ||
130 | static int code_instruction (LexState *ls, Instruction i) { | 105 | static 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 | ||
138 | static void fix_jump (LexState *ls, int pc, int dest) { | 114 | static 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 | |||
145 | static void deltastack (LexState *ls, int delta) { | 124 | static 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 | ||
154 | static int aux_code (LexState *ls, OpCode op, Instruction i, int delta) { | 134 | static 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 | ||
165 | static 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 | |||
173 | static 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 | |||
185 | static void code_kstr (LexState *ls, int c) { | 181 | static 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 | ||
230 | static void code_number (LexState *ls, real f) { | 226 | static 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 | |||
234 | static 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 | |||
244 | static 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 | |||
331 | static 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 | |||
339 | static void adjuststack (LexState *ls, int n) { | 342 | static 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 | ||
347 | static void close_exp (LexState *ls, int pc, int nresults) { | 350 | static 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 | ||
393 | static void unloaddot (LexState *ls, vardesc *v) { | 396 | static 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 | ||
402 | static void lua_pushvar (LexState *ls, vardesc *var) { | 410 | static 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 | ||
498 | static void next (LexState *ls) { | ||
499 | ls->token = luaX_lex(ls); | ||
500 | } | ||
501 | |||
502 | |||
503 | static 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 | |||
511 | static void error_unexpected (LexState *ls) { | ||
512 | luaY_error(ls, "unexpected token"); | ||
513 | } | ||
514 | |||
515 | |||
516 | static 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 | |||
530 | static void check (LexState *ls, int c) { | ||
531 | if (ls->token != c) | ||
532 | error_expected(ls, c); | ||
533 | next(ls); | ||
534 | } | ||
535 | |||
536 | static 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 | |||
543 | static 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 | |||
553 | static 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 | |||
559 | static 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 | |||
568 | TProtoFunc *luaY_parser (lua_State *L, ZIO *z) { | 504 | TProtoFunc *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 | |||
714 | static void recfield (LexState *ls) { | 651 | static 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 | ||
926 | static void simpleexp (LexState *ls, vardesc *v, stack_op *s) { | 854 | static 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) { | |||
1010 | static void exp1 (LexState *ls) { | 932 | static 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) { | |||
1054 | static int assignment (LexState *ls, vardesc *v, int nvars) { | 976 | static 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 | |||
1086 | static void whilestat (LexState *ls, int line) { | 1012 | static 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) { | |||
1200 | static void ifpart (LexState *ls, int line) { | 1139 | static 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 | } |