Mono’s c# compiler as a service on windows

The Mono team is proud to bring you a preview of C# 5.0 a few years before our friends in Building 41 do.

A snapshot of the code is available in the demo-repl. zip file. This contains the csharp. exe C# REPL shell and the Mono. CSharp. dll compiler-as-a-service assembly.

With Today’s code drop all those scenarios now work:

* Run Mono’s C# compiler on. NET
* Embed Mono’s Evaluator in your C# app.
* Use Mono’s REPL with the. NET framework runtime.

Background

Although we have had a compiler-as-a-service framework since September of 2008 it has been so far limited to Mono users, which effectively means only Linux and OSX users could use our C# REPL and the compiler as a service.

The reason is that the Mono’s C# compiler uses System. Reflection. Emit as its code generation backend. This API was fine for implementing C# 1.0 but required a few changes to support compiling its own core library (mscorlib, the

equivalent of libc in C or rt in Java).

When we started to work on our C# 2.0 support, we were working on our compiler as the language was being standardized at ECMA. Our compiler evolved faster than the underlying support for Reflection and Reflection. Emit did and this lead to more Mono-specific extensions being added to our Reflection and Reflection. Emit code. The more extensions that we depended on, the fewer chances we had of running with Microsoft’s runtime.

As time went by, Microsoft did improve their System. Reflection. Emit, but at that point, it was too late for us to go back to it.

This had the unfortunate side effects that our compiler could not run on the Microsoft runtime. Now, this per se is not a major problem since Windows users likely use Microsoft’s CSC compiler.

But this also meant that our awesome compiler as a service could not be used by. NET developers and it also meant that our REPL shell could not be used with. NET and most importantly, neither one would run on Silverlight.

Our compiler also relied heavily on our extended System. Reflection and System. Type as its own type system. And we could not just change our APIs for Microsoft’s APIs to run on the Microsoft runtime.

Today’s commit at the coref replaces our dependency on System. Type and introduced our own Mono. CSharp. TypeSpec which lifts many of the restrictions that we had on System. Type. All of the hard computations that we had to do for inflating generics types are done here now and we can query the types without the backward Reflection limitations.

With today’s changes, not only we became more portable, but the move from System. Type to TypeSpec and MemberCache improved the compiler performance by 30% and fixes dozens of bugs that were very hard to fix with the previous compiler architecture.
REPL Love

We have a small guide on using the C# REPL on Linux.

Caveat: both the Microsoft and the Mono C# compilers loads libraries from their “base directory”, never from the Global Assembly Cache.

In Mono, the csharp command happens to be in the same directory as the rest of Mono, so loading implicit libraries just works (Loading System. Core for example). But when running our csharp command on Windows, unless you put the binary in the same location as csc. exe the REPL wont be able to load libraries using their short names.

This is particularly obnoxious because to use LINQ you need to use the full assembly name, or copy csharp. exe to the directory that contains System. Core so you can just do:

Csharp> using System. Linq;
csharp> from x in “Foo” select x;

Future work



Mono’s c# compiler as a service on windows