如何编写一个阅读器宏来传输Clojure中的代码?

时间:2015-03-24 16:43:33

标签: clojure macros lisp

我想编写一个名为$=>的宏来传输代码,如:

(let [bb 11] ($=> @"aa#{bb}"))    => ["aa?" 11]

这意味着我想在@之后使用模式#\{.*?\}拼接所有字符串 并用?替换模式,然后评估模式的符号。

所以我写这样的宏:

(defmacro parser [clause]
   (if (and (sequential? clause)
            (= 2 (count clause))
            (= `deref (first clause))
            (string? (second clause)))
    (let [s (second clause)
          regx#  #"#\{(.*?)\}"
          m# (re-matcher regx# s)
          p# (take-while #(not (nil? %)) (repeatedly #(second (re-find m#))))
          ss# (clojure.string/replace s #"#\{(.*?)\}" "?" )
          ps# (map symbol p#)]
      `[~ss# ~@ps#])
   clause))

此宏效果很好

user=> (let [aa 11] (parser @"AAA#{aa}" ))
["AAA?" 11]

user=> (let [aa 11] (parser @"AA{aa}" ))
["AA{aa}"]

但我希望宏$=>可以传输代码中的所有模式,例如:

(let [a 1 b 2 c 3] 
     ($=> @"AAA#{a}" 
          (if true @"BBB#{b}") 
          (for [i (range 1)] @"CCC#{c}")))

它可以返回

[["AAA?" 1] ["BBB?" 2] (["CCC?" 3])]

我尝试了一些方法,所有方法都失败了。

现在我不知道如何解决这个问题。

0 个答案:

没有答案