188 lines
5.5 KiB
OCaml
188 lines
5.5 KiB
OCaml
![]() |
[@@@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
|
||
|
separate_map hardline app (Utils.nseq_to_list ast.decl)
|
||
|
|
||
|
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
|
||
|
let rec_str =
|
||
|
match rec_opt with
|
||
|
None -> ""
|
||
|
| Some _ -> " rec" in
|
||
|
string "let" ^^ string rec_str
|
||
|
^/^ pp_let_binding binding ^/^ pp_attributes attr
|
||
|
|
||
|
and pp_attributes attr =
|
||
|
let sep = string ";" ^^ break 1 in
|
||
|
let make s = string "[@@" ^^ string s.value ^^ string "]"
|
||
|
in separate_map sep make attr
|
||
|
|
||
|
and pp_string Region.{value; _} = string value
|
||
|
|
||
|
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
|
||
|
None -> string ""
|
||
|
| 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"
|
||
|
| PVar v -> pp_string v
|
||
|
| 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"
|
||
|
| PSomeApp p -> pp_some p
|
||
|
| PConstrApp a -> pp_c_app a
|
||
|
|
||
|
and pp_c_app Region.{value; _} =
|
||
|
match value with
|
||
|
constr, None -> pp_string constr
|
||
|
| constr, Some pat -> pp_string constr ^/^ pp_pattern pat
|
||
|
|
||
|
and pp_some Region.{value; _} =
|
||
|
string "Some" ^/^ pp_pattern (snd value)
|
||
|
|
||
|
and pp_int Region.{value; _} = string (fst value)
|
||
|
and pp_nat Region.{value; _} = string (fst value)
|
||
|
and pp_bytes Region.{value; _} = string (fst value)
|
||
|
|
||
|
and pp_ppar Region.{value; _} =
|
||
|
let {lpar; inside; rpar} = value in
|
||
|
string "(" ^^ pp_pattern inside ^^ string ")"
|
||
|
|
||
|
and pp_plist = function
|
||
|
PListComp cmp -> pp_list_comp cmp
|
||
|
| PCons cons -> pp_cons cons
|
||
|
|
||
|
and pp_list_comp Region.{value; _} =
|
||
|
let items = Utils.sepseq_to_list value.elements in
|
||
|
let sep = string ";" ^^ break 1 in
|
||
|
let items = separate_map sep pp_pattern items
|
||
|
in string "[" ^^ items ^^ string "]"
|
||
|
|
||
|
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
|
||
|
pp_string field_name ^^ string " =" ^/^ pp_pattern pattern
|
||
|
|
||
|
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
|
||
|
string "type" ^/^ string name.value
|
||
|
^/^ string "=" ^/^ pp_type_expr type_expr
|
||
|
|
||
|
and pp_expr expr =
|
||
|
string "TODO:pp_expr"
|
||
|
|
||
|
and pp_type_expr = function
|
||
|
TProd cartesian -> pp_cartesian cartesian
|
||
|
| TSum sum -> pp_variants sum
|
||
|
| TRecord fields -> pp_fields fields
|
||
|
| TApp t_app -> pp_type_app t_app
|
||
|
| TFun fun_type -> pp_fun_type fun_type
|
||
|
| TPar par -> pp_type_par par
|
||
|
| TVar var -> pp_string var
|
||
|
| TString s -> pp_string s
|
||
|
|
||
|
and pp_cartesian Region.{value; _} =
|
||
|
let cmp = Utils.nsepseq_to_list value in
|
||
|
let sep = string " *" ^^ break 1 in
|
||
|
separate_map sep pp_type_expr cmp
|
||
|
|
||
|
and pp_variants Region.{value; _} =
|
||
|
let variants = Utils.nsepseq_to_list value
|
||
|
and sep = string " |" ^^ break 1 in
|
||
|
separate_map sep pp_variant variants
|
||
|
|
||
|
and pp_variant Region.{value; _} =
|
||
|
let {constr; arg} = value in
|
||
|
match arg with
|
||
|
None -> pp_string constr
|
||
|
| Some (_, t_expr) ->
|
||
|
pp_string constr ^^ string " of" ^/^ pp_type_expr t_expr
|
||
|
|
||
|
and pp_fields 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_decl fields
|
||
|
in string "{" ^^ fields ^^ string "}"
|
||
|
|
||
|
and pp_field_decl Region.{value; _} =
|
||
|
let {field_name; field_type; _} = value in
|
||
|
let name = pp_string field_name in
|
||
|
let t_expr = pp_type_expr field_type
|
||
|
in name ^^ string " :" ^/^ t_expr
|
||
|
|
||
|
and pp_type_app Region.{value; _} =
|
||
|
let ctor, tuple = value
|
||
|
in pp_type_tuple tuple ^/^ pp_type_constr ctor
|
||
|
|
||
|
and pp_type_tuple Region.{value; _} =
|
||
|
let {lpar; inside; rpar} = value in
|
||
|
match inside with
|
||
|
t_expr, [] -> pp_type_expr t_expr
|
||
|
| seq -> let sep = string "," ^^ break 1 in
|
||
|
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
|
||
|
pp_type_expr lhs ^^ string " ->" ^/^ pp_type_expr rhs
|
||
|
|
||
|
and pp_type_par Region.{value; _} =
|
||
|
let {lpar; inside; rpar} = value in
|
||
|
string "(" ^^ pp_type_expr inside ^^ string ")"
|