File: typeable_class.ml

package info (click to toggle)
ocaml-deriving 0.1.1a-3
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd, stretch, wheezy
  • size: 728 kB
  • ctags: 1,265
  • sloc: ml: 4,827; makefile: 112
file content (72 lines) | stat: -rw-r--r-- 2,633 bytes parent folder | download
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
(*pp camlp4of *)

(* Copyright Jeremy Yallop 2007.
   This file is free software, distributed under the MIT license.
   See the file COPYING for details.
*)

module InContext (L : Base.Loc) =
struct
  open Type
  open Base
  open Camlp4.PreCast
  include Base.InContext(L)

  let classname = "Typeable"

  let mkName : name -> string = 
    let file_name, sl, _, _, _, _, _, _ = Loc.to_tuple loc in
      Printf.sprintf "%s_%d_%f_%s" 
        file_name sl (Unix.gettimeofday ())

  let gen ?eq ctxt ((tname,_,_,_,_) as decl : Type.decl) _ = 
    let paramList = 
      List.fold_right 
        (fun (p,_) cdr ->
             <:expr< $uid:NameMap.find p ctxt.argmap$.type_rep::$cdr$ >>)
        ctxt.params
      <:expr< [] >>
    in <:module_expr< struct type $Ast.TyDcl (loc, "a", [], atype ctxt decl, [])$
          let type_rep = TypeRep.mkFresh $str:mkName tname$ $paramList$ end >>

  let tup ctxt ts mexpr expr = 
      let params = 
        expr_list 
          (List.map (fun t -> <:expr< let module M = $expr ctxt t$ 
                                       in $mexpr$ >>) ts) in
        <:module_expr< Defaults(struct type $Ast.TyDcl (loc, "a", [], atype_expr ctxt (`Tuple ts), [])$
                                       let type_rep = Typeable.TypeRep.mkTuple $params$ end) >>

  let instance = object(self)
    inherit make_module_expr ~classname ~allow_private:true 

    method tuple ctxt ts = tup ctxt ts <:expr< M.type_rep >> (self#expr)
    method sum = gen 
    method record = gen
    method variant ctxt decl (_,tags) =
    let tags, extends = 
      List.fold_left 
        (fun (tags, extends) -> function
           | Tag (l, None)  -> <:expr< ($str:l$, None) :: $tags$ >>, extends
           | Tag (l,Some t) ->
               <:expr< ($str:l$, Some $mproject (self#expr ctxt t) "type_rep"$) ::$tags$ >>,
               extends
           | Extends t -> 
               tags,
               <:expr< $mproject (self#expr ctxt t) "type_rep"$::$extends$ >>)
        (<:expr< [] >>, <:expr< [] >>) tags in
      <:module_expr< Defaults(
        struct type $Ast.TyDcl (loc, "a", [], atype ctxt decl, [])$
               let type_rep = Typeable.TypeRep.mkPolyv $tags$ $extends$
        end) >>
  end
end

let _ = Base.register "Typeable" 
  ((fun (loc, context, decls) -> 
     let module M = InContext(struct let loc = loc end) in
       M.generate ~context ~decls ~make_module_expr:M.instance#rhs ~classname:M.classname
         ~default_module:"Defaults" ()),
  (fun (loc, context, decls) -> 
     let module M = InContext(struct let loc = loc end) in
       M.gen_sigs ~context ~decls ~classname:M.classname))