| Paste number 82951: | handler-case for emacs |
| Pasted by: | pjb |
| When: | 8 months, 2 weeks ago |
| Share: | Tweet this! | http://paste.lisp.org/+1S07 |
| Channel: | #lisp |
| Paste contents: |
;; (condition-case VAR BODYFORM HANDLERS...)
;;
;; Regain control when an error is signaled.
;; Executes BODYFORM and returns its value if no error happens.
;; Each element of HANDLERS looks like (CONDITION-NAME BODY...)
;; where the BODY is made of Lisp expressions.
;;
;; A handler is applicable to an error
;; if CONDITION-NAME is one of the error's condition names.
;; If an error happens, the first applicable handler is run.
;;
;; The car of a handler may be a list of condition names
;; instead of a single condition name.
;;
;; When a handler handles an error,
;; control returns to the condition-case and the handler BODY... is executed
;; with VAR bound to (SIGNALED-CONDITIONS . SIGNAL-DATA).
;; VAR may be nil; then you do not get access to the signal information.
;;
;; The value of the last BODY form is returned from the condition-case.
;; See also the function `signal' for more info.
(defmacro handler-case (expression &rest clauses)
"Common-Lisp
IMPLEMENTATION: The clause variable symbols are substituted by one single
condition-case variable symbol. This may cause problems
if the same symbol is used as data or if it's a dynamic
variable.
"
(let* ((var (gensym))
(neclause (assoc :NO-ERROR clauses))
(nell (cadr neclause))
(nebody (cddr neclause))
(handlers (mapcar (lambda (clause)
(let ((typespec (car clause))
(clausvar (cadr clause))
(body (cddr clause)))
(cons (if (and (consp typespec)
(eq 'or (car typespec)))
(cdr typespec)
typespec)
(if (null clausvar)
body
(subst var (car clausvar) body)))))
(remove neclause clauses))))
(if neclause
`(condition-case ,var
(multiple-value-bind ,nell ,expression ,@nebody)
,@handlers)
`(condition-case ,var
,expression
,@handlers))))This paste has no annotations.