PageRenderTime 47ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/src/runtime-exceptions.scm

http://github.com/pablomarx/Thomas
Scheme | 353 lines | 257 code | 38 blank | 58 comment | 0 complexity | 7efde7fc98d2570c5990f5545aa76f7a MD5 | raw file
  1. ;* Copyright 1992 Digital Equipment Corporation
  2. ;* All Rights Reserved
  3. ;*
  4. ;* Permission to use, copy, and modify this software and its documentation is
  5. ;* hereby granted only under the following terms and conditions. Both the
  6. ;* above copyright notice and this permission notice must appear in all copies
  7. ;* of the software, derivative works or modified versions, and any portions
  8. ;* thereof, and both notices must appear in supporting documentation.
  9. ;*
  10. ;* Users of this software agree to the terms and conditions set forth herein,
  11. ;* and hereby grant back to Digital a non-exclusive, unrestricted, royalty-free
  12. ;* right and license under any changes, enhancements or extensions made to the
  13. ;* core functions of the software, including but not limited to those affording
  14. ;* compatibility with other hardware or software environments, but excluding
  15. ;* applications which incorporate this software. Users further agree to use
  16. ;* their best efforts to return to Digital any such changes, enhancements or
  17. ;* extensions that they make and inform Digital of noteworthy uses of this
  18. ;* software. Correspondence should be provided to Digital at:
  19. ;*
  20. ;* Director, Cambridge Research Lab
  21. ;* Digital Equipment Corp
  22. ;* One Kendall Square, Bldg 700
  23. ;* Cambridge MA 02139
  24. ;*
  25. ;* This software may be distributed (but not offered for sale or transferred
  26. ;* for compensation) to third parties, provided such third parties agree to
  27. ;* abide by the terms and conditions of this notice.
  28. ;*
  29. ;* THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
  30. ;* WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
  31. ;* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
  32. ;* CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
  33. ;* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
  34. ;* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
  35. ;* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  36. ;* SOFTWARE.
  37. ; $Id: runtime-exceptions.scm,v 1.21 1992/09/10 02:46:10 jmiller Exp $
  38. ;;;; The Dylan exception system.
  39. ;;; Note: Functions starting with "implementation-specific:" must be
  40. ;;; written for each Scheme implementation. They go into files like
  41. ;;; "mit-specific.scm".
  42. ;;; Classes
  43. (define dylan:condition-format-string
  44. (dylan::generic-fn 'condition-format-string
  45. (make-param-list `((condition ,<condition>)) #F #F #F)
  46. (lambda (condition)
  47. (dylan-call dylan:error
  48. "(condition-format-string <condition>) -- no specialization"
  49. condition))))
  50. (define dylan:condition-format-arguments
  51. (dylan::generic-fn 'condition-format-arguments
  52. (make-param-list `((condition ,<condition>)) #F #F #F)
  53. (lambda (condition)
  54. (dylan-call
  55. dylan:error
  56. "(condition-format-arguments <condition>) -- no specialization"
  57. condition))))
  58. (dylan::add-slot <simple-error>
  59. #F 'INSTANCE #F dylan:condition-format-string 'CONDITION-FORMAT-STRING
  60. #F #F #F 'FORMAT-STRING: #F)
  61. (dylan::add-slot <simple-error>
  62. #F 'INSTANCE #F dylan:condition-format-arguments
  63. 'CONDITION-FORMAT-ARGUMENTS #F #F #F 'FORMAT-ARGUMENTS: #F)
  64. (define dylan:type-error-value
  65. (dylan::generic-fn 'type-error-value
  66. (make-param-list `((condition ,<condition>)) #F #F #F)
  67. (lambda (condition)
  68. (dylan-call dylan:error
  69. "(type-error-value <condition>) -- no specialization"
  70. condition))))
  71. (define dylan:type-error-expected-type
  72. (dylan::generic-fn 'type-error-expected-type
  73. (make-param-list `((condition ,<condition>)) #F #F #F)
  74. (lambda (condition)
  75. (dylan-call dylan:error
  76. "(type-error-expected-type <condition>) -- no specialization"
  77. condition))))
  78. (dylan::add-slot <type-error>
  79. #F 'INSTANCE #F dylan:type-error-value 'TYPE-ERROR-VALUE
  80. #F #F #F 'VALUE: #F)
  81. (dylan::add-slot <type-error>
  82. #F 'INSTANCE #F dylan:type-error-expected-type
  83. 'TYPE-ERROR-EXPECTED-TYPE #F #F #F 'TYPE: #F)
  84. (dylan::add-slot <simple-warning>
  85. #F 'INSTANCE #F dylan:condition-format-string 'CONDITION-FORMAT-STRING
  86. #F #F #F 'FORMAT-STRING: #F)
  87. (dylan::add-slot <simple-warning>
  88. #F 'INSTANCE #F dylan:condition-format-arguments
  89. 'CONDITION-FORMAT-ARGUMENTS #F #F #F 'FORMAT-ARGUMENTS: #F)
  90. ;;; Basic Operators (pages 138 and 139)
  91. (define (dylan::handler-bind type function test description thunk)
  92. ;; Assumes function is a method of two args, test is a method of one arg,
  93. ;; and description is a string or method of one argument. Can't check???
  94. (if (and (not (and (class? type) (subclass? type <condition>)))
  95. (not (and (singleton? type)
  96. (subclass? (get-type (singleton.object type))
  97. <condition>))))
  98. (dylan-call dylan:error
  99. "handler-bind -- not a <condition>" type))
  100. (implementation-specific:push-handler
  101. type function test description thunk))
  102. (define (make-default-condition args type operator)
  103. ;; Handles one arg (a condition) or many args (format string and format
  104. ;; args). Assumes type is a <simple-error> or <simple-warning>.
  105. (cond ((and (pair? args)
  106. (subclass? (get-type (car args)) <condition>))
  107. (if (null? (cdr args))
  108. (car args)
  109. (dylan-call dylan:error "extraneous args" operator (cdr args))))
  110. ((and (pair? args)
  111. (string? (car args)))
  112. (dylan-call dylan:make
  113. type
  114. 'FORMAT-STRING: (car args)
  115. 'FORMAT-ARGUMENTS: (cdr args)))
  116. (else (dylan-call dylan:error "bad first argument" operator args))))
  117. (define (dylan:signal multiple-values next-method . args)
  118. next-method
  119. (let* ((condition (make-default-condition args <simple-warning> 'SIGNAL))
  120. (condition-type (get-type condition)))
  121. (let frame-loop ((frames
  122. (implementation-specific:get-dylan-handler-frames)))
  123. (if (pair? frames)
  124. (let ((handler-type (caar frames))
  125. (handler-test (caddar frames)))
  126. (if (and (or (and (singleton? handler-type)
  127. (eq? condition (singleton.object handler-type)))
  128. (subclass? condition-type handler-type))
  129. (dylan-call handler-test condition))
  130. (let ((handler (cadar frames)))
  131. (dylan-mv-call handler multiple-values
  132. condition
  133. (lambda (multiple-values next-method)
  134. multiple-values next-method
  135. (frame-loop (cdr frames)))))
  136. (frame-loop (cdr frames))))
  137. (dylan-mv-call dylan:default-handler multiple-values condition)))))
  138. ;;; Full set of Operators for Signaling
  139. (define dylan:error ; NOT continuable
  140. (make-dylan-callable
  141. (lambda args
  142. (dylan-call dylan:signal
  143. (make-default-condition args <simple-error> 'ERROR))
  144. (dylan-call dylan:error "error -- attempt to return from error"))))
  145. (define dylan:cerror ; OK to continue
  146. (make-dylan-callable
  147. (lambda (restart-description . others)
  148. (call-with-current-continuation
  149. (lambda (continue)
  150. (dylan::handler-bind
  151. <simple-restart>
  152. (make-dylan-callable ; Called if restart attempted
  153. (lambda (condition next-handler)
  154. condition next-handler
  155. (continue #F)))
  156. (make-dylan-callable ; Test: always ready to handle
  157. (lambda (condition)
  158. condition
  159. #T))
  160. restart-description
  161. (lambda ()
  162. (dylan-apply dylan:error others))))))))
  163. (define dylan:break
  164. (make-dylan-callable
  165. (lambda args
  166. (call-with-current-continuation
  167. (lambda (continue)
  168. (dylan::handler-bind
  169. <simple-restart>
  170. (make-dylan-callable
  171. (lambda (condition next-handler)
  172. condition next-handler
  173. (continue #F)))
  174. (make-dylan-callable
  175. (lambda (condition)
  176. condition
  177. #T))
  178. "Continue from breakpoint."
  179. (lambda ()
  180. (implementation-specific:enter-debugger
  181. (make-default-condition args <simple-error> 'BREAK))
  182. #F)))))))
  183. (define dylan:check-type
  184. (make-dylan-callable
  185. (lambda (value type)
  186. (if (not (dylan-call dylan:instance? value type))
  187. (let ((condition (dylan-call dylan:make
  188. <type-error> 'value: value 'type: type)))
  189. (dylan-call dylan:signal condition))
  190. value))
  191. 2))
  192. (define dylan:abort
  193. (lambda (multiple-values next-method)
  194. (dylan-full-call dylan:error multiple-values next-method
  195. (dylan-call dylan:make <abort>))))
  196. ;;; Additional Operators for Handling
  197. (define dylan:default-handler
  198. (dylan::generic-fn 'default-handler
  199. (make-param-list `((CONDITION ,<condition>)) #F #F #F)
  200. (lambda (condition) condition #F)))
  201. (add-method
  202. dylan:default-handler
  203. (dylan::function->method
  204. (make-param-list `((CONDITION ,<serious-condition>)) #F #F #F)
  205. (lambda (serious)
  206. ;; Turn unhandled dylan condition into a Scheme condition unless it is
  207. ;; a dylan condition reflecting a Scheme condition, in which case, just
  208. ;; return so that the handler in dylan::catch-all-conditions will
  209. ;; return so that the remaining Scheme condition handlers may run.
  210. (let ((error-type (get-type serious)))
  211. (cond
  212. ((and (eq? error-type <simple-error>)
  213. (implementation-specific:is-reflected-error?
  214. (dylan-call dylan:condition-format-string serious)
  215. (dylan-call dylan:condition-format-arguments serious)))
  216. (implementation-specific:let-scheme-handle-it serious))
  217. ((eq? error-type <simple-error>)
  218. (implementation-specific:induce-error
  219. (dylan-call dylan:condition-format-string serious)
  220. (dylan-call dylan:condition-format-arguments serious)))
  221. ((eq? error-type <type-error>)
  222. (let ((value (dylan-call dylan:type-error-value serious))
  223. (expected-type (dylan-call dylan:type-error-expected-type
  224. serious)))
  225. (implementation-specific:induce-type-error
  226. value (class.debug-name expected-type))))
  227. (else
  228. (implementation-specific:signal-unhandled-dylan-condition
  229. serious)))))))
  230. (add-method
  231. dylan:default-handler
  232. (dylan::function->method
  233. (make-param-list `((CONDITION ,<simple-warning>)) #F #F #F)
  234. (lambda (warning)
  235. (implementation-specific:warning
  236. (dylan-call dylan:condition-format-string warning)
  237. (dylan-call dylan:condition-format-arguments warning))
  238. #F)))
  239. (add-method
  240. dylan:default-handler
  241. (dylan::function->method
  242. (make-param-list `((CONDITION ,<restart>)) #F #F #F)
  243. (lambda (restart)
  244. (dylan-call dylan:error
  245. "(default-handler <restart>) -- no handler established"
  246. restart))))
  247. ;;; Operators for Interactive Handling
  248. (define dylan:restart-query
  249. (dylan::generic-fn 'restart-query
  250. (make-param-list `((RESTART ,<restart>)) #F #F #F)
  251. #F))
  252. (add-method
  253. dylan:restart-query
  254. (dylan::dylan-callable->method
  255. (make-param-list `((RESTART ,<restart>)) #F #F #F)
  256. (lambda (multiple-values next-method restart)
  257. restart
  258. (dylan-full-call dylan:values multiple-values next-method))))
  259. (define dylan:return-query
  260. (dylan::generic-fn 'return-query
  261. (make-param-list `((CONDITION ,<condition>)) #F #F #F)
  262. #F))
  263. (add-method
  264. dylan:return-query
  265. (dylan::dylan-callable->method
  266. (make-param-list `((CONDITION ,<condition>)) #F #F #F)
  267. (lambda (multiple-values next-method condition)
  268. condition ; Ignored
  269. (display "RETURN-QUERY: please type in a list of values")
  270. (newline)
  271. (dylan-full-apply dylan:values multiple-values next-method (read)))))
  272. ;;; Operators for Introspection
  273. (define dylan:do-handlers
  274. (make-dylan-callable
  275. (lambda (funarg)
  276. (do ((frames
  277. (implementation-specific:get-dylan-handler-frames)
  278. (cdr frames)))
  279. ((null? frames))
  280. (let ((frame (car frames)))
  281. (dylan-call funarg
  282. (car frame) (cadr frame)
  283. (caddr frame) (cadddr frame))))
  284. ;; No value???
  285. #F)
  286. 1))
  287. (define dylan:return-allowed?
  288. (dylan::generic-fn 'return-allowed?
  289. (make-param-list `((CONDITION ,<condition>)) #F #F #F)
  290. (lambda (condition) condition #F)))
  291. (define dylan:return-description
  292. (dylan::generic-fn 'return-description
  293. (make-param-list `((CONDITION ,<condition>)) #F #F #F)
  294. (lambda (condition)
  295. (dylan-call dylan:error
  296. "(return-description <condition>) -- not specialized"
  297. condition))))
  298. ;;; Top-level wrapper for DYLAN code
  299. (define catch-errors? #T)
  300. (define (dylan::catch-all-conditions dylan-compiled-output)
  301. (if catch-errors?
  302. (implementation-specific:catch-all-errors
  303. dylan::scheme-condition-handler
  304. dylan-compiled-output)
  305. (dylan-compiled-output)))
  306. ;; A name for the condition handler...
  307. (define (dylan::scheme-condition-handler condition)
  308. (dylan-call
  309. dylan:signal
  310. (dylan-call dylan:make <simple-error>
  311. 'FORMAT-STRING:
  312. (implementation-specific:get-error-message condition)
  313. 'FORMAT-ARGUMENTS:
  314. (implementation-specific:get-error-arguments condition))))