diff options
author | Richard Quirk <richard.quirk@gmail.com> | 2014-03-19 19:31:31 +0100 |
---|---|---|
committer | Marcin Bukat <marcin.bukat@gmail.com> | 2014-04-02 20:31:54 +0200 |
commit | 36378988ad4059982742f05f5eb50580b456840a (patch) | |
tree | ee70be810d894566c5e351f21a1ebb79be742a85 /apps/plugins/lua/lparser.c | |
parent | 020f16a1c7d5bc9a302671cef03f56ac735e20c5 (diff) | |
download | rockbox-36378988ad4059982742f05f5eb50580b456840a.tar.gz rockbox-36378988ad4059982742f05f5eb50580b456840a.zip |
Update lua plugin to 5.2.3
Prior to this patch the Lua plugin used version 5.1.4. This change
reduces the number of modifications in the Lua source using some new
defines and because the upstream source is now more flexible.
Unless otherwise stated, l*.[ch] files are taken unmodified from the
upstream lua-5.2.3.
fscanf.c:
file descriptors in rockbox are just ints, they are hidden behind a
void* now so liolib requires less modifications. fscanf is updated to
use void* too.
getc.c: this is a new file required for getc implementation in lauxlib.c
lauxlib.c: LoadF replaced FILE* with int, the rockbox file
descriptor int are cast to FILE* (actually void* due to typedef).
getc uses the PREFIX version. stdin is not used, as per 5.1.4.
lbaselib.c: now uses strspn in the number parsing. print uses DEBUGF now
rather than being commented out.
lbitlib.c: use the built-in version from 5.2.3 rather than Reuben
Thomas's external library. Backwards compatible and adds some new bit
operations.
ldo.c: the LUAI_THROW/TRY defines are now in the core lua code, so have
been removed from rockconf.h
liolib.c: here the implementation has changed to use the LStream from
the original source, and cast the FILE* pointers to int. This has
reduced the number of modifications from the upstream version.
llex.c: the only change from upstream is to remove the locale include.
lmathlib.c: updated from the 5.2.3 version and re-applied the changes
that were made vs 5.1.4 for random numbers and to remove unsupported
float functions.
loadlib.c: upstream version, with the 5.1.4 changes for missing
functions.
lobject.c: upstream version, with ctype.h added and sprintf changed to
snprintf.
loslib.c: upstream version with locale.h removed and 5.1.4 changes for
unsupportable functions.
lstrlib.c: sprintf changed to snprintf.
ltable.c: upstream with the hashnum function from 5.1.4 to avoid frexp
in luai_hashnum.
luaconf.h: updated to 5.2.3 version, restored relevant parts from the
original 5.1.4 configuration. The COMPAT defines that are no longer
available are not included.
lundump.c: VERSION macro conflicts with the core Rockbox equivalent.
rocklib.c: luaL_reg is no longer available, replaced by luaL_Reg
equivalent. Moved checkboolean/optboolean functions to this file and out
of core lua files. luaL_getn is no longer available, replaced by
luaL_rawlen. luaL_register is deprecated, use the newlib/setfuncs
replacements. rli_init has to be called before setting up the newlib to
avoid overwriting the rb table.
rocklib_aux.pl: use rli_checkboolean from rocklib.c.
rocklua.c: new default bits library used, update the library loading
code with idiomatic 5.2 code.
strcspn.c: no longer needed, but strspn.c is required for strspn in
lbaselib.c
Change-Id: I0c7945c755f79083afe98ec117e1e8cf13de2651
Reviewed-on: http://gerrit.rockbox.org/774
Tested: Richard Quirk <richard.quirk@gmail.com>
Reviewed-by: Marcin Bukat <marcin.bukat@gmail.com>
Diffstat (limited to 'apps/plugins/lua/lparser.c')
-rw-r--r-- | apps/plugins/lua/lparser.c | 1015 |
1 files changed, 657 insertions, 358 deletions
diff --git a/apps/plugins/lua/lparser.c b/apps/plugins/lua/lparser.c index 800cdb1a3b..9e1a9ca2cf 100644 --- a/apps/plugins/lua/lparser.c +++ b/apps/plugins/lua/lparser.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lparser.c,v 2.42.1.3 2007/12/28 15:32:23 roberto Exp $ | 2 | ** $Id: lparser.c,v 2.130.1.1 2013/04/12 18:48:47 roberto Exp $ |
3 | ** Lua Parser | 3 | ** Lua Parser |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -27,11 +27,13 @@ | |||
27 | 27 | ||
28 | 28 | ||
29 | 29 | ||
30 | #define hasmultret(k) ((k) == VCALL || (k) == VVARARG) | 30 | /* maximum number of local variables per function (must be smaller |
31 | than 250, due to the bytecode format) */ | ||
32 | #define MAXVARS 200 | ||
33 | |||
31 | 34 | ||
32 | #define getlocvar(fs, i) ((fs)->f->locvars[(fs)->actvar[i]]) | 35 | #define hasmultret(k) ((k) == VCALL || (k) == VVARARG) |
33 | 36 | ||
34 | #define luaY_checklimit(fs,v,l,m) if ((v)>(l)) errorlimit(fs,l,m) | ||
35 | 37 | ||
36 | 38 | ||
37 | /* | 39 | /* |
@@ -39,10 +41,11 @@ | |||
39 | */ | 41 | */ |
40 | typedef struct BlockCnt { | 42 | typedef struct BlockCnt { |
41 | struct BlockCnt *previous; /* chain */ | 43 | struct BlockCnt *previous; /* chain */ |
42 | int breaklist; /* list of jumps out of this loop */ | 44 | short firstlabel; /* index of first label in this block */ |
43 | lu_byte nactvar; /* # active locals outside the breakable structure */ | 45 | short firstgoto; /* index of first pending goto in this block */ |
46 | lu_byte nactvar; /* # active locals outside the block */ | ||
44 | lu_byte upval; /* true if some variable in the block is an upvalue */ | 47 | lu_byte upval; /* true if some variable in the block is an upvalue */ |
45 | lu_byte isbreakable; /* true if `block' is a loop */ | 48 | lu_byte isloop; /* true if `block' is a loop */ |
46 | } BlockCnt; | 49 | } BlockCnt; |
47 | 50 | ||
48 | 51 | ||
@@ -50,11 +53,13 @@ typedef struct BlockCnt { | |||
50 | /* | 53 | /* |
51 | ** prototypes for recursive non-terminal functions | 54 | ** prototypes for recursive non-terminal functions |
52 | */ | 55 | */ |
53 | static void chunk (LexState *ls); | 56 | static void statement (LexState *ls); |
54 | static void expr (LexState *ls, expdesc *v); | 57 | static void expr (LexState *ls, expdesc *v); |
55 | 58 | ||
56 | 59 | ||
57 | static void anchor_token (LexState *ls) { | 60 | static void anchor_token (LexState *ls) { |
61 | /* last token from outer function must be EOS */ | ||
62 | lua_assert(ls->fs != NULL || ls->t.token == TK_EOS); | ||
58 | if (ls->t.token == TK_NAME || ls->t.token == TK_STRING) { | 63 | if (ls->t.token == TK_NAME || ls->t.token == TK_STRING) { |
59 | TString *ts = ls->t.seminfo.ts; | 64 | TString *ts = ls->t.seminfo.ts; |
60 | luaX_newstring(ls, getstr(ts), ts->tsv.len); | 65 | luaX_newstring(ls, getstr(ts), ts->tsv.len); |
@@ -62,18 +67,34 @@ static void anchor_token (LexState *ls) { | |||
62 | } | 67 | } |
63 | 68 | ||
64 | 69 | ||
65 | static void error_expected (LexState *ls, int token) { | 70 | /* semantic error */ |
71 | static l_noret semerror (LexState *ls, const char *msg) { | ||
72 | ls->t.token = 0; /* remove 'near to' from final message */ | ||
73 | luaX_syntaxerror(ls, msg); | ||
74 | } | ||
75 | |||
76 | |||
77 | static l_noret error_expected (LexState *ls, int token) { | ||
66 | luaX_syntaxerror(ls, | 78 | luaX_syntaxerror(ls, |
67 | luaO_pushfstring(ls->L, LUA_QS " expected", luaX_token2str(ls, token))); | 79 | luaO_pushfstring(ls->L, "%s expected", luaX_token2str(ls, token))); |
80 | } | ||
81 | |||
82 | |||
83 | static l_noret errorlimit (FuncState *fs, int limit, const char *what) { | ||
84 | lua_State *L = fs->ls->L; | ||
85 | const char *msg; | ||
86 | int line = fs->f->linedefined; | ||
87 | const char *where = (line == 0) | ||
88 | ? "main function" | ||
89 | : luaO_pushfstring(L, "function at line %d", line); | ||
90 | msg = luaO_pushfstring(L, "too many %s (limit is %d) in %s", | ||
91 | what, limit, where); | ||
92 | luaX_syntaxerror(fs->ls, msg); | ||
68 | } | 93 | } |
69 | 94 | ||
70 | 95 | ||
71 | static void errorlimit (FuncState *fs, int limit, const char *what) { | 96 | static void checklimit (FuncState *fs, int v, int l, const char *what) { |
72 | const char *msg = (fs->f->linedefined == 0) ? | 97 | if (v > l) errorlimit(fs, l, what); |
73 | luaO_pushfstring(fs->L, "main function has more than %d %s", limit, what) : | ||
74 | luaO_pushfstring(fs->L, "function at line %d has more than %d %s", | ||
75 | fs->f->linedefined, limit, what); | ||
76 | luaX_lexerror(fs->ls, msg, 0); | ||
77 | } | 98 | } |
78 | 99 | ||
79 | 100 | ||
@@ -91,6 +112,7 @@ static void check (LexState *ls, int c) { | |||
91 | error_expected(ls, c); | 112 | error_expected(ls, c); |
92 | } | 113 | } |
93 | 114 | ||
115 | |||
94 | static void checknext (LexState *ls, int c) { | 116 | static void checknext (LexState *ls, int c) { |
95 | check(ls, c); | 117 | check(ls, c); |
96 | luaX_next(ls); | 118 | luaX_next(ls); |
@@ -107,7 +129,7 @@ static void check_match (LexState *ls, int what, int who, int where) { | |||
107 | error_expected(ls, what); | 129 | error_expected(ls, what); |
108 | else { | 130 | else { |
109 | luaX_syntaxerror(ls, luaO_pushfstring(ls->L, | 131 | luaX_syntaxerror(ls, luaO_pushfstring(ls->L, |
110 | LUA_QS " expected (to close " LUA_QS " at line %d)", | 132 | "%s expected (to close %s at line %d)", |
111 | luaX_token2str(ls, what), luaX_token2str(ls, who), where)); | 133 | luaX_token2str(ls, what), luaX_token2str(ls, who), where)); |
112 | } | 134 | } |
113 | } | 135 | } |
@@ -126,7 +148,7 @@ static TString *str_checkname (LexState *ls) { | |||
126 | static void init_exp (expdesc *e, expkind k, int i) { | 148 | static void init_exp (expdesc *e, expkind k, int i) { |
127 | e->f = e->t = NO_JUMP; | 149 | e->f = e->t = NO_JUMP; |
128 | e->k = k; | 150 | e->k = k; |
129 | e->u.s.info = i; | 151 | e->u.info = i; |
130 | } | 152 | } |
131 | 153 | ||
132 | 154 | ||
@@ -135,7 +157,7 @@ static void codestring (LexState *ls, expdesc *e, TString *s) { | |||
135 | } | 157 | } |
136 | 158 | ||
137 | 159 | ||
138 | static void checkname(LexState *ls, expdesc *e) { | 160 | static void checkname (LexState *ls, expdesc *e) { |
139 | codestring(ls, e, str_checkname(ls)); | 161 | codestring(ls, e, str_checkname(ls)); |
140 | } | 162 | } |
141 | 163 | ||
@@ -145,7 +167,7 @@ static int registerlocalvar (LexState *ls, TString *varname) { | |||
145 | Proto *f = fs->f; | 167 | Proto *f = fs->f; |
146 | int oldsize = f->sizelocvars; | 168 | int oldsize = f->sizelocvars; |
147 | luaM_growvector(ls->L, f->locvars, fs->nlocvars, f->sizelocvars, | 169 | luaM_growvector(ls->L, f->locvars, fs->nlocvars, f->sizelocvars, |
148 | LocVar, SHRT_MAX, "too many local variables"); | 170 | LocVar, SHRT_MAX, "local variables"); |
149 | while (oldsize < f->sizelocvars) f->locvars[oldsize++].varname = NULL; | 171 | while (oldsize < f->sizelocvars) f->locvars[oldsize++].varname = NULL; |
150 | f->locvars[fs->nlocvars].varname = varname; | 172 | f->locvars[fs->nlocvars].varname = varname; |
151 | luaC_objbarrier(ls->L, f, varname); | 173 | luaC_objbarrier(ls->L, f, varname); |
@@ -153,14 +175,30 @@ static int registerlocalvar (LexState *ls, TString *varname) { | |||
153 | } | 175 | } |
154 | 176 | ||
155 | 177 | ||
156 | #define new_localvarliteral(ls,v,n) \ | 178 | static void new_localvar (LexState *ls, TString *name) { |
157 | new_localvar(ls, luaX_newstring(ls, "" v, (sizeof(v)/sizeof(char))-1), n) | 179 | FuncState *fs = ls->fs; |
180 | Dyndata *dyd = ls->dyd; | ||
181 | int reg = registerlocalvar(ls, name); | ||
182 | checklimit(fs, dyd->actvar.n + 1 - fs->firstlocal, | ||
183 | MAXVARS, "local variables"); | ||
184 | luaM_growvector(ls->L, dyd->actvar.arr, dyd->actvar.n + 1, | ||
185 | dyd->actvar.size, Vardesc, MAX_INT, "local variables"); | ||
186 | dyd->actvar.arr[dyd->actvar.n++].idx = cast(short, reg); | ||
187 | } | ||
158 | 188 | ||
159 | 189 | ||
160 | static void new_localvar (LexState *ls, TString *name, int n) { | 190 | static void new_localvarliteral_ (LexState *ls, const char *name, size_t sz) { |
161 | FuncState *fs = ls->fs; | 191 | new_localvar(ls, luaX_newstring(ls, name, sz)); |
162 | luaY_checklimit(fs, fs->nactvar+n+1, LUAI_MAXVARS, "local variables"); | 192 | } |
163 | fs->actvar[fs->nactvar+n] = cast(unsigned short, registerlocalvar(ls, name)); | 193 | |
194 | #define new_localvarliteral(ls,v) \ | ||
195 | new_localvarliteral_(ls, "" v, (sizeof(v)/sizeof(char))-1) | ||
196 | |||
197 | |||
198 | static LocVar *getlocvar (FuncState *fs, int i) { | ||
199 | int idx = fs->ls->dyd->actvar.arr[fs->firstlocal + i].idx; | ||
200 | lua_assert(idx < fs->nlocvars); | ||
201 | return &fs->f->locvars[idx]; | ||
164 | } | 202 | } |
165 | 203 | ||
166 | 204 | ||
@@ -168,77 +206,88 @@ static void adjustlocalvars (LexState *ls, int nvars) { | |||
168 | FuncState *fs = ls->fs; | 206 | FuncState *fs = ls->fs; |
169 | fs->nactvar = cast_byte(fs->nactvar + nvars); | 207 | fs->nactvar = cast_byte(fs->nactvar + nvars); |
170 | for (; nvars; nvars--) { | 208 | for (; nvars; nvars--) { |
171 | getlocvar(fs, fs->nactvar - nvars).startpc = fs->pc; | 209 | getlocvar(fs, fs->nactvar - nvars)->startpc = fs->pc; |
172 | } | 210 | } |
173 | } | 211 | } |
174 | 212 | ||
175 | 213 | ||
176 | static void removevars (LexState *ls, int tolevel) { | 214 | static void removevars (FuncState *fs, int tolevel) { |
177 | FuncState *fs = ls->fs; | 215 | fs->ls->dyd->actvar.n -= (fs->nactvar - tolevel); |
178 | while (fs->nactvar > tolevel) | 216 | while (fs->nactvar > tolevel) |
179 | getlocvar(fs, --fs->nactvar).endpc = fs->pc; | 217 | getlocvar(fs, --fs->nactvar)->endpc = fs->pc; |
180 | } | 218 | } |
181 | 219 | ||
182 | 220 | ||
183 | static int indexupvalue (FuncState *fs, TString *name, expdesc *v) { | 221 | static int searchupvalue (FuncState *fs, TString *name) { |
184 | int i; | 222 | int i; |
223 | Upvaldesc *up = fs->f->upvalues; | ||
224 | for (i = 0; i < fs->nups; i++) { | ||
225 | if (luaS_eqstr(up[i].name, name)) return i; | ||
226 | } | ||
227 | return -1; /* not found */ | ||
228 | } | ||
229 | |||
230 | |||
231 | static int newupvalue (FuncState *fs, TString *name, expdesc *v) { | ||
185 | Proto *f = fs->f; | 232 | Proto *f = fs->f; |
186 | int oldsize = f->sizeupvalues; | 233 | int oldsize = f->sizeupvalues; |
187 | for (i=0; i<f->nups; i++) { | 234 | checklimit(fs, fs->nups + 1, MAXUPVAL, "upvalues"); |
188 | if (fs->upvalues[i].k == v->k && fs->upvalues[i].info == v->u.s.info) { | 235 | luaM_growvector(fs->ls->L, f->upvalues, fs->nups, f->sizeupvalues, |
189 | lua_assert(f->upvalues[i] == name); | 236 | Upvaldesc, MAXUPVAL, "upvalues"); |
190 | return i; | 237 | while (oldsize < f->sizeupvalues) f->upvalues[oldsize++].name = NULL; |
191 | } | 238 | f->upvalues[fs->nups].instack = (v->k == VLOCAL); |
192 | } | 239 | f->upvalues[fs->nups].idx = cast_byte(v->u.info); |
193 | /* new one */ | 240 | f->upvalues[fs->nups].name = name; |
194 | luaY_checklimit(fs, f->nups + 1, LUAI_MAXUPVALUES, "upvalues"); | 241 | luaC_objbarrier(fs->ls->L, f, name); |
195 | luaM_growvector(fs->L, f->upvalues, f->nups, f->sizeupvalues, | 242 | return fs->nups++; |
196 | TString *, MAX_INT, ""); | ||
197 | while (oldsize < f->sizeupvalues) f->upvalues[oldsize++] = NULL; | ||
198 | f->upvalues[f->nups] = name; | ||
199 | luaC_objbarrier(fs->L, f, name); | ||
200 | lua_assert(v->k == VLOCAL || v->k == VUPVAL); | ||
201 | fs->upvalues[f->nups].k = cast_byte(v->k); | ||
202 | fs->upvalues[f->nups].info = cast_byte(v->u.s.info); | ||
203 | return f->nups++; | ||
204 | } | 243 | } |
205 | 244 | ||
206 | 245 | ||
207 | static int searchvar (FuncState *fs, TString *n) { | 246 | static int searchvar (FuncState *fs, TString *n) { |
208 | int i; | 247 | int i; |
209 | for (i=fs->nactvar-1; i >= 0; i--) { | 248 | for (i = cast_int(fs->nactvar) - 1; i >= 0; i--) { |
210 | if (n == getlocvar(fs, i).varname) | 249 | if (luaS_eqstr(n, getlocvar(fs, i)->varname)) |
211 | return i; | 250 | return i; |
212 | } | 251 | } |
213 | return -1; /* not found */ | 252 | return -1; /* not found */ |
214 | } | 253 | } |
215 | 254 | ||
216 | 255 | ||
256 | /* | ||
257 | Mark block where variable at given level was defined | ||
258 | (to emit close instructions later). | ||
259 | */ | ||
217 | static void markupval (FuncState *fs, int level) { | 260 | static void markupval (FuncState *fs, int level) { |
218 | BlockCnt *bl = fs->bl; | 261 | BlockCnt *bl = fs->bl; |
219 | while (bl && bl->nactvar > level) bl = bl->previous; | 262 | while (bl->nactvar > level) bl = bl->previous; |
220 | if (bl) bl->upval = 1; | 263 | bl->upval = 1; |
221 | } | 264 | } |
222 | 265 | ||
223 | 266 | ||
267 | /* | ||
268 | Find variable with given name 'n'. If it is an upvalue, add this | ||
269 | upvalue into all intermediate functions. | ||
270 | */ | ||
224 | static int singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) { | 271 | static int singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) { |
225 | if (fs == NULL) { /* no more levels? */ | 272 | if (fs == NULL) /* no more levels? */ |
226 | init_exp(var, VGLOBAL, NO_REG); /* default is global variable */ | 273 | return VVOID; /* default is global */ |
227 | return VGLOBAL; | ||
228 | } | ||
229 | else { | 274 | else { |
230 | int v = searchvar(fs, n); /* look up at current level */ | 275 | int v = searchvar(fs, n); /* look up locals at current level */ |
231 | if (v >= 0) { | 276 | if (v >= 0) { /* found? */ |
232 | init_exp(var, VLOCAL, v); | 277 | init_exp(var, VLOCAL, v); /* variable is local */ |
233 | if (!base) | 278 | if (!base) |
234 | markupval(fs, v); /* local will be used as an upval */ | 279 | markupval(fs, v); /* local will be used as an upval */ |
235 | return VLOCAL; | 280 | return VLOCAL; |
236 | } | 281 | } |
237 | else { /* not found at current level; try upper one */ | 282 | else { /* not found as local at current level; try upvalues */ |
238 | if (singlevaraux(fs->prev, n, var, 0) == VGLOBAL) | 283 | int idx = searchupvalue(fs, n); /* try existing upvalues */ |
239 | return VGLOBAL; | 284 | if (idx < 0) { /* not found? */ |
240 | var->u.s.info = indexupvalue(fs, n, var); /* else was LOCAL or UPVAL */ | 285 | if (singlevaraux(fs->prev, n, var, 0) == VVOID) /* try upper levels */ |
241 | var->k = VUPVAL; /* upvalue in this level */ | 286 | return VVOID; /* not found; is a global */ |
287 | /* else was LOCAL or UPVAL */ | ||
288 | idx = newupvalue(fs, n, var); /* will be a new upvalue */ | ||
289 | } | ||
290 | init_exp(var, VUPVAL, idx); | ||
242 | return VUPVAL; | 291 | return VUPVAL; |
243 | } | 292 | } |
244 | } | 293 | } |
@@ -248,8 +297,13 @@ static int singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) { | |||
248 | static void singlevar (LexState *ls, expdesc *var) { | 297 | static void singlevar (LexState *ls, expdesc *var) { |
249 | TString *varname = str_checkname(ls); | 298 | TString *varname = str_checkname(ls); |
250 | FuncState *fs = ls->fs; | 299 | FuncState *fs = ls->fs; |
251 | if (singlevaraux(fs, varname, var, 1) == VGLOBAL) | 300 | if (singlevaraux(fs, varname, var, 1) == VVOID) { /* global name? */ |
252 | var->u.s.info = luaK_stringK(fs, varname); /* info points to global name */ | 301 | expdesc key; |
302 | singlevaraux(fs, ls->envn, var, 1); /* get environment variable */ | ||
303 | lua_assert(var->k == VLOCAL || var->k == VUPVAL); | ||
304 | codestring(ls, &key, varname); /* key is variable name */ | ||
305 | luaK_indexed(fs, var, &key); /* env[varname] */ | ||
306 | } | ||
253 | } | 307 | } |
254 | 308 | ||
255 | 309 | ||
@@ -274,18 +328,118 @@ static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) { | |||
274 | 328 | ||
275 | 329 | ||
276 | static void enterlevel (LexState *ls) { | 330 | static void enterlevel (LexState *ls) { |
277 | if (++ls->L->nCcalls > LUAI_MAXCCALLS) | 331 | lua_State *L = ls->L; |
278 | luaX_lexerror(ls, "chunk has too many syntax levels", 0); | 332 | ++L->nCcalls; |
333 | checklimit(ls->fs, L->nCcalls, LUAI_MAXCCALLS, "C levels"); | ||
279 | } | 334 | } |
280 | 335 | ||
281 | 336 | ||
282 | #define leavelevel(ls) ((ls)->L->nCcalls--) | 337 | #define leavelevel(ls) ((ls)->L->nCcalls--) |
283 | 338 | ||
284 | 339 | ||
285 | static void enterblock (FuncState *fs, BlockCnt *bl, lu_byte isbreakable) { | 340 | static void closegoto (LexState *ls, int g, Labeldesc *label) { |
286 | bl->breaklist = NO_JUMP; | 341 | int i; |
287 | bl->isbreakable = isbreakable; | 342 | FuncState *fs = ls->fs; |
343 | Labellist *gl = &ls->dyd->gt; | ||
344 | Labeldesc *gt = &gl->arr[g]; | ||
345 | lua_assert(luaS_eqstr(gt->name, label->name)); | ||
346 | if (gt->nactvar < label->nactvar) { | ||
347 | TString *vname = getlocvar(fs, gt->nactvar)->varname; | ||
348 | const char *msg = luaO_pushfstring(ls->L, | ||
349 | "<goto %s> at line %d jumps into the scope of local " LUA_QS, | ||
350 | getstr(gt->name), gt->line, getstr(vname)); | ||
351 | semerror(ls, msg); | ||
352 | } | ||
353 | luaK_patchlist(fs, gt->pc, label->pc); | ||
354 | /* remove goto from pending list */ | ||
355 | for (i = g; i < gl->n - 1; i++) | ||
356 | gl->arr[i] = gl->arr[i + 1]; | ||
357 | gl->n--; | ||
358 | } | ||
359 | |||
360 | |||
361 | /* | ||
362 | ** try to close a goto with existing labels; this solves backward jumps | ||
363 | */ | ||
364 | static int findlabel (LexState *ls, int g) { | ||
365 | int i; | ||
366 | BlockCnt *bl = ls->fs->bl; | ||
367 | Dyndata *dyd = ls->dyd; | ||
368 | Labeldesc *gt = &dyd->gt.arr[g]; | ||
369 | /* check labels in current block for a match */ | ||
370 | for (i = bl->firstlabel; i < dyd->label.n; i++) { | ||
371 | Labeldesc *lb = &dyd->label.arr[i]; | ||
372 | if (luaS_eqstr(lb->name, gt->name)) { /* correct label? */ | ||
373 | if (gt->nactvar > lb->nactvar && | ||
374 | (bl->upval || dyd->label.n > bl->firstlabel)) | ||
375 | luaK_patchclose(ls->fs, gt->pc, lb->nactvar); | ||
376 | closegoto(ls, g, lb); /* close it */ | ||
377 | return 1; | ||
378 | } | ||
379 | } | ||
380 | return 0; /* label not found; cannot close goto */ | ||
381 | } | ||
382 | |||
383 | |||
384 | static int newlabelentry (LexState *ls, Labellist *l, TString *name, | ||
385 | int line, int pc) { | ||
386 | int n = l->n; | ||
387 | luaM_growvector(ls->L, l->arr, n, l->size, | ||
388 | Labeldesc, SHRT_MAX, "labels/gotos"); | ||
389 | l->arr[n].name = name; | ||
390 | l->arr[n].line = line; | ||
391 | l->arr[n].nactvar = ls->fs->nactvar; | ||
392 | l->arr[n].pc = pc; | ||
393 | l->n++; | ||
394 | return n; | ||
395 | } | ||
396 | |||
397 | |||
398 | /* | ||
399 | ** check whether new label 'lb' matches any pending gotos in current | ||
400 | ** block; solves forward jumps | ||
401 | */ | ||
402 | static void findgotos (LexState *ls, Labeldesc *lb) { | ||
403 | Labellist *gl = &ls->dyd->gt; | ||
404 | int i = ls->fs->bl->firstgoto; | ||
405 | while (i < gl->n) { | ||
406 | if (luaS_eqstr(gl->arr[i].name, lb->name)) | ||
407 | closegoto(ls, i, lb); | ||
408 | else | ||
409 | i++; | ||
410 | } | ||
411 | } | ||
412 | |||
413 | |||
414 | /* | ||
415 | ** "export" pending gotos to outer level, to check them against | ||
416 | ** outer labels; if the block being exited has upvalues, and | ||
417 | ** the goto exits the scope of any variable (which can be the | ||
418 | ** upvalue), close those variables being exited. | ||
419 | */ | ||
420 | static void movegotosout (FuncState *fs, BlockCnt *bl) { | ||
421 | int i = bl->firstgoto; | ||
422 | Labellist *gl = &fs->ls->dyd->gt; | ||
423 | /* correct pending gotos to current block and try to close it | ||
424 | with visible labels */ | ||
425 | while (i < gl->n) { | ||
426 | Labeldesc *gt = &gl->arr[i]; | ||
427 | if (gt->nactvar > bl->nactvar) { | ||
428 | if (bl->upval) | ||
429 | luaK_patchclose(fs, gt->pc, bl->nactvar); | ||
430 | gt->nactvar = bl->nactvar; | ||
431 | } | ||
432 | if (!findlabel(fs->ls, i)) | ||
433 | i++; /* move to next one */ | ||
434 | } | ||
435 | } | ||
436 | |||
437 | |||
438 | static void enterblock (FuncState *fs, BlockCnt *bl, lu_byte isloop) { | ||
439 | bl->isloop = isloop; | ||
288 | bl->nactvar = fs->nactvar; | 440 | bl->nactvar = fs->nactvar; |
441 | bl->firstlabel = fs->ls->dyd->label.n; | ||
442 | bl->firstgoto = fs->ls->dyd->gt.n; | ||
289 | bl->upval = 0; | 443 | bl->upval = 0; |
290 | bl->previous = fs->bl; | 444 | bl->previous = fs->bl; |
291 | fs->bl = bl; | 445 | fs->bl = bl; |
@@ -293,63 +447,108 @@ static void enterblock (FuncState *fs, BlockCnt *bl, lu_byte isbreakable) { | |||
293 | } | 447 | } |
294 | 448 | ||
295 | 449 | ||
450 | /* | ||
451 | ** create a label named "break" to resolve break statements | ||
452 | */ | ||
453 | static void breaklabel (LexState *ls) { | ||
454 | TString *n = luaS_new(ls->L, "break"); | ||
455 | int l = newlabelentry(ls, &ls->dyd->label, n, 0, ls->fs->pc); | ||
456 | findgotos(ls, &ls->dyd->label.arr[l]); | ||
457 | } | ||
458 | |||
459 | /* | ||
460 | ** generates an error for an undefined 'goto'; choose appropriate | ||
461 | ** message when label name is a reserved word (which can only be 'break') | ||
462 | */ | ||
463 | static l_noret undefgoto (LexState *ls, Labeldesc *gt) { | ||
464 | const char *msg = isreserved(gt->name) | ||
465 | ? "<%s> at line %d not inside a loop" | ||
466 | : "no visible label " LUA_QS " for <goto> at line %d"; | ||
467 | msg = luaO_pushfstring(ls->L, msg, getstr(gt->name), gt->line); | ||
468 | semerror(ls, msg); | ||
469 | } | ||
470 | |||
471 | |||
296 | static void leaveblock (FuncState *fs) { | 472 | static void leaveblock (FuncState *fs) { |
297 | BlockCnt *bl = fs->bl; | 473 | BlockCnt *bl = fs->bl; |
474 | LexState *ls = fs->ls; | ||
475 | if (bl->previous && bl->upval) { | ||
476 | /* create a 'jump to here' to close upvalues */ | ||
477 | int j = luaK_jump(fs); | ||
478 | luaK_patchclose(fs, j, bl->nactvar); | ||
479 | luaK_patchtohere(fs, j); | ||
480 | } | ||
481 | if (bl->isloop) | ||
482 | breaklabel(ls); /* close pending breaks */ | ||
298 | fs->bl = bl->previous; | 483 | fs->bl = bl->previous; |
299 | removevars(fs->ls, bl->nactvar); | 484 | removevars(fs, bl->nactvar); |
300 | if (bl->upval) | ||
301 | luaK_codeABC(fs, OP_CLOSE, bl->nactvar, 0, 0); | ||
302 | /* a block either controls scope or breaks (never both) */ | ||
303 | lua_assert(!bl->isbreakable || !bl->upval); | ||
304 | lua_assert(bl->nactvar == fs->nactvar); | 485 | lua_assert(bl->nactvar == fs->nactvar); |
305 | fs->freereg = fs->nactvar; /* free registers */ | 486 | fs->freereg = fs->nactvar; /* free registers */ |
306 | luaK_patchtohere(fs, bl->breaklist); | 487 | ls->dyd->label.n = bl->firstlabel; /* remove local labels */ |
488 | if (bl->previous) /* inner block? */ | ||
489 | movegotosout(fs, bl); /* update pending gotos to outer block */ | ||
490 | else if (bl->firstgoto < ls->dyd->gt.n) /* pending gotos in outer block? */ | ||
491 | undefgoto(ls, &ls->dyd->gt.arr[bl->firstgoto]); /* error */ | ||
307 | } | 492 | } |
308 | 493 | ||
309 | 494 | ||
310 | static void pushclosure (LexState *ls, FuncState *func, expdesc *v) { | 495 | /* |
496 | ** adds a new prototype into list of prototypes | ||
497 | */ | ||
498 | static Proto *addprototype (LexState *ls) { | ||
499 | Proto *clp; | ||
500 | lua_State *L = ls->L; | ||
311 | FuncState *fs = ls->fs; | 501 | FuncState *fs = ls->fs; |
312 | Proto *f = fs->f; | 502 | Proto *f = fs->f; /* prototype of current function */ |
313 | int oldsize = f->sizep; | 503 | if (fs->np >= f->sizep) { |
314 | int i; | 504 | int oldsize = f->sizep; |
315 | luaM_growvector(ls->L, f->p, fs->np, f->sizep, Proto *, | 505 | luaM_growvector(L, f->p, fs->np, f->sizep, Proto *, MAXARG_Bx, "functions"); |
316 | MAXARG_Bx, "constant table overflow"); | 506 | while (oldsize < f->sizep) f->p[oldsize++] = NULL; |
317 | while (oldsize < f->sizep) f->p[oldsize++] = NULL; | ||
318 | f->p[fs->np++] = func->f; | ||
319 | luaC_objbarrier(ls->L, f, func->f); | ||
320 | init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np-1)); | ||
321 | for (i=0; i<func->f->nups; i++) { | ||
322 | OpCode o = (func->upvalues[i].k == VLOCAL) ? OP_MOVE : OP_GETUPVAL; | ||
323 | luaK_codeABC(fs, o, 0, func->upvalues[i].info, 0); | ||
324 | } | 507 | } |
508 | f->p[fs->np++] = clp = luaF_newproto(L); | ||
509 | luaC_objbarrier(L, f, clp); | ||
510 | return clp; | ||
325 | } | 511 | } |
326 | 512 | ||
327 | 513 | ||
328 | static void lparser_open_func (LexState *ls, FuncState *fs) { | 514 | /* |
515 | ** codes instruction to create new closure in parent function. | ||
516 | ** The OP_CLOSURE instruction must use the last available register, | ||
517 | ** so that, if it invokes the GC, the GC knows which registers | ||
518 | ** are in use at that time. | ||
519 | */ | ||
520 | static void codeclosure (LexState *ls, expdesc *v) { | ||
521 | FuncState *fs = ls->fs->prev; | ||
522 | init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np - 1)); | ||
523 | luaK_exp2nextreg(fs, v); /* fix it at the last register */ | ||
524 | } | ||
525 | |||
526 | |||
527 | static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) { | ||
329 | lua_State *L = ls->L; | 528 | lua_State *L = ls->L; |
330 | Proto *f = luaF_newproto(L); | 529 | Proto *f; |
331 | fs->f = f; | ||
332 | fs->prev = ls->fs; /* linked list of funcstates */ | 530 | fs->prev = ls->fs; /* linked list of funcstates */ |
333 | fs->ls = ls; | 531 | fs->ls = ls; |
334 | fs->L = L; | ||
335 | ls->fs = fs; | 532 | ls->fs = fs; |
336 | fs->pc = 0; | 533 | fs->pc = 0; |
337 | fs->lasttarget = -1; | 534 | fs->lasttarget = 0; |
338 | fs->jpc = NO_JUMP; | 535 | fs->jpc = NO_JUMP; |
339 | fs->freereg = 0; | 536 | fs->freereg = 0; |
340 | fs->nk = 0; | 537 | fs->nk = 0; |
341 | fs->np = 0; | 538 | fs->np = 0; |
539 | fs->nups = 0; | ||
342 | fs->nlocvars = 0; | 540 | fs->nlocvars = 0; |
343 | fs->nactvar = 0; | 541 | fs->nactvar = 0; |
542 | fs->firstlocal = ls->dyd->actvar.n; | ||
344 | fs->bl = NULL; | 543 | fs->bl = NULL; |
544 | f = fs->f; | ||
345 | f->source = ls->source; | 545 | f->source = ls->source; |
346 | f->maxstacksize = 2; /* registers 0/1 are always valid */ | 546 | f->maxstacksize = 2; /* registers 0/1 are always valid */ |
347 | fs->h = luaH_new(L, 0, 0); | 547 | fs->h = luaH_new(L); |
348 | /* anchor table of constants and prototype (to avoid being collected) */ | 548 | /* anchor table of constants (to avoid being collected) */ |
349 | sethvalue2s(L, L->top, fs->h); | 549 | sethvalue2s(L, L->top, fs->h); |
350 | incr_top(L); | 550 | incr_top(L); |
351 | setptvalue2s(L, L->top, f); | 551 | enterblock(fs, bl, 0); |
352 | incr_top(L); | ||
353 | } | 552 | } |
354 | 553 | ||
355 | 554 | ||
@@ -357,8 +556,8 @@ static void close_func (LexState *ls) { | |||
357 | lua_State *L = ls->L; | 556 | lua_State *L = ls->L; |
358 | FuncState *fs = ls->fs; | 557 | FuncState *fs = ls->fs; |
359 | Proto *f = fs->f; | 558 | Proto *f = fs->f; |
360 | removevars(ls, 0); | ||
361 | luaK_ret(fs, 0, 0); /* final return */ | 559 | luaK_ret(fs, 0, 0); /* final return */ |
560 | leaveblock(fs); | ||
362 | luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction); | 561 | luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction); |
363 | f->sizecode = fs->pc; | 562 | f->sizecode = fs->pc; |
364 | luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->pc, int); | 563 | luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->pc, int); |
@@ -369,32 +568,14 @@ static void close_func (LexState *ls) { | |||
369 | f->sizep = fs->np; | 568 | f->sizep = fs->np; |
370 | luaM_reallocvector(L, f->locvars, f->sizelocvars, fs->nlocvars, LocVar); | 569 | luaM_reallocvector(L, f->locvars, f->sizelocvars, fs->nlocvars, LocVar); |
371 | f->sizelocvars = fs->nlocvars; | 570 | f->sizelocvars = fs->nlocvars; |
372 | luaM_reallocvector(L, f->upvalues, f->sizeupvalues, f->nups, TString *); | 571 | luaM_reallocvector(L, f->upvalues, f->sizeupvalues, fs->nups, Upvaldesc); |
373 | f->sizeupvalues = f->nups; | 572 | f->sizeupvalues = fs->nups; |
374 | lua_assert(luaG_checkcode(f)); | ||
375 | lua_assert(fs->bl == NULL); | 573 | lua_assert(fs->bl == NULL); |
376 | ls->fs = fs->prev; | 574 | ls->fs = fs->prev; |
377 | L->top -= 2; /* remove table and prototype from the stack */ | 575 | /* last token read was anchored in defunct function; must re-anchor it */ |
378 | /* last token read was anchored in defunct function; must reanchor it */ | 576 | anchor_token(ls); |
379 | if (fs) anchor_token(ls); | 577 | L->top--; /* pop table of constants */ |
380 | } | 578 | luaC_checkGC(L); |
381 | |||
382 | |||
383 | Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, const char *name) { | ||
384 | struct LexState lexstate; | ||
385 | struct FuncState funcstate; | ||
386 | lexstate.buff = buff; | ||
387 | luaX_setinput(L, &lexstate, z, luaS_new(L, name)); | ||
388 | lparser_open_func(&lexstate, &funcstate); | ||
389 | funcstate.f->is_vararg = VARARG_ISVARARG; /* main func. is always vararg */ | ||
390 | luaX_next(&lexstate); /* read first token */ | ||
391 | chunk(&lexstate); | ||
392 | check(&lexstate, TK_EOS); | ||
393 | close_func(&lexstate); | ||
394 | lua_assert(funcstate.prev == NULL); | ||
395 | lua_assert(funcstate.f->nups == 0); | ||
396 | lua_assert(lexstate.fs == NULL); | ||
397 | return funcstate.f; | ||
398 | } | 579 | } |
399 | 580 | ||
400 | 581 | ||
@@ -404,11 +585,39 @@ Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, const char *name) { | |||
404 | /*============================================================*/ | 585 | /*============================================================*/ |
405 | 586 | ||
406 | 587 | ||
407 | static void field (LexState *ls, expdesc *v) { | 588 | /* |
408 | /* field -> ['.' | ':'] NAME */ | 589 | ** check whether current token is in the follow set of a block. |
590 | ** 'until' closes syntactical blocks, but do not close scope, | ||
591 | ** so it handled in separate. | ||
592 | */ | ||
593 | static int block_follow (LexState *ls, int withuntil) { | ||
594 | switch (ls->t.token) { | ||
595 | case TK_ELSE: case TK_ELSEIF: | ||
596 | case TK_END: case TK_EOS: | ||
597 | return 1; | ||
598 | case TK_UNTIL: return withuntil; | ||
599 | default: return 0; | ||
600 | } | ||
601 | } | ||
602 | |||
603 | |||
604 | static void statlist (LexState *ls) { | ||
605 | /* statlist -> { stat [`;'] } */ | ||
606 | while (!block_follow(ls, 1)) { | ||
607 | if (ls->t.token == TK_RETURN) { | ||
608 | statement(ls); | ||
609 | return; /* 'return' must be last statement */ | ||
610 | } | ||
611 | statement(ls); | ||
612 | } | ||
613 | } | ||
614 | |||
615 | |||
616 | static void fieldsel (LexState *ls, expdesc *v) { | ||
617 | /* fieldsel -> ['.' | ':'] NAME */ | ||
409 | FuncState *fs = ls->fs; | 618 | FuncState *fs = ls->fs; |
410 | expdesc key; | 619 | expdesc key; |
411 | luaK_exp2anyreg(fs, v); | 620 | luaK_exp2anyregup(fs, v); |
412 | luaX_next(ls); /* skip the dot or colon */ | 621 | luaX_next(ls); /* skip the dot or colon */ |
413 | checkname(ls, &key); | 622 | checkname(ls, &key); |
414 | luaK_indexed(fs, v, &key); | 623 | luaK_indexed(fs, v, &key); |
@@ -447,7 +656,7 @@ static void recfield (LexState *ls, struct ConsControl *cc) { | |||
447 | expdesc key, val; | 656 | expdesc key, val; |
448 | int rkkey; | 657 | int rkkey; |
449 | if (ls->t.token == TK_NAME) { | 658 | if (ls->t.token == TK_NAME) { |
450 | luaY_checklimit(fs, cc->nh, MAX_INT, "items in a constructor"); | 659 | checklimit(fs, cc->nh, MAX_INT, "items in a constructor"); |
451 | checkname(ls, &key); | 660 | checkname(ls, &key); |
452 | } | 661 | } |
453 | else /* ls->t.token == '[' */ | 662 | else /* ls->t.token == '[' */ |
@@ -456,7 +665,7 @@ static void recfield (LexState *ls, struct ConsControl *cc) { | |||
456 | checknext(ls, '='); | 665 | checknext(ls, '='); |
457 | rkkey = luaK_exp2RK(fs, &key); | 666 | rkkey = luaK_exp2RK(fs, &key); |
458 | expr(ls, &val); | 667 | expr(ls, &val); |
459 | luaK_codeABC(fs, OP_SETTABLE, cc->t->u.s.info, rkkey, luaK_exp2RK(fs, &val)); | 668 | luaK_codeABC(fs, OP_SETTABLE, cc->t->u.info, rkkey, luaK_exp2RK(fs, &val)); |
460 | fs->freereg = reg; /* free registers */ | 669 | fs->freereg = reg; /* free registers */ |
461 | } | 670 | } |
462 | 671 | ||
@@ -466,7 +675,7 @@ static void closelistfield (FuncState *fs, struct ConsControl *cc) { | |||
466 | luaK_exp2nextreg(fs, &cc->v); | 675 | luaK_exp2nextreg(fs, &cc->v); |
467 | cc->v.k = VVOID; | 676 | cc->v.k = VVOID; |
468 | if (cc->tostore == LFIELDS_PER_FLUSH) { | 677 | if (cc->tostore == LFIELDS_PER_FLUSH) { |
469 | luaK_setlist(fs, cc->t->u.s.info, cc->na, cc->tostore); /* flush */ | 678 | luaK_setlist(fs, cc->t->u.info, cc->na, cc->tostore); /* flush */ |
470 | cc->tostore = 0; /* no more items pending */ | 679 | cc->tostore = 0; /* no more items pending */ |
471 | } | 680 | } |
472 | } | 681 | } |
@@ -476,27 +685,51 @@ static void lastlistfield (FuncState *fs, struct ConsControl *cc) { | |||
476 | if (cc->tostore == 0) return; | 685 | if (cc->tostore == 0) return; |
477 | if (hasmultret(cc->v.k)) { | 686 | if (hasmultret(cc->v.k)) { |
478 | luaK_setmultret(fs, &cc->v); | 687 | luaK_setmultret(fs, &cc->v); |
479 | luaK_setlist(fs, cc->t->u.s.info, cc->na, LUA_MULTRET); | 688 | luaK_setlist(fs, cc->t->u.info, cc->na, LUA_MULTRET); |
480 | cc->na--; /* do not count last expression (unknown number of elements) */ | 689 | cc->na--; /* do not count last expression (unknown number of elements) */ |
481 | } | 690 | } |
482 | else { | 691 | else { |
483 | if (cc->v.k != VVOID) | 692 | if (cc->v.k != VVOID) |
484 | luaK_exp2nextreg(fs, &cc->v); | 693 | luaK_exp2nextreg(fs, &cc->v); |
485 | luaK_setlist(fs, cc->t->u.s.info, cc->na, cc->tostore); | 694 | luaK_setlist(fs, cc->t->u.info, cc->na, cc->tostore); |
486 | } | 695 | } |
487 | } | 696 | } |
488 | 697 | ||
489 | 698 | ||
490 | static void listfield (LexState *ls, struct ConsControl *cc) { | 699 | static void listfield (LexState *ls, struct ConsControl *cc) { |
700 | /* listfield -> exp */ | ||
491 | expr(ls, &cc->v); | 701 | expr(ls, &cc->v); |
492 | luaY_checklimit(ls->fs, cc->na, MAX_INT, "items in a constructor"); | 702 | checklimit(ls->fs, cc->na, MAX_INT, "items in a constructor"); |
493 | cc->na++; | 703 | cc->na++; |
494 | cc->tostore++; | 704 | cc->tostore++; |
495 | } | 705 | } |
496 | 706 | ||
497 | 707 | ||
708 | static void field (LexState *ls, struct ConsControl *cc) { | ||
709 | /* field -> listfield | recfield */ | ||
710 | switch(ls->t.token) { | ||
711 | case TK_NAME: { /* may be 'listfield' or 'recfield' */ | ||
712 | if (luaX_lookahead(ls) != '=') /* expression? */ | ||
713 | listfield(ls, cc); | ||
714 | else | ||
715 | recfield(ls, cc); | ||
716 | break; | ||
717 | } | ||
718 | case '[': { | ||
719 | recfield(ls, cc); | ||
720 | break; | ||
721 | } | ||
722 | default: { | ||
723 | listfield(ls, cc); | ||
724 | break; | ||
725 | } | ||
726 | } | ||
727 | } | ||
728 | |||
729 | |||
498 | static void constructor (LexState *ls, expdesc *t) { | 730 | static void constructor (LexState *ls, expdesc *t) { |
499 | /* constructor -> ?? */ | 731 | /* constructor -> '{' [ field { sep field } [sep] ] '}' |
732 | sep -> ',' | ';' */ | ||
500 | FuncState *fs = ls->fs; | 733 | FuncState *fs = ls->fs; |
501 | int line = ls->linenumber; | 734 | int line = ls->linenumber; |
502 | int pc = luaK_codeABC(fs, OP_NEWTABLE, 0, 0, 0); | 735 | int pc = luaK_codeABC(fs, OP_NEWTABLE, 0, 0, 0); |
@@ -505,30 +738,13 @@ static void constructor (LexState *ls, expdesc *t) { | |||
505 | cc.t = t; | 738 | cc.t = t; |
506 | init_exp(t, VRELOCABLE, pc); | 739 | init_exp(t, VRELOCABLE, pc); |
507 | init_exp(&cc.v, VVOID, 0); /* no value (yet) */ | 740 | init_exp(&cc.v, VVOID, 0); /* no value (yet) */ |
508 | luaK_exp2nextreg(ls->fs, t); /* fix it at stack top (for gc) */ | 741 | luaK_exp2nextreg(ls->fs, t); /* fix it at stack top */ |
509 | checknext(ls, '{'); | 742 | checknext(ls, '{'); |
510 | do { | 743 | do { |
511 | lua_assert(cc.v.k == VVOID || cc.tostore > 0); | 744 | lua_assert(cc.v.k == VVOID || cc.tostore > 0); |
512 | if (ls->t.token == '}') break; | 745 | if (ls->t.token == '}') break; |
513 | closelistfield(fs, &cc); | 746 | closelistfield(fs, &cc); |
514 | switch(ls->t.token) { | 747 | field(ls, &cc); |
515 | case TK_NAME: { /* may be listfields or recfields */ | ||
516 | luaX_lookahead(ls); | ||
517 | if (ls->lookahead.token != '=') /* expression? */ | ||
518 | listfield(ls, &cc); | ||
519 | else | ||
520 | recfield(ls, &cc); | ||
521 | break; | ||
522 | } | ||
523 | case '[': { /* constructor_item -> recfield */ | ||
524 | recfield(ls, &cc); | ||
525 | break; | ||
526 | } | ||
527 | default: { /* constructor_part -> listfield */ | ||
528 | listfield(ls, &cc); | ||
529 | break; | ||
530 | } | ||
531 | } | ||
532 | } while (testnext(ls, ',') || testnext(ls, ';')); | 748 | } while (testnext(ls, ',') || testnext(ls, ';')); |
533 | check_match(ls, '}', '{', line); | 749 | check_match(ls, '}', '{', line); |
534 | lastlistfield(fs, &cc); | 750 | lastlistfield(fs, &cc); |
@@ -550,17 +766,13 @@ static void parlist (LexState *ls) { | |||
550 | do { | 766 | do { |
551 | switch (ls->t.token) { | 767 | switch (ls->t.token) { |
552 | case TK_NAME: { /* param -> NAME */ | 768 | case TK_NAME: { /* param -> NAME */ |
553 | new_localvar(ls, str_checkname(ls), nparams++); | 769 | new_localvar(ls, str_checkname(ls)); |
770 | nparams++; | ||
554 | break; | 771 | break; |
555 | } | 772 | } |
556 | case TK_DOTS: { /* param -> `...' */ | 773 | case TK_DOTS: { /* param -> `...' */ |
557 | luaX_next(ls); | 774 | luaX_next(ls); |
558 | #if defined(LUA_COMPAT_VARARG) | 775 | f->is_vararg = 1; |
559 | /* use `arg' as default name */ | ||
560 | new_localvarliteral(ls, "arg", nparams++); | ||
561 | f->is_vararg = VARARG_HASARG | VARARG_NEEDSARG; | ||
562 | #endif | ||
563 | f->is_vararg |= VARARG_ISVARARG; | ||
564 | break; | 776 | break; |
565 | } | 777 | } |
566 | default: luaX_syntaxerror(ls, "<name> or " LUA_QL("...") " expected"); | 778 | default: luaX_syntaxerror(ls, "<name> or " LUA_QL("...") " expected"); |
@@ -568,33 +780,35 @@ static void parlist (LexState *ls) { | |||
568 | } while (!f->is_vararg && testnext(ls, ',')); | 780 | } while (!f->is_vararg && testnext(ls, ',')); |
569 | } | 781 | } |
570 | adjustlocalvars(ls, nparams); | 782 | adjustlocalvars(ls, nparams); |
571 | f->numparams = cast_byte(fs->nactvar - (f->is_vararg & VARARG_HASARG)); | 783 | f->numparams = cast_byte(fs->nactvar); |
572 | luaK_reserveregs(fs, fs->nactvar); /* reserve register for parameters */ | 784 | luaK_reserveregs(fs, fs->nactvar); /* reserve register for parameters */ |
573 | } | 785 | } |
574 | 786 | ||
575 | 787 | ||
576 | static void body (LexState *ls, expdesc *e, int needself, int line) { | 788 | static void body (LexState *ls, expdesc *e, int ismethod, int line) { |
577 | /* body -> `(' parlist `)' chunk END */ | 789 | /* body -> `(' parlist `)' block END */ |
578 | FuncState new_fs; | 790 | FuncState new_fs; |
579 | lparser_open_func(ls, &new_fs); | 791 | BlockCnt bl; |
792 | new_fs.f = addprototype(ls); | ||
580 | new_fs.f->linedefined = line; | 793 | new_fs.f->linedefined = line; |
794 | open_func(ls, &new_fs, &bl); | ||
581 | checknext(ls, '('); | 795 | checknext(ls, '('); |
582 | if (needself) { | 796 | if (ismethod) { |
583 | new_localvarliteral(ls, "self", 0); | 797 | new_localvarliteral(ls, "self"); /* create 'self' parameter */ |
584 | adjustlocalvars(ls, 1); | 798 | adjustlocalvars(ls, 1); |
585 | } | 799 | } |
586 | parlist(ls); | 800 | parlist(ls); |
587 | checknext(ls, ')'); | 801 | checknext(ls, ')'); |
588 | chunk(ls); | 802 | statlist(ls); |
589 | new_fs.f->lastlinedefined = ls->linenumber; | 803 | new_fs.f->lastlinedefined = ls->linenumber; |
590 | check_match(ls, TK_END, TK_FUNCTION, line); | 804 | check_match(ls, TK_END, TK_FUNCTION, line); |
805 | codeclosure(ls, e); | ||
591 | close_func(ls); | 806 | close_func(ls); |
592 | pushclosure(ls, &new_fs, e); | ||
593 | } | 807 | } |
594 | 808 | ||
595 | 809 | ||
596 | static int explist1 (LexState *ls, expdesc *v) { | 810 | static int explist (LexState *ls, expdesc *v) { |
597 | /* explist1 -> expr { `,' expr } */ | 811 | /* explist -> expr { `,' expr } */ |
598 | int n = 1; /* at least one expression */ | 812 | int n = 1; /* at least one expression */ |
599 | expr(ls, v); | 813 | expr(ls, v); |
600 | while (testnext(ls, ',')) { | 814 | while (testnext(ls, ',')) { |
@@ -606,20 +820,17 @@ static int explist1 (LexState *ls, expdesc *v) { | |||
606 | } | 820 | } |
607 | 821 | ||
608 | 822 | ||
609 | static void funcargs (LexState *ls, expdesc *f) { | 823 | static void funcargs (LexState *ls, expdesc *f, int line) { |
610 | FuncState *fs = ls->fs; | 824 | FuncState *fs = ls->fs; |
611 | expdesc args; | 825 | expdesc args; |
612 | int base, nparams; | 826 | int base, nparams; |
613 | int line = ls->linenumber; | ||
614 | switch (ls->t.token) { | 827 | switch (ls->t.token) { |
615 | case '(': { /* funcargs -> `(' [ explist1 ] `)' */ | 828 | case '(': { /* funcargs -> `(' [ explist ] `)' */ |
616 | if (line != ls->lastline) | ||
617 | luaX_syntaxerror(ls,"ambiguous syntax (function call x new statement)"); | ||
618 | luaX_next(ls); | 829 | luaX_next(ls); |
619 | if (ls->t.token == ')') /* arg list is empty? */ | 830 | if (ls->t.token == ')') /* arg list is empty? */ |
620 | args.k = VVOID; | 831 | args.k = VVOID; |
621 | else { | 832 | else { |
622 | explist1(ls, &args); | 833 | explist(ls, &args); |
623 | luaK_setmultret(fs, &args); | 834 | luaK_setmultret(fs, &args); |
624 | } | 835 | } |
625 | check_match(ls, ')', '(', line); | 836 | check_match(ls, ')', '(', line); |
@@ -636,11 +847,10 @@ static void funcargs (LexState *ls, expdesc *f) { | |||
636 | } | 847 | } |
637 | default: { | 848 | default: { |
638 | luaX_syntaxerror(ls, "function arguments expected"); | 849 | luaX_syntaxerror(ls, "function arguments expected"); |
639 | return; | ||
640 | } | 850 | } |
641 | } | 851 | } |
642 | lua_assert(f->k == VNONRELOC); | 852 | lua_assert(f->k == VNONRELOC); |
643 | base = f->u.s.info; /* base register for call */ | 853 | base = f->u.info; /* base register for call */ |
644 | if (hasmultret(args.k)) | 854 | if (hasmultret(args.k)) |
645 | nparams = LUA_MULTRET; /* open call */ | 855 | nparams = LUA_MULTRET; /* open call */ |
646 | else { | 856 | else { |
@@ -664,8 +874,8 @@ static void funcargs (LexState *ls, expdesc *f) { | |||
664 | */ | 874 | */ |
665 | 875 | ||
666 | 876 | ||
667 | static void prefixexp (LexState *ls, expdesc *v) { | 877 | static void primaryexp (LexState *ls, expdesc *v) { |
668 | /* prefixexp -> NAME | '(' expr ')' */ | 878 | /* primaryexp -> NAME | '(' expr ')' */ |
669 | switch (ls->t.token) { | 879 | switch (ls->t.token) { |
670 | case '(': { | 880 | case '(': { |
671 | int line = ls->linenumber; | 881 | int line = ls->linenumber; |
@@ -681,26 +891,26 @@ static void prefixexp (LexState *ls, expdesc *v) { | |||
681 | } | 891 | } |
682 | default: { | 892 | default: { |
683 | luaX_syntaxerror(ls, "unexpected symbol"); | 893 | luaX_syntaxerror(ls, "unexpected symbol"); |
684 | return; | ||
685 | } | 894 | } |
686 | } | 895 | } |
687 | } | 896 | } |
688 | 897 | ||
689 | 898 | ||
690 | static void primaryexp (LexState *ls, expdesc *v) { | 899 | static void suffixedexp (LexState *ls, expdesc *v) { |
691 | /* primaryexp -> | 900 | /* suffixedexp -> |
692 | prefixexp { `.' NAME | `[' exp `]' | `:' NAME funcargs | funcargs } */ | 901 | primaryexp { '.' NAME | '[' exp ']' | ':' NAME funcargs | funcargs } */ |
693 | FuncState *fs = ls->fs; | 902 | FuncState *fs = ls->fs; |
694 | prefixexp(ls, v); | 903 | int line = ls->linenumber; |
904 | primaryexp(ls, v); | ||
695 | for (;;) { | 905 | for (;;) { |
696 | switch (ls->t.token) { | 906 | switch (ls->t.token) { |
697 | case '.': { /* field */ | 907 | case '.': { /* fieldsel */ |
698 | field(ls, v); | 908 | fieldsel(ls, v); |
699 | break; | 909 | break; |
700 | } | 910 | } |
701 | case '[': { /* `[' exp1 `]' */ | 911 | case '[': { /* `[' exp1 `]' */ |
702 | expdesc key; | 912 | expdesc key; |
703 | luaK_exp2anyreg(fs, v); | 913 | luaK_exp2anyregup(fs, v); |
704 | yindex(ls, &key); | 914 | yindex(ls, &key); |
705 | luaK_indexed(fs, v, &key); | 915 | luaK_indexed(fs, v, &key); |
706 | break; | 916 | break; |
@@ -710,12 +920,12 @@ static void primaryexp (LexState *ls, expdesc *v) { | |||
710 | luaX_next(ls); | 920 | luaX_next(ls); |
711 | checkname(ls, &key); | 921 | checkname(ls, &key); |
712 | luaK_self(fs, v, &key); | 922 | luaK_self(fs, v, &key); |
713 | funcargs(ls, v); | 923 | funcargs(ls, v, line); |
714 | break; | 924 | break; |
715 | } | 925 | } |
716 | case '(': case TK_STRING: case '{': { /* funcargs */ | 926 | case '(': case TK_STRING: case '{': { /* funcargs */ |
717 | luaK_exp2nextreg(fs, v); | 927 | luaK_exp2nextreg(fs, v); |
718 | funcargs(ls, v); | 928 | funcargs(ls, v, line); |
719 | break; | 929 | break; |
720 | } | 930 | } |
721 | default: return; | 931 | default: return; |
@@ -725,8 +935,8 @@ static void primaryexp (LexState *ls, expdesc *v) { | |||
725 | 935 | ||
726 | 936 | ||
727 | static void simpleexp (LexState *ls, expdesc *v) { | 937 | static void simpleexp (LexState *ls, expdesc *v) { |
728 | /* simpleexp -> NUMBER | STRING | NIL | true | false | ... | | 938 | /* simpleexp -> NUMBER | STRING | NIL | TRUE | FALSE | ... | |
729 | constructor | FUNCTION body | primaryexp */ | 939 | constructor | FUNCTION body | suffixedexp */ |
730 | switch (ls->t.token) { | 940 | switch (ls->t.token) { |
731 | case TK_NUMBER: { | 941 | case TK_NUMBER: { |
732 | init_exp(v, VKNUM, 0); | 942 | init_exp(v, VKNUM, 0); |
@@ -753,7 +963,6 @@ static void simpleexp (LexState *ls, expdesc *v) { | |||
753 | FuncState *fs = ls->fs; | 963 | FuncState *fs = ls->fs; |
754 | check_condition(ls, fs->f->is_vararg, | 964 | check_condition(ls, fs->f->is_vararg, |
755 | "cannot use " LUA_QL("...") " outside a vararg function"); | 965 | "cannot use " LUA_QL("...") " outside a vararg function"); |
756 | fs->f->is_vararg &= ~VARARG_NEEDSARG; /* don't need 'arg' */ | ||
757 | init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 1, 0)); | 966 | init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 1, 0)); |
758 | break; | 967 | break; |
759 | } | 968 | } |
@@ -767,7 +976,7 @@ static void simpleexp (LexState *ls, expdesc *v) { | |||
767 | return; | 976 | return; |
768 | } | 977 | } |
769 | default: { | 978 | default: { |
770 | primaryexp(ls, v); | 979 | suffixedexp(ls, v); |
771 | return; | 980 | return; |
772 | } | 981 | } |
773 | } | 982 | } |
@@ -811,11 +1020,11 @@ static const struct { | |||
811 | lu_byte left; /* left priority for each binary operator */ | 1020 | lu_byte left; /* left priority for each binary operator */ |
812 | lu_byte right; /* right priority */ | 1021 | lu_byte right; /* right priority */ |
813 | } priority[] = { /* ORDER OPR */ | 1022 | } priority[] = { /* ORDER OPR */ |
814 | {6, 6}, {6, 6}, {7, 7}, {7, 7}, {7, 7}, /* `+' `-' `/' `%' */ | 1023 | {6, 6}, {6, 6}, {7, 7}, {7, 7}, {7, 7}, /* `+' `-' `*' `/' `%' */ |
815 | {10, 9}, {5, 4}, /* power and concat (right associative) */ | 1024 | {10, 9}, {5, 4}, /* ^, .. (right associative) */ |
816 | {3, 3}, {3, 3}, /* equality and inequality */ | 1025 | {3, 3}, {3, 3}, {3, 3}, /* ==, <, <= */ |
817 | {3, 3}, {3, 3}, {3, 3}, {3, 3}, /* order */ | 1026 | {3, 3}, {3, 3}, {3, 3}, /* ~=, >, >= */ |
818 | {2, 2}, {1, 1} /* logical (and/or) */ | 1027 | {2, 2}, {1, 1} /* and, or */ |
819 | }; | 1028 | }; |
820 | 1029 | ||
821 | #define UNARY_PRIORITY 8 /* priority for unary operators */ | 1030 | #define UNARY_PRIORITY 8 /* priority for unary operators */ |
@@ -825,15 +1034,16 @@ static const struct { | |||
825 | ** subexpr -> (simpleexp | unop subexpr) { binop subexpr } | 1034 | ** subexpr -> (simpleexp | unop subexpr) { binop subexpr } |
826 | ** where `binop' is any binary operator with a priority higher than `limit' | 1035 | ** where `binop' is any binary operator with a priority higher than `limit' |
827 | */ | 1036 | */ |
828 | static BinOpr subexpr (LexState *ls, expdesc *v, unsigned int limit) { | 1037 | static BinOpr subexpr (LexState *ls, expdesc *v, int limit) { |
829 | BinOpr op; | 1038 | BinOpr op; |
830 | UnOpr uop; | 1039 | UnOpr uop; |
831 | enterlevel(ls); | 1040 | enterlevel(ls); |
832 | uop = getunopr(ls->t.token); | 1041 | uop = getunopr(ls->t.token); |
833 | if (uop != OPR_NOUNOPR) { | 1042 | if (uop != OPR_NOUNOPR) { |
1043 | int line = ls->linenumber; | ||
834 | luaX_next(ls); | 1044 | luaX_next(ls); |
835 | subexpr(ls, v, UNARY_PRIORITY); | 1045 | subexpr(ls, v, UNARY_PRIORITY); |
836 | luaK_prefix(ls->fs, uop, v); | 1046 | luaK_prefix(ls->fs, uop, v, line); |
837 | } | 1047 | } |
838 | else simpleexp(ls, v); | 1048 | else simpleexp(ls, v); |
839 | /* expand while operators have priorities higher than `limit' */ | 1049 | /* expand while operators have priorities higher than `limit' */ |
@@ -841,11 +1051,12 @@ static BinOpr subexpr (LexState *ls, expdesc *v, unsigned int limit) { | |||
841 | while (op != OPR_NOBINOPR && priority[op].left > limit) { | 1051 | while (op != OPR_NOBINOPR && priority[op].left > limit) { |
842 | expdesc v2; | 1052 | expdesc v2; |
843 | BinOpr nextop; | 1053 | BinOpr nextop; |
1054 | int line = ls->linenumber; | ||
844 | luaX_next(ls); | 1055 | luaX_next(ls); |
845 | luaK_infix(ls->fs, op, v); | 1056 | luaK_infix(ls->fs, op, v); |
846 | /* read sub-expression with higher priority */ | 1057 | /* read sub-expression with higher priority */ |
847 | nextop = subexpr(ls, &v2, priority[op].right); | 1058 | nextop = subexpr(ls, &v2, priority[op].right); |
848 | luaK_posfix(ls->fs, op, v, &v2); | 1059 | luaK_posfix(ls->fs, op, v, &v2, line); |
849 | op = nextop; | 1060 | op = nextop; |
850 | } | 1061 | } |
851 | leavelevel(ls); | 1062 | leavelevel(ls); |
@@ -868,23 +1079,12 @@ static void expr (LexState *ls, expdesc *v) { | |||
868 | */ | 1079 | */ |
869 | 1080 | ||
870 | 1081 | ||
871 | static int block_follow (int token) { | ||
872 | switch (token) { | ||
873 | case TK_ELSE: case TK_ELSEIF: case TK_END: | ||
874 | case TK_UNTIL: case TK_EOS: | ||
875 | return 1; | ||
876 | default: return 0; | ||
877 | } | ||
878 | } | ||
879 | |||
880 | |||
881 | static void block (LexState *ls) { | 1082 | static void block (LexState *ls) { |
882 | /* block -> chunk */ | 1083 | /* block -> statlist */ |
883 | FuncState *fs = ls->fs; | 1084 | FuncState *fs = ls->fs; |
884 | BlockCnt bl; | 1085 | BlockCnt bl; |
885 | enterblock(fs, &bl, 0); | 1086 | enterblock(fs, &bl, 0); |
886 | chunk(ls); | 1087 | statlist(ls); |
887 | lua_assert(bl.breaklist == NO_JUMP); | ||
888 | leaveblock(fs); | 1088 | leaveblock(fs); |
889 | } | 1089 | } |
890 | 1090 | ||
@@ -900,29 +1100,34 @@ struct LHS_assign { | |||
900 | 1100 | ||
901 | 1101 | ||
902 | /* | 1102 | /* |
903 | ** check whether, in an assignment to a local variable, the local variable | 1103 | ** check whether, in an assignment to an upvalue/local variable, the |
904 | ** is needed in a previous assignment (to a table). If so, save original | 1104 | ** upvalue/local variable is begin used in a previous assignment to a |
905 | ** local value in a safe place and use this safe copy in the previous | 1105 | ** table. If so, save original upvalue/local value in a safe place and |
906 | ** assignment. | 1106 | ** use this safe copy in the previous assignment. |
907 | */ | 1107 | */ |
908 | static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) { | 1108 | static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) { |
909 | FuncState *fs = ls->fs; | 1109 | FuncState *fs = ls->fs; |
910 | int extra = fs->freereg; /* eventual position to save local variable */ | 1110 | int extra = fs->freereg; /* eventual position to save local variable */ |
911 | int conflict = 0; | 1111 | int conflict = 0; |
912 | for (; lh; lh = lh->prev) { | 1112 | for (; lh; lh = lh->prev) { /* check all previous assignments */ |
913 | if (lh->v.k == VINDEXED) { | 1113 | if (lh->v.k == VINDEXED) { /* assigning to a table? */ |
914 | if (lh->v.u.s.info == v->u.s.info) { /* conflict? */ | 1114 | /* table is the upvalue/local being assigned now? */ |
1115 | if (lh->v.u.ind.vt == v->k && lh->v.u.ind.t == v->u.info) { | ||
915 | conflict = 1; | 1116 | conflict = 1; |
916 | lh->v.u.s.info = extra; /* previous assignment will use safe copy */ | 1117 | lh->v.u.ind.vt = VLOCAL; |
1118 | lh->v.u.ind.t = extra; /* previous assignment will use safe copy */ | ||
917 | } | 1119 | } |
918 | if (lh->v.u.s.aux == v->u.s.info) { /* conflict? */ | 1120 | /* index is the local being assigned? (index cannot be upvalue) */ |
1121 | if (v->k == VLOCAL && lh->v.u.ind.idx == v->u.info) { | ||
919 | conflict = 1; | 1122 | conflict = 1; |
920 | lh->v.u.s.aux = extra; /* previous assignment will use safe copy */ | 1123 | lh->v.u.ind.idx = extra; /* previous assignment will use safe copy */ |
921 | } | 1124 | } |
922 | } | 1125 | } |
923 | } | 1126 | } |
924 | if (conflict) { | 1127 | if (conflict) { |
925 | luaK_codeABC(fs, OP_MOVE, fs->freereg, v->u.s.info, 0); /* make copy */ | 1128 | /* copy upvalue/local value to a temporary (in position 'extra') */ |
1129 | OpCode op = (v->k == VLOCAL) ? OP_MOVE : OP_GETUPVAL; | ||
1130 | luaK_codeABC(fs, op, extra, v->u.info, 0); | ||
926 | luaK_reserveregs(fs, 1); | 1131 | luaK_reserveregs(fs, 1); |
927 | } | 1132 | } |
928 | } | 1133 | } |
@@ -930,22 +1135,21 @@ static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) { | |||
930 | 1135 | ||
931 | static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) { | 1136 | static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) { |
932 | expdesc e; | 1137 | expdesc e; |
933 | check_condition(ls, VLOCAL <= lh->v.k && lh->v.k <= VINDEXED, | 1138 | check_condition(ls, vkisvar(lh->v.k), "syntax error"); |
934 | "syntax error"); | 1139 | if (testnext(ls, ',')) { /* assignment -> ',' suffixedexp assignment */ |
935 | if (testnext(ls, ',')) { /* assignment -> `,' primaryexp assignment */ | ||
936 | struct LHS_assign nv; | 1140 | struct LHS_assign nv; |
937 | nv.prev = lh; | 1141 | nv.prev = lh; |
938 | primaryexp(ls, &nv.v); | 1142 | suffixedexp(ls, &nv.v); |
939 | if (nv.v.k == VLOCAL) | 1143 | if (nv.v.k != VINDEXED) |
940 | check_conflict(ls, lh, &nv.v); | 1144 | check_conflict(ls, lh, &nv.v); |
941 | luaY_checklimit(ls->fs, nvars, LUAI_MAXCCALLS - ls->L->nCcalls, | 1145 | checklimit(ls->fs, nvars + ls->L->nCcalls, LUAI_MAXCCALLS, |
942 | "variables in assignment"); | 1146 | "C levels"); |
943 | assignment(ls, &nv, nvars+1); | 1147 | assignment(ls, &nv, nvars+1); |
944 | } | 1148 | } |
945 | else { /* assignment -> `=' explist1 */ | 1149 | else { /* assignment -> `=' explist */ |
946 | int nexps; | 1150 | int nexps; |
947 | checknext(ls, '='); | 1151 | checknext(ls, '='); |
948 | nexps = explist1(ls, &e); | 1152 | nexps = explist(ls, &e); |
949 | if (nexps != nvars) { | 1153 | if (nexps != nvars) { |
950 | adjust_assign(ls, nvars, nexps, &e); | 1154 | adjust_assign(ls, nvars, nexps, &e); |
951 | if (nexps > nvars) | 1155 | if (nexps > nvars) |
@@ -972,19 +1176,57 @@ static int cond (LexState *ls) { | |||
972 | } | 1176 | } |
973 | 1177 | ||
974 | 1178 | ||
975 | static void breakstat (LexState *ls) { | 1179 | static void gotostat (LexState *ls, int pc) { |
1180 | int line = ls->linenumber; | ||
1181 | TString *label; | ||
1182 | int g; | ||
1183 | if (testnext(ls, TK_GOTO)) | ||
1184 | label = str_checkname(ls); | ||
1185 | else { | ||
1186 | luaX_next(ls); /* skip break */ | ||
1187 | label = luaS_new(ls->L, "break"); | ||
1188 | } | ||
1189 | g = newlabelentry(ls, &ls->dyd->gt, label, line, pc); | ||
1190 | findlabel(ls, g); /* close it if label already defined */ | ||
1191 | } | ||
1192 | |||
1193 | |||
1194 | /* check for repeated labels on the same block */ | ||
1195 | static void checkrepeated (FuncState *fs, Labellist *ll, TString *label) { | ||
1196 | int i; | ||
1197 | for (i = fs->bl->firstlabel; i < ll->n; i++) { | ||
1198 | if (luaS_eqstr(label, ll->arr[i].name)) { | ||
1199 | const char *msg = luaO_pushfstring(fs->ls->L, | ||
1200 | "label " LUA_QS " already defined on line %d", | ||
1201 | getstr(label), ll->arr[i].line); | ||
1202 | semerror(fs->ls, msg); | ||
1203 | } | ||
1204 | } | ||
1205 | } | ||
1206 | |||
1207 | |||
1208 | /* skip no-op statements */ | ||
1209 | static void skipnoopstat (LexState *ls) { | ||
1210 | while (ls->t.token == ';' || ls->t.token == TK_DBCOLON) | ||
1211 | statement(ls); | ||
1212 | } | ||
1213 | |||
1214 | |||
1215 | static void labelstat (LexState *ls, TString *label, int line) { | ||
1216 | /* label -> '::' NAME '::' */ | ||
976 | FuncState *fs = ls->fs; | 1217 | FuncState *fs = ls->fs; |
977 | BlockCnt *bl = fs->bl; | 1218 | Labellist *ll = &ls->dyd->label; |
978 | int upval = 0; | 1219 | int l; /* index of new label being created */ |
979 | while (bl && !bl->isbreakable) { | 1220 | checkrepeated(fs, ll, label); /* check for repeated labels */ |
980 | upval |= bl->upval; | 1221 | checknext(ls, TK_DBCOLON); /* skip double colon */ |
981 | bl = bl->previous; | 1222 | /* create new entry for this label */ |
1223 | l = newlabelentry(ls, ll, label, line, fs->pc); | ||
1224 | skipnoopstat(ls); /* skip other no-op statements */ | ||
1225 | if (block_follow(ls, 0)) { /* label is last no-op statement in the block? */ | ||
1226 | /* assume that locals are already out of scope */ | ||
1227 | ll->arr[l].nactvar = fs->bl->nactvar; | ||
982 | } | 1228 | } |
983 | if (!bl) | 1229 | findgotos(ls, &ll->arr[l]); |
984 | luaX_syntaxerror(ls, "no loop to break"); | ||
985 | if (upval) | ||
986 | luaK_codeABC(fs, OP_CLOSE, bl->nactvar, 0, 0); | ||
987 | luaK_concat(fs, &bl->breaklist, luaK_jump(fs)); | ||
988 | } | 1230 | } |
989 | 1231 | ||
990 | 1232 | ||
@@ -1000,7 +1242,7 @@ static void whilestat (LexState *ls, int line) { | |||
1000 | enterblock(fs, &bl, 1); | 1242 | enterblock(fs, &bl, 1); |
1001 | checknext(ls, TK_DO); | 1243 | checknext(ls, TK_DO); |
1002 | block(ls); | 1244 | block(ls); |
1003 | luaK_patchlist(fs, luaK_jump(fs), whileinit); | 1245 | luaK_jumpto(fs, whileinit); |
1004 | check_match(ls, TK_END, TK_WHILE, line); | 1246 | check_match(ls, TK_END, TK_WHILE, line); |
1005 | leaveblock(fs); | 1247 | leaveblock(fs); |
1006 | luaK_patchtohere(fs, condexit); /* false conditions finish the loop */ | 1248 | luaK_patchtohere(fs, condexit); /* false conditions finish the loop */ |
@@ -1016,30 +1258,25 @@ static void repeatstat (LexState *ls, int line) { | |||
1016 | enterblock(fs, &bl1, 1); /* loop block */ | 1258 | enterblock(fs, &bl1, 1); /* loop block */ |
1017 | enterblock(fs, &bl2, 0); /* scope block */ | 1259 | enterblock(fs, &bl2, 0); /* scope block */ |
1018 | luaX_next(ls); /* skip REPEAT */ | 1260 | luaX_next(ls); /* skip REPEAT */ |
1019 | chunk(ls); | 1261 | statlist(ls); |
1020 | check_match(ls, TK_UNTIL, TK_REPEAT, line); | 1262 | check_match(ls, TK_UNTIL, TK_REPEAT, line); |
1021 | condexit = cond(ls); /* read condition (inside scope block) */ | 1263 | condexit = cond(ls); /* read condition (inside scope block) */ |
1022 | if (!bl2.upval) { /* no upvalues? */ | 1264 | if (bl2.upval) /* upvalues? */ |
1023 | leaveblock(fs); /* finish scope */ | 1265 | luaK_patchclose(fs, condexit, bl2.nactvar); |
1024 | luaK_patchlist(ls->fs, condexit, repeat_init); /* close the loop */ | 1266 | leaveblock(fs); /* finish scope */ |
1025 | } | 1267 | luaK_patchlist(fs, condexit, repeat_init); /* close the loop */ |
1026 | else { /* complete semantics when there are upvalues */ | ||
1027 | breakstat(ls); /* if condition then break */ | ||
1028 | luaK_patchtohere(ls->fs, condexit); /* else... */ | ||
1029 | leaveblock(fs); /* finish scope... */ | ||
1030 | luaK_patchlist(ls->fs, luaK_jump(fs), repeat_init); /* and repeat */ | ||
1031 | } | ||
1032 | leaveblock(fs); /* finish loop */ | 1268 | leaveblock(fs); /* finish loop */ |
1033 | } | 1269 | } |
1034 | 1270 | ||
1035 | 1271 | ||
1036 | static int exp1 (LexState *ls) { | 1272 | static int exp1 (LexState *ls) { |
1037 | expdesc e; | 1273 | expdesc e; |
1038 | int k; | 1274 | int reg; |
1039 | expr(ls, &e); | 1275 | expr(ls, &e); |
1040 | k = e.k; | ||
1041 | luaK_exp2nextreg(ls->fs, &e); | 1276 | luaK_exp2nextreg(ls->fs, &e); |
1042 | return k; | 1277 | lua_assert(e.k == VNONRELOC); |
1278 | reg = e.u.info; | ||
1279 | return reg; | ||
1043 | } | 1280 | } |
1044 | 1281 | ||
1045 | 1282 | ||
@@ -1057,10 +1294,15 @@ static void forbody (LexState *ls, int base, int line, int nvars, int isnum) { | |||
1057 | block(ls); | 1294 | block(ls); |
1058 | leaveblock(fs); /* end of scope for declared variables */ | 1295 | leaveblock(fs); /* end of scope for declared variables */ |
1059 | luaK_patchtohere(fs, prep); | 1296 | luaK_patchtohere(fs, prep); |
1060 | endfor = (isnum) ? luaK_codeAsBx(fs, OP_FORLOOP, base, NO_JUMP) : | 1297 | if (isnum) /* numeric for? */ |
1061 | luaK_codeABC(fs, OP_TFORLOOP, base, 0, nvars); | 1298 | endfor = luaK_codeAsBx(fs, OP_FORLOOP, base, NO_JUMP); |
1062 | luaK_fixline(fs, line); /* pretend that `OP_FOR' starts the loop */ | 1299 | else { /* generic for */ |
1063 | luaK_patchlist(fs, (isnum ? endfor : luaK_jump(fs)), prep + 1); | 1300 | luaK_codeABC(fs, OP_TFORCALL, base, 0, nvars); |
1301 | luaK_fixline(fs, line); | ||
1302 | endfor = luaK_codeAsBx(fs, OP_TFORLOOP, base + 2, NO_JUMP); | ||
1303 | } | ||
1304 | luaK_patchlist(fs, endfor, prep + 1); | ||
1305 | luaK_fixline(fs, line); | ||
1064 | } | 1306 | } |
1065 | 1307 | ||
1066 | 1308 | ||
@@ -1068,10 +1310,10 @@ static void fornum (LexState *ls, TString *varname, int line) { | |||
1068 | /* fornum -> NAME = exp1,exp1[,exp1] forbody */ | 1310 | /* fornum -> NAME = exp1,exp1[,exp1] forbody */ |
1069 | FuncState *fs = ls->fs; | 1311 | FuncState *fs = ls->fs; |
1070 | int base = fs->freereg; | 1312 | int base = fs->freereg; |
1071 | new_localvarliteral(ls, "(for index)", 0); | 1313 | new_localvarliteral(ls, "(for index)"); |
1072 | new_localvarliteral(ls, "(for limit)", 1); | 1314 | new_localvarliteral(ls, "(for limit)"); |
1073 | new_localvarliteral(ls, "(for step)", 2); | 1315 | new_localvarliteral(ls, "(for step)"); |
1074 | new_localvar(ls, varname, 3); | 1316 | new_localvar(ls, varname); |
1075 | checknext(ls, '='); | 1317 | checknext(ls, '='); |
1076 | exp1(ls); /* initial value */ | 1318 | exp1(ls); /* initial value */ |
1077 | checknext(ls, ','); | 1319 | checknext(ls, ','); |
@@ -1079,7 +1321,7 @@ static void fornum (LexState *ls, TString *varname, int line) { | |||
1079 | if (testnext(ls, ',')) | 1321 | if (testnext(ls, ',')) |
1080 | exp1(ls); /* optional step */ | 1322 | exp1(ls); /* optional step */ |
1081 | else { /* default step = 1 */ | 1323 | else { /* default step = 1 */ |
1082 | luaK_codeABx(fs, OP_LOADK, fs->freereg, luaK_numberK(fs, 1)); | 1324 | luaK_codek(fs, fs->freereg, luaK_numberK(fs, 1)); |
1083 | luaK_reserveregs(fs, 1); | 1325 | luaK_reserveregs(fs, 1); |
1084 | } | 1326 | } |
1085 | forbody(ls, base, line, 1, 1); | 1327 | forbody(ls, base, line, 1, 1); |
@@ -1087,23 +1329,25 @@ static void fornum (LexState *ls, TString *varname, int line) { | |||
1087 | 1329 | ||
1088 | 1330 | ||
1089 | static void forlist (LexState *ls, TString *indexname) { | 1331 | static void forlist (LexState *ls, TString *indexname) { |
1090 | /* forlist -> NAME {,NAME} IN explist1 forbody */ | 1332 | /* forlist -> NAME {,NAME} IN explist forbody */ |
1091 | FuncState *fs = ls->fs; | 1333 | FuncState *fs = ls->fs; |
1092 | expdesc e; | 1334 | expdesc e; |
1093 | int nvars = 0; | 1335 | int nvars = 4; /* gen, state, control, plus at least one declared var */ |
1094 | int line; | 1336 | int line; |
1095 | int base = fs->freereg; | 1337 | int base = fs->freereg; |
1096 | /* create control variables */ | 1338 | /* create control variables */ |
1097 | new_localvarliteral(ls, "(for generator)", nvars++); | 1339 | new_localvarliteral(ls, "(for generator)"); |
1098 | new_localvarliteral(ls, "(for state)", nvars++); | 1340 | new_localvarliteral(ls, "(for state)"); |
1099 | new_localvarliteral(ls, "(for control)", nvars++); | 1341 | new_localvarliteral(ls, "(for control)"); |
1100 | /* create declared variables */ | 1342 | /* create declared variables */ |
1101 | new_localvar(ls, indexname, nvars++); | 1343 | new_localvar(ls, indexname); |
1102 | while (testnext(ls, ',')) | 1344 | while (testnext(ls, ',')) { |
1103 | new_localvar(ls, str_checkname(ls), nvars++); | 1345 | new_localvar(ls, str_checkname(ls)); |
1346 | nvars++; | ||
1347 | } | ||
1104 | checknext(ls, TK_IN); | 1348 | checknext(ls, TK_IN); |
1105 | line = ls->linenumber; | 1349 | line = ls->linenumber; |
1106 | adjust_assign(ls, 3, explist1(ls, &e), &e); | 1350 | adjust_assign(ls, 3, explist(ls, &e), &e); |
1107 | luaK_checkstack(fs, 3); /* extra space to call generator */ | 1351 | luaK_checkstack(fs, 3); /* extra space to call generator */ |
1108 | forbody(ls, base, line, nvars - 3, 0); | 1352 | forbody(ls, base, line, nvars - 3, 0); |
1109 | } | 1353 | } |
@@ -1127,65 +1371,77 @@ static void forstat (LexState *ls, int line) { | |||
1127 | } | 1371 | } |
1128 | 1372 | ||
1129 | 1373 | ||
1130 | static int test_then_block (LexState *ls) { | 1374 | static void test_then_block (LexState *ls, int *escapelist) { |
1131 | /* test_then_block -> [IF | ELSEIF] cond THEN block */ | 1375 | /* test_then_block -> [IF | ELSEIF] cond THEN block */ |
1132 | int condexit; | 1376 | BlockCnt bl; |
1377 | FuncState *fs = ls->fs; | ||
1378 | expdesc v; | ||
1379 | int jf; /* instruction to skip 'then' code (if condition is false) */ | ||
1133 | luaX_next(ls); /* skip IF or ELSEIF */ | 1380 | luaX_next(ls); /* skip IF or ELSEIF */ |
1134 | condexit = cond(ls); | 1381 | expr(ls, &v); /* read condition */ |
1135 | checknext(ls, TK_THEN); | 1382 | checknext(ls, TK_THEN); |
1136 | block(ls); /* `then' part */ | 1383 | if (ls->t.token == TK_GOTO || ls->t.token == TK_BREAK) { |
1137 | return condexit; | 1384 | luaK_goiffalse(ls->fs, &v); /* will jump to label if condition is true */ |
1385 | enterblock(fs, &bl, 0); /* must enter block before 'goto' */ | ||
1386 | gotostat(ls, v.t); /* handle goto/break */ | ||
1387 | skipnoopstat(ls); /* skip other no-op statements */ | ||
1388 | if (block_follow(ls, 0)) { /* 'goto' is the entire block? */ | ||
1389 | leaveblock(fs); | ||
1390 | return; /* and that is it */ | ||
1391 | } | ||
1392 | else /* must skip over 'then' part if condition is false */ | ||
1393 | jf = luaK_jump(fs); | ||
1394 | } | ||
1395 | else { /* regular case (not goto/break) */ | ||
1396 | luaK_goiftrue(ls->fs, &v); /* skip over block if condition is false */ | ||
1397 | enterblock(fs, &bl, 0); | ||
1398 | jf = v.f; | ||
1399 | } | ||
1400 | statlist(ls); /* `then' part */ | ||
1401 | leaveblock(fs); | ||
1402 | if (ls->t.token == TK_ELSE || | ||
1403 | ls->t.token == TK_ELSEIF) /* followed by 'else'/'elseif'? */ | ||
1404 | luaK_concat(fs, escapelist, luaK_jump(fs)); /* must jump over it */ | ||
1405 | luaK_patchtohere(fs, jf); | ||
1138 | } | 1406 | } |
1139 | 1407 | ||
1140 | 1408 | ||
1141 | static void ifstat (LexState *ls, int line) { | 1409 | static void ifstat (LexState *ls, int line) { |
1142 | /* ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END */ | 1410 | /* ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END */ |
1143 | FuncState *fs = ls->fs; | 1411 | FuncState *fs = ls->fs; |
1144 | int flist; | 1412 | int escapelist = NO_JUMP; /* exit list for finished parts */ |
1145 | int escapelist = NO_JUMP; | 1413 | test_then_block(ls, &escapelist); /* IF cond THEN block */ |
1146 | flist = test_then_block(ls); /* IF cond THEN block */ | 1414 | while (ls->t.token == TK_ELSEIF) |
1147 | while (ls->t.token == TK_ELSEIF) { | 1415 | test_then_block(ls, &escapelist); /* ELSEIF cond THEN block */ |
1148 | luaK_concat(fs, &escapelist, luaK_jump(fs)); | 1416 | if (testnext(ls, TK_ELSE)) |
1149 | luaK_patchtohere(fs, flist); | ||
1150 | flist = test_then_block(ls); /* ELSEIF cond THEN block */ | ||
1151 | } | ||
1152 | if (ls->t.token == TK_ELSE) { | ||
1153 | luaK_concat(fs, &escapelist, luaK_jump(fs)); | ||
1154 | luaK_patchtohere(fs, flist); | ||
1155 | luaX_next(ls); /* skip ELSE (after patch, for correct line info) */ | ||
1156 | block(ls); /* `else' part */ | 1417 | block(ls); /* `else' part */ |
1157 | } | ||
1158 | else | ||
1159 | luaK_concat(fs, &escapelist, flist); | ||
1160 | luaK_patchtohere(fs, escapelist); | ||
1161 | check_match(ls, TK_END, TK_IF, line); | 1418 | check_match(ls, TK_END, TK_IF, line); |
1419 | luaK_patchtohere(fs, escapelist); /* patch escape list to 'if' end */ | ||
1162 | } | 1420 | } |
1163 | 1421 | ||
1164 | 1422 | ||
1165 | static void localfunc (LexState *ls) { | 1423 | static void localfunc (LexState *ls) { |
1166 | expdesc v, b; | 1424 | expdesc b; |
1167 | FuncState *fs = ls->fs; | 1425 | FuncState *fs = ls->fs; |
1168 | new_localvar(ls, str_checkname(ls), 0); | 1426 | new_localvar(ls, str_checkname(ls)); /* new local variable */ |
1169 | init_exp(&v, VLOCAL, fs->freereg); | 1427 | adjustlocalvars(ls, 1); /* enter its scope */ |
1170 | luaK_reserveregs(fs, 1); | 1428 | body(ls, &b, 0, ls->linenumber); /* function created in next register */ |
1171 | adjustlocalvars(ls, 1); | ||
1172 | body(ls, &b, 0, ls->linenumber); | ||
1173 | luaK_storevar(fs, &v, &b); | ||
1174 | /* debug information will only see the variable after this point! */ | 1429 | /* debug information will only see the variable after this point! */ |
1175 | getlocvar(fs, fs->nactvar - 1).startpc = fs->pc; | 1430 | getlocvar(fs, b.u.info)->startpc = fs->pc; |
1176 | } | 1431 | } |
1177 | 1432 | ||
1178 | 1433 | ||
1179 | static void localstat (LexState *ls) { | 1434 | static void localstat (LexState *ls) { |
1180 | /* stat -> LOCAL NAME {`,' NAME} [`=' explist1] */ | 1435 | /* stat -> LOCAL NAME {`,' NAME} [`=' explist] */ |
1181 | int nvars = 0; | 1436 | int nvars = 0; |
1182 | int nexps; | 1437 | int nexps; |
1183 | expdesc e; | 1438 | expdesc e; |
1184 | do { | 1439 | do { |
1185 | new_localvar(ls, str_checkname(ls), nvars++); | 1440 | new_localvar(ls, str_checkname(ls)); |
1441 | nvars++; | ||
1186 | } while (testnext(ls, ',')); | 1442 | } while (testnext(ls, ',')); |
1187 | if (testnext(ls, '=')) | 1443 | if (testnext(ls, '=')) |
1188 | nexps = explist1(ls, &e); | 1444 | nexps = explist(ls, &e); |
1189 | else { | 1445 | else { |
1190 | e.k = VVOID; | 1446 | e.k = VVOID; |
1191 | nexps = 0; | 1447 | nexps = 0; |
@@ -1196,26 +1452,26 @@ static void localstat (LexState *ls) { | |||
1196 | 1452 | ||
1197 | 1453 | ||
1198 | static int funcname (LexState *ls, expdesc *v) { | 1454 | static int funcname (LexState *ls, expdesc *v) { |
1199 | /* funcname -> NAME {field} [`:' NAME] */ | 1455 | /* funcname -> NAME {fieldsel} [`:' NAME] */ |
1200 | int needself = 0; | 1456 | int ismethod = 0; |
1201 | singlevar(ls, v); | 1457 | singlevar(ls, v); |
1202 | while (ls->t.token == '.') | 1458 | while (ls->t.token == '.') |
1203 | field(ls, v); | 1459 | fieldsel(ls, v); |
1204 | if (ls->t.token == ':') { | 1460 | if (ls->t.token == ':') { |
1205 | needself = 1; | 1461 | ismethod = 1; |
1206 | field(ls, v); | 1462 | fieldsel(ls, v); |
1207 | } | 1463 | } |
1208 | return needself; | 1464 | return ismethod; |
1209 | } | 1465 | } |
1210 | 1466 | ||
1211 | 1467 | ||
1212 | static void funcstat (LexState *ls, int line) { | 1468 | static void funcstat (LexState *ls, int line) { |
1213 | /* funcstat -> FUNCTION funcname body */ | 1469 | /* funcstat -> FUNCTION funcname body */ |
1214 | int needself; | 1470 | int ismethod; |
1215 | expdesc v, b; | 1471 | expdesc v, b; |
1216 | luaX_next(ls); /* skip FUNCTION */ | 1472 | luaX_next(ls); /* skip FUNCTION */ |
1217 | needself = funcname(ls, &v); | 1473 | ismethod = funcname(ls, &v); |
1218 | body(ls, &b, needself, line); | 1474 | body(ls, &b, ismethod, line); |
1219 | luaK_storevar(ls->fs, &v, &b); | 1475 | luaK_storevar(ls->fs, &v, &b); |
1220 | luaK_fixline(ls->fs, line); /* definition `happens' in the first line */ | 1476 | luaK_fixline(ls->fs, line); /* definition `happens' in the first line */ |
1221 | } | 1477 | } |
@@ -1225,26 +1481,27 @@ static void exprstat (LexState *ls) { | |||
1225 | /* stat -> func | assignment */ | 1481 | /* stat -> func | assignment */ |
1226 | FuncState *fs = ls->fs; | 1482 | FuncState *fs = ls->fs; |
1227 | struct LHS_assign v; | 1483 | struct LHS_assign v; |
1228 | primaryexp(ls, &v.v); | 1484 | suffixedexp(ls, &v.v); |
1229 | if (v.v.k == VCALL) /* stat -> func */ | 1485 | if (ls->t.token == '=' || ls->t.token == ',') { /* stat -> assignment ? */ |
1230 | SETARG_C(getcode(fs, &v.v), 1); /* call statement uses no results */ | ||
1231 | else { /* stat -> assignment */ | ||
1232 | v.prev = NULL; | 1486 | v.prev = NULL; |
1233 | assignment(ls, &v, 1); | 1487 | assignment(ls, &v, 1); |
1234 | } | 1488 | } |
1489 | else { /* stat -> func */ | ||
1490 | check_condition(ls, v.v.k == VCALL, "syntax error"); | ||
1491 | SETARG_C(getcode(fs, &v.v), 1); /* call statement uses no results */ | ||
1492 | } | ||
1235 | } | 1493 | } |
1236 | 1494 | ||
1237 | 1495 | ||
1238 | static void retstat (LexState *ls) { | 1496 | static void retstat (LexState *ls) { |
1239 | /* stat -> RETURN explist */ | 1497 | /* stat -> RETURN [explist] [';'] */ |
1240 | FuncState *fs = ls->fs; | 1498 | FuncState *fs = ls->fs; |
1241 | expdesc e; | 1499 | expdesc e; |
1242 | int first, nret; /* registers with returned values */ | 1500 | int first, nret; /* registers with returned values */ |
1243 | luaX_next(ls); /* skip RETURN */ | 1501 | if (block_follow(ls, 1) || ls->t.token == ';') |
1244 | if (block_follow(ls->t.token) || ls->t.token == ';') | ||
1245 | first = nret = 0; /* return no values */ | 1502 | first = nret = 0; /* return no values */ |
1246 | else { | 1503 | else { |
1247 | nret = explist1(ls, &e); /* optional return values */ | 1504 | nret = explist(ls, &e); /* optional return values */ |
1248 | if (hasmultret(e.k)) { | 1505 | if (hasmultret(e.k)) { |
1249 | luaK_setmultret(fs, &e); | 1506 | luaK_setmultret(fs, &e); |
1250 | if (e.k == VCALL && nret == 1) { /* tail call? */ | 1507 | if (e.k == VCALL && nret == 1) { /* tail call? */ |
@@ -1265,37 +1522,43 @@ static void retstat (LexState *ls) { | |||
1265 | } | 1522 | } |
1266 | } | 1523 | } |
1267 | luaK_ret(fs, first, nret); | 1524 | luaK_ret(fs, first, nret); |
1525 | testnext(ls, ';'); /* skip optional semicolon */ | ||
1268 | } | 1526 | } |
1269 | 1527 | ||
1270 | 1528 | ||
1271 | static int statement (LexState *ls) { | 1529 | static void statement (LexState *ls) { |
1272 | int line = ls->linenumber; /* may be needed for error messages */ | 1530 | int line = ls->linenumber; /* may be needed for error messages */ |
1531 | enterlevel(ls); | ||
1273 | switch (ls->t.token) { | 1532 | switch (ls->t.token) { |
1533 | case ';': { /* stat -> ';' (empty statement) */ | ||
1534 | luaX_next(ls); /* skip ';' */ | ||
1535 | break; | ||
1536 | } | ||
1274 | case TK_IF: { /* stat -> ifstat */ | 1537 | case TK_IF: { /* stat -> ifstat */ |
1275 | ifstat(ls, line); | 1538 | ifstat(ls, line); |
1276 | return 0; | 1539 | break; |
1277 | } | 1540 | } |
1278 | case TK_WHILE: { /* stat -> whilestat */ | 1541 | case TK_WHILE: { /* stat -> whilestat */ |
1279 | whilestat(ls, line); | 1542 | whilestat(ls, line); |
1280 | return 0; | 1543 | break; |
1281 | } | 1544 | } |
1282 | case TK_DO: { /* stat -> DO block END */ | 1545 | case TK_DO: { /* stat -> DO block END */ |
1283 | luaX_next(ls); /* skip DO */ | 1546 | luaX_next(ls); /* skip DO */ |
1284 | block(ls); | 1547 | block(ls); |
1285 | check_match(ls, TK_END, TK_DO, line); | 1548 | check_match(ls, TK_END, TK_DO, line); |
1286 | return 0; | 1549 | break; |
1287 | } | 1550 | } |
1288 | case TK_FOR: { /* stat -> forstat */ | 1551 | case TK_FOR: { /* stat -> forstat */ |
1289 | forstat(ls, line); | 1552 | forstat(ls, line); |
1290 | return 0; | 1553 | break; |
1291 | } | 1554 | } |
1292 | case TK_REPEAT: { /* stat -> repeatstat */ | 1555 | case TK_REPEAT: { /* stat -> repeatstat */ |
1293 | repeatstat(ls, line); | 1556 | repeatstat(ls, line); |
1294 | return 0; | 1557 | break; |
1295 | } | 1558 | } |
1296 | case TK_FUNCTION: { | 1559 | case TK_FUNCTION: { /* stat -> funcstat */ |
1297 | funcstat(ls, line); /* stat -> funcstat */ | 1560 | funcstat(ls, line); |
1298 | return 0; | 1561 | break; |
1299 | } | 1562 | } |
1300 | case TK_LOCAL: { /* stat -> localstat */ | 1563 | case TK_LOCAL: { /* stat -> localstat */ |
1301 | luaX_next(ls); /* skip LOCAL */ | 1564 | luaX_next(ls); /* skip LOCAL */ |
@@ -1303,37 +1566,73 @@ static int statement (LexState *ls) { | |||
1303 | localfunc(ls); | 1566 | localfunc(ls); |
1304 | else | 1567 | else |
1305 | localstat(ls); | 1568 | localstat(ls); |
1306 | return 0; | 1569 | break; |
1570 | } | ||
1571 | case TK_DBCOLON: { /* stat -> label */ | ||
1572 | luaX_next(ls); /* skip double colon */ | ||
1573 | labelstat(ls, str_checkname(ls), line); | ||
1574 | break; | ||
1307 | } | 1575 | } |
1308 | case TK_RETURN: { /* stat -> retstat */ | 1576 | case TK_RETURN: { /* stat -> retstat */ |
1577 | luaX_next(ls); /* skip RETURN */ | ||
1309 | retstat(ls); | 1578 | retstat(ls); |
1310 | return 1; /* must be last statement */ | 1579 | break; |
1311 | } | 1580 | } |
1312 | case TK_BREAK: { /* stat -> breakstat */ | 1581 | case TK_BREAK: /* stat -> breakstat */ |
1313 | luaX_next(ls); /* skip BREAK */ | 1582 | case TK_GOTO: { /* stat -> 'goto' NAME */ |
1314 | breakstat(ls); | 1583 | gotostat(ls, luaK_jump(ls->fs)); |
1315 | return 1; /* must be last statement */ | 1584 | break; |
1316 | } | 1585 | } |
1317 | default: { | 1586 | default: { /* stat -> func | assignment */ |
1318 | exprstat(ls); | 1587 | exprstat(ls); |
1319 | return 0; /* to avoid warnings */ | 1588 | break; |
1320 | } | 1589 | } |
1321 | } | 1590 | } |
1591 | lua_assert(ls->fs->f->maxstacksize >= ls->fs->freereg && | ||
1592 | ls->fs->freereg >= ls->fs->nactvar); | ||
1593 | ls->fs->freereg = ls->fs->nactvar; /* free registers */ | ||
1594 | leavelevel(ls); | ||
1322 | } | 1595 | } |
1323 | 1596 | ||
1597 | /* }====================================================================== */ | ||
1324 | 1598 | ||
1325 | static void chunk (LexState *ls) { | 1599 | |
1326 | /* chunk -> { stat [`;'] } */ | 1600 | /* |
1327 | int islast = 0; | 1601 | ** compiles the main function, which is a regular vararg function with an |
1328 | enterlevel(ls); | 1602 | ** upvalue named LUA_ENV |
1329 | while (!islast && !block_follow(ls->t.token)) { | 1603 | */ |
1330 | islast = statement(ls); | 1604 | static void mainfunc (LexState *ls, FuncState *fs) { |
1331 | testnext(ls, ';'); | 1605 | BlockCnt bl; |
1332 | lua_assert(ls->fs->f->maxstacksize >= ls->fs->freereg && | 1606 | expdesc v; |
1333 | ls->fs->freereg >= ls->fs->nactvar); | 1607 | open_func(ls, fs, &bl); |
1334 | ls->fs->freereg = ls->fs->nactvar; /* free registers */ | 1608 | fs->f->is_vararg = 1; /* main function is always vararg */ |
1335 | } | 1609 | init_exp(&v, VLOCAL, 0); /* create and... */ |
1336 | leavelevel(ls); | 1610 | newupvalue(fs, ls->envn, &v); /* ...set environment upvalue */ |
1611 | luaX_next(ls); /* read first token */ | ||
1612 | statlist(ls); /* parse main body */ | ||
1613 | check(ls, TK_EOS); | ||
1614 | close_func(ls); | ||
1615 | } | ||
1616 | |||
1617 | |||
1618 | Closure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, | ||
1619 | Dyndata *dyd, const char *name, int firstchar) { | ||
1620 | LexState lexstate; | ||
1621 | FuncState funcstate; | ||
1622 | Closure *cl = luaF_newLclosure(L, 1); /* create main closure */ | ||
1623 | /* anchor closure (to avoid being collected) */ | ||
1624 | setclLvalue(L, L->top, cl); | ||
1625 | incr_top(L); | ||
1626 | funcstate.f = cl->l.p = luaF_newproto(L); | ||
1627 | funcstate.f->source = luaS_new(L, name); /* create and anchor TString */ | ||
1628 | lexstate.buff = buff; | ||
1629 | lexstate.dyd = dyd; | ||
1630 | dyd->actvar.n = dyd->gt.n = dyd->label.n = 0; | ||
1631 | luaX_setinput(L, &lexstate, z, funcstate.f->source, firstchar); | ||
1632 | mainfunc(&lexstate, &funcstate); | ||
1633 | lua_assert(!funcstate.prev && funcstate.nups == 1 && !lexstate.fs); | ||
1634 | /* all scopes should be correctly finished */ | ||
1635 | lua_assert(dyd->actvar.n == 0 && dyd->gt.n == 0 && dyd->label.n == 0); | ||
1636 | return cl; /* it's on the stack too */ | ||
1337 | } | 1637 | } |
1338 | 1638 | ||
1339 | /* }====================================================================== */ | ||