1845 lines
66 KiB
OCaml
1845 lines
66 KiB
OCaml
(* camlp4r q_MLast.cmo ./pa_extfun.cmo *)
|
|
(***********************************************************************)
|
|
(* *)
|
|
(* Camlp4 *)
|
|
(* *)
|
|
(* Daniel de Rauglaudre, projet Cristal, INRIA Rocquencourt *)
|
|
(* *)
|
|
(* Copyright 2001 Institut National de Recherche en Informatique et *)
|
|
(* Automatique. Distributed only by permission. *)
|
|
(* *)
|
|
(***********************************************************************)
|
|
|
|
(* $Id$ *)
|
|
|
|
open Pcaml;
|
|
open Spretty;
|
|
open Stdpp;
|
|
|
|
value no_ss = ref False;
|
|
value input_file_ic = ref None;
|
|
|
|
value not_impl name x =
|
|
let desc =
|
|
if Obj.is_block (Obj.repr x) then
|
|
"tag = " ^ string_of_int (Obj.tag (Obj.repr x))
|
|
else "int_val = " ^ string_of_int (Obj.magic x)
|
|
in
|
|
HVbox [: `S NO ("<pr_o: not impl: " ^ name ^ "; " ^ desc ^ ">") :]
|
|
;
|
|
|
|
value apply_it l f =
|
|
apply_it_f l where rec apply_it_f =
|
|
fun
|
|
[ [] -> f
|
|
| [a :: l] -> a (apply_it_f l) ]
|
|
;
|
|
|
|
value rec list elem =
|
|
fun
|
|
[ [] -> fun _ k -> k
|
|
| [x] -> fun dg k -> [: `elem x dg k :]
|
|
| [x :: l] -> fun dg k -> [: `elem x "" [: :]; list elem l dg k :] ]
|
|
;
|
|
|
|
value rec listws elem sep el dg k =
|
|
match el with
|
|
[ [] -> k
|
|
| [x] -> [: `elem x dg k :]
|
|
| [x :: l] ->
|
|
let sdg =
|
|
match sep with
|
|
[ S _ x -> x
|
|
| _ -> "" ]
|
|
in
|
|
[: `elem x sdg [: `sep :]; listws elem sep l dg k :] ]
|
|
;
|
|
|
|
value rec listwbws elem b sep el dg k =
|
|
match el with
|
|
[ [] -> [: b; k :]
|
|
| [x] -> [: `elem b x dg k :]
|
|
| [x :: l] ->
|
|
let sdg =
|
|
match sep with
|
|
[ S _ x -> x
|
|
| _ -> "" ]
|
|
in
|
|
[: `elem b x sdg [: :]; listwbws elem [: `sep :] sep l dg k :] ]
|
|
;
|
|
|
|
value level box elem next e dg k =
|
|
let rec curr e dg k = elem curr next e dg k in
|
|
box (curr e dg k)
|
|
;
|
|
|
|
value is_infix =
|
|
let infixes = Hashtbl.create 73 in
|
|
do {
|
|
List.iter (fun s -> Hashtbl.add infixes s True)
|
|
["=="; "!="; "+"; "+."; "-"; "-."; "*"; "*."; "/"; "/."; "**"; "**.";
|
|
"="; "=."; "<>"; "<>."; "<"; "<."; ">"; ">."; "<="; "<=."; ">="; ">=.";
|
|
"^"; "@"; "asr"; "land"; "lor"; "lsl"; "lsr"; "lxor"; "mod"; "or";
|
|
"quo"; "&&"; "||"; "~-"; "~-."];
|
|
fun s -> try Hashtbl.find infixes s with [ Not_found -> False ]
|
|
}
|
|
;
|
|
|
|
value is_keyword =
|
|
let keywords = Hashtbl.create 301 in
|
|
do {
|
|
List.iter (fun s -> Hashtbl.add keywords s True)
|
|
["<>"; "<="; "struct"; "asr"; "<-"; ";;"; ":="; "type"; "::"; "true";
|
|
"for"; "to"; "and"; "false"; "rec"; "or"; "of"; "with"; "while";
|
|
"module"; "when"; "exception"; "lsr"; "lsl"; "done"; "function"; "/.";
|
|
".."; "->"; "in"; "-."; "if"; "lor"; "external"; "sig"; "+."; "then";
|
|
"*."; "**"; "match"; "try"; "do"; "else"; "land"; "&&"; "as"; "open";
|
|
"}"; "|"; "end"; "{"; "lxor"; "_"; "^"; "]"; "["; "let"; "!="; "||";
|
|
"@"; ">"; "="; "<"; ";"; ":"; "mutable"; "/"; "[|"; "."; "-"; ","; "+";
|
|
"begin"; "downto"; "*"; ")"; "|]"; "("; "'"; "&"; "functor"; ">="; "#";
|
|
"~-."; "!"; "~-"; "fun"; "mod"; "=="; "val"];
|
|
fun s -> try Hashtbl.find keywords s with [ Not_found -> False ]
|
|
}
|
|
;
|
|
|
|
value has_special_chars v =
|
|
match v.[0] with
|
|
[ 'a'..'z' | 'A'..'Z' | '_' -> False
|
|
| _ ->
|
|
if String.length v >= 2 && v.[0] == '<' &&
|
|
(v.[1] == '<' || v.[1] == ':')
|
|
then
|
|
False
|
|
else True ]
|
|
;
|
|
|
|
value var_escaped v =
|
|
if has_special_chars v || is_infix v then "( " ^ v ^ " )"
|
|
else if is_keyword v then v ^ "__"
|
|
else v
|
|
;
|
|
|
|
value flag n f = if f then [: `S LR n :] else [: :];
|
|
|
|
value conv_con =
|
|
fun
|
|
[ "True" -> "true"
|
|
| "False" -> "false"
|
|
| x -> x ]
|
|
;
|
|
value conv_lab =
|
|
fun
|
|
[ "val" -> "contents"
|
|
| x -> x ]
|
|
;
|
|
|
|
(* default global loc *)
|
|
|
|
value loc = (0, 0);
|
|
|
|
value id_var s =
|
|
if has_special_chars s || is_infix s then
|
|
HVbox [: `S LR "("; `S LR s; `S LR ")" :]
|
|
else if is_keyword s then HVbox [: `S LR (s ^ "__") :]
|
|
else HVbox [: `S LR s :]
|
|
;
|
|
|
|
value virtual_flag =
|
|
fun
|
|
[ True -> [: `S LR "virtual" :]
|
|
| _ -> [: :] ]
|
|
;
|
|
|
|
value rec_flag =
|
|
fun
|
|
[ True -> [: `S LR "rec" :]
|
|
| _ -> [: :] ]
|
|
;
|
|
|
|
(* extensible printers *)
|
|
|
|
value sig_item x dg k =
|
|
let k = if no_ss.val then k else [: `S RO ";;"; k :] in
|
|
pr_sig_item.pr_fun "top" x "" k
|
|
;
|
|
value str_item x dg k =
|
|
let k = if no_ss.val then k else [: `S RO ";;"; k :] in
|
|
pr_str_item.pr_fun "top" x "" k
|
|
;
|
|
value expr e dg k = pr_expr.pr_fun "top" e dg k;
|
|
value patt e dg k = pr_patt.pr_fun "top" e dg k;
|
|
value expr1 e dg k = pr_expr.pr_fun "expr1" e dg k;
|
|
value simple_expr e dg k = pr_expr.pr_fun "simple" e dg k;
|
|
value patt1 e dg k = pr_patt.pr_fun "patt1" e dg k;
|
|
value simple_patt e dg k = pr_patt.pr_fun "simple" e dg k;
|
|
value expr_fun_args ge = Extfun.apply pr_expr_fun_args.val ge;
|
|
|
|
(* type core *)
|
|
|
|
value ctyp_f = ref (fun []);
|
|
value simple_ctyp_f = ref (fun []);
|
|
|
|
value ctyp t _ k = ctyp_f.val t "" k;
|
|
value simple_ctyp t _ k = simple_ctyp_f.val t "" k;
|
|
|
|
value mutable_flag =
|
|
fun
|
|
[ True -> [: `S LR "mutable" :]
|
|
| _ -> [: :] ]
|
|
;
|
|
|
|
value private_flag =
|
|
fun
|
|
[ True -> [: `S LR "private" :]
|
|
| _ -> [: :] ]
|
|
;
|
|
|
|
value input_from_source bp ep =
|
|
match input_file_ic.val with
|
|
[ Some ic when ep > bp ->
|
|
do {
|
|
seek_in ic bp;
|
|
let len = ep - bp in
|
|
let buff = Buffer.create 20 in
|
|
loop 0 where rec loop i =
|
|
if i < len then do {
|
|
let c = input_char ic in
|
|
Buffer.add_char buff c;
|
|
loop (i + 1)
|
|
}
|
|
else Buffer.contents buff
|
|
}
|
|
| _ -> "" ]
|
|
;
|
|
|
|
value rec labels loc b vl _ k =
|
|
match vl with
|
|
[ [] -> [: b; k :]
|
|
| [v] -> [: `label True (snd loc) b v "" k :]
|
|
| [v :: ([(nloc, _, _, _) :: _] as l)] ->
|
|
[: `label False (fst nloc) b v "" [: :]; labels loc [: :] l "" k :] ]
|
|
and label is_last bp_next b (loc, f, m, t) _ k =
|
|
let m = flag "mutable" m in
|
|
let txt =
|
|
let s = input_from_source (snd loc) bp_next in
|
|
let s =
|
|
try
|
|
let i = String.index s ';' in
|
|
String.sub s (i + 1) (String.length s - i - 1)
|
|
with
|
|
[ Not_found -> "" ]
|
|
in
|
|
try
|
|
let i = String.rindex s '\n' in
|
|
String.sub s 0 i
|
|
with
|
|
[ Not_found -> s ]
|
|
in
|
|
let k =
|
|
[: if is_last && txt = "" then [: :] else [: `S RO ";" :]; `S RO txt; k :]
|
|
in
|
|
Hbox
|
|
[: `HVbox
|
|
[: `HVbox [: b; m; `S LR (conv_lab f); `S LR ":" :];
|
|
`ctyp t "" [: :] :];
|
|
k :]
|
|
;
|
|
|
|
value rec ctyp_list tel _ k = listws simple_ctyp (S LR "*") tel "" k;
|
|
|
|
value include_comment_of_last_constructor ep =
|
|
match input_file_ic.val with
|
|
[ Some ic ->
|
|
do {
|
|
seek_in ic ep;
|
|
loop ep where rec loop ep =
|
|
let c = input_char ic in
|
|
if c = '\n' then ep + 1
|
|
else loop (ep + 1)
|
|
}
|
|
| None -> ep ]
|
|
;
|
|
|
|
value rec variants loc b vl dg k =
|
|
let ep = include_comment_of_last_constructor (snd loc) in
|
|
variants_loop (fst loc, ep) b vl dg k
|
|
and variants_loop loc b vl _ k =
|
|
match vl with
|
|
[ [] -> [: b; k :]
|
|
| [v] -> [: `variant (snd loc) b v "" k :]
|
|
| [v :: ([(nloc, _, _) :: _] as l)] ->
|
|
[: `variant (fst nloc) b v "" [: :];
|
|
variants_loop loc [: `S LR "|" :] l "" k :] ]
|
|
and variant bp_next b (loc, c, tl) _ k =
|
|
let txt =
|
|
let s = input_from_source (snd loc) bp_next in
|
|
try
|
|
let i = String.rindex s '\n' in
|
|
String.sub s 0 i
|
|
with
|
|
[ Not_found -> "" ]
|
|
in
|
|
let k = [: `S RO txt; k :] in
|
|
match tl with
|
|
[ [] -> HVbox [: b; `HOVbox [: `S LR c; k :] :]
|
|
| _ ->
|
|
HVbox
|
|
[: b; `HOVbox [: `S LR c; `S LR "of"; ctyp_list tl "" [: :]; k :] :] ]
|
|
;
|
|
|
|
value rec row_fields b rfl _ k = listwbws row_field b (S LR "|") rfl "" k
|
|
and row_field b rf _ k =
|
|
match rf with
|
|
[ MLast.RfTag c ao tl ->
|
|
let c = "`" ^ c in
|
|
match tl with
|
|
[ [] -> HVbox [: b; `HOVbox [: `S LR c; k :] :]
|
|
| _ ->
|
|
let ao = if ao then [: `S LR "&" :] else [: :] in
|
|
HVbox
|
|
[: b; `HOVbox [: `S LR c; `S LR "of"; ao; ctyp_list tl "" k :] :] ]
|
|
| MLast.RfInh t ->
|
|
HVbox [: b; `ctyp t "" k :] ]
|
|
;
|
|
|
|
value rec get_type_args t tl =
|
|
match t with
|
|
[ <:ctyp< $t1$ $t2$ >> -> get_type_args t1 [t2 :: tl]
|
|
| _ -> (t, tl) ]
|
|
;
|
|
|
|
value module_pref =
|
|
apply_it
|
|
[level (fun x -> HOVbox x)
|
|
(fun curr next t _ k ->
|
|
match t with
|
|
[ <:ctyp< $t1$ $t2$ >> ->
|
|
let (t, tl) = get_type_args t1 [t2] in
|
|
[: curr t "" [: :];
|
|
list
|
|
(fun t _ k ->
|
|
HOVbox [: `S NO "("; curr t "" [: :]; `S RO ")"; k :])
|
|
tl "" k :]
|
|
| <:ctyp< $t1$ . $t2$ >> ->
|
|
[: curr t1 "" [: `S NO "." :]; `next t2 "" k :]
|
|
| _ -> [: `next t "" k :] ])]
|
|
simple_ctyp
|
|
;
|
|
|
|
value rec class_longident sl dg k =
|
|
match sl with
|
|
[ [i] -> HVbox [: `S LR i; k :]
|
|
| [m :: sl] -> HVbox [: `S LR m; `S NO "."; `class_longident sl dg k :]
|
|
| _ -> HVbox [: `not_impl "class_longident" sl; k :] ]
|
|
;
|
|
|
|
value rec clty_longident sl dg k =
|
|
match sl with
|
|
[ [i] -> HVbox [: `S LR i; k :]
|
|
| [m :: sl] -> HVbox [: `S LR m; `S NO "."; `clty_longident sl dg k :]
|
|
| _ -> HVbox [: `not_impl "clty_longident" sl; k :] ]
|
|
;
|
|
|
|
value rec meth_list (ml, v) dg k =
|
|
match (ml, v) with
|
|
[ ([f], False) -> [: `field f dg k :]
|
|
| ([], _) -> [: `S LR ".."; k :]
|
|
| ([f :: ml], v) ->
|
|
[: `field f "" [: `S RO ";" :]; meth_list (ml, v) dg k :] ]
|
|
and field (lab, t) dg k = HVbox [: `S LR lab; `S LR ":"; `ctyp t dg k :];
|
|
|
|
simple_ctyp_f.val :=
|
|
apply_it
|
|
[level (fun x -> HOVbox x)
|
|
(fun curr next t _ k ->
|
|
match t with
|
|
[ <:ctyp< $t1$ == $t2$ >> ->
|
|
[: curr t1 "=" [: `S LR "=" :]; `next t2 "" k :]
|
|
| t -> [: `next t "" k :] ]);
|
|
level (fun x -> HOVbox x)
|
|
(fun curr next t _ k ->
|
|
match t with
|
|
[ <:ctyp< ? $lab$ : $t$ >> ->
|
|
[: `S LO "?"; `S LR lab; `S RO ":"; `next t "" k :]
|
|
| <:ctyp< ~ $lab$ : $t$ >> -> [: `S LO (lab ^ ":"); `next t "" k :]
|
|
| t -> [: `next t "" k :] ]);
|
|
level (fun x -> HOVbox x)
|
|
(fun curr next t _ k ->
|
|
match t with
|
|
[ <:ctyp< $t1$ $t2$ >> ->
|
|
let (t, tl) = get_type_args t1 [t2] in
|
|
match tl with
|
|
[ [<:ctyp< $_$ $_$ >>] -> [: curr t2 "" [: :]; curr t1 "" k :]
|
|
| [_] -> [: `next t2 "" [: :]; curr t1 "" k :]
|
|
| _ ->
|
|
[: `S LO "(";
|
|
listws (fun x _ k -> HOVbox [: curr x "" k :]) (S RO ",")
|
|
tl "" [: `S RO ")" :];
|
|
curr t "" k :] ]
|
|
| t -> [: `next t "" k :] ]);
|
|
level (fun x -> HOVbox x)
|
|
(fun curr next t _ k ->
|
|
match t with
|
|
[ <:ctyp< $t1$ . $t2$ >> ->
|
|
[: `module_pref t1 "" [: `S NO "." :]; `next t2 "" k :]
|
|
| t -> [: `next t "" k :] ]);
|
|
level (fun x -> HOVbox x)
|
|
(fun curr next t _ k ->
|
|
match t with
|
|
[ <:ctyp< '$s$ >> -> [: `S LO "'"; `S LR (var_escaped s); k :]
|
|
| <:ctyp< $lid:s$ >> -> [: `S LR s; k :]
|
|
| <:ctyp< $uid:s$ >> -> [: `S LR s; k :]
|
|
| <:ctyp< _ >> -> [: `S LR "_"; k :]
|
|
| <:ctyp< { $list:ftl$ } >> ->
|
|
let loc = MLast.loc_of_ctyp t in
|
|
[: `HVbox
|
|
[: labels loc [: `S LR "{" :] ftl "" [: `S LR "}" :];
|
|
k :] :]
|
|
| <:ctyp< [ $list:ctl$ ] >> ->
|
|
let loc = MLast.loc_of_ctyp t in
|
|
[: `BEbox [: `HVbox [: :];
|
|
variants loc [: :] ctl "" [: :]; k :] :]
|
|
| <:ctyp< [| $list:rfl$ |] >> ->
|
|
[: `HVbox
|
|
[: `HVbox [: :];
|
|
row_fields [: `S LR "[" :] rfl "" [: `S LR "]" :];
|
|
k :] :]
|
|
| <:ctyp< [| > $list:rfl$ |] >> ->
|
|
[: `HVbox
|
|
[: `HVbox [: :];
|
|
row_fields [: `S LR "[>" :] rfl "" [: `S LR "]" :];
|
|
k :] :]
|
|
| <:ctyp< [| < $list:rfl$ > $list:sl$ |] >> ->
|
|
let k1 = [: `S LR "]" :] in
|
|
let k1 =
|
|
match sl with
|
|
[ [] -> k1
|
|
| l ->
|
|
[: `S LR ">";
|
|
list (fun x _ k -> HVbox [: `S LR x; k :]) l "" k1 :] ]
|
|
in
|
|
[: `HVbox
|
|
[: `HVbox [: :]; row_fields [: `S LR "[<" :] rfl "" k1;
|
|
k :] :]
|
|
| <:ctyp< $_$ -> $_$ >> | <:ctyp< $_$ $_$ >> |
|
|
<:ctyp< $_$ == $_$ >> | <:ctyp< $_$ . $_$ >> |
|
|
<:ctyp< ($list:_$) >> | <:ctyp< $_$ as $_$ >> |
|
|
<:ctyp< ~ $_$ : $_$ >> | <:ctyp< ? $_$ : $_$ >> as t ->
|
|
[: `S LO "("; `ctyp t "" [: `HVbox [: `S RO ")"; k :] :] :]
|
|
| MLast.TyCls _ id -> [: `S LO "#"; `class_longident id "" k :]
|
|
| MLast.TyObj _ [] False -> [: `S LR "<>"; k :]
|
|
| MLast.TyObj _ ml v ->
|
|
[: `S LR "<"; meth_list (ml, v) "" [: `S LR ">"; k :] :] ])]
|
|
(fun t _ k -> not_impl "ctyp" t);
|
|
|
|
ctyp_f.val :=
|
|
apply_it
|
|
[level (fun x -> HOVbox x)
|
|
(fun curr next t _ k ->
|
|
match t with
|
|
[ <:ctyp< $x$ as $y$ >> ->
|
|
[: curr x "" [: `S LR "as" :]; `next y "" k :]
|
|
| t -> [: `next t "" k :] ]);
|
|
level (fun x -> HOVbox x)
|
|
(fun curr next t _ k ->
|
|
match t with
|
|
[ <:ctyp< $x$ -> $y$ >> ->
|
|
[: `next x "" [: `S LR "->" :]; curr y "" k :]
|
|
| t -> [: `next t "" k :] ]);
|
|
level (fun x -> HOVbox x)
|
|
(fun curr next t _ k ->
|
|
match t with
|
|
[ <:ctyp< ? $lab$ : $t$ >> ->
|
|
[: `S LO "?"; `S LR lab; `S RO ":"; `next t "" k :]
|
|
| t -> [: `next t "" k :] ]);
|
|
level (fun x -> HOVbox x)
|
|
(fun curr next t _ k ->
|
|
match t with
|
|
[ <:ctyp< ($list:tl$) >> -> listws next (S LR "*") tl "" k
|
|
| t -> [: `next t "" k :] ])]
|
|
simple_ctyp;
|
|
|
|
(* patterns *)
|
|
|
|
value rec get_patt_args a al =
|
|
match a with
|
|
[ <:patt< $a1$ $a2$ >> -> get_patt_args a1 [a2 :: al]
|
|
| _ -> (a, al) ]
|
|
;
|
|
|
|
value rec is_irrefut_patt =
|
|
fun
|
|
[ <:patt< $lid:_$ >> -> True
|
|
| <:patt< () >> -> True
|
|
| <:patt< _ >> -> True
|
|
| <:patt< ($x$ as $_$) >> -> is_irrefut_patt x
|
|
| <:patt< { $list:fpl$ } >> ->
|
|
List.for_all (fun (_, p) -> is_irrefut_patt p) fpl
|
|
| <:patt< ($p$ : $_$) >> -> is_irrefut_patt p
|
|
| <:patt< ($list:pl$) >> -> List.for_all is_irrefut_patt pl
|
|
| <:patt< ? $_$ : ($p$) >> -> is_irrefut_patt p
|
|
| <:patt< ? $_$ : ($p$ = $_$) >> -> is_irrefut_patt p
|
|
| <:patt< ~ $_$ : $p$ >> -> is_irrefut_patt p
|
|
| _ -> False ]
|
|
;
|
|
|
|
(* expressions *)
|
|
|
|
pr_expr_fun_args.val :=
|
|
extfun Extfun.empty with
|
|
[ <:expr< fun [$p$ -> $e$] >> as ge ->
|
|
if is_irrefut_patt p then
|
|
let (pl, e) = expr_fun_args e in
|
|
([p :: pl], e)
|
|
else ([], ge)
|
|
| ge -> ([], ge) ];
|
|
|
|
value raise_match_failure (bp, ep) k =
|
|
HOVbox
|
|
[: `S LR "raise"; `S LO "("; `S LR "Match_failure"; `S LO "(";
|
|
`S LR ("\"" ^ Pcaml.input_file.val ^ "\""); `S RO ",";
|
|
`S LR (string_of_int bp); `S RO ","; `S LR (string_of_int ep);
|
|
`S RO ")"; `S RO ")"; k :]
|
|
;
|
|
|
|
value rec bind_list b pel _ k =
|
|
match pel with
|
|
[ [pe] -> let_binding b pe "" k
|
|
| pel ->
|
|
Vbox [: `HVbox [: :]; listwbws let_binding b (S LR "and") pel "" k :] ]
|
|
and let_binding b (p, e) _ k =
|
|
let (pl, e) =
|
|
match p with
|
|
[ <:patt< ($_$ : $_$) >> -> ([], e)
|
|
| _ -> expr_fun_args e ]
|
|
in
|
|
match (p, e) with
|
|
[ (<:patt< $lid:_$ >>, <:expr< ($e$ : $t$) >>) ->
|
|
BEbox
|
|
[: `HVbox
|
|
[: `HVbox b;
|
|
`HVbox (list simple_patt [p :: pl] "" [: `S LR ":" :]);
|
|
`ctyp t "" [: `S LR "=" :] :];
|
|
`expr e "" [: :]; k :]
|
|
| _ ->
|
|
BEbox
|
|
[: `HVbox
|
|
[: `HVbox b;
|
|
`HVbox (list simple_patt [p :: pl] "" [: `S LR "=" :]) :];
|
|
`expr e "" [: :]; k :] ]
|
|
and match_assoc_list loc pel dg k =
|
|
match pel with
|
|
[ [] ->
|
|
HVbox
|
|
[: `HVbox [: `S LR "_"; `S LR "->" :]; `raise_match_failure loc k :]
|
|
| _ ->
|
|
BEVbox
|
|
[: `HVbox [: :]; listwbws match_assoc [: :] (S LR "|") pel "" k :] ]
|
|
and match_assoc b (p, w, e) dg k =
|
|
let s =
|
|
match w with
|
|
[ Some e1 ->
|
|
[: `HVbox
|
|
[: `HVbox [: :]; `patt p "" [: :];
|
|
`HVbox [: `S LR "when"; `expr e1 "" [: `S LR "->" :] :] :] :]
|
|
| _ -> [: `patt p "" [: `S LR "->" :] :] ]
|
|
in
|
|
HVbox [: b; `HVbox [: `HVbox s; `expr e dg k :] :]
|
|
;
|
|
|
|
value rec get_expr_args a al =
|
|
match a with
|
|
[ <:expr< $a1$ $a2$ >> -> get_expr_args a1 [a2 :: al]
|
|
| _ -> (a, al) ]
|
|
;
|
|
|
|
value label lab = S LR lab;
|
|
|
|
value field_expr (lab, e) dg k =
|
|
HVbox [: `label lab; `S LR "="; `expr e dg k :]
|
|
;
|
|
|
|
value type_params sl _ k =
|
|
match sl with
|
|
[ [] -> k
|
|
| [(s, _)] -> [: `S LO "'"; `S LR s; k :]
|
|
| sl ->
|
|
[: `S LO "(";
|
|
listws (fun (s, _) _ k -> HVbox [: `S LO "'"; `S LR s; k :])
|
|
(S RO ",") sl "" [: `S RO ")"; k :] :] ]
|
|
;
|
|
|
|
value constrain (t1, t2) _ k =
|
|
HVbox [: `S LR "constraint"; `ctyp t1 "" [: `S LR "=" :]; `ctyp t2 "" k :]
|
|
;
|
|
|
|
value type_list b tdl _ k =
|
|
HVbox
|
|
[: `HVbox [: :];
|
|
listwbws
|
|
(fun b ((_, tn), tp, te, cl) _ k ->
|
|
let cstr = list constrain cl "" k in
|
|
match te with
|
|
[ <:ctyp< '$s$ >> when not (List.mem_assoc s tp) ->
|
|
HVbox [: b; type_params tp "" [: :]; `S LR tn; cstr :]
|
|
| <:ctyp< [ $list:[]$ ] >> ->
|
|
HVbox [: b; type_params tp "" [: :]; `S LR tn; cstr :]
|
|
| _ ->
|
|
HVbox
|
|
[: `HVbox
|
|
[: b; type_params tp "" [: :]; `S LR tn; `S LR "=" :];
|
|
`ctyp te "" [: :]; cstr :] ])
|
|
b (S LR "and") tdl "" [: :];
|
|
k :]
|
|
;
|
|
|
|
value external_def (s, t, pl) _ k =
|
|
let ls =
|
|
list (fun s _ k -> HVbox [: `S LR ("\"" ^ s ^ "\""); k :]) pl "" k
|
|
in
|
|
HVbox
|
|
[: `HVbox [: `S LR "external"; `S LR (var_escaped s); `S LR ":" :];
|
|
`ctyp t "" [: `S LR "="; ls :] :]
|
|
;
|
|
|
|
value value_description (s, t) _ k =
|
|
HVbox
|
|
[: `HVbox [: `S LR "val"; `S LR (var_escaped s); `S LR ":" :];
|
|
`ctyp t "" k :]
|
|
;
|
|
|
|
value rec mod_ident sl _ k =
|
|
match sl with
|
|
[ [] -> k
|
|
| [s] -> [: `S LR s; k :]
|
|
| [s :: sl] -> [: `S LR s; `S NO "."; mod_ident sl "" k :] ]
|
|
;
|
|
|
|
value rec module_type mt k =
|
|
let next = module_type1 in
|
|
match mt with
|
|
[ <:module_type< functor ( $s$ : $mt1$ ) -> $mt2$ >> ->
|
|
let head =
|
|
HVbox
|
|
[: `S LR "functor"; `S LO "("; `S LR s; `S LR ":";
|
|
`module_type mt1 [: `S RO ")" :]; `S LR "->" :]
|
|
in
|
|
HVbox [: `head; `module_type mt2 k :]
|
|
| _ -> next mt k ]
|
|
and module_type1 mt k =
|
|
let curr = module_type1 in
|
|
let next = module_type2 in
|
|
match mt with
|
|
[ <:module_type< $mt$ with $list:icl$ >> ->
|
|
HVbox [: `curr mt [: :]; `with_constraints [: `S LR "with" :] icl "" k :]
|
|
| _ -> next mt k ]
|
|
and module_type2 mt k =
|
|
let curr = module_type2 in
|
|
let next = module_type3 in
|
|
match mt with
|
|
[ <:module_type< sig $list:s$ end >> ->
|
|
BEbox
|
|
[: `S LR "sig"; `HVbox [: `HVbox [: :]; list sig_item s "" [: :] :];
|
|
`HVbox [: `S LR "end"; k :] :]
|
|
| _ -> next mt k ]
|
|
and module_type3 mt k =
|
|
let curr = module_type3 in
|
|
let next = module_type5 in
|
|
match mt with
|
|
[ <:module_type< $mt1$ $mt2$ >> ->
|
|
HVbox [: `curr mt1 [: :]; `S LO "("; `next mt2 [: `S RO ")"; k :] :]
|
|
| <:module_type< $mt1$ . $mt2$ >> ->
|
|
HVbox [: `curr mt1 [: `S NO "." :]; `next mt2 k :]
|
|
| _ -> next mt k ]
|
|
and module_type5 mt k =
|
|
match mt with
|
|
[ <:module_type< $lid:s$ >> -> HVbox [: `S LR s; k :]
|
|
| <:module_type< $uid:s$ >> -> HVbox [: `S LR s; k :]
|
|
| _ -> HVbox [: `S LO "("; `module_type mt [: `S RO ")"; k :] :] ]
|
|
and module_declaration b mt k =
|
|
match mt with
|
|
[ <:module_type< functor ( $i$ : $t$ ) -> $mt$ >> ->
|
|
module_declaration
|
|
[: b; `S LO "("; `S LR i; `S LR ":"; `module_type t [: `S RO ")" :] :]
|
|
mt k
|
|
| _ ->
|
|
HVbox
|
|
[: `HVbox [: :];
|
|
`HVbox [: `HVbox [: b; `S LR ":" :]; `module_type mt [: :] :];
|
|
k :] ]
|
|
and modtype_declaration (s, mt) _ k =
|
|
HVbox
|
|
[: `HVbox [: :];
|
|
`HVbox
|
|
[: `HVbox [: `S LR "module"; `S LR "type"; `S LR s; `S LR "=" :];
|
|
`module_type mt [: :] :];
|
|
k :]
|
|
and with_constraints b icl _ k =
|
|
HVbox [: `HVbox [: :]; listwbws with_constraint b (S LR "and") icl "" k :]
|
|
and with_constraint b wc _ k =
|
|
match wc with
|
|
[ MLast.WcTyp _ p al e ->
|
|
let params =
|
|
match al with
|
|
[ [] -> [: :]
|
|
| [s] -> [: `S LO "'"; `S LR (fst s) :]
|
|
| sl -> [: `S LO "("; type_params sl "" [: `S RO ")" :] :] ]
|
|
in
|
|
HVbox
|
|
[: `HVbox
|
|
[: `HVbox b; `S LR "type"; params;
|
|
mod_ident p "" [: `S LR "=" :] :];
|
|
`ctyp e "" k :]
|
|
| MLast.WcMod _ sl mt ->
|
|
HVbox
|
|
[: b; `S LR "module"; mod_ident sl "" [: `S LR "=" :];
|
|
`module_type mt k :] ]
|
|
and module_expr me _ k =
|
|
match me with
|
|
[ <:module_expr< struct $list:s$ end >> ->
|
|
let s = HVbox [: `S LR "struct"; list str_item s "" [: :] :] in
|
|
HVbox [: `HVbox [: :]; `s; `HVbox [: `S LR "end"; k :] :]
|
|
| <:module_expr< functor ($s$ : $mt$) -> $me$ >> ->
|
|
let head =
|
|
HVbox
|
|
[: `S LR "functor"; `S LO "("; `S LR s; `S LR ":";
|
|
`module_type mt [: `S RO ")" :]; `S LR "->" :]
|
|
in
|
|
HVbox [: `head; `module_expr me "" k :]
|
|
| _ -> module_expr1 me "" k ]
|
|
and module_expr1 me _ k =
|
|
let curr = module_expr1 in
|
|
let next = module_expr2 in
|
|
match me with
|
|
[ <:module_expr< $me1$ $me2$ >> ->
|
|
HVbox
|
|
[: `curr me1 "" [: :]; `S LO "("; `next me2 "" [: `S RO ")"; k :] :]
|
|
| _ -> next me "" k ]
|
|
and module_expr2 me _ k =
|
|
let curr = module_expr2 in
|
|
let next = module_expr3 in
|
|
match me with
|
|
[ <:module_expr< $me1$ . $me2$ >> ->
|
|
HVbox [: `curr me1 "" [: `S NO "." :]; `next me2 "" k :]
|
|
| _ -> next me "" k ]
|
|
and module_expr3 me _ k =
|
|
match me with
|
|
[ <:module_expr< $uid:s$ >> -> HVbox [: `S LR s; k :]
|
|
| <:module_expr< ( $me$ : $mt$ ) >> ->
|
|
HVbox
|
|
[: `S LO "("; `module_expr me "" [: `S LR ":" :];
|
|
`module_type mt [: `S RO ")"; k :] :]
|
|
| <:module_expr< struct $list:_$ end >> ->
|
|
HVbox [: `S LO "("; `module_expr me "" [: `S RO ")"; k :] :]
|
|
| x -> not_impl "module_expr2" x ]
|
|
and module_binding b me k =
|
|
match me with
|
|
[ <:module_expr< functor ($s$ : $mt$) -> $mb$ >> ->
|
|
module_binding
|
|
[: `HVbox
|
|
[: b; `S LO "("; `S LR s; `S LR ":";
|
|
`module_type mt [: `S RO ")" :] :] :]
|
|
mb k
|
|
| <:module_expr< ( $me$ : $mt$ ) >> ->
|
|
HVbox
|
|
[: `HVbox [: :];
|
|
`HVbox
|
|
[: `HVbox
|
|
[: `HVbox [: b; `S LR ":" :];
|
|
`module_type mt [: `S LR "=" :] :];
|
|
`module_expr me "" [: :] :];
|
|
k :]
|
|
| _ ->
|
|
HVbox
|
|
[: `HVbox [: :];
|
|
`HVbox [: `HVbox [: b; `S LR "=" :]; `module_expr me "" [: :] :];
|
|
k :] ]
|
|
and class_declaration b ci _ k =
|
|
class_fun_binding
|
|
[: b; virtual_flag ci.MLast.ciVir; class_type_parameters ci.MLast.ciPrm;
|
|
`S LR ci.MLast.ciNam :]
|
|
ci.MLast.ciExp k
|
|
and class_fun_binding b ce k =
|
|
match ce with
|
|
[ MLast.CeFun _ p cfb ->
|
|
class_fun_binding [: b; `simple_patt p "" [: :] :] cfb k
|
|
| ce -> HVbox [: `HVbox [: b; `S LR "=" :]; `class_expr ce k :] ]
|
|
and class_type_parameters (loc, tpl) =
|
|
match tpl with
|
|
[ [] -> [: :]
|
|
| tpl ->
|
|
[: `S LO "[";
|
|
listws type_parameter (S RO ",") tpl "" [: `S RO "]" :] :] ]
|
|
and type_parameter tp dg k = HVbox [: `S LO "'"; `S LR (fst tp); k :]
|
|
and class_expr ce k =
|
|
match ce with
|
|
[ MLast.CeFun _ p ce ->
|
|
HVbox
|
|
[: `S LR "fun"; `simple_patt p "" [: `S LR "->" :];
|
|
`class_expr ce k :]
|
|
| MLast.CeLet _ rf lb ce ->
|
|
HVbox
|
|
[: `HVbox [: :];
|
|
`bind_list [: `S LR "let"; rec_flag rf :] lb "" [: `S LR "in" :];
|
|
`class_expr ce k :]
|
|
| ce -> class_expr1 ce k ]
|
|
and class_expr1 ce k =
|
|
match ce with
|
|
[ MLast.CeApp _ ce e ->
|
|
HVbox [: `class_expr1 ce [: :]; `simple_expr e "" k :]
|
|
| ce -> class_expr2 ce k ]
|
|
and class_expr2 ce k =
|
|
match ce with
|
|
[ MLast.CeCon _ ci [] -> class_longident ci "" k
|
|
| MLast.CeCon _ ci ctcl ->
|
|
HVbox
|
|
[: `S LO "["; listws ctyp (S RO ",") ctcl "" [: `S RO "]" :];
|
|
`class_longident ci "" k :]
|
|
| MLast.CeStr _ csp cf ->
|
|
class_structure [: `S LR "object"; `class_self_patt_opt csp :] cf
|
|
[: `S LR "end"; k :]
|
|
| MLast.CeTyc _ ce ct ->
|
|
HVbox
|
|
[: `S LO "("; `class_expr ce [: `S LR ":" :];
|
|
`class_type ct [: `S RO ")"; k :] :]
|
|
| MLast.CeFun _ _ _ ->
|
|
HVbox [: `S LO "("; `class_expr ce [: `S RO ")"; k :] :]
|
|
| _ -> HVbox [: `not_impl "class_expr" ce; k :] ]
|
|
and class_structure b cf k =
|
|
BEbox
|
|
[: `HVbox b; `HVbox [: `HVbox [: :]; list class_str_item cf "" [: :] :];
|
|
`HVbox k :]
|
|
and class_self_patt_opt csp =
|
|
match csp with
|
|
[ Some p -> HVbox [: `S LO "("; `patt p "" [: `S RO ")" :] :]
|
|
| None -> HVbox [: :] ]
|
|
and class_str_item cf dg k =
|
|
match cf with
|
|
[ MLast.CrDcl _ s ->
|
|
HVbox [: `HVbox [: :]; list class_str_item s "" [: :] :]
|
|
| MLast.CrInh _ ce pb ->
|
|
HVbox
|
|
[: `S LR "inherit"; `class_expr ce [: :];
|
|
match pb with
|
|
[ Some i -> [: `S LR "as"; `S LR i :]
|
|
| _ -> [: :] ];
|
|
k :]
|
|
| MLast.CrVal _ lab mf e -> HVbox [: `S LR "val"; `cvalue (lab, mf, e) k :]
|
|
| MLast.CrVir _ lab pf t ->
|
|
HVbox
|
|
[: `S LR "method"; `S LR "virtual"; private_flag pf; `label lab;
|
|
`S LR ":"; `ctyp t "" k :]
|
|
| MLast.CrMth _ lab pf fb ->
|
|
fun_binding [: `S LR "method"; private_flag pf; `label lab :] fb k
|
|
| MLast.CrCtr _ t1 t2 ->
|
|
HVbox
|
|
[: `HVbox [: `S LR "constraint"; `ctyp t1 "" [: `S LR "=" :] :];
|
|
`ctyp t2 "" k :]
|
|
| MLast.CrIni _ se -> HVbox [: `S LR "initializer"; `expr se "" k :] ]
|
|
and cvalue (lab, mf, e) k =
|
|
HVbox [: mutable_flag mf; `label lab; `S LR "="; `expr e "" k :]
|
|
and fun_binding b fb k =
|
|
match fb with
|
|
[ <:expr< fun $p$ -> $e$ >> ->
|
|
fun_binding [: b; `simple_patt p "" [: :] :] e k
|
|
| e -> HVbox [: `HVbox [: b; `S LR "=" :]; `expr e "" k :] ]
|
|
and class_type ct k =
|
|
match ct with
|
|
[ MLast.CtFun _ t ct ->
|
|
HVbox [: `ctyp t "" [: `S LR "->" :]; `class_type ct k :]
|
|
| _ -> class_signature ct k ]
|
|
and class_signature cs k =
|
|
match cs with
|
|
[ MLast.CtCon _ id [] -> clty_longident id "" k
|
|
| MLast.CtCon _ id tl ->
|
|
HVbox
|
|
[: `S LO "["; listws ctyp (S RO ",") tl "" [: `S RO "]" :];
|
|
`clty_longident id "" k :]
|
|
| MLast.CtSig _ cst csf ->
|
|
class_self_type [: `S LR "object" :] cst
|
|
[: `HVbox [: `HVbox [: :]; list class_sig_item csf "" [: :] :];
|
|
`HVbox [: `S LR "end"; k :] :]
|
|
| _ -> HVbox [: `not_impl "class_signature" cs; k :] ]
|
|
and class_self_type b cst k =
|
|
BEbox
|
|
[: `HVbox
|
|
[: b;
|
|
match cst with
|
|
[ None -> [: :]
|
|
| Some t -> [: `S LO "("; `ctyp t "" [: `S RO ")" :] :] ] :];
|
|
k :]
|
|
and class_sig_item csf dg k =
|
|
match csf with
|
|
[ MLast.CgCtr _ t1 t2 ->
|
|
HVbox
|
|
[: `S LR "constraint"; `ctyp t1 "" [: `S LR "=" :]; `ctyp t2 "" k :]
|
|
| MLast.CgDcl _ s ->
|
|
HVbox [: `HVbox [: :]; list class_sig_item s "" [: :] :]
|
|
| MLast.CgMth _ lab pf t ->
|
|
HVbox
|
|
[: `S LR "method"; private_flag pf; `label lab; `S LR ":";
|
|
`ctyp t "" k :]
|
|
| MLast.CgVal _ lab mf t ->
|
|
HVbox
|
|
[: `S LR "val"; mutable_flag mf; `label lab; `S LR ":";
|
|
`ctyp t "" k :]
|
|
| _ -> HVbox [: `not_impl "class_sig_item" csf; k :] ]
|
|
and class_description b ci _ k =
|
|
HVbox
|
|
[: `HVbox
|
|
[: b; virtual_flag ci.MLast.ciVir;
|
|
class_type_parameters ci.MLast.ciPrm; `S LR ci.MLast.ciNam;
|
|
`S LR ":" :];
|
|
`class_type ci.MLast.ciExp k :]
|
|
and class_type_declaration b ci _ k =
|
|
HVbox
|
|
[: `HVbox
|
|
[: b; virtual_flag ci.MLast.ciVir;
|
|
class_type_parameters ci.MLast.ciPrm; `S LR ci.MLast.ciNam;
|
|
`S LR "=" :];
|
|
`class_signature ci.MLast.ciExp k :]
|
|
;
|
|
|
|
pr_sig_item.pr_levels :=
|
|
[{pr_label = "top"; pr_box _ x = HVbox x;
|
|
pr_rules =
|
|
extfun Extfun.empty with
|
|
[ <:sig_item< type $list:stl$ >> ->
|
|
fun curr next dg k -> [: `type_list [: `S LR "type" :] stl "" k :]
|
|
| <:sig_item< declare $list:s$ end >> ->
|
|
fun curr next dg k -> [: `HVbox [: :]; list sig_item s "" [: :] :]
|
|
| MLast.SgDir _ _ _ as si ->
|
|
fun curr next dg k -> [: `not_impl "sig_item" si :]
|
|
| <:sig_item< exception $c$ of $list:tl$ >> ->
|
|
fun curr next dg k ->
|
|
[: `variant 0 [: `S LR "exception" :] (loc, c, tl) "" k :]
|
|
| <:sig_item< value $s$ : $t$ >> ->
|
|
fun curr next dg k -> [: `value_description (s, t) "" k :]
|
|
| <:sig_item< external $s$ : $t$ = $list:pl$ >> ->
|
|
fun curr next dg k -> [: `external_def (s, t, pl) "" k :]
|
|
| <:sig_item< include $mt$ >> ->
|
|
fun curr next dg k -> [: `S LR "include"; `module_type mt k :]
|
|
| <:sig_item< module $s$ : $mt$ >> ->
|
|
fun curr next dg k ->
|
|
[: `module_declaration [: `S LR "module"; `S LR s :] mt k :]
|
|
| <:sig_item< module type $s$ = $mt$ >> ->
|
|
fun curr next dg k -> [: `modtype_declaration (s, mt) "" k :]
|
|
| <:sig_item< open $sl$ >> ->
|
|
fun curr next dg k -> [: `S LR "open"; mod_ident sl "" k :]
|
|
| MLast.SgCls _ cd ->
|
|
fun curr next dg k ->
|
|
[: `HVbox [: :];
|
|
listwbws class_description [: `S LR "class" :] (S LR "and") cd
|
|
"" k :]
|
|
| MLast.SgClt _ cd ->
|
|
fun curr next dg k ->
|
|
[: `HVbox [: :];
|
|
listwbws class_type_declaration
|
|
[: `S LR "class"; `S LR "type" :] (S LR "and") cd ""
|
|
k :] ]}];
|
|
|
|
pr_str_item.pr_levels :=
|
|
[{pr_label = "top"; pr_box _ x = HVbox x;
|
|
pr_rules =
|
|
extfun Extfun.empty with
|
|
[ <:str_item< open $i$ >> ->
|
|
fun curr next dg k -> [: `S LR "open"; mod_ident i "" k :]
|
|
| <:str_item< $exp:e$ >> ->
|
|
fun curr next dg k ->
|
|
if no_ss.val then
|
|
[: `HVbox [: `S LR "let"; `S LR "_"; `S LR "=" :];
|
|
`expr e "" k :]
|
|
else [: `HVbox [: :]; `expr e "" k :]
|
|
| <:str_item< declare $list:s$ end >> ->
|
|
fun curr next dg k -> [: `HVbox [: :]; list str_item s "" [: :] :]
|
|
| <:str_item< # $s$ $opt:x$ >> ->
|
|
fun curr next dg k ->
|
|
let s =
|
|
"(* #" ^ s ^ " " ^
|
|
(match x with
|
|
[ Some <:expr< $str:s$ >> -> "\"" ^ s ^ "\""
|
|
| _ -> "?" ]) ^
|
|
" *)"
|
|
in
|
|
[: `S LR s :]
|
|
| <:str_item< exception $c$ of $list:tl$ = $b$ >> ->
|
|
fun curr next dg k ->
|
|
match b with
|
|
[ [] -> [: `variant 0 [: `S LR "exception" :] (loc, c, tl) "" k :]
|
|
| _ ->
|
|
[: `variant 0 [: `S LR "exception" :] (loc, c, tl) ""
|
|
[: `S LR "=" :];
|
|
mod_ident b "" k :] ]
|
|
| <:str_item< include $me$ >> ->
|
|
fun curr next dg k -> [: `S LR "include"; `module_expr me "" k :]
|
|
| <:str_item< type $list:tdl$ >> ->
|
|
fun curr next dg k -> [: `type_list [: `S LR "type" :] tdl "" k :]
|
|
| <:str_item< value $rec:rf$ $list:pel$ >> ->
|
|
fun curr next dg k ->
|
|
[: `bind_list
|
|
[: `S LR "let"; if rf then [: `S LR "rec" :] else [: :] :]
|
|
pel "" k :]
|
|
| <:str_item< external $s$ : $t$ = $list:pl$ >> ->
|
|
fun curr next dg k -> [: `external_def (s, t, pl) "" k :]
|
|
| <:str_item< module $s$ = $me$ >> ->
|
|
fun curr next dg k ->
|
|
[: `module_binding [: `S LR "module"; `S LR s :] me k :]
|
|
| <:str_item< module type $s$ = $mt$ >> ->
|
|
fun curr next dg k ->
|
|
[: `HVbox [: :];
|
|
`HVbox
|
|
[: `HVbox
|
|
[: `S LR "module"; `S LR "type"; `S LR s;
|
|
`S LR "=" :];
|
|
`module_type mt [: :] :];
|
|
k :]
|
|
| MLast.StCls _ cd ->
|
|
fun curr next dg k ->
|
|
[: `HVbox [: :];
|
|
listwbws class_declaration [: `S LR "class" :] (S LR "and") cd
|
|
"" k :]
|
|
| MLast.StClt _ cd ->
|
|
fun curr next dg k ->
|
|
[: `HVbox [: :];
|
|
listwbws class_type_declaration
|
|
[: `S LR "class"; `S LR "type" :] (S LR "and") cd ""
|
|
k :] ]}];
|
|
|
|
pr_expr.pr_levels :=
|
|
[{pr_label = "top"; pr_box _ x = HOVbox x;
|
|
pr_rules =
|
|
extfun Extfun.empty with
|
|
[ <:expr< do { $list:el$ } >> ->
|
|
fun curr next dg k ->
|
|
[: `HVbox [: `HVbox [: :]; listws next (S RO ";") el dg k :] :]
|
|
| e -> fun curr next dg k -> [: `next e dg k :] ]};
|
|
{pr_label = "expr1"; pr_box _ x = HOVbox x;
|
|
pr_rules =
|
|
extfun Extfun.empty with
|
|
[ <:expr< let $rec:r$ $p1$ = $e1$ in $e$ >> ->
|
|
fun curr next dg k ->
|
|
let r = if r then [: `S LR "rec" :] else [: :] in
|
|
if dg <> ";" then
|
|
[: `HVbox
|
|
[: `HVbox [: :];
|
|
`let_binding [: `S LR "let"; r :] (p1, e1) ""
|
|
[: `S LR "in" :];
|
|
`expr e dg k :] :]
|
|
else
|
|
let pel = [(p1, e1)] in
|
|
[: `BEbox
|
|
[: `S LR "begin";
|
|
`HVbox
|
|
[: `HVbox [: :];
|
|
listwbws
|
|
(fun b (p, e) _ k -> let_binding b (p, e) "" k)
|
|
[: `S LR "let"; r :] (S LR "and") pel ""
|
|
[: `S LR "in" :];
|
|
`expr e "" [: :] :];
|
|
`HVbox [: `S LR "end"; k :] :] :]
|
|
| <:expr< let $rec:r$ $list:pel$ in $e$ >> ->
|
|
fun curr next dg k ->
|
|
let r = if r then [: `S LR "rec" :] else [: :] in
|
|
if dg <> ";" then
|
|
[: `Vbox
|
|
[: `HVbox [: :];
|
|
listwbws
|
|
(fun b (p, e) _ k -> let_binding b (p, e) "" k)
|
|
[: `S LR "let"; r :] (S LR "and") pel ""
|
|
[: `S LR "in" :];
|
|
`expr e dg k :] :]
|
|
else
|
|
[: `BEbox
|
|
[: `S LR "begin";
|
|
`HVbox
|
|
[: `HVbox [: :];
|
|
listwbws
|
|
(fun b (p, e) _ k -> let_binding b (p, e) "" k)
|
|
[: `S LR "let"; r :] (S LR "and") pel ""
|
|
[: `S LR "in" :];
|
|
`expr e "" [: :] :];
|
|
`HVbox [: `S LR "end"; k :] :] :]
|
|
| <:expr< let module $m$ = $mb$ in $e$ >> ->
|
|
fun curr next dg k ->
|
|
if dg <> ";" then
|
|
[: `HVbox
|
|
[: `HVbox [: :];
|
|
`module_binding
|
|
[: `S LR "let"; `S LR "module"; `S LR m :] mb [: :];
|
|
`S LR "in"; `expr e dg k :] :]
|
|
else
|
|
[: `BEbox
|
|
[: `module_binding
|
|
[: `S LR "begin let"; `S LR "module"; `S LR m :] mb
|
|
[: :];
|
|
`HVbox
|
|
[: `HVbox [: :]; `S LR "in"; `expr e dg [: :] :];
|
|
`HVbox [: `S LR "end"; k :] :] :]
|
|
| <:expr< fun [ $list:pel$ ] >> as e ->
|
|
fun curr next dg k ->
|
|
let loc = MLast.loc_of_expr e in
|
|
if not (List.mem dg ["|"; ";"]) then
|
|
match pel with
|
|
[ [] ->
|
|
[: `S LR "fun"; `S LR "_"; `S LR "->";
|
|
`raise_match_failure loc k :]
|
|
| [(p, None, e)] ->
|
|
let (pl, e) = expr_fun_args e in
|
|
[: `BEbox
|
|
[: `HOVbox
|
|
[: `S LR "fun";
|
|
list simple_patt [p :: pl] ""
|
|
[: `S LR "->" :] :];
|
|
`expr e "" k :] :]
|
|
| _ ->
|
|
[: `Vbox
|
|
[: `HVbox [: :]; `S LR "function";
|
|
`match_assoc_list loc pel "" k :] :] ]
|
|
else
|
|
match pel with
|
|
[ [] ->
|
|
[: `S LR "(fun"; `S LR "_"; `S LR "->";
|
|
`raise_match_failure loc [: `S RO ")"; k :] :]
|
|
| [(p, None, e)] ->
|
|
if is_irrefut_patt p then
|
|
let (pl, e) = expr_fun_args e in
|
|
[: `S LO "(";
|
|
`BEbox
|
|
[: `HOVbox
|
|
[: `S LR "fun";
|
|
list simple_patt [p :: pl] ""
|
|
[: `S LR "->" :] :];
|
|
`expr e "" [: `S RO ")"; k :] :] :]
|
|
else
|
|
[: `HVbox
|
|
[: `S LR "fun ["; `patt p "" [: `S LR "->" :] :];
|
|
`expr e "" [: `S LR "]"; k :] :]
|
|
| _ ->
|
|
[: `Vbox
|
|
[: `HVbox [: :]; `S LR "begin function";
|
|
`match_assoc_list loc pel "" k;
|
|
`HVbox [: `S LR "end"; k :] :] :] ]
|
|
| <:expr< match $e$ with [ $list:pel$ ] >> as ge ->
|
|
fun curr next dg k ->
|
|
let loc = MLast.loc_of_expr ge in
|
|
if not (List.mem dg ["|"; ";"]) then
|
|
[: `HVbox
|
|
[: `HVbox [: :];
|
|
`BEbox
|
|
[: `S LR "match"; `expr e "" [: :]; `S LR "with" :];
|
|
`match_assoc_list loc pel "" k :] :]
|
|
else
|
|
[: `HVbox
|
|
[: `HVbox [: :];
|
|
`BEbox
|
|
[: `S LR "begin match"; `expr e "" [: :];
|
|
`S LR "with" :];
|
|
`match_assoc_list loc pel "" [: :];
|
|
`HVbox [: `S LR "end"; k :] :] :]
|
|
| <:expr< try $e$ with [ $list:pel$ ] >> as ge ->
|
|
fun curr next dg k ->
|
|
let loc = MLast.loc_of_expr ge in
|
|
if not (List.mem dg ["|"; ";"]) then
|
|
[: `HVbox
|
|
[: `HVbox [: :];
|
|
`BEbox
|
|
[: `S LR "try"; `expr e "" [: :]; `S LR "with" :];
|
|
`match_assoc_list loc pel "" k :] :]
|
|
else
|
|
[: `HVbox
|
|
[: `HVbox [: :];
|
|
`BEbox
|
|
[: `S LR "begin try"; `expr e "" [: :];
|
|
`S LR "with" :];
|
|
`match_assoc_list loc pel "" [: :];
|
|
`HVbox [: `S LR "end"; k :] :] :]
|
|
| <:expr< if $_$ then () else raise (Assert_failure $_$) >> as e ->
|
|
fun curr next dg k -> [: `next e dg k :]
|
|
| <:expr< if $e1$ then $e2$ else $e3$ >> as e ->
|
|
fun curr next dg k ->
|
|
let eel_e =
|
|
elseif e3 where rec elseif e =
|
|
match e with
|
|
[ <:expr< if $e1$ then $e2$ else $e3$ >> ->
|
|
let (eel, e) = elseif e3 in
|
|
([(e1, e2) :: eel], e)
|
|
| _ -> ([], e) ]
|
|
in
|
|
if not (List.mem dg ["else"]) then
|
|
match eel_e with
|
|
[ ([], <:expr< () >>) ->
|
|
[: `HOVbox [: `S LR "if"; `expr e1 "" [: `S LR "then" :] :];
|
|
`expr1 e2 dg k :]
|
|
| (eel, <:expr< () >>) ->
|
|
let (eel, (e1f, e2f)) =
|
|
let r = List.rev eel in
|
|
(List.rev (List.tl r), List.hd r)
|
|
in
|
|
[: `HVbox
|
|
[: `HVbox [: :];
|
|
`HVbox
|
|
[: `HOVbox
|
|
[: `S LR "if";
|
|
`expr e1 "" [: `S LR "then" :] :];
|
|
`expr1 e2 "else" [: :] :];
|
|
list
|
|
(fun (e1, e2) _ k ->
|
|
HVbox
|
|
[: `HOVbox
|
|
[: `S LR "else"; `S LR "if";
|
|
`expr e1 "" [: `S LR "then" :] :];
|
|
`expr1 e2 "else" k :])
|
|
eel "" [: :];
|
|
`HVbox
|
|
[: `HOVbox
|
|
[: `S LR "else"; `S LR "if";
|
|
`expr e1f "" [: `S LR "then" :] :];
|
|
`expr1 e2f dg k :] :] :]
|
|
| (eel, e) ->
|
|
[: `HVbox
|
|
[: `HVbox [: :];
|
|
`HVbox
|
|
[: `HOVbox
|
|
[: `S LR "if";
|
|
`expr e1 "" [: `S LR "then" :] :];
|
|
`expr1 e2 "else" [: :] :];
|
|
list
|
|
(fun (e1, e2) _ k ->
|
|
HVbox
|
|
[: `HOVbox
|
|
[: `S LR "else"; `S LR "if";
|
|
`expr e1 "" [: `S LR "then" :] :];
|
|
`expr1 e2 "else" k :])
|
|
eel "" [: :];
|
|
`HVbox [: `S LR "else"; `expr1 e dg k :] :] :] ]
|
|
else
|
|
match eel_e with
|
|
[ (_, <:expr< () >>) -> [: `next e "" k :]
|
|
| (eel, e) ->
|
|
[: `HVbox
|
|
[: `HVbox [: :];
|
|
`HVbox
|
|
[: `HOVbox
|
|
[: `S LR "if";
|
|
`expr e1 "" [: `S LR "then" :] :];
|
|
`expr1 e2 "" [: :] :];
|
|
list
|
|
(fun (e1, e2) _ k ->
|
|
HVbox
|
|
[: `HOVbox
|
|
[: `S LR "else"; `S LR "if";
|
|
`expr e1 "" [: `S LR "then" :] :];
|
|
`expr1 e2 "" [: :] :])
|
|
eel "" [: :];
|
|
`HVbox [: `S LR "else"; `expr1 e "" k :] :] :] ]
|
|
| <:expr< for $i$ = $e1$ $to:d$ $e2$ do { $list:el$ } >> ->
|
|
fun curr next dg k ->
|
|
let d = if d then "to" else "downto" in
|
|
[: `BEbox
|
|
[: `HOVbox
|
|
[: `S LR "for"; `S LR i; `S LR "=";
|
|
`expr e1 "" [: `S LR d :];
|
|
`expr e2 "" [: `S LR "do" :] :];
|
|
`HVbox
|
|
[: `HVbox [: :];
|
|
listws expr (S RO ";") el "" [: :] :];
|
|
`HVbox [: `S LR "done"; k :] :] :]
|
|
| <:expr< while $e1$ do { $list:el$ } >> ->
|
|
fun curr next dg k ->
|
|
[: `BEbox
|
|
[: `BEbox
|
|
[: `S LR "while"; `expr e1 "" [: :]; `S LR "do" :];
|
|
`HVbox
|
|
[: `HVbox [: :];
|
|
listws expr (S RO ";") el "" [: :] :];
|
|
`HVbox [: `S LR "done"; k :] :] :]
|
|
| e -> fun curr next dg k -> [: `next e dg k :] ]};
|
|
{pr_label = ""; pr_box _ x = HOVbox x;
|
|
pr_rules =
|
|
extfun Extfun.empty with
|
|
[ <:expr< ($list:el$) >> ->
|
|
fun curr next dg k ->
|
|
[: `HVbox [: :]; listws next (S RO ",") el "" k :]
|
|
| e -> fun curr next dg k -> [: `next e dg k :] ]};
|
|
{pr_label = ""; pr_box _ x = HOVbox x;
|
|
pr_rules =
|
|
extfun Extfun.empty with
|
|
[ <:expr< $x$.val := $y$ >> ->
|
|
fun curr next dg k ->
|
|
[: `next x "" [: `S LR ":=" :]; `expr y dg k :]
|
|
| <:expr< $x$ := $y$ >> ->
|
|
fun curr next dg k ->
|
|
[: `next x "" [: `S LR "<-" :]; `expr y dg k :]
|
|
| e -> fun curr next dg k -> [: `next e "" k :] ]};
|
|
{pr_label = ""; pr_box _ x = HOVbox [: `HVbox [: :]; x :];
|
|
pr_rules =
|
|
extfun Extfun.empty with
|
|
[ <:expr< $lid:("||" as f)$ $x$ $y$ >> ->
|
|
fun curr next dg k -> [: `next x "" [: `S LR f :]; curr y "" k :]
|
|
| <:expr< $lid:("or" as f)$ $x$ $y$ >> ->
|
|
fun curr next dg k -> [: `next x "" [: `S LR f :]; curr y "" k :]
|
|
| e -> fun curr next dg k -> [: `next e dg k :] ]};
|
|
{pr_label = ""; pr_box _ x = HOVbox [: `HVbox [: :]; x :];
|
|
pr_rules =
|
|
extfun Extfun.empty with
|
|
[ <:expr< $lid:(("&&") as f)$ $x$ $y$ >> ->
|
|
fun curr next dg k -> [: `next x "" [: `S LR f :]; curr y "" k :]
|
|
| <:expr< $lid:(("&") as f)$ $x$ $y$ >> ->
|
|
fun curr next dg k -> [: `next x "" [: `S LR f :]; curr y "" k :]
|
|
| e -> fun curr next dg k -> [: `next e dg k :] ]};
|
|
{pr_label = ""; pr_box _ x = HOVbox x;
|
|
pr_rules =
|
|
extfun Extfun.empty with
|
|
[ <:expr< $lid:op$ $x$ $y$ >> as e ->
|
|
fun curr next dg k ->
|
|
match op with
|
|
[ "=" | "<>" | "<" | "<." | "<=" | ">" | ">=" | "==" | "!=" ->
|
|
[: curr x "" [: `S LR op :]; `next y "" k :]
|
|
| _ -> [: `next e "" k :] ]
|
|
| e -> fun curr next dg k -> [: `next e dg k :] ]};
|
|
{pr_label = ""; pr_box _ x = HOVbox x;
|
|
pr_rules =
|
|
extfun Extfun.empty with
|
|
[ <:expr< $lid:op$ $x$ $y$ >> as e ->
|
|
fun curr next dg k ->
|
|
match op with
|
|
[ "^" | "@" -> [: `next x "" [: `S LR op :]; curr y "" k :]
|
|
| _ -> [: `next e "" k :] ]
|
|
| e -> fun curr next dg k -> [: `next e dg k :] ]};
|
|
{pr_label = ""; pr_box _ x = HOVbox x;
|
|
pr_rules =
|
|
extfun Extfun.empty with
|
|
[ <:expr< [$_$ :: $_$] >> as e ->
|
|
fun curr next dg k ->
|
|
let (el, c) =
|
|
make_list e where rec make_list e =
|
|
match e with
|
|
[ <:expr< [$e$ :: $y$] >> ->
|
|
let (el, c) = make_list y in
|
|
([e :: el], c)
|
|
| <:expr< [] >> -> ([], None)
|
|
| x -> ([], Some e) ]
|
|
in
|
|
match c with
|
|
[ None -> [: `next e "" k :]
|
|
| Some x ->
|
|
[: listws next (S LR "::") el "" [: `S LR "::" :];
|
|
`next x "" k :] ]
|
|
| e -> fun curr next dg k -> [: `next e dg k :] ]};
|
|
{pr_label = ""; pr_box _ x = HOVbox x;
|
|
pr_rules =
|
|
extfun Extfun.empty with
|
|
[ <:expr< $lid:op$ $x$ $y$ >> as e ->
|
|
fun curr next dg k ->
|
|
match op with
|
|
[ "+" | "+." | "-" | "-." ->
|
|
[: curr x "" [: `S LR op :]; `next y "" k :]
|
|
| _ -> [: `next e "" k :] ]
|
|
| e -> fun curr next dg k -> [: `next e dg k :] ]};
|
|
{pr_label = ""; pr_box _ x = HOVbox x;
|
|
pr_rules =
|
|
extfun Extfun.empty with
|
|
[ <:expr< $lid:op$ $x$ $y$ >> as e ->
|
|
fun curr next dg k ->
|
|
match op with
|
|
[ "*" | "/" | "*." | "/." | "land" | "lor" | "lxor" | "mod" ->
|
|
[: curr x "" [: `S LR op :]; `next y "" k :]
|
|
| _ -> [: `next e "" k :] ]
|
|
| e -> fun curr next dg k -> [: `next e dg k :] ]};
|
|
{pr_label = ""; pr_box _ x = HOVbox x;
|
|
pr_rules =
|
|
extfun Extfun.empty with
|
|
[ <:expr< $lid:op$ $x$ $y$ >> as e ->
|
|
fun curr next dg k ->
|
|
match op with
|
|
[ "**" | "asr" | "lsl" | "lsr" ->
|
|
[: `next x "" [: `S LR op :]; curr y "" k :]
|
|
| _ -> [: `next e "" k :] ]
|
|
| e -> fun curr next dg k -> [: `next e dg k :] ]};
|
|
{pr_label = ""; pr_box _ x = HOVbox x;
|
|
pr_rules =
|
|
extfun Extfun.empty with
|
|
[ <:expr< $lid:"~-"$ $x$ >> ->
|
|
fun curr next dg k -> [: `S LR "-"; curr x "" k :]
|
|
| <:expr< $lid:"~-."$ $x$ >> ->
|
|
fun curr next dg k -> [: `S LR "-."; curr x "" k :]
|
|
| e -> fun curr next dg k -> [: `next e dg k :] ]};
|
|
{pr_label = ""; pr_box _ x = HOVbox x;
|
|
pr_rules =
|
|
extfun Extfun.empty with
|
|
[ <:expr< $int:x$ >> -> fun curr next dg k -> [: `S LR x; k :]
|
|
| <:expr< $flo:x$ >> -> fun curr next dg k -> [: `S LR x; k :]
|
|
| e -> fun curr next dg k -> [: `next e dg k :] ]};
|
|
{pr_label = "apply"; pr_box _ x = HOVbox x;
|
|
pr_rules =
|
|
extfun Extfun.empty with
|
|
[ <:expr< [$_$ :: $_$] >> as e ->
|
|
fun curr next dg k -> [: `next e "" k :]
|
|
| <:expr< Pervasives.ref (Lazy.Delayed (fun () -> $x$)) >> ->
|
|
fun curr next dg k -> [: `S LR "lazy"; `next x "" k :]
|
|
| <:expr< if $e$ then () else raise (Assert_failure $_$) >> ->
|
|
fun curr next dg k -> [: `S LR "assert"; `next e "" k :]
|
|
| <:expr< raise (Assert_failure $_$) >> ->
|
|
fun curr next dg k -> [: `S LR "assert"; `S LR "false"; k :]
|
|
| <:expr< $lid:n$ $x$ $y$ >> as e ->
|
|
fun curr next dg k ->
|
|
let loc = MLast.loc_of_expr e in
|
|
if is_infix n then [: `next e "" k :]
|
|
else [: curr <:expr< $lid:n$ $x$ >> "" [: :]; `next y "" k :]
|
|
| <:expr< $x$ $y$ >> ->
|
|
fun curr next dg k ->
|
|
match get_expr_args x [y] with
|
|
[ (_, [_]) -> [: curr x "" [: :]; `next y "" k :]
|
|
| ((<:expr< $uid:_$ >> | <:expr< $_$ . $uid:_$ >> as a), al) ->
|
|
[: curr a "" [: :];
|
|
`HOVbox
|
|
[: `S LO "(";
|
|
listws (fun x _ k -> HOVbox [: curr x "" k :])
|
|
(S RO ",") al "" [: `S RO ")"; k :] :] :]
|
|
| _ -> [: curr x "" [: :]; `next y "" k :] ]
|
|
| MLast.ExNew _ sl ->
|
|
fun curr next dg k -> [: `S LR "new"; `class_longident sl "" k :]
|
|
| e -> fun curr next dg k -> [: `next e dg k :] ]};
|
|
{pr_label = "dot"; pr_box _ x = HOVbox x;
|
|
pr_rules =
|
|
extfun Extfun.empty with
|
|
[ <:expr< $x$ . ( $y$ ) >> ->
|
|
fun curr next dg k ->
|
|
[: curr x "" [: :]; `S NO ".("; `expr y "" [: `S RO ")"; k :] :]
|
|
| <:expr< $x$ . [ $y$ ] >> ->
|
|
fun curr next dg k ->
|
|
[: curr x "" [: :]; `S NO ".["; `expr y "" [: `S RO "]"; k :] :]
|
|
| <:expr< $e$. val >> ->
|
|
fun curr next dg k -> [: `S LO "!"; `next e "" k :]
|
|
| <:expr< $e1$ . $e2$ >> ->
|
|
fun curr next dg k ->
|
|
[: curr e1 "" [: :]; `S NO "."; curr e2 "" k :]
|
|
| e -> fun curr next dg k -> [: `next e "" k :] ]};
|
|
{pr_label = ""; pr_box _ x = HOVbox x;
|
|
pr_rules =
|
|
extfun Extfun.empty with
|
|
[ <:expr< [$_$ :: $_$] >> as e ->
|
|
fun curr next dg k ->
|
|
let (el, c) =
|
|
make_list e where rec make_list e =
|
|
match e with
|
|
[ <:expr< [$e$ :: $y$] >> ->
|
|
let (el, c) = make_list y in
|
|
([e :: el], c)
|
|
| <:expr< [] >> -> ([], None)
|
|
| x -> ([], Some e) ]
|
|
in
|
|
match c with
|
|
[ None ->
|
|
[: `S LO "[";
|
|
listws expr (S RO ";") el "" [: `S RO "]"; k :] :]
|
|
| Some x -> [: `next e "" k :] ]
|
|
| e -> fun curr next dg k -> [: `next e dg k :] ]};
|
|
{pr_label = "simple"; pr_box _ x = HOVbox x;
|
|
pr_rules =
|
|
extfun Extfun.empty with
|
|
[ <:expr< $int:x$ >> ->
|
|
fun curr next dg k ->
|
|
if x.[0] = '-' then [: `S LO "("; `S LR x; `S RO ")"; k :]
|
|
else [: `S LR x; k :]
|
|
| <:expr< $flo:x$ >> ->
|
|
fun curr next dg k ->
|
|
if x.[0] = '-' then [: `S LO "("; `S LR x; `S RO ")"; k :]
|
|
else [: `S LR x; k :]
|
|
| <:expr< $str:s$ >> ->
|
|
fun curr next dg k -> [: `S LR ("\"" ^ s ^ "\""); k :]
|
|
| <:expr< $chr:c$ >> ->
|
|
fun curr next dg k ->
|
|
let c = if c = "'" then "\'" else c in
|
|
[: `S LR ("'" ^ c ^ "'"); k :]
|
|
| <:expr< $uid:s$ >> ->
|
|
fun curr next dg k -> [: `S LR (conv_con s); k :]
|
|
| <:expr< $lid:s$ >> ->
|
|
fun curr next dg k -> [: `S LR (var_escaped s); k :]
|
|
| <:expr< $e$ # $lab$ >> ->
|
|
fun curr next dg k ->
|
|
[: curr e "" [: :]; `S NO "#"; `label lab; k :]
|
|
| <:expr< ` $i$ >> -> fun curr next dg k -> [: `S LR ("`" ^ i); k :]
|
|
| <:expr< ~ $i$ : $lid:j$ >> when i = j ->
|
|
fun curr next dg k -> [: `S LR ("~" ^ i); k :]
|
|
| <:expr< ~ $i$ : $e$ >> ->
|
|
fun curr next dg k -> [: `S LO ("~" ^ i ^ ":"); curr e "" k :]
|
|
| <:expr< ? $i$ : $lid:j$ >> when i = j ->
|
|
fun curr next dg k -> [: `S LR ("?" ^ i); k :]
|
|
| <:expr< ? $i$ : $e$ >> ->
|
|
fun curr next dg k -> [: `S LO ("?" ^ i ^ ":"); curr e "" k :]
|
|
| <:expr< [| $list:el$ |] >> ->
|
|
fun curr next dg k ->
|
|
[: `S LR "[|"; listws expr (S RO ";") el "" [: `S LR "|]"; k :] :]
|
|
| <:expr< { $list:fel$ } >> ->
|
|
fun curr next dg k ->
|
|
[: `S LO "{";
|
|
listws
|
|
(fun (lab, e) dg k ->
|
|
HVbox [: `patt lab "" [: `S LR "=" :]; `expr1 e dg k :])
|
|
(S RO ";") fel "" [: `S RO "}"; k :] :]
|
|
| <:expr< { ($e$) with $list:fel$ } >> ->
|
|
fun curr next dg k ->
|
|
[: `HVbox [: `S LO "{"; curr e "" [: `S LR "with" :] :];
|
|
listws
|
|
(fun (lab, e) dg k ->
|
|
HVbox [: `patt lab "" [: `S LR "=" :]; `expr1 e dg k :])
|
|
(S RO ";") fel "" [: `S RO "}"; k :] :]
|
|
| <:expr< ($e$ : $t$) >> ->
|
|
fun curr next dg k ->
|
|
[: `S LO "("; `expr e "" [: `S LR ":" :];
|
|
`ctyp t "" [: `S RO ")"; k :] :]
|
|
| <:expr< ($e$ : $t1$ :> $t2$) >> ->
|
|
fun curr next dg k ->
|
|
[: `S LO "("; `expr e "" [: `S LR ":" :];
|
|
`ctyp t1 "" [: `S LR ":>" :]; `ctyp t2 "" [: `S RO ")"; k :] :]
|
|
| <:expr< ($e$ :> $t2$) >> ->
|
|
fun curr next dg k ->
|
|
[: `S LO "("; `expr e "" [: `S LR ":>" :];
|
|
`ctyp t2 "" [: `S RO ")"; k :] :]
|
|
| MLast.ExOvr _ [] -> fun curr next dg k -> [: `S LR "{< >}"; k :]
|
|
| MLast.ExOvr _ fel ->
|
|
fun curr next dg k ->
|
|
[: `S LR "{<";
|
|
listws field_expr (S RO ";") fel dg [: `S LR ">}"; k :] :]
|
|
| <:expr< do { $list:el$ } >> ->
|
|
fun curr next dg k ->
|
|
match el with
|
|
[ [e] -> curr e dg k
|
|
| _ ->
|
|
[: `BEbox
|
|
[: `S LR "begin";
|
|
`HVbox
|
|
[: `HVbox [: :];
|
|
listws expr1 (S RO ";") el "" [: :] :];
|
|
`HVbox [: `S LR "end"; k :] :] :] ]
|
|
| <:expr< $_$ $_$ >> | <:expr< $uid:_$ $_$ $_$ >> |
|
|
<:expr< fun [ $list:_$ ] >> | <:expr< match $_$ with [ $list:_$ ] >> |
|
|
<:expr< if $_$ then $_$ else $_$ >> |
|
|
<:expr< try $_$ with [ $list:_$ ] >> |
|
|
<:expr< let $rec:_$ $list:_$ in $_$ >> |
|
|
<:expr< for $_$ = $_$ $to:_$ $_$ do { $list:_$ } >> |
|
|
<:expr< while $_$ do { $list:_$ } >> | <:expr< ($list: _$) >> |
|
|
<:expr< $_$ . $_$ >> | <:expr< $_$ . ( $_$ ) >> |
|
|
<:expr< $_$ . [ $_$ ] >> | <:expr< $_$ := $_$ >> |
|
|
MLast.ExNew _ _ as e ->
|
|
fun curr next dg k ->
|
|
[: `S LO "("; `expr e "" [: `HVbox [: `S RO ")"; k :] :] :]
|
|
| e -> fun curr next dg k -> [: `next e "" k :] ]}];
|
|
|
|
pr_patt.pr_levels :=
|
|
[{pr_label = "top"; pr_box _ x = HOVCbox x;
|
|
pr_rules =
|
|
extfun Extfun.empty with
|
|
[ <:patt< ($x$ as $lid:y$) >> ->
|
|
fun curr next dg k ->
|
|
[: curr x "" [: :]; `S LR "as"; `S LR (var_escaped y); k :]
|
|
| <:patt< ($x$ as $y$) >> ->
|
|
fun curr next dg k ->
|
|
[: curr y "" [: :]; `S LR "as"; `next x "" k :]
|
|
| p -> fun curr next dg k -> [: `next p "" k :] ]};
|
|
{pr_label = ""; pr_box _ x = HOVbox [: `HVbox [: :]; x :];
|
|
pr_rules =
|
|
extfun Extfun.empty with
|
|
[ <:patt< $x$ | $y$ >> ->
|
|
fun curr next dg k -> [: curr x "" [: `S LR "|" :]; `next y "" k :]
|
|
| p -> fun curr next dg k -> [: `next p "" k :] ]};
|
|
{pr_label = ""; pr_box _ x = HOVCbox [: `HVbox [: :]; x :];
|
|
pr_rules =
|
|
extfun Extfun.empty with
|
|
[ <:patt< ($list:pl$) >> ->
|
|
fun curr next dg k ->
|
|
[: `HVbox [: :]; listws next (S RO ",") pl "" k :]
|
|
| p -> fun curr next dg k -> [: `next p "" k :] ]};
|
|
{pr_label = "patt1"; pr_box _ x = HOVbox [: `HVbox [: :]; x :];
|
|
pr_rules =
|
|
extfun Extfun.empty with
|
|
[ <:patt< $x$ .. $y$ >> ->
|
|
fun curr next dg k -> [: curr x "" [: `S NO ".." :]; `next y "" k :]
|
|
| p -> fun curr next dg k -> [: `next p "" k :] ]};
|
|
{pr_label = ""; pr_box _ x = HOVCbox x;
|
|
pr_rules =
|
|
extfun Extfun.empty with
|
|
[ <:patt< [$_$ :: $_$] >> as p ->
|
|
fun curr next dg k ->
|
|
let (pl, c) =
|
|
make_list p where rec make_list p =
|
|
match p with
|
|
[ <:patt< [$p$ :: $y$] >> ->
|
|
let (pl, c) = make_list y in
|
|
([p :: pl], c)
|
|
| <:patt< [] >> -> ([], None)
|
|
| x -> ([], Some p) ]
|
|
in
|
|
match c with
|
|
[ None ->
|
|
[: `S LO "[";
|
|
listws patt (S RO ";") pl "" [: `S RO "]"; k :] :]
|
|
| Some x ->
|
|
[: `HVbox [: :]; listws next (S LR "::") (pl @ [x]) "" k :] ]
|
|
| p -> fun curr next dg k -> [: `next p "" k :] ]};
|
|
{pr_label = ""; pr_box _ x = HOVbox x;
|
|
pr_rules =
|
|
extfun Extfun.empty with
|
|
[ <:patt< [$_$ :: $_$] >> as p ->
|
|
fun curr next dg k -> [: `next p "" k :]
|
|
| <:patt< $x$ $y$ >> ->
|
|
fun curr next dg k ->
|
|
match get_patt_args x [y] with
|
|
[ (_, [_]) -> [: curr x "" [: :]; `next y "" k :]
|
|
| ((<:patt< $uid:_$ >> | <:patt< $_$ . $uid:_$ >> as a), al) ->
|
|
[: curr a "" [: :];
|
|
`HOVbox
|
|
[: `S LO "(";
|
|
listws (fun x _ k -> HOVbox [: curr x "" k :])
|
|
(S RO ",") al "" [: `S RO ")"; k :] :] :]
|
|
| _ -> [: curr x "" [: :]; `next y "" k :] ]
|
|
| p -> fun curr next dg k -> [: `next p "" k :] ]};
|
|
{pr_label = ""; pr_box _ x = HOVbox x;
|
|
pr_rules =
|
|
extfun Extfun.empty with
|
|
[ <:patt< $x$ . $y$ >> ->
|
|
fun curr next dg k -> [: curr x "" [: :]; `S NO "."; `next y "" k :]
|
|
| p -> fun curr next dg k -> [: `next p "" k :] ]};
|
|
{pr_label = "simple"; pr_box _ x = HOVbox x;
|
|
pr_rules =
|
|
extfun Extfun.empty with
|
|
[ <:patt< [| $list:pl$ |] >> ->
|
|
fun curr next dg k ->
|
|
[: `S LR "[|"; listws patt (S RO ";") pl "" [: `S LR "|]"; k :] :]
|
|
| <:patt< { $list:fpl$ } >> ->
|
|
fun curr next dg k ->
|
|
[: `HVbox
|
|
[: `S LO "{";
|
|
listws
|
|
(fun (lab, p) _ k ->
|
|
HVbox
|
|
[: `patt lab "" [: `S LR "=" :]; `patt p "" k :])
|
|
(S RO ";") fpl "" [: `S RO "}"; k :] :] :]
|
|
| <:patt< [$_$ :: $_$] >> as p ->
|
|
fun curr next dg k ->
|
|
let (pl, c) =
|
|
make_list p where rec make_list p =
|
|
match p with
|
|
[ <:patt< [$p$ :: $y$] >> ->
|
|
let (pl, c) = make_list y in
|
|
([p :: pl], c)
|
|
| <:patt< [] >> -> ([], None)
|
|
| x -> ([], Some p) ]
|
|
in
|
|
match c with
|
|
[ None ->
|
|
[: `S LO "[";
|
|
listws patt (S RO ";") pl "" [: `S RO "]"; k :] :]
|
|
| Some x ->
|
|
[: `S LO "("; `patt p "" [: `HVbox [: `S RO ")"; k :] :] :] ]
|
|
| <:patt< ($p$ : $ct$) >> ->
|
|
fun curr next dg k ->
|
|
[: `S LO "("; `patt p "" [: `S LR ":" :];
|
|
`ctyp ct "" [: `S RO ")"; k :] :]
|
|
| <:patt< $int:s$ >> -> fun curr next dg k -> [: `S LR s; k :]
|
|
| <:patt< $flo:s$ >> -> fun curr next dg k -> [: `S LR s; k :]
|
|
| <:patt< $str:s$ >> ->
|
|
fun curr next dg k -> [: `S LR ("\"" ^ s ^ "\""); k :]
|
|
| <:patt< $chr:c$ >> ->
|
|
fun curr next dg k ->
|
|
let c = if c = "'" then "\'" else c in
|
|
[: `S LR ("'" ^ c ^ "'"); k :]
|
|
| <:patt< $lid:i$ >> -> fun curr next dg k -> [: `id_var i; k :]
|
|
| <:patt< $uid:i$ >> ->
|
|
fun curr next dg k -> [: `S LR (conv_con i); k :]
|
|
| <:patt< ` $i$ >> -> fun curr next dg k -> [: `S LR ("`" ^ i); k :]
|
|
| <:patt< # $list:sl$ >> ->
|
|
fun curr next dg k -> [: `S LO "#"; mod_ident sl dg k :]
|
|
| <:patt< ~ $i$ : $lid:j$ >> when i = j ->
|
|
fun curr next dg k -> [: `S LR ("~" ^ i); k :]
|
|
| <:patt< ~ $i$ : $p$ >> ->
|
|
fun curr next dg k ->
|
|
[: `S LO ("~" ^ i ^ ":"); `simple_patt p "" k :]
|
|
| <:patt< ? $i$ : ($p$) >> ->
|
|
fun curr next dg k ->
|
|
match p with
|
|
[ <:patt< $lid:x$ >> when i = x -> [: `S LR ("?" ^ i); k :]
|
|
| _ -> [: `S LO ("?" ^ i ^ ":"); `simple_patt p "" k :] ]
|
|
| <:patt< ? $i$ : ($p$ = $e$) >> ->
|
|
fun curr next dg k ->
|
|
match p with
|
|
[ <:patt< $lid:x$ >> when i = x ->
|
|
[: `S LO "?"; `S LO "("; `patt p "" [: `S LR "=" :];
|
|
`expr e "" [: `S RO ")"; k :] :]
|
|
| _ ->
|
|
[: `S LO ("?" ^ i ^ ":"); `S LO "(";
|
|
`patt p "" [: `S LR "=" :];
|
|
`expr e "" [: `S RO ")"; k :] :] ]
|
|
| <:patt< ? $i$ : ($p$ : $t$ = $e$) >> ->
|
|
fun curr next dg k ->
|
|
match p with
|
|
[ <:patt< $lid:x$ >> when i = x ->
|
|
[: `S LO "?"; `S LO "("; `patt p "" [: `S LR "=" :];
|
|
`expr e "" [: `S RO ")"; k :] :]
|
|
| _ ->
|
|
[: `S LO ("?" ^ i ^ ":"); `S LO "(";
|
|
`patt p "" [: `S LR "=" :];
|
|
`expr e "" [: `S RO ")"; k :] :] ]
|
|
| <:patt< _ >> -> fun curr next dg k -> [: `S LR "_"; k :]
|
|
| <:patt< $_$ $_$ >> | <:patt< ($_$ as $_$) >> | <:patt< $_$ | $_$ >> |
|
|
<:patt< ($list:_$) >> | <:patt< $_$ .. $_$ >> as p ->
|
|
fun curr next dg k ->
|
|
[: `S LO "("; `patt p "" [: `HVbox [: `S RO ")"; k :] :] :]
|
|
| p -> fun curr next dg k -> [: `next p "" k :] ]}];
|
|
|
|
value output_string_eval oc s =
|
|
loop 0 where rec loop i =
|
|
if i == String.length s then ()
|
|
else if i == String.length s - 1 then output_char oc s.[i]
|
|
else
|
|
match (s.[i], s.[i + 1]) with
|
|
[ ('\\', 'n') -> do { output_char oc '\n'; loop (i + 2) }
|
|
| (c, _) -> do { output_char oc c; loop (i + 1) } ]
|
|
;
|
|
|
|
value maxl = ref 78;
|
|
value sep = ref None;
|
|
value comm_after = ref False;
|
|
value type_comm = ref False;
|
|
value delayed_comm = ref "";
|
|
|
|
value copy_after oc s =
|
|
let s =
|
|
try
|
|
let i = String.index s '\n' in
|
|
do {
|
|
output_string oc (String.sub s 0 i);
|
|
String.sub s i (String.length s - i)
|
|
}
|
|
with
|
|
[ Not_found -> s ]
|
|
in
|
|
do {
|
|
output_string oc delayed_comm.val;
|
|
let len = String.length s in
|
|
let i =
|
|
if len > 4 && String.sub s (len - 3) 3 = "*)\n"
|
|
then
|
|
loop (len - 6) where rec loop i =
|
|
if i >= 0 then
|
|
if String.sub s i 5 = "\n(** " then i + 1 else loop (i - 1)
|
|
else len
|
|
else len
|
|
in
|
|
output_string oc (String.sub s 0 i);
|
|
delayed_comm.val :=
|
|
if i < len then "\n" ^ String.sub s i (len - i - 1)
|
|
else String.sub s i (len - i)
|
|
}
|
|
;
|
|
|
|
value input_from_next_bol ic bol len =
|
|
let buff = Buffer.create 20 in
|
|
loop bol 0 where rec loop bol_found i =
|
|
if i = len then Buffer.contents buff
|
|
else
|
|
let c = input_char ic in
|
|
let bol_found = bol_found || c = '\n' in
|
|
do {
|
|
if bol_found then Buffer.add_char buff c else ();
|
|
loop bol_found (i + 1)
|
|
}
|
|
;
|
|
|
|
value copy_source ic oc first bp ep =
|
|
match sep.val with
|
|
[ Some str ->
|
|
if first then ()
|
|
else if ep == in_channel_length ic then output_string oc "\n"
|
|
else output_string_eval oc str
|
|
| None ->
|
|
do {
|
|
seek_in ic bp;
|
|
let s = input_from_next_bol ic first (ep - bp) in
|
|
if not comm_after.val then output_string oc s
|
|
else copy_after oc s
|
|
} ]
|
|
;
|
|
|
|
value copy_to_end ic oc first bp =
|
|
let ilen = in_channel_length ic in
|
|
if bp < ilen then copy_source ic oc first bp ilen
|
|
else output_string oc "\n"
|
|
;
|
|
|
|
value apply_printer printer ast =
|
|
let oc =
|
|
match Pcaml.output_file.val with
|
|
[ Some f -> open_out_bin f
|
|
| None -> stdout ]
|
|
in
|
|
let cleanup () =
|
|
match Pcaml.output_file.val with
|
|
[ Some _ -> close_out oc
|
|
| None -> () ]
|
|
in
|
|
let pr_ch = output_char oc in
|
|
let pr_str = output_string oc in
|
|
let pr_nl () = output_char oc '\n' in
|
|
if Pcaml.input_file.val <> "-" && Pcaml.input_file.val <> "" then do {
|
|
let ic = open_in_bin Pcaml.input_file.val in
|
|
try
|
|
do {
|
|
input_file_ic.val := if type_comm.val then Some ic else None;
|
|
let (first, last_pos) =
|
|
List.fold_left
|
|
(fun (first, last_pos) (si, (bp, ep)) ->
|
|
do {
|
|
copy_source ic oc first last_pos bp;
|
|
flush oc;
|
|
print_pretty pr_ch pr_str pr_nl "" "" maxl.val (fun _ -> ())
|
|
(printer si "" [: :]);
|
|
flush oc;
|
|
(False, ep)
|
|
})
|
|
(True, 0) ast
|
|
in
|
|
copy_to_end ic oc first last_pos;
|
|
flush oc
|
|
}
|
|
with x ->
|
|
do { close_in ic; input_file_ic.val := None; cleanup (); raise x };
|
|
close_in ic;
|
|
input_file_ic.val := None;
|
|
cleanup ()
|
|
}
|
|
else do {
|
|
List.iter
|
|
(fun (si, _) ->
|
|
do {
|
|
print_pretty pr_ch pr_str pr_nl "" "" maxl.val (fun _ -> ())
|
|
(printer si "" [: :]);
|
|
match sep.val with
|
|
[ Some str -> output_string_eval oc str
|
|
| None -> output_char oc '\n' ];
|
|
flush oc
|
|
})
|
|
ast;
|
|
cleanup ()
|
|
}
|
|
;
|
|
|
|
Pcaml.print_interf.val := apply_printer sig_item;
|
|
Pcaml.print_implem.val := apply_printer str_item;
|
|
|
|
Pcaml.add_option "-l" (Arg.Int (fun x -> maxl.val := x))
|
|
"<length> Maximum line length for pretty printing.";
|
|
|
|
Pcaml.add_option "-no_ss" (Arg.Set no_ss)
|
|
" Do not print double semicolons.";
|
|
|
|
Pcaml.add_option "-sep" (Arg.String (fun x -> sep.val := Some x))
|
|
"<string> Use this string between phrases instead of reading source.";
|
|
|
|
Pcaml.add_option "-ca" (Arg.Set comm_after)
|
|
" Put the ocamldoc comments after declarations.";
|
|
|
|
Pcaml.add_option "-tc" (Arg.Set type_comm)
|
|
" Add the comments inside sum and record types.";
|