private static void listfield(LexState ls, ConsControl cc) { expr(ls, cc.v); luaY_checklimit(ls.fs, cc.na, MAXINT, "items in a constructor"); cc.na++; cc.tostore++; }
private static void lastlistfield(FuncState fs, ConsControl cc) { if (cc.tostore == 0) return; if (hasmultret(cc.v.k) != 0) { LuaKSetMultRet(fs, cc.v); LuaKSetList(fs, cc.t.u.s.info, cc.na, LUA_MULTRET); cc.na--; /* do not count last expression (unknown number of elements) */ } else { if (cc.v.k != expkind.VVOID) LuaKExp2NextReg(fs, cc.v); LuaKSetList(fs, cc.t.u.s.info, cc.na, cc.tostore); } }
private static void closelistfield(FuncState fs, ConsControl cc) { if (cc.v.k == expkind.VVOID) return; /* there is no list item */ LuaKExp2NextReg(fs, cc.v); cc.v.k = expkind.VVOID; if (cc.tostore == LFIELDS_PER_FLUSH) { LuaKSetList(fs, cc.t.u.s.info, cc.na, cc.tostore); /* flush */ cc.tostore = 0; /* no more items pending */ } }
private static void constructor(LexState ls, expdesc t) { /* constructor . ?? */ FuncState fs = ls.fs; int line = ls.linenumber; int pc = LuaKCodeABC(fs, OpCode.OP_NEWTABLE, 0, 0, 0); ConsControl cc = new ConsControl(); cc.na = cc.nh = cc.tostore = 0; cc.t = t; init_exp(t, expkind.VRELOCABLE, pc); init_exp(cc.v, expkind.VVOID, 0); /* no value (yet) */ LuaKExp2NextReg(ls.fs, t); /* fix it at stack top (for gc) */ checknext(ls, '{'); do { LuaAssert(cc.v.k == expkind.VVOID || cc.tostore > 0); if (ls.t.token == '}') break; closelistfield(fs, cc); switch(ls.t.token) { case (int)RESERVED.TK_NAME: { /* may be listfields or recfields */ LuaXLookAhead(ls); if (ls.lookahead.token != '=') /* expression? */ listfield(ls, cc); else recfield(ls, cc); break; } case '[': { /* constructor_item . recfield */ recfield(ls, cc); break; } default: { /* constructor_part . listfield */ listfield(ls, cc); break; } } } while ((testnext(ls, ',')!=0) || (testnext(ls, ';')!=0)); check_match(ls, '}', '{', line); lastlistfield(fs, cc); SETARG_B(new InstructionPtr(fs.f.code, pc), LuaOInt2FB((uint)cc.na)); /* set initial array size */ SETARG_C(new InstructionPtr(fs.f.code, pc), LuaOInt2FB((uint)cc.nh)); /* set initial table size */ }
private static void recfield(LexState ls, ConsControl cc) { /* recfield . (NAME | `['exp1`]') = exp1 */ FuncState fs = ls.fs; int reg = ls.fs.freereg; expdesc key = new expdesc(), val = new expdesc(); int rkkey; if (ls.t.token == (int)RESERVED.TK_NAME) { luaY_checklimit(fs, cc.nh, MAXINT, "items in a constructor"); checkname(ls, key); } else /* ls.t.token == '[' */ yindex(ls, key); cc.nh++; checknext(ls, '='); rkkey = LuaKExp2RK(fs, key); expr(ls, val); LuaKCodeABC(fs, OpCode.OP_SETTABLE, cc.t.u.s.info, rkkey, LuaKExp2RK(fs, val)); fs.freereg = reg; /* free registers */ }