1

フォームを指定して、欠落しているすべてのシンボルを自分自身として定義するマクロを作成しようとしています。

今までに私は次のものを持っています:

(def ^:private missing-symbol-pattern #"Unable to resolve symbol: (.+) in this context")

(cl/defn ^:private missing-symbol [s]
  (cl/when-let [[_ sym] (cl/re-find missing-symbol-pattern s)] sym))

(cl/defmacro try-eval [expr]
               `(try (do (cl/println '~expr) (cl/eval '~expr)) 
                 (catch Exception e#
                   (cl/if-let [sym# (do (cl/println (.getMessage e#)) (missing-symbol (.getMessage e#)))]
                              (cl/eval `(do 
                                          (def ~(cl/symbol sym#) '~(cl/symbol sym#))
                                          (cl/println ~sym#)
                                          (try-eval ~'~expr)))
                              (cl/eval `(throw ~e#))))))

clここにの別名がclojure.coreあります)副作用に問題がある可能性があることは知っていますが、これはここでは重要ではありません(ただし、副作用の問題がない方が良いでしょう)

欠落している(解決できない)シンボルが複数ある場合、次の例外が発生します。

java.lang.RuntimeException: Can't embed object in code, maybe print-dup not defined: java.lang.ClassCastException: clojure.lang.Symbol cannot be cast to clojure.lang.IDeref, compiling:(shen/primitives.clj:517)

何を変更するかについて誰かが考えていますか?「既製」のソリューションはありますか?

乾杯

4

1 に答える 1

3

try / catchを使用して解決されないシンボルを見つけるのではなく、&env内で使用可能なシンボルを使用して何かを行うことができますdefmacro。のキー&envは、ローカルで定義されたシンボルです。

&envおよび&formに関する記事。

resolveとの組み合わせを使用して、(keys &env)定義されていないシンボルを分離できます。次に、定義されていないシンボルを定義することを選択できます。(not (or (resolve sym) (contains? &env sym))

Midjeソースコードでこれに似た処理を行い、表形式のテストで定義されているシンボルと定義されていないシンボルを判別します。

[注:以下のコードlocalsには実際にあり(keys &env)ます]

(defn- headings-rows+values [table locals]
  (letfn [(table-variable? [s]
            (and (symbol? s)
              (not (metaconstant-symbol? s))
              (not (resolve s))
              (not (contains? locals s))))]
    (split-with table-variable? (remove-pipes+where table))))
于 2012-04-21T18:02:33.877 に答える