我想编写一个名为$=>
的宏来传输代码,如:
(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])]
我尝试了一些方法,所有方法都失败了。
现在我不知道如何解决这个问题。