Last active
March 28, 2018 22:27
-
-
Save spacebat/3acc7185081f76bd6ceede659cb59410 to your computer and use it in GitHub Desktop.
An extension to the syntax of condition-case to support else and finally cases
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; This gist licensed GPLv3 | |
(cl-defmacro condition-case+ (var form (&rest handlers/else/finally)) | |
"Like condition-case, only if the last handlers have matching | |
forms of :else or :finally. In that case, the body of an :else | |
handler is evaluated if no exception was thrown. The body of | |
a :finally clause is evaluated always as the last thing before | |
the form is exited whether normally or not. If both :else | |
and :finally appear among the handlers, :else must be second last | |
and :finally must be last." | |
(cl-flet ((maybe-split-last (symbol handlers) | |
(let ((last-handler (last handlers))) | |
(cond | |
((and (listp (car last-handler)) | |
(eq (caar last-handler) symbol)) | |
(list (butlast handlers) | |
(cdar last-handler))) | |
(t | |
(list handlers nil)))))) | |
(destructuring-bind (handlers finally) (maybe-split-last :finally handlers/else/finally) | |
(destructuring-bind (handlers else) (maybe-split-last :else handlers) | |
(let ((errant-matchers (cl-loop for (match . handler-body) in handlers | |
if (member match '(:else :finally)) | |
collect match))) | |
(when errant-matchers | |
(error "Matcher(s) %s found out of place. Please read the documentation" | |
(mapconcat 'prin1-to-string errant-matchers ", ")))) | |
(let* ((success? (cl-gensym "success?")) | |
(body `(let (,success?) | |
(condition-case ,var | |
(prog1 | |
,form | |
(setq ,success? t)) | |
,@handlers) | |
,@(if else | |
`((when ,success? | |
,@(if (listp else) | |
else | |
(list else)))))))) | |
(if finally | |
`(unwind-protect | |
,body | |
,@finally) | |
body)))))) |
Author
spacebat
commented
Mar 28, 2018
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment