| author | steckerm | 
| Sat, 20 Sep 2014 10:42:08 +0200 | |
| changeset 58401 | b8ca69d9897b | 
| parent 56667 | 65e84b0ef974 | 
| child 61077 | 06cca32aa519 | 
| 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
 | 
| 56667 
65e84b0ef974
more abstract Exn.Interrupt and POSIX return code;
 wenzelm parents: 
56628diff
changeset | 22 | val return_code: exn -> int -> int | 
| 56628 | 23 |   val capture_exit: int -> ('a -> 'b) -> 'a -> 'b
 | 
| 28459 
f6a4d913cfb1
simplified Exn.EXCEPTIONS, flatten nested occurrences;
 wenzelm parents: 
28444diff
changeset | 24 | exception EXCEPTIONS of exn list | 
| 28444 | 25 | end; | 
| 26 | ||
| 27 | structure Exn: EXN = | |
| 23962 | 28 | struct | 
| 29 | ||
| 44158 | 30 | (* exceptions as values *) | 
| 28444 | 31 | |
| 23962 | 32 | datatype 'a result = | 
| 43761 
e72ba84ae58f
tuned signature -- corresponding to Scala version;
 wenzelm parents: 
43537diff
changeset | 33 | Res of 'a | | 
| 23962 | 34 | Exn of exn; | 
| 35 | ||
| 43761 
e72ba84ae58f
tuned signature -- corresponding to Scala version;
 wenzelm parents: 
43537diff
changeset | 36 | fun get_res (Res x) = SOME x | 
| 
e72ba84ae58f
tuned signature -- corresponding to Scala version;
 wenzelm parents: 
43537diff
changeset | 37 | | get_res _ = NONE; | 
| 23962 | 38 | |
| 39 | fun get_exn (Exn exn) = SOME exn | |
| 40 | | get_exn _ = NONE; | |
| 41 | ||
| 43761 
e72ba84ae58f
tuned signature -- corresponding to Scala version;
 wenzelm parents: 
43537diff
changeset | 42 | fun capture f x = Res (f x) handle e => Exn e; | 
| 23962 | 43 | |
| 43761 
e72ba84ae58f
tuned signature -- corresponding to Scala version;
 wenzelm parents: 
43537diff
changeset | 44 | fun release (Res y) = y | 
| 31427 
5a07cc86675d
reraise exceptions to preserve original position (ML system specific);
 wenzelm parents: 
29564diff
changeset | 45 | | release (Exn e) = reraise e; | 
| 23962 | 46 | |
| 43761 
e72ba84ae58f
tuned signature -- corresponding to Scala version;
 wenzelm parents: 
43537diff
changeset | 47 | 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 | 48 | | map_result f (Exn e) = Exn e; | 
| 
098c86e53153
more precise propagation of reports/results through some inner syntax layers;
 wenzelm parents: 
40483diff
changeset | 49 | |
| 44246 | 50 | fun maps_result f = (fn Res x => x | Exn e => Exn e) o map_result f; | 
| 39472 | 51 | |
| 28444 | 52 | |
| 39232 
69c6d3e87660
more abstract treatment of interrupts in structure Exn -- hardly ever need to mention Interrupt literally;
 wenzelm parents: 
34136diff
changeset | 53 | (* interrupts *) | 
| 28444 | 54 | |
| 55 | exception Interrupt = Interrupt; | |
| 39232 
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 interrupt () = raise Interrupt; | 
| 
69c6d3e87660
more abstract treatment of interrupts in structure Exn -- hardly ever need to mention Interrupt literally;
 wenzelm parents: 
34136diff
changeset | 58 | |
| 
69c6d3e87660
more abstract treatment of interrupts in structure Exn -- hardly ever need to mention Interrupt literally;
 wenzelm parents: 
34136diff
changeset | 59 | 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 | 60 |   | 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 | 61 | | is_interrupt _ = false; | 
| 
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 | 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 | 64 | |
| 
69c6d3e87660
more abstract treatment of interrupts in structure Exn -- hardly ever need to mention Interrupt literally;
 wenzelm parents: 
34136diff
changeset | 65 | 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 | 66 | | is_interrupt_exn _ = false; | 
| 
69c6d3e87660
more abstract treatment of interrupts in structure Exn -- hardly ever need to mention Interrupt literally;
 wenzelm parents: 
34136diff
changeset | 67 | |
| 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 | fun interruptible_capture f x = | 
| 43761 
e72ba84ae58f
tuned signature -- corresponding to Scala version;
 wenzelm parents: 
43537diff
changeset | 69 | 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 | 70 | |
| 39232 
69c6d3e87660
more abstract treatment of interrupts in structure Exn -- hardly ever need to mention Interrupt literally;
 wenzelm parents: 
34136diff
changeset | 71 | |
| 56667 
65e84b0ef974
more abstract Exn.Interrupt and POSIX return code;
 wenzelm parents: 
56628diff
changeset | 72 | (* POSIX return code *) | 
| 
65e84b0ef974
more abstract Exn.Interrupt and POSIX return code;
 wenzelm parents: 
56628diff
changeset | 73 | |
| 
65e84b0ef974
more abstract Exn.Interrupt and POSIX return code;
 wenzelm parents: 
56628diff
changeset | 74 | fun return_code exn rc = | 
| 
65e84b0ef974
more abstract Exn.Interrupt and POSIX return code;
 wenzelm parents: 
56628diff
changeset | 75 | if is_interrupt exn then (130: int) else rc; | 
| 56628 | 76 | |
| 77 | fun capture_exit rc f x = | |
| 56667 
65e84b0ef974
more abstract Exn.Interrupt and POSIX return code;
 wenzelm parents: 
56628diff
changeset | 78 | f x handle exn => exit (return_code exn rc); | 
| 56628 | 79 | |
| 80 | ||
| 44247 | 81 | (* concatenated exceptions *) | 
| 39232 
69c6d3e87660
more abstract treatment of interrupts in structure Exn -- hardly ever need to mention Interrupt literally;
 wenzelm parents: 
34136diff
changeset | 82 | |
| 28459 
f6a4d913cfb1
simplified Exn.EXCEPTIONS, flatten nested occurrences;
 wenzelm parents: 
28444diff
changeset | 83 | exception EXCEPTIONS of exn list; | 
| 28444 | 84 | |
| 23962 | 85 | 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 | 86 | |
| 
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 | 87 | 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 | 88 |