Talking about CSREPL – REPL for C#

Here is a little update to Don Box’s very cool CSREPL – REPL for C# program.  I added multiline support, a"Go" cmd (ala SQL), and Eval and Exit commands.  Just run the the console program and type some c# and type "go" on a new line to execute the code.  If you just want to evaluate an expression, type "Eval" (case sensitive) followed by the expression and type go on a new line.

Example:

c:\>cscmd
Enter line(s) of C# code, type ‘GO’ and hit Enter.

> Eval 1+1
> go
2
> for(int i=0; i<5; i++)
> {
>   Console.WriteLine("Hello");
> }
> go
Hello
Hello
Hello
Hello
Hello

>exit

Can be handy for some things.  Did a Win version too, maybe will post that latter. 

//
// Cmd.cs
//
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Reflection;
using System.Text;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.Text.RegularExpressions;

namespace CSCmd
{
    public class Cmd
    {
        static string progString =
@"using System;
using System.Text;
public delegate void Proc();
public class Wrapper
{
    public static object Set(string name, object value)
    {
        AppDomain.CurrentDomain.SetData(name, value);
        return value;
    }
    public static object Get(string name)
    {
        return AppDomain.CurrentDomain.GetData(name);
    }
    public static object Invoke(Proc proc)
    {
        proc();
        return null;
    }
    public static object Run()
    {
        {0};
        return null;
    }
}";

        public static string StringEval(string expr)
        {
            if ( expr.StartsWith("Eval ") )
                expr = expr.Replace("Eval ", "return ");
           
            string program = progString.Replace("{0}", expr);

            ICodeCompiler compiler = CodeDomProvider.CreateProvider("C#").CreateCompiler();
            CompilerParameters cp = new CompilerParameters();
            cp.GenerateExecutable = false;
            cp.GenerateInMemory = true;

            CompilerResults results = compiler.CompileAssemblyFromSource(cp, program);
            if ( results.Errors.HasErrors )
            {
                return results.Errors[0].ErrorText;
            }
            else
            {
                Assembly assm = results.CompiledAssembly;
                Type target = assm.GetType("Wrapper");
                MethodInfo method = target.GetMethod("Run");
                object result = method.Invoke(null, null);
                return result == null ? null : result.ToString();
            }
        }
    }
}

//
// Program.cs
//
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;

namespace CSCmd
{
    class Program
    {
        static void Main(string[] args)
        {
            StringBuilder sb = new StringBuilder();
            Console.WriteLine("Enter line(s) of C# code, type ‘GO’ and hit Enter.\n");
            while ( true )
            {
                Console.Write("> ");
                Console.Out.Flush();
                string expr = Console.ReadLine();
                if ( expr == null )
                    break;

                if ( expr.Equals("exit", StringComparison.InvariantCultureIgnoreCase) )
                    break;
                if ( ! expr.Equals("go", StringComparison.InvariantCultureIgnoreCase) )
                {
                    sb.Append(expr);
                    continue;
                }

                try
                {
                    string program = sb.ToString();
                    sb.Length = 0;
                    string result = Cmd.StringEval(program);
                    if ( result == null )
                        result = "";
                    Console.WriteLine(result);
                    //if ( !result.EndsWith("\n") )
                    //    Console.WriteLine();
                }
                catch ( Exception ex )
                {
                    Console.WriteLine(ex.GetType().Name + ": " + ex.Message);
                }
            }
        }
    }
}


William

Advertisements
This entry was posted in Uncategorized. Bookmark the permalink.