2 (****************************************************************************)
6 (* INRIA Rocquencourt *)
8 (* Copyright 2002-2006 Institut National de Recherche en Informatique et *)
9 (* en Automatique. All rights reserved. This file is distributed under *)
10 (* the terms of the GNU Library General Public License, with the special *)
11 (* exception on linking described in LICENSE at the top of the Objective *)
12 (* Caml source tree. *)
14 (****************************************************************************)
17 * - Daniel de Rauglaudre: initial version
18 * - Nicolas Pouillard: refactoring
23 (* There is a few Obj.magic due to the fact that we no longer have compiler
24 files like Parsetree, Location, Longident but Camlp4_import that wrap them to
25 avoid name clashing. *)
29 value print_out_value :
30 ref (formatter -> Outcometree.out_value -> unit);
31 value print_out_type :
32 ref (formatter -> Outcometree.out_type -> unit);
33 value print_out_class_type :
34 ref (formatter -> Outcometree.out_class_type -> unit);
35 value print_out_module_type :
36 ref (formatter -> Outcometree.out_module_type -> unit);
37 value print_out_sig_item :
38 ref (formatter -> Outcometree.out_sig_item -> unit);
39 value print_out_signature :
40 ref (formatter -> list Outcometree.out_sig_item -> unit);
41 value print_out_phrase :
42 ref (formatter -> Outcometree.out_phrase -> unit);
45 value print_out_value = Obj.magic print_out_value;
46 value print_out_type = Obj.magic print_out_type;
47 value print_out_class_type = Obj.magic print_out_class_type;
48 value print_out_module_type = Obj.magic print_out_module_type;
49 value print_out_sig_item = Obj.magic print_out_sig_item;
50 value print_out_signature = Obj.magic print_out_signature;
51 value print_out_phrase = Obj.magic print_out_phrase;
54 (* This file originally come from typing/oprint.ml *)
57 open Camlp4_import.Outcometree;
61 value cautious f ppf arg =
62 try f ppf arg with [ Ellipsis -> fprintf ppf "..." ]
65 value rec print_ident ppf =
67 [ Oide_ident s -> fprintf ppf "%s" s
68 | Oide_dot id s -> fprintf ppf "%a.%s" print_ident id s
69 | Oide_apply id1 id2 ->
70 fprintf ppf "%a(%a)" print_ident id1 print_ident id2 ]
73 value value_ident ppf name =
74 if List.mem name ["or"; "mod"; "land"; "lor"; "lxor"; "lsl"; "lsr"; "asr"]
76 fprintf ppf "( %s )" name
79 [ 'a'..'z' | '\223'..'\246' | '\248'..'\255' | '_' ->
81 | _ -> fprintf ppf "( %s )" name ]
86 value print_out_value ppf tree =
87 let rec print_tree ppf =
89 [ Oval_constr name ([_ :: _] as params) ->
90 fprintf ppf "@[<1>%a@ %a@]" print_ident name
91 (print_tree_list print_simple_tree "") params
92 | Oval_variant name (Some param) ->
93 fprintf ppf "@[<2>`%s@ %a@]" name print_simple_tree param
94 | tree -> print_simple_tree ppf tree ]
95 and print_simple_tree ppf =
97 [ Oval_int i -> fprintf ppf "%i" i
98 | Oval_int32 i -> fprintf ppf "%ldl" i
99 | Oval_int64 i -> fprintf ppf "%LdL" i
100 | Oval_nativeint i -> fprintf ppf "%ndn" i
101 | Oval_float f -> fprintf ppf "%.12g" f
102 | Oval_char c -> fprintf ppf "'%s'" (Char.escaped c)
104 try fprintf ppf "\"%s\"" (String.escaped s) with
105 [ Invalid_argument "String.create" -> fprintf ppf "<huge string>" ]
107 fprintf ppf "@[<1>[%a]@]" (print_tree_list print_tree ";") tl
109 fprintf ppf "@[<2>[|%a|]@]" (print_tree_list print_tree ";") tl
110 | Oval_constr (Oide_ident "true") [] -> fprintf ppf "True"
111 | Oval_constr (Oide_ident "false") [] -> fprintf ppf "False"
112 | Oval_constr name [] -> print_ident ppf name
113 | Oval_variant name None -> fprintf ppf "`%s" name
114 | Oval_stuff s -> fprintf ppf "%s" s
116 fprintf ppf "@[<1>{%a}@]" (cautious (print_fields True)) fel
117 | Oval_tuple tree_list ->
118 fprintf ppf "@[(%a)@]" (print_tree_list print_tree ",") tree_list
119 | Oval_ellipsis -> raise Ellipsis
120 | Oval_printer f -> f ppf
121 | tree -> fprintf ppf "@[<1>(%a)@]" (cautious print_tree) tree ]
122 and print_fields first ppf =
125 | [(name, tree) :: fields] ->
128 [ Oide_ident "contents" -> Oide_ident "val"
132 if not first then fprintf ppf ";@ " else ();
133 fprintf ppf "@[<1>%a=@,%a@]" print_ident name (cautious print_tree)
135 print_fields False ppf fields
137 and print_tree_list print_item sep ppf tree_list =
138 let rec print_list first ppf =
141 | [tree :: tree_list] ->
143 if not first then fprintf ppf "%s@ " sep else ();
145 print_list False ppf tree_list
148 cautious (print_list True) ppf tree_list
150 cautious print_tree ppf tree
153 value rec print_list pr sep ppf =
157 | [a :: l] -> do { pr ppf a; sep ppf; print_list pr sep ppf l } ]
161 print_list (fun ppf s -> fprintf ppf "'%s" s) (fun ppf -> fprintf ppf "@ ")
165 print_list (fun ppf s -> fprintf ppf "`%s" s) (fun ppf -> fprintf ppf "@ ")
170 value rec print_out_type ppf =
172 [ Otyp_alias ty s -> fprintf ppf "@[%a as '%s@]" print_out_type ty s
173 | ty -> print_out_type_1 ppf ty ]
174 and print_out_type_1 ppf =
176 [ Otyp_arrow lab ty1 ty2 ->
177 fprintf ppf "@[%a%a ->@ %a@]" print_ty_label lab
178 print_out_type_2 ty1 print_out_type_1 ty2
180 fprintf ppf "@[<hov 2>!%a.@ %a@]"
183 | ty -> print_out_type_2 ppf ty ]
184 and print_out_type_2 ppf =
186 [ Otyp_constr id ([_ :: _] as tyl) ->
187 fprintf ppf "@[%a@;<1 2>%a@]" print_ident id
188 (print_typlist print_simple_out_type "") tyl
189 | ty -> print_simple_out_type ppf ty ]
190 and print_simple_out_type ppf =
191 let rec print_tkind ppf =
193 [ Otyp_var ng s -> fprintf ppf "'%s%s" (if ng then "_" else "") s
194 | Otyp_constr id [] -> fprintf ppf "@[%a@]" print_ident id
196 fprintf ppf "@[<1>(%a)@]" (print_typlist print_out_type " *") tyl
197 | Otyp_stuff s -> fprintf ppf "%s" s
198 | Otyp_variant non_gen row_fields closed tags ->
199 let print_present ppf =
201 [ None | Some [] -> ()
202 | Some l -> fprintf ppf "@;<1 -2>> @[<hov>%a@]" pr_present l ]
204 let print_fields ppf =
206 [ Ovar_fields fields ->
207 print_list print_row_field (fun ppf -> fprintf ppf "@;<1 -2>| ")
209 | Ovar_name id tyl ->
210 fprintf ppf "@[%a%a@]" print_typargs tyl print_ident id ]
212 fprintf ppf "%s[%s@[<hv>@[<hv>%a@]%a ]@]" (if non_gen then "_" else "")
213 (if closed then if tags = None then "= " else "< "
214 else if tags = None then "> "
216 print_fields row_fields
218 | Otyp_object fields rest ->
219 fprintf ppf "@[<2>< %a >@]" (print_fields rest) fields
220 | Otyp_class ng id tyl ->
221 fprintf ppf "@[%a%s#%a@]" print_typargs tyl (if ng then "_" else "")
223 | Otyp_manifest ty1 ty2 ->
224 fprintf ppf "@[<2>%a ==@ %a@]" print_out_type ty1 print_out_type ty2
225 | Otyp_sum constrs ->
226 fprintf ppf "@[<hv>[ %a ]@]"
227 (print_list print_out_constr (fun ppf -> fprintf ppf "@ | ")) constrs
228 | Otyp_record lbls ->
229 fprintf ppf "@[<hv 2>{ %a }@]"
230 (print_list print_out_label (fun ppf -> fprintf ppf ";@ ")) lbls
231 | Otyp_abstract -> fprintf ppf "<abstract>"
232 | Otyp_alias _ _ | Otyp_poly _ _
233 | Otyp_arrow _ _ _ | Otyp_constr _ [_ :: _] as ty ->
234 fprintf ppf "@[<1>(%a)@]" print_out_type ty ]
237 and print_out_constr ppf (name, tyl) =
239 [ [] -> fprintf ppf "%s" name
241 fprintf ppf "@[<2>%s of@ %a@]" name
242 (print_typlist print_out_type " and") tyl ]
243 and print_out_label ppf (name, mut, arg) =
244 fprintf ppf "@[<2>%s :@ %s%a@]" name (if mut then "mutable " else "")
246 and print_fields rest ppf =
250 [ Some non_gen -> fprintf ppf "%s.." (if non_gen then "_" else "")
254 fprintf ppf "%s : %a" s print_out_type t;
256 [ Some _ -> fprintf ppf ";@ "
258 print_fields rest ppf []
261 fprintf ppf "%s : %a;@ %a" s print_out_type t (print_fields rest) l ]
262 and print_row_field ppf (l, opt_amp, tyl) =
264 if opt_amp then fprintf ppf " of@ &@ "
265 else if tyl <> [] then fprintf ppf " of@ "
268 fprintf ppf "@[<hv 2>`%s%t%a@]" l pr_of (print_typlist print_out_type " &")
270 and print_typlist print_elem sep ppf =
273 | [ty] -> print_elem ppf ty
275 fprintf ppf "%a%s@ %a" print_elem ty sep (print_typlist print_elem sep)
277 and print_typargs ppf =
280 | [ty1] -> fprintf ppf "%a@ " print_simple_out_type ty1
282 fprintf ppf "@[<1>(%a)@]@ " (print_typlist print_out_type ",") tyl ]
283 and print_ty_label ppf lab =
284 if lab <> "" then fprintf ppf "~%s:" lab else ()
287 value type_parameter ppf (ty, (co, cn)) =
288 fprintf ppf "%s'%s" (if not cn then "+" else if not co then "-" else "")
292 value print_out_class_params ppf =
296 fprintf ppf "@[<1>[%a]@]@ "
297 (print_list type_parameter (fun ppf -> fprintf ppf ", "))
301 (* Signature items *)
303 value rec print_out_class_type ppf =
305 [ Octy_constr id tyl ->
310 fprintf ppf "@[<1>[%a]@]@ "
311 (print_typlist Toploop.print_out_type.val ",") tyl ]
313 fprintf ppf "@[%a%a@]" pr_tyl tyl print_ident id
314 | Octy_fun lab ty cty ->
315 fprintf ppf "@[%a[ %a ] ->@ %a@]" print_ty_label lab
316 Toploop.print_out_type.val ty print_out_class_type cty
317 | Octy_signature self_ty csil ->
320 [ Some ty -> fprintf ppf "@ @[(%a)@]" Toploop.print_out_type.val ty
323 fprintf ppf "@[<hv 2>@[<2>object%a@]@ %a@;<1 -2>end@]" pr_param self_ty
324 (print_list print_out_class_sig_item (fun ppf -> fprintf ppf "@ "))
326 and print_out_class_sig_item ppf =
328 [ Ocsg_constraint ty1 ty2 ->
329 fprintf ppf "@[<2>type %a =@ %a;@]" Toploop.print_out_type.val ty1
330 Toploop.print_out_type.val ty2
331 | Ocsg_method name priv virt ty ->
332 fprintf ppf "@[<2>method %s%s%s :@ %a;@]"
333 (if priv then "private " else "") (if virt then "virtual " else "")
334 name Toploop.print_out_type.val ty
335 | Ocsg_value name mut virt ty ->
336 fprintf ppf "@[<2>value %s%s%s :@ %a;@]"
337 (if mut then "mutable " else "") (if virt then "virtual " else "")
338 name Toploop.print_out_type.val ty ]
341 value rec print_out_module_type ppf =
343 [ Omty_ident id -> fprintf ppf "%a" print_ident id
344 | Omty_signature sg ->
345 fprintf ppf "@[<hv 2>sig@ %a@;<1 -2>end@]"
346 Toploop.print_out_signature.val sg
347 | Omty_functor name mty_arg mty_res ->
348 fprintf ppf "@[<2>functor@ (%s : %a) ->@ %a@]" name
349 print_out_module_type mty_arg print_out_module_type mty_res
350 | Omty_abstract -> () ]
351 and print_out_signature ppf =
354 | [item] -> fprintf ppf "%a;" Toploop.print_out_sig_item.val item
356 fprintf ppf "%a;@ %a" Toploop.print_out_sig_item.val item
357 print_out_signature items ]
358 and print_out_sig_item ppf =
360 [ Osig_class vir_flag name params clt rs ->
361 fprintf ppf "@[<2>%s%s@ %a%s@ :@ %a@]"
362 (if rs = Orec_next then "and" else "class")
363 (if vir_flag then " virtual" else "") print_out_class_params params
364 name Toploop.print_out_class_type.val clt
365 | Osig_class_type vir_flag name params clt rs ->
366 fprintf ppf "@[<2>%s%s@ %a%s@ =@ %a@]"
367 (if rs = Orec_next then "and" else "class type")
368 (if vir_flag then " virtual" else "") print_out_class_params params
369 name Toploop.print_out_class_type.val clt
370 | Osig_exception id tyl ->
371 fprintf ppf "@[<2>exception %a@]" print_out_constr (id, tyl)
372 | Osig_modtype name Omty_abstract ->
373 fprintf ppf "@[<2>module type %s@]" name
374 | Osig_modtype name mty ->
375 fprintf ppf "@[<2>module type %s =@ %a@]" name
376 Toploop.print_out_module_type.val mty
377 | Osig_module name mty rs ->
378 fprintf ppf "@[<2>%s %s :@ %a@]"
379 (match rs with [ Orec_not -> "module"
380 | Orec_first -> "module rec"
381 | Orec_next -> "and" ]) name
382 Toploop.print_out_module_type.val mty
385 (if rs = Orec_next then "and" else "type")
387 | Osig_value name ty prims ->
388 let kwd = if prims = [] then "value" else "external" in
394 fprintf ppf "@ = \"%s\"" s;
395 List.iter (fun s -> fprintf ppf "@ \"%s\"" s) sl
398 fprintf ppf "@[<2>%s %a :@ %a%a@]" kwd value_ident name
399 Toploop.print_out_type.val ty pr_prims prims ]
401 and print_out_type_decl kwd ppf (name, args, ty, priv, constraints) =
402 let constrain ppf (ty, ty') =
403 fprintf ppf "@ @[<2>constraint %a =@ %a@]" Toploop.print_out_type.val ty
404 Toploop.print_out_type.val ty'
406 let print_constraints ppf params = List.iter (constrain ppf) params in
407 let type_defined ppf =
409 [ [] -> fprintf ppf "%s" name
410 | [arg] -> fprintf ppf "%s %a" name type_parameter arg
412 fprintf ppf "%s@ %a" name
413 (print_list type_parameter (fun ppf -> fprintf ppf "@ ")) args ]
414 and print_kind ppf ty =
416 (if priv = Obj.magic Camlp4_import.Asttypes.Private then " private" else "")
417 Toploop.print_out_type.val ty
419 let print_types ppf = fun
420 [ Otyp_manifest ty1 ty2 ->
421 fprintf ppf "@ @[<2>%a ==%a@]"
422 Toploop.print_out_type.val ty1
424 | ty -> print_kind ppf ty ]
426 fprintf ppf "@[<2>@[<hv 2>@[%s %t@] =%a@]%a@]" kwd type_defined
427 print_types ty print_constraints constraints
432 value print_out_exception ppf exn outv =
434 [ Sys.Break -> fprintf ppf "Interrupted.@."
435 | Out_of_memory -> fprintf ppf "Out of memory during evaluation.@."
437 fprintf ppf "Stack overflow during evaluation (looping recursion?).@."
439 fprintf ppf "@[Exception:@ %a.@]@." Toploop.print_out_value.val outv ]
442 value rec print_items ppf =
445 | [(tree, valopt) :: items] ->
449 fprintf ppf "@[<2>%a =@ %a@]" Toploop.print_out_sig_item.val tree
450 Toploop.print_out_value.val v
451 | None -> fprintf ppf "@[%a@]" Toploop.print_out_sig_item.val tree ];
452 if items <> [] then fprintf ppf "@ %a" print_items items else ()
456 value print_out_phrase ppf =
458 [ Ophr_eval outv ty ->
459 fprintf ppf "@[- : %a@ =@ %a@]@." Toploop.print_out_type.val ty
460 Toploop.print_out_value.val outv
461 | Ophr_signature [] -> ()
462 | Ophr_signature items -> fprintf ppf "@[<v>%a@]@." print_items items
463 | Ophr_exception (exn, outv) -> print_out_exception ppf exn outv ]
466 Toploop.print_out_value.val := print_out_value;
467 Toploop.print_out_type.val := print_out_type;
468 Toploop.print_out_class_type.val := print_out_class_type;
469 Toploop.print_out_module_type.val := print_out_module_type;
470 Toploop.print_out_sig_item.val := print_out_sig_item;
471 Toploop.print_out_signature.val := print_out_signature;
472 Toploop.print_out_phrase.val := print_out_phrase;