aboutsummaryrefslogtreecommitdiff
path: root/lparser.c
diff options
context:
space:
mode:
Diffstat (limited to 'lparser.c')
-rw-r--r--lparser.c62
1 files changed, 47 insertions, 15 deletions
diff --git a/lparser.c b/lparser.c
index 935526ce..1ab1cc69 100644
--- a/lparser.c
+++ b/lparser.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lparser.c,v 2.66 2009/09/23 20:14:00 roberto Exp roberto $ 2** $Id: lparser.c,v 2.67 2009/09/28 16:32:50 roberto Exp roberto $
3** Lua Parser 3** Lua Parser
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -227,10 +227,8 @@ static void markupval (FuncState *fs, int level) {
227 227
228 228
229static int singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) { 229static int singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) {
230 if (fs == NULL) { /* no more levels? */ 230 if (fs == NULL) /* no more levels? */
231 init_exp(var, VGLOBAL, NO_REG); /* default is global variable */ 231 return VGLOBAL; /* default is global variable */
232 return VGLOBAL;
233 }
234 else { 232 else {
235 int v = searchvar(fs, n); /* look up at current level */ 233 int v = searchvar(fs, n); /* look up at current level */
236 if (v >= 0) { 234 if (v >= 0) {
@@ -253,8 +251,16 @@ static int singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) {
253static void singlevar (LexState *ls, expdesc *var) { 251static void singlevar (LexState *ls, expdesc *var) {
254 TString *varname = str_checkname(ls); 252 TString *varname = str_checkname(ls);
255 FuncState *fs = ls->fs; 253 FuncState *fs = ls->fs;
256 if (singlevaraux(fs, varname, var, 1) == VGLOBAL) 254 if (singlevaraux(fs, varname, var, 1) == VGLOBAL) {
257 var->u.s.info = luaK_stringK(fs, varname); /* info points to global name */ 255 if (fs->envreg == NO_REG) /* regular global? */
256 init_exp(var, VGLOBAL, luaK_stringK(fs, varname));
257 else { /* "globals" are in current lexical environment */
258 expdesc key;
259 init_exp(var, VLOCAL, fs->envreg); /* current environment */
260 codestring(ls, &key, varname); /* key is variable name */
261 luaK_indexed(fs, var, &key); /* env[varname] */
262 }
263 }
258} 264}
259 265
260 266
@@ -313,15 +319,17 @@ static void leaveblock (FuncState *fs) {
313} 319}
314 320
315 321
316static void pushclosure (LexState *ls, FuncState *func, expdesc *v) { 322static void pushclosure (LexState *ls, Proto *clp, expdesc *v) {
317 FuncState *fs = ls->fs->prev; 323 FuncState *fs = ls->fs->prev;
318 Proto *f = fs->f; 324 Proto *f = fs->f; /* prototype of function creating new closure */
319 int oldsize = f->sizep; 325 int oldsize = f->sizep;
320 luaM_growvector(ls->L, f->p, fs->np, f->sizep, Proto *, 326 luaM_growvector(ls->L, f->p, fs->np, f->sizep, Proto *,
321 MAXARG_Bx, "functions"); 327 MAXARG_Bx, "functions");
322 while (oldsize < f->sizep) f->p[oldsize++] = NULL; 328 while (oldsize < f->sizep) f->p[oldsize++] = NULL;
323 f->p[fs->np++] = func->f; 329 f->p[fs->np++] = clp;
324 luaC_objbarrier(ls->L, f, func->f); 330 /* initial environment for new function is current lexical environment */
331 clp->envreg = fs->envreg;
332 luaC_objbarrier(ls->L, f, clp);
325 init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np-1)); 333 init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np-1));
326} 334}
327 335
@@ -342,6 +350,7 @@ static void open_func (LexState *ls, FuncState *fs) {
342 fs->nups = 0; 350 fs->nups = 0;
343 fs->nlocvars = 0; 351 fs->nlocvars = 0;
344 fs->nactvar = 0; 352 fs->nactvar = 0;
353 fs->envreg = NO_REG;
345 fs->bl = NULL; 354 fs->bl = NULL;
346 fs->h = luaH_new(L); 355 fs->h = luaH_new(L);
347 /* anchor table of constants (to avoid being collected) */ 356 /* anchor table of constants (to avoid being collected) */
@@ -589,7 +598,7 @@ static void body (LexState *ls, expdesc *e, int needself, int line) {
589 chunk(ls); 598 chunk(ls);
590 new_fs.f->lastlinedefined = ls->linenumber; 599 new_fs.f->lastlinedefined = ls->linenumber;
591 check_match(ls, TK_END, TK_FUNCTION, line); 600 check_match(ls, TK_END, TK_FUNCTION, line);
592 pushclosure(ls, &new_fs, e); 601 pushclosure(ls, new_fs.f, e);
593 close_func(ls); 602 close_func(ls);
594} 603}
595 604
@@ -1035,11 +1044,12 @@ static void repeatstat (LexState *ls, int line) {
1035 1044
1036static int exp1 (LexState *ls) { 1045static int exp1 (LexState *ls) {
1037 expdesc e; 1046 expdesc e;
1038 int k; 1047 int reg;
1039 expr(ls, &e); 1048 expr(ls, &e);
1040 k = e.k;
1041 luaK_exp2nextreg(ls->fs, &e); 1049 luaK_exp2nextreg(ls->fs, &e);
1042 return k; 1050 lua_assert(e.k == VNONRELOC);
1051 reg = e.u.s.info;
1052 return reg;
1043} 1053}
1044 1054
1045 1055
@@ -1226,6 +1236,24 @@ static void funcstat (LexState *ls, int line) {
1226} 1236}
1227 1237
1228 1238
1239static void instat (LexState *ls, int line) {
1240 /* instat -> IN exp DO block END */
1241 FuncState *fs = ls->fs;
1242 int oldenv = fs->envreg; /* save current environment */
1243 BlockCnt bl;
1244 luaX_next(ls); /* skip IN */
1245 enterblock(fs, &bl, 0); /* scope for environment variable */
1246 new_localvarliteral(ls, "(environment)", 0);
1247 fs->envreg = exp1(ls); /* new environment */
1248 adjustlocalvars(ls, 1);
1249 checknext(ls, TK_DO);
1250 block(ls);
1251 leaveblock(fs);
1252 check_match(ls, TK_END, TK_IN, line);
1253 fs->envreg = oldenv; /* restore outer environment */
1254}
1255
1256
1229static void exprstat (LexState *ls) { 1257static void exprstat (LexState *ls) {
1230 /* stat -> func | assignment */ 1258 /* stat -> func | assignment */
1231 FuncState *fs = ls->fs; 1259 FuncState *fs = ls->fs;
@@ -1290,6 +1318,10 @@ static int statement (LexState *ls) {
1290 check_match(ls, TK_END, TK_DO, line); 1318 check_match(ls, TK_END, TK_DO, line);
1291 return 0; 1319 return 0;
1292 } 1320 }
1321 case TK_IN: {
1322 instat(ls, line);
1323 return 0;
1324 }
1293 case TK_FOR: { /* stat -> forstat */ 1325 case TK_FOR: { /* stat -> forstat */
1294 forstat(ls, line); 1326 forstat(ls, line);
1295 return 0; 1327 return 0;