--- lparser.c Fri Dec 2 21:23:56 2011 +++ lparser.c Sat Feb 18 06:42:31 2012 @@ -1138,8 +1138,26 @@ } -static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) { +static void getfrom (LexState *ls, expdesc *v, expdesc *e) { + expdesc key; + if (v->k == VLOCAL) + codestring(ls, &key, getlocvar(ls->fs, v->u.info)->varname); + else if (v->k == VUPVAL) + codestring(ls, &key, ls->fs->f->upvalues[v->u.info].name); + else if (v->k == VINDEXED) { + lua_assert(ISK(v->u.ind.idx)); + init_exp(&key, VK, INDEXK(v->u.ind.idx)); + } + else + check_condition(ls, vkisvar(v->k), + "syntax error in " LUA_QL("in") " vars"); + luaK_indexed(ls->fs, e, &key); +} + + +static int assignment (LexState *ls, struct LHS_assign *lh, int nvars, lu_byte *from_var) { expdesc e; + int from = 0; check_condition(ls, vkisvar(lh->v.k), "syntax error"); if (testnext(ls, ',')) { /* assignment -> `,' primaryexp assignment */ struct LHS_assign nv; @@ -1149,12 +1167,25 @@ check_conflict(ls, lh, &nv.v); checklimit(ls->fs, nvars + ls->L->nCcalls, LUAI_MAXCCALLS, "C levels"); - assignment(ls, &nv, nvars+1); + from = assignment(ls, &nv, nvars+1, from_var); } - else { /* assignment -> `=' explist */ + else { /* assignment -> IN primaryexp | `=' explist */ int nexps; - checknext(ls, '='); - nexps = explist(ls, &e); + if (testnext(ls, TK_IN)) { + new_localvarliteral(ls, "(from)"); + primaryexp(ls, &e); + luaK_exp2nextreg(ls->fs, &e); + *from_var = ls->fs->nactvar; + adjustlocalvars(ls, 1); + luaK_setoneret(ls->fs, &e); /* close last expression */ + getfrom(ls, &lh->v, &e); + luaK_storevar(ls->fs, &lh->v, &e); + return 1; /* avoid default */ + } + else { + checknext(ls, '='); + nexps = explist(ls, &e); + } if (nexps != nvars) { adjust_assign(ls, nvars, nexps, &e); if (nexps> nvars) @@ -1163,11 +1194,13 @@ else { luaK_setoneret(ls->fs, &e); /* close last expression */ luaK_storevar(ls->fs, &lh->v, &e); - return; /* avoid default */ + return 0; /* avoid default */ } } init_exp(&e, VNONRELOC, ls->fs->freereg-1); /* default assignment */ + if (from) getfrom(ls, &lh->v, &e); luaK_storevar(ls->fs, &lh->v, &e); + return from; } @@ -1431,7 +1464,7 @@ static void localstat (LexState *ls) { - /* stat -> LOCAL NAME {`,' NAME} [`=' explist] */ + /* stat -> LOCAL NAME {`,' NAME} [IN primaryexp | `=' explist] */ int nvars = 0; int nexps; expdesc e; @@ -1439,6 +1472,29 @@ new_localvar(ls, str_checkname(ls)); nvars++; } while (testnext(ls, ',')); + if (testnext(ls, TK_IN)) { + lu_byte from_var; + int regs = ls->fs->freereg; + int vars = ls->fs->nactvar; + luaK_reserveregs(ls->fs, nvars); + adjustlocalvars(ls, nvars); + new_localvarliteral(ls, "(from)"); + primaryexp(ls, &e); + luaK_exp2nextreg(ls->fs, &e); + from_var = ls->fs->nactvar; + adjustlocalvars(ls, 1); + luaK_setoneret(ls->fs, &e); /* close last expression */ + for (nexps=0; nexpsfs->freereg-1); + codestring(ls, &key, getlocvar(ls->fs, vars+nexps)->varname); + luaK_indexed(ls->fs, &e, &key); + init_exp(&v, VLOCAL, regs+nexps); + luaK_storevar(ls->fs, &v, &e); + } + removevars(ls->fs, from_var); + return; + } if (testnext(ls, '=')) nexps = explist(ls, &e); else { @@ -1484,8 +1540,10 @@ if (v.v.k == VCALL) /* stat -> func */ SETARG_C(getcode(fs, &v.v), 1); /* call statement uses no results */ else { /* stat -> assignment */ + lu_byte from_var; v.prev = NULL; - assignment(ls, &v, 1); + if (assignment(ls, &v, 1, &from_var)) + removevars(ls->fs, from_var); } }

AltStyle によって変換されたページ (->オリジナル) /