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点,我们的工具从当前的调用帧中提取所有 'locals',然后将所有这些局部绑定提供给 env/locals,这样编译器就不会在它们前面加上命名空间。

例如,如果在调用堆栈中有对 'x' 的局部绑定,并且用户的repl输入表达式涉及到 'x',那么我们希望编译器让符号 'x' 保持原样,不要在其前面加上任何命名空间。在最终的javascript中,它必须是 'x',而不是 'some.namespace.x'

我们实现这一目标的方法是在编译时将'x'放入env/locals中,并且一切正常。除了最近的更改,这变成了一项更大的挑战。因此,这个工单要求提供传入env的方式。

0

评论者:thheller

您可以在用户表达式中将其包裹在一个fn中,这样您就可以跳过对locals的修改。REPL基本上对1,2,...

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

0

评论者:dnolen

这似乎是添加到{{cljs.compiler.api}}命名空间的有用功能。

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