summaryrefslogtreecommitdiff
path: root/src/pretty_print_lem.ml
diff options
context:
space:
mode:
Diffstat (limited to 'src/pretty_print_lem.ml')
-rw-r--r--src/pretty_print_lem.ml215
1 files changed, 115 insertions, 100 deletions
diff --git a/src/pretty_print_lem.ml b/src/pretty_print_lem.ml
index d7f403a4..5c67f93a 100644
--- a/src/pretty_print_lem.ml
+++ b/src/pretty_print_lem.ml
@@ -194,7 +194,7 @@ let doc_nexp_lem nexp =
| Nexp_exp n -> "exp_" ^ mangle_nexp n
| Nexp_neg n -> "neg_" ^ mangle_nexp n
| _ ->
- raise (Reporting_basic.err_unreachable l __POS__
+ raise (Reporting.err_unreachable l __POS__
("cannot pretty-print nexp \"" ^ string_of_nexp full_nexp ^ "\""))
end in
string ("'" ^ mangle_nexp full_nexp)
@@ -219,19 +219,19 @@ let rec lem_nexps_of_typ (Typ_aux (t,l)) =
match t with
| Typ_id _ -> NexpSet.empty
| Typ_var kid -> NexpSet.singleton (orig_nexp (nvar kid))
- | Typ_fn (t1,t2,_) -> NexpSet.union (trec t1) (trec t2)
+ | Typ_fn (t1,t2,_) -> List.fold_left NexpSet.union (trec t2) (List.map trec t1)
| Typ_tup ts ->
List.fold_left (fun s t -> NexpSet.union s (trec t))
NexpSet.empty ts
| Typ_app(Id_aux (Id "vector", _), [
- Typ_arg_aux (Typ_arg_nexp m, _);
- Typ_arg_aux (Typ_arg_order ord, _);
- Typ_arg_aux (Typ_arg_typ elem_typ, _)]) ->
+ A_aux (A_nexp m, _);
+ A_aux (A_order ord, _);
+ A_aux (A_typ elem_typ, _)]) ->
let m = nexp_simp m in
if !opt_mwords && is_bit_typ elem_typ && not (is_nexp_constant m) then
NexpSet.singleton (orig_nexp m)
else trec elem_typ
- | Typ_app(Id_aux (Id "register", _), [Typ_arg_aux (Typ_arg_typ etyp, _)]) ->
+ | Typ_app(Id_aux (Id "register", _), [A_aux (A_typ etyp, _)]) ->
trec etyp
| Typ_app(Id_aux (Id "range", _),_)
| Typ_app(Id_aux (Id "implicit", _),_)
@@ -240,13 +240,14 @@ let rec lem_nexps_of_typ (Typ_aux (t,l)) =
List.fold_left (fun s ta -> NexpSet.union s (lem_nexps_of_typ_arg ta))
NexpSet.empty tas
| Typ_exist (kids,_,t) -> trec t
- | Typ_bidir _ -> raise (Reporting_basic.err_unreachable l __POS__ "Lem doesn't support bidir types")
- | Typ_internal_unknown -> raise (Reporting_basic.err_unreachable l __POS__ "escaped Typ_internal_unknown")
-and lem_nexps_of_typ_arg (Typ_arg_aux (ta,_)) =
+ | Typ_bidir _ -> raise (Reporting.err_unreachable l __POS__ "Lem doesn't support bidir types")
+ | Typ_internal_unknown -> raise (Reporting.err_unreachable l __POS__ "escaped Typ_internal_unknown")
+and lem_nexps_of_typ_arg (A_aux (ta,_)) =
match ta with
- | Typ_arg_nexp nexp -> NexpSet.singleton (nexp_simp (orig_nexp nexp))
- | Typ_arg_typ typ -> lem_nexps_of_typ typ
- | Typ_arg_order _ -> NexpSet.empty
+ | A_nexp nexp -> NexpSet.singleton (nexp_simp (orig_nexp nexp))
+ | A_typ typ -> lem_nexps_of_typ typ
+ | A_order _ -> NexpSet.empty
+ | A_bool _ -> NexpSet.empty
let lem_tyvars_of_typ typ =
NexpSet.fold (fun nexp ks -> KidSet.union ks (tyvars_of_nexp nexp))
@@ -258,15 +259,12 @@ let doc_typ_lem, doc_atomic_typ_lem =
let rec typ ty = fn_typ true ty
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) ->
+ | Typ_fn(args,ret,efct) ->
let ret_typ =
if effectful efct
then separate space [string "M"; fn_typ true ret]
else separate space [fn_typ false ret] in
- let arg_typs = match arg with
- | Typ_aux (Typ_tup typs, _) ->
- List.map (app_typ false) typs
- | _ -> [tup_typ false arg] in
+ let arg_typs = List.map (app_typ false) args 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
@@ -277,28 +275,30 @@ let doc_typ_lem, doc_atomic_typ_lem =
| _ -> app_typ atyp_needed ty
and app_typ atyp_needed ((Typ_aux (t, l)) as ty) = match t with
| Typ_app(Id_aux (Id "vector", _), [
- Typ_arg_aux (Typ_arg_nexp m, _);
- Typ_arg_aux (Typ_arg_order ord, _);
- Typ_arg_aux (Typ_arg_typ elem_typ, _)]) ->
+ A_aux (A_nexp m, _);
+ A_aux (A_order ord, _);
+ A_aux (A_typ elem_typ, _)]) ->
let tpp = match elem_typ with
| Typ_aux (Typ_id (Id_aux (Id "bit",_)),_) when !opt_mwords ->
string "mword " ^^ doc_nexp_lem (nexp_simp m)
(* (match nexp_simp m with
| (Nexp_aux(Nexp_constant i,_)) -> string "bitvector ty" ^^ doc_int i
| (Nexp_aux(Nexp_var _, _)) -> separate space [string "bitvector"; doc_nexp m]
- | _ -> raise (Reporting_basic.err_unreachable l __POS__
+ | _ -> raise (Reporting.err_unreachable l __POS__
"cannot pretty-print bitvector type with non-constant length")) *)
| _ -> string "list" ^^ space ^^ typ elem_typ in
if atyp_needed then parens tpp else tpp
- | Typ_app(Id_aux (Id "register", _), [Typ_arg_aux (Typ_arg_typ etyp, _)]) ->
+ | Typ_app(Id_aux (Id "register", _), [A_aux (A_typ etyp, _)]) ->
let tpp = string "register_ref regstate register_value " ^^ typ etyp in
if atyp_needed then parens tpp else tpp
| Typ_app(Id_aux (Id "range", _),_) ->
(string "integer")
| Typ_app(Id_aux (Id "implicit", _),_) ->
(string "integer")
- | Typ_app(Id_aux (Id "atom", _), [Typ_arg_aux(Typ_arg_nexp n,_)]) ->
+ | Typ_app(Id_aux (Id "atom", _), [A_aux(A_nexp n,_)]) ->
(string "integer")
+ | Typ_app(Id_aux (Id "atom_bool", _), [A_aux(A_bool nc,_)]) ->
+ (string "bool")
| Typ_app(id,args) ->
let tpp = (doc_id_lem_type id) ^^ space ^^ (separate_map space doc_typ_arg_lem args) in
if atyp_needed then parens tpp else tpp
@@ -316,22 +316,25 @@ let doc_typ_lem, doc_atomic_typ_lem =
* if we add a new Typ constructor *)
let tpp = typ ty in
if atyp_needed then parens tpp else tpp
- | Typ_exist (kids,_,ty) -> begin
+ | Typ_exist (kopts,_,ty) when List.for_all is_nat_kopt kopts -> begin
+ let kids = List.map kopt_kid kopts in
let tpp = typ ty in
let visible_vars = lem_tyvars_of_typ ty in
match List.filter (fun kid -> KidSet.mem kid visible_vars) kids with
| [] -> if atyp_needed then parens tpp else tpp
- | bad -> raise (Reporting_basic.err_general l
+ | bad -> raise (Reporting.err_general l
("Existential type variable(s) " ^
String.concat ", " (List.map string_of_kid bad) ^
" escape into Lem"))
end
+ | Typ_exist _ -> unreachable l __POS__ "Non-integer existentials currently unsupported in Lem" (* TODO *)
| Typ_bidir _ -> unreachable l __POS__ "Lem doesn't support bidir types"
| Typ_internal_unknown -> unreachable l __POS__ "escaped Typ_internal_unknown"
- and doc_typ_arg_lem (Typ_arg_aux(t,_)) = match t with
- | Typ_arg_typ t -> app_typ true t
- | Typ_arg_nexp n -> doc_nexp_lem (nexp_simp n)
- | Typ_arg_order o -> empty
+ and doc_typ_arg_lem (A_aux(t,_)) = match t with
+ | A_typ t -> app_typ true t
+ | A_nexp n -> doc_nexp_lem (nexp_simp n)
+ | A_order o -> empty
+ | A_bool _ -> empty
in typ', atomic_typ
(* Check for variables in types that would be pretty-printed. *)
@@ -341,10 +344,10 @@ let contains_t_pp_var ctxt (Typ_aux (t,a) as typ) =
let replace_typ_size ctxt env (Typ_aux (t,a)) =
match t with
- | Typ_app (Id_aux (Id "vector",_) as id, [Typ_arg_aux (Typ_arg_nexp size,_);ord;typ']) ->
+ | Typ_app (Id_aux (Id "vector",_) as id, [A_aux (A_nexp size,_);ord;typ']) ->
begin
let mk_typ nexp =
- Some (Typ_aux (Typ_app (id, [Typ_arg_aux (Typ_arg_nexp nexp,Parse_ast.Unknown);ord;typ']),a))
+ Some (Typ_aux (Typ_app (id, [A_aux (A_nexp nexp,Parse_ast.Unknown);ord;typ']),a))
in
match Type_check.solve env size with
| Some n -> mk_typ (nconstant n)
@@ -394,7 +397,7 @@ let doc_lit_lem (L_aux(lit,l)) =
| L_bin n -> failwith "Shouldn't happen" (*"(num_to_vec " ^ ("0b" ^ n) ^ ")" (*shouldn't happen*)*)
| L_undef ->
utf8string "(return (failwith \"undefined value of unsupported type\"))"
- | L_string s -> utf8string ("\"" ^ s ^ "\"")
+ | L_string s -> utf8string ("\"" ^ (String.escaped s) ^ "\"")
| L_real s ->
(* Lem does not support decimal syntax, so we translate a string
of the form "x.y" into the ratio (x * 10^len(y) + y) / 10^len(y).
@@ -408,14 +411,13 @@ let doc_lit_lem (L_aux(lit,l)) =
let denom = Big_int.pow_int_positive 10 (String.length f) in
(Big_int.add (Big_int.mul (Big_int.of_string i) denom) (Big_int.of_string f), denom)
| _ ->
- raise (Reporting_basic.Fatal_error
- (Reporting_basic.Err_syntax_locn (l, "could not parse real literal"))) in
+ raise (Reporting.Fatal_error
+ (Reporting.Err_syntax_locn (l, "could not parse real literal"))) in
parens (separate space (List.map string [
"realFromFrac"; Big_int.to_string num; Big_int.to_string denom]))
(* typ_doc is the doc for the type being quantified *)
let doc_quant_item vars_included (QI_aux (qi, _)) = match qi with
-| QI_id (KOpt_aux (KOpt_none kid, _))
| QI_id (KOpt_aux (KOpt_kind (_, kid), _)) ->
(match vars_included with
None -> doc_var kid
@@ -443,19 +445,19 @@ let rec typeclass_nexps (Typ_aux(t,l)) =
| Typ_id _
| Typ_var _
-> NexpSet.empty
- | Typ_fn (t1,t2,_) -> NexpSet.union (typeclass_nexps t1) (typeclass_nexps t2)
+ | Typ_fn (ts,t,_) -> List.fold_left NexpSet.union (typeclass_nexps t) (List.map typeclass_nexps ts)
| Typ_tup ts -> List.fold_left NexpSet.union NexpSet.empty (List.map typeclass_nexps ts)
| Typ_app (Id_aux (Id "vector",_),
- [Typ_arg_aux (Typ_arg_nexp size_nexp,_);
- _;Typ_arg_aux (Typ_arg_typ (Typ_aux (Typ_id (Id_aux (Id "bit",_)),_)),_)])
+ [A_aux (A_nexp size_nexp,_);
+ _;A_aux (A_typ (Typ_aux (Typ_id (Id_aux (Id "bit",_)),_)),_)])
| Typ_app (Id_aux (Id "itself",_),
- [Typ_arg_aux (Typ_arg_nexp size_nexp,_)]) ->
+ [A_aux (A_nexp size_nexp,_)]) ->
let size_nexp = nexp_simp size_nexp in
if is_nexp_constant size_nexp then NexpSet.empty else
NexpSet.singleton (orig_nexp size_nexp)
| Typ_app (id, args) ->
let add_arg_nexps nexps = function
- | Typ_arg_aux (Typ_arg_typ typ, _) ->
+ | A_aux (A_typ typ, _) ->
NexpSet.union nexps (typeclass_nexps typ)
| _ -> nexps
in
@@ -516,7 +518,7 @@ let rec doc_pat_lem ctxt apat_needed (P_aux (p,(l,annot)) as pa) = match p with
let ppp = brackets (separate_map semi (doc_pat_lem ctxt true) pats) in
if apat_needed then parens ppp else ppp
| P_vector_concat pats ->
- raise (Reporting_basic.err_unreachable l __POS__
+ raise (Reporting.err_unreachable l __POS__
"vector concatenation patterns should have been removed before pretty-printing")
| P_tup pats ->
(match pats with
@@ -531,13 +533,14 @@ let rec typ_needs_printed (Typ_aux (t,_) as typ) = match t with
| Typ_tup ts -> List.exists typ_needs_printed ts
| Typ_app (Id_aux (Id "itself",_),_) -> true
| Typ_app (_, targs) -> is_bitvector_typ typ || List.exists typ_needs_printed_arg targs
- | Typ_fn (t1,t2,_) -> typ_needs_printed t1 || typ_needs_printed t2
- | Typ_exist (kids,_,t) ->
+ | Typ_fn (ts,t,_) -> List.exists typ_needs_printed ts || typ_needs_printed t
+ | Typ_exist (kopts,_,t) ->
+ let kids = List.map kopt_kid kopts in (* TODO: Check this *)
let visible_kids = KidSet.inter (KidSet.of_list kids) (lem_tyvars_of_typ t) in
typ_needs_printed t && KidSet.is_empty visible_kids
| _ -> false
-and typ_needs_printed_arg (Typ_arg_aux (targ, _)) = match targ with
- | Typ_arg_typ t -> typ_needs_printed t
+and typ_needs_printed_arg (A_aux (targ, _)) = match targ with
+ | A_typ t -> typ_needs_printed t
| _ -> false
let contains_early_return exp =
@@ -556,13 +559,13 @@ let find_e_ids exp =
let typ_id_of (Typ_aux (typ, l)) = match typ with
| Typ_id id -> id
- | Typ_app (register, [Typ_arg_aux (Typ_arg_typ (Typ_aux (Typ_id id, _)), _)])
+ | Typ_app (register, [A_aux (A_typ (Typ_aux (Typ_id id, _)), _)])
when string_of_id register = "register" -> id
| Typ_app (id, _) -> id
- | _ -> raise (Reporting_basic.err_unreachable l __POS__ "failed to get type id")
+ | _ -> raise (Reporting.err_unreachable l __POS__ "failed to get type id")
let prefix_recordtype = true
-let report = Reporting_basic.err_unreachable
+let report = Reporting.err_unreachable
let doc_exp_lem, doc_let_lem =
let rec top_exp (ctxt : context) (aexp_needed : bool)
(E_aux (e, (l,annot)) as full_exp) =
@@ -635,7 +638,7 @@ let doc_exp_lem, doc_let_lem =
| _ ->
liftR ((prefix 2 1) (string "write_reg") (doc_lexp_deref_lem ctxt le ^/^ expY e)))
| E_vector_append(le,re) ->
- raise (Reporting_basic.err_unreachable l __POS__
+ raise (Reporting.err_unreachable l __POS__
"E_vector_append should have been rewritten before pretty-printing")
| E_cons(le,re) -> doc_op (group (colon^^colon)) (expY le) (expY re)
| E_if(c,t,e) -> wrap_parens (align (if_exp ctxt false c t e))
@@ -666,7 +669,7 @@ let doc_exp_lem, doc_let_lem =
| (P_aux (P_var (P_aux (P_id id, _), _), _))
| (P_aux (P_id id, _))), _), _),
body), _), _), _)), _)), _) -> id, body
- | _ -> raise (Reporting_basic.err_unreachable l __POS__ ("Unable to find loop variable in " ^ string_of_exp body)) in
+ | _ -> raise (Reporting.err_unreachable l __POS__ ("Unable to find loop variable in " ^ string_of_exp body)) in
let step = match ord_exp with
| E_aux (E_lit (L_aux (L_false, _)), _) ->
parens (separate space [string "integerNegate"; expY exp3])
@@ -697,7 +700,7 @@ let doc_exp_lem, doc_let_lem =
(prefix 2 1 (group body_lambda) (expN body))
)
)
- | _ -> raise (Reporting_basic.err_unreachable l __POS__
+ | _ -> raise (Reporting.err_unreachable l __POS__
"Unexpected number of arguments for loop combinator")
end
| Id_aux (Id (("while" | "until") as combinator), _) ->
@@ -734,7 +737,7 @@ let doc_exp_lem, doc_let_lem =
(parens (prefix 2 1 (group lambda) (expN cond)))
(parens (prefix 2 1 (group lambda) (expN body))))
)
- | _ -> raise (Reporting_basic.err_unreachable l __POS__
+ | _ -> raise (Reporting.err_unreachable l __POS__
"Unexpected number of arguments for loop combinator")
end
| Id_aux (Id "early_return", _) ->
@@ -754,7 +757,7 @@ let doc_exp_lem, doc_let_lem =
| _ -> aexp_needed, epp
in
if aexp_needed then parens tepp else tepp
- | _ -> raise (Reporting_basic.err_unreachable l __POS__
+ | _ -> raise (Reporting.err_unreachable l __POS__
"Unexpected number of arguments for early_return builtin")
end
| _ ->
@@ -790,10 +793,10 @@ let doc_exp_lem, doc_let_lem =
end
end
| E_vector_access (v,e) ->
- raise (Reporting_basic.err_unreachable l __POS__
+ raise (Reporting.err_unreachable l __POS__
"E_vector_access should have been rewritten before pretty-printing")
| E_vector_subrange (v,e1,e2) ->
- raise (Reporting_basic.err_unreachable l __POS__
+ raise (Reporting.err_unreachable l __POS__
"E_vector_subrange should have been rewritten before pretty-printing")
| E_field((E_aux(_,(l,fannot)) as fexp),id) ->
let ft = typ_of_annot (l,fannot) in
@@ -828,7 +831,7 @@ let doc_exp_lem, doc_let_lem =
| E_cast(typ,e) -> expV aexp_needed e
| E_tuple exps ->
parens (align (group (separate_map (comma ^^ break 1) expN exps)))
- | E_record(FES_aux(FES_Fexps(fexps,_),_)) ->
+ | E_record fexps ->
let recordtyp = match destruct_tannot annot with
| Some (env, Typ_aux (Typ_id tid,_), _)
| Some (env, Typ_aux (Typ_app (tid, _), _), _) ->
@@ -838,7 +841,7 @@ let doc_exp_lem, doc_let_lem =
wrap_parens (anglebars (space ^^ (align (separate_map
(semi_sp ^^ break 1)
(doc_fexp ctxt recordtyp) fexps)) ^^ space))
- | E_record_update(e,(FES_aux(FES_Fexps(fexps,_),_))) ->
+ | E_record_update(e, fexps) ->
let recordtyp = match destruct_tannot annot with
| Some (env, Typ_aux (Typ_id tid,_), _)
| Some (env, Typ_aux (Typ_app (tid, _), _), _)
@@ -850,7 +853,7 @@ let doc_exp_lem, doc_let_lem =
let t = Env.base_typ_of (env_of full_exp) (typ_of full_exp) in
let start, (len, order, etyp) =
if is_vector_typ t then vector_start_index t, vector_typ_args_of t
- else raise (Reporting_basic.err_unreachable l __POS__
+ else raise (Reporting.err_unreachable l __POS__
"E_vector of non-vector type") in
let dir,dir_out = if is_order_inc order then (true,"true") else (false, "false") in
let start = match nexp_simp start with
@@ -877,10 +880,10 @@ let doc_exp_lem, doc_let_lem =
else (epp,aexp_needed) in
if aexp_needed then parens (align epp) else epp
| E_vector_update(v,e1,e2) ->
- raise (Reporting_basic.err_unreachable l __POS__
+ raise (Reporting.err_unreachable l __POS__
"E_vector_update should have been rewritten before pretty-printing")
| E_vector_update_subrange(v,e1,e2,e3) ->
- raise (Reporting_basic.err_unreachable l __POS__
+ raise (Reporting.err_unreachable l __POS__
"E_vector_update should have been rewritten before pretty-printing")
| E_list exps ->
brackets (separate_map semi (expN) exps)
@@ -898,7 +901,7 @@ let doc_exp_lem, doc_let_lem =
(separate_map (break 1) (doc_case ctxt) pexps) ^/^
(string "end)")))
else
- raise (Reporting_basic.err_todo l "Warning: try-block around pure expression")
+ raise (Reporting.err_todo l "Warning: try-block around pure expression")
| E_throw e ->
align (liftR (separate space [string "throw"; expY e]))
| E_exit e -> liftR (separate space [string "exit"; expY e])
@@ -935,7 +938,7 @@ let doc_exp_lem, doc_let_lem =
(match nexp_simp nexp with
| Nexp_aux (Nexp_constant i, _) -> doc_lit_lem (L_aux (L_num i, l))
| _ ->
- raise (Reporting_basic.err_unreachable l __POS__
+ raise (Reporting.err_unreachable l __POS__
"pretty-printing non-constant sizeof expressions to Lem not supported"))
| E_return r ->
let ta =
@@ -951,7 +954,7 @@ let doc_exp_lem, doc_let_lem =
align (parens (string "early_return" ^//^ expV true r ^//^ ta))
| E_constraint _ -> string "true"
| E_internal_value _ ->
- raise (Reporting_basic.err_unreachable l __POS__
+ raise (Reporting.err_unreachable l __POS__
"unsupported internal expression encountered while pretty-printing")
and if_exp ctxt (elseif : bool) c t e =
let if_pp = string (if elseif then "else if" else "if") in
@@ -984,7 +987,7 @@ let doc_exp_lem, doc_let_lem =
group (prefix 3 1 (separate space [pipe; doc_pat_lem ctxt false pat;arrow])
(group (top_exp ctxt false e)))
| Pat_aux(Pat_when(_,_,_),(l,_)) ->
- raise (Reporting_basic.err_unreachable l __POS__
+ raise (Reporting.err_unreachable l __POS__
"guarded pattern expression should have been rewritten before pretty-printing")
and doc_lexp_deref_lem ctxt ((LEXP_aux(lexp,(l,annot))) as le) = match lexp with
@@ -994,7 +997,7 @@ let doc_exp_lem, doc_let_lem =
| LEXP_cast (typ,id) -> doc_id_lem (append_id id "_ref")
| LEXP_tup lexps -> parens (separate_map comma_sp (doc_lexp_deref_lem ctxt) lexps)
| _ ->
- raise (Reporting_basic.err_unreachable l __POS__ ("doc_lexp_deref_lem: Unsupported lexp"))
+ raise (Reporting.err_unreachable l __POS__ ("doc_lexp_deref_lem: Unsupported lexp"))
(* expose doc_exp_lem and doc_let *)
in top_exp, let_exp
@@ -1009,10 +1012,12 @@ let rec doc_range_lem (BF_aux(r,_)) = match r with
| BF_concat(ir1,ir2) -> (doc_range ir1) ^^ comma ^^ (doc_range ir2)
let doc_typdef_lem (TD_aux(td, (l, annot))) = match td with
- | TD_abbrev(id,nm,(TypSchm_aux (TypSchm_ts (typq, _), _) as typschm)) ->
+ | TD_abbrev(id,typq,A_aux (A_typ typ, _)) ->
+ let typschm = TypSchm_aux (TypSchm_ts (typq, typ), l) in
doc_op equals
(separate space [string "type"; doc_id_lem_type id; doc_typquant_items_lem None typq])
(doc_typschm_lem false typschm)
+ | TD_abbrev _ -> empty
| TD_record(id,nm,typq,fs,_) ->
let fname fid = if prefix_recordtype && string_of_id id <> "regstate"
then concat [doc_id_lem id;string "_";doc_id_lem_type fid;]
@@ -1022,9 +1027,8 @@ let doc_typdef_lem (TD_aux(td, (l, annot))) = match td with
let rectyp = match typq with
| TypQ_aux (TypQ_tq qs, _) ->
let quant_item = function
- | QI_aux (QI_id (KOpt_aux (KOpt_none kid, _)), l)
| QI_aux (QI_id (KOpt_aux (KOpt_kind (_, kid), _)), l) ->
- [Typ_arg_aux (Typ_arg_nexp (Nexp_aux (Nexp_var kid, l)), l)]
+ [A_aux (A_nexp (Nexp_aux (Nexp_var kid, l)), l)]
| _ -> [] in
let targs = List.concat (List.map quant_item qs) in
mk_typ (Typ_app (id, targs))
@@ -1033,8 +1037,8 @@ let doc_typdef_lem (TD_aux(td, (l, annot))) = match td with
(* let doc_field (ftyp, fid) =
let reftyp =
mk_typ (Typ_app (Id_aux (Id "field_ref", Parse_ast.Unknown),
- [mk_typ_arg (Typ_arg_typ rectyp);
- mk_typ_arg (Typ_arg_typ ftyp)])) in
+ [mk_typ_arg (A_typ rectyp);
+ mk_typ_arg (A_typ ftyp)])) in
let rfannot = doc_tannot_lem empty_ctxt env false reftyp in
let get, set =
string "rec_val" ^^ dot ^^ fname fid,
@@ -1049,7 +1053,7 @@ let doc_typdef_lem (TD_aux(td, (l, annot))) = match td with
match nexp_simp start with
| Nexp_aux (Nexp_constant i, _) -> (i, is_order_inc ord)
| _ ->
- raise (Reporting_basic.err_unreachable Parse_ast.Unknown __POS__
+ raise (Reporting.err_unreachable Parse_ast.Unknown __POS__
("register " ^ string_of_id id ^ " has non-constant start index " ^ string_of_nexp start))
with
| _ -> (Big_int.zero, true) in
@@ -1229,44 +1233,40 @@ let doc_typdef_lem (TD_aux(td, (l, annot))) = match td with
fromInterpValuePP ^^ hardline ^^ hardline ^^
fromToInterpValuePP ^^ hardline
else empty)
- | _ -> raise (Reporting_basic.err_unreachable l __POS__ "register with non-constant indices")
+ | _ -> raise (Reporting.err_unreachable l __POS__ "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 args_of_typs l env typs =
let arg i typ =
let id = mk_id ("arg" ^ string_of_int i) in
P_aux (P_id id, (l, mk_tannot env typ no_effect)),
E_aux (E_id id, (l, mk_tannot 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 rec untuple_args_pat (P_aux (paux, ((l, _) as annot)) as pat) arg_typs =
let env = env_of_annot annot in
- let (Typ_aux (taux, _)) = typ_of_annot annot in
let identity = (fun body -> body) in
- match paux, taux with
+ match paux, arg_typs with
| P_tup [], _ ->
let annot = (l, mk_tannot Env.empty unit_typ no_effect) in
[P_aux (P_lit (mk_lit L_unit), annot)], identity
- | P_tup pats, _ -> pats, identity
- | P_wild, Typ_tup typs ->
+ | P_wild, (_::_::_) ->
let wild typ = P_aux (P_wild, (l, mk_tannot env typ no_effect)) in
- List.map wild typs, identity
- | P_typ (_, pat), _ -> untuple_args_pat pat
- | P_as _, Typ_tup _ | P_id _, Typ_tup _ ->
- let argpats, argexps = args_of_typ l env (pat_typ_of pat) in
+ List.map wild arg_typs, identity
+ | P_typ (_, pat), _ -> untuple_args_pat pat arg_typs
+ | P_as _, (_::_::_)
+ | P_id _, (_::_::_) ->
+ let argpats, argexps = args_of_typs l env arg_typs 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
+ (* The type checker currently has a special case for a single arg type; if
+ that is removed, then remove the next case. *)
+ | P_tup pats, [_] -> [pat], identity
+ | P_tup pats, _ -> pats, identity
| _, _ ->
[pat], identity
-let doc_rec_lem force_rec (Rec_aux(r,_)) = match r with
- | Rec_nonrec when not force_rec -> space
- | _ -> space ^^ string "rec" ^^ space
-
let doc_tannot_opt_lem (Typ_annot_opt_aux(t,_)) = match t with
| Typ_annot_opt_some(tq,typ) -> (*doc_typquant_lem tq*) (doc_typ_lem typ)
| Typ_annot_opt_none -> empty
@@ -1279,17 +1279,21 @@ let doc_fun_body_lem ctxt exp =
let doc_funcl_lem (FCL_aux(FCL_Funcl(id, pexp), annot)) =
let typ = typ_of_annot annot in
+ let arg_typs = match typ with
+ | Typ_aux (Typ_fn (arg_typs, typ_ret, _), _) -> arg_typs
+ | Typ_aux (_, l) -> raise (unreachable l __POS__ "Non-function type for funcl")
+ in
let pat,guard,exp,(l,_) = destruct_pexp pexp in
let ctxt =
{ early_ret = contains_early_return exp;
bound_nexps = NexpSet.union (lem_nexps_of_typ typ) (typeclass_nexps typ);
top_env = env_of_annot annot } in
- let pats, bind = untuple_args_pat pat in
+ let pats, bind = untuple_args_pat pat arg_typs in
let patspp = separate_map space (doc_pat_lem ctxt true) pats in
let _ = match guard with
| None -> ()
| _ ->
- raise (Reporting_basic.err_unreachable l __POS__
+ raise (Reporting.err_unreachable l __POS__
"guarded pattern expression should have been rewritten before pretty-printing") in
group (prefix 3 1
(separate space [doc_id_lem id; patspp; equals])
@@ -1316,9 +1320,19 @@ let doc_mutrec_lem = function
let rec doc_fundef_lem (FD_aux(FD_function(r, typa, efa, fcls),fannot) as fd) =
match fcls with
| [] -> failwith "FD_function with empty function list"
- | FCL_aux (FCL_Funcl(id,_),annot) :: _
- when not (Env.is_extern id (env_of_annot annot) "lem") ->
- string "let" ^^ (doc_rec_lem (List.length fcls > 1) r) ^^ (doc_fundef_rhs_lem fd)
+ | FCL_aux (FCL_Funcl(id, pexp),annot) :: _
+ when not (Env.is_extern id (env_of_annot annot) "lem") ->
+ (* Output "rec" modifier if function calls itself. Mutually recursive
+ functions are handled separately by doc_mutrec_lem. *)
+ let is_funcl_rec =
+ fold_pexp
+ { (pure_exp_alg false (||)) with
+ e_app = (fun (id', args) -> List.fold_left (||) (Id.compare id id' = 0) args);
+ e_app_infix = (fun (l, id', r) -> l || (Id.compare id id' = 0) || r) }
+ pexp
+ in
+ let doc_rec = if is_funcl_rec then [string "rec"] else [] in
+ separate space ([string "let"] @ doc_rec @ [doc_fundef_rhs_lem fd])
| _ -> empty
@@ -1343,8 +1357,8 @@ let doc_dec_lem (DEC_aux (reg, ((l, _) as annot))) =
string o;
string "[]"]))
^/^ hardline
- else raise (Reporting_basic.err_unreachable l __POS__ ("can't deal with register type " ^ string_of_typ typ))
- else raise (Reporting_basic.err_unreachable l __POS__ ("can't deal with register type " ^ string_of_typ typ)) *)
+ else raise (Reporting.err_unreachable l __POS__ ("can't deal with register type " ^ string_of_typ typ))
+ else raise (Reporting.err_unreachable l __POS__ ("can't deal with register type " ^ string_of_typ typ)) *)
| DEC_alias(id,alspec) -> empty
| DEC_typ_alias(typ,id,alspec) -> empty
@@ -1370,7 +1384,7 @@ let is_field_accessor regtypes fdef =
let doc_regtype_fields (tname, (n1, n2, fields)) =
let i1, i2 = match n1, n2 with
| Nexp_aux(Nexp_constant i1,_),Nexp_aux(Nexp_constant i2,_) -> i1, i2
- | _ -> raise (Reporting_basic.err_typ Parse_ast.Unknown
+ | _ -> raise (Reporting.err_typ Parse_ast.Unknown
("Non-constant indices in register type " ^ tname)) in
let dir_b = i1 < i2 in
let dir = (if dir_b then "true" else "false") in
@@ -1378,7 +1392,7 @@ let doc_regtype_fields (tname, (n1, n2, fields)) =
let i, j = match fr with
| BF_aux (BF_single i, _) -> (i, i)
| BF_aux (BF_range (i, j), _) -> (i, j)
- | _ -> raise (Reporting_basic.err_unreachable Parse_ast.Unknown __POS__
+ | _ -> raise (Reporting.err_unreachable Parse_ast.Unknown __POS__
("Unsupported type in field " ^ string_of_id fid ^ " of " ^ tname)) in
let fsize = Big_int.succ (Big_int.abs (Big_int.sub i j)) in
(* TODO Assumes normalised, decreasing bitvector slices; however, since
@@ -1387,8 +1401,8 @@ let doc_regtype_fields (tname, (n1, n2, fields)) =
let ftyp = vector_typ (nconstant fsize) dec_ord bit_typ in
let reftyp =
mk_typ (Typ_app (Id_aux (Id "field_ref", Parse_ast.Unknown),
- [mk_typ_arg (Typ_arg_typ (mk_id_typ (mk_id tname)));
- mk_typ_arg (Typ_arg_typ ftyp)])) in
+ [mk_typ_arg (A_typ (mk_id_typ (mk_id tname)));
+ mk_typ_arg (A_typ ftyp)])) in
let rfannot = doc_tannot_lem empty_ctxt Env.empty false reftyp in
doc_op equals
(concat [string "let "; parens (concat [string tname; underscore; doc_id_lem fid; rfannot])])
@@ -1419,6 +1433,7 @@ let rec doc_def_lem def =
| DEF_kind _ -> empty
| DEF_mapdef (MD_aux (_, (l, _))) -> unreachable l __POS__ "Lem doesn't support mappings"
+ | DEF_pragma _ -> empty
let find_exc_typ defs =
let is_exc_typ_def = function