summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/pretty_print_lem.ml107
1 files changed, 67 insertions, 40 deletions
diff --git a/src/pretty_print_lem.ml b/src/pretty_print_lem.ml
index 48eed31a..b0b76ac1 100644
--- a/src/pretty_print_lem.ml
+++ b/src/pretty_print_lem.ml
@@ -247,12 +247,15 @@ let doc_typ_lem, doc_atomic_typ_lem =
and typ' ty = fn_typ false ty
and fn_typ atyp_needed ((Typ_aux (t, _)) as ty) = match t with
| Typ_fn(arg,ret,efct) ->
- (*let exc_typ = string "string" in*)
let ret_typ =
if effectful efct
- then separate space [string "_M";(*parens exc_typ;*) fn_typ true ret]
+ then separate space [string "_M"; fn_typ true ret]
else separate space [fn_typ false ret] in
- let tpp = separate space [tup_typ true arg; arrow;ret_typ] in
+ let arg_typs = match arg with
+ | Typ_aux (Typ_tup typs, _) ->
+ List.map (app_typ true) typs
+ | _ -> [tup_typ true arg] in
+ let tpp = separate (space ^^ arrow ^^ space) (arg_typs @ [ret_typ]) in
(* once we have proper excetions we need to know what the exceptions type is *)
if atyp_needed then parens tpp else tpp
| _ -> tup_typ atyp_needed ty
@@ -702,13 +705,17 @@ let doc_exp_lem, doc_let_lem =
parens (separate_map comma (expV false) args) in
if aexp_needed then parens (align epp) else epp
| _ ->
- let call = match annot with
+ let call, is_extern = match annot with
| Some (env, _, _) when Env.is_extern f env "lem" ->
- string (Env.get_extern f env "lem")
- | _ -> doc_id_lem f in
- let argspp = match args with
- | [arg] -> expV true arg
- | args -> parens (align (separate_map (comma ^^ break 0) (expV false) args)) in
+ string (Env.get_extern f env "lem"), true
+ | _ -> doc_id_lem f, false in
+ let argspp =
+ (* TODO Update Sail library functions to not use tupled arguments,
+ then remove the special case here *)
+ if is_extern then
+ parens (align (separate_map (comma ^^ break 0) (expV true) args))
+ else
+ align (separate_map (break 1) (expV true) args) in
let epp = align (call ^//^ argspp) in
let (taepp,aexp_needed) =
let t = (*Env.base_typ_of (env_of full_exp)*) (typ_of full_exp) in
@@ -1203,6 +1210,43 @@ let doc_typdef_lem (TD_aux(td, (l, annot))) = match td with
break 0 ^^ brackets (align doc_rids)]))
| _ -> raise (Reporting_basic.err_unreachable l "register with non-constant indices")
+let args_of_typ l env typ =
+ let typs = match typ with
+ | Typ_aux (Typ_tup typs, _) -> typs
+ | typ -> [typ] in
+ let arg i typ =
+ let id = mk_id ("arg" ^ string_of_int i) in
+ P_aux (P_id id, (l, Some (env, typ, no_effect))),
+ E_aux (E_id id, (l, Some (env, typ, no_effect))) in
+ List.split (List.mapi arg typs)
+
+let rec untuple_args_pat (P_aux (paux, ((l, _) as annot)) as pat) =
+ let env = env_of_annot annot in
+ let id = (fun body -> body) in
+ match paux with
+ | P_tup [] ->
+ let annot = (l, Some (Env.empty, unit_typ, no_effect)) in
+ [P_aux (P_lit (mk_lit L_unit), annot)], id
+ | P_tup pats -> pats, id
+ | P_wild ->
+ begin
+ match pat_typ_of pat with
+ | Typ_aux (Typ_tup typs, _) ->
+ let wild typ = P_aux (P_wild, (l, Some (env, typ, no_effect))) in
+ List.map wild typs, id
+ | _ -> [pat], id
+ end
+ | P_lit _ | P_id _ | P_var _ | P_app _ | P_record _
+ | P_vector _ | P_vector_concat _ | P_list _ | P_cons _ ->
+ [pat], id
+ | P_typ (_, pat) -> untuple_args_pat pat
+ | P_as _ ->
+ let argpats, argexps = args_of_typ l env (pat_typ_of pat) in
+ let argexp = E_aux (E_tuple argexps, annot) in
+ let bindargs (E_aux (_, bannot) as body) =
+ E_aux (E_let (LB_aux (LB_val (pat, argexp), annot), body), bannot) in
+ argpats, bindargs
+
let doc_rec_lem (Rec_aux(r,_)) = match r with
| Rec_nonrec -> space
| Rec_rec -> space ^^ string "rec" ^^ space
@@ -1219,14 +1263,16 @@ let doc_fun_body_lem exp =
let doc_funcl_lem (FCL_aux(FCL_Funcl(id,pexp),_)) =
let pat,guard,exp,(l,_) = destruct_pexp pexp in
+ let pats, bind = untuple_args_pat pat in
+ let patspp = separate_map space (doc_pat_lem true) pats in
let _ = match guard with
| None -> ()
| _ ->
raise (Reporting_basic.err_unreachable l
- "guarded pattern expression should have been rewritten before pretty-printing")
- in
- group (prefix 3 1 ((doc_pat_lem false pat) ^^ space ^^ arrow)
- (doc_fun_body_lem exp))
+ "guarded pattern expression should have been rewritten before pretty-printing") in
+ group (prefix 3 1
+ (separate space [doc_id_lem id; patspp; equals])
+ (doc_fun_body_lem (bind exp)))
let get_id = function
| [] -> failwith "FD_function with empty list"
@@ -1235,29 +1281,7 @@ let get_id = function
module StringSet = Set.Make(String)
let doc_fundef_rhs_lem (FD_aux(FD_function(r, typa, efa, funcls),fannot) as fd) =
- match funcls with
- | [] -> failwith "FD_function with empty function list"
- | [FCL_aux(FCL_Funcl(id,pexp),_)] ->
- let pat,guard,exp,(l,_) = destruct_pexp pexp in
- let _ = match guard with
- | None -> ()
- | _ ->
- raise (Reporting_basic.err_unreachable l
- "guarded pattern expression should have been rewritten before pretty-printing")
- in
- (prefix 2 1)
- ((separate space)
- [doc_id_lem id;
- (doc_pat_lem true pat);
- equals])
- (doc_fun_body_lem exp)
- | _ ->
- let clauses =
- (separate_map (break 1))
- (fun fcl -> separate space [pipe;doc_funcl_lem fcl]) funcls in
- (prefix 2 1)
- ((separate space) [doc_id_lem (id_of_fundef fd);equals;string "function"])
- (clauses ^/^ string "end")
+ separate_map (hardline ^^ string "and ") doc_funcl_lem funcls
let doc_mutrec_lem = function
| [] -> failwith "DEF_internal_mutrec with empty function list"
@@ -1294,10 +1318,12 @@ let rec doc_fundef_lem (FD_aux(FD_function(r, typa, efa, fcls),fannot) as fd) =
if StringSet.mem candidate already_used then
pick_name_not_clashing_with already_used (candidate ^ "'")
else candidate in
+ let unit_pat = P_aux (P_lit (mk_lit L_unit), (l, Some (Env.empty, unit_typ, no_effect))) in
let aux_fname = pick_name_not_clashing_with already_used_fnames (string_of_id id ^ "_" ^ ctor) in
+ let aux_args = if argspat = [] then unit_pat else P_aux (P_tup argspat,pannot) in
let already_used_fnames = StringSet.add aux_fname already_used_fnames in
let fcl = FCL_aux (FCL_Funcl (Id_aux (Id aux_fname,l),
- Pat_aux (Pat_exp (P_aux (P_tup argspat,pannot),exp),(pexp_l,None)))
+ Pat_aux (Pat_exp (aux_args,exp),(pexp_l,None)))
,annot) in
let auxiliary_functions =
auxiliary_functions ^^ hardline ^^ hardline ^^
@@ -1311,6 +1337,7 @@ let rec doc_fundef_lem (FD_aux(FD_function(r, typa, efa, fcls),fannot) as fd) =
| _ -> P_aux (P_as (P_aux (p,a), Id_aux (Id ("arg" ^ string_of_int idx),l)),a) in
let named_argspat = List.mapi name_pat argspat in
let named_pat = P_aux (P_app (Id_aux (Id ctor,l),named_argspat),pannot) in
+ let named_args = if argspat = [] then [unit_pat] else named_argspat in
let doc_arg idx (P_aux (p,(l,a))) = match p with
| P_as (pat,id) -> doc_id_lem id
| P_lit lit -> doc_lit_lem false lit a
@@ -1321,7 +1348,7 @@ let rec doc_fundef_lem (FD_aux(FD_function(r, typa, efa, fcls),fannot) as fd) =
(separate space
[pipe;doc_pat_lem false named_pat;arrow;
string aux_fname;
- parens (separate comma (List.mapi doc_arg named_argspat))]) in
+ separate space (List.mapi doc_arg named_args)]) in
(already_used_fnames,auxiliary_functions,clauses)
) (StringSet.empty,empty,empty) fcls in
@@ -1424,8 +1451,8 @@ let doc_regtype_fields (tname, (n1, n2, fields)) =
space; langlebar; string " field_name = \"" ^^ doc_id_lem fid ^^ string "\";"; hardline;
space; space; space; string (" field_start = " ^ string_of_big_int i ^ ";"); hardline;
space; space; space; string (" field_is_inc = " ^ dir ^ ";"); hardline;
- space; space; space; string (" get_field = (fun reg -> get_" ^ tname ^ "_" ^ string_of_id fid ^ "(reg));"); hardline;
- space; space; space; string (" set_field = (fun reg v -> set_" ^ tname ^ "_" ^ string_of_id fid ^ "(reg, v)) "); ranglebar])
+ space; space; space; string (" get_field = get_" ^ tname ^ "_" ^ string_of_id fid ^ ";"); hardline;
+ space; space; space; string (" set_field = set_" ^ tname ^ "_" ^ string_of_id fid ^ " "); ranglebar])
in
separate_map hardline doc_field fields