假设我写了一个编程语言;对于同名,我将其称为 lang 。
开始写作的漫长旅程 lang ,我决定通过本身写朗开始。我实际上无法运行,因为没有任何运行的程序。
因此,我首先在Java中为 lang 编写另一个编译器。这次,当我完成后,我决定将其转换为字节码,然后将其保留。我现在有一个工作编译器,它将我所有的 lang 代码转换为字节。
因此,我决定将我的语言的自兼委员会插入我刚刚在Java中制作的编译器。然后,我将自兼委员会转换为字节码,然后删除Java编译器。我现在有一个 lang 编译器,纯粹写在本身中,转换为字节码,可以使用。
这创建了一个可靠的程序,我了解所有这些,但是我的问题是,相对于JVM的编译器设计,,如果我决定为我的语言发布更新该怎么办?如何更新字节码?我是否只需重写旧语言的更新版本?
我问这个,因为这是我想做的。本身就编写一种不存在的语言,然后首先在Java中创建编译器来将其引导到JVM。
与C 所做的相同。c带有类,然后在其中编写了C ,最后将C C c的c用于引导C 。但是,他们到底是如何更新语言的?
我将从您开发的两个可能的情况下回答。随时使用任何字节代码语言,您可以更新虚拟机或语言。
假设您首先要更新语言以具有新的语法或更改当前语义。然后,您可以将当前的编译器保留在> lang (编译器 a )中,并编辑其源,以便它可以正确编译您的新功能。然后,您使用旧编译器编译编译器,从而为您提供编译器 b 。如有必要,您现在可以重写编译器以使用新功能,然后使用编译器 b 对其进行编译以提供编译器 c 。
如果JVM更改怎么办?好吧,在这种情况下,您将旧版本的JVM保留在周围,调整编译器以应对新的字节码更改,然后用旧版本对其进行编译(这类似于编译器 b )。这将为您提供一个编译器,该编译器将其编译到新的字节码,但可以在旧的VM上运行。下一步是使其自行编译,现在您有一个在新VM上运行的新编译器(类似于编译器 c )。
我认为您的编译器不是最好的方法。
我将从我的语言的语法开始。
接下来是Lexer/Parser,将我的语言表达式转换为抽象语法树(AST)。AST是表达式的正确中间表示。
您将通过编写遍历AST的代码生成器来为您选择的虚拟机或处理器发射字节码或汇编语言指令。
您的更新在哪里发生?
如果是语言的基本原理,则必须修改语法和字节码排放。
如果您要优化字节码或移植到新处理器,则必须修改代码生成器。
第一个 lang 编译器可以写在 subset 的> lang 中。而且您只需要一个子集(bootstrap)编译器(甚至是Interoreter)。这可以用java写。
以后,可以用 lang 编写更广泛的编译器。较新的版本也可以做。
您甚至可以编写将Lang程序转换为Java的翻译器,并使用它在Lang中创建第一个转换器,然后将其转换为字节码编译器。