5 evaluations. Interrupt counts as neutral element. |
5 evaluations. Interrupt counts as neutral element. |
6 *) |
6 *) |
7 |
7 |
8 signature PAR_EXN = |
8 signature PAR_EXN = |
9 sig |
9 sig |
|
10 val serial: exn -> serial * exn |
10 val make: exn list -> exn |
11 val make: exn list -> exn |
11 val dest: exn -> (serial * exn) list option |
12 val dest: exn -> exn list option |
12 val release_all: 'a Exn.result list -> 'a list |
13 val release_all: 'a Exn.result list -> 'a list |
13 val release_first: 'a Exn.result list -> 'a list |
14 val release_first: 'a Exn.result list -> 'a list |
14 end; |
15 end; |
15 |
16 |
16 structure Par_Exn = |
17 structure Par_Exn = |
17 struct |
18 struct |
18 |
19 |
|
20 (* identification via serial numbers *) |
|
21 |
|
22 fun serial exn = |
|
23 (case get_exn_serial exn of |
|
24 SOME i => (i, exn) |
|
25 | NONE => let val i = Library.serial () in (i, set_exn_serial i exn) end); |
|
26 |
|
27 val exn_ord = rev_order o int_ord o pairself (the o get_exn_serial); |
|
28 |
|
29 |
19 (* parallel exceptions *) |
30 (* parallel exceptions *) |
20 |
31 |
21 exception Par_Exn of (serial * exn) Ord_List.T; |
32 exception Par_Exn of exn Ord_List.T; |
22 |
|
23 fun exn_ord ((i, _), (j, _)) = int_ord (j, i); |
|
24 |
33 |
25 fun par_exns (Par_Exn exns) = SOME exns |
34 fun par_exns (Par_Exn exns) = SOME exns |
26 | par_exns exn = if Exn.is_interrupt exn then NONE else SOME [(serial (), exn)]; |
35 | par_exns exn = if Exn.is_interrupt exn then NONE else SOME [#2 (serial exn)]; |
27 |
36 |
28 fun make exns = |
37 fun make exns = |
29 (case map_filter par_exns exns of |
38 (case map_filter par_exns exns of |
30 [] => Exn.Interrupt |
39 [] => Exn.Interrupt |
31 | e :: es => Par_Exn (Library.foldl (Ord_List.merge exn_ord) (e, es))); |
40 | e :: es => Par_Exn (Library.foldl (Ord_List.merge exn_ord) (e, es))); |