一、程序的基本結構
程序的控制核心是Context類,它持有:
·類型管理器TypeManager,管理該運用程序域加載的命名空間及類型的樹,樹結構如下:
TypeDictionary(Root) |--TypeDictionary | |--TypeDictionary | |--TypeDictionary | | | |--Type | |--Type | | | |--TypeDictionary | |--Type |--Type |
其中TypeDictionary對應的是命名空間,Type對應的是類型。TypeManager還管理一個名為Now的 TypeDictionary,表示當前所在的 TypeDictionary。
·AliasCmds ,命令縮寫字典。
·Instances,用戶變量字典。
·CmdDispatcher是命令指派器。控制台獲取指令後傳給Context。代碼:
while ((cmd = Console.ReadLine().Trim()) != "exit") { if (!String.IsNullOrEmpty(cmd)) { cxt.Invoke(cmd); } Console.Write(">> "); }
Context又傳給CmdDispatcher處理。CmdDispatcher解析命令,根據命令的特征選擇不同的CmdHandler 來處理。目前編寫了5個CmdDispatcher:
CdClassCmdHandler:進出命名空間的處理,針對cdc指令;
ListClassCmdHandler:列出命名空間和類型,針對lsc,dirc指令;
ListInstanceCmdHandler:列出用戶變量,針對 my 指令;
ListAliasCmdHandler:列出指令縮寫,針對 alias 指令;
CscCmdHandler:編譯並運行代碼,其它CmdDispatcher 處理不了的都交給它。
CmdDispatcher.Dispatch()方法代碼:
public void Dispatch() { String[] results = InputCmdString.Split(SPLITS, StringSplitOptions.None); if(results.Length == 0) return; String cmd = results[0]; String mark = String.Empty; IList<String> args = new List<String>(); Int32 argIndex = 1; if (results.Length > 1 && results[1].StartsWith("-")) { argIndex ++; mark = results[1]; } for(;argIndex < results.Length;argIndex++) { args.Add(results[argIndex]); } switch (cmd.ToLower()) { case "debug": // 開啟debug開關 Context.Debug = true; break; case "undebug": // 關閉debug開關 Context.Debug = false; break; case "cdc": // 改變命名空間 new CdClassCmdHandler(Context, InputCmdString, mark, args).Run(); break; case "lsc": // 列出命名空間的內容 case "dirc": new ListClassCmdHandler(Context, InputCmdString, mark, args).Run(); break; case "my": // 列出用戶變量 new ListInstanceCmdHandler(Context, InputCmdString, mark, args).Run (); break; case "alias": // 列出alias列表 new ListAliasCmdHandler(Context, InputCmdString, mark, args).Run(); break; default: String fullCmd = Context.GetFullCmd(cmd); if (fullCmd != null) // 處理 alias { if (mark != null) fullCmd += " " + mark; if (args != null && args.Count > 0) { foreach(String s in args) { fullCmd += " " + s; } } Context.Invoke(fullCmd); } else // 編譯代碼並運行 { new CscCmdHandler(Context, InputCmdString).Run(); } break; } return; }