Define the macro key-if to have the form
(KEY-IF test
:THEN exp1 exp2 ...
:ELSE exp3 exp4 ...)
This does about the same thing as:
(COND (test exp exp ...)
(T else-exp else-exp ...))
Almost everything is optional in key-if except the test. Here are some legal forms and their results:
> (key-if (> 3 1) :then 'ok)Solution:
OK
> (key-if (<> (key-if (> 3 1) :else 'oops)
NIL
> (key-if (> 3 1) :then)
NIL
> (key-if (> 3 1) :else 'oops :then 'ok)
OK
> (key-if (> 3 1) :else 'oops :then (print 'hi) 'ok)
HI
OK
(defmacro key-if (test &rest args)
(defun extract-then-else (exp)
(defun iter (exp then-list else-list flag)
(cond
((null exp) (values (nreverse then-list) (nreverse else-list)))
((eq :then (car exp)) (iter (cdr exp)
then-list
else-list t))
((eq :else (car exp)) (iter (cdr exp)
then-list
else-list nil))
(t (if (null flag)
(iter (cdr exp) then-list (cons (car exp)
else-list) flag)
(iter (cdr exp) (cons (car exp) then-list)
else-list flag)))))
(iter exp nil nil nil))
(multiple-value-bind (then else) (extract-then-else args)
`(cond (,test ,(cons 'progn then))
(t ,(cons 'progn else)))))
No comments:
Post a Comment