2020-05-03 10:40:11 +02:00
|
|
|
[@@@warning "-42"]
|
|
|
|
|
|
|
|
open AST
|
|
|
|
module Region = Simple_utils.Region
|
|
|
|
open! Region
|
|
|
|
open! PPrint
|
|
|
|
|
|
|
|
let paragraph (s : string) = flow (break 1) (words s)
|
|
|
|
|
|
|
|
let rec make ast =
|
|
|
|
let app decl = group (pp_declaration decl) in
|
2020-05-12 19:25:02 +02:00
|
|
|
separate_map (hardline ^^ hardline) app (Utils.nseq_to_list ast.decl)
|
2020-05-03 10:40:11 +02:00
|
|
|
|
|
|
|
and pp_declaration = function
|
|
|
|
Let decl -> pp_let_decl decl
|
|
|
|
| TypeDecl decl -> pp_type_decl decl
|
|
|
|
|
|
|
|
and pp_let_decl Region.{value; _} =
|
|
|
|
let _, rec_opt, binding, attr = value in
|
2020-05-08 19:01:51 +02:00
|
|
|
let rec_doc =
|
2020-05-03 10:40:11 +02:00
|
|
|
match rec_opt with
|
2020-05-08 19:01:51 +02:00
|
|
|
None -> empty
|
|
|
|
| Some _ -> string " rec" in
|
|
|
|
let binding = pp_let_binding binding
|
|
|
|
and attr = pp_attributes attr
|
|
|
|
in string "let" ^^ rec_doc ^/^ binding ^/^ attr
|
2020-05-03 10:40:11 +02:00
|
|
|
|
|
|
|
and pp_attributes attr =
|
2020-05-08 19:01:51 +02:00
|
|
|
let sep = string ";" ^^ break 1 in
|
2020-05-03 10:40:11 +02:00
|
|
|
let make s = string "[@@" ^^ string s.value ^^ string "]"
|
|
|
|
in separate_map sep make attr
|
|
|
|
|
2020-05-08 19:01:51 +02:00
|
|
|
and pp_ident Region.{value; _} = string value
|
|
|
|
|
|
|
|
and pp_string s = pp_ident s
|
2020-05-03 10:40:11 +02:00
|
|
|
|
|
|
|
and pp_let_binding (binding : let_binding) =
|
|
|
|
let {binders; lhs_type; let_rhs; _} = binding in
|
|
|
|
let patterns = Utils.nseq_to_list binders in
|
|
|
|
let patterns = flow (break 1) (List.map pp_pattern patterns) in
|
|
|
|
let lhs_type =
|
|
|
|
match lhs_type with
|
2020-05-08 19:01:51 +02:00
|
|
|
None -> empty
|
2020-05-03 10:40:11 +02:00
|
|
|
| Some (_, t_expr) -> string " :" ^/^ pp_type_expr t_expr in
|
|
|
|
let let_rhs = pp_expr let_rhs in
|
|
|
|
patterns ^^ lhs_type ^^ string " =" ^/^ let_rhs
|
|
|
|
|
|
|
|
and pp_pattern = function
|
|
|
|
PConstr p -> pp_pconstr p
|
|
|
|
| PUnit _ -> string "()"
|
|
|
|
| PFalse _ -> string "false"
|
|
|
|
| PTrue _ -> string "true"
|
2020-05-08 19:01:51 +02:00
|
|
|
| PVar v -> pp_ident v
|
2020-05-03 10:40:11 +02:00
|
|
|
| PInt i -> pp_int i
|
|
|
|
| PNat n -> pp_nat n
|
|
|
|
| PBytes b -> pp_bytes b
|
|
|
|
| PString s -> pp_string s
|
|
|
|
| PWild _ -> string "_"
|
|
|
|
| PList l -> pp_plist l
|
|
|
|
| PTuple t -> pp_ptuple t
|
|
|
|
| PPar p -> pp_ppar p
|
|
|
|
| PRecord r -> pp_precord r
|
|
|
|
| PTyped t -> pp_ptyped t
|
|
|
|
|
|
|
|
and pp_pconstr = function
|
|
|
|
PNone _ -> string "None"
|
2020-05-07 20:26:47 +02:00
|
|
|
| PSomeApp p -> pp_patt_some p
|
|
|
|
| PConstrApp a -> pp_patt_c_app a
|
2020-05-03 10:40:11 +02:00
|
|
|
|
2020-05-07 20:26:47 +02:00
|
|
|
and pp_patt_c_app Region.{value; _} =
|
2020-05-03 10:40:11 +02:00
|
|
|
match value with
|
2020-05-08 19:01:51 +02:00
|
|
|
constr, None -> pp_ident constr
|
|
|
|
| constr, Some pat -> pp_ident constr ^^ pp_pattern pat
|
2020-05-03 10:40:11 +02:00
|
|
|
|
2020-05-07 20:26:47 +02:00
|
|
|
and pp_patt_some Region.{value; _} =
|
2020-05-03 10:40:11 +02:00
|
|
|
string "Some" ^/^ pp_pattern (snd value)
|
|
|
|
|
2020-05-07 11:11:16 +02:00
|
|
|
and pp_int Region.{value; _} =
|
|
|
|
string (Z.to_string (snd value))
|
|
|
|
|
|
|
|
and pp_nat Region.{value; _} =
|
|
|
|
string (Z.to_string (snd value) ^ "n")
|
|
|
|
|
|
|
|
and pp_bytes Region.{value; _} =
|
|
|
|
string ("0x" ^ Hex.show (snd value))
|
2020-05-03 10:40:11 +02:00
|
|
|
|
|
|
|
and pp_ppar Region.{value; _} =
|
2020-05-08 19:01:51 +02:00
|
|
|
let {inside; _} = value in
|
2020-05-03 10:40:11 +02:00
|
|
|
string "(" ^^ pp_pattern inside ^^ string ")"
|
|
|
|
|
|
|
|
and pp_plist = function
|
|
|
|
PListComp cmp -> pp_list_comp cmp
|
|
|
|
| PCons cons -> pp_cons cons
|
|
|
|
|
2020-05-08 19:01:51 +02:00
|
|
|
and pp_list_comp e =
|
|
|
|
string "[" ^^ pp_injection pp_pattern e ^^ string "]"
|
|
|
|
|
2020-05-03 10:40:11 +02:00
|
|
|
and pp_cons Region.{value; _} =
|
|
|
|
let patt1, _, patt2 = value in
|
|
|
|
pp_pattern patt1 ^^ string " ::" ^/^ pp_pattern patt2
|
|
|
|
|
|
|
|
and pp_ptuple Region.{value; _} =
|
|
|
|
let cmp = Utils.nsepseq_to_list value in
|
|
|
|
let sep = string "," ^^ break 1 in
|
|
|
|
separate_map sep pp_pattern cmp
|
|
|
|
|
|
|
|
and pp_precord Region.{value; _} =
|
|
|
|
let fields = value.ne_elements in
|
|
|
|
let fields = Utils.nsepseq_to_list fields in
|
|
|
|
let sep = string ";" ^^ break 1 in
|
|
|
|
let fields = separate_map sep pp_field_pattern fields
|
|
|
|
in string "{" ^^ fields ^^ string "}"
|
|
|
|
|
|
|
|
and pp_field_pattern Region.{value; _} =
|
|
|
|
let {field_name; pattern; _} = value in
|
2020-05-08 19:01:51 +02:00
|
|
|
pp_ident field_name ^^ string " =" ^/^ pp_pattern pattern
|
2020-05-03 10:40:11 +02:00
|
|
|
|
|
|
|
and pp_ptyped Region.{value; _} =
|
|
|
|
let {pattern; type_expr; _} = value in
|
|
|
|
pp_pattern pattern ^^ string " :" ^/^ pp_type_expr type_expr
|
|
|
|
|
|
|
|
and pp_type_decl decl =
|
|
|
|
let {name; type_expr; _} = decl.value in
|
2020-05-12 19:25:02 +02:00
|
|
|
string "type " ^^ string name.value ^^ string " ="
|
|
|
|
^^ group (nest 2 (break 1 ^^ pp_type_expr type_expr))
|
2020-05-03 10:40:11 +02:00
|
|
|
|
2020-05-04 12:34:42 +02:00
|
|
|
and pp_expr = function
|
|
|
|
ECase e -> pp_case_expr e
|
|
|
|
| ECond e -> pp_cond_expr e
|
|
|
|
| EAnnot e -> pp_annot_expr e
|
|
|
|
| ELogic e -> pp_logic_expr e
|
|
|
|
| EArith e -> pp_arith_expr e
|
|
|
|
| EString e -> pp_string_expr e
|
|
|
|
| EList e -> pp_list_expr e
|
|
|
|
| EConstr e -> pp_constr_expr e
|
|
|
|
| ERecord e -> pp_record_expr e
|
|
|
|
| EProj e -> pp_projection e
|
|
|
|
| EUpdate e -> pp_update e
|
2020-05-08 19:01:51 +02:00
|
|
|
| EVar v -> pp_ident v
|
2020-05-04 12:34:42 +02:00
|
|
|
| ECall e -> pp_call_expr e
|
|
|
|
| EBytes e -> pp_bytes e
|
|
|
|
| EUnit _ -> string "()"
|
|
|
|
| ETuple e -> pp_tuple_expr e
|
|
|
|
| EPar e -> pp_par_expr e
|
|
|
|
| ELetIn e -> pp_let_in e
|
|
|
|
| EFun e -> pp_fun e
|
|
|
|
| ESeq e -> pp_seq e
|
|
|
|
|
2020-05-07 11:11:16 +02:00
|
|
|
and pp_case_expr Region.{value; _} =
|
|
|
|
let {expr; cases; _} = value in
|
|
|
|
string "match " ^^ pp_expr expr ^/^ string "with" ^/^ pp_cases cases
|
|
|
|
|
|
|
|
and pp_cases Region.{value; _} =
|
|
|
|
let cases = Utils.nsepseq_to_list value
|
|
|
|
and sep = break 1 ^^ string "| "
|
|
|
|
in separate_map sep pp_clause cases
|
|
|
|
|
|
|
|
and pp_clause Region.{value; _} =
|
|
|
|
let {pattern; rhs; _} = value in
|
|
|
|
pp_pattern pattern ^^ string " ->" ^/^ pp_expr rhs
|
|
|
|
|
|
|
|
and pp_cond_expr Region.{value; _} =
|
|
|
|
let {test; ifso; kwd_else; ifnot; _} = value in
|
|
|
|
let if_then = string "if " ^^ pp_expr test
|
|
|
|
^/^ string "then " ^^ pp_expr ifso in
|
|
|
|
if kwd_else#is_ghost then if_then
|
|
|
|
else if_then ^/^ string "else " ^^ pp_expr ifnot
|
|
|
|
|
|
|
|
and pp_annot_expr Region.{value; _} =
|
|
|
|
let expr, _, type_expr = value.inside in
|
|
|
|
string "(" ^^ pp_expr expr ^^ string " :"
|
|
|
|
^/^ pp_type_expr type_expr ^^ string ")"
|
|
|
|
|
|
|
|
and pp_logic_expr = function
|
|
|
|
BoolExpr e -> pp_bool_expr e
|
|
|
|
| CompExpr e -> pp_comp_expr e
|
|
|
|
|
|
|
|
and pp_bool_expr = function
|
|
|
|
Or e -> pp_bin_op "||" e
|
|
|
|
| And e -> pp_bin_op "&&" e
|
|
|
|
| Not e -> pp_un_op "not" e
|
|
|
|
| True _ -> string "true"
|
|
|
|
| False _ -> string "false"
|
|
|
|
|
|
|
|
and pp_bin_op op Region.{value; _} =
|
|
|
|
let {arg1; arg2; _} = value
|
|
|
|
in pp_expr arg1 ^/^ string (op ^ " ") ^^ pp_expr arg2
|
|
|
|
|
|
|
|
and pp_un_op op Region.{value; _} =
|
|
|
|
string (op ^ " ") ^^ pp_expr value.arg
|
|
|
|
|
|
|
|
and pp_comp_expr = function
|
|
|
|
Lt e -> pp_bin_op "<" e
|
|
|
|
| Leq e -> pp_bin_op "<=" e
|
|
|
|
| Gt e -> pp_bin_op ">" e
|
|
|
|
| Geq e -> pp_bin_op ">=" e
|
|
|
|
| Equal e -> pp_bin_op "=" e
|
|
|
|
| Neq e -> pp_bin_op "<>" e
|
|
|
|
|
|
|
|
and pp_arith_expr = function
|
|
|
|
Add e -> pp_bin_op "+" e
|
|
|
|
| Sub e -> pp_bin_op "-" e
|
|
|
|
| Mult e -> pp_bin_op "*" e
|
|
|
|
| Div e -> pp_bin_op "/" e
|
|
|
|
| Mod e -> pp_bin_op "mod" e
|
2020-05-08 19:01:51 +02:00
|
|
|
| Neg e -> string "-" ^^ pp_expr e.value.arg
|
2020-05-07 11:11:16 +02:00
|
|
|
| Int e -> pp_int e
|
|
|
|
| Nat e -> pp_nat e
|
|
|
|
| Mutez e -> pp_mutez e
|
|
|
|
|
|
|
|
and pp_mutez Region.{value; _} =
|
2020-05-08 19:01:51 +02:00
|
|
|
Z.to_string (snd value) ^ "mutez" |> string
|
2020-05-07 11:11:16 +02:00
|
|
|
|
|
|
|
and pp_string_expr = function
|
|
|
|
Cat e -> pp_bin_op "^" e
|
|
|
|
| String e -> pp_string e
|
|
|
|
|
|
|
|
and pp_list_expr = function
|
|
|
|
ECons e -> pp_bin_op "::" e
|
|
|
|
| EListComp e -> pp_injection pp_expr e
|
|
|
|
|
2020-05-08 19:01:51 +02:00
|
|
|
and pp_injection :
|
|
|
|
'a.('a -> document) -> 'a injection Region.reg -> document =
|
|
|
|
fun printer Region.{value; _} ->
|
|
|
|
let {compound; elements; terminator} = value in
|
|
|
|
let sep = ";" in
|
|
|
|
let sep_doc = string sep ^^ break 1 in
|
|
|
|
let elements = Utils.sepseq_to_list elements in
|
|
|
|
let elements = separate_map sep_doc printer elements in
|
|
|
|
let doc =
|
|
|
|
match pp_compound compound with
|
|
|
|
None -> elements
|
|
|
|
| Some (opening, closing) ->
|
|
|
|
string opening ^^ elements ^^ string closing
|
|
|
|
in match terminator with
|
|
|
|
None -> doc
|
|
|
|
| Some _ -> doc ^^ string sep
|
2020-05-07 11:11:16 +02:00
|
|
|
|
|
|
|
and pp_compound = function
|
|
|
|
BeginEnd (start, _) ->
|
2020-05-08 19:01:51 +02:00
|
|
|
if start#is_ghost then None else Some ("begin","end")
|
|
|
|
| Braces (start, _) ->
|
|
|
|
if start#is_ghost then None else Some ("{","}")
|
|
|
|
| Brackets (start, _) ->
|
|
|
|
if start#is_ghost then None else Some ("[","]")
|
2020-05-07 11:11:16 +02:00
|
|
|
|
2020-05-07 20:26:47 +02:00
|
|
|
and pp_constr_expr = function
|
|
|
|
ENone _ -> string "None"
|
|
|
|
| ESomeApp a -> pp_some a
|
|
|
|
| EConstrApp a -> pp_constr_app a
|
|
|
|
|
2020-05-08 19:01:51 +02:00
|
|
|
and pp_some Region.{value=_, e; _} = string "Some" ^/^ pp_expr e
|
2020-05-07 20:26:47 +02:00
|
|
|
|
|
|
|
and pp_constr_app Region.{value; _} =
|
|
|
|
let constr, arg = value in
|
|
|
|
let constr = string constr.value in
|
|
|
|
match arg with
|
|
|
|
None -> constr
|
2020-05-08 19:01:51 +02:00
|
|
|
| Some e -> constr ^/^ pp_expr e
|
2020-05-07 20:26:47 +02:00
|
|
|
|
|
|
|
and pp_record_expr ne_inj = pp_ne_injection pp_field_assign ne_inj
|
|
|
|
|
2020-05-08 19:01:51 +02:00
|
|
|
and pp_field_assign Region.{value; _} =
|
|
|
|
let {field_name; field_expr; _} = value in
|
|
|
|
pp_ident field_name ^^ string " =" ^/^ pp_expr field_expr
|
|
|
|
|
|
|
|
and pp_ne_injection :
|
|
|
|
'a.('a -> document) -> 'a ne_injection Region.reg -> document =
|
|
|
|
fun printer Region.{value; _} ->
|
|
|
|
let {compound; ne_elements; terminator} = value in
|
|
|
|
let elements = pp_nsepseq ";" printer ne_elements in
|
|
|
|
let doc =
|
|
|
|
match pp_compound compound with
|
|
|
|
None -> elements
|
|
|
|
| Some (opening, closing) ->
|
|
|
|
string opening ^^ elements ^^ string closing
|
|
|
|
in match terminator with
|
|
|
|
None -> doc
|
|
|
|
| Some _ -> doc ^^ string ";"
|
|
|
|
|
|
|
|
and pp_nsepseq :
|
|
|
|
'a.string ->
|
|
|
|
('a -> document) ->
|
|
|
|
('a, Region.t) Utils.nsepseq ->
|
|
|
|
document =
|
|
|
|
fun sep printer elements ->
|
|
|
|
let elems = Utils.nsepseq_to_list elements
|
|
|
|
and sep = string sep ^^ break 1
|
|
|
|
in separate_map sep printer elems
|
|
|
|
|
|
|
|
and pp_nseq : 'a.('a -> document) -> 'a Utils.nseq -> document =
|
|
|
|
fun printer (head, tail) ->
|
|
|
|
separate_map (break 1) printer (head::tail)
|
|
|
|
|
|
|
|
and pp_projection Region.{value; _} =
|
|
|
|
let {struct_name; field_path; _} = value in
|
|
|
|
let fields = Utils.nsepseq_to_list field_path
|
|
|
|
and sep = string "." ^^ break 0 in
|
|
|
|
let fields = separate_map sep pp_selection fields in
|
|
|
|
pp_ident struct_name ^^ string "." ^^ break 0 ^^ fields
|
|
|
|
|
|
|
|
and pp_selection = function
|
|
|
|
FieldName v -> string v.value
|
|
|
|
| Component cmp -> cmp.value |> snd |> Z.to_string |> string
|
|
|
|
|
|
|
|
and pp_update Region.{value; _} =
|
|
|
|
let {record; updates; _} = value in
|
|
|
|
let updates = pp_ne_injection pp_field_path_assign updates
|
|
|
|
and record = pp_path record in
|
|
|
|
string "{" ^^ record ^/^ string "with" ^/^ updates ^^ string "}"
|
|
|
|
|
|
|
|
and pp_field_path_assign Region.{value; _} =
|
|
|
|
let {field_path; field_expr; _} = value in
|
|
|
|
let path = pp_nsepseq "." pp_ident field_path
|
|
|
|
in path ^^ string " =" ^/^ pp_expr field_expr
|
|
|
|
|
|
|
|
and pp_path = function
|
|
|
|
Name v -> pp_ident v
|
|
|
|
| Path p -> pp_projection p
|
|
|
|
|
|
|
|
and pp_call_expr Region.{value; _} =
|
|
|
|
let lambda, arguments = value in
|
|
|
|
pp_expr lambda ^/^ pp_nseq pp_expr arguments
|
|
|
|
|
|
|
|
and pp_tuple_expr Region.{value; _} =
|
|
|
|
pp_nsepseq "," pp_expr value
|
|
|
|
|
|
|
|
and pp_par_expr Region.{value; _} =
|
|
|
|
string "(" ^^ pp_expr value.inside ^^ string ")"
|
|
|
|
|
|
|
|
and pp_let_in Region.{value; _} =
|
|
|
|
let {binding; kwd_rec; body; attributes; _} = value in
|
|
|
|
let binding = pp_let_binding binding
|
|
|
|
and body = pp_expr body
|
|
|
|
and attr = pp_attributes attributes in
|
|
|
|
let rec_doc = match kwd_rec with
|
|
|
|
None -> empty
|
|
|
|
| Some _ -> string " rec"
|
|
|
|
in string "let" ^^ rec_doc ^/^ binding
|
|
|
|
^/^ string "in" ^/^ body ^/^ attr
|
|
|
|
|
|
|
|
and pp_fun Region.{value; _} =
|
|
|
|
let {binders; lhs_type; body; _} = value in
|
|
|
|
let binders = pp_nseq pp_pattern binders
|
|
|
|
and annot = match lhs_type with
|
|
|
|
None -> empty
|
|
|
|
| Some (_,e) -> string ": " ^/^ pp_type_expr e
|
|
|
|
and body = pp_expr body in
|
|
|
|
string "fun " ^^ binders ^^ annot ^^ string " ->" ^/^ body
|
|
|
|
|
|
|
|
and pp_seq e = pp_injection pp_expr e
|
2020-05-03 10:40:11 +02:00
|
|
|
|
|
|
|
and pp_type_expr = function
|
2020-05-04 12:34:42 +02:00
|
|
|
TProd t -> pp_cartesian t
|
|
|
|
| TSum t -> pp_variants t
|
|
|
|
| TRecord t -> pp_fields t
|
|
|
|
| TApp t -> pp_type_app t
|
|
|
|
| TFun t -> pp_fun_type t
|
|
|
|
| TPar t -> pp_type_par t
|
2020-05-08 19:01:51 +02:00
|
|
|
| TVar t -> pp_ident t
|
2020-05-04 12:34:42 +02:00
|
|
|
| TString s -> pp_string s
|
2020-05-03 10:40:11 +02:00
|
|
|
|
|
|
|
and pp_cartesian Region.{value; _} =
|
2020-05-12 19:25:02 +02:00
|
|
|
let head, tail = value in
|
|
|
|
let rec app = function
|
|
|
|
[] -> empty
|
|
|
|
| [e] -> group (break 1 ^^ pp_type_expr e)
|
|
|
|
| e::items ->
|
|
|
|
group (break 1 ^^ pp_type_expr e ^^ string " *") ^^ app items
|
|
|
|
in pp_type_expr head ^^ string " *" ^^ app (List.map snd tail)
|
2020-05-03 10:40:11 +02:00
|
|
|
|
|
|
|
and pp_variants Region.{value; _} =
|
|
|
|
let variants = Utils.nsepseq_to_list value
|
2020-05-12 19:25:02 +02:00
|
|
|
in separate_map (break 1) pp_variant variants
|
2020-05-03 10:40:11 +02:00
|
|
|
|
|
|
|
and pp_variant Region.{value; _} =
|
|
|
|
let {constr; arg} = value in
|
2020-05-12 19:25:02 +02:00
|
|
|
string "| " ^^
|
2020-05-03 10:40:11 +02:00
|
|
|
match arg with
|
2020-05-08 19:01:51 +02:00
|
|
|
None -> pp_ident constr
|
2020-05-03 10:40:11 +02:00
|
|
|
| Some (_, t_expr) ->
|
2020-05-12 19:25:02 +02:00
|
|
|
prefix 4 1 (pp_ident constr ^^ string " of") (pp_type_expr t_expr)
|
2020-05-03 10:40:11 +02:00
|
|
|
|
2020-05-08 19:01:51 +02:00
|
|
|
and pp_fields fields =
|
|
|
|
let fields = pp_ne_injection pp_field_decl fields
|
2020-05-03 10:40:11 +02:00
|
|
|
in string "{" ^^ fields ^^ string "}"
|
|
|
|
|
|
|
|
and pp_field_decl Region.{value; _} =
|
|
|
|
let {field_name; field_type; _} = value in
|
2020-05-08 19:01:51 +02:00
|
|
|
let name = pp_ident field_name in
|
2020-05-03 10:40:11 +02:00
|
|
|
let t_expr = pp_type_expr field_type
|
|
|
|
in name ^^ string " :" ^/^ t_expr
|
|
|
|
|
|
|
|
and pp_type_app Region.{value; _} =
|
2020-05-12 19:25:02 +02:00
|
|
|
let ctor, tuple = value in
|
|
|
|
pp_type_tuple tuple ^^ string " " ^^ pp_type_constr ctor
|
2020-05-03 10:40:11 +02:00
|
|
|
|
|
|
|
and pp_type_tuple Region.{value; _} =
|
2020-05-08 19:01:51 +02:00
|
|
|
let {inside; _} = value in
|
2020-05-03 10:40:11 +02:00
|
|
|
match inside with
|
|
|
|
t_expr, [] -> pp_type_expr t_expr
|
2020-05-12 19:25:02 +02:00
|
|
|
| seq -> let sep = group (string "," ^^ break 1) in
|
2020-05-03 10:40:11 +02:00
|
|
|
let lst = Utils.nsepseq_to_list seq in
|
|
|
|
let cmp = separate_map sep pp_type_expr lst
|
|
|
|
in string "(" ^^ cmp ^^ string ")"
|
|
|
|
|
|
|
|
and pp_type_constr ctor =
|
|
|
|
string ctor.value
|
|
|
|
|
|
|
|
and pp_fun_type Region.{value; _} =
|
|
|
|
let lhs, _, rhs = value in
|
2020-05-12 19:25:02 +02:00
|
|
|
group (pp_type_expr lhs ^^ string " ->") ^/^ pp_type_expr rhs
|
2020-05-03 10:40:11 +02:00
|
|
|
|
|
|
|
and pp_type_par Region.{value; _} =
|
2020-05-12 19:25:02 +02:00
|
|
|
string "(" ^^ nest 1 (pp_type_expr value.inside ^^ string ")")
|