diff -urN lua-5.1/src/lparser.c lua-5.1-new/src/lparser.c --- lua-5.1/src/lparser.c 2005年12月22日 11:19:56.000000000 -0500 +++ lua-5.1-new/src/lparser.c 2006年02月19日 01:05:32.000000000 -0500 @@ -927,8 +927,33 @@ } -static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) { +static void getfrom (LexState *ls, expdesc *e, expdesc *v) +{ + expdesc key; + int k = v->k; + + if (k == VLOCAL) { + codestring(ls, &key, getlocvar(ls->fs, v->u.s.info).varname); + } + else if (k == VUPVAL) { + codestring(ls, &key, ls->fs->f->upvalues[v->u.s.info]); + } + else if (k== VGLOBAL) { + init_exp(&key, VK, v->u.s.info); + } + else { + check_condition(ls, VLOCAL <= k && k <= VGLOBAL, + "syntax error in from 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, VLOCAL <= lh->v.k && lh->v.k <= VINDEXED, "syntax error"); if (testnext(ls, ',')) { /* assignment -> `,' primaryexp assignment */ @@ -937,25 +962,44 @@ primaryexp(ls, &nv.v); if (nv.v.k == VLOCAL) check_conflict(ls, lh, &nv.v); - assignment(ls, &nv, nvars+1); + from = assignment(ls, &nv, nvars+1, from_var); } - else { /* assignment -> `=' explist1 */ + else { /* assignment -> IN primaryexp | `=' explist1 */ int nexps; - checknext(ls, '='); - nexps = explist1(ls, &e); - if (nexps != nvars) { - adjust_assign(ls, nvars, nexps, &e); - if (nexps> nvars) - ls->fs->freereg -= nexps - nvars; /* remove extra values */ + + if (testnext(ls, TK_IN)) { + new_localvarliteral(ls, "(from)", 0); + 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, &e, &lh->v); + luaK_storevar(ls->fs, &lh->v, &e); + return 1; /* avoid default */ } else { + checknext(ls, '='); + nexps = explist1(ls, &e); + } + + if (nexps == nvars) { luaK_setoneret(ls->fs, &e); /* close last expression */ luaK_storevar(ls->fs, &lh->v, &e); - return; /* avoid default */ + return 0; /* avoid default */ + } + else { + adjust_assign(ls, nvars, nexps, &e); + if (nexps> nvars) + ls->fs->freereg -= nexps - nvars; /* remove extra values */ } } + init_exp(&e, VNONRELOC, ls->fs->freereg-1); /* default assignment */ + if (from) getfrom(ls, &e, &lh->v); luaK_storevar(ls->fs, &lh->v, &e); + return from; } @@ -1174,13 +1218,40 @@ static void localstat (LexState *ls) { - /* stat -> LOCAL NAME {`,' NAME} [`=' explist1] */ + /* stat -> LOCAL NAME {`,' NAME} [ IN primaryexp | `=' explist1] */ int nvars = 0; int nexps; expdesc e; do { 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)", 0); + 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; nexps
fs->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, from_var); + return; + } if (testnext(ls, '=')) nexps = explist1(ls, &e); else { @@ -1226,8 +1297,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, from_var); } }
AltStyle
によって変換されたページ
(->オリジナル)
/
アドレス:
モード:
デフォルト
音声ブラウザ
ルビ付き
配色反転
文字拡大
モバイル