Beispiel #1
0
            public ReturnCode Run()
            {
                //暫存運算結果
                string val;

                //如果運算成功就寫入變量的值
                //回傳空白的返回碼
                if (ExprParser.TryParse(expr, out val))
                {
                    //如果是反應設定
                    if (ID == "$WAITFORRESP" && val.ToUpper() == "FALSE")
                    {
                        Internals.Execute("MAKERESP", "");
                        return(new ReturnCode("", ""));
                    }

                    //寫入變量
                    Variables.Write(ID, val);

                    return(new ReturnCode("", ""));
                }
                //失敗的話就回傳錯誤信息
                else
                {
                    return(new ReturnCode("ERR", expr + Localization.GetMessage("INVALIDEXPR", " is not a valid expression.") + " [MUTAN, " + ID + "=" + expr + "]"));
                }
            }
Beispiel #2
0
        private void textBox1_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                if (textBox1.Text.EndsWith("?"))
                {
                    string val;
                    MUTAN.ExprParser.TryParse(textBox1.Text.TrimEnd('?'), out val);
                    textBox1.Text = val;
                    textBox1.SelectAll();
                    return;
                }

                ActivityLog.Add(textBox1.Text);

                MUTAN.IRunnable obj;
                MUTAN.LineParser.TryParse(textBox1.Text, out obj);

                textBox1.Text = "";

                if (obj == null)
                {
                    textBox1.Text = "ERR";
                    textBox1.SelectAll();
                    return;
                }

                MUTAN.ReturnCode tmp = obj.Run();

                if (tmp.Command != "")
                {
                    Internals.Execute(tmp.Command, tmp.Argument);
                }
            }
        }
Beispiel #3
0
            public ReturnCode Run()
            {
                //暫存內容
                string arg = "";

                foreach (string line in content)
                {
                    //每一句用 /n 分隔
                    arg += line + "\n";
                }
                //利用 WAITFORRESP 指令等待回應然後執行反應
                Internals.Execute("WAITFORRESP", arg);
                return(new ReturnCode("", ""));
            }
Beispiel #4
0
        //執行循環
        void RunScript()
        {
            //如果不是要中斷的話就一直重覆
            while (!BREAKING)
            {
                //執行物件, 取得返回碼
                MUTAN.ReturnCode tmp = obj.Run();

                //如果是 BREAK 指令, 就設 BREAK 為真, 退出循環
                if (tmp.Command.Trim() == "BREAK")
                {
                    BREAKING = true;
                    break;
                }
                //否則就執行指令
                else
                {
                    Internals.Execute(tmp.Command, tmp.Argument);
                }
            }

            //如果循環結束了就中斷線程
            Break();
        }
Beispiel #5
0
            public ReturnCode Run()
            {
                //如果參數是空白,就直接執行, 不必運算參數
                if (arg.Trim() == "")
                {
                    Internals.Execute(RID, "");
                    return(new ReturnCode("", ""));
                }

                //否則就要對參數進行運數

                //暫存運算結果
                string val;

                //如果失敗的話就回傳錯誤信息
                if (!ExprParser.TryParse(arg, out val))
                {
                    return(new ReturnCode("ERR", arg + Localization.GetMessage("INVALIDEXPR", " is not a valid expression.") + "[MUTAN, " + RID + "(" + arg + ")]"));
                }

                //否則就執行
                Internals.Execute(RID, val);
                return(new ReturnCode("", ""));
            }
Beispiel #6
0
        //處理引擎的輸出
        void Engine_OutputDataReceived(object sender, DataReceivedEventArgs e)
        {
            string Data = Utils.UriDecode(e.Data);

            //如果是空白輸出, 不要理會
            //Ignore NULL and empty inputs that will crash the program
            if (Data == null || Data.Trim() == "")
            {
                return;
            }

            //activity log
            ActivityLog.Add("From " + Name + ": " + Data);

            //如果是詢問, 則調用 MUTAN 表達式解析器, 並返回結東
            //詢問的語法是 "(表達式)?"
            //First check if the engine is asking a question about value of an expression
            if (Data.EndsWith("?"))
            {
                //首先保護進程以免受到 BROADCAST 干擾
                NoBroadcast = true;

                string result;

                //去掉最後的問號, 就是表達式了
                //如果格式有誤的話, 會返回 INVALIDEXPR (無效的表達式) 或 IMBALBRACKET (括號不平衡)
                MUTAN.ExprParser.TryParse(Data.TrimEnd('?'), out result);
                Engine.StandardInput.WriteLine(result);

                //解除 BROADCAST 干擾保護
                NoBroadcast = false;

                //activity log
                ActivityLog.Add("To " + Name + ": " + result);

                return;
            }

            string RID = "";
            string arg = "";

            //首先假設是溝通用的指令, 主要是用來讓進程宣佈自己的角色和功能, 並取得可用接口等等的溝通協調用的指令
            //對字串分割並去掉多餘空白
            if (MUTAN.IsExec(Data))
            {
                RID = Data.Split('(')[0];
                arg = Data.Substring(RID.Length + 1, Data.Length - RID.Length - 2);
                RID = RID.Trim();
            }


            switch (RID)
            {
            //這是用來進入除錯模式的, 除錯模式下不會要求完備性
            case "DEBUG":
                Internals.Debugging = true;
                Variables.Write("$SYS_DEBUG", "TRUE");
                Internals.MESSAGE(Localization.GetMessage("DEBUG", "Entered debug mode. AZUSA will display all errors and listen to all commands."));
                return;

            //進行回傳
            case "Return":
                output    = arg;
                RESPONDED = true;
                return;

            //這是用來讓進程取得 AZUSA 的 pid, 進程可以利用 pid 檢查 AZUSA 是否存活, 當 AZUSA 意外退出時, 進程可以檢查到並一併退出
            case "GetAzusaPid":

                //首先保護進程以免受到 BROADCAST 干擾
                NoBroadcast = true;

                Engine.StandardInput.WriteLine(Process.GetCurrentProcess().Id);
                //activity log
                ActivityLog.Add("To " + Name + ": " + Process.GetCurrentProcess().Id);

                //解除 BROADCAST 干擾保護
                NoBroadcast = false;

                return;

            //這是讓進程宣佈自己的身份的, 這指令應該是進程完成各種初始化之後才用的
            case "RegisterAs":
                //先記錄現在是否完備
                bool tmp = ProcessManager.CheckCompleteness();

                //然後進行相應的登錄
                switch (arg)
                {
                case "AI":
                    currentType = PortType.AI;
                    ProcessManager.AIPid.Add(pid);
                    break;

                case "Input":
                    currentType = PortType.Input;
                    ProcessManager.InputPid.Add(pid);
                    break;

                case "Output":
                    currentType = PortType.Output;
                    ProcessManager.OutputPid.Add(pid);
                    break;

                case "Application":
                    currentType = PortType.Application;
                    break;

                default:
                    break;
                }

                //再次檢查完備性, 如果之前不完備, 現在完備了就進行提示
                if (!tmp && ProcessManager.CheckCompleteness())
                {
                    Internals.READY();
                }

                return;

            //這是讓進程宣佈自己的可連接的接口, AZUSA 記錄後可以轉告其他進程, 進程之間可以直接對接而不必經 AZUSA
            case "RegisterPort":
                ProcessManager.Ports.Add(arg.Trim('"'), currentType);
                this.Ports.Add(arg.Trim('"'));
                ProcessManager.Broadcast("PortHasChanged");
                return;

            //這是讓進程取得當前可用所有端口
            case "GetAllPorts":

                //首先保護進程以免受到 BROADCAST 干擾
                NoBroadcast = true;

                string result = "";
                foreach (KeyValuePair <string, PortType> port in ProcessManager.Ports)
                {
                    result += port.Key + ",";
                }

                Engine.StandardInput.WriteLine(result.Trim(','));

                //解除 BROADCAST 干擾保護
                NoBroadcast = false;

                //activity log
                ActivityLog.Add("To " + Name + ": " + result.Trim(','));

                return;

            //這是讓進程取得當前可用的AI 端口(AI引擎的接口)
            case "GetAIPorts":

                //首先保護進程以免受到 BROADCAST 干擾
                NoBroadcast = true;

                result = "";
                foreach (KeyValuePair <string, PortType> port in ProcessManager.Ports)
                {
                    if (port.Value == PortType.AI)
                    {
                        result += port.Key + ",";
                    }
                }

                Engine.StandardInput.WriteLine(result.Trim(','));

                //解除 BROADCAST 干擾保護
                NoBroadcast = false;

                //activity log
                ActivityLog.Add("To " + Name + ": " + result.Trim(','));

                return;

            //這是讓進程取得當前可用的輸入端口(輸入引擎的接口)
            case "GetInputPorts":

                //首先保護進程以免受到 BROADCAST 干擾
                NoBroadcast = true;

                result = "";
                foreach (KeyValuePair <string, PortType> port in ProcessManager.Ports)
                {
                    if (port.Value == PortType.Input)
                    {
                        result += port.Key + ",";
                    }
                }

                Engine.StandardInput.WriteLine(result.Trim(','));

                //解除 BROADCAST 干擾保護
                NoBroadcast = false;

                //activity log
                ActivityLog.Add("To " + Name + ": " + result.Trim(','));

                return;

            //這是讓進程取得當前可用的輸出端口(輸出引擎的接口)
            case "GetOutputPorts":

                //首先保護進程以免受到 BROADCAST 干擾
                NoBroadcast = true;

                result = "";
                foreach (KeyValuePair <string, PortType> port in ProcessManager.Ports)
                {
                    if (port.Value == PortType.Output)
                    {
                        result += port.Key + ",";
                    }
                }

                Engine.StandardInput.WriteLine(result.Trim(','));

                //解除 BROADCAST 干擾保護
                NoBroadcast = false;

                //activity log
                ActivityLog.Add("To " + Name + ": " + result.Trim(','));

                return;

            //這是讓進程可以宣佈自己責負甚麼函式, AZUSA 在接收到這種函件就會轉發給進程
            //函式接管不是唯一的, 可以同時有多個進程接管同一個函式, AZUSA 會每個宣告了接管的進程都轉發一遍
            case "LinkRID":
                string[] parsed = arg.Split(',');

                this.RIDs.Add(parsed[0], Convert.ToBoolean(parsed[1]));

                return;

            default:
                break;
            }

            //檢查整體架構是否完備, 完備或除錯模式下才執行指令
            if (Internals.SysReady || Internals.Debugging)
            {
                //否則假設是 MUTAN 指令,嘗試解析, 如果失敗的話, 就無視掉本次輸出

                //先創建一個可運行物件, 用來儲存解析結果
                MUTAN.IRunnable obj;


                //然後用單行解析器
                if (MUTAN.LineParser.TryParse(Data, out obj))
                {
                    //如果成功解析, 則運行物件, 獲取回傳碼
                    MUTAN.ReturnCode tmp = obj.Run();

                    //然後按回傳碼執行指令
                    if (tmp.Command != "")
                    {
                        Internals.Execute(tmp.Command, tmp.Argument);
                    }
                }
            }
            else
            {
                Internals.ERROR(Localization.GetMessage("ENGINEMISSING", "Some engines are missing. AZUSA will not execute any MUTAN commands unless AI and I/O are all registered."));
            }
        }
Beispiel #7
0
 public ReturnCode Run()
 {
     //執行 WAITFORRESP 指令, 讓 AZUSA 等待回應然後執行反應
     Internals.Execute("WAITFORRESP", content);
     return(new ReturnCode("", ""));
 }