A C# interpreter in 50 lines of code

With all the hype around scripting languages these days, here’s my contribution. A C# line interpreter. The principe is simple: append the code to a string and evaluate it when a return statement is added. This is some magic we can do with the System.CodeDom and System.Reflection namespace. Not quite has dynamic has ruby or python, but better then nothing…

Run it. Type some c# code, each line will be compiled instantly, type a return something; to restart the session.

Here’s an example:

Instant C#, hack some code...
>>> string cool = "wow that's cool!";
>>> cool = cool.ToUpper();
>>> return cool;
WOW THAT'S COOL!
>>>

using System;
using System.Reflection;
using System.Text;
using System.CodeDom.Compiler;
using Microsoft.CSharp;
 
public class InstantCSharp
{
    private StringBuilder _code = new StringBuilder();
    ICodeCompiler compiler = new CSharpCodeProvider().CreateCompiler();
    CompilerParameters parameters = new CompilerParameters();
 
    public static void Main()
    {
        new InstantCSharp().Start();
    }
 
    public InstantCSharp()
    {
        parameters.GenerateInMemory = true;
        parameters.ReferencedAssemblies.Add("System.dll");
    }
 
    public void Start()
    {
        Console.WriteLine("Instant C#, hack some code...");
 
        string cmd = ReadCmd();
 
        while (cmd != null)
        {
            object obj = Run(cmd);
            if (obj != null) Console.WriteLine(obj);
            cmd = ReadCmd();
        }
    }
 
    private static string ReadCmd()
    {
        Console.Write(">>> ");
        return Console.ReadLine();
    }
 
    private object Run(string cmd)
    {
        string code;
        string returnline = null;
        bool haserrors = false;
 
        if (!cmd.StartsWith("return"))
        {
            returnline = "return null;";
        }
 
        code = @"
            using System;
            public class Runner
            {
                public object Run()
                {
                    " + _code.ToString() + cmd + returnline + @"
                }
            }";
 
        CompilerResults compiled =
            compiler.CompileAssemblyFromSource(parameters, code);
 
        foreach (CompilerError e in compiled.Errors)
        {
            Console.WriteLine(e.ErrorText);
            if (!e.IsWarning) haserrors = true;
        }    
        if (haserrors) return null;
 
        object obj = compiled.CompiledAssembly.CreateInstance("Runner");
        object returned = compiled.CompiledAssembly.GetType("Runner")
            .InvokeMember(
                "Run",
                BindingFlags.InvokeMethod,
                null, obj, new object[] {}
            );    
 
        _code.Append(cmd); // All ok so include the line
        if (returnline == null) // A return call means end of the session
            _code = new StringBuilder();
 
        return returned;
    }
 
}

2 Comments

Filed under Misc

2 responses to “A C# interpreter in 50 lines of code

  1. Anonymous

    G’day – I notice you’re using some inline styles there. If you add “overflow: auto” to the list, your code section will no longer overflow its box in Firefox/Mozilla. Sadly, nothing much can be done to fix it in IE6…

    : Bat :

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s