实现简单的CSharpShell -- OrcShell (1) 基本结构
一、程序的基本结构
程序的控制核心是Context类,它持有:
·类型管理器TypeManager,管理该运用程序域加载的命名空间及类型的树,树结构如下:
TypeDictionary(Root)
|--TypeDictionary
| |--TypeDictionary
| |--TypeDictionary
| |
| |--Type
| |--Type
| |
|
|--TypeDictionary
|
|--Type
|--Type
|
|--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(">> ");
}
{
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;
}
{
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;
}
版权所有,欢迎转载