示例#1
0
 private static void CgDoStat(FuncInfo fi, DoStat node)
 {
     fi.EnterScope(false);
     CgBlock(fi, node.Block);
     fi.CloseOpenUpvals();
     fi.ExitScope();
 }
示例#2
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();
        }
示例#3
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();
        }
示例#4
0
        private static void CgRepeatStat(FuncInfo fi, RepeatStat node)
        {
            fi.EnterScope(true);

            var pcBeforeBlock = fi.PC();

            CgBlock(fi, node.Block);

            var r = fi.AllocReg();

            CgExp(fi, node.Exp, r, 1);
            fi.FreeReg();

            fi.EmitTest(r, 0);
            fi.EmitJmp(fi.GetJmpArgA(), pcBeforeBlock - fi.PC() - 1);
            fi.CloseOpenUpvals();

            fi.ExitScope();
        }
示例#5
0
        private static void CgWhileStat(FuncInfo fi, WhileStat node)
        {
            var pcBeforeExp = fi.PC();

            var r = fi.AllocReg();

            CgExp(fi, node.Exp, r, 1);
            fi.FreeReg();

            fi.EmitTest(r, 0);
            var pcJmpToEnd = fi.EmitJmp(0, 0);

            fi.EnterScope(true);
            CgBlock(fi, node.Block);
            fi.CloseOpenUpvals();
            fi.EmitJmp(0, pcBeforeExp - fi.PC() - 1);
            fi.ExitScope();

            fi.FixsBx(pcJmpToEnd, fi.PC() - pcJmpToEnd);
        }
示例#6
0
        private static void CgIfStat(FuncInfo fi, IfStat node)
        {
            var pcJmpToEnds    = new int[node.Exps.Count];
            var pcJmpToNextExp = -1;

            for (var i = 0; i < node.Exps.Count; i++)
            {
                var exp = node.Exps[i];

                if (pcJmpToNextExp >= 0)
                {
                    fi.FixsBx(pcJmpToNextExp, fi.PC() - pcJmpToNextExp);
                }

                var r = fi.AllocReg();
                CgExp(fi, exp, r, 1);
                fi.FreeReg();

                fi.EmitTest(r, 0);
                pcJmpToNextExp = fi.EmitJmp(0, 0);

                fi.EnterScope(false);
                CgBlock(fi, node.Blocks[i]);
                fi.CloseOpenUpvals();
                fi.ExitScope();

                if (i < node.Exps.Count - 1)
                {
                    pcJmpToEnds[i] = fi.EmitJmp(0, 0);
                }
                else
                {
                    pcJmpToEnds[i] = pcJmpToNextExp;
                }
            }

            foreach (var pc in pcJmpToEnds)
            {
                fi.FixsBx(pc, fi.PC() - pc);
            }
        }