diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2000-06-05 11:56:18 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2000-06-05 11:56:18 -0300 |
commit | dbfb810267d8fd7ecf546ea1e1edc8892547e664 (patch) | |
tree | ca5906c0238233c903f2c9427646e67c74bc7806 | |
parent | 9c14b5e416e1ca3ebed37c4ceb860579124ac29f (diff) | |
download | lua-dbfb810267d8fd7ecf546ea1e1edc8892547e664.tar.gz lua-dbfb810267d8fd7ecf546ea1e1edc8892547e664.tar.bz2 lua-dbfb810267d8fd7ecf546ea1e1edc8892547e664.zip |
cleansing of lparser.c
-rw-r--r-- | lcode.c | 38 | ||||
-rw-r--r-- | lgc.c | 11 | ||||
-rw-r--r-- | lopcodes.h | 4 | ||||
-rw-r--r-- | lparser.c | 416 | ||||
-rw-r--r-- | lvm.c | 25 |
5 files changed, 223 insertions, 271 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lcode.c,v 1.32 2000/05/24 13:54:49 roberto Exp roberto $ | 2 | ** $Id: lcode.c,v 1.33 2000/05/24 18:04:17 roberto Exp roberto $ |
3 | ** Code generator for Lua | 3 | ** Code generator for Lua |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -69,16 +69,16 @@ static int luaK_getjump (FuncState *fs, int pc) { | |||
69 | 69 | ||
70 | 70 | ||
71 | /* | 71 | /* |
72 | ** discharge list of jumps to last target. | ||
73 | ** returns current `pc' and marks it as a jump target (to avoid wrong | 72 | ** returns current `pc' and marks it as a jump target (to avoid wrong |
74 | ** optimizations with consecutive instructions not in the same basic block). | 73 | ** optimizations with consecutive instructions not in the same basic block). |
74 | ** discharge list of jumps to last target. | ||
75 | */ | 75 | */ |
76 | int luaK_getlabel (FuncState *fs) { | 76 | int luaK_getlabel (FuncState *fs) { |
77 | if (fs->pc != fs->lasttarget) { | 77 | if (fs->pc != fs->lasttarget) { |
78 | int lasttarget = fs->lasttarget; | 78 | int lasttarget = fs->lasttarget; |
79 | fs->lasttarget = fs->pc; | 79 | fs->lasttarget = fs->pc; |
80 | luaK_patchlist(fs, fs->jlt, lasttarget); /* discharge old list `jlt' */ | 80 | luaK_patchlist(fs, fs->jlt, lasttarget); /* discharge old list `jlt' */ |
81 | fs->jlt = NO_JUMP; /* nobody jumps to this new label (till now) */ | 81 | fs->jlt = NO_JUMP; /* nobody jumps to this new label (yet) */ |
82 | } | 82 | } |
83 | return fs->pc; | 83 | return fs->pc; |
84 | } | 84 | } |
@@ -86,7 +86,7 @@ int luaK_getlabel (FuncState *fs) { | |||
86 | 86 | ||
87 | void luaK_deltastack (FuncState *fs, int delta) { | 87 | void luaK_deltastack (FuncState *fs, int delta) { |
88 | fs->stacklevel += delta; | 88 | fs->stacklevel += delta; |
89 | if (delta > 0 && fs->stacklevel > fs->f->maxstacksize) { | 89 | if (fs->stacklevel > fs->f->maxstacksize) { |
90 | if (fs->stacklevel > MAXSTACK) | 90 | if (fs->stacklevel > MAXSTACK) |
91 | luaK_error(fs->ls, "function or expression too complex"); | 91 | luaK_error(fs->ls, "function or expression too complex"); |
92 | fs->f->maxstacksize = fs->stacklevel; | 92 | fs->f->maxstacksize = fs->stacklevel; |
@@ -99,7 +99,7 @@ void luaK_kstr (LexState *ls, int c) { | |||
99 | } | 99 | } |
100 | 100 | ||
101 | 101 | ||
102 | static int real_constant (FuncState *fs, Number r) { | 102 | static int number_constant (FuncState *fs, Number r) { |
103 | /* check whether `r' has appeared within the last LOOKBACKNUMS entries */ | 103 | /* check whether `r' has appeared within the last LOOKBACKNUMS entries */ |
104 | Proto *f = fs->f; | 104 | Proto *f = fs->f; |
105 | int c = f->nknum; | 105 | int c = f->nknum; |
@@ -116,17 +116,17 @@ static int real_constant (FuncState *fs, Number r) { | |||
116 | 116 | ||
117 | 117 | ||
118 | void luaK_number (FuncState *fs, Number f) { | 118 | void luaK_number (FuncState *fs, Number f) { |
119 | if (f <= (Number)MAXARG_S && (int)f == f) | 119 | if (f <= (Number)MAXARG_S && (Number)(int)f == f) |
120 | luaK_code1(fs, OP_PUSHINT, (int)f); /* f has a short integer value */ | 120 | luaK_code1(fs, OP_PUSHINT, (int)f); /* f has a short integer value */ |
121 | else | 121 | else |
122 | luaK_code1(fs, OP_PUSHNUM, real_constant(fs, f)); | 122 | luaK_code1(fs, OP_PUSHNUM, number_constant(fs, f)); |
123 | } | 123 | } |
124 | 124 | ||
125 | 125 | ||
126 | void luaK_adjuststack (FuncState *fs, int n) { | 126 | void luaK_adjuststack (FuncState *fs, int n) { |
127 | if (n > 0) | 127 | if (n > 0) |
128 | luaK_code1(fs, OP_POP, n); | 128 | luaK_code1(fs, OP_POP, n); |
129 | else if (n < 0) | 129 | else |
130 | luaK_code1(fs, OP_PUSHNIL, -n); | 130 | luaK_code1(fs, OP_PUSHNIL, -n); |
131 | } | 131 | } |
132 | 132 | ||
@@ -170,7 +170,7 @@ static int discharge (FuncState *fs, expdesc *var) { | |||
170 | 170 | ||
171 | static void discharge1 (FuncState *fs, expdesc *var) { | 171 | static void discharge1 (FuncState *fs, expdesc *var) { |
172 | discharge(fs, var); | 172 | discharge(fs, var); |
173 | /* if it has jumps it is already discharged */ | 173 | /* if it has jumps then it is already discharged */ |
174 | if (var->u.l.t == NO_JUMP && var->u.l.f == NO_JUMP) | 174 | if (var->u.l.t == NO_JUMP && var->u.l.f == NO_JUMP) |
175 | luaK_setcallreturns(fs, 1); /* call must return 1 value */ | 175 | luaK_setcallreturns(fs, 1); /* call must return 1 value */ |
176 | } | 176 | } |
@@ -275,12 +275,10 @@ static void luaK_testgo (FuncState *fs, expdesc *v, int invert, OpCode jump) { | |||
275 | discharge1(fs, v); | 275 | discharge1(fs, v); |
276 | previous = &fs->f->code[fs->pc-1]; | 276 | previous = &fs->f->code[fs->pc-1]; |
277 | LUA_ASSERT(L, GET_OPCODE(*previous) != OP_SETLINE, "bad place to set line"); | 277 | LUA_ASSERT(L, GET_OPCODE(*previous) != OP_SETLINE, "bad place to set line"); |
278 | if (ISJUMP(GET_OPCODE(*previous))) { | 278 | if (!ISJUMP(GET_OPCODE(*previous))) |
279 | if (invert) | ||
280 | SET_OPCODE(*previous, invertjump(GET_OPCODE(*previous))); | ||
281 | } | ||
282 | else | ||
283 | luaK_code1(fs, jump, NO_JUMP); | 279 | luaK_code1(fs, jump, NO_JUMP); |
280 | else if (invert) | ||
281 | SET_OPCODE(*previous, invertjump(GET_OPCODE(*previous))); | ||
284 | luaK_concat(fs, exitlist, fs->pc-1); /* insert last jump in `exitlist' */ | 282 | luaK_concat(fs, exitlist, fs->pc-1); /* insert last jump in `exitlist' */ |
285 | luaK_patchlist(fs, *golist, luaK_getlabel(fs)); | 283 | luaK_patchlist(fs, *golist, luaK_getlabel(fs)); |
286 | *golist = NO_JUMP; | 284 | *golist = NO_JUMP; |
@@ -431,12 +429,17 @@ int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) { | |||
431 | break; | 429 | break; |
432 | 430 | ||
433 | case OP_SETTABLE: | 431 | case OP_SETTABLE: |
432 | delta = -arg2; | ||
433 | break; | ||
434 | |||
434 | case OP_SETLIST: | 435 | case OP_SETLIST: |
436 | if (arg2 == 0) return NO_JUMP; /* nothing to do */ | ||
435 | delta = -arg2; | 437 | delta = -arg2; |
436 | break; | 438 | break; |
437 | 439 | ||
438 | case OP_SETMAP: | 440 | case OP_SETMAP: |
439 | delta = -2*(arg1+1); | 441 | if (arg1 == 0) return NO_JUMP; /* nothing to do */ |
442 | delta = -2*arg1; | ||
440 | break; | 443 | break; |
441 | 444 | ||
442 | case OP_RETURN: | 445 | case OP_RETURN: |
@@ -448,6 +451,7 @@ int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) { | |||
448 | break; | 451 | break; |
449 | 452 | ||
450 | case OP_PUSHNIL: | 453 | case OP_PUSHNIL: |
454 | if (arg1 == 0) return NO_JUMP; /* nothing to do */ | ||
451 | delta = arg1; | 455 | delta = arg1; |
452 | switch(GET_OPCODE(i)) { | 456 | switch(GET_OPCODE(i)) { |
453 | case OP_PUSHNIL: SETARG_U(i, GETARG_U(i)+arg1); optm = 1; break; | 457 | case OP_PUSHNIL: SETARG_U(i, GETARG_U(i)+arg1); optm = 1; break; |
@@ -456,6 +460,7 @@ int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) { | |||
456 | break; | 460 | break; |
457 | 461 | ||
458 | case OP_POP: | 462 | case OP_POP: |
463 | if (arg1 == 0) return NO_JUMP; /* nothing to do */ | ||
459 | delta = -arg1; | 464 | delta = -arg1; |
460 | switch(GET_OPCODE(i)) { | 465 | switch(GET_OPCODE(i)) { |
461 | case OP_SETTABLE: SETARG_B(i, GETARG_B(i)+arg1); optm = 1; break; | 466 | case OP_SETTABLE: SETARG_B(i, GETARG_B(i)+arg1); optm = 1; break; |
@@ -561,13 +566,14 @@ int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) { | |||
561 | fs->f->code[fs->pc-1] = i; /* change previous instruction */ | 566 | fs->f->code[fs->pc-1] = i; /* change previous instruction */ |
562 | return fs->pc-1; /* do not generate new instruction */ | 567 | return fs->pc-1; /* do not generate new instruction */ |
563 | } | 568 | } |
569 | /* build new instruction */ | ||
564 | switch ((enum Mode)luaK_opproperties[o].mode) { | 570 | switch ((enum Mode)luaK_opproperties[o].mode) { |
565 | case iO: i = CREATE_0(o); break; | 571 | case iO: i = CREATE_0(o); break; |
566 | case iU: i = CREATE_U(o, arg1); break; | 572 | case iU: i = CREATE_U(o, arg1); break; |
567 | case iS: i = CREATE_S(o, arg1); break; | 573 | case iS: i = CREATE_S(o, arg1); break; |
568 | case iAB: i = CREATE_AB(o, arg1, arg2); break; | 574 | case iAB: i = CREATE_AB(o, arg1, arg2); break; |
569 | } | 575 | } |
570 | /* actually create the new instruction */ | 576 | /* put new instruction in code array */ |
571 | luaM_growvector(fs->L, fs->f->code, fs->pc, 1, Instruction, | 577 | luaM_growvector(fs->L, fs->f->code, fs->pc, 1, Instruction, |
572 | "code size overflow", MAX_INT); | 578 | "code size overflow", MAX_INT); |
573 | fs->f->code[fs->pc] = i; | 579 | fs->f->code[fs->pc] = i; |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lgc.c,v 1.52 2000/05/30 18:54:49 roberto Exp roberto $ | 2 | ** $Id: lgc.c,v 1.53 2000/05/30 19:00:31 roberto Exp roberto $ |
3 | ** Garbage Collector | 3 | ** Garbage Collector |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -34,10 +34,15 @@ static void protomark (lua_State *L, Proto *f) { | |||
34 | int i; | 34 | int i; |
35 | f->marked = 1; | 35 | f->marked = 1; |
36 | strmark(L, f->source); | 36 | strmark(L, f->source); |
37 | for (i=f->nkstr-1; i>=0; i--) | 37 | for (i=0; i<f->nkstr; i++) |
38 | strmark(L, f->kstr[i]); | 38 | strmark(L, f->kstr[i]); |
39 | for (i=f->nkproto-1; i>=0; i--) | 39 | for (i=0; i<f->nkproto; i++) |
40 | protomark(L, f->kproto[i]); | 40 | protomark(L, f->kproto[i]); |
41 | if (f->locvars) { /* is there debug information? */ | ||
42 | LocVar *lv; | ||
43 | for (lv=f->locvars; lv->line != -1; lv++) /* mark local-variable names */ | ||
44 | if (lv->varname) strmark(L, lv->varname); | ||
45 | } | ||
41 | } | 46 | } |
42 | } | 47 | } |
43 | 48 | ||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lopcodes.h,v 1.61 2000/05/15 19:48:04 roberto Exp roberto $ | 2 | ** $Id: lopcodes.h,v 1.62 2000/05/22 18:44:46 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 | */ |
@@ -113,7 +113,7 @@ OP_SETGLOBAL,/* K x - VAR[KSTR[k]]=x */ | |||
113 | OP_SETTABLE,/* A B v a_a-a_1 i t (pops b values) t[i]=v */ | 113 | OP_SETTABLE,/* A B v a_a-a_1 i t (pops b values) t[i]=v */ |
114 | 114 | ||
115 | OP_SETLIST,/* A B v_b-v_1 t t t[i+a*FPF]=v_i */ | 115 | OP_SETLIST,/* A B v_b-v_1 t t t[i+a*FPF]=v_i */ |
116 | OP_SETMAP,/* U v_u k_u - v_0 k_0 t t t[k_i]=v_i */ | 116 | OP_SETMAP,/* U v_u k_u - v_1 k_1 t t t[k_i]=v_i */ |
117 | 117 | ||
118 | OP_ADD,/* - y x x+y */ | 118 | OP_ADD,/* - y x x+y */ |
119 | OP_ADDI,/* S x x+s */ | 119 | OP_ADDI,/* S x x+s */ |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lparser.c,v 1.92 2000/05/25 18:59:59 roberto Exp roberto $ | 2 | ** $Id: lparser.c,v 1.93 2000/05/30 19:00:31 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 | */ |
@@ -11,7 +11,6 @@ | |||
11 | #define LUA_REENTRANT | 11 | #define LUA_REENTRANT |
12 | 12 | ||
13 | #include "lcode.h" | 13 | #include "lcode.h" |
14 | #include "ldo.h" | ||
15 | #include "lfunc.h" | 14 | #include "lfunc.h" |
16 | #include "llex.h" | 15 | #include "llex.h" |
17 | #include "lmem.h" | 16 | #include "lmem.h" |
@@ -79,11 +78,6 @@ static void error_expected (LexState *ls, int token) { | |||
79 | } | 78 | } |
80 | 79 | ||
81 | 80 | ||
82 | static void error_unexpected (LexState *ls) { | ||
83 | luaK_error(ls, "unexpected token"); | ||
84 | } | ||
85 | |||
86 | |||
87 | static void check (LexState *ls, int c) { | 81 | static void check (LexState *ls, int c) { |
88 | if (ls->t.token != c) | 82 | if (ls->t.token != c) |
89 | error_expected(ls, c); | 83 | error_expected(ls, c); |
@@ -91,6 +85,11 @@ static void check (LexState *ls, int c) { | |||
91 | } | 85 | } |
92 | 86 | ||
93 | 87 | ||
88 | static void check_condition (LexState *ls, int c, const char *msg) { | ||
89 | if (!c) luaK_error(ls, msg); | ||
90 | } | ||
91 | |||
92 | |||
94 | static void setline (LexState *ls) { | 93 | static void setline (LexState *ls) { |
95 | FuncState *fs = ls->fs; | 94 | FuncState *fs = ls->fs; |
96 | if (ls->L->debug && ls->linenumber != fs->lastsetline) { | 95 | if (ls->L->debug && ls->linenumber != fs->lastsetline) { |
@@ -159,27 +158,17 @@ static void code_string (LexState *ls, TString *s) { | |||
159 | } | 158 | } |
160 | 159 | ||
161 | 160 | ||
162 | static int checkname (LexState *ls) { | ||
163 | int sc; | ||
164 | if (ls->t.token != TK_NAME) | ||
165 | luaK_error(ls, "<name> expected"); | ||
166 | sc = string_constant(ls->fs, ls->t.seminfo.ts); | ||
167 | next(ls); | ||
168 | return sc; | ||
169 | } | ||
170 | |||
171 | |||
172 | static TString *str_checkname (LexState *ls) { | 161 | static TString *str_checkname (LexState *ls) { |
173 | int i = checkname(ls); /* this call may realloc `f->kstr' */ | 162 | TString *ts; |
174 | return ls->fs->f->kstr[i]; | 163 | check_condition(ls, (ls->t.token == TK_NAME), "<name> expected"); |
164 | ts = ls->t.seminfo.ts; | ||
165 | next(ls); | ||
166 | return ts; | ||
175 | } | 167 | } |
176 | 168 | ||
177 | 169 | ||
178 | static TString *optionalname (LexState *ls) { | 170 | static int checkname (LexState *ls) { |
179 | if (ls->t.token == TK_NAME) | 171 | return string_constant(ls->fs, str_checkname(ls)); |
180 | return str_checkname(ls); | ||
181 | else | ||
182 | return NULL; | ||
183 | } | 172 | } |
184 | 173 | ||
185 | 174 | ||
@@ -229,94 +218,90 @@ static void add_localvar (LexState *ls, const char *name) { | |||
229 | } | 218 | } |
230 | 219 | ||
231 | 220 | ||
232 | static int aux_localname (FuncState *fs, TString *n) { | 221 | static int search_local (LexState *ls, TString *n, expdesc *var) { |
233 | int i; | 222 | FuncState *fs; |
234 | for (i=fs->nlocalvar-1; i >= 0; i--) | 223 | int level = 0; |
235 | if (n == fs->localvar[i]) return i; /* local var index */ | 224 | for (fs=ls->fs; fs; fs=fs->prev) { |
236 | return -1; /* not found */ | 225 | int i; |
226 | for (i=fs->nlocalvar-1; i >= 0; i--) { | ||
227 | if (n == fs->localvar[i]) { | ||
228 | var->k = VLOCAL; | ||
229 | var->u.index = i; | ||
230 | return level; | ||
231 | } | ||
232 | } | ||
233 | level++; /* `var' not found; check outer level */ | ||
234 | } | ||
235 | var->k = VGLOBAL; /* not found in any level; must be global */ | ||
236 | return -1; | ||
237 | } | 237 | } |
238 | 238 | ||
239 | 239 | ||
240 | static void singlevar (LexState *ls, TString *n, expdesc *var, int prev) { | 240 | static void singlevar (LexState *ls, TString *n, expdesc *var) { |
241 | FuncState *fs = prev ? ls->fs->prev : ls->fs; | 241 | int level = search_local(ls, n, var); |
242 | int i = aux_localname(fs, n); | 242 | if (level >= 1) /* neither local (0) nor global (-1)? */ |
243 | if (i >= 0) { /* local value? */ | 243 | luaX_syntaxerror(ls, "cannot access a variable in outer scope", n->str); |
244 | var->k = VLOCAL; | 244 | else if (level == -1) /* global? */ |
245 | var->u.index = i; | 245 | var->u.index = string_constant(ls->fs, n); |
246 | } | ||
247 | else { | ||
248 | FuncState *level = fs; | ||
249 | while ((level = level->prev) != NULL) /* check shadowing */ | ||
250 | if (aux_localname(level, n) >= 0) | ||
251 | luaX_syntaxerror(ls, "cannot access a variable in outer scope", n->str); | ||
252 | var->k = VGLOBAL; | ||
253 | var->u.index = string_constant(fs, n); | ||
254 | } | ||
255 | } | 246 | } |
256 | 247 | ||
257 | 248 | ||
258 | static int indexupvalue (LexState *ls, TString *n) { | 249 | static int indexupvalue (LexState *ls, expdesc *v) { |
259 | FuncState *fs = ls->fs; | 250 | FuncState *fs = ls->fs; |
260 | expdesc v; | ||
261 | int i; | 251 | int i; |
262 | singlevar(ls, n, &v, 1); | ||
263 | for (i=0; i<fs->nupvalues; i++) { | 252 | for (i=0; i<fs->nupvalues; i++) { |
264 | if (fs->upvalues[i].k == v.k && fs->upvalues[i].u.index == v.u.index) | 253 | if (fs->upvalues[i].k == v->k && fs->upvalues[i].u.index == v->u.index) |
265 | return i; | 254 | return i; |
266 | } | 255 | } |
267 | /* new one */ | 256 | /* new one */ |
268 | ++(fs->nupvalues); | 257 | luaX_checklimit(ls, fs->nupvalues+1, MAXUPVALUES, "upvalues"); |
269 | luaX_checklimit(ls, fs->nupvalues, MAXUPVALUES, "upvalues"); | 258 | fs->upvalues[fs->nupvalues] = *v; |
270 | fs->upvalues[i] = v; /* i = fs->nupvalues - 1 */ | 259 | return fs->nupvalues++; |
271 | return i; | ||
272 | } | 260 | } |
273 | 261 | ||
274 | 262 | ||
275 | static void pushupvalue (LexState *ls, TString *n) { | 263 | static void pushupvalue (LexState *ls, TString *n) { |
276 | FuncState *fs = ls->fs; | 264 | FuncState *fs = ls->fs; |
277 | if (fs->prev == NULL) | 265 | expdesc v; |
278 | luaX_syntaxerror(ls, "cannot access upvalue in main", n->str); | 266 | int level = search_local(ls, n, &v); |
279 | if (aux_localname(ls->fs, n) >= 0) | 267 | if (level == -1) { /* global? */ |
280 | luaX_syntaxerror(ls, "cannot access an upvalue in current scope", n->str); | 268 | if (fs->prev == NULL) |
281 | luaK_code1(fs, OP_PUSHUPVALUE, indexupvalue(ls, n)); | 269 | luaX_syntaxerror(ls, "cannot access upvalue in main", n->str); |
270 | v.u.index = string_constant(fs->prev, n); | ||
271 | } | ||
272 | else if (level != 1) | ||
273 | luaX_syntaxerror(ls, | ||
274 | "upvalue must be global or local to immediately outer scope", n->str); | ||
275 | luaK_code1(fs, OP_PUSHUPVALUE, indexupvalue(ls, &v)); | ||
282 | } | 276 | } |
283 | 277 | ||
284 | 278 | ||
285 | static void adjust_mult_assign (LexState *ls, int nvars, int nexps) { | 279 | static void adjust_mult_assign (LexState *ls, int nvars, int nexps) { |
286 | FuncState *fs = ls->fs; | 280 | FuncState *fs = ls->fs; |
287 | int diff = nexps - nvars; | 281 | int diff = nexps - nvars; |
288 | if (nexps == 0 || !luaK_lastisopen(fs)) { /* list is empty or closed */ | 282 | if (nexps > 0 && luaK_lastisopen(fs)) { /* list ends in a function call */ |
289 | /* push or pop eventual difference between list lengths */ | ||
290 | luaK_adjuststack(fs, diff); | ||
291 | } | ||
292 | else { /* list ends in a function call; must correct it */ | ||
293 | diff--; /* do not count function call itself */ | 283 | diff--; /* do not count function call itself */ |
294 | if (diff <= 0) { /* more variables than values? */ | 284 | if (diff <= 0) { /* more variables than values? */ |
295 | /* function call must provide extra values */ | 285 | luaK_setcallreturns(fs, -diff); /* function call provide extra values */ |
296 | luaK_setcallreturns(fs, -diff); | 286 | diff = 0; /* no more difference */ |
297 | } | 287 | } |
298 | else { /* more values than variables */ | 288 | else /* more values than variables */ |
299 | luaK_setcallreturns(fs, 0); /* call should provide no value */ | 289 | luaK_setcallreturns(fs, 0); /* call should provide no value */ |
300 | luaK_adjuststack(fs, diff); /* pop eventual extra values */ | ||
301 | } | ||
302 | } | 290 | } |
291 | /* push or pop eventual difference between list lengths */ | ||
292 | luaK_adjuststack(fs, diff); | ||
303 | } | 293 | } |
304 | 294 | ||
305 | 295 | ||
306 | static void code_args (LexState *ls, int nparams, int dots) { | 296 | static void code_params (LexState *ls, int nparams, int dots) { |
307 | FuncState *fs = ls->fs; | 297 | FuncState *fs = ls->fs; |
308 | nparams -= dots; /* do not count `...' as a parameter */ | ||
309 | adjustlocalvars(ls, nparams); | 298 | adjustlocalvars(ls, nparams); |
310 | luaX_checklimit(ls, fs->nlocalvar, MAXPARAMS, "parameters"); | 299 | luaX_checklimit(ls, fs->nlocalvar, MAXPARAMS, "parameters"); |
311 | nparams = fs->nlocalvar; /* `self' could be there already */ | 300 | fs->f->numparams = fs->nlocalvar; /* `self' could be there already */ |
312 | fs->f->numparams = nparams; | ||
313 | fs->f->is_vararg = dots; | 301 | fs->f->is_vararg = dots; |
314 | if (!dots) | 302 | if (dots) |
315 | luaK_deltastack(fs, nparams); | ||
316 | else { | ||
317 | luaK_deltastack(fs, nparams+1); | ||
318 | add_localvar(ls, "arg"); | 303 | add_localvar(ls, "arg"); |
319 | } | 304 | luaK_deltastack(fs, fs->nlocalvar); /* count parameters in the stack */ |
320 | } | 305 | } |
321 | 306 | ||
322 | 307 | ||
@@ -336,21 +321,23 @@ static void leavebreak (FuncState *fs, Breaklabel *bl) { | |||
336 | } | 321 | } |
337 | 322 | ||
338 | 323 | ||
339 | static Breaklabel *findlabel (FuncState *fs, TString *name) { | 324 | static Breaklabel *findlabel (LexState *ls) { |
325 | FuncState *fs = ls->fs; | ||
340 | Breaklabel *bl; | 326 | Breaklabel *bl; |
327 | TString *label = (ls->t.token == TK_NAME) ? ls->t.seminfo.ts : NULL; | ||
341 | for (bl=fs->bl; bl; bl=bl->previous) { | 328 | for (bl=fs->bl; bl; bl=bl->previous) { |
342 | if (bl->label == name) | 329 | if (bl->label == label) { |
330 | if (label) next(ls); /* no errors; can skip optional label */ | ||
343 | return bl; | 331 | return bl; |
332 | } | ||
344 | } | 333 | } |
345 | if (name) /* label not found: choose appropriate error message */ | 334 | /* label not found */ |
346 | luaX_syntaxerror(fs->ls, "break not inside given label", name->str); | 335 | luaK_error(fs->ls, "invalid break"); |
347 | else | ||
348 | luaK_error(fs->ls, "break not inside while or repeat loop"); | ||
349 | return NULL; /* to avoid warnings */ | 336 | return NULL; /* to avoid warnings */ |
350 | } | 337 | } |
351 | 338 | ||
352 | 339 | ||
353 | static void func_onstack (LexState *ls, FuncState *func) { | 340 | static void pushclosure (LexState *ls, FuncState *func) { |
354 | FuncState *fs = ls->fs; | 341 | FuncState *fs = ls->fs; |
355 | Proto *f = fs->f; | 342 | Proto *f = fs->f; |
356 | int i; | 343 | int i; |
@@ -363,7 +350,7 @@ static void func_onstack (LexState *ls, FuncState *func) { | |||
363 | } | 350 | } |
364 | 351 | ||
365 | 352 | ||
366 | static void init_state (LexState *ls, FuncState *fs, TString *source) { | 353 | static void open_func (LexState *ls, FuncState *fs, TString *source) { |
367 | Proto *f = luaF_newproto(ls->L); | 354 | Proto *f = luaF_newproto(ls->L); |
368 | fs->prev = ls->fs; /* linked list of funcstates */ | 355 | fs->prev = ls->fs; /* linked list of funcstates */ |
369 | fs->ls = ls; | 356 | fs->ls = ls; |
@@ -410,13 +397,13 @@ Proto *luaY_parser (lua_State *L, ZIO *z) { | |||
410 | struct LexState lexstate; | 397 | struct LexState lexstate; |
411 | struct FuncState funcstate; | 398 | struct FuncState funcstate; |
412 | luaX_setinput(L, &lexstate, z); | 399 | luaX_setinput(L, &lexstate, z); |
413 | init_state(&lexstate, &funcstate, luaS_new(L, zname(z))); | 400 | open_func(&lexstate, &funcstate, luaS_new(L, zname(z))); |
414 | next(&lexstate); /* read first token */ | 401 | next(&lexstate); /* read first token */ |
415 | chunk(&lexstate); | 402 | chunk(&lexstate); |
416 | if (lexstate.t.token != TK_EOS) | 403 | check_condition(&lexstate, (lexstate.t.token == TK_EOS), "<eof> expected"); |
417 | luaK_error(&lexstate, "<eof> expected"); | ||
418 | close_func(&lexstate); | 404 | close_func(&lexstate); |
419 | LUA_ASSERT(L, funcstate.prev == NULL, "wrong list end"); | 405 | LUA_ASSERT(L, funcstate.prev == NULL, "wrong list end"); |
406 | LUA_ASSERT(L, funcstate.nupvalues == 0, "no upvalues in main"); | ||
420 | return funcstate.f; | 407 | return funcstate.f; |
421 | } | 408 | } |
422 | 409 | ||
@@ -443,28 +430,16 @@ static int explist1 (LexState *ls) { | |||
443 | } | 430 | } |
444 | 431 | ||
445 | 432 | ||
446 | static int explist (LexState *ls) { | ||
447 | /* explist -> [ explist1 ] */ | ||
448 | switch (ls->t.token) { | ||
449 | case TK_NUMBER: case TK_STRING: case TK_NIL: case '{': | ||
450 | case TK_FUNCTION: case '(': case TK_NAME: case '%': | ||
451 | case TK_NOT: case '-': /* first `expr' */ | ||
452 | return explist1(ls); | ||
453 | default: | ||
454 | return 0; /* empty list */ | ||
455 | } | ||
456 | } | ||
457 | |||
458 | |||
459 | static void funcargs (LexState *ls, int slf) { | 433 | static void funcargs (LexState *ls, int slf) { |
460 | FuncState *fs = ls->fs; | 434 | FuncState *fs = ls->fs; |
461 | int slevel = fs->stacklevel - slf - 1; /* where is func in the stack */ | 435 | int slevel = fs->stacklevel - slf - 1; /* where is func in the stack */ |
462 | switch (ls->t.token) { | 436 | switch (ls->t.token) { |
463 | case '(': { /* funcargs -> '(' explist ')' */ | 437 | case '(': { /* funcargs -> '(' [ explist1 ] ')' */ |
464 | int line = ls->linenumber; | 438 | int line = ls->linenumber; |
465 | int nargs; | 439 | int nargs = 0; |
466 | next(ls); | 440 | next(ls); |
467 | nargs = explist(ls); | 441 | if (ls->t.token != ')') /* arg list not empty? */ |
442 | nargs = explist1(ls); | ||
468 | check_match(ls, ')', '(', line); | 443 | check_match(ls, ')', '(', line); |
469 | #ifdef LUA_COMPAT_ARGRET | 444 | #ifdef LUA_COMPAT_ARGRET |
470 | if (nargs > 0) /* arg list is not empty? */ | 445 | if (nargs > 0) /* arg list is not empty? */ |
@@ -543,7 +518,7 @@ static void var_or_func (LexState *ls, expdesc *v) { | |||
543 | v->u.l.t = v->u.l.f = NO_JUMP; | 518 | v->u.l.t = v->u.l.f = NO_JUMP; |
544 | } | 519 | } |
545 | else /* variable name */ | 520 | else /* variable name */ |
546 | singlevar(ls, str_checkname(ls), v, 0); | 521 | singlevar(ls, str_checkname(ls), v); |
547 | var_or_func_tail(ls, v); | 522 | var_or_func_tail(ls, v); |
548 | } | 523 | } |
549 | 524 | ||
@@ -580,7 +555,6 @@ static int recfields (LexState *ls) { | |||
580 | /* recfields -> recfield { ',' recfield } [','] */ | 555 | /* recfields -> recfield { ',' recfield } [','] */ |
581 | FuncState *fs = ls->fs; | 556 | FuncState *fs = ls->fs; |
582 | int n = 1; /* at least one element */ | 557 | int n = 1; /* at least one element */ |
583 | int mod_n = 1; /* mod_n == n%RFIELDS_PER_FLUSH */ | ||
584 | recfield(ls); | 558 | recfield(ls); |
585 | while (ls->t.token == ',') { | 559 | while (ls->t.token == ',') { |
586 | next(ls); | 560 | next(ls); |
@@ -588,13 +562,10 @@ static int recfields (LexState *ls) { | |||
588 | break; | 562 | break; |
589 | recfield(ls); | 563 | recfield(ls); |
590 | n++; | 564 | n++; |
591 | if (++mod_n == RFIELDS_PER_FLUSH) { | 565 | if (n%RFIELDS_PER_FLUSH == 0) |
592 | luaK_code1(fs, OP_SETMAP, RFIELDS_PER_FLUSH-1); | 566 | luaK_code1(fs, OP_SETMAP, RFIELDS_PER_FLUSH); |
593 | mod_n = 0; | ||
594 | } | ||
595 | } | 567 | } |
596 | if (mod_n) | 568 | luaK_code1(fs, OP_SETMAP, n%RFIELDS_PER_FLUSH); |
597 | luaK_code1(fs, OP_SETMAP, mod_n-1); | ||
598 | return n; | 569 | return n; |
599 | } | 570 | } |
600 | 571 | ||
@@ -603,7 +574,6 @@ static int listfields (LexState *ls) { | |||
603 | /* listfields -> exp1 { ',' exp1 } [','] */ | 574 | /* listfields -> exp1 { ',' exp1 } [','] */ |
604 | FuncState *fs = ls->fs; | 575 | FuncState *fs = ls->fs; |
605 | int n = 1; /* at least one element */ | 576 | int n = 1; /* at least one element */ |
606 | int mod_n = 1; /* mod_n == n%LFIELDS_PER_FLUSH */ | ||
607 | exp1(ls); | 577 | exp1(ls); |
608 | while (ls->t.token == ',') { | 578 | while (ls->t.token == ',') { |
609 | next(ls); | 579 | next(ls); |
@@ -613,13 +583,10 @@ static int listfields (LexState *ls) { | |||
613 | n++; | 583 | n++; |
614 | luaX_checklimit(ls, n/LFIELDS_PER_FLUSH, MAXARG_A, | 584 | luaX_checklimit(ls, n/LFIELDS_PER_FLUSH, MAXARG_A, |
615 | "`item groups' in a list initializer"); | 585 | "`item groups' in a list initializer"); |
616 | if (++mod_n == LFIELDS_PER_FLUSH) { | 586 | if (n%LFIELDS_PER_FLUSH == 0) |
617 | luaK_code2(fs, OP_SETLIST, n/LFIELDS_PER_FLUSH - 1, LFIELDS_PER_FLUSH); | 587 | luaK_code2(fs, OP_SETLIST, n/LFIELDS_PER_FLUSH - 1, LFIELDS_PER_FLUSH); |
618 | mod_n = 0; | ||
619 | } | ||
620 | } | 588 | } |
621 | if (mod_n > 0) | 589 | luaK_code2(fs, OP_SETLIST, n/LFIELDS_PER_FLUSH, n%LFIELDS_PER_FLUSH); |
622 | luaK_code2(fs, OP_SETLIST, n/LFIELDS_PER_FLUSH, mod_n); | ||
623 | return n; | 590 | return n; |
624 | } | 591 | } |
625 | 592 | ||
@@ -663,18 +630,15 @@ static void constructor (LexState *ls) { | |||
663 | check(ls, '{'); | 630 | check(ls, '{'); |
664 | constructor_part(ls, &cd); | 631 | constructor_part(ls, &cd); |
665 | nelems = cd.n; | 632 | nelems = cd.n; |
666 | if (ls->t.token == ';') { | 633 | if (optional(ls, ';')) { |
667 | Constdesc other_cd; | 634 | Constdesc other_cd; |
668 | next(ls); | ||
669 | constructor_part(ls, &other_cd); | 635 | constructor_part(ls, &other_cd); |
670 | if (cd.k == other_cd.k) /* repeated parts? */ | 636 | check_condition(ls, (cd.k != other_cd.k), "invalid constructor syntax"); |
671 | luaK_error(ls, "invalid constructor syntax"); | ||
672 | nelems += other_cd.n; | 637 | nelems += other_cd.n; |
673 | } | 638 | } |
674 | check_match(ls, '}', '{', line); | 639 | check_match(ls, '}', '{', line); |
675 | /* set initial table size */ | ||
676 | luaX_checklimit(ls, nelems, MAXARG_U, "elements in a table constructor"); | 640 | luaX_checklimit(ls, nelems, MAXARG_U, "elements in a table constructor"); |
677 | SETARG_U(fs->f->code[pc], nelems); | 641 | SETARG_U(fs->f->code[pc], nelems); /* set initial table size */ |
678 | } | 642 | } |
679 | 643 | ||
680 | /* }====================================================================== */ | 644 | /* }====================================================================== */ |
@@ -811,6 +775,16 @@ static void expr (LexState *ls, expdesc *v) { | |||
811 | */ | 775 | */ |
812 | 776 | ||
813 | 777 | ||
778 | static int block_follow (int token) { | ||
779 | switch (token) { | ||
780 | case TK_ELSE: case TK_ELSEIF: case TK_END: | ||
781 | case TK_UNTIL: case TK_EOS: | ||
782 | return 1; | ||
783 | default: return 0; | ||
784 | } | ||
785 | } | ||
786 | |||
787 | |||
814 | static void block (LexState *ls) { | 788 | static void block (LexState *ls) { |
815 | /* block -> chunk */ | 789 | /* block -> chunk */ |
816 | FuncState *fs = ls->fs; | 790 | FuncState *fs = ls->fs; |
@@ -822,21 +796,18 @@ static void block (LexState *ls) { | |||
822 | 796 | ||
823 | 797 | ||
824 | static int assignment (LexState *ls, expdesc *v, int nvars) { | 798 | static int assignment (LexState *ls, expdesc *v, int nvars) { |
825 | int left = 0; | 799 | int left = 0; /* number of values left in the stack after assignment */ |
826 | luaX_checklimit(ls, nvars, MAXVARSLH, "variables in a multiple assignment"); | 800 | luaX_checklimit(ls, nvars, MAXVARSLH, "variables in a multiple assignment"); |
827 | if (ls->t.token == ',') { /* assignment -> ',' NAME assignment */ | 801 | if (ls->t.token == ',') { /* assignment -> ',' NAME assignment */ |
828 | expdesc nv; | 802 | expdesc nv; |
829 | next(ls); | 803 | next(ls); |
830 | var_or_func(ls, &nv); | 804 | var_or_func(ls, &nv); |
831 | if (nv.k == VEXP) | 805 | check_condition(ls, (nv.k != VEXP), "syntax error"); |
832 | luaK_error(ls, "syntax error"); | ||
833 | left = assignment(ls, &nv, nvars+1); | 806 | left = assignment(ls, &nv, nvars+1); |
834 | } | 807 | } |
835 | else { /* assignment -> '=' explist1 */ | 808 | else { /* assignment -> '=' explist1 */ |
836 | int nexps;; | 809 | int nexps; |
837 | if (ls->t.token != '=') | 810 | check(ls, '='); |
838 | error_unexpected(ls); | ||
839 | next(ls); | ||
840 | nexps = explist1(ls); | 811 | nexps = explist1(ls); |
841 | adjust_mult_assign(ls, nvars, nexps); | 812 | adjust_mult_assign(ls, nvars, nexps); |
842 | } | 813 | } |
@@ -850,16 +821,22 @@ static int assignment (LexState *ls, expdesc *v, int nvars) { | |||
850 | } | 821 | } |
851 | 822 | ||
852 | 823 | ||
824 | static void cond (LexState *ls, expdesc *v) { | ||
825 | /* cond -> exp */ | ||
826 | expr(ls, v); /* read condition */ | ||
827 | luaK_goiftrue(ls->fs, v, 0); | ||
828 | } | ||
829 | |||
830 | |||
853 | static void whilestat (LexState *ls, int line) { | 831 | static void whilestat (LexState *ls, int line) { |
854 | /* whilestat -> WHILE exp1 DO block END */ | 832 | /* whilestat -> WHILE cond DO block END */ |
855 | FuncState *fs = ls->fs; | 833 | FuncState *fs = ls->fs; |
856 | int while_init = luaK_getlabel(fs); | 834 | int while_init = luaK_getlabel(fs); |
857 | expdesc v; | 835 | expdesc v; |
858 | Breaklabel bl; | 836 | Breaklabel bl; |
859 | enterbreak(fs, &bl); | 837 | enterbreak(fs, &bl); |
860 | setline_and_next(ls); /* trace WHILE when looping */ | 838 | setline_and_next(ls); /* trace WHILE when looping */ |
861 | expr(ls, &v); /* read condition */ | 839 | cond(ls, &v); |
862 | luaK_goiftrue(fs, &v, 0); | ||
863 | check(ls, TK_DO); | 840 | check(ls, TK_DO); |
864 | block(ls); | 841 | block(ls); |
865 | luaK_patchlist(fs, luaK_jump(fs), while_init); | 842 | luaK_patchlist(fs, luaK_jump(fs), while_init); |
@@ -870,7 +847,7 @@ static void whilestat (LexState *ls, int line) { | |||
870 | 847 | ||
871 | 848 | ||
872 | static void repeatstat (LexState *ls, int line) { | 849 | static void repeatstat (LexState *ls, int line) { |
873 | /* repeatstat -> REPEAT block UNTIL exp1 */ | 850 | /* repeatstat -> REPEAT block UNTIL cond */ |
874 | FuncState *fs = ls->fs; | 851 | FuncState *fs = ls->fs; |
875 | int repeat_init = luaK_getlabel(fs); | 852 | int repeat_init = luaK_getlabel(fs); |
876 | expdesc v; | 853 | expdesc v; |
@@ -879,14 +856,14 @@ static void repeatstat (LexState *ls, int line) { | |||
879 | setline_and_next(ls); /* trace REPEAT when looping */ | 856 | setline_and_next(ls); /* trace REPEAT when looping */ |
880 | block(ls); | 857 | block(ls); |
881 | check_match(ls, TK_UNTIL, TK_REPEAT, line); | 858 | check_match(ls, TK_UNTIL, TK_REPEAT, line); |
882 | expr(ls, &v); | 859 | cond(ls, &v); |
883 | luaK_goiftrue(fs, &v, 0); | ||
884 | luaK_patchlist(fs, v.u.l.f, repeat_init); | 860 | luaK_patchlist(fs, v.u.l.f, repeat_init); |
885 | leavebreak(fs, &bl); | 861 | leavebreak(fs, &bl); |
886 | } | 862 | } |
887 | 863 | ||
888 | 864 | ||
889 | static void forbody (LexState *ls, OpCode prepfor, OpCode loopfor) { | 865 | static void forbody (LexState *ls, OpCode prepfor, OpCode loopfor) { |
866 | /* forbody -> DO block END */ | ||
890 | FuncState *fs = ls->fs; | 867 | FuncState *fs = ls->fs; |
891 | int prep = luaK_code1(fs, prepfor, NO_JUMP); | 868 | int prep = luaK_code1(fs, prepfor, NO_JUMP); |
892 | int blockinit = luaK_getlabel(fs); | 869 | int blockinit = luaK_getlabel(fs); |
@@ -898,6 +875,7 @@ static void forbody (LexState *ls, OpCode prepfor, OpCode loopfor) { | |||
898 | 875 | ||
899 | 876 | ||
900 | static void fornum (LexState *ls, TString *varname) { | 877 | static void fornum (LexState *ls, TString *varname) { |
878 | /* fornum -> NAME = exp1,exp1[,exp1] forbody */ | ||
901 | FuncState *fs = ls->fs; | 879 | FuncState *fs = ls->fs; |
902 | store_localvar(ls, varname, 0); | 880 | store_localvar(ls, varname, 0); |
903 | check(ls, '='); | 881 | check(ls, '='); |
@@ -910,19 +888,21 @@ static void fornum (LexState *ls, TString *varname) { | |||
910 | luaK_code1(fs, OP_PUSHINT, 1); /* default step */ | 888 | luaK_code1(fs, OP_PUSHINT, 1); /* default step */ |
911 | adjustlocalvars(ls, 1); /* scope for control variables */ | 889 | adjustlocalvars(ls, 1); /* scope for control variables */ |
912 | add_localvar(ls, "*limit*"); | 890 | add_localvar(ls, "*limit*"); |
913 | add_localvar(ls, "*step*"); | 891 | add_localvar(ls, "*count*"); |
914 | forbody(ls, OP_FORPREP, OP_FORLOOP); | 892 | forbody(ls, OP_FORPREP, OP_FORLOOP); |
915 | removelocalvars(ls, 3); | 893 | removelocalvars(ls, 3); |
916 | } | 894 | } |
917 | 895 | ||
918 | 896 | ||
919 | static void forlist (LexState *ls, TString *indexname) { | 897 | static void forlist (LexState *ls, TString *indexname) { |
898 | /* forlist -> NAME,NAME IN exp1 forbody */ | ||
920 | TString *valname; | 899 | TString *valname; |
921 | check(ls, ','); | 900 | check(ls, ','); |
922 | valname = str_checkname(ls); | 901 | valname = str_checkname(ls); |
923 | /* next test is dirty, but avoids `in' being a reserved word */ | 902 | /* next test is dirty, but avoids `in' being a reserved word */ |
924 | if (ls->t.token != TK_NAME || ls->t.seminfo.ts != luaS_new(ls->L, "in")) | 903 | check_condition(ls, |
925 | luaK_error(ls, "`in' expected"); | 904 | (ls->t.token == TK_NAME && ls->t.seminfo.ts == luaS_new(ls->L, "in")), |
905 | "`in' expected"); | ||
926 | next(ls); /* skip `in' */ | 906 | next(ls); /* skip `in' */ |
927 | exp1(ls); /* table */ | 907 | exp1(ls); /* table */ |
928 | add_localvar(ls, "*table*"); | 908 | add_localvar(ls, "*table*"); |
@@ -936,8 +916,7 @@ static void forlist (LexState *ls, TString *indexname) { | |||
936 | 916 | ||
937 | 917 | ||
938 | static void forstat (LexState *ls, int line) { | 918 | static void forstat (LexState *ls, int line) { |
939 | /* forstat -> FOR NAME '=' expr1 ',' expr1 [',' expr1] DO block END */ | 919 | /* forstat -> fornum | forlist */ |
940 | /* forstat -> FOR NAME1, NAME2 IN expr1 DO block END */ | ||
941 | FuncState *fs = ls->fs; | 920 | FuncState *fs = ls->fs; |
942 | TString *varname; | 921 | TString *varname; |
943 | Breaklabel bl; | 922 | Breaklabel bl; |
@@ -954,11 +933,10 @@ static void forstat (LexState *ls, int line) { | |||
954 | } | 933 | } |
955 | 934 | ||
956 | 935 | ||
957 | static void test_and_block (LexState *ls, expdesc *v) { | 936 | static void test_then_block (LexState *ls, expdesc *v) { |
958 | /* test_and_block -> [IF | ELSEIF] cond THEN block */ | 937 | /* test_then_block -> [IF | ELSEIF] cond THEN block */ |
959 | setline_and_next(ls); /* skip IF or ELSEIF */ | 938 | setline_and_next(ls); /* skip IF or ELSEIF */ |
960 | expr(ls, v); /* cond */ | 939 | cond(ls, v); |
961 | luaK_goiftrue(ls->fs, v, 0); | ||
962 | setline(ls); /* to trace the THEN */ | 940 | setline(ls); /* to trace the THEN */ |
963 | check(ls, TK_THEN); | 941 | check(ls, TK_THEN); |
964 | block(ls); /* `then' part */ | 942 | block(ls); /* `then' part */ |
@@ -970,11 +948,11 @@ static void ifstat (LexState *ls, int line) { | |||
970 | FuncState *fs = ls->fs; | 948 | FuncState *fs = ls->fs; |
971 | expdesc v; | 949 | expdesc v; |
972 | int escapelist = NO_JUMP; | 950 | int escapelist = NO_JUMP; |
973 | test_and_block(ls, &v); /* IF cond THEN block */ | 951 | test_then_block(ls, &v); /* IF cond THEN block */ |
974 | while (ls->t.token == TK_ELSEIF) { | 952 | while (ls->t.token == TK_ELSEIF) { |
975 | luaK_concat(fs, &escapelist, luaK_jump(fs)); | 953 | luaK_concat(fs, &escapelist, luaK_jump(fs)); |
976 | luaK_patchlist(fs, v.u.l.f, luaK_getlabel(fs)); | 954 | luaK_patchlist(fs, v.u.l.f, luaK_getlabel(fs)); |
977 | test_and_block(ls, &v); /* ELSEIF cond THEN block */ | 955 | test_then_block(ls, &v); /* ELSEIF cond THEN block */ |
978 | } | 956 | } |
979 | if (ls->t.token == TK_ELSE) { | 957 | if (ls->t.token == TK_ELSE) { |
980 | luaK_concat(fs, &escapelist, luaK_jump(fs)); | 958 | luaK_concat(fs, &escapelist, luaK_jump(fs)); |
@@ -989,36 +967,18 @@ static void ifstat (LexState *ls, int line) { | |||
989 | } | 967 | } |
990 | 968 | ||
991 | 969 | ||
992 | static int localnamelist (LexState *ls) { | ||
993 | /* localnamelist -> NAME {',' NAME} */ | ||
994 | int i = 1; | ||
995 | store_localvar(ls, str_checkname(ls), 0); | ||
996 | while (ls->t.token == ',') { | ||
997 | next(ls); | ||
998 | store_localvar(ls, str_checkname(ls), i++); | ||
999 | } | ||
1000 | return i; | ||
1001 | } | ||
1002 | |||
1003 | |||
1004 | static int decinit (LexState *ls) { | ||
1005 | /* decinit -> ['=' explist1] */ | ||
1006 | if (ls->t.token == '=') { | ||
1007 | next(ls); | ||
1008 | return explist1(ls); | ||
1009 | } | ||
1010 | else | ||
1011 | return 0; /* no initializations */ | ||
1012 | } | ||
1013 | |||
1014 | |||
1015 | static void localstat (LexState *ls) { | 970 | static void localstat (LexState *ls) { |
1016 | /* stat -> LOCAL localnamelist decinit */ | 971 | /* stat -> LOCAL NAME {',' NAME} ['=' explist1] */ |
1017 | int nvars; | 972 | int nvars = 0; |
1018 | int nexps; | 973 | int nexps; |
1019 | setline_and_next(ls); /* skip LOCAL */ | 974 | do { |
1020 | nvars = localnamelist(ls); | 975 | setline_and_next(ls); /* skip LOCAL or ',' */ |
1021 | nexps = decinit(ls); | 976 | store_localvar(ls, str_checkname(ls), nvars++); |
977 | } while (ls->t.token == ','); | ||
978 | if (optional(ls, '=')) | ||
979 | nexps = explist1(ls); | ||
980 | else | ||
981 | nexps = 0; | ||
1022 | adjustlocalvars(ls, nvars); | 982 | adjustlocalvars(ls, nvars); |
1023 | adjust_mult_assign(ls, nvars, nexps); | 983 | adjust_mult_assign(ls, nvars, nexps); |
1024 | } | 984 | } |
@@ -1027,7 +987,7 @@ static void localstat (LexState *ls) { | |||
1027 | static int funcname (LexState *ls, expdesc *v) { | 987 | static int funcname (LexState *ls, expdesc *v) { |
1028 | /* funcname -> NAME [':' NAME | '.' NAME] */ | 988 | /* funcname -> NAME [':' NAME | '.' NAME] */ |
1029 | int needself = 0; | 989 | int needself = 0; |
1030 | singlevar(ls, str_checkname(ls), v, 0); | 990 | singlevar(ls, str_checkname(ls), v); |
1031 | if (ls->t.token == ':' || ls->t.token == '.') { | 991 | if (ls->t.token == ':' || ls->t.token == '.') { |
1032 | needself = (ls->t.token == ':'); | 992 | needself = (ls->t.token == ':'); |
1033 | next(ls); | 993 | next(ls); |
@@ -1043,8 +1003,8 @@ static void funcstat (LexState *ls, int line) { | |||
1043 | /* funcstat -> FUNCTION funcname body */ | 1003 | /* funcstat -> FUNCTION funcname body */ |
1044 | int needself; | 1004 | int needself; |
1045 | expdesc v; | 1005 | expdesc v; |
1046 | if (ls->fs->prev) /* inside other function? */ | 1006 | check_condition(ls, (ls->fs->prev == NULL), |
1047 | luaK_error(ls, "cannot nest this kind of function declaration"); | 1007 | "cannot nest this kind of function declaration"); |
1048 | setline_and_next(ls); /* skip FUNCTION */ | 1008 | setline_and_next(ls); /* skip FUNCTION */ |
1049 | needself = funcname(ls, &v); | 1009 | needself = funcname(ls, &v); |
1050 | body(ls, needself, line); | 1010 | body(ls, needself, line); |
@@ -1059,8 +1019,7 @@ static void namestat (LexState *ls) { | |||
1059 | setline(ls); | 1019 | setline(ls); |
1060 | var_or_func(ls, &v); | 1020 | var_or_func(ls, &v); |
1061 | if (v.k == VEXP) { /* stat -> func */ | 1021 | if (v.k == VEXP) { /* stat -> func */ |
1062 | if (!luaK_lastisopen(fs)) /* is just an upvalue? */ | 1022 | check_condition(ls, luaK_lastisopen(fs), "syntax error"); /* an upvalue? */ |
1063 | luaK_error(ls, "syntax error"); | ||
1064 | luaK_setcallreturns(fs, 0); /* call statement uses no results */ | 1023 | luaK_setcallreturns(fs, 0); /* call statement uses no results */ |
1065 | } | 1024 | } |
1066 | else { /* stat -> ['%'] NAME assignment */ | 1025 | else { /* stat -> ['%'] NAME assignment */ |
@@ -1074,7 +1033,8 @@ static void retstat (LexState *ls) { | |||
1074 | /* stat -> RETURN explist */ | 1033 | /* stat -> RETURN explist */ |
1075 | FuncState *fs = ls->fs; | 1034 | FuncState *fs = ls->fs; |
1076 | setline_and_next(ls); /* skip RETURN */ | 1035 | setline_and_next(ls); /* skip RETURN */ |
1077 | explist(ls); | 1036 | if (!block_follow(ls->t.token)) |
1037 | explist1(ls); /* optional return values */ | ||
1078 | luaK_code1(fs, OP_RETURN, ls->fs->nlocalvar); | 1038 | luaK_code1(fs, OP_RETURN, ls->fs->nlocalvar); |
1079 | fs->stacklevel = fs->nlocalvar; /* removes all temp values */ | 1039 | fs->stacklevel = fs->nlocalvar; /* removes all temp values */ |
1080 | } | 1040 | } |
@@ -1086,7 +1046,7 @@ static void breakstat (LexState *ls) { | |||
1086 | Breaklabel *bl; | 1046 | Breaklabel *bl; |
1087 | int currentlevel = fs->stacklevel; | 1047 | int currentlevel = fs->stacklevel; |
1088 | setline_and_next(ls); /* skip BREAK */ | 1048 | setline_and_next(ls); /* skip BREAK */ |
1089 | bl = findlabel(fs, optionalname(ls)); | 1049 | bl = findlabel(ls); |
1090 | luaK_adjuststack(fs, currentlevel - bl->stacklevel); | 1050 | luaK_adjuststack(fs, currentlevel - bl->stacklevel); |
1091 | luaK_concat(fs, &bl->breaklist, luaK_jump(fs)); | 1051 | luaK_concat(fs, &bl->breaklist, luaK_jump(fs)); |
1092 | fs->stacklevel = currentlevel; | 1052 | fs->stacklevel = currentlevel; |
@@ -1098,66 +1058,48 @@ static int stat (LexState *ls) { | |||
1098 | switch (ls->t.token) { | 1058 | switch (ls->t.token) { |
1099 | case TK_IF: { /* stat -> ifstat */ | 1059 | case TK_IF: { /* stat -> ifstat */ |
1100 | ifstat(ls, line); | 1060 | ifstat(ls, line); |
1101 | return 1; | 1061 | return 0; |
1102 | } | 1062 | } |
1103 | case TK_WHILE: { /* stat -> whilestat */ | 1063 | case TK_WHILE: { /* stat -> whilestat */ |
1104 | whilestat(ls, line); | 1064 | whilestat(ls, line); |
1105 | return 1; | 1065 | return 0; |
1106 | } | 1066 | } |
1107 | case TK_DO: { /* stat -> DO block END */ | 1067 | case TK_DO: { /* stat -> DO block END */ |
1108 | setline_and_next(ls); /* skip DO */ | 1068 | setline_and_next(ls); /* skip DO */ |
1109 | block(ls); | 1069 | block(ls); |
1110 | check_END(ls, TK_DO, line); | 1070 | check_END(ls, TK_DO, line); |
1111 | return 1; | 1071 | return 0; |
1112 | } | 1072 | } |
1113 | case TK_FOR: { /* stat -> forstat */ | 1073 | case TK_FOR: { /* stat -> forstat */ |
1114 | forstat(ls, line); | 1074 | forstat(ls, line); |
1115 | return 1; | 1075 | return 0; |
1116 | } | 1076 | } |
1117 | case TK_REPEAT: { /* stat -> repeatstat */ | 1077 | case TK_REPEAT: { /* stat -> repeatstat */ |
1118 | repeatstat(ls, line); | 1078 | repeatstat(ls, line); |
1119 | return 1; | 1079 | return 0; |
1120 | } | 1080 | } |
1121 | case TK_FUNCTION: { /* stat -> funcstat */ | 1081 | case TK_FUNCTION: { /* stat -> funcstat */ |
1122 | funcstat(ls, line); | 1082 | funcstat(ls, line); |
1123 | return 1; | 1083 | return 0; |
1124 | } | 1084 | } |
1125 | case TK_LOCAL: { /* stat -> localstat */ | 1085 | case TK_LOCAL: { /* stat -> localstat */ |
1126 | localstat(ls); | 1086 | localstat(ls); |
1127 | return 1; | 1087 | return 0; |
1128 | } | 1088 | } |
1129 | case TK_NAME: case '%': { /* stat -> namestat */ | 1089 | case TK_NAME: case '%': { /* stat -> namestat */ |
1130 | namestat(ls); | 1090 | namestat(ls); |
1131 | return 1; | 1091 | return 0; |
1132 | } | 1092 | } |
1133 | case TK_RETURN: { /* stat -> retstat */ | 1093 | case TK_RETURN: { /* stat -> retstat */ |
1134 | retstat(ls); | 1094 | retstat(ls); |
1135 | return 2; /* must be last statement */ | 1095 | return 1; /* must be last statement */ |
1136 | } | 1096 | } |
1137 | case TK_BREAK: { /* stat -> breakstat */ | 1097 | case TK_BREAK: { /* stat -> breakstat */ |
1138 | breakstat(ls); | 1098 | breakstat(ls); |
1139 | return 2; /* must be last statement */ | 1099 | return 1; /* must be last statement */ |
1140 | } | 1100 | } |
1141 | default: { | 1101 | default: { |
1142 | return 0; /* no statement */ | 1102 | luaK_error(ls, "<statement> expected"); |
1143 | } | ||
1144 | } | ||
1145 | } | ||
1146 | |||
1147 | |||
1148 | static int param (LexState *ls, int n) { | ||
1149 | /* param -> NAME | DOTS */ | ||
1150 | switch (ls->t.token) { | ||
1151 | case TK_DOTS: { | ||
1152 | next(ls); | ||
1153 | return 1; | ||
1154 | } | ||
1155 | case TK_NAME: { | ||
1156 | store_localvar(ls, str_checkname(ls), n); | ||
1157 | return 0; | ||
1158 | } | ||
1159 | default: { | ||
1160 | luaK_error(ls, "<name> or `...' expected"); | ||
1161 | return 0; /* to avoid warnings */ | 1103 | return 0; /* to avoid warnings */ |
1162 | } | 1104 | } |
1163 | } | 1105 | } |
@@ -1169,22 +1111,22 @@ static void parlist (LexState *ls) { | |||
1169 | int nparams = 0; | 1111 | int nparams = 0; |
1170 | int dots = 0; | 1112 | int dots = 0; |
1171 | if (ls->t.token != ')') { /* is `parlist' not empty? */ | 1113 | if (ls->t.token != ')') { /* is `parlist' not empty? */ |
1172 | dots = param(ls, nparams); | 1114 | do { |
1173 | nparams++; | 1115 | switch (ls->t.token) { |
1174 | while (ls->t.token == ',' && !dots) { | 1116 | case TK_DOTS: next(ls); dots = 1; break; |
1175 | next(ls); | 1117 | case TK_NAME: store_localvar(ls, str_checkname(ls), nparams++); break; |
1176 | dots = param(ls, nparams); | 1118 | default: luaK_error(ls, "<name> or `...' expected"); |
1177 | nparams++; | 1119 | } |
1178 | } | 1120 | } while (!dots && optional(ls, ',')); |
1179 | } | 1121 | } |
1180 | code_args(ls, nparams, dots); | 1122 | code_params(ls, nparams, dots); |
1181 | } | 1123 | } |
1182 | 1124 | ||
1183 | 1125 | ||
1184 | static void body (LexState *ls, int needself, int line) { | 1126 | static void body (LexState *ls, int needself, int line) { |
1185 | /* body -> '(' parlist ')' chunk END */ | 1127 | /* body -> '(' parlist ')' chunk END */ |
1186 | FuncState new_fs; | 1128 | FuncState new_fs; |
1187 | init_state(ls, &new_fs, ls->fs->f->source); | 1129 | open_func(ls, &new_fs, ls->fs->f->source); |
1188 | new_fs.f->lineDefined = line; | 1130 | new_fs.f->lineDefined = line; |
1189 | check(ls, '('); | 1131 | check(ls, '('); |
1190 | if (needself) | 1132 | if (needself) |
@@ -1194,40 +1136,40 @@ static void body (LexState *ls, int needself, int line) { | |||
1194 | chunk(ls); | 1136 | chunk(ls); |
1195 | check_END(ls, TK_FUNCTION, line); | 1137 | check_END(ls, TK_FUNCTION, line); |
1196 | close_func(ls); | 1138 | close_func(ls); |
1197 | func_onstack(ls, &new_fs); | 1139 | pushclosure(ls, &new_fs); |
1198 | } | 1140 | } |
1199 | 1141 | ||
1200 | 1142 | ||
1201 | /* }====================================================================== */ | 1143 | /* }====================================================================== */ |
1202 | 1144 | ||
1203 | 1145 | ||
1204 | static void label (LexState *ls, Breaklabel *bl) { | 1146 | static TString *optional_label (LexState *ls) { |
1205 | /* label -> [ '|' NAME '|' ] */ | 1147 | /* label -> [ '|' NAME '|' ] */ |
1206 | if (optional(ls, '|')) { | 1148 | if (optional(ls, '|')) { |
1207 | enterbreak(ls->fs, bl); | 1149 | TString *l = str_checkname(ls); |
1208 | bl->label = str_checkname(ls); | ||
1209 | check(ls, '|'); | 1150 | check(ls, '|'); |
1151 | return l; | ||
1210 | } | 1152 | } |
1211 | else | 1153 | else |
1212 | bl->label = NULL; /* there is no label */ | 1154 | return NULL; /* there is no label */ |
1213 | } | 1155 | } |
1214 | 1156 | ||
1215 | 1157 | ||
1216 | static void chunk (LexState *ls) { | 1158 | static void chunk (LexState *ls) { |
1217 | /* chunk -> { [label] stat [';'] } */ | 1159 | /* chunk -> { [label] stat [';'] } */ |
1218 | Breaklabel bl; | 1160 | int islast = 0; |
1219 | int a; | 1161 | while (!islast && !block_follow(ls->t.token)) { |
1220 | do { | 1162 | Breaklabel bl; |
1221 | label(ls, &bl); | 1163 | TString *l = optional_label(ls); |
1222 | a = stat(ls); | 1164 | if (l) { |
1223 | if (a != 0) | 1165 | enterbreak(ls->fs, &bl); |
1224 | optional(ls, ';'); | 1166 | bl.label = l; |
1225 | else if (bl.label) | 1167 | } |
1226 | luaK_error(ls, "label without a statement"); | 1168 | islast = stat(ls); |
1169 | optional(ls, ';'); | ||
1227 | LUA_ASSERT(ls->L, ls->fs->stacklevel == ls->fs->nlocalvar, | 1170 | LUA_ASSERT(ls->L, ls->fs->stacklevel == ls->fs->nlocalvar, |
1228 | "stack size != # local vars"); | 1171 | "stack size != # local vars"); |
1229 | if (bl.label) | 1172 | if (l) leavebreak(ls->fs, &bl); |
1230 | leavebreak(ls->fs, &bl); | 1173 | } |
1231 | } while (a == 1); | ||
1232 | } | 1174 | } |
1233 | 1175 | ||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lvm.c,v 1.109 2000/05/25 19:02:21 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 1.110 2000/05/30 19:00:31 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 | */ |
@@ -483,13 +483,13 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { | |||
483 | 483 | ||
484 | case OP_SETMAP: { | 484 | case OP_SETMAP: { |
485 | int n = GETARG_U(i); | 485 | int n = GETARG_U(i); |
486 | StkId finaltop = top-2*(n+1); | 486 | StkId finaltop = top-2*n; |
487 | Hash *arr = avalue(finaltop-1); | 487 | Hash *arr = avalue(finaltop-1); |
488 | L->top = finaltop; /* final value of `top' (in case of errors) */ | 488 | L->top = finaltop; /* final value of `top' (in case of errors) */ |
489 | do { | 489 | for (; n; n--) { |
490 | luaH_set(L, arr, top-2, top-1); | 490 | luaH_set(L, arr, top-2, top-1); |
491 | top-=2; | 491 | top-=2; |
492 | } while (n--); | 492 | } |
493 | break; | 493 | break; |
494 | } | 494 | } |
495 | 495 | ||
@@ -625,23 +625,22 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { | |||
625 | lua_error(L, "`for' limit must be a number"); | 625 | lua_error(L, "`for' limit must be a number"); |
626 | if (tonumber(top-3)) | 626 | if (tonumber(top-3)) |
627 | lua_error(L, "`for' initial value must be a number"); | 627 | lua_error(L, "`for' initial value must be a number"); |
628 | /* number of steps */ | ||
629 | nvalue(top-2) = (nvalue(top-2)-nvalue(top-3))/nvalue(top-1); | ||
628 | nvalue(top-3) -= nvalue(top-1); /* to be undone by first FORLOOP */ | 630 | nvalue(top-3) -= nvalue(top-1); /* to be undone by first FORLOOP */ |
629 | pc += GETARG_S(i); | 631 | pc += GETARG_S(i); |
630 | break; | 632 | break; |
631 | 633 | ||
632 | case OP_FORLOOP: { | 634 | case OP_FORLOOP: { |
633 | Number step = nvalue(top-1); | ||
634 | Number limit = nvalue(top-2); | ||
635 | Number index; | ||
636 | LUA_ASSERT(L, ttype(top-1) == TAG_NUMBER, "invalid step"); | 635 | LUA_ASSERT(L, ttype(top-1) == TAG_NUMBER, "invalid step"); |
637 | LUA_ASSERT(L, ttype(top-2) == TAG_NUMBER, "invalid limit"); | 636 | LUA_ASSERT(L, ttype(top-2) == TAG_NUMBER, "invalid count"); |
638 | if (ttype(top-3) != TAG_NUMBER) | 637 | if (nvalue(top-2) < 0) |
639 | lua_error(L, "`for' index must be a number"); | ||
640 | index = nvalue(top-3)+step; | ||
641 | if ((step>0) ? index>limit : index<limit) | ||
642 | top -= 3; /* end loop: remove control variables */ | 638 | top -= 3; /* end loop: remove control variables */ |
643 | else { | 639 | else { |
644 | nvalue(top-3) = index; | 640 | nvalue(top-2)--; /* decrement count */ |
641 | if (ttype(top-3) != TAG_NUMBER) | ||
642 | lua_error(L, "`for' index must be a number"); | ||
643 | nvalue(top-3) += nvalue(top-1); /* increment index */ | ||
645 | pc += GETARG_S(i); | 644 | pc += GETARG_S(i); |
646 | } | 645 | } |
647 | break; | 646 | break; |