在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 < 6; i++) Console.WriteLine(i); })

0

1

2

3

4

5

下面是原代码,在Whidbey Beta2下,将其编译为Console程序。


C#的CSREPL-REPL_ideusing System;

C#的CSREPL-REPL_ideusing System.Collections.Generic;

C#的CSREPL-REPL_ideusing System.Reflection;

C#的CSREPL-REPL_ideusing System.Text;

C#的CSREPL-REPL_ideusing System.CodeDom;

C#的CSREPL-REPL_ideusing System.CodeDom.Compiler;

C#的CSREPL-REPL_ide

C#的CSREPL-REPL_ide 

C#的CSREPL-REPL_ide

C#的CSREPL-REPL_c#_10C#的CSREPL-REPL_ide_11namespace csrepl ...{

C#的CSREPL-REPL_i++_12C#的CSREPL-REPL_c#_13    class Program ...{

C#的CSREPL-REPL_ide_14

C#的CSREPL-REPL_ide_14 

C#的CSREPL-REPL_ide_14

C#的CSREPL-REPL_ide_14        static string funcprefix = "using System; "

C#的CSREPL-REPL_ide_14            + "public delegate void Proc(); "

C#的CSREPL-REPL_ide_14            + "public class Wrapper {  "

C#的CSREPL-REPL_ide_14            + "  public static object Set(string name, object value) {  "

C#的CSREPL-REPL_ide_14            + "    AppDomain.CurrentDomain.SetData(name, value); "

C#的CSREPL-REPL_ide_14            + "    return value;  "

C#的CSREPL-REPL_ide_14            + "  } "

C#的CSREPL-REPL_ide_14            + "  public static object Get(string name) {  "

C#的CSREPL-REPL_ide_14            + "    return AppDomain.CurrentDomain.GetData(name); "

C#的CSREPL-REPL_ide_14            + "  } "

C#的CSREPL-REPL_ide_14            + "  public static object Invoke(Proc proc) {  "

C#的CSREPL-REPL_ide_14            + "    proc(); "

C#的CSREPL-REPL_ide_14            + "    return null;  "

C#的CSREPL-REPL_ide_14            + "  } "

C#的CSREPL-REPL_ide_14            + "  public static object Eval() { return  ";

C#的CSREPL-REPL_ide_14        static string funcsuffix = ";  } }";

C#的CSREPL-REPL_ide_14

C#的CSREPL-REPL_ide_14 

C#的CSREPL-REPL_ide_14

C#的CSREPL-REPL_ide_14

C#的CSREPL-REPL_i++_12C#的CSREPL-REPL_c#_13        static string StringEval(string expr) ...{

C#的CSREPL-REPL_ide_14            string program = funcprefix + expr + funcsuffix;

C#的CSREPL-REPL_ide_14

C#的CSREPL-REPL_ide_14 

C#的CSREPL-REPL_ide_14

C#的CSREPL-REPL_ide_14            ICodeCompiler compiler = CodeDomProvider.CreateProvider("C#").CreateCompiler();

C#的CSREPL-REPL_ide_14            CompilerParameters cp = new CompilerParameters();

C#的CSREPL-REPL_ide_14            cp.GenerateExecutable = false;

C#的CSREPL-REPL_ide_14            cp.GenerateInMemory = true;

C#的CSREPL-REPL_ide_14

C#的CSREPL-REPL_ide_14 

C#的CSREPL-REPL_ide_14

C#的CSREPL-REPL_ide_14            CompilerResults results = compiler.CompileAssemblyFromSource(cp, program);

C#的CSREPL-REPL_i++_12C#的CSREPL-REPL_c#_13            if (results.Errors.HasErrors) ...{

C#的CSREPL-REPL_ide_14                if (results.Errors[0].ErrorNumber == "CS0029")

C#的CSREPL-REPL_ide_14                    return StringEval("Invoke(delegate { " + expr + "; })");

C#的CSREPL-REPL_ide_14                return results.Errors[0].ErrorText;

C#的CSREPL-REPL_c#_56            }

C#的CSREPL-REPL_i++_12C#的CSREPL-REPL_c#_13            else ...{

C#的CSREPL-REPL_ide_14                Assembly assm = results.CompiledAssembly;

C#的CSREPL-REPL_ide_14                Type target = assm.GetType("Wrapper");

C#的CSREPL-REPL_ide_14                MethodInfo method = target.GetMethod("Eval");

C#的CSREPL-REPL_ide_14                object result = method.Invoke(null, null);

C#的CSREPL-REPL_ide_14                return result == null ? null : result.ToString();

C#的CSREPL-REPL_c#_56            }

C#的CSREPL-REPL_c#_56        }

C#的CSREPL-REPL_ide_14

C#的CSREPL-REPL_ide_14 

C#的CSREPL-REPL_ide_14

C#的CSREPL-REPL_i++_12C#的CSREPL-REPL_c#_13        static void Main(string[] args) ...{

C#的CSREPL-REPL_ide_14

C#的CSREPL-REPL_ide_14 

C#的CSREPL-REPL_ide_14

C#的CSREPL-REPL_i++_12C#的CSREPL-REPL_c#_13            while (true ) ...{

C#的CSREPL-REPL_ide_14                Console.Write("> ");

C#的CSREPL-REPL_ide_14                Console.Out.Flush();

C#的CSREPL-REPL_ide_14                string expr = Console.ReadLine();

C#的CSREPL-REPL_ide_14                if (expr == null)

C#的CSREPL-REPL_ide_14                    break;

C#的CSREPL-REPL_i++_12C#的CSREPL-REPL_c#_13                try ...{

C#的CSREPL-REPL_ide_14                    string result = StringEval(expr);

C#的CSREPL-REPL_ide_14                    Console.WriteLine(result);

C#的CSREPL-REPL_c#_56                }

C#的CSREPL-REPL_i++_12C#的CSREPL-REPL_c#_13                catch (TargetInvocationException ex) ...{

C#的CSREPL-REPL_ide_14                    Console.WriteLine(ex.InnerException.GetType().Name + ": " + ex.InnerException.Message);

C#的CSREPL-REPL_c#_56                }

C#的CSREPL-REPL_i++_12C#的CSREPL-REPL_c#_13                catch (Exception ex) ...{

C#的CSREPL-REPL_ide_14                    Console.WriteLine(ex.GetType().Name + ": " + ex.Message);

C#的CSREPL-REPL_c#_56                }

C#的CSREPL-REPL_c#_56            }

C#的CSREPL-REPL_ide_14

C#的CSREPL-REPL_c#_56        }

C#的CSREPL-REPL_c#_56    }

C#的CSREPL-REPL_i++_98}