簡體   English   中英

在宏中取消引用時未定義的變量

[英]Undefined variable while unquoting in macro

這是我的宏定義:

*(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替換,並且在run-test中評估值。 我試圖更換線路

          do (run-test tc)

          do (run-test ,tc)

但這表示錯誤

未定義的變量:TC

如何更改以獲得正確的結果?

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

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

如您所見,代碼嘗試調用(run-test tc) run-test在表單上run-test ; 傳遞包含表單的變量時,它將不起作用。

如果將代碼更改為(run-test ,tc) ,則在宏擴展時嘗試引用tc變量,但它僅在運行時綁定。

一個解決方案是在宏擴展時做更多的事情:

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

就像練習一樣。 你可以擺脫宏:

(defun run-test (test)
  (format t "~%Run test ~a ... ~a" test (eval test)))

(defun run-tests (tests)
  (mapc 'run-test tests)
  (values))

* (run-tests '((= 2 (1+ 1))
               (= 1 1)))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM