package GT
Generic programming with extensible transformations
Install
Dune Dependency
Authors
Maintainers
Sources
0.5.2.tar.gz
md5=9d18b96ada4d18fdda0b5f5698273145
sha512=945070bea4322bf8f7932a259af91432a3c109a05294ba2a27c1c2e9d2796ffb4cc32f6b8e28ff465311277696296ddda531a2ce818e590c09c64c5721d65e19
doc/src/gmap/gmap.ml.html
Source file gmap.ml
1 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 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221
(* * Generic transformers (GT): `gmap` plugin. * Copyright (C) 2017-2022 * Dmitrii Kosarev a.k.a. Kakadu * St.Petersburg University, JetBrains Research *) (** {i Gmap} plugin (functor). For type declaration [type ('a,'b,...) typ = ...] it will create a transformation function with type [('a -> 'a2) -> ('b -> 'b2) -> ... -> ('a,'b,...) typ -> ('a2,'b2,...) typ ] Inherited attributes' type (both default and for type parameters) is [unit]. *) open Ppxlib open Printf open GTCommon open HelpersBase let trait_name = "gmap" let param_name_mangler = sprintf "%s_2" module Make (AstHelpers : GTHELPERS_sig.S) = struct let trait_name = trait_name module P = Plugin.Make (AstHelpers) open AstHelpers (* TODO: rethink this function *) let hack_params ?(loc = noloc) ps = let param_names = map_type_param_names ps ~f:id in let rez_names = map_type_param_names ps ~f:param_name_mangler in let name_migrations = List.zip_exn param_names rez_names in let assoc s = try List.Assoc.find_exn ~equal:String.equal name_migrations s with | Caml.Not_found -> Ppxlib.Location.raise_errorf ~loc:Location.none "can't find new typ for param `%s" s in let blownup_params = List.concat_map param_names ~f:(fun s1 -> [ named_type_arg ~loc s1; named_type_arg ~loc @@ assoc s1 ]) in param_names, rez_names, assoc, blownup_params ;; class g args tdecls = object (self : 'self) inherit P.no_inherit_arg args tdecls as super method trait_name = trait_name method inh_of_main ~loc _tdecl = Typ.ident ~loc "unit" method syn_of_param ~loc s = Typ.var ~loc @@ param_name_mangler s method inh_of_param ~loc tdecl _name = self#inh_of_main ~loc tdecl method syn_of_main ~loc ?(in_class = false) tdecl = if in_class && is_polyvariant_tdecl tdecl then Typ.var ~loc @@ sprintf "syn_%s" tdecl.ptype_name.txt else ( let param_names, rez_names, find_param, blownup_params = hack_params tdecl.ptype_params in let ans = let ident = Lident (self#cur_name tdecl) in Typ.constr ~loc ident @@ List.map ~f:(Typ.var ~loc) rez_names in ans) method plugin_class_params ~loc (typs : Ppxlib.core_type list) ~typname : Typ.t list = let typs2 = List.map typs ~f:(fun typ -> map_core_type typ ~onvar:(fun s -> let open Ppxlib.Ast_builder.Default in Option.some @@ ptyp_var ~loc:typ.ptyp_loc (param_name_mangler s))) in let blownup_params = List.concat @@ List.map2_exn ~f:(fun a b -> [ a; b ]) typs typs2 in List.map blownup_params ~f:Typ.from_caml @ [ Typ.var ~loc @@ Naming.make_extra_param typname ; Typ.var ~loc @@ sprintf "syn_%s" typname ] method hack ~loc (mangler : string -> string) param tdecl : Typ.t = let loc = loc_from_caml tdecl.ptype_loc in let on_abstract () = Typ.constr ~loc (Lident tdecl.ptype_name.txt) @@ map_type_param_names tdecl.ptype_params ~f:(fun s -> Typ.var ~loc @@ mangler s) in visit_typedecl ~loc tdecl ~onopen:(fun () -> failwith "open types are not supported") ~onrecord:(fun _ -> on_abstract ()) ~onvariant:(fun _ -> on_abstract ()) ~onabstract:(fun () -> on_abstract ()) ~onmanifest:(fun typ -> if not (is_polyvariant typ) then on_abstract () else ( match typ.ptyp_desc with | Ptyp_variant (rf, _, _) -> let onvar s = let open Ast_builder.Default in Some (ptyp_var ~loc:tdecl.ptype_loc @@ mangler s) in Typ.variant ~loc ~is_open:true @@ List.map rf ~f:(fun rf -> match rf.prf_desc with | Rtag (name, has_empty, ts) -> let open Ast_builder.Default in let on_t t = map_core_type ~onvar ~onconstr:(fun name ts -> match name with | Lident s when String.equal s tdecl.ptype_name.txt -> Option.some @@ ptyp_var ~loc:tdecl.ptype_loc param | _ -> None) t in { rf with prf_desc = Rtag (name, has_empty, List.map ts ~f:on_t) } | Rinherit typ -> { rf with prf_desc = Rinherit (map_core_type typ ~onvar) }) | _ -> failwith "should not happen")) method! extra_class_sig_members tdecl = let loc = loc_from_caml tdecl.ptype_loc in super#extra_class_sig_members tdecl @ [ (let syn = sprintf "syn_%s" tdecl.ptype_name.txt in Ctf.constraint_ ~loc (Typ.var ~loc @@ syn) (self#hack ~loc param_name_mangler syn tdecl)) ] method! extra_class_str_members tdecl = let loc = loc_from_caml tdecl.ptype_loc in super#extra_class_str_members tdecl @ [ (let syn = sprintf "syn_%s" tdecl.ptype_name.txt in Cf.constraint_ ~loc (Typ.var ~loc @@ syn) (self#hack ~loc param_name_mangler syn tdecl)) ] method on_tuple_constr ~loc ~is_self_rec ~mutual_decls ~inhe tdecl constr_info ts = let ctuple = List.map ts ~f:(fun (name, typ) -> self#app_transformation_expr ~loc (self#do_typ_gen ~loc ~is_self_rec ~mutual_decls tdecl typ) inhe (Exp.ident ~loc name)) in match constr_info with | Some (`Normal s) -> Exp.construct ~loc (lident s) ctuple | Some (`Poly s) -> Exp.variant ~loc s ctuple | None -> Exp.tuple ~loc ctuple method on_record_declaration ~loc ~is_self_rec ~mutual_decls tdecl labs = let pat = Pat.record ~loc @@ List.map labs ~f:(fun l -> Lident l.pld_name.txt, Pat.var ~loc l.pld_name.txt) in let methname = sprintf "do_%s" tdecl.ptype_name.txt in [ Cf.method_concrete ~loc methname @@ Exp.fun_ ~loc (Pat.unit ~loc) @@ Exp.fun_ ~loc pat @@ Exp.record ~loc @@ List.map labs ~f:(fun { pld_name; pld_type } -> ( lident pld_name.txt , self#app_transformation_expr ~loc (self#do_typ_gen ~loc ~is_self_rec ~mutual_decls tdecl pld_type) (Exp.unit ~loc) (Exp.ident ~loc pld_name.txt) )) ] method! on_record_constr ~loc ~is_self_rec ~mutual_decls ~inhe tdecl info bindings labs = assert (List.length labs > 0); let is_poly, cname = match info with | `Normal s -> false, s | `Poly s -> true, s in (* Exp.fun_list ~loc (List.map bindings ~f:(fun (s,_,_) -> Pat.sprintf ~loc "%s" s)) @@ *) (if is_poly then Exp.variant ~loc cname else Exp.construct ~loc (lident cname)) [ Exp.record ~loc @@ List.map bindings ~f:(fun (s, labname, typ) -> ( lident labname , self#app_transformation_expr ~loc (self#do_typ_gen ~loc ~is_self_rec ~mutual_decls tdecl typ) inhe (Exp.ident ~loc s) )) ] method! make_inh ~loc = Pat.unit ~loc, Exp.unit ~loc end let create = (new g :> P.plugin_constructor) end let register () = Expander.register_plugin trait_name (module Make : Plugin_intf.MAKE) let () = register ()
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>