X-Git-Url: https://git.distorted.org.uk/~mdw/lisp/blobdiff_plain/f2d46aaa6bd5788d956bb767d92da97916407724..bf0a8c394bdf34895ad53771665f70c3b80e272e:/mdw-base.lisp diff --git a/mdw-base.lisp b/mdw-base.lisp index 787255b..bbe7662 100644 --- a/mdw-base.lisp +++ b/mdw-base.lisp @@ -33,7 +33,7 @@ #:stringify #:listify #:fix-pair #:pairify #:whitespace-char-p #:slot-uninitialized - #:nlet #:while + #:nlet #:while #:case2 #:ecase2 #:with-gensyms #:let*/gensyms #:with-places #:locp #:locf #:ref #:with-locatives #:update-place #:update-place-after @@ -149,9 +149,38 @@ gensyms will be bound to the corresponding VALUE." (defmacro while (cond &body body) "If COND is false, evaluate to nil; otherwise evaluate BODY and try again." `(loop - (unless `cond (return)) + (unless ,cond (return)) ,@body)) +(compile-time-defun do-case2-like (kind vform clauses) + "Helper function for `case2' and `ecase2'." + (with-gensyms (scrutinee argument) + `(multiple-value-bind (,scrutinee ,argument) ,vform + (declare (ignorable ,argument)) + (,kind ,scrutinee + ,@(mapcar (lambda (clause) + (destructuring-bind + (cases (&optional var) &rest forms) + clause + `(,cases + ,@(if var + (list `(let ((,var ,argument)) ,@forms)) + forms)))) + clauses))))) + +(defmacro case2 (vform &body clauses) + "VFORM is a form which evaluates to two values, SCRUTINEE and ARGUMENT. +The CLAUSES have the form (CASES ([VAR]) FORMS...), where a standard `case' +clause has the form (CASES FORMS...). The `case2' form evaluates the VFORM, +and compares the SCRUTINEE to the various CASES, in order, just like `case'. +If there is a match, then the corresponding FORMs are evaluated with VAR (if +specified) bound to the value of ARGUMENT." + (do-case2-like 'case vform clauses)) + +(defmacro ecase2 (vform &body clauses) + "Like `case2', but signals an error if no clause matches the SCRUTINEE." + (do-case2-like 'ecase vform clauses)) + ;;;-------------------------------------------------------------------------- ;;; with-places