2

我正在设计一种高级的、面向对象的、垃圾收集的编程语言,但我在如何制作模板方面遇到了问题。我计划创建一个类似于 .NET 或 JVM 的 VM 类型系统(但它会在底层使用 LLVM)。问题是我想拥有强大的、类似 C++ 的模板,但具有动态链接(因此我可以替换模板库而无需重新编译使用它的所有内容)。我希望能够在没有模板定义的情况下编译源文件。应尽量减少 JIT 时的代码生成。

以下是我正在考虑的选项:

  • 具有静态链接到每个编译单元的模板库的概念。模板库本质上就像一个 AST,在模板实例化时需要填充空白。这样做的问题是,如果使用不同版本的模板库编译两个文件,它们可能不兼容,或者如果模板库有错误,则所有内容都必须重新编译。这就是 C++ 的做法。
  • 具有在 JIT 时间链接的模板库。这解决了大部分问题,但要求 IR 本质上是 AST。我希望 IR 的水平要低得多。这需要更多的 JIT 工作。
  • 拥有类似 C# 的懦弱泛型,只有类型作为参数。这是相当有限的,但允许简单的代码生成和动态链接。

还有其他我没有想到的好方法吗?我倾向于第一个选项,但我真的不喜欢任何选项。你认为最好的选择是什么?

4

4 回答 4

1

我想这取决于你想要的专业化程度,即模板编译器的强大程度。

如果你看一下 c++,编译器可以做各种花哨的事情(比如通过递归生成子类,可能计算分形继承图以及即时计算 Pi 的数量)。

如果你想要这种能力,你可能需要一个强大的高级 JIT。FWIW,我认为那会很酷。(只需在运行时包含完整的编译器。)

于 2009-04-30T21:41:43.800 回答
0

想想这些模板会有多强大。您必须记住,拥有即时编译的语言意味着必须在加载时和运行时完成大量繁重的工作。因此,您制作的模板越强大,您从中获得的性能就越低。


如果您真的要走这条路,您还可以按照Macke 的建议在运行时包含编译器。事实上,有很多语言可以做到这一点。

通过这样做,您正在使您的语言实现成为“解释”或部分“解释”的语言。在这些术语中,模板只是 match-replace-eval 的化装,这有什么问题,模板通常在动态语言中像这样工作。请记住,最后将是功率与性能。


注意:当面对这种决定时,可能值得稍微退后一步。确定用例并确定它们的优先级,将如何实现与设计分开,这样您就可以迭代设计,而不会让实现成为瘫痪的原因,但仍然要考虑它。

每次迭代您都会扩展设计以涵盖更多用例,同时确定最佳设计。当你达到你喜欢的设计时,你可以迭代,然后你也可以迭代实现。这种方法允许您首先涵盖更重要的情况。

是的,我建议采用迭代增量方法。我这样做是因为这个问题是关于一种语言的设计,但它似乎非常关心实现。有必要保持这些想法的基础,否则您最终会陷入极端之一(功能太强大而可怜的性能或根本没有高性能解决方案的模板)。

于 2013-12-13T21:09:40.227 回答
0

你想要达到的目标几乎是不可能的。您必须为模板定义和使用这些模板的代码保留几乎所有语言的高级表示,并从几乎经过轻微处理的源代码级别执行 JIT 编译。如果您对此感到满意 - 您必须让编译器的其余部分非常简单,并且您将无法使用任何重量级的 LLVM 优化。没有其他方法可以解决,模板元编程依赖于高级信息的可用性。

于 2011-09-21T19:27:24.227 回答
0

有点依赖于语言的其余部分......如果你有运算符重载、值类型等,那么你真的很复杂(并且可能错过了很好的优化机会)不走 C++ 路线:使用模板的代码还必须在 JIT 时间内表示为 AST,以实现最大程度的专业化。

由于 C++ 模板本质上是一种宏形式,因此在生成代码之前,它们可以减少由重复产生的所有膨胀。

模板类型(至少在 C++ 中)往往是所有其他代码基础的最核心类型,因此,如果它们发生变化,假设其他代码仍然与它兼容,除了最小的变化之外,其他代码仍然兼容。

于 2011-09-21T18:13:40.670 回答