请在 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 报告)
...