Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Page
Library
Module
Module type
Parameter
Class
Class type
Source
atd_annot.ml1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140open Printf type t = Atd_ast.annot let error_at loc s = failwith (sprintf "%s:\n%s" (Atd_ast.string_of_loc loc) s) let has_section k l = try ignore (List.assoc k l); true with Not_found -> false let has_field k k2 l = List.exists ( fun k1 -> try (* each section must be unique *) let _, l2 = List.assoc k1 l in ignore (List.assoc k2 l2); true with Not_found -> false ) k let rec find f = function [] -> None | x :: l -> match f x with None -> find f l | Some _ as y -> y let get_flag k k2 l = let result = find ( fun k1 -> try (* each section must be unique *) let loc, l2 = List.assoc k1 l in let loc, o = List.assoc k2 l2 in match o with None -> Some true | Some "true" -> Some true | Some "false" -> Some false | Some s -> error_at loc (sprintf "Invalid value %S for flag %s.%s" s k1 k2) with Not_found -> None ) k in match result with None -> false | Some x -> x let get_field parse default k k2 l = let result = find ( fun k1 -> try (* each section must be unique *) let loc, l2 = List.assoc k1 l in let loc, o = List.assoc k2 l2 in match o with Some s -> (match parse s with Some x as y -> y | None -> error_at loc (sprintf "Invalid annotation <%s %s=%S>" k1 k2 s) ) | None -> error_at loc (sprintf "Missing value for annotation %s.%s" k1 k2) with Not_found -> None ) k in match result with None -> default | Some x -> x (* replace first occurrence, if any *) let rec replace k v = function (k', _) as x :: l -> if k = k' then (k, v) :: l else x :: replace k v l | [] -> [] let set_field loc k k2 v l : Atd_ast.annot = try let section_loc, section = List.assoc k l in let section = try let _field = List.assoc k2 section in replace k2 (loc, v) section with Not_found -> (k2, (loc, v)) :: section in replace k (section_loc, section) l with Not_found -> (k, (loc, [ k2, (loc, v) ])) :: l let collapse merge l = let tbl = Hashtbl.create 10 in let n = ref 0 in List.iter ( fun (s1, f1) -> incr n; try let _, f2 = Hashtbl.find tbl s1 in Hashtbl.replace tbl s1 (!n, merge f1 f2) with Not_found -> Hashtbl.add tbl s1 (!n, f1) ) (List.rev l); let l = Hashtbl.fold (fun s (i, f) l -> (i, (s, f)) :: l) tbl [] in let l = List.sort (fun (i, _) (j, _) -> compare j i) l in List.map snd l let override_values x1 x2 = x1 let override_fields (loc1, l1) (loc2, l2) = (loc1, collapse override_values (l1 @ l2)) let merge l = collapse override_fields l let create_id = let n = ref (-1) in fun () -> incr n; if !n < 0 then failwith "Atd_annot.create_id: counter overflow" else string_of_int !n