Example #1
0
        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();
        }
Example #2
0
        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();
        }
Example #3
0
        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]));
        }
Example #4
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);
        }
Example #5
0
        private static void CgLocalFuncDefStat(FuncInfo fi, LocalFuncDefStat node)
        {
            var r = fi.AddLocVar(node.Name);

            CgFuncDefExp(fi, node.Exp, r);
        }
Example #6
0
        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);
            }
        }