static void codearith (FuncState *fs, OpCode op, expdesc *e1, expdesc *e2, int line) { if (!constfolding(fs, op - OP_ADD + LUA_OPADD, e1, e2)) { int o1, o2; if (op == OP_UNM || op == OP_BNOT || op == OP_LEN) { o2 = 0; o1 = luaK_exp2anyreg(fs, e1); /* cannot operate on constants */ } else { /* regular case (binary operators) */ o2 = luaK_exp2RK(fs, e2); o1 = luaK_exp2RK(fs, e1); } if (o1 > o2) { freeexp(fs, e1); freeexp(fs, e2); } else { freeexp(fs, e2); freeexp(fs, e1); } e1->u.info = luaK_codeABC(fs, op, 0, o1, o2); e1->k = VRELOCABLE; luaK_fixline(fs, line); } }
static void forbody (LexState *ls, int base, int line, int nvars, int isnum) { /* forbody -> DO block */ BlockCnt bl; FuncState *fs = GetCurrentFuncState( ls ); adjustlocalvars(ls, 3); /* control variables */ checknext(ls, TK_DO); int prep = isnum ? luaK_codeAsBx(fs, OP_FORPREP, base, NO_JUMP) : luaK_jump(fs); enterblock(fs, &bl, 0); /* scope for declared variables */ adjustlocalvars(ls, nvars); luaK_reserveregs(fs, nvars); block(ls); leaveblock(fs); /* end of scope for declared variables */ luaK_patchtohere(fs, prep); int endfor = (isnum) ? luaK_codeAsBx(fs, OP_FORLOOP, base, NO_JUMP) : luaK_codeABC(fs, OP_TFORLOOP, base, 0, nvars); luaK_fixline(fs, line); /* pretend that `OP_FOR' starts the loop */ luaK_patchlist(fs, (isnum ? endfor : luaK_jump(fs)), prep + 1); }
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 funcargs(LexState* ls, expdesc* f) { FuncState* fs = ls->fs; expdesc args; int base, nparams; int line = ls->linenumber; switch (ls->t.token) { case '(': /* funcargs -> `(' [ explist1 ] `)' */ { if (line != ls->lastline) luaX_syntaxerror(ls, "ambiguous syntax (function call x new statement)"); luaX_next(ls); if (ls->t.token == ')') /* arg list is empty? */ args.k = VVOID; else { explist1(ls, &args); luaK_setmultret(fs, &args); } check_match(ls, ')', '(', line); break; } case '{': /* funcargs -> constructor */ { constructor(ls, &args); break; } case TK_STRING: /* funcargs -> STRING */ { codestring(ls, &args, ls->t.seminfo.ts); luaX_next(ls); /* must use `seminfo' before `next' */ break; } default: { luaX_syntaxerror(ls, "function arguments expected"); return; } } lua_assert(f->k == VNONRELOC); base = f->u.s.info; /* base register for call */ if (hasmultret(args.k)) nparams = LUA_MULTRET; /* open call */ else { if (args.k != VVOID) luaK_exp2nextreg(fs, &args); /* close last argument */ nparams = fs->freereg - (base + 1); } init_exp(f, VCALL, luaK_codeABC(fs, OP_CALL, base, nparams + 1, 2)); luaK_fixline(fs, line); fs->freereg = base + 1; /* call remove function and arguments and leaves (unless changed) one result */ }
static void forbody (LexState *ls, int base, int line, int nvars, int isnum) { BlockCnt bl; FuncState *fs = ls->fs; int prep, endfor; adjustlocalvars(ls, nvars); /* scope for all variables */ check(ls, TK_DO); enterblock(fs, &bl, 1); /* loop block */ prep = luaK_getlabel(fs); block(ls); luaK_patchtohere(fs, prep-1); endfor = (isnum) ? luaK_codeAsBx(fs, OP_FORLOOP, base, NO_JUMP) : luaK_codeABC(fs, OP_TFORLOOP, base, 0, nvars - 3); luaK_fixline(fs, line); /* pretend that `OP_FOR' starts the loop */ luaK_patchlist(fs, (isnum) ? endfor : luaK_jump(fs), prep); leaveblock(fs); }