diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2018-11-07 14:42:05 -0200 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2018-11-07 14:42:05 -0200 |
| commit | 7f6f70853c8a2730fca2e95d5968ad52cf470bda (patch) | |
| tree | 948147a9cf6a5c5eb34232e7547c310eb06eadea /lparser.c | |
| parent | b8fed93215a23a3f443c5b0126f0de1725771b44 (diff) | |
| download | lua-7f6f70853c8a2730fca2e95d5968ad52cf470bda.tar.gz lua-7f6f70853c8a2730fca2e95d5968ad52cf470bda.tar.bz2 lua-7f6f70853c8a2730fca2e95d5968ad52cf470bda.zip | |
To-be-closed variable in 'for' loop separated from the state
The variable to be closed in a generic 'for' loop now is the
4th value produced in the loop initialization, instead of being
the loop state (the 2nd value produced). That allows a loop to
use a state with a '__toclose' metamethod but do not close it.
(As an example, 'f:lines()' might use the file 'f' as a state
for the loop, but it should not close the file when the loop ends.)
Diffstat (limited to 'lparser.c')
| -rw-r--r-- | lparser.c | 25 |
1 files changed, 14 insertions, 11 deletions
| @@ -165,6 +165,9 @@ static int registerlocalvar (LexState *ls, TString *varname) { | |||
| 165 | } | 165 | } |
| 166 | 166 | ||
| 167 | 167 | ||
| 168 | /* | ||
| 169 | ** Create a new local variable with the given 'name'. | ||
| 170 | */ | ||
| 168 | static void new_localvar (LexState *ls, TString *name) { | 171 | static void new_localvar (LexState *ls, TString *name) { |
| 169 | FuncState *fs = ls->fs; | 172 | FuncState *fs = ls->fs; |
| 170 | Dyndata *dyd = ls->dyd; | 173 | Dyndata *dyd = ls->dyd; |
| @@ -176,13 +179,8 @@ static void new_localvar (LexState *ls, TString *name) { | |||
| 176 | dyd->actvar.arr[dyd->actvar.n++].idx = cast(short, reg); | 179 | dyd->actvar.arr[dyd->actvar.n++].idx = cast(short, reg); |
| 177 | } | 180 | } |
| 178 | 181 | ||
| 179 | |||
| 180 | static void new_localvarliteral_ (LexState *ls, const char *name, size_t sz) { | ||
| 181 | new_localvar(ls, luaX_newstring(ls, name, sz)); | ||
| 182 | } | ||
| 183 | |||
| 184 | #define new_localvarliteral(ls,v) \ | 182 | #define new_localvarliteral(ls,v) \ |
| 185 | new_localvarliteral_(ls, "" v, (sizeof(v)/sizeof(char))-1) | 183 | new_localvar(ls, luaX_newstring(ls, "" v, (sizeof(v)/sizeof(char)) - 1)); |
| 186 | 184 | ||
| 187 | 185 | ||
| 188 | static LocVar *getlocvar (FuncState *fs, int i) { | 186 | static LocVar *getlocvar (FuncState *fs, int i) { |
| @@ -192,6 +190,9 @@ static LocVar *getlocvar (FuncState *fs, int i) { | |||
| 192 | } | 190 | } |
| 193 | 191 | ||
| 194 | 192 | ||
| 193 | /* | ||
| 194 | ** Start the scope for the last 'nvars' created variables. | ||
| 195 | */ | ||
| 195 | static void adjustlocalvars (LexState *ls, int nvars) { | 196 | static void adjustlocalvars (LexState *ls, int nvars) { |
| 196 | FuncState *fs = ls->fs; | 197 | FuncState *fs = ls->fs; |
| 197 | fs->nactvar = cast_byte(fs->nactvar + nvars); | 198 | fs->nactvar = cast_byte(fs->nactvar + nvars); |
| @@ -1357,7 +1358,6 @@ static void forbody (LexState *ls, int base, int line, int nvars, int kind) { | |||
| 1357 | BlockCnt bl; | 1358 | BlockCnt bl; |
| 1358 | FuncState *fs = ls->fs; | 1359 | FuncState *fs = ls->fs; |
| 1359 | int prep, endfor; | 1360 | int prep, endfor; |
| 1360 | adjustlocalvars(ls, 3); /* control variables */ | ||
| 1361 | checknext(ls, TK_DO); | 1361 | checknext(ls, TK_DO); |
| 1362 | prep = luaK_codeABx(fs, forprep[kind], base, 0); | 1362 | prep = luaK_codeABx(fs, forprep[kind], base, 0); |
| 1363 | enterblock(fs, &bl, 0); /* scope for declared variables */ | 1363 | enterblock(fs, &bl, 0); /* scope for declared variables */ |
| @@ -1399,6 +1399,7 @@ static void fornum (LexState *ls, TString *varname, int line) { | |||
| 1399 | luaK_int(fs, fs->freereg, 1); | 1399 | luaK_int(fs, fs->freereg, 1); |
| 1400 | luaK_reserveregs(fs, 1); | 1400 | luaK_reserveregs(fs, 1); |
| 1401 | } | 1401 | } |
| 1402 | adjustlocalvars(ls, 3); /* control variables */ | ||
| 1402 | forbody(ls, base, line, 1, basicfor); | 1403 | forbody(ls, base, line, 1, basicfor); |
| 1403 | } | 1404 | } |
| 1404 | 1405 | ||
| @@ -1407,7 +1408,7 @@ static void forlist (LexState *ls, TString *indexname) { | |||
| 1407 | /* forlist -> NAME {,NAME} IN explist forbody */ | 1408 | /* forlist -> NAME {,NAME} IN explist forbody */ |
| 1408 | FuncState *fs = ls->fs; | 1409 | FuncState *fs = ls->fs; |
| 1409 | expdesc e; | 1410 | expdesc e; |
| 1410 | int nvars = 4; /* gen, state, control, plus at least one declared var */ | 1411 | int nvars = 5; /* gen, state, control, toclose, 'indexname' */ |
| 1411 | int line; | 1412 | int line; |
| 1412 | int base = fs->freereg; | 1413 | int base = fs->freereg; |
| 1413 | /* create control variables */ | 1414 | /* create control variables */ |
| @@ -1415,6 +1416,7 @@ static void forlist (LexState *ls, TString *indexname) { | |||
| 1415 | new_localvarliteral(ls, "(for state)"); | 1416 | new_localvarliteral(ls, "(for state)"); |
| 1416 | markupval(fs, fs->nactvar); /* state may create an upvalue */ | 1417 | markupval(fs, fs->nactvar); /* state may create an upvalue */ |
| 1417 | new_localvarliteral(ls, "(for control)"); | 1418 | new_localvarliteral(ls, "(for control)"); |
| 1419 | new_localvarliteral(ls, "(for toclose)"); | ||
| 1418 | /* create declared variables */ | 1420 | /* create declared variables */ |
| 1419 | new_localvar(ls, indexname); | 1421 | new_localvar(ls, indexname); |
| 1420 | while (testnext(ls, ',')) { | 1422 | while (testnext(ls, ',')) { |
| @@ -1423,9 +1425,10 @@ static void forlist (LexState *ls, TString *indexname) { | |||
| 1423 | } | 1425 | } |
| 1424 | checknext(ls, TK_IN); | 1426 | checknext(ls, TK_IN); |
| 1425 | line = ls->linenumber; | 1427 | line = ls->linenumber; |
| 1426 | adjust_assign(ls, 3, explist(ls, &e), &e); | 1428 | adjust_assign(ls, 4, explist(ls, &e), &e); |
| 1429 | adjustlocalvars(ls, 4); /* control variables */ | ||
| 1427 | luaK_checkstack(fs, 3); /* extra space to call generator */ | 1430 | luaK_checkstack(fs, 3); /* extra space to call generator */ |
| 1428 | forbody(ls, base, line, nvars - 3, 2); | 1431 | forbody(ls, base, line, nvars - 4, 2); |
| 1429 | } | 1432 | } |
| 1430 | 1433 | ||
| 1431 | 1434 | ||
| @@ -1575,9 +1578,9 @@ static void tocloselocalstat (LexState *ls) { | |||
| 1575 | new_localvar(ls, str_checkname(ls)); | 1578 | new_localvar(ls, str_checkname(ls)); |
| 1576 | checknext(ls, '='); | 1579 | checknext(ls, '='); |
| 1577 | exp1(ls, 0); | 1580 | exp1(ls, 0); |
| 1578 | luaK_codeABC(fs, OP_TBC, fs->nactvar, 0, 0); | ||
| 1579 | markupval(fs, fs->nactvar); | 1581 | markupval(fs, fs->nactvar); |
| 1580 | adjustlocalvars(ls, 1); | 1582 | adjustlocalvars(ls, 1); |
| 1583 | luaK_codeABC(fs, OP_TBC, fs->nactvar - 1, 0, 0); | ||
| 1581 | } | 1584 | } |
| 1582 | 1585 | ||
| 1583 | 1586 | ||
