private static void CgForInStat(FuncInfo fi, ForInStat node) { fi.EnterScope(true); CgLocalVarDeclStat(fi, new LocalVarDeclStat { NameList = new List <string> { "(for generator)", "(for state)", "(for control)" }, ExpList = node.ExpList }); foreach (var name in node.NameList) { fi.AddLocVar(name); } var pcJmpToTfc = fi.EmitJmp(0, 0); CgBlock(fi, node.Block); fi.CloseOpenUpvals(); fi.FixsBx(pcJmpToTfc, fi.PC() - pcJmpToTfc); var rGenerator = fi.SlotOfLocVar("(for generator)"); fi.EmitTForCall(rGenerator, node.NameList.Count); fi.EmitTForLoop(rGenerator + 2, pcJmpToTfc - fi.PC() - 1); fi.ExitScope(); }
private static void CgForNumStat(FuncInfo fi, ForNumStat node) { fi.EnterScope(true); CgLocalVarDeclStat(fi, new LocalVarDeclStat { NameList = new List <string> { "(for index)", "(for limit)", "(for step)" }, ExpList = new List <Exp> { node.InitExp, node.LimitExp, node.StepExp } }); fi.AddLocVar(node.VarName); var a = fi.UsedRegs - 4; var pcForPrep = fi.EmitForPrep(a, 0); CgBlock(fi, node.Block); fi.CloseOpenUpvals(); var pcForLoop = fi.EmitForLoop(a, 0); fi.FixsBx(pcForPrep, pcForLoop - pcForPrep - 1); fi.FixsBx(pcForLoop, pcForPrep - pcForLoop); fi.ExitScope(); }
public static ProtoType GenProto(Block chunk) { var fd = new FuncDefExp { IsVararg = true, Block = chunk, ParList = new List <string>() }; var fi = new FuncInfo(null, fd); fi.AddLocVar("_ENV"); CgFuncDefExp(fi, fd, 0); return(ToProto(fi.SubFuncs[0])); }
private static void CgFuncDefExp(FuncInfo fi, FuncDefExp node, int a) { var subFi = new FuncInfo(fi, node); fi.SubFuncs.Add(subFi); foreach (var param in node.ParList) { subFi.AddLocVar(param); } CgBlock(subFi, node.Block); subFi.ExitScope(); subFi.EmitReturn(0, 0); var bx = fi.SubFuncs.Count - 1; fi.EmitClosure(a, bx); }
private static void CgLocalFuncDefStat(FuncInfo fi, LocalFuncDefStat node) { var r = fi.AddLocVar(node.Name); CgFuncDefExp(fi, node.Exp, r); }
private static void CgLocalVarDeclStat(FuncInfo fi, LocalVarDeclStat node) { var exps = RemoveTailNil(node.ExpList); var nExps = exps.Count; var nNames = node.NameList.Count; var oldRegs = fi.UsedRegs; if (nExps == nNames) { foreach (var exp in exps) { var a = fi.AllocReg(); CgExp(fi, exp, a, 1); } } else if (nExps > nNames) { for (var i = 0; i < exps.Count; i++) { var exp = exps[i]; var a = fi.AllocReg(); if (i == nExps - 1 && IsVarargOrFuncCall(exp)) { CgExp(fi, exp, a, 0); } else { CgExp(fi, exp, a, 1); } } } else { var multRet = false; for (var i = 0; i < exps.Count; i++) { var exp = exps[i]; var a = fi.AllocReg(); if (i == nExps - 1 && IsVarargOrFuncCall(exp)) { multRet = true; var n = nNames - nExps + 1; CgExp(fi, exp, a, n); fi.AllocRegs(n - 1); } else { CgExp(fi, exp, a, 1); } } if (!multRet) { var n = nNames - nExps; var a = fi.AllocRegs(n); fi.EmitLoadNil(a, n); } } fi.UsedRegs = oldRegs; foreach (var name in node.NameList) { fi.AddLocVar(name); } }