package GT
Generic programming with extensible transformations
Install
Dune Dependency
Authors
Maintainers
Sources
0.5.2.tar.gz
md5=9d18b96ada4d18fdda0b5f5698273145
sha512=945070bea4322bf8f7932a259af91432a3c109a05294ba2a27c1c2e9d2796ffb4cc32f6b8e28ff465311277696296ddda531a2ce818e590c09c64c5721d65e19
doc/src/show/show.ml.html
Source file show.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
(* * Generic transformers: plugins. * Copyright (C) 2016-2022 * Dmitrii Kosarev aka Kakadu * St.Petersburg State University, JetBrains Research *) (** {i Show} plugin: converts value to a string. Synthetized attributes' type (both default and for type parameters) is [string]. Inherited attributes' type (both default and for type parameters) is [unit]. For type declaration [type ('a,'b,...) typ = ...] it will create transformation function with type [('a -> string) -> ('b -> string) -> ... -> ('a,'b,...) typ -> string] See also: {!Fmt} plugin. *) open Ppxlib open Printf open GTCommon open HelpersBase let trait_name = "show" module Make (AstHelpers : GTHELPERS_sig.S) = struct let trait_name = trait_name module P = Plugin.Make (AstHelpers) open AstHelpers let app_format_sprintf ~loc arg = Exp.app ~loc (Exp.of_longident ~loc (Ldot (Lident "Format", "sprintf"))) arg ;; class g args tdecls = object (self) inherit [loc, Exp.t, Typ.t, type_arg, Cl.t, Ctf.t, Cf.t, Str.t, Sig.t, Pat.t] Plugin_intf .typ_g inherit P.generator args tdecls inherit P.no_inherit_arg args tdecls method trait_name = trait_name method inh_of_main ~loc _tdecl = Typ.ident ~loc "unit" method syn_of_main ~loc ?in_class _tdecl = Typ.ident ~loc "string" method syn_of_param ~loc _ = Typ.ident ~loc "string" method inh_of_param ~loc tdecl _name = self#inh_of_main ~loc tdecl method plugin_class_params ~loc typs ~typname = List.map typs ~f:Typ.from_caml @ [ Typ.var ~loc @@ Naming.make_extra_param typname ] (* Adapted to generate only single method per constructor definition *) method on_tuple_constr ~loc ~is_self_rec ~mutual_decls ~inhe tdecl constr_info ts = let constr_name = match constr_info with | Some (`Poly s) -> sprintf "`%s" s | Some (`Normal s) -> sprintf "%s" s | None -> "" in let names = List.map ts ~f:fst in Exp.let_ ~loc [ Pat.unit ~loc, inhe ] @@ if List.length ts = 0 then Exp.string_const ~loc constr_name else List.fold_left ts ~f:(fun acc (name, typ) -> Exp.app ~loc acc (self#app_transformation_expr ~loc (self#do_typ_gen ~loc ~is_self_rec ~mutual_decls tdecl typ) (Exp.unit ~loc) (Exp.ident ~loc name))) ~init: Exp.( app ~loc (of_longident ~loc (Ldot (Lident "Printf", "sprintf"))) @@ let fmt = StringLabels.concat ~sep:", " @@ List.map names ~f:(fun _ -> "%s") in Exp.string_const ~loc @@ Printf.sprintf "%s%s(%s)" constr_name (if List.is_empty ts || Option.is_none constr_info then "" else " ") fmt) method! on_record_constr ~loc ~is_self_rec ~mutual_decls ~inhe tdecl info bindings labs = assert (List.length labs > 0); let constr_name = match info with | `Poly s -> sprintf "`%s" s | `Normal s -> s in if List.length bindings = 0 then failwith "Record constructors can't have empty label list" else List.fold_left bindings ~f:(fun acc (ident, labname, typ) -> Exp.app ~loc acc @@ self#app_transformation_expr ~loc (self#do_typ_gen ~loc ~is_self_rec ~mutual_decls tdecl typ) (Exp.unit ~loc) (Exp.ident ~loc ident)) ~init: Exp.( app ~loc (of_longident ~loc (Ldot (Lident "Printf", "sprintf"))) @@ let fmt = StringLabels.concat ~sep:", " @@ List.map bindings ~f:(fun (_, lab, _) -> Printf.sprintf "%s=%%s" lab) in Exp.string_const ~loc @@ Printf.sprintf "%s {%s}" constr_name fmt) 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 fmt = List.fold_left labs ~init:"" ~f:(fun acc x -> sprintf "%s %s=%%s;" acc x.pld_name.txt) in [ Cf.method_concrete ~loc (Naming.meth_name_for_record tdecl) @@ Exp.fun_ ~loc (Pat.unit ~loc) @@ Exp.fun_ ~loc pat @@ List.fold_left labs ~f:(fun acc { pld_name; pld_type } -> Exp.app ~loc acc (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))) ~init: (app_format_sprintf ~loc @@ Exp.string_const ~loc @@ sprintf "{%s }" fmt) ] method treat_type_specially t = Option.map ~f:(fun _ -> let loc = loc_from_caml t.ptyp_loc in Exp.fun_ ~loc (Pat.unit ~loc) @@ Exp.fun_ ~loc (Pat.any ~loc) @@ Exp.string_const ~loc "\"<opaque>\"") @@ List.find t.ptyp_attributes ~f:(fun { attr_name = { txt } } -> String.equal txt "opaque") 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)"
>