如何为使用 Reflection.Emit 制作的编译器制作 REPL?

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

为解释器做一个 repl 是微不足道的。但是,我想知道如何为编译器做同样的事情。我了解 LLVM 如何双向工作,并为 C 等编译语言提供 REPL,但不明白这怎么可能。

我正在用 F# 构建一种玩具语言,所以想知道如果我生成带有反射发射的程序集,该怎么做(即:如果编译为 .NET 字节码)

编译型语言的 REPL 工作方式通常是发出代码并立即运行。当您使用 F# Interactive 时,F# 代码被解析、类型检查和编译(像往常一样),但不是将其保存到文件中,而是将生成的程序集保存在内存中并立即运行代码。我认为 C# REPL 实际上将程序集保存到磁盘的某处,然后立即从那里加载代码。

  • 最简单的入口点可能是 .NET 中的 DynamicMethod 类型(请参阅 MSDN documentation with a sample。您可以使用它来发出 IL 代码,将其包装成委托并调用它。

  • 如果您需要发出类型(不仅仅是方法主体),那么您将需要 DefineDynamicAssembly 方法(请参阅 MSDN documentation),它允许您定义具有类型的程序集.

另一种方法是在 Roslyn 或 F# Quotations 之上构建您的语言,但如果您已经编译为 .NET 字节码,那么上面的方法应该可以解决问题。