all-fields))) (make-condition-from-values type inits)) (throw 'wrong-type-arg "make-condition" "Wrong type argument: ~S" type))) (define (make-compound-condition . conditions) "Return a new compound condition composed of CONDITIONS." (let* ((types (map condition-type conditions)) (ct (make-compound-condition-type 'compound types)) (inits (append-map (lambda (c) (let ((ct (condition-type c))) (map (lambda (f) (condition-ref c f)) (condition-type-all-fields ct)))) conditions))) (make-condition-from-values ct inits))) (define (extract-condition c type) "Return a condition of condition type TYPE with the field values specified by C." (define (first-field-index parents) ;; Return the index of the first field of TYPE within C. (let loop ((parents parents) (index 0)) (let ((parent (car parents))) (cond ((null? parents) #f) ((eq? parent type) index) ((pair? parent) (or (loop parent index) (loop (cdr parents) (+ index (apply + (map condition-type-all-fields parent)))))) (else (let ((shift (length (condition-type-all-fields parent)))) (loop (cdr parents) (+ index shift)))))))) (define (list-fields start-index field-names) ;; Return a list of the form `(FIELD-NAME VALUE...)'. (let loop ((index start-index) (field-names field-names) (result '())) (if (null? field-names) (reverse! result) (loop (+ 1 index) (cdr field-names) (cons* (struct-ref c index) (car field-names) result))))) (if (and (condition? c) (condition-type? type)) (let* ((ct (condition-type c)) (parent (condition-type-parent ct))) (cond ((eq? type ct) c) ((pair? parent) ;; C is a compound condition. (let ((field-index (first-field-index parent))) ;;(format #t "field-index: ~a ~a~%" field-index ;; (list-fields field-index ;; (condition-type-all-fields type))) (apply make-condition type (list-fields field-index (condition-type-all-fields type))))) (else ;; C does not have type TYPE. #f))) (throw 'wrong-type-arg "extract-condition" "Wrong type argument")))