Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
38 lines (33 sloc) 1.54 KB
;;;; A simple macro that acts likes case, except it can use arbitrary test
;;;; functions. It was stolen from the CLISP source. For the most part, it
;;;; is a series of nested cond statements playing dress-up.
(in-package :toolbox)
(defun case-expand (whole-form form-name test keyform clauses)
(let ((var (gensym (concatenate 'string (symbol-name form-name) "-KEY-"))))
`(let ((,var ,keyform))
#'(lambda (remaining-clauses)
(let ((clause (first remaining-clauses))
(remaining-clauses (rest remaining-clauses)))
(unless (consp clause)
(format t "~a: missing key list" whole-form)
(break) )
(let ((keys (first clause)))
`(,(cond ((or (eq keys 'T) (eq keys 'OTHERWISE))
(if remaining-clauses
(format t "~a: the ~a clause must be the last one"
whole-form clause )
((listp keys)
`(or ,@(mapcar #'(lambda (key)
`(,test ,var ',key))
(t `(,test ,var ',keys)))
,@(rest clause)))))
(defmacro fcase (&whole whole-form
test keyform &body clauses)
(case-expand whole-form 'fcase test keyform clauses))