/// <summary> /// 为场景添加符号表 /// </summary> /// <param name="scene">场景实例</param> /// <returns>操作成功与否</returns> public bool AddSymbolTable(Scene scene) { if (this.userSymbolTableContainer.ContainsKey(scene.Scenario)) { return false; } this.userSymbolTableContainer.Add(scene.Scenario, new Dictionary<string, object>()); return true; }
/// <summary> /// 处理动作项目为动作序列,封装成场景实例 /// </summary> private List<Scene> ProcessSARelation() { List<Scene> resList = new List<Scene>(); foreach (KeyValuePair<string, Dictionary<string, SceneActionPackage>> sapKvp in this.ilPackageContainer) { string sceneName = sapKvp.Key; Dictionary<string, SceneActionPackage> sapPool = sapKvp.Value; List<SceneAction> saHeaderList = new List<SceneAction>(); Dictionary<string, SceneAction> labelDict = new Dictionary<string, SceneAction>(); foreach (KeyValuePair<string, SceneActionPackage> SAPPair in sapPool) { string nodename = SAPPair.Key; SceneActionPackage sap = SAPPair.Value; // 不脏的项目才入队展开 if (sap.dirtyBit == false) { saHeaderList.Add(this.iResContainer[sceneName][nodename]); Queue<string> openSet = new Queue<string>(); openSet.Enqueue(nodename); // 广度优先遍历 while (openSet.Count != 0) { // 标记脏位 SceneActionPackage currentSAP = this.ilPackageContainer[sceneName][openSet.Dequeue()]; currentSAP.dirtyBit = true; // 处理label字典 if (currentSAP.aType == SActionType.act_label) { labelDict[currentSAP.aTag] = this.iResContainer[sceneName][currentSAP.saNodeName]; } // 处理next if (currentSAP.next != "" && currentSAP.next != null) { this.iResContainer[sceneName][currentSAP.saNodeName].next = this.iResContainer[sceneName][currentSAP.next]; } // 处理trueRouting if (currentSAP.trueRouting.Count > 0) { this.iResContainer[sceneName][currentSAP.saNodeName].trueRouting = new List<SceneAction>(); foreach (string trueSaName in currentSAP.trueRouting) { this.iResContainer[sceneName][currentSAP.saNodeName].trueRouting.Add( this.iResContainer[sceneName][trueSaName]); openSet.Enqueue(trueSaName); } } // 处理falseRouting if (currentSAP.falseRouting.Count > 0) { this.iResContainer[sceneName][currentSAP.saNodeName].falseRouting = new List<SceneAction>(); foreach (string falseSaName in currentSAP.falseRouting) { this.iResContainer[sceneName][currentSAP.saNodeName].falseRouting.Add( this.iResContainer[sceneName][falseSaName]); openSet.Enqueue(falseSaName); } } } } } CommonUtils.ConsoleLine(String.Format("Finished SAP Relation Recovery: {0}", sceneName), "YuriIL Convertor", OutputStyle.Normal); Scene parseScene = null; if (saHeaderList.Count > 0) { SceneAction mainSa = saHeaderList[0]; List<SceneFunction> funcVec = new List<SceneFunction>(); for (int fc = 1; fc < saHeaderList.Count; fc++) { SceneAction fsa = saHeaderList[fc]; funcVec.Add(this.ParseSaToSF(fsa, sceneName)); } parseScene = new Scene(sceneName, mainSa, funcVec, labelDict); } resList.Add(parseScene); CommonUtils.ConsoleLine(String.Format("Finished SAP Function Recovery: {0}", sceneName), "YuriIL Convertor", OutputStyle.Normal); } return resList; }
/// <summary> /// 获取指定场景的IL文件头 /// </summary> /// <param name="scene">场景实例</param> /// <returns>IL文件头字符串</returns> public static string GetILSign(Scene scene) { return String.Format(">>>YuriIL?{0}", scene.Scenario); }
/// <summary> /// <para>使用一个变量作为右值</para> /// <para>如果这个变量从未使用过,将抛出错误</para> /// </summary> /// <param name="sceneObject">场景实例/param> /// <param name="varName">变量名</param> /// <returns>变量在运行时环境的引用</returns> public object Fetch(Scene sceneObject, string varName) { Dictionary<string, object> table = this.FindSymbolTable(sceneObject.Scenario); // 如果查无此键 if (table.ContainsKey(varName) == false) { throw new Exception("变量 " + varName + " 在作为左值之前被引用"); } return table[varName]; }
/// <summary> /// 场景调用 /// </summary> /// <param name="scene">场景实例</param> /// <param name="target">目标标签</param> public void CallScene(Scene scene, SceneAction target = null) { this.CallStack.Submit(scene, target); }
/// <summary> /// 向栈机提交一个场景调用 /// </summary> /// <param name="sc">被调用的场景Scene实例</param> /// <param name="offset">IP偏移</param> public void Submit(Scene sc, SceneAction offset = null) { StackMachineFrame smf = new StackMachineFrame() { State = StackMachineState.Interpreting, ScriptName = sc.Scenario, PC = 0, IP = offset == null ? sc.Ctor : offset, Argv = null, BindingSceneName = sc.Scenario, BindingFunctionName = null, Delay = TimeSpan.FromMilliseconds(0), Tag = "" }; this.coreStack.Push(smf); this.EBP = this.SAVEP = this.coreStack.Peek(); }