Search code examples
.netcompiler-constructionf#read-eval-print-loop

How make a REPL for a compiler made with Reflection.Emit?


Making a repl for a interpreter is trivial. However, I wonder how do the same for a compiler. I see how LLVM can work both-ways and exist REPL for compiled languages like C, but don't grasp how is that posible.

I'm building a toy language in F#, so wonder how do the same (ie: If compile to .NET bytecode) if I generate assemblies with reflection emit


Solution

  • The way the REPL for compiled languages works is generally that it emits the code and immediately runs it. When you use F# Interactive, the F# code is parsed, type checked and compiled (as usual), but rather than saving it to a file it just keeps the generated assembly in memory and it runs the code immediately. I think the C# REPL actually saves the assembly somewhere to disk and then immediately loads the code from there.

    • The simplest entry point for this is probably the DynamicMethod type in .NET (see the MSDN documentation with a sample. You can use it to emit IL code, wrap it into a delegate and invoke it.

    • If you need to emit types (not just method bodies), then you'll need the DefineDynamicAssembly method (see MSDN documentation) which lets you define assemblies with types.

    An alternative would be to build your language on top of Roslyn or F# Quotations, but if you're already compiling to .NET bytecode, then the above should do the trick.