macros - 在宏中取消引用时 undefined variable

标签 macros lisp common-lisp

这是我的宏定义:

*(defmacro run-test (test)
   `(format t "Run test ~a ... ~a" ',test ,test))
*(run-test (= 1 1))
Run test (= 1 1) ... T
NIL

现在一切正常,所以我定义了第二个宏(运行多个测试):

*(defmacro run-tests (&body body) 
   `(loop for tc in ',body 
      do (run-test tc)))
* (run-tests (= 2 (1+ 1)) (= 1 1))
Run test TC ... (= 2 (1+ 1) Run test TC ... (= 1 1)

这个结果不是我想要的,我希望 tc 的每个值都被 sexp 替换,并在运行测试中评估该值。我试图更换线路

          do (run-test tc)

          do (run-test ,tc)

但这表示错误

Undefined variable: TC

我怎样才能改变它以获得正确的结果?

最佳答案

查看例如的扩展(运行测试(= 1 1)):

(loop for tc in '((= 1 1)) do (run-test tc))

如您所见,代码尝试调用 (run-test tc)。但是 run-test 操作的是一个表单;当您传递包含 表单的变量时,它将不起作用。

如果您将代码更改为 (run-test ,tc),您将尝试在宏扩展期间引用 tc 变量,但它仅在运行时绑定(bind)。

一个解决方案是在宏展开时做更多的事情:

(defmacro run-tests (&body body)
  `(progn ,@(loop for tc in body collect `(run-test ,tc))))

关于macros - 在宏中取消引用时 undefined variable ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19373134/

相关文章:

macros - 宏观规则!宏采用字符串文字 "...",扩展为 "..."和 b"..."

macros - Racket 宏,打印变量名称及其值的列表

lisp - Lisp 中的 1 和 '1 有什么区别?

lisp - 优化选项 sbcl

c++ - 可变参数模板计数参数,省略号作为参数传递

c++ - 这种宏有什么意义?

syntax-error - 常见的 lisp 错误 : "should be lambda expression"

lisp - 方案:关于条件

emacs - 如何在Windows 7 x64上使用SLIME和Steel Bank Common Lisp开始编程?

lisp - 从 s 表达式创建 lambda