summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristopher Pulte2015-10-28 12:09:28 +0000
committerChristopher Pulte2015-10-28 12:09:28 +0000
commit91a38a0dbcac11574768ff2fa2cb180d8d897487 (patch)
tree96345da4636839e26a80678a22b1b4003310e632 /src
parentea3171159c61ce03c76aef37b472ba9da2d932c7 (diff)
progress on lem backend: auto-generate read_register and write_register functions, and state definition
Diffstat (limited to 'src')
-rw-r--r--src/gen_lib/sail_values.lem145
-rw-r--r--src/gen_lib/state.lem10
-rw-r--r--src/gen_lib/vector.lem16
-rw-r--r--src/pretty_print.ml540
-rw-r--r--src/pretty_print.mli2
-rw-r--r--src/process_file.ml21
-rw-r--r--src/rewriter.ml11
7 files changed, 494 insertions, 251 deletions
diff --git a/src/gen_lib/sail_values.lem b/src/gen_lib/sail_values.lem
index 0d60efce..8048c676 100644
--- a/src/gen_lib/sail_values.lem
+++ b/src/gen_lib/sail_values.lem
@@ -1,52 +1,8 @@
open import Pervasives
+open import State
+open import Vector
+open import Arch
-type M 's 'a = <| runState : 's -> ('a * 's) |>
-
-val return : forall 's 'a. 'a -> M 's 'a
-let return a = <| runState = (fun s -> (a,s)) |>
-
-val bind : forall 's 'a 'b. M 's 'a -> ('a -> M 's 'b) -> M 's 'b
-let bind m f = <| runState = (fun s -> let (a,s) = m.runState s in (f a).runState s) |>
-
-let (>>=) = bind
-let (>>) m n = m >>= fun _ -> n
-
-(* only expected to be 0, 1, 2; 2 represents undef *)
-type bit = Zero | One | Undef
-let is_inc = true
-
-type register =
- | CR | CR0 | CR1
- | CTR
- | LR
- | XER | XER_SO | XER_OV | XER_CA
- | GPR0
- | GPR1
- | GPR2
- | GPR3
- | GPR4
- | VRSAVE
- | SPRG3
-
-type vector = Vector of list bit * nat
-
-(* auto-generate *)
-let GPR = [GPR0;GPR1;GPR2;GPR3;GPR4]
-
-(* auto-generate *)
-type state =
- <| cr : vector;
- ctr : vector;
- lr : vector;
- xer : vector;
- gpr0 : vector;
- gpr1 : vector;
- gpr2 : vector;
- gpr3 : vector;
- gpr4 : vector;
- vrsave : vector;
- sprg3 : vector |>
-
let to_bool = function
| Zero -> false
| One -> true
@@ -57,25 +13,6 @@ let get_blist (Vector bs _) = bs
let get_start (Vector _ s) = s
let length (Vector bs _) = length bs
-(* auto-generate *)
-let length_register : register -> nat = function
- | CR -> 32
- | CR0 -> 4
- | CR1 -> 4
- | CTR -> 64
- | LR -> 64
- | XER -> 64
- | XER_SO -> 1
- | XER_OV -> 1
- | XER_CA -> 1
- | GPR0 -> 64
- | GPR1 -> 64
- | GPR2 -> 64
- | GPR3 -> 64
- | GPR4 -> 64
- | VRSAVE -> 32
- | SPRG3 -> 64
-end
let vector_access (Vector bs start) n =
let (Just b) = if is_inc then List.index bs (n - start)
@@ -83,76 +20,13 @@ let vector_access (Vector bs start) n =
b
-let read_vector_subrange (Vector bs start) n m =
- let (length,offset) = if is_inc then (m-n+1,n-start) else (n-m+1,start-n) in
- let (_,suffix) = List.splitAt offset bs in
- let (subvector,_) = List.splitAt length suffix in
- Vector subvector n
-
-let write_vector_subrange (Vector bs start) n m (Vector bs' _) =
- let (length,offset) = if is_inc then (m-n+1,n-start) else (n-m+1,start-n) in
- let (prefix,_) = List.splitAt offset bs in
- let (_,suffix) = List.splitAt (offset + length) bs in
- Vector (prefix ++ (List.take length bs') ++ suffix) start
-
-(* auto-generate *)
-let read_register reg =
- <| runState =
- fun s ->
- let v = match reg with
- | CR -> s.cr
- | CR0 -> read_vector_subrange s.cr 32 35
- | CR1 -> read_vector_subrange s.cr 36 39
- | CTR -> s.ctr
- | LR -> s.lr
- | XER -> s.xer
- | XER_SO -> read_vector_subrange s.xer 32 32
- | XER_OV -> read_vector_subrange s.xer 33 33
- | XER_CA -> read_vector_subrange s.xer 34 34
- | GPR0 -> s.gpr0
- | GPR1 -> s.gpr1
- | GPR2 -> s.gpr2
- | GPR3 -> s.gpr3
- | GPR4 -> s.gpr4
- | VRSAVE -> s.vrsave
- | SPRG3 -> s.sprg3
- end in
- (v,s)
- |>
-
- (* auto-generate *)
-let write_register reg v =
- <| runState =
- fun s ->
- let s' =
- match reg with
- | CR -> <| s with cr = write_vector_subrange s.cr 32 64 v |>
- | CR0 -> <| s with cr = write_vector_subrange s.cr 32 35 v |>
- | CR1 -> <| s with cr = write_vector_subrange s.cr 36 39 v |>
- | CTR -> <| s with ctr = write_vector_subrange s.cr 0 64 v |>
- | LR -> <| s with lr = write_vector_subrange s.cr 0 64 v |>
- | XER -> <| s with xer = write_vector_subrange s.cr 0 64 v |>
- | XER_SO -> <| s with xer = write_vector_subrange s.xer 32 32 v |>
- | XER_OV -> <| s with xer = write_vector_subrange s.xer 33 33 v |>
- | XER_CA -> <| s with xer = write_vector_subrange s.xer 34 34 v |>
- | GPR0 -> <| s with gpr0 = write_vector_subrange s.cr 0 64 v |>
- | GPR1 -> <| s with gpr1 = write_vector_subrange s.cr 0 64 v |>
- | GPR2 -> <| s with gpr2 = write_vector_subrange s.cr 0 64 v |>
- | GPR3 -> <| s with gpr3 = write_vector_subrange s.cr 0 64 v |>
- | GPR4 -> <| s with gpr4 = write_vector_subrange s.cr 0 64 v |>
- | VRSAVE -> <| s with vrsave = write_vector_subrange s.vrsave 32 64 v |>
- | SPRG3 -> <| s with sprg3 = write_vector_subrange s.vrsave 0 64 v |>
- end in
- ((),s')
- |>
-
let write_two_registers r1 r2 vec =
let size = length_register r1 in
let start = get_start vec in
let vsize = length vec in
- let r1_v = read_vector_subrange vec start ((if is_inc then size - start else start - size) - 1) in
+ let r1_v = read_vector_subrange is_inc vec start ((if is_inc then size - start else start - size) - 1) in
let r2_v =
- read_vector_subrange
+ read_vector_subrange is_inc
vec (if is_inc then size - start else start - size)
(if is_inc then vsize - start else start - vsize) in
write_register r1 r1_v >> write_register r2 r2_v
@@ -399,15 +273,15 @@ let shift_op_vec op (((Vector bs start) as l),r) =
match op with
| LL (*"<<"*) ->
let right_vec = Vector (List.replicate n Zero) 0 in
- let left_vec = read_vector_subrange l n (if is_inc then len + start else start - len) in
+ let left_vec = read_vector_subrange is_inc l n (if is_inc then len + start else start - len) in
vector_concat left_vec right_vec
| RR (*">>"*) ->
- let right_vec = read_vector_subrange l start n in
+ let right_vec = read_vector_subrange is_inc l start n in
let left_vec = Vector (List.replicate n Zero) 0 in
vector_concat left_vec right_vec
| LLL (*"<<<"*) ->
- let left_vec = read_vector_subrange l n (if is_inc then len + start else start - len) in
- let right_vec = read_vector_subrange l start n in
+ let left_vec = read_vector_subrange is_inc l n (if is_inc then len + start else start - len) in
+ let right_vec = read_vector_subrange is_inc l start n in
vector_concat left_vec right_vec
end
@@ -522,4 +396,3 @@ let eq_vec_vec (l,r) = eq (to_num true l, to_num true r)
let neq (l,r) = bitwise_not_bit (eq (l,r))
let neq_vec (l,r) = bitwise_not_bit (eq_vec_vec (l,r))
-
diff --git a/src/gen_lib/state.lem b/src/gen_lib/state.lem
new file mode 100644
index 00000000..462eeec2
--- /dev/null
+++ b/src/gen_lib/state.lem
@@ -0,0 +1,10 @@
+type M 's 'a = <| runState : 's -> ('a * 's) |>
+
+val return : forall 's 'a. 'a -> M 's 'a
+let return a = <| runState = (fun s -> (a,s)) |>
+
+val bind : forall 's 'a 'b. M 's 'a -> ('a -> M 's 'b) -> M 's 'b
+let bind m f = <| runState = (fun s -> let (a,s) = m.runState s in (f a).runState s) |>
+
+let (>>=) = bind
+let (>>) m n = m >>= fun _ -> n
diff --git a/src/gen_lib/vector.lem b/src/gen_lib/vector.lem
new file mode 100644
index 00000000..e7b20aeb
--- /dev/null
+++ b/src/gen_lib/vector.lem
@@ -0,0 +1,16 @@
+open import Pervasives
+
+type bit = Zero | One | Undef
+type vector = Vector of list bit * nat
+
+let read_vector_subrange is_inc (Vector bs start) n m =
+ let (length,offset) = if is_inc then (m-n+1,n-start) else (n-m+1,start-n) in
+ let (_,suffix) = List.splitAt offset bs in
+ let (subvector,_) = List.splitAt length suffix in
+ Vector subvector n
+
+let write_vector_subrange is_inc (Vector bs start) n m (Vector bs' _) =
+ let (length,offset) = if is_inc then (m-n+1,n-start) else (n-m+1,start-n) in
+ let (prefix,_) = List.splitAt offset bs in
+ let (_,suffix) = List.splitAt (offset + length) bs in
+ Vector (prefix ++ (List.take length bs') ++ suffix) start
diff --git a/src/pretty_print.ml b/src/pretty_print.ml
index 86bcb77f..db49989f 100644
--- a/src/pretty_print.ml
+++ b/src/pretty_print.ml
@@ -1258,7 +1258,7 @@ let doc_typ_ocaml, doc_atomic_typ_ocaml =
| Typ_app(Id_aux (Id "atom", _), [Typ_arg_aux(Typ_arg_nexp n,_)]) ->
(string "number")
| Typ_app(id,args) ->
- (separate_map space doc_typ_arg_ocaml args) ^^ space ^^ (doc_id_ocaml_type id)
+ (separate_map space doc_typ_arg_ocaml args) ^^ space ^^ (doc_id_ocaml_type id)
| _ -> atomic_typ ty
and atomic_typ ((Typ_aux (t, _)) as ty) = match t with
| Typ_id id -> doc_id_ocaml_type id
@@ -1791,25 +1791,149 @@ let pp_defs_ocaml f d top_line opens =
(separate_map hardline (fun lib -> (string "open") ^^ space ^^ (string lib)) opens) ^/^
(doc_defs_ocaml d))
+
+
(****************************************************************************
* PPrint-based sail-to-lem pretty printer
****************************************************************************)
+let langlebar = string "<|"
+let ranglebar = string "|>"
+let anglebars = enclose langlebar ranglebar
+
+
let doc_id_lem (Id_aux(i,_)) =
match i with
| Id("bit") -> string "vbit"
- | Id i -> string (if i.[0] = '\'' || is_number(i.[0]) then "_" ^ i else i)
+ | Id i -> string (if i.[0] = '\'' || is_number(i.[0])
+ then "_" ^ i else i)
| DeIid x ->
- (* add an extra space through empty to avoid a closing-comment
- * token in case of x ending with star. *)
- parens (separate space [colon; string x; empty])
+ (* add an extra space through empty to avoid a closing-comment
+ * token in case of x ending with star. *)
+ parens (separate space [colon; string x; empty])
+
+let doc_id_lem_type (Id_aux(i,_)) =
+ match i with
+ | Id("bit") -> string "vbit"
+ | Id i -> string i
+ | DeIid x ->
+ (* add an extra space through empty to avoid a closing-comment
+ * token in case of x ending with star. *)
+ parens (separate space [colon; string x; empty])
+
+let doc_id_lem_ctor (Id_aux(i,_)) =
+ match i with
+ | Id("bit") -> string "vbit"
+ | Id i -> string (String.capitalize i)
+ | DeIid x ->
+ (* add an extra space through empty to avoid a closing-comment
+ * token in case of x ending with star. *)
+ parens (separate space [colon; string (String.capitalize x); empty])
+
+let doc_typ_lem, doc_atomic_typ_lem =
+ (* following the structure of parser for precedence *)
+ let rec typ ty = fn_typ ty
+ and fn_typ ((Typ_aux (t, _)) as ty) = match t with
+ | Typ_fn(arg,ret,efct) ->
+ separate space [tup_typ arg; arrow; fn_typ ret]
+ | _ -> tup_typ ty
+ and tup_typ ((Typ_aux (t, _)) as ty) = match t with
+ | Typ_tup typs -> parens (separate_map star app_typ typs)
+ | _ -> app_typ ty
+ and app_typ ((Typ_aux (t, _)) as ty) = match t with
+ | Typ_app(Id_aux (Id "vector", _), [
+ Typ_arg_aux(Typ_arg_nexp n, _);
+ Typ_arg_aux(Typ_arg_nexp m, _);
+ Typ_arg_aux (Typ_arg_order ord, _);
+ Typ_arg_aux (Typ_arg_typ typ, _)]) ->
+ string "vector"
+ | Typ_app(Id_aux (Id "range", _), [
+ Typ_arg_aux(Typ_arg_nexp n, _);
+ Typ_arg_aux(Typ_arg_nexp m, _);]) ->
+ (string "number")
+ | Typ_app(Id_aux (Id "atom", _), [Typ_arg_aux(Typ_arg_nexp n,_)]) ->
+ (string "number")
+ | Typ_app(id,args) ->
+ (doc_id_lem_type id) ^^ space ^^ (separate_map space doc_typ_arg_lem args)
+ | _ -> atomic_typ ty
+ and atomic_typ ((Typ_aux (t, _)) as ty) = match t with
+ | Typ_id id -> doc_id_lem_type id
+ | Typ_var v -> doc_var v
+ | Typ_wild -> underscore
+ | Typ_app _ | Typ_tup _ | Typ_fn _ ->
+ (* exhaustiveness matters here to avoid infinite loops
+ * if we add a new Typ constructor *)
+ group (parens (typ ty))
+ and doc_typ_arg_lem (Typ_arg_aux(t,_)) = match t with
+ | Typ_arg_typ t -> app_typ t
+ | Typ_arg_nexp n -> empty
+ | Typ_arg_order o -> empty
+ | Typ_arg_effect e -> empty
+ in typ, atomic_typ
+
+let doc_lit_lem in_pat (L_aux(l,_)) =
+ utf8string (match l with
+ | L_unit -> "()"
+ | L_zero -> "Zero"
+ | L_one -> "One"
+ | L_true -> "One"
+ | L_false -> "Zero"
+ | L_num i -> (* if in_pat then string_of_int i else "(big_int_of_int " ^ string_of_int i ^ ")" *) string_of_int i
+ | L_hex n -> failwith "Shouldn't happen" (*"(num_to_vec " ^ ("0x" ^ n) ^ ")" (*shouldn't happen*)*)
+ | L_bin n -> failwith "Shouldn't happen" (*"(num_to_vec " ^ ("0b" ^ n) ^ ")" (*shouldn't happen*)*)
+ | L_undef -> "Undef"
+ | L_string s -> "\"" ^ s ^ "\"")
+
+(* typ_doc is the doc for the type being quantified *)
+let doc_typquant_lem (TypQ_aux(tq,_)) typ_doc = typ_doc
+
+let doc_typscm_lem (TypSchm_aux(TypSchm_ts(tq,t),_)) =
+ (doc_typquant tq (doc_typ_lem t))
+
+(*Note: vector concatenation, literal vectors, indexed vectors, and record should
+ be removed prior to pp. The latter two have never yet been seen
+*)
+let doc_pat_lem =
+ let rec pat pa = app_pat pa
+ and app_pat ((P_aux(p,(l,annot))) as pa) = match p with
+ | P_app(id, ((_ :: _) as pats)) ->
+ (match annot with
+ | Base(_,Constructor _,_,_,_,_) ->
+ doc_unop (doc_id_lem_ctor id) (separate_map space pat pats)
+ | _ -> empty)
+ | P_lit lit -> doc_lit_lem true lit
+ | P_wild -> underscore
+ | P_id id -> doc_id_lem id
+ | P_as(p,id) -> parens (separate space [pat p; string "as"; doc_id_lem id])
+ | P_typ(typ,p) -> doc_op colon (pat p) (doc_typ_lem typ)
+ | P_app(id,[]) ->
+ (match annot with
+ | Base(_,Constructor n,_,_,_,_) -> doc_id_lem_ctor id
+ | _ -> empty)
+ | P_vector pats ->
+ let non_bit_print () =
+ parens
+ (separate space [string "Vector";
+ (separate space [squarebars (separate_map semi pat pats);
+ underscore;underscore])]) in
+ (match annot with
+ | Base(([],t),_,_,_,_,_) ->
+ if is_bit_vector t
+ then parens (separate space [string "Vector";
+ (separate space [squarebars (separate_map semi pat pats);
+ underscore;underscore])])
+ else non_bit_print()
+ | _ -> non_bit_print ())
+ | P_tup pats -> parens (separate_map comma_sp pat pats)
+ | P_list pats -> brackets (separate_map semi pat pats) (*Never seen but easy in lem*)
+ in pat
let doc_exp_lem, doc_let_lem =
- let rec top_exp read_registers (E_aux (e, (_,annot))) =
- let exp = top_exp read_registers in
+ let rec top_exp (E_aux (e, (_,annot))) =
+ let exp = top_exp in
match e with
| E_assign((LEXP_aux(le_act,tannot) as le),e) ->
- (match annot with
+ (match annot with
| Base(_,(Emp_local | Emp_set),_,_,_,_) ->
(match le_act with
| LEXP_id _ | LEXP_cast _ ->
@@ -1818,7 +1942,7 @@ let doc_exp_lem, doc_let_lem =
| LEXP_vector _ ->
doc_op (string "<-") (doc_lexp_array_lem le) (exp e)
| LEXP_vector_range _ ->
- doc_lexp_rwrite le e)
+ doc_lexp_rwrite le e)
| _ ->
(match le_act with
| LEXP_vector _ | LEXP_vector_range _ | LEXP_cast _ | LEXP_field _ | LEXP_id _ ->
@@ -1827,14 +1951,12 @@ let doc_exp_lem, doc_let_lem =
| E_vector_append(l,r) ->
parens ((string "vector_concat ") ^^ (exp l) ^^ space ^^ (exp r))
| E_cons(l,r) -> doc_op (group (colon^^colon)) (exp l) (exp r)
- | E_if(c,t,E_aux(E_block [], _)) ->
- string "if" ^^ space ^^ string "to_bool" ^^ parens (exp c) ^/^
- string "then" ^^ space ^^ (exp t)
| E_if(c,t,e) ->
parens (
- string "if" ^^ space ^^ string "to_bool" ^^ parens (exp c) ^/^
- string "then" ^^ space ^^ group (exp t) ^/^
- string "else" ^^ space ^^ group (exp e))
+ (separate space [string "if";string "to_bool";parens (exp c)]) ^/^
+ (prefix 2 1 (string "then") (exp t)) ^/^
+ (prefix 2 1 (string "else") (exp e))
+ ) ^^ hardline
| E_for(id,exp1,exp2,exp3,(Ord_aux(order,_)),exp4) ->
let var= doc_id_lem id in
let (compare,next) = if order = Ord_inc then string "<=",string "+" else string ">=",string "-" in
@@ -1869,11 +1991,11 @@ let doc_exp_lem, doc_let_lem =
if i >= stop then (body i; foreach_dec (i - by) stop by body) else ()
*)*)
- | E_let(leb,e) -> doc_op (string "in") (let_exp leb) (exp e)
+ | E_let(leb,e) -> (let_exp leb) ^^ space ^^ string "in" ^/^ (exp e)
| E_app(f,args) ->
let call = match annot with
| Base(_,External (Some n),_,_,_,_) -> string n
- | Base(_,Constructor i,_,_,_,_) -> doc_id_ocaml_ctor i f
+ | Base(_,Constructor _,_,_,_,_) -> doc_id_lem_ctor f
| _ -> doc_id_lem f in
parens (doc_unop call (parens (separate_map comma exp args)))
| E_vector_access(v,e) ->
@@ -1885,7 +2007,7 @@ let doc_exp_lem, doc_let_lem =
| _ -> (string "vector_access")) in
parens (call ^^ space ^^ exp v ^^ space ^^ exp e)
| E_vector_subrange(v,e1,e2) ->
- parens ((string "vector_subrange") ^^ space ^^ (exp v) ^^ space ^^ (exp e1) ^^ space ^^ (exp e2))
+ parens ((string "read_vector_subrange") ^^ space ^^ (exp v) ^^ space ^^ (exp e1) ^^ space ^^ (exp e2))
| E_field((E_aux(_,(_,fannot)) as fexp),id) ->
(match fannot with
| Base((_,{t= Tapp("register",_)}),_,_,_,_,_) |
@@ -1905,11 +2027,11 @@ let doc_exp_lem, doc_let_lem =
(match annot with
| Base((_, ({t = Tapp("reg",_)} | {t=Tabbrev(_,{t=Tapp("reg",_)})})),_,_,_,_,_) ->
doc_id_lem id
- | Base((_, ({t = Tapp("register",_)} | {t=Tabbrev(_,{t=Tapp("register",_)})})),_,_,_,_,_) ->
- if read_registers
- then string "(read_register " ^^ doc_id_lem id ^^ string ")"
- else doc_id_lem id
- | Base(_,(Constructor i |Enum i),_,_,_,_) -> doc_id_ocaml_ctor i id
+ | Base((_, ({t = Tapp("register",_)} | {t=Tabbrev(_,{t=Tapp("register",_)})})),tag,_,_,_,_) ->
+ (match tag with
+ | External _ -> string "(read_register " ^^ doc_id_lem id ^^ string ")"
+ | _ -> doc_id_lem id)
+ | Base(_,(Constructor i |Enum i),_,_,_,_) -> doc_id_lem_ctor id
| Base((_,t),Alias alias_info,_,_,_,_) ->
(match alias_info with
| Alias_field(reg,field) ->
@@ -1921,31 +2043,28 @@ let doc_exp_lem, doc_let_lem =
if start = stop
then parens (separate space [string "bit_vector_access";string reg;doc_int start])
else parens
- (separate space [string "vector_subrange"; string reg; doc_int start; doc_int stop])
+ (separate space [string "read_vector_subrange"; string reg; doc_int start; doc_int stop])
| Alias_pair(reg1,reg2) ->
parens (separate space [string "vector_concat"; string reg1; string reg2]))
| _ -> doc_id_lem id)
- | E_lit lit -> doc_lit_ocaml false lit
+ | E_lit lit -> doc_lit_lem false lit
| E_cast(typ,e) ->
(match annot with
- | Base(_,External _,_,_,_,_) ->
- if read_registers
- then parens( string "read_register" ^^ space ^^ exp e)
- else exp e
- | _ -> (parens (doc_op colon (group (exp e)) (doc_typ_ocaml typ))))
+ | Base(_,External _,_,_,_,_) -> parens( string "read_register" ^^ space ^^ exp e)
+ | _ -> (parens (doc_op colon (group (exp e)) (doc_typ_lem typ))))
| E_tuple exps ->
parens (separate_map comma exp exps)
| E_record(FES_aux(FES_Fexps(fexps,_),_)) ->
- braces (separate_map semi_sp doc_fexp fexps)
+ anglebars (separate_map semi_sp doc_fexp fexps)
| E_record_update(e,(FES_aux(FES_Fexps(fexps,_),_))) ->
- braces (doc_op (string "with") (exp e) (separate_map semi_sp doc_fexp fexps))
+ anglebars (doc_op (string "with") (exp e) (separate_map semi_sp doc_fexp fexps))
| E_vector exps ->
(match annot with
| Base((_,t),_,_,_,_,_) ->
match t.t with
| Tapp("vector", [TA_nexp start; _; TA_ord order; _])
| Tabbrev(_,{t= Tapp("vector", [TA_nexp start; _; TA_ord order; _])}) ->
- let call = if is_bit_vector t then (string "Vvector") else (string "VvectorR") in
+ let call = string "Vector" in
let dir,dir_out = match order.order with
| Oinc -> true,"true"
| _ -> false, "false" in
@@ -1996,7 +2115,7 @@ let doc_exp_lem, doc_let_lem =
| E_list exps ->
brackets (separate_map semi exp exps)
| E_case(e,pexps) ->
- let opening = separate space [string "("; string "match"; top_exp true e; string "with"] in
+ let opening = separate space [string "("; string "match"; top_exp e; string "with"] in
let cases = separate_map (break 1) doc_case pexps in
surround 2 1 opening cases rparen
| E_exit e ->
@@ -2011,72 +2130,65 @@ let doc_exp_lem, doc_let_lem =
separate space [string "let";
doc_lexp_lem true lexp; (*Rewriter/typecheck should ensure this is only cast or id*)
equals;
- string "ref";
exp eq_exp;
string "in";
exp in_exp]
| E_internal_plet (pat,e1,e2) ->
- (separate space [(exp e1); string ">>= fun"; doc_pat_ocaml pat;arrow]) ^/^
+ (separate space [exp e1; string ">>= fun"; doc_pat_lem pat;arrow]) ^/^
exp e2
| E_internal_return (e1) ->
separate space [string "return"; exp e1;]
and let_exp (LB_aux(lb,_)) = match lb with
- | LB_val_explicit(ts,pat,e) ->
- prefix 2 1
- (separate space [string "let"; doc_pat_ocaml pat; equals])
- (top_exp true e)
+ | LB_val_explicit(_,pat,e)
| LB_val_implicit(pat,e) ->
prefix 2 1
- (separate space [string "let"; doc_pat_ocaml pat; equals])
- (top_exp true e)
+ (separate space [string "let"; doc_pat_lem pat; equals])
+ (top_exp e)
- and doc_fexp (FE_aux(FE_Fexp(id,e),_)) = doc_op equals (doc_id_lem id) (top_exp true e)
+ and doc_fexp (FE_aux(FE_Fexp(id,e),_)) = doc_op equals (doc_id_lem id) (top_exp e)
and doc_case (Pat_aux(Pat_exp(pat,e),_)) =
- doc_op arrow (separate space [pipe; doc_pat_ocaml pat]) (group (top_exp true e))
+ doc_op arrow (separate space [pipe; doc_pat_lem pat]) (group (top_exp e))
and doc_lexp_lem top_call ((LEXP_aux(lexp,(l,annot))) as le) =
- let exp = top_exp true in
+ let exp = top_exp in
match lexp with
- | LEXP_vector(v,e) -> parens ((string "vector_access") ^^ space ^^ doc_lexp_lem false v) ^^ dot ^^ parens (exp e)
+ | LEXP_vector(v,e) -> parens ((string "vector_access") ^^ space ^^ (doc_lexp_lem false v)) ^^ dot ^^ parens (exp e)
| LEXP_vector_range(v,e1,e2) ->
- parens ((string "vector_subrange") ^^ space ^^ (doc_lexp_lem false v) ^^ space ^^ (exp e1) ^^ space ^^ (exp e2))
- | LEXP_field(v,id) -> (doc_lexp_lem false v) ^^ dot ^^ doc_id_ocaml id
- | LEXP_id id
- | LEXP_cast(_,id) ->
- let name = doc_id_ocaml id in
- match annot,top_call with
- | Base((_,{t=Tapp("reg",_)}),Emp_set,_,_,_,_),false
- | Base((_,{t=Tabbrev(_,{t=Tapp("reg",_)})}),Emp_set,_,_,_,_),false ->
- string "!" ^^ name
- | _ -> name
-
+ parens ((string "read_vector_subrange") ^^ space ^^ (doc_lexp_lem false v) ^^ space ^^ (exp e1) ^^ space ^^ (exp e2))
+ | LEXP_field(v,id) -> (doc_lexp_lem false v) ^^ dot ^^ doc_id_lem id
+ | LEXP_id id | LEXP_cast(_,id) ->
+ let name = doc_id_lem id in
+ match annot,top_call with
+ | Base((_,{t=Tapp("reg",_)}),Emp_set,_,_,_,_),false | Base((_,{t=Tabbrev(_,{t=Tapp("reg",_)})}),Emp_set,_,_,_,_),false ->
+ string "!" ^^ name
+ | _ -> name
and doc_lexp_array_lem ((LEXP_aux(lexp,(l,annot))) as le) = match lexp with
| LEXP_vector(v,e) ->
- (match annot with
- | Base((_,t),_,_,_,_,_) ->
- let t_act = match t.t with | Tapp("reg",[TA_typ t]) | Tabbrev(_,{t=Tapp("reg",[TA_typ t])}) -> t | _ -> t in
- (match t_act.t with
- | Tid "bit" | Tabbrev(_,{t=Tid "bit"}) ->
- parens ((string "get_barray") ^^ space ^^ doc_lexp_lem false v) ^^ dot ^^ parens (top_exp false e)
- | _ -> parens ((string "get_varray") ^^ space ^^ doc_lexp_lem false v) ^^ dot ^^ parens (top_exp false e))
- | _ ->
- parens ((string "get_varray") ^^ space ^^ doc_lexp_lem false v) ^^ dot ^^ parens (top_exp false e))
+ (match annot with
+ | Base((_,t),_,_,_,_,_) ->
+ let t_act = match t.t with | Tapp("reg",[TA_typ t]) | Tabbrev(_,{t=Tapp("reg",[TA_typ t])}) -> t | _ -> t in
+ (match t_act.t with
+ | Tid "bit" | Tabbrev(_,{t=Tid "bit"}) ->
+ parens ((string "get_barray") ^^ space ^^ doc_lexp_lem false v) ^^ dot ^^ parens (top_exp e)
+ | _ -> parens ((string "get_varray") ^^ space ^^ doc_lexp_lem false v) ^^ dot ^^ parens (top_exp e))
+ | _ ->
+ parens ((string "get_varray") ^^ space ^^ doc_lexp_lem false v) ^^ dot ^^ parens (top_exp e))
| _ -> empty
-
+
and doc_lexp_rwrite ((LEXP_aux(lexp,(l,annot))) as le) e_new_v =
- let exp = top_exp true in
+ let exp = top_exp in
let (is_bit,is_bitv) = match e_new_v with
| E_aux(_,(_,Base((_,t),_,_,_,_,_))) ->
(match t.t with
| Tapp("vector", [_;_;_;(TA_typ ({t=Tid "bit"} | {t=Tabbrev(_,{t=Tid "bit"})}))]) |
Tabbrev(_,{t=Tapp("vector",[_;_;_;TA_typ ({t=Tid "bit"} | {t=Tabbrev(_,{t=Tid "bit"})})])}) ->
- (false,true)
- | Tid "bit" | Tabbrev(_,{t=Tid "bit"}) -> (true,false)
- | _ -> (false,false))
+ (false,true)
+ | Tid "bit" | Tabbrev(_,{t=Tid "bit"}) -> (true,false)
+ | _ -> (false,false))
| _ -> (false,false) in
match lexp with
| LEXP_vector(v,e) ->
@@ -2085,17 +2197,17 @@ let doc_exp_lem, doc_let_lem =
dot ^^ parens (exp e))
(exp e_new_v)
| LEXP_vector_range(v,e1,e2) ->
- parens ((string (if is_bitv then "set_vector_subrange_bit" else "set_vector_subrange_v")) ^^ space ^^
- doc_lexp_lem false v ^^ space ^^ exp e1 ^^ space ^^ exp e2 ^^ space ^^ exp e_new_v)
+ parens ((string (if is_bitv then "write_vector_subrange_bit" else "write_vector_subrange_v")) ^^ space ^^
+ doc_lexp_lem false v ^^ space ^^ exp e1 ^^ space ^^ exp e2 ^^ space ^^ exp e_new_v)
| LEXP_field(v,id) ->
- parens ((string (if is_bit then "set_register_field_bit" else "set_register_field_v")) ^^ space ^^
- doc_lexp_lem false v ^^ space ^^string_lit (doc_id id) ^^ space ^^ exp e_new_v)
+ parens ((string (if is_bit then "write_register_field_bit" else "write_register_field_v")) ^^ space ^^
+ doc_lexp_lem false v ^^ space ^^string_lit (doc_id id) ^^ space ^^ exp e_new_v)
| LEXP_id id | LEXP_cast (_,id) ->
(match annot with
| Base(_,Alias alias_info,_,_,_,_) ->
(match alias_info with
| Alias_field(reg,field) ->
- parens ((if is_bit then string "set_register_field_bit" else string "set_register_field_v") ^^ space ^^
+ parens ((if is_bit then string "write_register_field_bit" else string "write_register_field_v") ^^ space ^^
string reg ^^ space ^^string_lit (string field) ^^ space ^^ exp e_new_v)
| Alias_extract(reg,start,stop) ->
if start = stop
@@ -2105,21 +2217,62 @@ let doc_exp_lem, doc_let_lem =
dot ^^ parens (doc_int start))
(exp e_new_v)
else
- parens ((string (if is_bitv then "set_vector_subrange_bit" else "set_vector_subrange_v")) ^^ space ^^
+ parens ((string (if is_bitv then "write_vector_subrange_bit" else "write_vector_subrange_v")) ^^ space ^^
string reg ^^ space ^^ doc_int start ^^ space ^^ doc_int stop ^^ space ^^ exp e_new_v)
| Alias_pair(reg1,reg2) ->
- parens ((string "set_two_regs") ^^ space ^^ string reg1 ^^ space ^^ string reg2 ^^ space ^^ exp e_new_v))
+ parens ((string "write_two_regs") ^^ space ^^ string reg1 ^^ space ^^ string reg2 ^^ space ^^ exp e_new_v))
| _ ->
- parens (separate space [string "set_register"; doc_id_lem id; exp e_new_v]))
+ parens (separate space [string "write_register"; doc_id_lem id; exp e_new_v]))
and doc_lexp_fcall ((LEXP_aux(lexp,(l,annot))) as le) e_new_v = match lexp with
- | LEXP_memory(id,args) -> doc_id_lem id ^^ parens (separate_map comma (top_exp true) (args@[e_new_v]))
+ | LEXP_memory(id,args) -> doc_id_lem id ^^ parens (separate_map comma top_exp (args@[e_new_v]))
(* expose doc_exp and doc_let *)
- in top_exp true, let_exp
+ in top_exp, let_exp
+
+(*TODO Upcase and downcase type and constructors as needed*)
+let doc_type_union_lem (Tu_aux(typ_u,_)) = match typ_u with
+ | Tu_ty_id(typ,id) -> separate space [pipe; doc_id_lem_ctor id; string "of"; doc_typ_lem typ;]
+ | Tu_id id -> separate space [pipe; doc_id_lem_ctor id]
+
+let rec doc_range_lem (BF_aux(r,_)) = match r with
+ | BF_single i -> parens (doc_op comma (doc_int i) (doc_int i))
+ | BF_range(i1,i2) -> parens (doc_op comma (doc_int i1) (doc_int i2))
+ | BF_concat(ir1,ir2) -> (doc_range ir1) ^^ comma ^^ (doc_range ir2)
+
+let doc_typdef_lem (TD_aux(td,_)) = match td with
+ | TD_abbrev(id,nm,typschm) ->
+ doc_op equals (concat [string "type"; space; doc_id_lem_type id;]) (doc_typscm_lem typschm)
+ | TD_record(id,nm,typq,fs,_) ->
+ let f_pp (typ,id) = concat [doc_id_lem_type id; space; colon; doc_typ_lem typ; semi] in
+ let fs_doc = group (separate_map (break 1) f_pp fs) in
+ doc_op equals
+ (concat [string "type"; space; doc_id_lem_type id;])
+ (doc_typquant_lem typq (anglebars fs_doc))
+ | TD_variant(id,nm,typq,ar,_) ->
+ let n = List.length ar in
+ let ar_doc = group (separate_map (break 1) doc_type_union_lem ar) in
+ doc_op equals
+ (concat [string "type"; space; doc_id_lem_type id;])
+ (if n > 246
+ then brackets (space ^^(doc_typquant_lem typq ar_doc))
+ else (doc_typquant_lem typq ar_doc))
+ | TD_enum(id,nm,enums,_) ->
+ let enums_doc = group (separate_map (break 1 ^^ pipe) doc_id_lem_ctor enums) in
+ doc_op equals
+ (concat [string "type"; space; doc_id_lem_type id;])
+ (enums_doc)
+ | TD_register(id,n1,n2,rs) -> failwith "TD_register shouldn't occur here"
+
+let doc_rec_lem (Rec_aux(r,_)) = match r with
+ | Rec_nonrec -> space
+ | Rec_rec -> 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)
let doc_funcl_lem (FCL_aux(FCL_Funcl(id,pat,exp),_)) =
- group (doc_op arrow (doc_pat_ocaml pat) (doc_exp_lem exp))
+ group (doc_op arrow (doc_pat_lem pat) (doc_exp_lem exp))
let get_id = function
| [] -> failwith "FD_function with empty list"
@@ -2129,36 +2282,227 @@ let doc_fundef_lem (FD_aux(FD_function(r, typa, efa, fcls),_)) =
match fcls with
| [] -> failwith "FD_function with empty function list"
| [FCL_aux (FCL_Funcl(id,pat,exp),_)] ->
- (separate space [(string "let"); (doc_rec_ocaml r); (doc_id_lem id); (doc_pat_ocaml pat); equals]) ^^ hardline ^^ (doc_exp_lem exp)
+ prefix 2 1
+ (separate space [(string "let") ^^ (doc_rec_lem r) ^^ (doc_id_lem id);
+ (doc_pat_lem pat);
+ equals])
+ (doc_exp_lem exp)
| _ ->
let id = get_id fcls in
let sep = hardline ^^ pipe ^^ space in
- let clauses = separate_map sep doc_funcl_lem fcls in
- separate space [string "let";
- doc_rec_ocaml r;
- doc_id_lem id;
- equals;
- (string "function");
- (hardline^^pipe);
- clauses]
+ let clauses = hardline ^^ pipe ^^ separate_map sep doc_funcl_lem fcls in
+ prefix 2 1
+ (separate space [string "let" ^^ doc_rec_lem r ^^ doc_id_lem id;
+ equals;
+ (string "function")]
+ )
+ clauses
+
+let doc_dec_lem (DEC_aux (reg,(l,annot))) =
+ match reg with
+ | DEC_reg(typ,id) -> failwith "DEC_reg shouldn't occur here"
+ | DEC_alias(id,alspec) -> empty (*
+ doc_op equals (string "register alias" ^^ space ^^ doc_id id) (doc_alias alspec) *)
+ | DEC_typ_alias(typ,id,alspec) -> empty (*
+ doc_op equals (string "register alias" ^^ space ^^ doc_atomic_typ typ) (doc_alias alspec) *)
let doc_def_lem def = group (match def with
| DEF_default df -> empty
| DEF_spec v_spec -> empty (*unless we want to have a separate pass to create mli files*)
- | DEF_type t_def -> doc_typdef_ocaml t_def
+ | DEF_type t_def -> doc_typdef_lem t_def
| DEF_fundef f_def -> doc_fundef_lem f_def
| DEF_val lbind -> doc_let_lem lbind
- | DEF_reg_dec dec -> doc_dec_ocaml dec
+ | DEF_reg_dec dec -> doc_dec_lem dec
| DEF_scattered sdef -> empty (*shoulnd't still be here*)
) ^^ hardline
+
+let reg_decls defs =
+
+ let (regtyps,typedregs,simpleregs,defs) =
+ List.fold_left
+ (fun (regtyps,typedregs,simpleregs,defs) def ->
+ match def with
+ | DEF_type (TD_aux(TD_register (Id_aux (Id name, _),n1,n2,rs),_)) ->
+ (regtyps @ [(name,(n1,n2,rs))],typedregs,simpleregs,defs)
+ | DEF_reg_dec (DEC_aux (DEC_reg(Typ_aux (Typ_id (Id_aux (Id typ,_)),_),Id_aux (Id name,_)),_)) ->
+ (regtyps,typedregs @ [(name,typ)],simpleregs,defs)
+ | DEF_reg_dec (DEC_aux (DEC_reg(_, Id_aux (Id name,_)),_)) ->
+ (regtyps,typedregs,simpleregs @ [name],defs)
+ | def -> (regtyps,typedregs,simpleregs,defs @ [def])
+ ) ([],[],[],[]) defs in
+
+ let default name = (name,
+ Nexp_aux (Nexp_constant 0,Unknown),
+ Nexp_aux (Nexp_constant 63,Unknown),
+ name) in
+
+ let dirpp = separate space [string "let";string "is_inc";equals;string "true"] in
+
+ let reg_decls =
+ (List.map default simpleregs) @
+ List.fold_left
+ (fun acc (id,typ) ->
+ let (n1,n2,rs) = List.assoc typ regtyps in
+ let rs_decls =
+ List.map
+ (function
+ | (BF_aux (BF_range (i,j), _), Id_aux (Id name,_)) ->
+ (name, Nexp_aux (Nexp_constant i,Unknown), Nexp_aux (Nexp_constant j, Unknown),id)
+ | (BF_aux (BF_single i, _), Id_aux (Id name, _)) ->
+ (name, Nexp_aux (Nexp_constant i,Unknown), Nexp_aux (Nexp_constant i, Unknown),id)
+ ) rs in
+ acc @ ((id,n1,n2,id) :: rs_decls)
+ ) [] typedregs in
+
+ let proper_regs = (List.map snd typedregs) @ simpleregs in
+ let regs_and_fields = List.map (fun (x,_,_,_) -> x) reg_decls in
+
+ let regspp =
+ prefix 2 1
+ (separate space [string "type"; string "register";equals])
+ (separate_map space (fun reg -> pipe ^^ space ^^ string reg) regs_and_fields) in
+
+ let statepp =
+ prefix 2 1
+ (separate space [string "type";string "state";equals])
+ (anglebars
+ (separate_map
+ (semi ^^ break 1)
+ (fun reg -> separate space [string (String.lowercase reg);colon;string "vector"])
+ proper_regs
+ )) in
+
+ let lengthpp =
+ prefix 2 1
+ (separate space [string "let";string "length_register";colon;string "register";
+ arrow;string "nat";equals;string "function"])
+ ((separate_map
+ (break 1)
+ (fun (id,n1,n2,_) ->
+ separate
+ space
+ [pipe;string id;arrow;
+ string "natFromInteger" ^^
+ parens (
+ separate
+ space [
+ string "abs";
+ parens (separate
+ space
+ [doc_nexp n2;
+ minus;
+ doc_nexp n1]);
+ plus;string "1"]
+ )
+ ])
+ reg_decls
+ ) ^^
+ hardline ^^
+ string "end") in
+
+ let read_register_pp =
+ prefix
+ 2 1
+ (separate space [string "let";string "read_register";string "reg";equals])
+ (enclose
+ (langlebar ^^ space) (ranglebar)
+ (prefix
+ 2 1
+ (separate space [string "runState";equals])
+ (prefix 2 1
+ ((separate space [string "fun"; string "s";arrow]) ^^ hardline ^^
+ (separate space [string "let";string "v";equals;string "match reg with"]))
+ ((separate_map
+ (break 1)
+ (fun (id,n1,n2,id2) ->
+ separate
+ space
+ [pipe;
+ string id;
+ arrow;
+ string "read_vector_subrange";
+ string "is_inc";
+ string "s." ^^ (string (String.lowercase id2));
+ doc_nexp n1;
+ doc_nexp n2])
+ reg_decls
+ ) ^^
+ hardline ^^
+ string "end in")
+ ) ^^ hardline ^^
+ string "(v,s)" ^^ hardline
+ )
+ )
+ in
+
+ let write_register_pp =
+ prefix
+ 2 1
+ (separate space [string "let";string "write_register";string "reg";string "v";equals])
+ (enclose
+ (langlebar ^^ space) (ranglebar)
+ (prefix
+ 2 1
+ (separate space [string "runState";equals])
+ (prefix 2 1
+ ((separate space [string "fun"; string "s";arrow]) ^^ hardline ^^
+ (separate space [string "let";string "s'";equals;string "match reg with"]))
+ ((separate_map
+ (break 1)
+ (fun (id,n1,n2,id2) ->
+ separate
+ space
+ [pipe;string id;arrow;
+ (
+ enclose
+ (langlebar ^^ space) (space ^^ ranglebar)
+ (separate
+ space
+ [string "s with";
+ string (String.lowercase id2);
+ equals;
+ string "write_vector_subrange";
+ string "is_inc";
+ string "s." ^^ string (String.lowercase id2);
+ doc_nexp n1;
+ doc_nexp n2;
+ string "v"])
+ )
+ ]
+ )
+ reg_decls
+ ) ^^
+ hardline ^^
+ string "end in")
+ ) ^^ hardline ^^
+ string "((),s')" ^^ hardline
+ )
+ )
+ in
+
+ (separate (hardline ^^ hardline) [dirpp;regspp;statepp;lengthpp;read_register_pp;write_register_pp],defs)
+
+
let doc_defs_lem (Defs(defs)) =
- separate_map hardline doc_def_lem defs
-let pp_defs_lem f d top_line opens =
- print f (string "(*" ^^ (string top_line) ^^ string "*)" ^/^
- (separate_map hardline (fun lib -> (string "open") ^^ space ^^ (string lib)) opens) ^/^
- (doc_defs_lem d))
+ let (decls,defs) = reg_decls defs in
+ (decls,separate_map hardline doc_def_lem defs)
+
+
+let pp_defs_lem f_arch f d top_line opens =
+ let (decls,defs) = doc_defs_lem d in
+ print f
+ (string "(*" ^^ (string top_line) ^^ string "*)" ^/^
+ (separate_map
+ hardline
+ (fun lib -> separate space [string "open import";string lib])
+ ("Vector" :: "State" :: "Arch" :: opens)) ^/^ defs);
+ print f_arch
+ (string "(*" ^^ (string top_line) ^^ string "*)" ^/^
+ (separate_map
+ hardline
+ (fun lib -> separate space [string "open import";string lib]) ["Pervasives";"State";"Vector"]) ^/^ decls);
diff --git a/src/pretty_print.mli b/src/pretty_print.mli
index 4b51db8a..43680643 100644
--- a/src/pretty_print.mli
+++ b/src/pretty_print.mli
@@ -10,4 +10,4 @@ val pat_to_string : tannot pat -> string
val pp_lem_defs : Format.formatter -> tannot defs -> unit
val pp_defs_ocaml : out_channel -> tannot defs -> string -> string list -> unit
-val pp_defs_lem : out_channel -> tannot defs -> string -> string list -> unit
+val pp_defs_lem : out_channel -> out_channel -> tannot defs -> string -> string list -> unit
diff --git a/src/process_file.ml b/src/process_file.ml
index 135f0931..1a776cff 100644
--- a/src/process_file.ml
+++ b/src/process_file.ml
@@ -173,14 +173,21 @@ let output1 libpath out_arg filename defs (* alldoc_accum alldoc_inc_accum alldo
close_output_with_check ext_o
end
| Lem_out None ->
- let ((o,temp_file_name, _) as ext_o) = open_output_with_check_unformatted (f' ^ "embed.lem") in
- begin Pretty_print.pp_defs_lem o defs (generated_line filename) ["Sail_values";];
- close_output_with_check ext_o
- end
+ let ((o1,_, _) as ext_o1) =
+ open_output_with_check_unformatted ("arch.lem") in
+ let ((o2,_, _) as ext_o2) =
+ open_output_with_check_unformatted (f' ^ "embed.lem") in
+ Pretty_print.pp_defs_lem o1 o2 defs (generated_line filename) ["Sail_values"];
+ close_output_with_check ext_o1;
+ close_output_with_check ext_o2
| Lem_out (Some lib) ->
- let ((o,temp_file_name, _) as ext_o) = open_output_with_check_unformatted (f' ^ "embed.lem") in
- Pretty_print.pp_defs_lem o defs (generated_line filename) ["Sail_values"; lib];
- close_output_with_check ext_o
+ let ((o1,_, _) as ext_o1) =
+ open_output_with_check_unformatted ("arch.lem") in
+ let ((o2,_, _) as ext_o2) =
+ open_output_with_check_unformatted (f' ^ "embed.lem") in
+ Pretty_print.pp_defs_lem o1 o2 defs (generated_line filename) ["Sail_values"; lib];
+ close_output_with_check ext_o1;
+ close_output_with_check ext_o2
| Ocaml_out None ->
let ((o,temp_file_name, _) as ext_o) = open_output_with_check_unformatted (f' ^ ".ml") in
begin Pretty_print.pp_defs_ocaml o defs (generated_line filename) ["Big_int_Z";"Sail_values"];
diff --git a/src/rewriter.ml b/src/rewriter.ml
index d6b1fb33..30b6b3fe 100644
--- a/src/rewriter.ml
+++ b/src/rewriter.ml
@@ -907,9 +907,6 @@ let gettype (E_aux (_,(_,a))) =
| _ -> failwith "a_normalise doesn't support Overload"
-let dedup = List.fold_left (fun acc e -> if List.exists ((=) e) acc then acc else e :: acc) []
-
-
let effectful_effs {effect = Eset effs} =
List.exists
(fun (BE_aux (be,_)) -> match be with BE_nondet | BE_unspec | BE_undef -> false | _ -> true)
@@ -919,10 +916,6 @@ let effectful eaux =
effectful_effs (geteffs eaux)
let eff_union e1 e2 = union_effects (geteffs e1) (geteffs e2)
-(*KATHY:CHANGE: Not sure why the more general effect union is bad here?*)
-(* let {effect = Eset effs_e1} = geteffs e1 in
- let {effect = Eset effs_e2} = geteffs e2 in
- {effect = Eset (dedup (effs_e1 @ effs_e2))}*)
let remove_blocks_exp_alg =
@@ -1148,8 +1141,8 @@ and n_exp (exp : 'a exp) (k : 'a exp -> 'a exp) : 'a exp =
| E_case (exp1,pexps) ->
n_exp_name exp1 (fun exp1 ->
n_pexpL pexps (fun pexps ->
- let geteffs (Pat_aux (_,(_,Base (_,_,_,_,{effect = Eset effs},_)))) = effs in
- let effsum = {effect = Eset (dedup (List.flatten (List.map geteffs pexps)))} in
+ let geteffs (Pat_aux (_,(_,Base (_,_,_,_,eff,_)))) = eff in
+ let effsum = List.fold_left union_effects {effect = Eset []} (List.map geteffs pexps) in
k (rewrap_effs effsum (E_case (exp1,pexps)))))
| E_let (lb,body) ->
n_lb lb (fun lb ->