private static expkind singlevaraux(FuncState fs, TString n, expdesc var, int base_) { if (fs == null) { /* no more levels? */ init_exp(var, expkind.VGLOBAL, Lua.NO_REG); /* default is global variable */ return expkind.VGLOBAL; } else { int v = searchvar(fs, n); /* look up at current level */ if (v >= 0) { init_exp(var, expkind.VLOCAL, v); if (base_ == 0) markupval(fs, v); /* local will be used as an upval */ return expkind.VLOCAL; } else { /* not found at current level; try upper one */ if (singlevaraux(fs.prev, n, var, 0) == expkind.VGLOBAL) return expkind.VGLOBAL; var.u.s.info = indexupvalue(fs, n, var); /* else was LOCAL or UPVAL */ var.k = expkind.VUPVAL; /* upvalue in this level */ return expkind.VUPVAL; } } }
private static int indexupvalue(FuncState fs, TString name, expdesc v) { int i; Proto f = fs.f; int oldsize = f.sizeupvalues; for (i = 0; i < f.nups; i++) { if ((int)fs.upvalues[i].k == (int)v.k && fs.upvalues[i].info == v.u.s.info) { Lua.lua_assert(f.upvalues[i] == name); return i; } } /* new one */ luaY_checklimit(fs, f.nups + 1, Lua.LUAI_MAXUPVALUES, "upvalues"); Lua.luaM_growvector(fs.L, ref f.upvalues, f.nups, ref f.sizeupvalues, Lua.MAX_INT, ""); while (oldsize < f.sizeupvalues) f.upvalues[oldsize++] = null; f.upvalues[f.nups] = name; Lua.luaC_objbarrier(fs.L, f, name); Lua.lua_assert(v.k == expkind.VLOCAL || v.k == expkind.VUPVAL); fs.upvalues[f.nups].k = Lua.cast_byte(v.k); fs.upvalues[f.nups].info = Lua.cast_byte(v.u.s.info); return f.nups++; }
private static int searchvar(FuncState fs, TString n) { int i; for (i = fs.nactvar - 1; i >= 0; i--) { if (n == getlocvar(fs, i).varname) return i; } return -1; /* not found */ }
private static void new_localvar(LexState ls, TString name, int n) { FuncState fs = ls.fs; luaY_checklimit(fs, fs.nactvar + n + 1, Lua.LUAI_MAXVARS, "local variables"); fs.actvar[fs.nactvar + n] = (ushort)registerlocalvar(ls, name); }
private static int registerlocalvar(LexState ls, TString varname) { FuncState fs = ls.fs; Proto f = fs.f; int oldsize = f.sizelocvars; Lua.luaM_growvector(ls.L, ref f.locvars, fs.nlocvars, ref f.sizelocvars, (int)Lua.SHRT_MAX, "too many local variables"); while (oldsize < f.sizelocvars) f.locvars[oldsize++].varname = null; f.locvars[fs.nlocvars].varname = varname; Lua.luaC_objbarrier(ls.L, f, varname); return fs.nlocvars++; }
private static void forlist(LexState ls, TString indexname) { /* forlist . NAME {,NAME} IN explist1 forbody */ FuncState fs = ls.fs; expdesc e = new expdesc(); int nvars = 0; int line; int base_ = fs.freereg; /* create control variables */ new_localvarliteral(ls, "(for generator)", nvars++); new_localvarliteral(ls, "(for state)", nvars++); new_localvarliteral(ls, "(for control)", nvars++); /* create declared variables */ new_localvar(ls, indexname, nvars++); while (testnext(ls, ',') != 0) new_localvar(ls, str_checkname(ls), nvars++); checknext(ls, (int)RESERVED.TK_IN); line = ls.linenumber; adjust_assign(ls, 3, explist1(ls, e), e); Lua.luaK_checkstack(fs, 3); /* extra space to call generator */ forbody(ls, base_, line, nvars - 3, 0); }
private static void fornum(LexState ls, TString varname, int line) { /* fornum . NAME = exp1,exp1[,exp1] forbody */ FuncState fs = ls.fs; int base_ = fs.freereg; new_localvarliteral(ls, "(for index)", 0); new_localvarliteral(ls, "(for limit)", 1); new_localvarliteral(ls, "(for step)", 2); new_localvar(ls, varname, 3); checknext(ls, '='); exp1(ls); /* initial value */ checknext(ls, ','); exp1(ls); /* limit */ if (testnext(ls, ',') != 0) exp1(ls); /* optional step */ else { /* default step = 1 */ Lua.luaK_codeABx(fs, OpCode.OP_LOADK, fs.freereg, Lua.luaK_numberK(fs, 1)); Lua.luaK_reserveregs(fs, 1); } forbody(ls, base_, line, 1, 1); }
private static void codestring(LexState ls, expdesc e, TString s) { init_exp(e, expkind.VK, Lua.luaK_stringK(ls.fs, s)); }