Paste number 82951: handler-case for emacs

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:
Raw Source | XML | Display As

;; (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.

Colorize as:
Show Line Numbers

Lisppaste pastes can be made by anyone at any time. Imagine a fearsomely comprehensive disclaimer of liability. Now fear, comprehensively.