conditions.scm 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. ;;; conditions.scm --- The R6RS conditions library
  2. ;; Copyright (C) 2010 Free Software Foundation, Inc.
  3. ;;
  4. ;; This library is free software; you can redistribute it and/or
  5. ;; modify it under the terms of the GNU Lesser General Public
  6. ;; License as published by the Free Software Foundation; either
  7. ;; version 3 of the License, or (at your option) any later version.
  8. ;;
  9. ;; This library is distributed in the hope that it will be useful,
  10. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. ;; Lesser General Public License for more details.
  13. ;;
  14. ;; You should have received a copy of the GNU Lesser General Public
  15. ;; License along with this library; if not, write to the Free Software
  16. ;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  17. (library (rnrs conditions (6))
  18. (export &condition
  19. condition
  20. simple-conditions
  21. condition?
  22. condition-predicate
  23. condition-accessor
  24. define-condition-type
  25. &message
  26. make-message-condition
  27. message-condition?
  28. condition-message
  29. &warning
  30. make-warning
  31. warning?
  32. &serious
  33. make-serious-condition
  34. serious-condition?
  35. &error
  36. make-error
  37. error?
  38. &violation
  39. make-violation
  40. violation?
  41. &assertion
  42. make-assertion-violation
  43. assertion-violation?
  44. &irritants
  45. make-irritants-condition
  46. irritants-condition?
  47. condition-irritants
  48. &who
  49. make-who-condition
  50. who-condition?
  51. condition-who
  52. &non-continuable
  53. make-non-continuable-violation
  54. non-continuable-violation?
  55. &implementation-restriction
  56. make-implementation-restriction-violation
  57. implementation-restriction-violation?
  58. &lexical
  59. make-lexical-violation
  60. lexical-violation?
  61. &syntax
  62. make-syntax-violation
  63. syntax-violation?
  64. syntax-violation-form
  65. syntax-violation-subform
  66. &undefined
  67. make-undefined-violation
  68. undefined-violation?)
  69. (import (only (guile) and=> @@)
  70. (rnrs base (6))
  71. (rnrs lists (6))
  72. (rnrs records procedural (6)))
  73. (define &compound-condition (make-record-type-descriptor
  74. '&compound-condition #f #f #f #f
  75. '#((immutable components))))
  76. (define compound-condition? (record-predicate &compound-condition))
  77. (define make-compound-condition
  78. (record-constructor (make-record-constructor-descriptor
  79. &compound-condition #f #f)))
  80. (define simple-conditions
  81. (let ((compound-ref (record-accessor &compound-condition 0)))
  82. (lambda (condition)
  83. (cond ((compound-condition? condition)
  84. (compound-ref condition))
  85. ((condition-internal? condition)
  86. (list condition))
  87. (else
  88. (assertion-violation 'simple-conditions
  89. "not a condition"
  90. condition))))))
  91. (define (condition? obj)
  92. (or (compound-condition? obj) (condition-internal? obj)))
  93. (define condition
  94. (lambda conditions
  95. (define (flatten cond)
  96. (if (compound-condition? cond) (simple-conditions cond) (list cond)))
  97. (or (for-all condition? conditions)
  98. (assertion-violation 'condition "non-condition argument" conditions))
  99. (if (or (null? conditions) (> (length conditions) 1))
  100. (make-compound-condition (apply append (map flatten conditions)))
  101. (car conditions))))
  102. (define-syntax define-condition-type
  103. (syntax-rules ()
  104. ((_ condition-type supertype constructor predicate
  105. (field accessor) ...)
  106. (letrec-syntax
  107. ((transform-fields
  108. (syntax-rules ()
  109. ((_ (f a) . rest)
  110. (cons '(immutable f a) (transform-fields . rest)))
  111. ((_) '())))
  112. (generate-accessors
  113. (syntax-rules ()
  114. ((_ counter (f a) . rest)
  115. (begin (define a
  116. (condition-accessor
  117. condition-type
  118. (record-accessor condition-type counter)))
  119. (generate-accessors (+ counter 1) . rest)))
  120. ((_ counter) (begin)))))
  121. (begin
  122. (define condition-type
  123. (make-record-type-descriptor
  124. 'condition-type supertype #f #f #f
  125. (list->vector (transform-fields (field accessor) ...))))
  126. (define constructor
  127. (record-constructor
  128. (make-record-constructor-descriptor condition-type #f #f)))
  129. (define predicate (condition-predicate condition-type))
  130. (generate-accessors 0 (field accessor) ...))))))
  131. (define &condition (@@ (rnrs records procedural) &condition))
  132. (define &condition-constructor-descriptor
  133. (make-record-constructor-descriptor &condition #f #f))
  134. (define condition-internal? (record-predicate &condition))
  135. (define (condition-predicate rtd)
  136. (let ((rtd-predicate (record-predicate rtd)))
  137. (lambda (obj)
  138. (cond ((compound-condition? obj)
  139. (exists rtd-predicate (simple-conditions obj)))
  140. ((condition-internal? obj) (rtd-predicate obj))
  141. (else #f)))))
  142. (define (condition-accessor rtd proc)
  143. (let ((rtd-predicate (record-predicate rtd)))
  144. (lambda (obj)
  145. (cond ((rtd-predicate obj) (proc obj))
  146. ((compound-condition? obj)
  147. (and=> (find rtd-predicate (simple-conditions obj)) proc))
  148. (else #f)))))
  149. (define-condition-type &message &condition
  150. make-message-condition message-condition?
  151. (message condition-message))
  152. (define-condition-type &warning &condition make-warning warning?)
  153. (define &serious (@@ (rnrs records procedural) &serious))
  154. (define make-serious-condition
  155. (@@ (rnrs records procedural) make-serious-condition))
  156. (define serious-condition? (condition-predicate &serious))
  157. (define-condition-type &error &serious make-error error?)
  158. (define &violation (@@ (rnrs records procedural) &violation))
  159. (define make-violation (@@ (rnrs records procedural) make-violation))
  160. (define violation? (condition-predicate &violation))
  161. (define &assertion (@@ (rnrs records procedural) &assertion))
  162. (define make-assertion-violation
  163. (@@ (rnrs records procedural) make-assertion-violation))
  164. (define assertion-violation? (condition-predicate &assertion))
  165. (define-condition-type &irritants &condition
  166. make-irritants-condition irritants-condition?
  167. (irritants condition-irritants))
  168. (define-condition-type &who &condition
  169. make-who-condition who-condition?
  170. (who condition-who))
  171. (define-condition-type &non-continuable &violation
  172. make-non-continuable-violation
  173. non-continuable-violation?)
  174. (define-condition-type &implementation-restriction
  175. &violation
  176. make-implementation-restriction-violation
  177. implementation-restriction-violation?)
  178. (define-condition-type &lexical &violation
  179. make-lexical-violation lexical-violation?)
  180. (define-condition-type &syntax &violation
  181. make-syntax-violation syntax-violation?
  182. (form syntax-violation-form)
  183. (subform syntax-violation-subform))
  184. (define-condition-type &undefined &violation
  185. make-undefined-violation undefined-violation?)
  186. )