【发布时间】:2016-01-11 21:01:45
【问题描述】:
为解释器创建一个 repl 是微不足道的。但是,我想知道如何为编译器做同样的事情。我看到 LLVM 可以双向工作,并且存在用于 C 等编译语言的 REPL,但不知道这怎么可能。
我正在用 F# 构建一个玩具语言,所以想知道如果我生成带有反射发射的程序集,该怎么做(即:如果编译为 .NET 字节码)
【问题讨论】:
标签: .net compiler-construction f# read-eval-print-loop
为解释器创建一个 repl 是微不足道的。但是,我想知道如何为编译器做同样的事情。我看到 LLVM 可以双向工作,并且存在用于 C 等编译语言的 REPL,但不知道这怎么可能。
我正在用 F# 构建一个玩具语言,所以想知道如果我生成带有反射发射的程序集,该怎么做(即:如果编译为 .NET 字节码)
【问题讨论】:
标签: .net compiler-construction f# read-eval-print-loop
用于编译语言的 REPL 的工作方式通常是发出代码并立即运行它。当您使用 F# Interactive 时,F# 代码会被解析、类型检查和编译(像往常一样),但不是将其保存到文件中,而是将生成的程序集保存在内存中并立即运行代码。我认为 C# REPL 实际上将程序集保存到磁盘的某个位置,然后立即从那里加载代码。
最简单的入口点可能是 .NET 中的 DynamicMethod 类型(请参阅 MSDN documentation with a sample。您可以使用它来发出 IL 代码,将其包装到委托中并调用它。
如果您需要发出类型(不仅仅是方法体),那么您将需要DefineDynamicAssembly 方法(请参阅MSDN documentation),它可以让您定义带有类型的程序集。
另一种方法是在 Roslyn 或 F# Quotations 之上构建您的语言,但如果您已经编译为 .NET 字节码,那么上述方法应该可以解决问题。
【讨论】: