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.ml206
1 files changed, 168 insertions, 38 deletions
diff --git a/src/pretty_print_lem.ml b/src/pretty_print_lem.ml
index 9b66331b..2971081e 100644
--- a/src/pretty_print_lem.ml
+++ b/src/pretty_print_lem.ml
@@ -140,6 +140,12 @@ let is_regtyp (Typ_aux (typ, _)) env = match typ with
| Typ_id(id) when Env.is_regtyp id env -> true
| _ -> false
+let doc_nexp_lem (Nexp_aux (nexp, l) as full_nexp) = match nexp with
+ | Nexp_constant i -> string ("ty" ^ string_of_int i)
+ | Nexp_var v -> string (string_of_kid v)
+ | _ -> raise (Reporting_basic.err_unreachable l
+ ("cannot pretty-print non-atomic nexp \"" ^ string_of_nexp full_nexp ^ "\""))
+
let doc_typ_lem, doc_atomic_typ_lem =
(* following the structure of parser for precedence *)
let rec typ regtypes ty = fn_typ regtypes true ty
@@ -168,17 +174,19 @@ let doc_typ_lem, doc_atomic_typ_lem =
Typ_arg_aux (Typ_arg_typ elem_typ, _)]) ->
let tpp = match elem_typ with
| Typ_aux (Typ_id (Id_aux (Id "bit",_)),_) ->
- (match simplify_nexp m with
+ string "bitvector " ^^ doc_nexp_lem (simplify_nexp m)
+ (* (match simplify_nexp 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
- "cannot pretty-print bitvector type with non-constant length"))
+ "cannot pretty-print bitvector type with non-constant length")) *)
| _ -> string "vector" ^^ space ^^ typ regtypes elem_typ in
if atyp_needed then parens tpp else tpp
| Typ_app(Id_aux (Id "register", _), [Typ_arg_aux (Typ_arg_typ etyp, _)]) ->
(* TODO: Better distinguish register names and contents? *)
(* fn_typ regtypes atyp_needed etyp *)
- (string "register")
+ let tpp = (string "register_ref regstate " ^^ typ regtypes etyp) in
+ if atyp_needed then parens tpp else tpp
| Typ_app(Id_aux (Id "range", _),_) ->
(string "integer")
| Typ_app(Id_aux (Id "implicit", _),_) ->
@@ -206,7 +214,7 @@ let doc_typ_lem, doc_atomic_typ_lem =
if atyp_needed then parens tpp else tpp
and doc_typ_arg_lem regtypes (Typ_arg_aux(t,_)) = match t with
| Typ_arg_typ t -> app_typ regtypes true t
- | Typ_arg_nexp n -> empty
+ | Typ_arg_nexp n -> doc_nexp_lem (simplify_nexp n)
| Typ_arg_order o -> empty
in typ', atomic_typ
@@ -233,10 +241,10 @@ and contains_t_arg_pp_var (Typ_arg_aux (targ, _)) = match targ with
| _ -> false
let doc_tannot_lem regtypes eff typ =
- if contains_t_pp_var typ then empty
- else
+ (* if contains_t_pp_var typ then empty
+ else *)
let ta = doc_typ_lem regtypes typ in
- if eff then string " : M " ^^ parens ta
+ if eff then string " : _M " ^^ parens ta
else string " : " ^^ ta
(* doc_lit_lem gets as an additional parameter the type information from the
@@ -345,6 +353,13 @@ let contains_early_return exp =
{ (Rewriter.compute_exp_alg false (||))
with e_return = (fun (_, r) -> (true, E_return r)) } 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, _)), _)])
+ when string_of_id register = "register" -> id
+ | Typ_app (id, _) -> id
+ | _ -> raise (Reporting_basic.err_unreachable l "failed to get type id")
+
let prefix_recordtype = true
let report = Reporting_basic.err_unreachable
let doc_exp_lem, doc_let_lem =
@@ -364,14 +379,18 @@ let doc_exp_lem, doc_let_lem =
(match le_act (*, t, tag*) with
| LEXP_vector_range (le,e2,e3) ->
(match le with
- | LEXP_aux (LEXP_field (le,id), lannot) ->
- if is_bit_typ (typ_of_annot lannot) then
+ | LEXP_aux (LEXP_field ((LEXP_aux (_, lannot) as le),id), fannot) ->
+ if is_bit_typ (typ_of_annot fannot) then
raise (report l "indexing a register's (single bit) bitfield not supported")
else
+ let field_ref =
+ doc_id_lem (typ_id_of (typ_of_annot lannot)) ^^
+ underscore ^^
+ doc_id_lem id in
liftR ((prefix 2 1)
(string "write_reg_field_range")
(align (doc_lexp_deref_lem regtypes early_ret le ^^ space^^
- string_lit (doc_id_lem id) ^/^ expY e2 ^/^ expY e3 ^/^ expY e)))
+ field_ref ^/^ expY e2 ^/^ expY e3 ^/^ expY e)))
| _ ->
liftR ((prefix 2 1)
(string "write_reg_range")
@@ -379,27 +398,35 @@ let doc_exp_lem, doc_let_lem =
)
| LEXP_vector (le,e2) when is_bit_typ t ->
(match le with
- | LEXP_aux (LEXP_field (le,id), lannot) ->
- if is_bit_typ (typ_of_annot lannot) then
+ | LEXP_aux (LEXP_field ((LEXP_aux (_, lannot) as le),id), fannot) ->
+ if is_bit_typ (typ_of_annot fannot) then
raise (report l "indexing a register's (single bit) bitfield not supported")
else
+ let field_ref =
+ doc_id_lem (typ_id_of (typ_of_annot lannot)) ^^
+ underscore ^^
+ doc_id_lem id in
liftR ((prefix 2 1)
(string "write_reg_field_bit")
- (align (doc_lexp_deref_lem regtypes early_ret le ^^ space ^^ doc_id_lem id ^/^ expY e2 ^/^ expY e)))
+ (align (doc_lexp_deref_lem regtypes early_ret le ^^ space ^^ field_ref ^/^ expY e2 ^/^ expY e)))
| _ ->
liftR ((prefix 2 1)
(string "write_reg_bit")
(doc_lexp_deref_lem regtypes early_ret le ^^ space ^^ expY e2 ^/^ expY e))
)
- | LEXP_field (le,id) when is_bit_typ t ->
+ (* | LEXP_field (le,id) when is_bit_typ t ->
liftR ((prefix 2 1)
(string "write_reg_bitfield")
- (doc_lexp_deref_lem regtypes early_ret le ^^ space ^^ string_lit(doc_id_lem id) ^/^ expY e))
- | LEXP_field (le,id) ->
+ (doc_lexp_deref_lem regtypes early_ret le ^^ space ^^ string_lit(doc_id_lem id) ^/^ expY e)) *)
+ | LEXP_field ((LEXP_aux (_, lannot) as le),id) ->
+ let field_ref =
+ doc_id_lem (typ_id_of (typ_of_annot lannot)) ^^
+ underscore ^^
+ doc_id_lem id in
liftR ((prefix 2 1)
(string "write_reg_field")
(doc_lexp_deref_lem regtypes early_ret le ^^ space ^^
- string_lit(doc_id_lem id) ^/^ expY e))
+ field_ref ^/^ expY e))
(* | (LEXP_id id | LEXP_cast (_,id)), t, Alias alias_info ->
(match alias_info with
| Alias_field(reg,field) ->
@@ -561,8 +588,7 @@ let doc_exp_lem, doc_let_lem =
when Env.is_regtyp tid env ->
let t = (* Env.base_typ_of (env_of full_exp) *) (typ_of full_exp) in
let eff = effect_of full_exp in
- let field_f = string "get" ^^ underscore ^^
- doc_id_lem tid ^^ underscore ^^ doc_id_lem id in
+ let field_f = doc_id_lem tid ^^ underscore ^^ doc_id_lem id ^^ dot ^^ string "get_field" in
let (ta,aexp_needed) =
if contains_bitvector_typ t && not (contains_t_pp_var t)
then (doc_tannot_lem regtypes (effectful eff) t, true)
@@ -669,7 +695,8 @@ let doc_exp_lem, doc_let_lem =
(doc_fexp regtypes early_ret recordtyp) fexps)) ^^ space) in
if aexp_needed then parens epp else epp
| E_record_update(e,(FES_aux(FES_Fexps(fexps,_),_))) ->
- let recordtyp = match annot with
+ let (E_aux (_, (_, eannot))) = e in
+ let recordtyp = match eannot with
| Some (env, Typ_aux (Typ_id tid,_), _) when Env.is_record tid env ->
tid
| _ -> raise (report l "cannot get record type") in
@@ -984,15 +1011,41 @@ let doc_typdef_lem regtypes (TD_aux(td, (l, _))) = match td with
doc_op equals (concat [string "type"; space; doc_id_lem_type id])
(doc_typschm_lem regtypes false typschm)
| TD_record(id,nm,typq,fs,_) ->
- let f_pp (typ,fid) =
- let fname = if prefix_recordtype
- then concat [doc_id_lem id;string "_";doc_id_lem_type fid;]
- else doc_id_lem_type fid in
- concat [fname;space;colon;space;doc_typ_lem regtypes typ; semi] in
- let fs_doc = group (separate_map (break 1) f_pp fs) in
+ let fname fid = if prefix_recordtype
+ then concat [doc_id_lem id;string "_";doc_id_lem_type fid;]
+ else doc_id_lem_type fid in
+ let f_pp (typ,fid) =
+ concat [fname fid;space;colon;space;doc_typ_lem regtypes typ; semi] in
+ 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)]
+ | _ -> [] in
+ let targs = List.concat (List.map quant_item qs) in
+ mk_typ (Typ_app (id, targs))
+ | TypQ_aux (TypQ_no_forall, _) -> mk_id_typ id in
+ let fs_doc = group (separate_map (break 1) f_pp fs) in
+ 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
+ let rfannot = doc_tannot_lem regtypes false reftyp in
+ let get, set =
+ string "rec_val" ^^ dot ^^ fname fid,
+ anglebars (space ^^ string "rec_val with " ^^
+ (doc_op equals (fname fid) (string "v")) ^^ space) in
doc_op equals
- (concat [string "type"; space; doc_id_lem_type id;])
- ((*doc_typquant_lem typq*) (anglebars (space ^^ align fs_doc ^^ space)))
+ (concat [string "let "; parens (concat [doc_id_lem id; underscore; doc_id_lem fid; rfannot])])
+ (anglebars (concat [space;
+ doc_op equals (string "get_field") (parens (doc_op arrow (string "fun rec_val") get)); semi_sp;
+ doc_op equals (string "set_field") (parens (doc_op arrow (string "fun rec_val v") set)); space])) in
+ doc_op equals
+ (separate space [string "type"; doc_id_lem_type id; doc_typquant_items_lem typq])
+ ((*doc_typquant_lem typq*) (anglebars (space ^^ align fs_doc ^^ space))) ^^ hardline ^^
+ separate_map hardline doc_field fs
| TD_variant(id,nm,typq,ar,_) ->
(match id with
| Id_aux ((Id "read_kind"),_) -> empty
@@ -1196,27 +1249,38 @@ let doc_typdef_lem regtypes (TD_aux(td, (l, _))) = match td with
| BF_aux (BF_single i, _) -> (i, i)
| BF_aux (BF_range (i, j), _) -> (i, j)
| _ -> raise (Reporting_basic.err_unreachable l "unsupported field type") in
+ let fsize = if dir_b then j-i+1 else i-j+1 in
+ let ftyp = vector_typ (nconstant i) (nconstant fsize) 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 id));
+ mk_typ_arg (Typ_arg_typ ftyp)])) in
+ let rfannot = doc_tannot_lem regtypes false reftyp in
let get, set =
"bitvector_subrange" ^ dir_suffix ^ " (reg, " ^ string_of_int i ^ ", " ^ string_of_int j ^ ")",
"bitvector_update" ^ dir_suffix ^ " (reg, " ^ string_of_int i ^ ", " ^ string_of_int j ^ ", v)" in
doc_op equals
- (concat [string "let get_"; doc_id_lem id; underscore; doc_id_lem fid;
- space; parens (string "reg" ^^ tannot)]) (string get) ^^
- hardline ^^
- doc_op equals
+ (concat [string "let "; parens (concat [doc_id_lem id; underscore; doc_id_lem fid; rfannot])])
+ (concat [
+ space; langlebar; string (" get_field = (fun reg -> " ^ get ^ ");"); hardline;
+ space; space; space; string (" set_field = (fun reg v -> " ^ set ^ ") "); ranglebar])
+ (* string " = <|" (*; parens (string "reg" ^^ tannot) *)]) ^^ hardline ^^
+ string (" get_field = (fun reg -> " ^ get ^ ");") ^^ hardline ^^
+ string (" set_field = (fun reg v -> " ^ set ^") |>") *)
+ (* doc_op equals
(concat [string "let set_"; doc_id_lem id; underscore; doc_id_lem fid;
- space; parens (separate comma_sp [parens (string "reg" ^^ tannot); string "v"])]) (string set)
+ space; parens (separate comma_sp [parens (string "reg" ^^ tannot); string "v"])]) (string set) *)
in
doc_op equals
(concat [string "type";space;doc_id_lem id])
(doc_typ_lem regtypes vtyp)
^^ hardline ^^
- doc_op equals
+ (* doc_op equals
(concat [string "let";space;string "build_";doc_id_lem id;space;string "regname"])
(string "Register" ^^ space ^^
align (separate space [string "regname"; doc_int size; doc_int i1; dir;
break 0 ^^ brackets (align doc_rids)]))
- ^^ hardline ^^
+ ^^ hardline ^^ *)
doc_op equals
(concat [string "let";space;string "cast_";doc_id_lem id;space;string "reg"])
(string "reg")
@@ -1331,7 +1395,8 @@ let rec doc_fundef_lem regtypes (FD_aux(FD_function(r, typa, efa, fcls),fannot))
let doc_dec_lem (DEC_aux (reg, ((l, _) as annot))) =
match reg with
| DEC_reg(typ,id) ->
- let env = env_of_annot annot in
+ empty
+ (* let env = env_of_annot annot in
(match typ with
| Typ_aux (Typ_id idt, _) when Env.is_regtyp idt env ->
separate space [string "let";doc_id_lem id;equals;
@@ -1354,7 +1419,7 @@ let doc_dec_lem (DEC_aux (reg, ((l, _) as annot))) =
else raise (Reporting_basic.err_unreachable l
("can't deal with register type " ^ string_of_typ typ))
else raise (Reporting_basic.err_unreachable l
- ("can't deal with register type " ^ string_of_typ typ)))
+ ("can't deal with register type " ^ string_of_typ typ))) *)
| DEC_alias(id,alspec) -> empty
| DEC_typ_alias(typ,id,alspec) -> empty
@@ -1397,9 +1462,50 @@ let find_regtypes (Defs defs) =
| _ -> acc
) [] defs
-let pp_defs_lem (types_file,types_modules) (prompt_file,prompt_modules) (state_file,state_modules) d top_line =
+let find_registers (Defs defs) =
+ List.fold_left
+ (fun acc def ->
+ match def with
+ | DEF_reg_dec (DEC_aux(DEC_reg (typ, id),_)) -> (typ, id) :: acc
+ | _ -> acc
+ ) [] defs
+
+let doc_regstate_lem regtypes registers =
+ let l = Parse_ast.Unknown in
+ let annot = (l, None) in
+ let regstate = match registers with
+ | [] ->
+ TD_abbrev (
+ Id_aux (Id "regstate", l),
+ Name_sect_aux (Name_sect_none, l),
+ TypSchm_aux (TypSchm_ts (TypQ_aux (TypQ_tq [], l), unit_typ), l))
+ | _ ->
+ TD_record (
+ Id_aux (Id "regstate", l),
+ Name_sect_aux (Name_sect_none, l),
+ TypQ_aux (TypQ_tq [], l),
+ registers,
+ false) in
+ concat [
+ doc_typdef_lem regtypes (TD_aux (regstate, annot)); hardline;
+ hardline;
+ string "type _M 'a = M regstate 'a"
+ ]
+
+let doc_register_refs_lem regtypes registers =
+ let doc_register_ref (typ, id) =
+ let idd = doc_id_lem id in
+ let field = if prefix_recordtype then string "regstate_" ^^ idd else idd in
+ concat [string "let "; idd; string " = <|"; hardline;
+ string " read_from = (fun s -> s."; field; string ");"; hardline;
+ string " write_to = (fun s v -> (<| s with "; field; string " = v |>)) |>"] in
+ separate_map hardline doc_register_ref registers
+
+let pp_defs_lem (types_file,types_modules) (types_seq_file,types_seq_modules) (prompt_file,prompt_modules) (state_file,state_modules) d top_line =
let regtypes = find_regtypes d in
let (typdefs,valdefs) = doc_defs_lem regtypes d in
+ let regstate_def = doc_regstate_lem regtypes (find_registers d) in
+ let register_refs = doc_register_refs_lem regtypes (find_registers d) in
(print types_file)
(concat
[string "(*" ^^ (string top_line) ^^ string "*)";hardline;
@@ -1418,6 +1524,30 @@ let pp_defs_lem (types_file,types_modules) (prompt_file,prompt_modules) (state_f
hardline]
else empty;
typdefs]);
+ (print types_seq_file)
+ (concat
+ [string "(*" ^^ (string top_line) ^^ string "*)";hardline;
+ (separate_map hardline)
+ (fun lib -> separate space [string "open import";string lib]) types_seq_modules;hardline;
+ if !print_to_from_interp_value
+ then
+ concat
+ [(separate_map hardline)
+ (fun lib -> separate space [string " import";string lib]) ["Interp";"Interp_ast"];
+ string "open import Deep_shallow_convert";
+ hardline;
+ hardline;
+ string "module SI = Interp"; hardline;
+ string "module SIA = Interp_ast"; hardline;
+ hardline]
+ else empty;
+ typdefs;
+ hardline;
+ hardline;
+ regstate_def;
+ hardline;
+ hardline;
+ register_refs]);
(print prompt_file)
(concat
[string "(*" ^^ (string top_line) ^^ string "*)";hardline;