Beispiel #1
0
        public void ProcessNumberVariableConstant()
        {
            SimpleContext sc   = new SimpleContext("");
            IEvaluator    etor = new PolishEvaluator();

            sc.Assign("a", 5);
            sc.Assign("b", 12);
            sc.Assign("na", -5);
            sc.Assign("nb", -12);

            var res = etor.Eval("$a $b +", sc);

            Assert.AreEqual(res, 17);

            res = etor.Eval("$a $nb +", sc);
            Assert.AreEqual(res, -7);

            res = etor.Eval("$b $na -", sc);
            Assert.AreEqual(res, 17);

            res = etor.Eval("$na $nb -", sc);
            Assert.AreEqual(res, 7);

            res = etor.Eval("2 $na 3 + -", sc);
            Assert.AreEqual(res, 4);
        }
Beispiel #2
0
 /// <summary>
 /// 左值运算一个变量
 /// </summary>
 /// <param name="varname">变量名</param>
 /// <param name="valuePolish">右值逆波兰式</param>
 /// <param name="vsm">关于哪个调用堆栈做动作</param>
 public void Assignment(string varname, string valuePolish, StackMachine vsm)
 {
     // 处理局部变量
     if (varname.StartsWith("$"))
     {
         // 非函数调用
         if (this.GameState(vsm) != StackMachineState.FunctionCalling)
         {
             this.Symbols.SceneCtxDao.Assign(vsm.EBP.ScriptName, varname.Replace("$", String.Empty), PolishEvaluator.Evaluate(valuePolish, vsm));
         }
         // 函数调用
         else
         {
             var functionFrame = vsm.ESP.BindingFunction;
             functionFrame.Symbols[varname.Replace("$", String.Empty)] = PolishEvaluator.Evaluate(valuePolish, vsm);
         }
     }
     // 处理全局变量
     else if (varname.StartsWith("&"))
     {
         this.Symbols.GlobalCtxDao.GlobalAssign(varname.Replace("&", String.Empty), PolishEvaluator.Evaluate(valuePolish, vsm));
     }
     // 处理持久化变量
     else if (varname.StartsWith("%"))
     {
         PersistContextDAO.Assign(varname.Replace("%", String.Empty), PolishEvaluator.Evaluate(valuePolish, vsm));
     }
 }
Beispiel #3
0
        public void ProcessStringNumberConstant()
        {
            SimpleContext sc   = new SimpleContext("");
            IEvaluator    etor = new PolishEvaluator();

            var res = etor.Eval("\"testnumber:\" 233 +", sc);

            Assert.AreEqual(res, "testnumber:233");

            res = etor.Eval("\"testnumber:\" 233 1000 + +", sc);
            Assert.AreEqual(res, "testnumber:1233");
        }
Beispiel #4
0
        public void ProcessStringConstant()
        {
            SimpleContext sc   = new SimpleContext("");
            IEvaluator    etor = new PolishEvaluator();

            var res = etor.Eval("\"he\" \"llo\" +", sc);

            Assert.AreEqual(res, "hello");

            res = etor.Eval("\"hello\" \"~\" \"world\" + +", sc);
            Assert.AreEqual(res, "hello~world");
        }
Beispiel #5
0
        public void ProcessNumberConstant()
        {
            SimpleContext sc   = new SimpleContext("");
            IEvaluator    etor = new PolishEvaluator();

            var res = etor.Eval("1 2 +", sc);

            Assert.AreEqual(res, 3);

            res = etor.Eval("5 8 -", sc);
            Assert.AreEqual(res, -3);

            res = etor.Eval("2.33 3.33 +", sc);
            Assert.AreEqual(res, 5.66);

            res = etor.Eval("2.33 3.33 -", sc);
            Assert.AreEqual(res, -1);
        }
Beispiel #6
0
        public void ProcessStringVariableConstant()
        {
            SimpleContext sc   = new SimpleContext("");
            IEvaluator    etor = new PolishEvaluator();

            sc.Assign("str1", "hello");
            sc.Assign("str2", "world");
            sc.Assign("spacer", " ");

            var res = etor.Eval("$str1 $str2 +", sc);

            Assert.AreEqual(res, "helloworld");

            res = etor.Eval("$str1 $spacer $str2 + +", sc);
            Assert.AreEqual(res, "hello world");

            res = etor.Eval("\"TEST\" $spacer $str2 + +", sc);
            Assert.AreEqual(res, "TEST world");
        }
Beispiel #7
0
        public void ProcessStringNumberVariableConstant()
        {
            SimpleContext sc   = new SimpleContext("");
            IEvaluator    etor = new PolishEvaluator();

            sc.Assign("str1", "hello");
            sc.Assign("str2", "world");
            sc.Assign("num1", 1000);
            sc.Assign("num2", 24);

            var res = etor.Eval("\"testnumber:\" $num1 $num2 + +", sc);

            Assert.AreEqual(res, "testnumber:1024");

            res = etor.Eval("\"testnumber:\" $num1 501 - +", sc);
            Assert.AreEqual(res, "testnumber:499");

            res = etor.Eval("$str1 $num1 $str2 $num2 + + +", sc);
            Assert.AreEqual(res, "hello1000world24");
        }
Beispiel #8
0
        /// <summary>
        /// 处理并行调用和信号函数的消息循环
        /// </summary>
        private void ParallelUpdateContext(object sender, EventArgs e)
        {
            // 如果主消息循环暂停那么就直接迭代掉
            if (Director.IsContextUpdatePaused)
            {
                return;
            }
            // 获取绑定的调用堆栈
            var dispatcher = sender as DispatcherTimer;

            dispatcher.Stop();
            ParallelDispatcherArgsPackage pdap;

            try
            {
                pdap = dispatcher.Tag as ParallelDispatcherArgsPackage;
            }
            catch (Exception ex)
            {
                LogUtils.LogLine("Parallel Failed " + ex, "Director", LogLevel.Warning);
                dispatcher.Start();
                return;
            }
            if (pdap == null)
            {
                LogUtils.LogLine("Parallel Failed.", "Director", LogLevel.Warning);
                dispatcher.Start();
                return;
            }
            var paraVM = pdap.IsSemaphore ? pdap.SemaphoreStack : Director.RunMana.ParallelExecutorStack.Peek()[pdap.Index].Executor;

            bool resumeFlag = true;

            while (true)
            {
                // 取得调用堆栈顶部状态
                StackMachineState stackState    = Director.RunMana.GameState(paraVM);
                GameState         paraGameState = GameState.Exit;
                switch (stackState)
                {
                case StackMachineState.Interpreting:
                case StackMachineState.FunctionCalling:
                    resumeFlag    = false;
                    paraGameState = GameState.Performing;
                    break;

                case StackMachineState.WaitUser:
                    dispatcher.Start();
                    return;

                case StackMachineState.WaitAnimation:
                    // 并行器里不应该出现等待动画结束,立即结束本次迭代
                    return;

                case StackMachineState.Await:
                    paraGameState = GameState.Waiting;
                    resumeFlag    = true;
                    break;

                case StackMachineState.Interrupt:
                    LogUtils.LogLine(
                        "There is a interrupt in parallel function, which may cause system pause",
                        "Director", LogLevel.Warning);
                    paraGameState = GameState.Interrupt;
                    resumeFlag    = false;
                    break;

                case StackMachineState.NOP:
                    paraGameState = GameState.Exit;
                    resumeFlag    = true;
                    break;
                }
                // 根据调用堆栈顶部更新系统
                switch (paraGameState)
                {
                // 等待状态
                case GameState.Waiting:
                    // 计算已经等待的时间
                    if (DateTime.Now - paraVM.ESP.TimeStamp > paraVM.ESP.Delay)
                    {
                        paraVM.Consume();
                    }
                    break;

                // 等待动画
                case GameState.WaitAni:
                    if (SpriteAnimation.IsAnyAnimation == false)
                    {
                        paraVM.Consume();
                    }
                    break;

                // 演绎脚本
                case GameState.Performing:
                    // 取下一动作
                    var nextInstruct = Director.RunMana.MoveNext(paraVM);
                    // 如果指令空了就立即迭代本次消息循环
                    if (nextInstruct == null)
                    {
                        dispatcher.Start();
                        return;
                    }
                    // 处理影响调用堆栈的动作
                    if (nextInstruct.Type == SActionType.act_wait)
                    {
                        double waitMs = nextInstruct.ArgsDict.ContainsKey("time")
                                ? (double)PolishEvaluator.Evaluate(nextInstruct.ArgsDict["time"], paraVM)
                                : 0;
                        paraVM.Submit("Parallel Time Waiting", DateTime.Now, TimeSpan.FromMilliseconds(waitMs));
                        break;
                    }
                    else if (nextInstruct.Type == SActionType.act_waitani)
                    {
                        // 并行器里不应该出现等待动画结束,立即结束本次迭代
                        LogUtils.LogLine(
                            "There is a animation wait in parallel function, which may cause system pause",
                            "Director", LogLevel.Warning);
                        break;
                    }
                    else if (nextInstruct.Type == SActionType.act_waituser)
                    {
                        LogUtils.LogLine(
                            "There is a user wait in parallel function, which may cause system pause",
                            "Director", LogLevel.Warning);
                        paraVM.Submit("Director", nextInstruct.NodeName);
                        break;
                    }
                    else if (nextInstruct.Type == SActionType.act_jump)
                    {
                        var jumpToScene  = nextInstruct.ArgsDict["filename"];
                        var jumpToTarget = nextInstruct.ArgsDict["target"];
                        // 场景内跳转
                        if (jumpToScene == String.Empty)
                        {
                            if (stackState == StackMachineState.Interpreting)
                            {
                                var currentScene = this.resMana.GetScene(paraVM.ESP.BindingSceneName);
                                if (!currentScene.LabelDictionary.ContainsKey(jumpToTarget))
                                {
                                    LogUtils.LogLine(
                                        String.Format("Ignored Jump Instruction (target not exist): {0}",
                                                      jumpToTarget),
                                        "Director", LogLevel.Error);
                                    break;
                                }
                                paraVM.ESP.MircoStep(currentScene.LabelDictionary[jumpToTarget]);
                            }
                            else if (stackState == StackMachineState.FunctionCalling)
                            {
                                var currentFunc = paraVM.ESP.BindingFunction;
                                if (!currentFunc.LabelDictionary.ContainsKey(jumpToTarget))
                                {
                                    LogUtils.LogLine(
                                        String.Format("Ignored Jump Instruction (target not exist): {0}",
                                                      jumpToTarget),
                                        "Director", LogLevel.Error);
                                    break;
                                }
                                paraVM.ESP.MircoStep(currentFunc.LabelDictionary[jumpToTarget]);
                            }
                        }
                        // 跨场景跳转
                        else
                        {
                            LogUtils.LogLine(
                                "There is a jump across scene in parallel function, it will be ignored",
                                "Director", LogLevel.Warning);
                        }
                        break;
                    }
                    else if (nextInstruct.Type == SActionType.act_call)
                    {
                        var callFunc = nextInstruct.ArgsDict["name"];
                        var signFunc = nextInstruct.ArgsDict["sign"];
                        this.FunctionCalling(callFunc, signFunc, paraVM);
                        break;
                    }
                    // 处理常规动作
                    pdap.Render.Execute(nextInstruct);
                    break;

                // 系统中断
                case GameState.Interrupt:
                    var interruptSa        = paraVM.ESP.IP;
                    var interruptExitPoint = paraVM.ESP.Tag;
                    // 退出中断
                    var pureInt = paraVM.ESP.BindingInterrupt.PureInterrupt;
                    var interruptFuncCalling = paraVM.ESP.BindingInterrupt.InterruptFuncSign;
                    var needExitWait         = paraVM.ESP.BindingInterrupt.ExitWait;
                    Director.RunMana.ExitCall(paraVM);
                    // 处理中断优先动作
                    if (interruptSa != null)
                    {
                        if (interruptSa.Type == SActionType.act_waituser)
                        {
                            LogUtils.LogLine(
                                "There is a user wait in parallel function, which may cause system pause",
                                "Director", LogLevel.Warning);
                            paraVM.Submit("Director", interruptSa.NodeName);
                            break;
                        }
                        else
                        {
                            var iterSa = interruptSa;
                            while (iterSa != null)
                            {
                                pdap.Render.Execute(interruptSa);
                                iterSa = iterSa.Next;
                            }
                        }
                    }
                    // 判断中断是否需要处理后续动作
                    if (pureInt)
                    {
                        break;
                    }
                    // 跳出所有用户等待
                    if (needExitWait || interruptExitPoint != String.Empty)
                    {
                        while (paraVM.Count() > 0 && paraVM.ESP.State == StackMachineState.WaitUser)
                        {
                            Director.RunMana.ExitCall(paraVM);
                        }
                    }
                    // 处理跳转(与中断调用互斥)
                    if (interruptExitPoint != String.Empty)
                    {
                        RunnableYuriri curRunnable;
                        if (paraVM.EBP.BindingFunction == null)
                        {
                            curRunnable = this.resMana.GetScene(paraVM.EBP.BindingSceneName);
                        }
                        else
                        {
                            curRunnable = paraVM.EBP.BindingFunction;
                        }
                        if (!curRunnable.LabelDictionary.ContainsKey(interruptExitPoint))
                        {
                            LogUtils.LogLine(String.Format("Ignored parallel Interrupt jump Instruction (target not exist): {0}",
                                                           interruptExitPoint), "Director", LogLevel.Error);
                            break;
                        }
                        paraVM.EBP.MircoStep(curRunnable.LabelDictionary[interruptExitPoint]);
                    }
                    // 处理中断函数调用
                    else if (interruptFuncCalling != String.Empty)
                    {
                        var ifcItems    = interruptFuncCalling.Split('(');
                        var funPureName = ifcItems[0];
                        var funParas    = "(" + ifcItems[1];
                        this.FunctionCalling(funPureName, funParas, paraVM);
                    }
                    break;

                // 退出(其实就是执行完毕了一轮,应该重新开始)
                case GameState.Exit:
                    if (pdap.IsSemaphore == false)
                    {
                        paraVM.Submit(pdap.BindingSF, new List <object>());
                    }
                    else
                    {
                        switch (pdap.SemaphoreType)
                        {
                        case SemaphoreHandlerType.ScheduleOnce:
                            return;

                        case SemaphoreHandlerType.ScheduleForever:
                            paraVM.Submit(pdap.BindingSF, new List <object>());
                            break;

                        case SemaphoreHandlerType.ScheduleWhenActivated:
                            throw new NotImplementedException();
                        }
                    }
                    break;
                }
                if (resumeFlag)
                {
                    break;
                }
            }
            if (resumeFlag)
            {
                dispatcher.Start();
            }
        }
Beispiel #9
0
        /// <summary>
        /// 处理消息循环
        /// </summary>
        private void UpdateContext(object sender, EventArgs e)
        {
            bool resumeFlag = true;

            this.timer.Stop();
            while (true)
            {
                // 取得调用堆栈顶部状态
                StackMachineState stackState = Director.RunMana.GameState(Director.RunMana.CallStack);
                switch (stackState)
                {
                case StackMachineState.Interpreting:
                case StackMachineState.FunctionCalling:
                    this.curState = GameState.Performing;
                    resumeFlag    = false;
                    break;

                case StackMachineState.WaitUser:
                    this.curState = GameState.WaitForUserInput;
                    resumeFlag    = true;
                    break;

                case StackMachineState.WaitAnimation:
                    this.curState = GameState.WaitAni;
                    resumeFlag    = true;
                    break;

                case StackMachineState.Await:
                    this.curState = GameState.Waiting;
                    resumeFlag    = true;
                    break;

                case StackMachineState.Interrupt:
                    this.curState = GameState.Interrupt;
                    resumeFlag    = false;
                    break;

                case StackMachineState.AutoWait:
                    this.curState = GameState.AutoPlay;
                    resumeFlag    = true;
                    break;

                case StackMachineState.NOP:
                    this.curState = GameState.Exit;
                    resumeFlag    = true;
                    break;
                }
                // 根据调用堆栈顶部更新系统
                switch (this.curState)
                {
                // 等待状态
                case GameState.Waiting:
                    // 计算已经等待的时间
                    if (DateTime.Now - Director.RunMana.CallStack.ESP.TimeStamp >
                        Director.RunMana.CallStack.ESP.Delay)
                    {
                        Director.RunMana.ExitCall(Director.RunMana.CallStack);
                    }
                    break;

                // 等待动画
                case GameState.WaitAni:
                    if (SpriteAnimation.IsAnyAnimation == false && SCamera2D.IsAnyAnimation == false &&
                        SCamera3D.IsAnyAnimation == false)
                    {
                        Director.RunMana.ExitCall(Director.RunMana.CallStack);
                    }
                    break;

                // 自动播放
                case GameState.AutoPlay:
                    // 等待动画和延时
                    if (DateTime.Now - Director.RunMana.CallStack.ESP.TimeStamp > Director.RunMana.CallStack.ESP.Delay &&
                        SpriteAnimation.IsAnyAnimation == false &&
                        SCamera2D.IsAnyAnimation == false &&
                        SCamera3D.IsAnyAnimation == false &&
                        Director.IsRClicking == false &&
                        Musician.IsVoicePlaying == false &&
                        SemaphoreDispatcher.GetSemaphoreState("System_PreviewShutdown") == false &&
                        ViewPageManager.IsAtMainStage() == true)
                    {
                        this.updateRender.IsShowingDialog = false;
                        this.updateRender.dialogPreStr    = String.Empty;
                        if (this.updateRender.IsContinousDialog == false)
                        {
                            ViewManager.GetInstance().GetMessageLayer(0).Visibility = Visibility.Hidden;
                            this.updateRender.HideMessageTria();
                        }
                        Director.RunMana.ExitCall(Director.RunMana.CallStack);
                    }
                    break;

                // 等待用户操作
                case GameState.WaitForUserInput:
                    break;

                // 中断
                case GameState.Interrupt:
                    var interruptSa        = Director.RunMana.CallStack.ESP.IP;
                    var interruptExitPoint = Director.RunMana.CallStack.ESP.Tag;
                    // 退出中断
                    var pureInt = Director.RunMana.CallStack.ESP.BindingInterrupt.PureInterrupt;
                    var interruptFuncCalling = Director.RunMana.CallStack.ESP.BindingInterrupt.InterruptFuncSign;
                    var needExitWait         = Director.RunMana.CallStack.ESP.BindingInterrupt.ExitWait;
                    Director.RunMana.ExitCall(Director.RunMana.CallStack);
                    // 处理中断优先动作
                    if (interruptSa != null)
                    {
                        if (interruptSa.Type == SActionType.act_waituser)
                        {
                            Director.RunMana.UserWait("Director", interruptSa.NodeName);
                        }
                        else
                        {
                            var iterSa = interruptSa;
                            while (iterSa != null)
                            {
                                this.updateRender.Execute(interruptSa);
                                iterSa = iterSa.Next;
                            }
                        }
                    }
                    // 判断中断是否需要处理后续动作
                    if (pureInt)
                    {
                        break;
                    }
                    // 跳出所有用户等待
                    if (needExitWait || interruptExitPoint != String.Empty)
                    {
                        Director.RunMana.ExitUserWait();
                    }
                    // 处理跳转(与中断调用互斥)
                    if (interruptExitPoint != String.Empty)
                    {
                        RunnableYuriri curRunnable;
                        if (Director.RunMana.CallStack.EBP.BindingFunction == null)
                        {
                            curRunnable = this.resMana.GetScene(Director.RunMana.CallStack.EBP.BindingSceneName);
                        }
                        else
                        {
                            curRunnable = Director.RunMana.CallStack.EBP.BindingFunction;
                        }
                        if (!curRunnable.LabelDictionary.ContainsKey(interruptExitPoint))
                        {
                            LogUtils.LogLine(String.Format("Ignored Interrupt jump Instruction (target not exist): {0}",
                                                           interruptExitPoint), "Director", LogLevel.Error);
                            break;
                        }
                        Director.RunMana.CallStack.EBP.MircoStep(curRunnable.LabelDictionary[interruptExitPoint]);
                    }
                    // 处理中断函数调用
                    else if (interruptFuncCalling != String.Empty)
                    {
                        var ifcItems    = interruptFuncCalling.Split('(');
                        var funPureName = ifcItems[0];
                        var funParas    = "(" + ifcItems[1];
                        this.FunctionCalling(funPureName, funParas, Director.RunMana.CallStack);
                    }
                    break;

                // 演绎脚本
                case GameState.Performing:
                    // 取下一动作
                    var nextInstruct = Director.RunMana.MoveNext(Director.RunMana.CallStack);
                    // 如果指令空了就立即迭代本次消息循环
                    if (nextInstruct == null)
                    {
                        this.timer.Start();
                        return;
                    }
                    // 处理影响调用堆栈的动作
                    if (nextInstruct.Type == SActionType.act_wait)
                    {
                        double waitMs = nextInstruct.ArgsDict.ContainsKey("time")
                                ? (double)PolishEvaluator.Evaluate(nextInstruct.ArgsDict["time"], Director.RunMana.CallStack)
                                : 0;
                        Director.RunMana.Delay(nextInstruct.NodeName, DateTime.Now,
                                               TimeSpan.FromMilliseconds(waitMs));
                        break;
                    }
                    else if (nextInstruct.Type == SActionType.act_waitani)
                    {
                        Director.RunMana.AnimateWait(nextInstruct.NodeName);
                        break;
                    }
                    else if (nextInstruct.Type == SActionType.act_waituser)
                    {
                        Director.RunMana.UserWait("Director", nextInstruct.NodeName);
                        break;
                    }
                    else if (nextInstruct.Type == SActionType.act_jump)
                    {
                        var jumpToScene  = nextInstruct.ArgsDict["filename"];
                        var jumpToTarget = nextInstruct.ArgsDict["target"];
                        // 场景内跳转
                        if (jumpToScene == String.Empty)
                        {
                            if (stackState == StackMachineState.Interpreting)
                            {
                                var currentScene = this.resMana.GetScene(Director.RunMana.CallStack.ESP.BindingSceneName);
                                if (!currentScene.LabelDictionary.ContainsKey(jumpToTarget))
                                {
                                    LogUtils.LogLine(
                                        String.Format("Ignored Jump Instruction (target not exist): {0}",
                                                      jumpToTarget),
                                        "Director", LogLevel.Error);
                                    break;
                                }
                                Director.RunMana.CallStack.ESP.MircoStep(currentScene.LabelDictionary[jumpToTarget]);
                            }
                            else if (stackState == StackMachineState.FunctionCalling)
                            {
                                var currentFunc = Director.RunMana.CallStack.ESP.BindingFunction;
                                if (!currentFunc.LabelDictionary.ContainsKey(jumpToTarget))
                                {
                                    LogUtils.LogLine(
                                        String.Format("Ignored Jump Instruction (target not exist): {0}",
                                                      jumpToTarget),
                                        "Director", LogLevel.Error);
                                    break;
                                }
                                Director.RunMana.CallStack.ESP.MircoStep(currentFunc.LabelDictionary[jumpToTarget]);
                            }
                        }
                        // 跨场景跳转
                        else
                        {
                            var jumpScene = this.resMana.GetScene(jumpToScene);
                            if (jumpScene == null)
                            {
                                LogUtils.LogLine(
                                    String.Format("Ignored Jump Instruction (scene not exist): {0}", jumpToScene),
                                    "Director", LogLevel.Error);
                                break;
                            }
                            if (jumpToTarget != String.Empty && !jumpScene.LabelDictionary.ContainsKey(jumpToTarget))
                            {
                                LogUtils.LogLine(
                                    String.Format("Ignored Jump Instruction (target not exist): {0} -> {1}",
                                                  jumpToScene, jumpToTarget),
                                    "Director", LogLevel.Error);
                                break;
                            }
                            Director.RunMana.ExitCall(Director.RunMana.CallStack);
                            Director.RunMana.CallScene(jumpScene,
                                                       jumpToTarget == String.Empty ? jumpScene.Ctor : jumpScene.LabelDictionary[jumpToTarget]);
                        }
                        break;
                    }
                    else if (nextInstruct.Type == SActionType.act_call)
                    {
                        var callFunc = nextInstruct.ArgsDict["name"];
                        var signFunc = nextInstruct.ArgsDict["sign"];
                        this.FunctionCalling(callFunc, signFunc, Director.RunMana.CallStack);
                        break;
                    }
                    // 处理常规动作
                    this.updateRender.Execute(nextInstruct);
                    break;

                // 退出
                case GameState.Exit:
                    this.updateRender.Shutdown();
                    break;
                }
                // 处理IO
                this.updateRender.UpdateForMouseState();
                // 是否恢复消息循环
                if (resumeFlag)
                {
                    break;
                }
            }
            if (resumeFlag)
            {
                this.timer.Start();
            }
        }
Beispiel #10
0
        /// <summary>
        /// 在指定的调用堆栈上做递归寻指
        /// </summary>
        /// <param name="vsm">关于哪个调用堆栈做动作</param>
        /// <returns>动作实例</returns>
        private SceneAction FetchNextInstruction(StackMachine vsm)
        {
            // 调用栈已经为空时预备退出
            if (vsm.Count() == 0)
            {
                return(null);
            }
            // 取出当前要执行的指令
            if (vsm.ESP.State != StackMachineState.Interpreting &&
                vsm.ESP.State != StackMachineState.FunctionCalling)
            {
                return(null);
            }
            SceneAction ret = vsm.ESP.IP;

            // 如果没有下一指令就弹栈
            if (ret == null)
            {
                this.ExitCall(vsm);
                // 递归寻指
                return(this.FetchNextInstruction(vsm));
            }
            // 如果没有条件子句
            if (ret.CondPolish == String.Empty)
            {
                // 处理控制流程
                switch (ret.Type)
                {
                case SActionType.NOP:
                case SActionType.act_function:
                case SActionType.act_for:
                    // 优先进入trueRouting
                    if (ret.TrueRouting != null && ret.TrueRouting.Count > 0)
                    {
                        return(vsm.ESP.MircoStep(ret.TrueRouting[0]));
                    }
                    // falseRouting
                    if (ret.FalseRouting != null && ret.FalseRouting.Count > 0)
                    {
                        return(vsm.ESP.MircoStep(ret.FalseRouting[0]));
                    }
                    // next
                    return(vsm.ESP.MacroStep(ret));

                case SActionType.act_endfor:
                    // endfor直接跳过
                    return(vsm.ESP.MacroStep(ret));
                }
                // 移动下一指令指针,为下次处理做准备
                return(vsm.ESP.MacroStep(ret));
            }
            // 条件子句不为空时
            else
            {
                // 计算条件真值
                bool condBoolean = PolishEvaluator.EvaluateBoolean(ret.CondPolish, vsm);
                // 处理控制流程
                switch (ret.Type)
                {
                // IF语句
                case SActionType.act_if:
                    // 条件为真且有真分支
                    if (condBoolean == true && ret.TrueRouting != null && ret.TrueRouting.Count > 0)
                    {
                        // 移动下一指令指针,进入trueRouting
                        ret = vsm.ESP.MircoStep(ret.TrueRouting[0]);
                    }
                    // 条件为假且有假分支
                    else if (condBoolean == false && ret.FalseRouting != null && ret.FalseRouting.Count > 0)
                    {
                        // 移动下一指令指针,进入falseRouting
                        ret = vsm.ESP.MircoStep(ret.FalseRouting[0]);
                    }
                    // 没有执行的语句时,移动指令指针到next节点
                    else
                    {
                        // 跳过if语句
                        ret = vsm.ESP.MacroStep(ret);
                    }
                    // 返回当前要执行的指令实例
                    return(ret);

                // FOR语句
                case SActionType.act_for:
                    // 如果条件为真就进入真分支
                    if (condBoolean == true && ret.TrueRouting != null && ret.TrueRouting.Count > 0)
                    {
                        // 移动下一指令指针,进入trueRouting
                        ret = vsm.ESP.MircoStep(ret.TrueRouting[0]);
                    }
                    // 如果条件为假直接跳过for语句
                    else
                    {
                        // 跳过if语句
                        ret = vsm.ESP.MacroStep(ret);
                    }
                    // 返回当前要执行的指令实例
                    return(ret);

                // 除此以外,带了cond的语句,为真才执行
                default:
                    if (condBoolean == false)
                    {
                        // 跳过当前语句
                        ret = vsm.ESP.MacroStep(ret);
                    }
                    // 返回当前要执行的指令实例
                    return(ret);
                }
            }
        }