aboutsummaryrefslogtreecommitdiff
path: root/lparser.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2018-10-08 10:42:07 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2018-10-08 10:42:07 -0300
commit4cd1f4aac01184765818e0cebf02da454ccf6590 (patch)
treec7e6398095afccc9987ed42598477094b6ee2aa6 /lparser.c
parentb114c7d4871051cbdd7af185a61f35fe4028da79 (diff)
downloadlua-4cd1f4aac01184765818e0cebf02da454ccf6590.tar.gz
lua-4cd1f4aac01184765818e0cebf02da454ccf6590.tar.bz2
lua-4cd1f4aac01184765818e0cebf02da454ccf6590.zip
Towards "to closed" local variables
Start of the implementation of "scoped variables" or "to be closed" variables, local variables whose '__close' (or themselves) are called when they go out of scope. This commit implements the syntax, the opcode, and the creation of the corresponding upvalue, but it still does not call the finalizations when the variable goes out of scope (the most important part). Currently, the syntax is 'local scoped name = exp', but that will probably change.
Diffstat (limited to 'lparser.c')
-rw-r--r--lparser.c34
1 files changed, 30 insertions, 4 deletions
diff --git a/lparser.c b/lparser.c
index 32500b02..84abeb90 100644
--- a/lparser.c
+++ b/lparser.c
@@ -255,6 +255,7 @@ static void markupval (FuncState *fs, int level) {
255 while (bl->nactvar > level) 255 while (bl->nactvar > level)
256 bl = bl->previous; 256 bl = bl->previous;
257 bl->upval = 1; 257 bl->upval = 1;
258 fs->needclose = 1;
258} 259}
259 260
260 261
@@ -547,6 +548,7 @@ static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) {
547 fs->nups = 0; 548 fs->nups = 0;
548 fs->nlocvars = 0; 549 fs->nlocvars = 0;
549 fs->nactvar = 0; 550 fs->nactvar = 0;
551 fs->needclose = 0;
550 fs->firstlocal = ls->dyd->actvar.n; 552 fs->firstlocal = ls->dyd->actvar.n;
551 fs->bl = NULL; 553 fs->bl = NULL;
552 f->source = ls->source; 554 f->source = ls->source;
@@ -1509,15 +1511,16 @@ static void localfunc (LexState *ls) {
1509} 1511}
1510 1512
1511 1513
1512static void localstat (LexState *ls) { 1514static void commonlocalstat (LexState *ls, TString *firstvar) {
1513 /* stat -> LOCAL NAME {',' NAME} ['=' explist] */ 1515 /* stat -> LOCAL NAME {',' NAME} ['=' explist] */
1514 int nvars = 0; 1516 int nvars = 1;
1515 int nexps; 1517 int nexps;
1516 expdesc e; 1518 expdesc e;
1517 do { 1519 new_localvar(ls, firstvar);
1520 while (testnext(ls, ',')) {
1518 new_localvar(ls, str_checkname(ls)); 1521 new_localvar(ls, str_checkname(ls));
1519 nvars++; 1522 nvars++;
1520 } while (testnext(ls, ',')); 1523 }
1521 if (testnext(ls, '=')) 1524 if (testnext(ls, '='))
1522 nexps = explist(ls, &e); 1525 nexps = explist(ls, &e);
1523 else { 1526 else {
@@ -1529,6 +1532,29 @@ static void localstat (LexState *ls) {
1529} 1532}
1530 1533
1531 1534
1535static void scopedlocalstat (LexState *ls) {
1536 FuncState *fs = ls->fs;
1537 new_localvar(ls, str_checkname(ls));
1538 checknext(ls, '=');
1539 luaK_codeABC(fs, OP_TBC, fs->nactvar, 0, 0);
1540 markupval(fs, fs->nactvar);
1541 exp1(ls, 0);
1542 adjustlocalvars(ls, 1);
1543}
1544
1545
1546static void localstat (LexState *ls) {
1547 /* stat -> LOCAL NAME {',' NAME} ['=' explist]
1548 | LOCAL SCOPED NAME '=' exp */
1549 TString *firstvar = str_checkname(ls);
1550 if (ls->t.token == TK_NAME &&
1551 eqshrstr(firstvar, luaS_newliteral(ls->L, "scoped")))
1552 scopedlocalstat(ls);
1553 else
1554 commonlocalstat(ls, firstvar);
1555}
1556
1557
1532static int funcname (LexState *ls, expdesc *v) { 1558static int funcname (LexState *ls, expdesc *v) {
1533 /* funcname -> NAME {fieldsel} [':' NAME] */ 1559 /* funcname -> NAME {fieldsel} [':' NAME] */
1534 int ismethod = 0; 1560 int ismethod = 0;