我想知道案例宏是如何工作的,但仅扩展它是不够的。如何在不知道有多少参数的情况下生成cond语句?它是使用循环还是其他东西?如果是这样,那么为什么当我运行macroexpand时它不会出现。
我需要写一些类似方式的东西,这就是我问的原因。
答案 0 :(得分:1)
是的,您需要使用迭代 - loop
,do
,mapcar
& 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))