Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Running a mini-program in Mono.Csharp

I'm trying to write an interactive C# teaching app, where the user can experiment/change code examples and see what happens (kinda like jsfiddle).

I've found a lot of examples for small expressions or REPL-like uses of Mono.Csharp as runtime compiler, but I can't quite find an example where a "mini program" is executed.

Here's my toy code so far (an MVC action). The "code" parameter is posted straight from a textarea.

[HttpPost]
public ActionResult Index(string code)
{
    var reportWriter = new StringWriter();
    var settings = new CompilerSettings();
    var printer = new ConsoleReportPrinter(reportWriter);
    var reports = new Report(printer);
    var eval = new Evaluator(settings, reports);

    var model = new CodeViewModel();
    model.Code = code;
    eval.Run(code);
    model.Result = reportWriter.ToString();

    return View("Index", model);
}

Now suppose the code is a string like this:

using System;
public class MyClass
{
    public void DoSomething()
    {
        Console.WriteLine("hello from DoSomething!");
    }
}

How do I bootstrap this (i.e. instantiate a MyClass object and call DoSomething on it)? I've tried just appending new MyClass().DoSomething(); to the end, but I get this:

{interactive}(1,2): warning CS0105: The using directive for `System' appeared previously in this namespace
{interactive}(1,8): (Location of the symbol related to previous warning)
{interactive}(11,1): error CS1530: Keyword `new' is not allowed on namespace elements
{interactive}(11,4): error CS1525: Unexpected symbol `MyClass', expecting `class', `delegate', `enum', `interface', `partial', or `struct'

What am I missing?

like image 971
Matthew Groves Avatar asked Sep 28 '12 03:09

Matthew Groves


People also ask

What version of C# does Mono support?

The Mono C# compiler is considered feature complete for C# 1.0, C# 2.0, C# 3.0, C# 4.0, C# 5.0 and C# 6.0 (ECMA) and it has partial support for C# 7.

What is Mono mcs?

mcs is the Mono C# compiler, an implementation of the ECMA-334 language specification. You can pass one or more options to drive the compiler, and a set of source files. Extra options or arguments can be provided in a response file. Response files are referenced by prepending the @ symbol to the response file name.

What is compiler in C#?

About CompilingThe amazing part of the coding process is the compiler. The compiler takes the text that you've written and will convert it to machine code (in the case of languages such as C++) or an intermediary language that can be executed by a Just In Time Compiler (in the case of languages such as C# and Java).


2 Answers

var reportWriter = new StringWriter();
var settings = new CompilerSettings();
var printer = new ConsoleReportPrinter(reportWriter);
var reports = new Report(printer);
var eval = new Evaluator(settings, reports);

eval.Run(code);

eval.Run(@"
    var output = new System.IO.StringWriter(); 
    Console.SetOut(output);
    new MyClass().DoSomething();");

var model = new CodeViewModel();
model.Code = code;

if (reports.Errors > 0)
   model.Result = reportWriter.ToString();
else
   model.Result = (string) eval.Evaluate("output.ToString();");

return View("Index", model);
like image 101
SHSE Avatar answered Oct 08 '22 02:10

SHSE


Although this question has already been accepted, I was having a similar issue when I ran across this post. I finally figured it out, so I thought I'd post here in case someone else runs into trouble.

You cannot mix using's and other statements in the same call to the Evaluator. From the documentation on the Mono.CSharp REPL:

The using declarations must appear on their own and can not be mixed with regular statements in a single line.

Since this is using individual calls to the Evaluator for each line, this same restriction applies for invoking the Evaluator from your application.

like image 28
jheddings Avatar answered Oct 08 '22 01:10

jheddings