2024 clojure 状态调查! 上分享您的想法。

欢迎!请参阅 关于 页面,了解更多有关该工具的信息。

0
ClojureScript
在我们的项目中(一个 clojurescript 调试器)中,我们想将 cljs 表达式或一系列表达式转换为 JavaScript,以便它们可以在 JavaScript 控制台中执行。

我们还希望有一些类似 closure/compile-form-seq (https://github.com/clojure/clojurescript/blob/master/src/clj/cljs/closure.clj#L308) 的东西。

然而,我们需要提供,名称空间要求以及在此类环境中的本地变量

{:ns {:name "test.core" :requires {(quote gstring) (quote goog.string)}} :locals {}}


此代码似乎做了我们想要的事情。

(defn compile-form-seq
    "将一系列表达式编译为 JavaScript 源字符串。"
    [forms env]
    (env/ensure
    (compiler/with-core-cljs nil
      (fn []
        (with-out-str
            (doseq [form forms]
              (compiler/emit (analyzer/analyze env form))))))))


我不确定为什么需要 env/ensure。

您能否修补 compile-form-seq 以提供所需的接口,或者建议我们应该做什么。

谢谢
Stu

4 个答案

0

评论者:mikethompson

明确一下
1. 当我们的调试器处于断点时,
2. 用户可以在 repl 中键入表达式,
3. 作为响应,我们的调试器必须将用户键入的表达式编译为 JavaScript(然后执行它,显示结果),
4. 考虑任何局部绑定。 <---- 这是最关键的部分。

为了满足第 4 点,我们的工具从当前的调用帧中提取所有“局部变量”,然后在这些局部绑定中将所有这些局部变量提供给 env/locals,这样编译器就不会在它们的前面添加名称空间。

例如,如果在调用栈中有一个对 'x' 的局部绑定,并且用户输入的表达式包含 'x',那么我们希望编译器保持 'x' 这个符号不变,不需要在它前面加上某个命名空间。在最终的 JavaScript 中,它仍然是 'x',而不是 'some.namespace.x'。

我们实现这一点的方法是在编译时将 'x' 放入 env/locals 中——一切正常。但是,随着最近的变化,这已经变成一个更大的挑战。因此,这个工单是要求提供传递 env 的方法。

0

评论者:thheller

您可以将用户表达式包裹在一个 fn 中,这样就可以避免对局部的操作。REPL基本上就是对 1、2、... 做同样的操作。

(fn [x] ~user-expression-here)

0

评论者:dnolen

这似乎是一件很有用的东西可以添加到 {{cljs.compiler.api}} 命名空间中。

0
参考: https://clojure.atlassian.net/browse/CLJS-1059 (由 stumitchell 报告)
...