使用 Clojure 将语法添加到 JavaScript

Add syntax to JavaScript with Clojure

我想像 Sweet.js 一样向我的 JavaScript 文件添加新语法,但使用 Clojure/ClojureScript 进行转换。

这是我想做的事情:

//original

specialFunction add(a, b) {
   return a + b;
}


//transformed

function add(a, b) {
   return a + b;
}
registerSpecialFunction({
   name: "add",
   args: ["a", "b"],
   func: add
});

如果我错了请纠正我,但我认为最好的方法是:

  1. 将JS文件解析成AST
  2. 进行转换
  3. 打印结果 AST 作为 JavaScript

知道如何完成第 1 部分和第 3 部分吗?我的想法对吗?

请注意,这可能是一项艰巨的任务,但可能是一项很好的学习练习。

如果您想从 Clojure 中获得相同的控件,则必须重新实现 Sweet.js 中的概念或宏,或者 Babylon 中自定义解析器扩展的想法(Babel 的解析器)。

无论哪种方式,您都需要编写一个能够理解 JavaScript 语法超集的解析器。您可能想查看解析器生成器,例如 instaparse (Clojure) and peg.js (JavaScript).

然后你需要决定是要对语言语法进行固定数量的添加(如Babel)还是允许宏定义自己的语法extensions/replacement规则(如Sweet.js) .此时,您需要编写某种引擎来转换解析器生成的 AST。

宏可以通过多种方式实现,从 replacement rules like you'd find in C and C++ to full blown compile-time evaluated functions that work directly with the AST like you'd find in Clojure.

使用这个新工具解析和转换 AST 后,您需要将其转换为有效的 JavaScript AST。它将使事情更容易保持与 ESTree specification as this will allow you to use tools like escodegen 的兼容性,以实际从 AST 本身生成 JavaScript 代码。

当然,像 peg.js 和 escodegen 这样的搭载工具只有在您将工具编写为 ClojureScript 并针对 NodeJS 进行编译和 运行 时才有可能。另一种选择是在 JVM 生态系统中找到兼容的工具,并将它们与 JVM 编译的 Clojure 一起使用。

JavaScript 生态系统有一系列很好的工具可用于解析、转换和生成 ES 代码(查看 example/inspiration 的 Babel 包),但你必须记住如果您正在编写 ClojureScript 并 运行 它在 Node 下,您实际上是在创建一个 JavaScript 可执行文件,并且首先从 JavaScript 开始可能更容易。