|
22 | 22 | * along with this program; if not, write to the Free Software
|
23 | 23 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *)
|
24 | 24 |
|
| 25 | +type lam = Lambda.lambda |
25 | 26 |
|
26 |
| - |
27 |
| -let make_test_sequence_variant_constant |
28 |
| - (fail : Lambda.lambda option) (arg : Lambda.lambda) |
29 |
| - (int_lambda_list : (int * (string * Lambda.lambda) ) list) : Lambda.lambda= |
| 27 | + |
| 28 | +module Map_lambda = struct |
| 29 | + open Map_gen |
| 30 | + type key = |
| 31 | + | Bottom of int |
| 32 | + | Normalized of lam |
| 33 | + |
| 34 | + let bottom_id = ref (-1) |
| 35 | + let bottom () = incr bottom_id ; Bottom !bottom_id |
| 36 | + let compare_key (x : key) (y : key) = Pervasives.compare x y |
| 37 | + let old_order = ref 1 |
| 38 | + let next_id () = |
| 39 | + incr old_order; !old_order |
| 40 | + let rec adjust (tree : _ Map_gen.t as 'a) x replace : 'a = |
| 41 | + match tree with |
| 42 | + | Empty -> |
| 43 | + singleton x (replace None) |
| 44 | + | Leaf {k ; v} -> |
| 45 | + let c = compare_key x k in |
| 46 | + if c = 0 then singleton x (replace (Some v)) else |
| 47 | + if c < 0 then |
| 48 | + Map_gen.unsafe_two_elements x (replace None) k v |
| 49 | + else |
| 50 | + Map_gen.unsafe_two_elements k v x (replace None) |
| 51 | + | Node ({l; k ; r} as tree) -> |
| 52 | + let c = compare_key x k in |
| 53 | + if c = 0 then |
| 54 | + Map_gen.unsafe_node x (replace (Some tree.v)) l r tree.h |
| 55 | + else if c < 0 then |
| 56 | + bal (adjust l x replace ) k tree.v r |
| 57 | + else |
| 58 | + bal l k tree.v (adjust r x replace ) |
| 59 | + |
| 60 | + |
| 61 | + let of_list (int_lambda_list : (int * (string * lam)) list) : (key, (int * string) list * lam * int ) t= |
| 62 | + Ext_list.fold_left int_lambda_list empty (fun acc (hash,(name,lam)) -> |
| 63 | + let key = |
| 64 | + match Lambda.make_key lam with |
| 65 | + | None -> bottom () |
| 66 | + | Some key -> Normalized key in |
| 67 | + adjust acc key (function |
| 68 | + | None -> [hash, name], lam, next_id () |
| 69 | + | Some (acc,action,stamp) -> (hash,name) :: acc, action, stamp |
| 70 | + )) |
| 71 | + let rec values_aux s acc = |
| 72 | + match s with |
| 73 | + | Empty -> acc |
| 74 | + | Leaf {v} -> v :: acc |
| 75 | + | Node {l;v;r} -> |
| 76 | + values_aux l (v ::values_aux r acc) |
| 77 | + let values s : ((int * string) list * lam) list = |
| 78 | + Ext_list.sort_via_arrayf ( values_aux s []) |
| 79 | + (fun (_,_,d0) (_,_,d1) -> compare d0 d1) |
| 80 | + (fun (a,b,_) -> (a,b)) |
| 81 | + |
| 82 | +end |
| 83 | + |
| 84 | +let or_list (arg : lam) (hash_names : (int * string) list) = |
| 85 | + match hash_names with |
| 86 | + | (hash,name):: rest -> |
| 87 | + let init : lam = |
| 88 | + Lprim(Pintcomp Ceq, |
| 89 | + [arg; Lconst ((Const_pointer (hash, Pt_variant{name})))], |
| 90 | + Location.none) in |
| 91 | + Ext_list.fold_left rest init (fun acc (hash,name) -> |
| 92 | + Lambda.Lprim |
| 93 | + (Psequor , |
| 94 | + [acc ; |
| 95 | + Lprim(Pintcomp Ceq, |
| 96 | + [arg; |
| 97 | + Lconst ((Const_pointer (hash, Pt_variant{name})))], |
| 98 | + Location.none)], Location.none) |
| 99 | + ) |
| 100 | + | _ -> assert false |
| 101 | + |
| 102 | +let make_test_sequence_variant_constant |
| 103 | + (fail : lam option) (arg : lam) |
| 104 | + (int_lambda_list : (int * (string * lam) ) list) : lam = |
| 105 | + let int_lambda_list : ((int * string) list * lam) list = |
| 106 | + Map_lambda.(values (of_list int_lambda_list)) in |
| 107 | + match int_lambda_list, fail with |
| 108 | + | (_, act) :: rest, None |
| 109 | + | rest, Some act -> |
| 110 | + Ext_list.fold_right rest act (fun (hash_names,act1) acc -> |
| 111 | + let predicate : lam = or_list arg hash_names in |
| 112 | + Lifthenelse (predicate,act1, acc)) |
| 113 | + | [], None -> assert false |
| 114 | + |
| 115 | +let make_test_sequence_variant_constant_2 |
| 116 | + (fail : lam option) (arg : lam) |
| 117 | + (int_lambda_list : (int * (string * lam) ) list) : lam= |
30 | 118 | match int_lambda_list, fail with
|
31 |
| - | (_, (_,act)) :: rest, None -> |
| 119 | + | (_, (_,act)) :: rest, None |
| 120 | + | rest , Some act -> |
32 | 121 | Ext_list.fold_right rest act (fun (hash1,(name,act1)) acc ->
|
33 |
| - Lifthenelse (Lprim(Pintcomp Ceq, |
34 |
| - [arg; Lconst ((Const_pointer (hash1, Pt_variant{name})))], Location.none), |
35 |
| - act1, acc |
36 |
| - ) |
37 |
| - ) |
38 |
| - | _, Some fail -> |
39 |
| - Ext_list.fold_right int_lambda_list fail (fun (hash1,(name,act1)) acc -> |
40 | 122 | Lifthenelse (Lprim(Pintcomp Ceq,
|
41 | 123 | [arg; Lconst (Const_pointer(hash1, Pt_variant{name}))], Location.none),
|
42 | 124 | act1, acc
|
43 | 125 | )
|
44 | 126 | )
|
45 | 127 | | [], None -> assert false
|
46 | 128 |
|
47 |
| -let call_switcher_variant_constant |
| 129 | +let call_switcher_variant_constant |
48 | 130 | (_loc : Location.t)
|
49 |
| - (fail : Lambda.lambda option) |
50 |
| - (arg : Lambda.lambda) |
51 |
| - (int_lambda_list : (int * (string * Lambda.lambda)) list) |
| 131 | + (fail : lam option) |
| 132 | + (arg : lam) |
| 133 | + (int_lambda_list : (int * (string * lam)) list) |
52 | 134 | (_names : Lambda.switch_names option) =
|
53 |
| - Ext_log.dwarn ~__POS__ "%a@." Ext_obj.pp_any _names; |
| 135 | + |
| 136 | + let int_lambda_list : ((int * string) list * lam) list = |
| 137 | + Map_lambda.(values (of_list int_lambda_list)) in |
54 | 138 | match int_lambda_list, fail with
|
55 |
| - | (_, (_,act)) :: rest, None -> |
56 |
| - Ext_list.fold_right rest act (fun (hash1,(name,act1)) acc -> |
57 |
| - Lifthenelse (Lprim(Pintcomp Ceq, |
58 |
| - [arg; Lconst (Const_pointer(hash1, Pt_variant{name}))], Location.none), |
59 |
| - act1, acc |
60 |
| - ) |
61 |
| - ) |
62 |
| - | _, Some fail -> |
63 |
| - Ext_list.fold_right int_lambda_list fail (fun (hash1,(name,act1)) acc -> |
64 |
| - Lifthenelse (Lprim(Pintcomp Ceq, |
65 |
| - [arg; Lconst (Const_pointer(hash1, Pt_variant{name}))], Location.none), |
| 139 | + | (_,act) :: rest, None |
| 140 | + | rest, Some act -> |
| 141 | + Ext_list.fold_right rest act (fun (hash_names,act1) acc -> |
| 142 | + let predicate = or_list arg hash_names in |
| 143 | + Lifthenelse (predicate, |
66 | 144 | act1, acc
|
67 | 145 | )
|
68 | 146 | )
|
69 | 147 | | [], None -> assert false
|
70 | 148 |
|
71 | 149 |
|
| 150 | + |
| 151 | + |
72 | 152 | let call_switcher_variant_constr
|
73 | 153 | (loc : Location.t)
|
74 |
| - (fail : Lambda.lambda option) |
75 |
| - (arg : Lambda.lambda) |
| 154 | + (fail : lam option) |
| 155 | + (arg : lam) |
76 | 156 | int_lambda_list
|
77 |
| - (names : Lambda.switch_names option) : Lambda.lambda = |
| 157 | + (names : Lambda.switch_names option) : lam = |
78 | 158 | let v = Ident.create "variant" in
|
79 | 159 | Llet(Alias, Pgenval, v, Lprim(Pfield (0, Fld_poly_var_tag), [arg], loc),
|
80 | 160 | call_switcher_variant_constant
|
|
0 commit comments