1 (* Copyright Jeremy Yallop 2007.
2 This file is free software, distributed under the MIT license.
3 See the file COPYING for details.
6 open Pa_deriving_common.Defs
8 module Description
: ClassDescription
= struct
10 let runtimename = "Deriving_Show"
11 let default_module = Some
"Defaults"
12 let allow_private = true
19 ["Int32";"t"], "int32";
21 ["Int64";"t"], "int64";
22 ["nativeint"], "nativeint";
25 ["string" ], "string";
28 ["option" ], "option";
34 module InContext
(L
: Loc
) : Class
= struct
36 open Pa_deriving_common.Base
37 open Pa_deriving_common.Utils
38 open Pa_deriving_common.Type
42 module Helpers
= Pa_deriving_common.Base.InContext
(L
)(Description
)
47 [ <:str_item
< let format formatter
= function $list
:formatter$
>> ]
49 let in_a_box box i e
=
51 Format.$lid
:box$ formatter $`
int:i$
;
53 Format.pp_close_box formatter
() >>
57 Format.pp_print_string formatter
"(";
59 Format.pp_print_string formatter
")" >>
61 let in_hovbox ?
(indent
= 0) = in_a_box "pp_open_hovbox" indent
62 and in_box ?
(indent
= 0) = in_a_box "pp_open_box" indent
64 let instance = object (self
)
66 inherit make_module_expr
69 method nargs ctxt tvars args
=
70 match tvars
, args
with
72 let format_expr id ty
=
73 <:expr
< $self#call_expr ctxt ty
"format"$ formatter $lid
:id$
>> in
74 let format_expr' id ty
=
75 <:expr
< Format.pp_print_string formatter
",";
76 Format.pp_print_space formatter
();
77 $
format_expr id ty$
>> in
78 let exprs = format_expr id ty
:: List.map2
format_expr' ids tys
in
79 in_paren (in_hovbox ~indent
:1 (seq_list
exprs))
82 method tuple ctxt args
=
83 let n = List.length args
in
84 let tvars, tpatt
, _
= tuple
n in
85 wrap [ <:match_case
< $tpatt$
-> $self#nargs ctxt
tvars args$
>> ]
88 method case ctxt
(name
, args
) =
91 <:match_case
< $uid
:name$
-> Format.pp_print_string formatter $str
:name$
>>
93 let tvars, patt
, exp
= tuple
(List.length args
) in
95 <:expr
< Format.pp_print_string formatter $str
:name$
;
96 Format.pp_print_break formatter
1 2;
97 $self#nargs ctxt
tvars args$
>> in
98 <:match_case
< $uid
:name$ $patt$
-> $
in_hovbox format_expr$
>>
100 method sum ?eq ctxt tname params constraints summands
=
101 wrap (List.map
(self#case ctxt
) summands
)
104 method field ctxt
(name
, (vars
, ty
), mut
) =
106 raise
(Underivable
(classname ^
" cannot be derived for record types "
107 ^
"with polymorphic fields"));
108 <:expr
< Format.pp_print_string formatter $str
:name ^
" = "$
;
109 $self#call_expr ctxt ty
"format"$ formatter $lid
:name$
>>
111 method record ?eq ctxt tname params constraints fields
=
114 (fun l r
-> <:expr
< $l$
; Format.pp_print_string formatter
"; "; $r$
>>)
115 (List.map
(self#field ctxt
) fields
) in
118 Format.pp_print_char formatter '
{'
;
120 Format.pp_print_char formatter '
}'
; >> in
121 wrap [ <:match_case
< $record_pattern fields$
-> $
in_hovbox format_record$
>>]
123 method polycase ctxt
: Pa_deriving_common.Type.tagspec
-> Ast.match_case
= function
126 <:expr
< Format.pp_print_string formatter $str
:"`" ^ name ^
" "$
>> in
127 <:match_case
< `$uid
:name$
-> $
format_expr$
>>
130 <:expr
< Format.pp_print_string formatter $str
:"`" ^ name ^
" "$
;
131 $self#call_expr ctxt
(`Tuple es
) "format"$ formatter x
>> in
132 <:match_case
< `$uid
:name$ x
-> $
in_hovbox format_expr$
>>
134 let patt, guard
, cast
= cast_pattern ctxt
.argmap t
in
136 <:expr
< $self#call_expr ctxt t
"format"$ formatter $cast$
>> in
137 <:match_case
< $
patt$
when $guard$
-> $
in_hovbox format_expr$
>>
139 method variant ctxt tname params constraints
(_
,tags
) =
140 wrap (List.map
(self#polycase ctxt
) tags
@ [ <:match_case
< _
-> assert false >> ])
144 let make_module_expr = instance#rhs
145 let generate = default_generate ~
make_module_expr ~make_module_type
146 let generate_sigs = default_generate_sigs ~make_module_sig
147 let generate_expr = instance#expr
151 module Show
= Pa_deriving_common.Base.Register
(Description
)(InContext
)