我有一个替代符号的所有实例列表功能:如何通过引用SEXP宏观
(defun replace-symbol-in-sexp-fn (symbol-to-replace new-symbol sexp)
(if (eq sexp nil)
sexp
(cons
(if (listp (car sexp))
(replace-symbol-in-sexp-fn symbol-to-replace new-symbol (car sexp))
(if (eq (car sexp) symbol-to-replace)
(setf (car sexp) new-symbol)
(car sexp)))
(replace-symbol-in-sexp-fn symbol-to-replace new-symbol (cdr sexp)))))
(defmacro replace-symbol-in-sexp (symbol-to-replace new-symbol sexp)
`(replace-symbol-in-sexp-fn ,symbol-to-replace ,new-symbol ,sexp))
(macroexpand-1 (replace-symbol-in-sexp '+ '* (+ 2 3)))
; => TYPE-ERROR "The value 5 is not of type LIST" if sexp has comma,
; => UNBOUND-VARIABLE "The variable SEXP is unbound" if sexp has no comma
我得到任何一个类型的错误或试图评估时未定义变量错误最后的表达,取决于sexp是否在最后一行中是否逗号。我测试过并更换符号功能于SEXP-FN工作给予时说:
(replace-symbol-in-sexp-fn '+ '* '(+ 2 3)) ; => (* 2 3)
我想现在宏产生这样使得SEXP没有被引用像'(+ 2 3)
,所以我可以用任意的lisp代码运行replace-symbol-in-sexp-fn。很显然,我可以评估和传递引用到SEXP替代符号功能于SEXP-FN,如:
(eval (replace-symbol-in-sexp-fn '+ '* '(+ 2 3))
但是,这是一个笨拙的尝试模仿宏,所以我宁愿实际上只使用一个宏。有没有一种干净的方式来做我想用宏做的事情?我错过了什么?
“我得到一个类型错误或未定义变量错误”我没有看到这些问题中的任何一个。你能举一个例子吗? – 2014-11-24 03:23:24
用精确的结果进行编辑。 – cosmicexplorer 2014-11-25 13:04:21