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.
This commit is contained in:
34
lparser.c
34
lparser.c
@@ -255,6 +255,7 @@ static void markupval (FuncState *fs, int level) {
|
||||
while (bl->nactvar > level)
|
||||
bl = bl->previous;
|
||||
bl->upval = 1;
|
||||
fs->needclose = 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -547,6 +548,7 @@ static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) {
|
||||
fs->nups = 0;
|
||||
fs->nlocvars = 0;
|
||||
fs->nactvar = 0;
|
||||
fs->needclose = 0;
|
||||
fs->firstlocal = ls->dyd->actvar.n;
|
||||
fs->bl = NULL;
|
||||
f->source = ls->source;
|
||||
@@ -1509,15 +1511,16 @@ static void localfunc (LexState *ls) {
|
||||
}
|
||||
|
||||
|
||||
static void localstat (LexState *ls) {
|
||||
static void commonlocalstat (LexState *ls, TString *firstvar) {
|
||||
/* stat -> LOCAL NAME {',' NAME} ['=' explist] */
|
||||
int nvars = 0;
|
||||
int nvars = 1;
|
||||
int nexps;
|
||||
expdesc e;
|
||||
do {
|
||||
new_localvar(ls, firstvar);
|
||||
while (testnext(ls, ',')) {
|
||||
new_localvar(ls, str_checkname(ls));
|
||||
nvars++;
|
||||
} while (testnext(ls, ','));
|
||||
}
|
||||
if (testnext(ls, '='))
|
||||
nexps = explist(ls, &e);
|
||||
else {
|
||||
@@ -1529,6 +1532,29 @@ static void localstat (LexState *ls) {
|
||||
}
|
||||
|
||||
|
||||
static void scopedlocalstat (LexState *ls) {
|
||||
FuncState *fs = ls->fs;
|
||||
new_localvar(ls, str_checkname(ls));
|
||||
checknext(ls, '=');
|
||||
luaK_codeABC(fs, OP_TBC, fs->nactvar, 0, 0);
|
||||
markupval(fs, fs->nactvar);
|
||||
exp1(ls, 0);
|
||||
adjustlocalvars(ls, 1);
|
||||
}
|
||||
|
||||
|
||||
static void localstat (LexState *ls) {
|
||||
/* stat -> LOCAL NAME {',' NAME} ['=' explist]
|
||||
| LOCAL SCOPED NAME '=' exp */
|
||||
TString *firstvar = str_checkname(ls);
|
||||
if (ls->t.token == TK_NAME &&
|
||||
eqshrstr(firstvar, luaS_newliteral(ls->L, "scoped")))
|
||||
scopedlocalstat(ls);
|
||||
else
|
||||
commonlocalstat(ls, firstvar);
|
||||
}
|
||||
|
||||
|
||||
static int funcname (LexState *ls, expdesc *v) {
|
||||
/* funcname -> NAME {fieldsel} [':' NAME] */
|
||||
int ismethod = 0;
|
||||
|
||||
Reference in New Issue
Block a user