<iframe align="top" marginwidth="0" marginheight="0" src="http://www.zealware.com/csdnblog01.html" frameborder="0" width="728" scrolling="no" height="90"></iframe>
原文:CSREPL - REPL for C#
在ChrisAn忙于将Python寄宿于AvPad之时,我在思考为什么他不把C#也同时考虑进去呢?
作为一项生存能力的测试,我在10分钟内,编写了一个简单的REPL程序,它支持C#表达式和语句的命令行解析。
下面是它的基本使用方法:
>1+2+3
6
>DateTime.Now.ToString("T");
4:12:36 PM
为了支持交叉表达式变量,我定义了两个内置的函数,Set 和 Get:
>Set("X",32)
32
>Get("X")
32
为了支持调用任意的代码块,我定义了一个能够解析void(void) 代理的 Invoke方法:
> Invoke(delegate { for (int i = 0; i
0
1
2
3
4
5
下面是原代码,在Whidbey Beta2下,将其编译为Console程序。
using
System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
using System.CodeDom;
using System.CodeDom.Compiler;
namespace csrepl ... {
classProgram...{
staticstringfuncprefix="usingSystem; "
+"publicdelegatevoidProc(); "
+"publicclassWrapper{ "
+"publicstaticobjectSet(stringname,objectvalue){ "
+"AppDomain.CurrentDomain.SetData(name,value); "
+"returnvalue; "
+"} "
+"publicstaticobjectGet(stringname){ "
+"returnAppDomain.CurrentDomain.GetData(name); "
+"} "
+"publicstaticobjectInvoke(Procproc){ "
+"proc(); "
+"returnnull; "
+"} "
+"publicstaticobjectEval(){return ";
staticstringfuncsuffix="; }}";
staticstringStringEval(stringexpr)...{
stringprogram=funcprefix+expr+funcsuffix;
ICodeCompilercompiler=CodeDomProvider.CreateProvider("C#").CreateCompiler();
CompilerParameterscp=newCompilerParameters();
cp.GenerateExecutable=false;
cp.GenerateInMemory=true;
CompilerResultsresults=compiler.CompileAssemblyFromSource(cp,program);
if(results.Errors.HasErrors)...{
if(results.Errors[0].ErrorNumber=="CS0029")
returnStringEval("Invoke(delegate{"+expr+";})");
returnresults.Errors[0].ErrorText;
}
else...{
Assemblyassm=results.CompiledAssembly;
Typetarget=assm.GetType("Wrapper");
MethodInfomethod=target.GetMethod("Eval");
objectresult=method.Invoke(null,null);
returnresult==null?null:result.ToString();
}
}
staticvoidMain(string[]args)...{
while(true)...{
Console.Write(">");
Console.Out.Flush();
stringexpr=Console.ReadLine();
if(expr==null)
break;
try...{
stringresult=StringEval(expr);
Console.WriteLine(result);
}
catch(TargetInvocationExceptionex)...{
Console.WriteLine(ex.InnerException.GetType().Name+":"+ex.InnerException.Message);
}
catch(Exceptionex)...{
Console.WriteLine(ex.GetType().Name+":"+ex.Message);
}
}
}
}
}
using System.Collections.Generic;
using System.Reflection;
using System.Text;
using System.CodeDom;
using System.CodeDom.Compiler;
namespace csrepl ... {
classProgram...{
staticstringfuncprefix="usingSystem; "
+"publicdelegatevoidProc(); "
+"publicclassWrapper{ "
+"publicstaticobjectSet(stringname,objectvalue){ "
+"AppDomain.CurrentDomain.SetData(name,value); "
+"returnvalue; "
+"} "
+"publicstaticobjectGet(stringname){ "
+"returnAppDomain.CurrentDomain.GetData(name); "
+"} "
+"publicstaticobjectInvoke(Procproc){ "
+"proc(); "
+"returnnull; "
+"} "
+"publicstaticobjectEval(){return ";
staticstringfuncsuffix="; }}";
staticstringStringEval(stringexpr)...{
stringprogram=funcprefix+expr+funcsuffix;
ICodeCompilercompiler=CodeDomProvider.CreateProvider("C#").CreateCompiler();
CompilerParameterscp=newCompilerParameters();
cp.GenerateExecutable=false;
cp.GenerateInMemory=true;
CompilerResultsresults=compiler.CompileAssemblyFromSource(cp,program);
if(results.Errors.HasErrors)...{
if(results.Errors[0].ErrorNumber=="CS0029")
returnStringEval("Invoke(delegate{"+expr+";})");
returnresults.Errors[0].ErrorText;
}
else...{
Assemblyassm=results.CompiledAssembly;
Typetarget=assm.GetType("Wrapper");
MethodInfomethod=target.GetMethod("Eval");
objectresult=method.Invoke(null,null);
returnresult==null?null:result.ToString();
}
}
staticvoidMain(string[]args)...{
while(true)...{
Console.Write(">");
Console.Out.Flush();
stringexpr=Console.ReadLine();
if(expr==null)
break;
try...{
stringresult=StringEval(expr);
Console.WriteLine(result);
}
catch(TargetInvocationExceptionex)...{
Console.WriteLine(ex.InnerException.GetType().Name+":"+ex.InnerException.Message);
}
catch(Exceptionex)...{
Console.WriteLine(ex.GetType().Name+":"+ex.Message);
}
}
}
}
}
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1726369