Changeset 5025


Ignore:
Timestamp:
Aug 25, 2006, 7:22:03 PM (18 years ago)
Author:
Gary Byers
Message:

HANDLER-CASE: the :NO-ERROR clause can appear at most once but doesn't
have to be the last clause.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/ccl/lib/macros.lisp

    r4912 r5025  
    374374     
    375375
    376 (defmacro handler-case (form &rest clauses &aux last)
     376(defmacro handler-case (form &rest clauses)
    377377  "(HANDLER-CASE form
    378378   { (type ([var]) body) }* )
     
    382382   as if by MULTIPLE-VALUE-CALL.  The :NO-ERROR clause accepts more than one
    383383   var specification."
    384   (flet ((handler-case (type var &rest body)
    385            (when (eq type :no-error)
    386              (signal-program-error "The :no-error clause must be last."))
     384  (let* ((no-error-clause (assoc :no-error clauses)))
     385    (if no-error-clause
     386      (let* ((normal-return (gensym))
     387             (error-return (gensym)))
     388        `(block ,error-return
     389          (multiple-value-call #'(lambda ,@(cdr no-error-clause))
     390            (block ,normal-return
     391              (return-from ,error-return
     392                (handler-case (return-from ,normal-return ,form)
     393                  ,@(remove no-error-clause clauses)))))))
     394      (flet ((handler-case (type var &rest body)
     395               (when (eq type :no-error)
     396                 (signal-program-error "Duplicate :no-error clause. "))
    387397           (values type var body)))
    388     (cond ((null clauses) form)
    389           ((eq (car (setq last (car (last clauses)))) :no-error)
    390            (let ((error (gensym))
    391                  (block (gensym))
    392                  (var   (cadr last)))
    393              (if var
    394                `(block ,error
    395                   (multiple-value-call #'(lambda ,@(cdr last))
    396                                        (block ,block
    397                                          (return-from ,error
    398                                            (handler-case (return-from ,block ,form)
    399                                              ,@(butlast clauses))))))
    400                `(block ,error
    401                   (block ,block
    402                     (return-from ,error
    403                       (handler-case (return-from ,block ,form)
    404                         ,@(butlast clauses))))
    405                   (locally ,@(cddr last))))))
     398        (cond ((null clauses) form)
    406399          ((null (cdr clauses))
    407400           (let ((block   (gensym))
     
    440433                                (catch ,cluster (return-from ,block ,form)))))
    441434                    (case (pop ,val)
    442                       ,@(nreverse cases)))))))))
     435                      ,@(nreverse cases)))))))))))
    443436
    444437(defmacro with-simple-restart ((restart-name format-string &rest format-args)
Note: See TracChangeset for help on using the changeset viewer.