| author | haftmann | 
| Fri, 03 Jan 2014 22:04:44 +0100 | |
| changeset 54929 | f1ded3cea58d | 
| parent 44247 | 270366301bd7 | 
| child 56628 | a2df9de46060 | 
| permissions | -rw-r--r-- | 
| 34136 | 1 | (* Title: Pure/General/exn.ML | 
| 23962 | 2 | Author: Makarius | 
| 3 | ||
| 43761 
e72ba84ae58f
tuned signature -- corresponding to Scala version;
 wenzelm parents: 
43537diff
changeset | 4 | Support for exceptions. | 
| 23962 | 5 | *) | 
| 6 | ||
| 28444 | 7 | signature EXN = | 
| 8 | sig | |
| 43761 
e72ba84ae58f
tuned signature -- corresponding to Scala version;
 wenzelm parents: 
43537diff
changeset | 9 | datatype 'a result = Res of 'a | Exn of exn | 
| 
e72ba84ae58f
tuned signature -- corresponding to Scala version;
 wenzelm parents: 
43537diff
changeset | 10 | val get_res: 'a result -> 'a option | 
| 28444 | 11 | val get_exn: 'a result -> exn option | 
| 12 |   val capture: ('a -> 'b) -> 'a -> 'b result
 | |
| 13 | val release: 'a result -> 'a | |
| 40234 
39af96cc57cb
added Exn.interruptible_capture, which reraises interrupts as required by user-code (when Exn.capture is not immediately followed by Exn.release);
 wenzelm parents: 
39472diff
changeset | 14 |   val map_result: ('a -> 'b) -> 'a result -> 'b result
 | 
| 42223 
098c86e53153
more precise propagation of reports/results through some inner syntax layers;
 wenzelm parents: 
40483diff
changeset | 15 |   val maps_result: ('a -> 'b result) -> 'a result -> 'b result
 | 
| 28444 | 16 | exception Interrupt | 
| 39232 
69c6d3e87660
more abstract treatment of interrupts in structure Exn -- hardly ever need to mention Interrupt literally;
 wenzelm parents: 
34136diff
changeset | 17 | val interrupt: unit -> 'a | 
| 
69c6d3e87660
more abstract treatment of interrupts in structure Exn -- hardly ever need to mention Interrupt literally;
 wenzelm parents: 
34136diff
changeset | 18 | val is_interrupt: exn -> bool | 
| 
69c6d3e87660
more abstract treatment of interrupts in structure Exn -- hardly ever need to mention Interrupt literally;
 wenzelm parents: 
34136diff
changeset | 19 | val interrupt_exn: 'a result | 
| 
69c6d3e87660
more abstract treatment of interrupts in structure Exn -- hardly ever need to mention Interrupt literally;
 wenzelm parents: 
34136diff
changeset | 20 | val is_interrupt_exn: 'a result -> bool | 
| 40234 
39af96cc57cb
added Exn.interruptible_capture, which reraises interrupts as required by user-code (when Exn.capture is not immediately followed by Exn.release);
 wenzelm parents: 
39472diff
changeset | 21 |   val interruptible_capture: ('a -> 'b) -> 'a -> 'b result
 | 
| 28459 
f6a4d913cfb1
simplified Exn.EXCEPTIONS, flatten nested occurrences;
 wenzelm parents: 
28444diff
changeset | 22 | exception EXCEPTIONS of exn list | 
| 28444 | 23 | end; | 
| 24 | ||
| 25 | structure Exn: EXN = | |
| 23962 | 26 | struct | 
| 27 | ||
| 44158 | 28 | (* exceptions as values *) | 
| 28444 | 29 | |
| 23962 | 30 | datatype 'a result = | 
| 43761 
e72ba84ae58f
tuned signature -- corresponding to Scala version;
 wenzelm parents: 
43537diff
changeset | 31 | Res of 'a | | 
| 23962 | 32 | Exn of exn; | 
| 33 | ||
| 43761 
e72ba84ae58f
tuned signature -- corresponding to Scala version;
 wenzelm parents: 
43537diff
changeset | 34 | fun get_res (Res x) = SOME x | 
| 
e72ba84ae58f
tuned signature -- corresponding to Scala version;
 wenzelm parents: 
43537diff
changeset | 35 | | get_res _ = NONE; | 
| 23962 | 36 | |
| 37 | fun get_exn (Exn exn) = SOME exn | |
| 38 | | get_exn _ = NONE; | |
| 39 | ||
| 43761 
e72ba84ae58f
tuned signature -- corresponding to Scala version;
 wenzelm parents: 
43537diff
changeset | 40 | fun capture f x = Res (f x) handle e => Exn e; | 
| 23962 | 41 | |
| 43761 
e72ba84ae58f
tuned signature -- corresponding to Scala version;
 wenzelm parents: 
43537diff
changeset | 42 | fun release (Res y) = y | 
| 31427 
5a07cc86675d
reraise exceptions to preserve original position (ML system specific);
 wenzelm parents: 
29564diff
changeset | 43 | | release (Exn e) = reraise e; | 
| 23962 | 44 | |
| 43761 
e72ba84ae58f
tuned signature -- corresponding to Scala version;
 wenzelm parents: 
43537diff
changeset | 45 | fun map_result f (Res x) = Res (f x) | 
| 42223 
098c86e53153
more precise propagation of reports/results through some inner syntax layers;
 wenzelm parents: 
40483diff
changeset | 46 | | map_result f (Exn e) = Exn e; | 
| 
098c86e53153
more precise propagation of reports/results through some inner syntax layers;
 wenzelm parents: 
40483diff
changeset | 47 | |
| 44246 | 48 | fun maps_result f = (fn Res x => x | Exn e => Exn e) o map_result f; | 
| 39472 | 49 | |
| 28444 | 50 | |
| 39232 
69c6d3e87660
more abstract treatment of interrupts in structure Exn -- hardly ever need to mention Interrupt literally;
 wenzelm parents: 
34136diff
changeset | 51 | (* interrupts *) | 
| 28444 | 52 | |
| 53 | exception Interrupt = Interrupt; | |
| 39232 
69c6d3e87660
more abstract treatment of interrupts in structure Exn -- hardly ever need to mention Interrupt literally;
 wenzelm parents: 
34136diff
changeset | 54 | |
| 
69c6d3e87660
more abstract treatment of interrupts in structure Exn -- hardly ever need to mention Interrupt literally;
 wenzelm parents: 
34136diff
changeset | 55 | fun interrupt () = raise Interrupt; | 
| 
69c6d3e87660
more abstract treatment of interrupts in structure Exn -- hardly ever need to mention Interrupt literally;
 wenzelm parents: 
34136diff
changeset | 56 | |
| 
69c6d3e87660
more abstract treatment of interrupts in structure Exn -- hardly ever need to mention Interrupt literally;
 wenzelm parents: 
34136diff
changeset | 57 | fun is_interrupt Interrupt = true | 
| 40234 
39af96cc57cb
added Exn.interruptible_capture, which reraises interrupts as required by user-code (when Exn.capture is not immediately followed by Exn.release);
 wenzelm parents: 
39472diff
changeset | 58 |   | is_interrupt (IO.Io {cause, ...}) = is_interrupt cause
 | 
| 39232 
69c6d3e87660
more abstract treatment of interrupts in structure Exn -- hardly ever need to mention Interrupt literally;
 wenzelm parents: 
34136diff
changeset | 59 | | is_interrupt _ = false; | 
| 
69c6d3e87660
more abstract treatment of interrupts in structure Exn -- hardly ever need to mention Interrupt literally;
 wenzelm parents: 
34136diff
changeset | 60 | |
| 
69c6d3e87660
more abstract treatment of interrupts in structure Exn -- hardly ever need to mention Interrupt literally;
 wenzelm parents: 
34136diff
changeset | 61 | val interrupt_exn = Exn Interrupt; | 
| 
69c6d3e87660
more abstract treatment of interrupts in structure Exn -- hardly ever need to mention Interrupt literally;
 wenzelm parents: 
34136diff
changeset | 62 | |
| 
69c6d3e87660
more abstract treatment of interrupts in structure Exn -- hardly ever need to mention Interrupt literally;
 wenzelm parents: 
34136diff
changeset | 63 | fun is_interrupt_exn (Exn exn) = is_interrupt exn | 
| 
69c6d3e87660
more abstract treatment of interrupts in structure Exn -- hardly ever need to mention Interrupt literally;
 wenzelm parents: 
34136diff
changeset | 64 | | is_interrupt_exn _ = false; | 
| 
69c6d3e87660
more abstract treatment of interrupts in structure Exn -- hardly ever need to mention Interrupt literally;
 wenzelm parents: 
34136diff
changeset | 65 | |
| 40234 
39af96cc57cb
added Exn.interruptible_capture, which reraises interrupts as required by user-code (when Exn.capture is not immediately followed by Exn.release);
 wenzelm parents: 
39472diff
changeset | 66 | fun interruptible_capture f x = | 
| 43761 
e72ba84ae58f
tuned signature -- corresponding to Scala version;
 wenzelm parents: 
43537diff
changeset | 67 | Res (f x) handle e => if is_interrupt e then reraise e else Exn e; | 
| 40234 
39af96cc57cb
added Exn.interruptible_capture, which reraises interrupts as required by user-code (when Exn.capture is not immediately followed by Exn.release);
 wenzelm parents: 
39472diff
changeset | 68 | |
| 39232 
69c6d3e87660
more abstract treatment of interrupts in structure Exn -- hardly ever need to mention Interrupt literally;
 wenzelm parents: 
34136diff
changeset | 69 | |
| 44247 | 70 | (* concatenated exceptions *) | 
| 39232 
69c6d3e87660
more abstract treatment of interrupts in structure Exn -- hardly ever need to mention Interrupt literally;
 wenzelm parents: 
34136diff
changeset | 71 | |
| 28459 
f6a4d913cfb1
simplified Exn.EXCEPTIONS, flatten nested occurrences;
 wenzelm parents: 
28444diff
changeset | 72 | exception EXCEPTIONS of exn list; | 
| 28444 | 73 | |
| 23962 | 74 | end; | 
| 40483 
3848283c14bb
treat pervasive "Interrupt" constructor as illegal -- superseded by Exn.Interrupt for internal use and Exn.is_interrupt/Exn.interrupt in user-space;
 wenzelm parents: 
40234diff
changeset | 75 | |
| 
3848283c14bb
treat pervasive "Interrupt" constructor as illegal -- superseded by Exn.Interrupt for internal use and Exn.is_interrupt/Exn.interrupt in user-space;
 wenzelm parents: 
40234diff
changeset | 76 | datatype illegal = Interrupt; | 
| 
3848283c14bb
treat pervasive "Interrupt" constructor as illegal -- superseded by Exn.Interrupt for internal use and Exn.is_interrupt/Exn.interrupt in user-space;
 wenzelm parents: 
40234diff
changeset | 77 |