在宏中取消引用时未定义的变量

Wu *_* Li 2 lisp macros common-lisp

这是我的宏定义:

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

一切都工作正常,所以我已经定义了第二个宏(运行多个测试):

*(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)
Run Code Online (Sandbox Code Playgroud)

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

          do (run-test tc)
Run Code Online (Sandbox Code Playgroud)

          do (run-test ,tc)
Run Code Online (Sandbox Code Playgroud)

但这表示错误

未定义的变量:TC

如何更改以获得正确的结果?

Lar*_*off 10

看看扩展例如(run-tests (= 1 1)):

(loop for tc in '((= 1 1)) do (run-test tc))
Run Code Online (Sandbox Code Playgroud)

如您所见,代码尝试调用(run-test tc).但是run-test在表格上运作; 传递包含表单的变量时,它将不起作用.

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

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

(defmacro run-tests (&body body)
  `(progn ,@(loop for tc in body collect `(run-test ,tc))))
Run Code Online (Sandbox Code Playgroud)