static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) { expdesc e; check_condition(ls, VLOCAL <= lh->v.k && lh->v.k <= VINDEXED, "syntax error"); if (testnext(ls, ',')) { /* assignment -> `,' primaryexp assignment */ struct LHS_assign nv; nv.prev = lh; primaryexp(ls, &nv.v); if (nv.v.k == VLOCAL) check_conflict(ls, lh, &nv.v); luaY_checklimit(ls->fs, nvars, LUAI_MAXCCALLS - ls->L->nCcalls, "variables in assignment"); assignment(ls, &nv, nvars+1); } else { /* assignment -> `=' 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 */ } else { luaK_setoneret(ls->fs, &e); /* close last expression */ luaK_storevar(ls->fs, &lh->v, &e); return; /* avoid default */ } } init_exp(&e, VNONRELOC, ls->fs->freereg-1); /* default assignment */ luaK_storevar(ls->fs, &lh->v, &e); }
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 */ struct LHS_assign nv; nv.prev = lh; primaryexp(ls, &nv.v); if (nv.v.k == VLOCAL) check_conflict(ls, lh, &nv.v); luaY_checklimit(ls->fs, nvars, LUAI_MAXCCALLS - ls->L->nCcalls, "variables in assignment"); from = assignment(ls, &nv, nvars+1, from_var); } else { /* assignment -> IN primaryexp | `=' explist1 */ int nexps; 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 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; }
static void assignment (LexState *ls, struct LHS_assign *lh, int nvars, BinOpr *opr) { expdesc e; check_condition(ls, VLOCAL <= lh->v.k && lh->v.k <= VINDEXED, "syntax error"); if (testnext(ls, ',')) { /* assignment -> `,' primaryexp assignment */ struct LHS_assign nv; nv.prev = lh; primaryexp(ls, &nv.v); if (nv.v.k == VLOCAL) check_conflict(ls, lh, &nv.v); assignment(ls, &nv, nvars+1, opr); } else { /* assignment -> `=' explist1 */ int nexps; *opr = OPR_NOBINOPR; switch(ls->t.token) { case '=': break; case TK_CONCATASSIGN: *opr = OPR_CONCAT; break; case TK_ADDASSIGN: *opr = OPR_ADD; break; case TK_SUBASSIGN: *opr = OPR_SUB; break; case TK_MULASSIGN: *opr = OPR_MUL; break; case TK_DIVASSIGN: *opr = OPR_DIV; break; case TK_POWASSIGN: *opr = OPR_POW; break; case TK_MODASSIGN: *opr = OPR_MOD; break; default: luaX_syntaxerror(ls, "unexpected symbol"); break; }; luaX_next(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 */ } else { luaK_setoneret(ls->fs, &e); /* close last expression */ luaK_storevar(ls->fs, &lh->v, &e, *opr); return; /* avoid default */ } } init_exp(&e, VNONRELOC, ls->fs->freereg-1); /* default assignment */ luaK_storevar(ls->fs, &lh->v, &e, *opr); }
static void localfunc (LexState *ls) { expdesc v, b; new_localvar(ls, str_checkname(ls), 0); init_exp(&v, VLOCAL, ls->fs->freereg++); adjustlocalvars(ls, 1); body(ls, &b, 0, ls->linenumber); luaK_storevar(ls->fs, &v, &b); }
static void funcstat (LexState *ls, int line) { /* funcstat -> FUNCTION funcname body */ int needself; expdesc v, b; luaX_next(ls); /* skip FUNCTION */ needself = funcname(ls, &v); body(ls, &b, needself, line); luaK_storevar(ls->fs, &v, &b); luaK_fixline(ls->fs, line); /* definition `happens' in the first line */ }
static void localfunc (LexState *ls) { expdesc v, b; FuncState *fs = ls->fs; new_localvar(ls, str_checkname(ls), 0); init_exp(&v, VLOCAL, fs->freereg); luaK_reserveregs(fs, 1); adjustlocalvars(ls, 1); body(ls, &b, 0, ls->linenumber); luaK_storevar(fs, &v, &b); /* debug information will only see the variable after this point! */ getlocvar(fs, fs->nactvar - 1).startpc = fs->pc; }
static void localstat (LexState *ls) { /* 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<nvars; nexps++) { expdesc v, key; init_exp(&e, VNONRELOC, ls->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 { e.k = VVOID; nexps = 0; } adjust_assign(ls, nvars, nexps, &e); adjustlocalvars(ls, nvars); }
static void inc_assignment(LexState *ls, struct LHS_assign *lh) { BinOpr op = getbinopr(ls->t.token); FuncState * fs=ls->fs; expdesc e, v2; /* reserve all registers needed by the lvalue */ luaK_reserveregs(fs,fs->freereg-fs->nactvar); luaX_next(ls); checknext(ls, '='); enterlevel(ls); e = lh->v; luaK_infix(fs,op,&e); /* we only match one expr(), not a full explist(), so "a+=2,2" will be a parse error. */ expr(ls,&v2); luaK_posfix(fs, op, &e, &v2); leavelevel(ls); luaK_exp2nextreg(fs,&e); luaK_setoneret(ls->fs, &e); luaK_storevar(ls->fs, &lh->v, &e); }
static void changevalue (LexState *ls, int op) { FuncState *fs = ls->fs; expdesc v, e1, e2; testnext(ls, '('); primaryexp(ls, &v); e1 = v; if (v.k == VINDEXED) luaK_reserveregs(fs, 1); /* <- this call solved the problem with indexed values */ if (testnext(ls, ',')) { luaK_exp2nextreg(fs, &e1); /* <- this call solved the problem with indexed values, 0.32.0 */ expr(ls, &e2); } else { /* using special opcodes is not faster */ init_exp(&e2, VKNUM, 0); e2.u.nval = (lua_Integer)1; } testnext(ls, ')'); codearith(fs, op, &e1, &e2); luaK_setoneret(fs, &e1); /* close last expression */ luaK_storevar(fs, &v, &e1); }