Lisp - “case”宏实现

时间:2014-01-05 12:03:33

标签: macros lisp

我想知道案例宏是如何工作的,但仅扩展它是不够的。如何在不知道有多少参数的情况下生成cond语句?它是使用循环还是其他东西?如果是这样,那么为什么当我运行macroexpand时它不会出现。

我需要写一些类似方式的东西,这就是我问的原因。

1 个答案:

答案 0 :(得分:1)

是的,您需要使用迭代 - loopdomapcar& 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))