src/Pure/ML-Systems/exn.ML
author wenzelm
Fri, 03 Oct 2008 21:06:38 +0200
changeset 28490 40c3f900c457
parent 28459 f6a4d913cfb1
child 29564 f8b933a62151
permissions -rw-r--r--
removed obsolete Posix/Signal compatibility wrappers;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
23962
e0358fac0541 Runtime exceptions as values (from library.ML);
wenzelm
parents:
diff changeset
     1
(*  Title:      Pure/ML-Systems/exn.ML
e0358fac0541 Runtime exceptions as values (from library.ML);
wenzelm
parents:
diff changeset
     2
    ID:         $Id$
e0358fac0541 Runtime exceptions as values (from library.ML);
wenzelm
parents:
diff changeset
     3
    Author:     Makarius
e0358fac0541 Runtime exceptions as values (from library.ML);
wenzelm
parents:
diff changeset
     4
28444
283d5e41953d more robust treatment of Interrupt;
wenzelm
parents: 23962
diff changeset
     5
Extra support for exceptions.
23962
e0358fac0541 Runtime exceptions as values (from library.ML);
wenzelm
parents:
diff changeset
     6
*)
e0358fac0541 Runtime exceptions as values (from library.ML);
wenzelm
parents:
diff changeset
     7
28444
283d5e41953d more robust treatment of Interrupt;
wenzelm
parents: 23962
diff changeset
     8
signature EXN =
283d5e41953d more robust treatment of Interrupt;
wenzelm
parents: 23962
diff changeset
     9
sig
283d5e41953d more robust treatment of Interrupt;
wenzelm
parents: 23962
diff changeset
    10
  datatype 'a result = Exn of exn | Result of 'a
283d5e41953d more robust treatment of Interrupt;
wenzelm
parents: 23962
diff changeset
    11
  val get_result: 'a result -> 'a option
283d5e41953d more robust treatment of Interrupt;
wenzelm
parents: 23962
diff changeset
    12
  val get_exn: 'a result -> exn option
283d5e41953d more robust treatment of Interrupt;
wenzelm
parents: 23962
diff changeset
    13
  val capture: ('a -> 'b) -> 'a -> 'b result
283d5e41953d more robust treatment of Interrupt;
wenzelm
parents: 23962
diff changeset
    14
  val release: 'a result -> 'a
283d5e41953d more robust treatment of Interrupt;
wenzelm
parents: 23962
diff changeset
    15
  exception Interrupt
28459
f6a4d913cfb1 simplified Exn.EXCEPTIONS, flatten nested occurrences;
wenzelm
parents: 28444
diff changeset
    16
  exception EXCEPTIONS of exn list
28444
283d5e41953d more robust treatment of Interrupt;
wenzelm
parents: 23962
diff changeset
    17
  val release_all: 'a result list -> 'a list
283d5e41953d more robust treatment of Interrupt;
wenzelm
parents: 23962
diff changeset
    18
  val release_first: 'a result list -> 'a list
283d5e41953d more robust treatment of Interrupt;
wenzelm
parents: 23962
diff changeset
    19
end;
283d5e41953d more robust treatment of Interrupt;
wenzelm
parents: 23962
diff changeset
    20
283d5e41953d more robust treatment of Interrupt;
wenzelm
parents: 23962
diff changeset
    21
structure Exn: EXN =
23962
e0358fac0541 Runtime exceptions as values (from library.ML);
wenzelm
parents:
diff changeset
    22
struct
e0358fac0541 Runtime exceptions as values (from library.ML);
wenzelm
parents:
diff changeset
    23
28444
283d5e41953d more robust treatment of Interrupt;
wenzelm
parents: 23962
diff changeset
    24
(* runtime exceptions as values *)
283d5e41953d more robust treatment of Interrupt;
wenzelm
parents: 23962
diff changeset
    25
23962
e0358fac0541 Runtime exceptions as values (from library.ML);
wenzelm
parents:
diff changeset
    26
datatype 'a result =
e0358fac0541 Runtime exceptions as values (from library.ML);
wenzelm
parents:
diff changeset
    27
  Result of 'a |
e0358fac0541 Runtime exceptions as values (from library.ML);
wenzelm
parents:
diff changeset
    28
  Exn of exn;
e0358fac0541 Runtime exceptions as values (from library.ML);
wenzelm
parents:
diff changeset
    29
e0358fac0541 Runtime exceptions as values (from library.ML);
wenzelm
parents:
diff changeset
    30
fun get_result (Result x) = SOME x
e0358fac0541 Runtime exceptions as values (from library.ML);
wenzelm
parents:
diff changeset
    31
  | get_result _ = NONE;
e0358fac0541 Runtime exceptions as values (from library.ML);
wenzelm
parents:
diff changeset
    32
e0358fac0541 Runtime exceptions as values (from library.ML);
wenzelm
parents:
diff changeset
    33
fun get_exn (Exn exn) = SOME exn
e0358fac0541 Runtime exceptions as values (from library.ML);
wenzelm
parents:
diff changeset
    34
  | get_exn _ = NONE;
e0358fac0541 Runtime exceptions as values (from library.ML);
wenzelm
parents:
diff changeset
    35
e0358fac0541 Runtime exceptions as values (from library.ML);
wenzelm
parents:
diff changeset
    36
fun capture f x = Result (f x) handle e => Exn e;
e0358fac0541 Runtime exceptions as values (from library.ML);
wenzelm
parents:
diff changeset
    37
e0358fac0541 Runtime exceptions as values (from library.ML);
wenzelm
parents:
diff changeset
    38
fun release (Result y) = y
e0358fac0541 Runtime exceptions as values (from library.ML);
wenzelm
parents:
diff changeset
    39
  | release (Exn e) = raise e;
e0358fac0541 Runtime exceptions as values (from library.ML);
wenzelm
parents:
diff changeset
    40
28444
283d5e41953d more robust treatment of Interrupt;
wenzelm
parents: 23962
diff changeset
    41
28459
f6a4d913cfb1 simplified Exn.EXCEPTIONS, flatten nested occurrences;
wenzelm
parents: 28444
diff changeset
    42
(* interrupt and nested exceptions *)
28444
283d5e41953d more robust treatment of Interrupt;
wenzelm
parents: 23962
diff changeset
    43
283d5e41953d more robust treatment of Interrupt;
wenzelm
parents: 23962
diff changeset
    44
exception Interrupt = Interrupt;
28459
f6a4d913cfb1 simplified Exn.EXCEPTIONS, flatten nested occurrences;
wenzelm
parents: 28444
diff changeset
    45
exception EXCEPTIONS of exn list;
28444
283d5e41953d more robust treatment of Interrupt;
wenzelm
parents: 23962
diff changeset
    46
28459
f6a4d913cfb1 simplified Exn.EXCEPTIONS, flatten nested occurrences;
wenzelm
parents: 28444
diff changeset
    47
fun plain_exns (Result _) = []
f6a4d913cfb1 simplified Exn.EXCEPTIONS, flatten nested occurrences;
wenzelm
parents: 28444
diff changeset
    48
  | plain_exns (Exn Interrupt) = []
f6a4d913cfb1 simplified Exn.EXCEPTIONS, flatten nested occurrences;
wenzelm
parents: 28444
diff changeset
    49
  | plain_exns (Exn (EXCEPTIONS exns)) = List.concat (map (plain_exns o Exn) exns)
f6a4d913cfb1 simplified Exn.EXCEPTIONS, flatten nested occurrences;
wenzelm
parents: 28444
diff changeset
    50
  | plain_exns (Exn exn) = [exn];
28444
283d5e41953d more robust treatment of Interrupt;
wenzelm
parents: 23962
diff changeset
    51
23962
e0358fac0541 Runtime exceptions as values (from library.ML);
wenzelm
parents:
diff changeset
    52
28444
283d5e41953d more robust treatment of Interrupt;
wenzelm
parents: 23962
diff changeset
    53
fun release_all results =
283d5e41953d more robust treatment of Interrupt;
wenzelm
parents: 23962
diff changeset
    54
  if List.all (fn Result _ => true | _ => false) results
283d5e41953d more robust treatment of Interrupt;
wenzelm
parents: 23962
diff changeset
    55
  then map (fn Result x => x) results
283d5e41953d more robust treatment of Interrupt;
wenzelm
parents: 23962
diff changeset
    56
  else
28459
f6a4d913cfb1 simplified Exn.EXCEPTIONS, flatten nested occurrences;
wenzelm
parents: 28444
diff changeset
    57
    (case List.concat (map plain_exns results) of
28444
283d5e41953d more robust treatment of Interrupt;
wenzelm
parents: 23962
diff changeset
    58
      [] => raise Interrupt
28459
f6a4d913cfb1 simplified Exn.EXCEPTIONS, flatten nested occurrences;
wenzelm
parents: 28444
diff changeset
    59
    | exns => raise EXCEPTIONS exns);
28444
283d5e41953d more robust treatment of Interrupt;
wenzelm
parents: 23962
diff changeset
    60
283d5e41953d more robust treatment of Interrupt;
wenzelm
parents: 23962
diff changeset
    61
fun release_first results = release_all results
28459
f6a4d913cfb1 simplified Exn.EXCEPTIONS, flatten nested occurrences;
wenzelm
parents: 28444
diff changeset
    62
  handle EXCEPTIONS (exn :: _) => raise exn;
28444
283d5e41953d more robust treatment of Interrupt;
wenzelm
parents: 23962
diff changeset
    63
23962
e0358fac0541 Runtime exceptions as values (from library.ML);
wenzelm
parents:
diff changeset
    64
end;