| author | huffman | 
| Mon, 27 Apr 2009 07:26:17 -0700 | |
| changeset 31007 | 7c871a9cf6f4 | 
| parent 29564 | f8b933a62151 | 
| child 31427 | 5a07cc86675d | 
| permissions | -rw-r--r-- | 
| 23962 | 1 | (* Title: Pure/ML-Systems/exn.ML | 
| 2 | Author: Makarius | |
| 3 | ||
| 28444 | 4 | Extra support for exceptions. | 
| 23962 | 5 | *) | 
| 6 | ||
| 28444 | 7 | signature EXN = | 
| 8 | sig | |
| 9 | datatype 'a result = Exn of exn | Result of 'a | |
| 10 | val get_result: 'a result -> 'a option | |
| 11 | val get_exn: 'a result -> exn option | |
| 12 |   val capture: ('a -> 'b) -> 'a -> 'b result
 | |
| 13 | val release: 'a result -> 'a | |
| 14 | exception Interrupt | |
| 28459 
f6a4d913cfb1
simplified Exn.EXCEPTIONS, flatten nested occurrences;
 wenzelm parents: 
28444diff
changeset | 15 | exception EXCEPTIONS of exn list | 
| 28444 | 16 | val release_all: 'a result list -> 'a list | 
| 17 | val release_first: 'a result list -> 'a list | |
| 18 | end; | |
| 19 | ||
| 20 | structure Exn: EXN = | |
| 23962 | 21 | struct | 
| 22 | ||
| 28444 | 23 | (* runtime exceptions as values *) | 
| 24 | ||
| 23962 | 25 | datatype 'a result = | 
| 26 | Result of 'a | | |
| 27 | Exn of exn; | |
| 28 | ||
| 29 | fun get_result (Result x) = SOME x | |
| 30 | | get_result _ = NONE; | |
| 31 | ||
| 32 | fun get_exn (Exn exn) = SOME exn | |
| 33 | | get_exn _ = NONE; | |
| 34 | ||
| 35 | fun capture f x = Result (f x) handle e => Exn e; | |
| 36 | ||
| 37 | fun release (Result y) = y | |
| 38 | | release (Exn e) = raise e; | |
| 39 | ||
| 28444 | 40 | |
| 28459 
f6a4d913cfb1
simplified Exn.EXCEPTIONS, flatten nested occurrences;
 wenzelm parents: 
28444diff
changeset | 41 | (* interrupt and nested exceptions *) | 
| 28444 | 42 | |
| 43 | exception Interrupt = Interrupt; | |
| 28459 
f6a4d913cfb1
simplified Exn.EXCEPTIONS, flatten nested occurrences;
 wenzelm parents: 
28444diff
changeset | 44 | exception EXCEPTIONS of exn list; | 
| 28444 | 45 | |
| 28459 
f6a4d913cfb1
simplified Exn.EXCEPTIONS, flatten nested occurrences;
 wenzelm parents: 
28444diff
changeset | 46 | fun plain_exns (Result _) = [] | 
| 
f6a4d913cfb1
simplified Exn.EXCEPTIONS, flatten nested occurrences;
 wenzelm parents: 
28444diff
changeset | 47 | | plain_exns (Exn Interrupt) = [] | 
| 
f6a4d913cfb1
simplified Exn.EXCEPTIONS, flatten nested occurrences;
 wenzelm parents: 
28444diff
changeset | 48 | | plain_exns (Exn (EXCEPTIONS exns)) = List.concat (map (plain_exns o Exn) exns) | 
| 
f6a4d913cfb1
simplified Exn.EXCEPTIONS, flatten nested occurrences;
 wenzelm parents: 
28444diff
changeset | 49 | | plain_exns (Exn exn) = [exn]; | 
| 28444 | 50 | |
| 23962 | 51 | |
| 28444 | 52 | fun release_all results = | 
| 53 | if List.all (fn Result _ => true | _ => false) results | |
| 54 | then map (fn Result x => x) results | |
| 55 | else | |
| 28459 
f6a4d913cfb1
simplified Exn.EXCEPTIONS, flatten nested occurrences;
 wenzelm parents: 
28444diff
changeset | 56 | (case List.concat (map plain_exns results) of | 
| 28444 | 57 | [] => raise Interrupt | 
| 28459 
f6a4d913cfb1
simplified Exn.EXCEPTIONS, flatten nested occurrences;
 wenzelm parents: 
28444diff
changeset | 58 | | exns => raise EXCEPTIONS exns); | 
| 28444 | 59 | |
| 60 | fun release_first results = release_all results | |
| 28459 
f6a4d913cfb1
simplified Exn.EXCEPTIONS, flatten nested occurrences;
 wenzelm parents: 
28444diff
changeset | 61 | handle EXCEPTIONS (exn :: _) => raise exn; | 
| 28444 | 62 | |
| 23962 | 63 | end; |