2012-03-22 56 views
1

我想寫一個宏,寫一堆宏的Lisp宏,但我有問題生成宏代碼,使用splice運算符(在建立綁定),擴展內部表達式第一。編寫一個Lisp宏與嵌套quasiquoting

(defmacro define-term-construct (name filter-p list-keywords) 
    (let* ((do-list-name (output-symbol "do-~a-list" name)) 
     (with-name (output-symbol "with-~a" name)) 
     (do-filter-name (output-symbol "do-~as" name))) 
    `(progn 
     (defmacro ,do-list-name 
     (ls (&key ,@(append list-keywords '(id operation))) &body body) 
      (with-gensyms (el) 
      `(loop-list (,el ,ls :id ,id :operation ,operation) 
       (let (XXX,@(build-bind ,,name ,el)) 
       (when (,',filter-p ,el) 
        (,',with-name ,el 
          ,@body))))))))) 

後第一遍我想:

(define-term-construct some some-p (args name)) 

-> 

(PROGN 
    (DEFMACRO DO-SOME-LIST (LS (&KEY ARGS NAME ID OPERATION) &BODY BODY) 
    (WITH-GENSYMS (EL) 
    `(LOOP-LIST (,EL ,LS :ID ,ID :OPERATION ,OPERATION) 
     (LET (,@(BUILD-BIND ,SOME ,EL)) 
     (WHEN (SOME-P ,EL) 
      (WITH-SOME ,EL 
       ,@BODY))))))) 

任何想法,我應該用什麼報價/ quasiquotes以獲得所需的代碼?

+0

您應該更完整地顯示您的代碼。也就是說,包括你所有的宏的輔助函數,比如'do-list-name'等。 – Kaz 2012-03-22 05:21:55

+0

do-list-name將是'define-term-construct'生成的宏。我只想知道如何在嵌套quasiquotting中輸出拼接操作符。 – 2012-03-22 05:44:30

+0

'輸出符號'就像'(intern(格式無))'我接受它。 – Kaz 2012-03-22 07:21:25

回答

1

你說你想得到的輸出有不平衡的逗號。 ,@已經平衡了反引號,所以你不能有,SOME,EL。這是隻有一個級別的反引號內部的兩個級別的引用/拼接。

我懷疑你想:

`(WITH-GENSYMS (EL) ... (LET (,@(BUILD-BIND 'SOME EL)) ...)) 

some符號進來作爲參數傳遞給原來的宏,並已通過在build-bind功能時,最終成爲一個符號引用。 EL直接進行評估。它只是一個由WITH-GENSYMS綁定構造引入的局部變量,它不再處於反引用上下文中,因爲它位於拼接中。

音譯即回原來的外部宏觀的反引號:SOME成爲,name

,@(build-bind ',name el) ;; two commas out balance two backquotes in 

符號爲保護報價的保護傘,這將確保它被視爲一個象徵,而不是根據拼接囂一個變量。

el不需要拼接;它不是可變材料,而是生成模板的硬編碼特徵。如果您要放入,el,它會在define-term-construct宏的作用域中查找el變量,但不存在這種情況。

+0

這是有道理的,它現在起作用。謝謝! – 2012-03-22 18:16:42