2014-01-05 62 views
1

我想知道情況宏如何工作,但只是擴大它是不夠的。它如何在不知道有多少參數的情況下生成cond語句?它使用循環還是什麼?如果是這樣,那麼爲什麼當我運行macroexpand時不會顯示出來。Lisp - 「案例」的宏執行

我需要寫一些類似的東西,這就是爲什麼我問。

+3

爲什麼不看看你最喜歡的實現的源代碼? – uselpa

回答

1

是的,你就需要使用迭代 - 的loop之一,domapcar & C(或遞歸)。

看看,例如,CLISP's implementation of case

(defun case-expand (whole-form form-name test keyform clauses) 
    (let ((var (gensym (string-concat (symbol-name form-name) "-KEY-")))) 
    `(let ((,var ,keyform)) 
     (cond 
     ,@(maplist 
      #'(lambda (remaining-clauses) 
       (let ((clause (first remaining-clauses)) 
        (remaining-clauses (rest remaining-clauses))) 
       (unless (consp clause) 
        (error-of-type 'source-program-error 
        :form whole-form 
        :detail clause 
        (TEXT "~S: missing key list") 
        form-name)) 
       (let ((keys (first clause))) 
        `(,(cond ((or (eq keys 'T) (eq keys 'OTHERWISE)) 
          (if remaining-clauses 
           (error-of-type 'source-program-error 
            :form whole-form 
            :detail clause 
            (TEXT "~S: the ~S clause must be the last one") 
            form-name keys) 
           't)) 
          ((listp keys) 
          `(or ,@(mapcar #'(lambda (key) 
               `(,test ,var ',key)) 
              keys))) 
          (t `(,test ,var ',keys))) 
        ,@(rest clause))))) 
      clauses))))) 

(defmacro case (&whole whole-form 
       keyform &body clauses) 
    (case-expand whole-form 'case 'eql keyform clauses)) 
+0

請注意,對此的一些遞歸方法並不明確。例如,'case'可以展開成一個'if',它檢查第一個case並將else部分留作'(case ...)'。宏定義不會顯式遞歸。 –