summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/gen_lib/sail_values.ml215
-rw-r--r--src/pretty_print.ml201
-rw-r--r--src/process_file.ml6
-rw-r--r--src/test/test1.sail2
-rw-r--r--src/type_internal.ml6
-rw-r--r--src/util.ml5
-rw-r--r--src/util.mli2
7 files changed, 321 insertions, 116 deletions
diff --git a/src/gen_lib/sail_values.ml b/src/gen_lib/sail_values.ml
index c8181572..42f0bfde 100644
--- a/src/gen_lib/sail_values.ml
+++ b/src/gen_lib/sail_values.ml
@@ -6,8 +6,8 @@ type number = Big_int_Z.big_int
type value =
| Vvector of vbit array * int * bool
- | VvectorR of value ref array * int * bool
- | Vregister of vbit array * int * bool * (string * (int * int)) list
+ | VvectorR of value array * int * bool
+ | Vregister of vbit array ref * int * bool * (string * (int * int)) list
| Vbit of vbit (*Mostly for Vundef in place of undefined register place holders*)
let to_bool = function
@@ -16,26 +16,48 @@ let to_bool = function
| Vundef -> assert false
let get_barray = function
- | Vvector(a,_,_)
- | Vregister(a,_,_,_) -> a
+ | Vvector(a,_,_) -> a
+ | Vregister(a,_,_,_) -> !a
| _ -> assert false
let get_varray = function
| VvectorR(a,_,_) -> a
| _ -> assert false
+let get_ord = function
+ | Vvector(_,_,o) | Vregister(_,_,o,_) | VvectorR(_,_,o) -> o
+ | _ -> assert false
+
+let get_start = function
+ | Vvector(_,s,o) | Vregister(_,s,o,_) | VvectorR(_,s,o) -> s
+ | _ -> assert false
+
+let length = function
+ | Vvector(array,_,_) -> big_int_of_int (Array.length array)
+ | Vregister(array,_,_,_) -> big_int_of_int (Array.length !array)
+ | VvectorR(array,_,_) -> big_int_of_int (Array.length array)
+ | _ -> assert false
+
+let read_register = function
+ | Vregister(a,start,inc,_) -> Vvector(!a,start,inc)
+ | v -> v
+
let vector_access v n = match v with
| VvectorR(array,start,is_inc) ->
if is_inc
- then !(array.(n-start))
- else !(array.(start-n))
+ then (array.(n-start))
+ else (array.(start-n))
| _ -> assert false
let bit_vector_access v n = match v with
- | Vvector(array,start,is_inc) | Vregister(array,start,is_inc,_) ->
+ | Vvector(array,start,is_inc) ->
if is_inc
then array.(n-start)
else array.(start-n)
+ | Vregister(array,start,is_inc,_) ->
+ if is_inc
+ then !array.(n-start)
+ else !array.(start-n)
| _ -> assert false
let vector_subrange v n m =
@@ -51,28 +73,149 @@ let vector_subrange v n m =
match v with
| VvectorR(array,start,is_inc) ->
let (length,offset) = if is_inc then (m-n+1,n-start) else (n-m+1,start-n) in
- VvectorR(builder array length offset (ref (VvectorR([||], 0, is_inc))),n,is_inc)
+ VvectorR(builder array length offset (VvectorR([||], 0, is_inc)),n,is_inc)
| Vvector(array,start,is_inc) ->
let (length,offset) = if is_inc then (m-n+1,n-start) else (n-m+1,start-n) in
Vvector(builder array length offset Vzero,n,is_inc)
| Vregister(array,start,is_inc,fields) ->
let (length,offset) = if is_inc then (m-n+1,n-start) else (n-m+1,start-n) in
- Vvector(builder array length offset Vzero,n,is_inc)
+ Vvector(builder !array length offset Vzero,n,is_inc)
| _ -> v
-let vector_append l r =
+let get_register_field_vec reg field =
+ match reg with
+ | Vregister(_,_,_,fields) ->
+ (match List.assoc field fields with
+ | (i,j) ->
+ if i = j
+ then Vbit Vundef
+ else vector_subrange reg i j)
+ | _ -> Vbit Vundef
+
+let get_register_field_bit reg field =
+ match reg with
+ | Vregister(_,_,_,fields) ->
+ (match List.assoc field fields with
+ | (i,j) ->
+ if i = j
+ then bit_vector_access reg i
+ else Vundef)
+ | _ -> Vundef
+
+let set_register register value = match register,value with
+ | Vregister(a,_,_,_), Vregister(new_v,_,_,_) ->
+ a := !new_v
+ | Vregister(a,_,_,_), Vvector(new_v,_,_) ->
+ a := new_v
+ | _ -> ()
+
+let set_vector_subrange_vec v n m new_v =
+ let walker array length offset new_values =
+ begin
+ for x = 0 to length-1
+ do array.(x+offset) <- new_values.(x)
+ done;
+ end
+ in
+ match v with
+ | VvectorR(array,start,is_inc) ->
+ let (length,offset) = if is_inc then (m-n+1,n-start) else (n-m+1,start-n) in
+ walker array length offset new_v
+ | _ -> ()
+
+let set_vector_subrange_bit v n m new_v =
+ let walker array length offset new_values =
+ begin
+ for x = 0 to length-1
+ do array.(x+offset) <- new_values.(x)
+ done;
+ end
+ in
+ match v with
+ | Vvector(array,start,is_inc) ->
+ let (length,offset) = if is_inc then (m-n+1,n-start) else (n-m+1,start-n) in
+ walker array length offset new_v
+ | Vregister(array,start,is_inc,fields) ->
+ let (length,offset) = if is_inc then (m-n+1,n-start) else (n-m+1,start-n) in
+ walker !array length offset new_v
+ | _ -> ()
+
+let set_register_field_v reg field new_v =
+ match reg with
+ | Vregister(array,start,dir,fields) ->
+ (match List.assoc field fields with
+ | (i,j) ->
+ if i = j
+ then ()
+ else set_vector_subrange_bit reg i j new_v)
+ | _ -> ()
+
+let set_register_field_bit reg field new_v =
+ match reg with
+ | Vregister(array,start,dir,fields) ->
+ (match List.assoc field fields with
+ | (i,j) ->
+ if i = j
+ then !array.(if dir then i - start else start - i) <- new_v
+ else ())
+ | _ -> ()
+
+let set_two_reg r1 r2 vec =
+ let size = int_of_big_int (length r1) in
+ let dir = get_ord r1 in
+ let start = get_start vec in
+ let vsize = int_of_big_int (length vec) in
+ let r1_v = vector_subrange vec start ((if dir then size - start else start - size) - 1) in
+ let r2_v = vector_subrange vec (if dir then size - start else start - size)
+ (if dir then vsize - start else start - vsize) in
+ begin set_register r1 r1_v; set_register r2 r2_v end
+
+
+let make_indexed_v entries default start size dir =
+ let default_value = match default with
+ | None -> Vbit Vundef
+ | Some v -> v in
+ let array = Array.make size default_value in
+ begin
+ List.iter (fun (i,v) -> array.(if dir then start - i else i - start) <- v) entries;
+ VvectorR(array, start, dir)
+ end
+
+let make_indexed_bitv entries default start size dir =
+ let default_value = match default with
+ | None -> Vundef
+ | Some v -> v in
+ let array = Array.make size default_value in
+ begin
+ List.iter (fun (i,v) -> array.(if dir then start - i else i - start) <- v) entries;
+ Vvector(array, start, dir)
+ end
+
+let vector_concat l r =
match l,r with
- | Vvector(arrayl,start,ord), Vvector(arrayr,_,_)
- | Vvector(arrayl,start,ord), Vregister(arrayr,_,_,_)
- | Vregister(arrayl,start,ord,_), Vvector(arrayr,_,_)
+ | Vvector(arrayl,start,ord), Vvector(arrayr,_,_) ->
+ Vvector(Array.append arrayl arrayr, start, ord)
+ | Vvector(arrayl,start,ord), Vregister(arrayr,_,_,_) ->
+ Vvector(Array.append arrayl !arrayr, start,ord)
+ | Vregister(arrayl,start,ord,_), Vvector(arrayr,_,_) ->
+ Vvector(Array.append !arrayl arrayr, start, ord)
| Vregister(arrayl,start,ord,_), Vregister(arrayr,_,_,_) ->
- Vvector(Array.append arrayl arrayr,start,ord)
+ Vvector(Array.append !arrayl !arrayr,start,ord)
| VvectorR(arrayl,start,ord),VvectorR(arrayr,_,_) ->
VvectorR(Array.append arrayl arrayr, start,ord)
| _ -> Vbit Vundef
let has_undef = function
- | Vvector(array,_,_) | Vregister(array,_,_,_) ->
+ | Vvector(array,_,_) ->
+ let rec foreach i =
+ if i <= Array.length array
+ then
+ if array.(i) = Vundef then true
+ else foreach (i+1)
+ else false in
+ foreach 0
+ | Vregister(array,_,_,_) ->
+ let array = !array in
let rec foreach i =
if i <= Array.length array
then
@@ -83,7 +226,8 @@ let has_undef = function
| _ -> false
let most_significant = function
- | Vvector(array,_,_) | Vregister(array,_,_,_) -> array.(0)
+ | Vvector(array,_,_) -> array.(0)
+ | Vregister(array,_,_,_) -> !array.(0)
| _ -> assert false
let bitwise_not_bit = function
@@ -92,11 +236,12 @@ let bitwise_not_bit = function
| _ -> Vundef
let bitwise_not = function
- | Vvector(array,s,d) | Vregister(array,s,d,_) -> Vvector( Array.map bitwise_not_bit array,s,d)
- | _ -> assert false
+ | Vvector(array,s,d)-> Vvector( Array.map bitwise_not_bit array,s,d)
+ | Vregister(array,s,d,_) -> Vvector( Array.map bitwise_not_bit !array,s,d)
+ | _ -> assert false
let unsigned = function
- | (Vvector(array,_,_) as v) | (Vregister(array,_,_,_) as v)->
+ | (Vvector(array,_,_) as v) ->
if has_undef v
then assert false
else
@@ -107,7 +252,20 @@ let unsigned = function
| _ -> ()
done;
!acc
- end
+ end
+ | (Vregister(array,_,_,_) as v)->
+ let array = !array in
+ if has_undef v
+ then assert false
+ else
+ let acc = ref zero_big_int in
+ begin for i = (Array.length array) - 1 downto 0 do
+ match array.(i) with
+ | Vone -> acc := add_big_int !acc (power_int_positive_int 2 i)
+ | _ -> ()
+ done;
+ !acc
+ end
| _ -> assert false
let signed v =
@@ -184,10 +342,6 @@ let to_vec ord len n =
let to_vec_inc (len,n) = to_vec true len n
let to_vec_dec (len,n) = to_vec false len n
-let length = function
- | Vvector(array,_,_) | Vregister(array,_,_,_) -> big_int_of_int (Array.length array)
- | VvectorR(array,_,_) -> big_int_of_int (Array.length array)
- | _ -> assert false
let arith_op op (l,r) = op l r
let add = arith_op add_big_int
@@ -198,10 +352,6 @@ let modulo = arith_op mod_big_int
let quot = arith_op div_big_int
let power = arith_op power_big
-let get_ord = function
- | Vvector(_,_,o) | Vregister(_,_,o,_) | VvectorR(_,_,o) -> o
- | _ -> assert false
-
let arith_op_vec op sign size (l,r) =
let ord = get_ord l in
let (l',r') = to_num sign l, to_num sign r in
@@ -314,22 +464,23 @@ let minus_overflow_vec_bit_signed = arith_op_overflow_vec_bit sub_big_int true u
let shift_op_vec op (l,r) =
match l with
- | Vvector(array,start,ord) | Vregister(array,start,ord,_) ->
+ | Vvector(_,start,ord) | Vregister(_,start,ord,_) ->
+ let array = match l with | Vvector(array,_,_) -> array | Vregister(array,_,_,_) -> !array | _ -> assert false in
let len = Array.length array in
let n = int_of_big_int r in
(match op with
| "<<" ->
let right_vec = Vvector(Array.make n Vzero,0,true) in
let left_vec = vector_subrange l n (if ord then len + start else start - len) in
- vector_append left_vec right_vec
+ vector_concat left_vec right_vec
| ">>" ->
let right_vec = vector_subrange l start n in
let left_vec = Vvector(Array.make n Vzero,0,true) in
- vector_append left_vec right_vec
+ vector_concat left_vec right_vec
| "<<<" ->
let left_vec = vector_subrange l n (if ord then len + start else start - len) in
let right_vec = vector_subrange l start n in
- vector_append left_vec right_vec
+ vector_concat left_vec right_vec
| _ -> assert false)
| _ -> assert false
diff --git a/src/pretty_print.ml b/src/pretty_print.ml
index 9b5173c3..322091f0 100644
--- a/src/pretty_print.ml
+++ b/src/pretty_print.ml
@@ -1204,7 +1204,7 @@ let star_sp = star ^^ space
let doc_id_ocaml (Id_aux(i,_)) =
match i with
| Id("bit") -> string "vbit"
- | Id i -> string (if i.[0] = '\'' then "_" ^ i else i)
+ | Id i -> string (if i.[0] = '\'' then "_" ^ i else String.uncapitalize i)
| DeIid x ->
(* add an extra space through empty to avoid a closing-comment
* token in case of x ending with star. *)
@@ -1252,7 +1252,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) ^^ (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
@@ -1269,16 +1269,16 @@ let doc_typ_ocaml, doc_atomic_typ_ocaml =
| Typ_arg_effect e -> empty
in typ, atomic_typ
-let doc_lit_ocaml (L_aux(l,_)) =
+let doc_lit_ocaml in_pat (L_aux(l,_)) =
utf8string (match l with
| L_unit -> "()"
| L_zero -> "Vzero"
| L_one -> "Vone"
| L_true -> "Vone"
| L_false -> "Vzero"
- | L_num i -> string_of_int i
- | L_hex n -> "(num_to_vec" ^ ("0x" ^ n) ^ ")" (*shouldn't happen*)
- | L_bin n -> "(num_to_vec" ^ ("0b" ^ n) ^ ")" (*shouldn't happen*)
+ | L_num i -> if in_pat then string_of_int i else "(big_int_of_int " ^ string_of_int i ^ ")"
+ | L_hex n -> "(num_to_vec " ^ ("0x" ^ n) ^ ")" (*shouldn't happen*)
+ | L_bin n -> "(num_to_vec " ^ ("0b" ^ n) ^ ")" (*shouldn't happen*)
| L_undef -> "Vundef"
| L_string s -> "\"" ^ s ^ "\"")
@@ -1291,15 +1291,13 @@ let doc_typscm_ocaml (TypSchm_aux(TypSchm_ts(tq,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_ocaml, doc_atomic_pat_ocaml =
+let doc_pat_ocaml =
let rec pat pa = app_pat pa
- and app_pat ((P_aux(p,l)) as pa) = match p with
- | P_app(id, ((_ :: _) as pats)) -> doc_unop (doc_id_ocaml_ctor id) (parens (separate_map comma_sp atomic_pat pats))
- | _ -> atomic_pat pa
- and atomic_pat ((P_aux(p,(l,annot))) as pa) = match p with
- | P_lit lit -> doc_lit lit
+ and app_pat ((P_aux(p,(l,annot))) as pa) = match p with
+ | P_app(id, ((_ :: _) as pats)) -> doc_unop (doc_id_ocaml_ctor id) (parens (separate_map comma_sp pat pats))
+ | P_lit lit -> doc_lit_ocaml true lit
| P_wild -> underscore
- | P_id id -> doc_id id
+ | P_id id -> doc_id_ocaml id
| P_as(p,id) -> parens (separate space [pat p; string "as"; doc_id_ocaml id])
| P_typ(typ,p) -> doc_op colon (pat p) (doc_typ_ocaml typ)
| P_app(id,[]) -> doc_id_ocaml_ctor id
@@ -1311,12 +1309,14 @@ let doc_pat_ocaml, doc_atomic_pat_ocaml =
then parens (separate space [string "Vvector"; squarebars (separate_map semi pat pats); underscore ; underscore])
else non_bit_print()
| _ -> non_bit_print ())
- | P_tup pats -> parens (separate_map comma_sp atomic_pat pats)
+ | P_tup pats -> parens (separate_map comma_sp pat pats)
| P_list pats -> brackets (separate_map semi pat pats) (*Never seen but easy in ocaml*)
- in pat, atomic_pat
+ in pat
let doc_exp_ocaml, doc_let_ocaml =
- let rec exp (E_aux (e, (_,annot))) = match e with
+ let rec top_exp read_registers (E_aux (e, (_,annot))) =
+ let exp = top_exp read_registers in
+ match e with
| E_assign((LEXP_aux(le_act,tannot) as le),e) ->
(match annot with
| Base(_,(Emp_local | Emp_set),_,_,_,_) ->
@@ -1325,16 +1325,16 @@ let doc_exp_ocaml, doc_let_ocaml =
(*Setting local variable fully *)
doc_op coloneq (doc_lexp_ocaml le) (exp e)
| LEXP_vector _ ->
- doc_op (string "<-") (doc_lexp_ocaml le) (exp e)
+ doc_op (string "<-") (doc_lexp_array_ocaml le) (exp e)
| LEXP_vector_range _ ->
- group ((string "set_vector_range") ^^ space ^^ (doc_lexp_ocaml le) ^^ space ^^ (exp e)))
+ parens ((string "set_vector_range") ^^ space ^^ (doc_lexp_ocaml le) ^^ space ^^ (exp e)))
| _ ->
(match le_act with
| LEXP_vector _ | LEXP_vector_range _ | LEXP_cast _ | LEXP_field _ | LEXP_id _ ->
(doc_lexp_rwrite le e)
| LEXP_memory _ -> (doc_lexp_fcall le e)))
| E_vector_append(l,r) ->
- group (parens (string "vector_append ") ^^ (exp l) ^^ space ^^ (exp 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) ^/^
@@ -1399,7 +1399,12 @@ let doc_exp_ocaml, doc_let_ocaml =
(match fannot with
| Base((_,{t= Tapp("register",_)}),_,_,_,_,_) |
Base((_,{t= Tabbrev(_,{t=Tapp("register",_)})}),_,_,_,_,_)->
- parens ((string "get_register_field") ^^ space ^^ (exp fexp) ^^ space ^^ string_lit (doc_id id))
+ let field_f = match annot with
+ | Base((_,{t = Tid "bit"}),_,_,_,_,_) |
+ Base((_,{t = Tabbrev(_,{t=Tid "bit"})}),_,_,_,_,_) ->
+ string "get_register_field_bit"
+ | _ -> string "get_register_field_vec" in
+ parens (field_f ^^ space ^^ (exp fexp) ^^ space ^^ string_lit (doc_id id))
| _ -> exp fexp ^^ dot ^^ doc_id id)
| E_block [] -> string "()"
| E_block exps | E_nondet exps ->
@@ -1409,21 +1414,34 @@ let doc_exp_ocaml, doc_let_ocaml =
(match annot with
| Base((_, ({t = Tapp("reg",_)} | {t=Tabbrev(_,{t=Tapp("reg",_)})})),_,_,_,_,_) ->
string "!" ^^ doc_id_ocaml id
- | Base((_,({t=Tapp("register",_)} | {t=Tabbrev(_,{t=Tapp("register",_)})})), External _,_,_,_,_) ->
- string "!" ^^ doc_id_ocaml id
- | Base(_,Alias alias_info,_,_,_,_) ->
+ | Base((_, ({t = Tapp("register",_)} | {t=Tabbrev(_,{t=Tapp("register",_)})})),_,_,_,_,_) ->
+ if read_registers
+ then string "(read_register " ^^ doc_id_ocaml id ^^ string ")"
+ else doc_id_ocaml id
+ | Base(_,(Constructor|Enum _),_,_,_,_) -> doc_id_ocaml_ctor id
+ | Base((_,t),Alias alias_info,_,_,_,_) ->
(match alias_info with
| Alias_field(reg,field) ->
- parens (string "get_register_field" ^^ space ^^ string reg ^^ string_lit (string field))
+ let field_f = match t.t with
+ | Tid "bit" | Tabbrev(_,{t=Tid "bit"}) -> string "get_register_field_bit"
+ | _ -> string "get_register_field_vec" in
+ parens (separate space [field_f; string reg; string_lit (string field)])
| Alias_extract(reg,start,stop) ->
if start = stop
- then parens (string "bit_vector_access" ^^ space ^^ string reg ^^ space ^^ doc_int start)
- else parens (string "vector_subrange" ^^ space ^^ string reg ^^ space ^^ doc_int start ^^ space ^^ doc_int 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])
| Alias_pair(reg1,reg2) ->
- parens (string "vector_append" ^^ space ^^ string reg1 ^^ space ^^ string reg2))
+ parens (separate space [string "vector_concat"; string reg1; string reg2]))
| _ -> doc_id_ocaml id)
- | E_lit lit -> doc_lit lit
- | E_cast(typ,e) -> (parens (doc_op colon (group (exp e)) (doc_typ_ocaml typ)))
+ | E_lit lit -> doc_lit_ocaml 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))))
| E_tuple exps ->
parens (separate_map comma exp exps)
| E_record(FES_aux(FES_Fexps(fexps,_),_)) ->
@@ -1444,7 +1462,9 @@ let doc_exp_ocaml, doc_let_ocaml =
| Nconst i -> string_of_big_int i
| N2n(_,Some i) -> string_of_big_int i
| _ -> if dir then "0" else string_of_int (List.length exps) in
- group (call ^^ space ^^ squarebars (separate_map semi exp exps) ^^ string start ^^ string dir_out))
+ parens (separate space [call; parens (separate comma_sp [squarebars (separate_map semi exp exps);
+ string start;
+ string dir_out])]))
| E_vector_indexed (iexps, (Def_val_aux (default,_))) ->
(match annot with
| Base((_,t),_,_,_,_,_) ->
@@ -1456,17 +1476,24 @@ let doc_exp_ocaml, doc_let_ocaml =
| Oinc -> true,"true"
| _ -> false, "false" in
let start = match start.nexp with
- | Nconst i -> string_of_big_int i
- | N2n(_,Some i) -> string_of_big_int i
+ | Nconst i | N2n(_,Some i)-> string_of_big_int i
+ | N2n({nexp=Nconst i},_) -> string_of_int (Util.power 2 (int_of_big_int i))
| _ -> if dir then "0" else string_of_int (List.length iexps) in
let size = match len.nexp with
- | Nconst i | N2n(_,Some i)-> string_of_big_int i in
+ | Nconst i | N2n(_,Some i)-> string_of_big_int i
+ | N2n({nexp=Nconst i},_) -> string_of_int (Util.power 2 (int_of_big_int i))
+ in
let default_string =
(match default with
| Def_val_empty -> string "None"
| Def_val_dec e -> parens (string "Some " ^^ (exp e))) in
let iexp (i,e) = parens (separate_map comma_sp (fun x -> x) [(doc_int i); (exp e)]) in
- group (call ^^ (brackets (separate_map semi iexp iexps)) ^^ space ^^ default_string ^^ string start ^^ string size ^^ string dir_out))
+ parens (separate space [call;
+ (brackets (separate_map semi iexp iexps));
+ default_string;
+ string start;
+ string size;
+ string dir_out]))
| E_vector_update(v,e1,e2) ->
(*Has never happened to date*)
brackets (doc_op (string "with") (exp v) (doc_op equals (exp e1) (exp e2)))
@@ -1476,9 +1503,9 @@ let doc_exp_ocaml, doc_let_ocaml =
doc_op (string "with") (exp v)
(doc_op equals (exp e1 ^^ colon ^^ exp e2) (exp e3)))
| E_list exps ->
- brackets (separate_map comma exp exps)
+ brackets (separate_map semi exp exps)
| E_case(e,pexps) ->
- let opening = separate space [string "("; string "match"; exp e; string "with"] in
+ let opening = separate space [string "("; string "match"; top_exp true e; string "with"] in
let cases = separate_map (break 1) doc_case pexps in
surround 2 1 opening cases rparen
| E_exit e ->
@@ -1507,34 +1534,50 @@ let doc_exp_ocaml, doc_let_ocaml =
and let_exp (LB_aux(lb,_)) = match lb with
| LB_val_explicit(ts,pat,e) ->
prefix 2 1
- (separate space [string "let"; doc_atomic_pat_ocaml pat; equals])
- (exp e)
+ (separate space [string "let"; doc_pat_ocaml pat; equals])
+ (top_exp false e)
| LB_val_implicit(pat,e) ->
prefix 2 1
- (separate space [string "let"; doc_atomic_pat_ocaml pat; equals])
- (exp e)
+ (separate space [string "let"; doc_pat_ocaml pat; equals])
+ (top_exp false e)
- and doc_fexp (FE_aux(FE_Fexp(id,e),_)) = doc_op equals (doc_id_ocaml id) (exp e)
+ and doc_fexp (FE_aux(FE_Fexp(id,e),_)) = doc_op equals (doc_id_ocaml id) (top_exp false e)
and doc_case (Pat_aux(Pat_exp(pat,e),_)) =
- doc_op arrow (separate space [pipe; doc_atomic_pat_ocaml pat]) (group (exp e))
+ doc_op arrow (separate space [pipe; doc_pat_ocaml pat]) (group (top_exp false e))
- and doc_lexp_ocaml ((LEXP_aux(lexp,(l,annot))) as le) = match lexp with
- | LEXP_vector(v,e) -> parens ((string "get_varray") ^^ space ^^ doc_lexp_ocaml v) ^^ dot ^^ parens (exp e)
- | LEXP_vector_range(v,e1,e2) ->
+ and doc_lexp_ocaml ((LEXP_aux(lexp,(l,annot))) as le) =
+ let exp = top_exp false in
+ match lexp with
+ | LEXP_vector(v,e) -> parens ((string "vector_access") ^^ space ^^ doc_lexp_ocaml v) ^^ dot ^^ parens (exp e)
+ | LEXP_vector_range(v,e1,e2) ->
parens ((string "vector_subrange") ^^ space ^^ doc_lexp_ocaml v ^^ space ^^ (exp e1) ^^ space ^^ (exp e2))
- | LEXP_field(v,id) -> doc_lexp_ocaml v ^^ dot ^^ doc_id_ocaml id
- | LEXP_id id -> doc_id_ocaml id
- | LEXP_cast(typ,id) -> (doc_id_ocaml id)
+ | LEXP_field(v,id) -> doc_lexp_ocaml v ^^ dot ^^ doc_id_ocaml id
+ | LEXP_id id -> doc_id_ocaml id
+ | LEXP_cast(typ,id) -> (doc_id_ocaml id)
+
+ and doc_lexp_array_ocaml ((LEXP_aux(lexp,(l,annot))) as le) = match lexp with
+ | LEXP_vector(v,e) -> parens ((string "get_varray") ^^ space ^^ doc_lexp_ocaml v) ^^ dot ^^ parens (top_exp false e)
+ | _ -> empty
and doc_lexp_rwrite ((LEXP_aux(lexp,(l,annot))) as le) e_new_v =
+ let exp = top_exp false in
+ let is_bit = 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"})})])}) ->
+ true
+ | _ -> false)
+ | _ -> false in
match lexp with
| LEXP_vector(v,e) ->
doc_op (string "<-")
- (group (parens ((string "get_varray") ^^ space ^^ doc_lexp_ocaml v)) ^^ dot ^^ parens (exp e))
+ (group (parens ((string (if is_bit then "get_barray" else "get_varray")) ^^ space ^^ doc_lexp_ocaml v)) ^^
+ dot ^^ parens (exp e))
(exp e_new_v)
| LEXP_vector_range(v,e1,e2) ->
- parens ((string "set_vector_subrange") ^^ space ^^
+ parens ((string (if is_bit then "set_vector_subrange_bit" else "set_vector_subrange_v")) ^^ space ^^
doc_lexp_ocaml v ^^ space ^^ exp e1 ^^ space ^^ exp e2 ^^ space ^^ exp e_new_v)
| LEXP_field(v,id) ->
parens ((string "set_register_field") ^^ space ^^
@@ -1544,27 +1587,28 @@ let doc_exp_ocaml, doc_let_ocaml =
| Base(_,Alias alias_info,_,_,_,_) ->
(match alias_info with
| Alias_field(reg,field) ->
- parens ((string "set_register_field") ^^ space ^^
+ parens ((if is_bit then string "set_register_field_bit" else string "set_register_field_v") ^^ space ^^
string reg ^^ space ^^string_lit (string field) ^^ space ^^ exp e_new_v)
| Alias_extract(reg,start,stop) ->
if start = stop
then
doc_op (string "<-")
- (group (parens ((string "get_varray") ^^ space ^^ string reg)) ^^ dot ^^ parens (doc_int start))
+ (group (parens ((string (if is_bit then "get_barray" else "get_varray")) ^^ space ^^ string reg)) ^^
+ dot ^^ parens (doc_int start))
(exp e_new_v)
else
- parens ((string "set_vector_subrange") ^^ space ^^
+ parens ((string (if is_bit then "set_vector_subrange_bit" else "set_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))
| _ ->
- doc_op (string ":=") (doc_id_ocaml id) (exp e_new_v))
+ parens (separate space [string "set_register"; doc_id_ocaml 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_ocaml id ^^ parens (separate_map comma exp (args@[e_new_v]))
+ | LEXP_memory(id,args) -> doc_id_ocaml id ^^ parens (separate_map comma (top_exp false) (args@[e_new_v]))
(* expose doc_exp and doc_let *)
- in exp, let_exp
+ in top_exp false, let_exp
(*TODO Upcase and downcase type and constructors as needed*)
let doc_type_union_ocaml (Tu_aux(typ_u,_)) = match typ_u with
@@ -1600,24 +1644,24 @@ let doc_typdef_ocaml (TD_aux(td,_)) = match td with
match n1,n2 with
| Nexp_aux(Nexp_constant i1,_),Nexp_aux(Nexp_constant i2,_) ->
let dir = i1 < i2 in
- let size = if dir then i2-i1 -1 else i1-i2 -1 in
+ let size = if dir then i2-i1 else i1-i2 in
doc_op equals
((string "let") ^^ space ^^ doc_id_ocaml id ^^ space ^^ (string "init_val"))
- (separate space [string "ref";
- string "Vregister";
+ (separate space [string "Vregister";
(parens (separate comma_sp
[parens (separate space
[string "match init_val with";
pipe;
string "None";
arrow;
- string "Array.make";
+ string "ref";
+ string "(Array.make";
doc_int size;
- string "Vzero";
+ string "Vzero)";
pipe;
string "Some init_val";
arrow;
- string "init_val";]);
+ string "ref init_val";]);
doc_nexp n1;
string (if dir then "true" else "false");
brackets doc_rids]))])
@@ -1644,12 +1688,13 @@ let doc_fundef_ocaml (FD_aux(FD_function(r, typa, efa, fcls),_)) =
| _ ->
let id = get_id fcls in
let sep = hardline ^^ pipe ^^ space in
- let clauses = separate_map sep doc_funcl fcls in
+ let clauses = separate_map sep doc_funcl_ocaml fcls in
separate space [string "let";
doc_rec_ocaml r;
doc_id_ocaml id;
equals;
(string "function");
+ (hardline^^pipe);
clauses]
let doc_dec_ocaml (DEC_aux (reg,(l,annot))) =
@@ -1665,18 +1710,18 @@ let doc_dec_ocaml (DEC_aux (reg,(l,annot))) =
separate space [string "let";
doc_id_ocaml id;
equals;
- string "ref";
- parens (separate space
- [string "Vregister";
- parens (separate comma [doc_int (int_of_big_int start);
- o;
- parens (separate space
- [string "Array.make";
- doc_int (int_of_big_int size);
- string "Vzero";
- string "[]"])])])]
+ string "Vregister";
+ parens (separate comma [separate space [string "ref";
+ parens (separate space
+ [string "Array.make";
+ doc_int (int_of_big_int size);
+ string "Vzero";])];
+ doc_int (int_of_big_int start);
+ o;
+ brackets empty])]
| _ -> empty)
- | Tapp("register", [TA_typ {t=Tid idt}]) ->
+ | Tapp("register", [TA_typ {t=Tid idt}]) |
+ Tabbrev( {t= Tid idt}, _) ->
separate space [string "let";
doc_id_ocaml id;
equals;
@@ -1684,10 +1729,10 @@ let doc_dec_ocaml (DEC_aux (reg,(l,annot))) =
string "None"]
|_-> empty)
| _ -> empty)
- | DEC_alias(id,alspec) ->
- doc_op equals (string "register alias" ^^ space ^^ doc_id id) (doc_alias alspec)
- | DEC_typ_alias(typ,id,alspec) ->
- doc_op equals (string "register alias" ^^ space ^^ doc_atomic_typ typ) (doc_alias alspec)
+ | 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_ocaml def = group (match def with
| DEF_default df -> empty
diff --git a/src/process_file.ml b/src/process_file.ml
index 5b6c8ee5..443ea9b0 100644
--- a/src/process_file.ml
+++ b/src/process_file.ml
@@ -174,7 +174,7 @@ let output1 libpath out_arg filename defs (* alldoc_accum alldoc_inc_accum alldo
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_ocaml o defs (generated_line filename) ["Sail_values"];
+ begin Pretty_print.pp_defs_ocaml o defs (generated_line filename) ["Sail_values";];
close_output_with_check ext_o
end
| Lem_out (Some lib) ->
@@ -183,12 +183,12 @@ let output1 libpath out_arg filename defs (* alldoc_accum alldoc_inc_accum alldo
close_output_with_check ext_o
| 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) ["Sail_values"];
+ begin Pretty_print.pp_defs_ocaml o defs (generated_line filename) ["Big_int_Z";"Sail_values"];
close_output_with_check ext_o
end
| Ocaml_out (Some lib) ->
let ((o,temp_file_name, _) as ext_o) = open_output_with_check_unformatted (f' ^ ".ml") in
- Pretty_print.pp_defs_ocaml o defs (generated_line filename) ["Sail_values"; lib];
+ Pretty_print.pp_defs_ocaml o defs (generated_line filename) ["Big_int_Z"; "Sail_values"; lib];
close_output_with_check ext_o
diff --git a/src/test/test1.sail b/src/test/test1.sail
index 8143bf5d..0c08324c 100644
--- a/src/test/test1.sail
+++ b/src/test/test1.sail
@@ -12,7 +12,7 @@ typedef creg = register bits [5:10] { 5 : h ; 6..7 : j}
let (bool) e = true
val forall Nat 'a, Nat 'b. bit['a:'b] sliced
let (bit) v = bitzero
-let ( bit [ 32 ] ) v1 = 0b101
+let ( bit [ 3 ] ) v1 = 0b101
let ( bit [32] ) v2 = 0xABCDEF01
diff --git a/src/type_internal.ml b/src/type_internal.ml
index 9d840639..af6626b8 100644
--- a/src/type_internal.ml
+++ b/src/type_internal.ml
@@ -2879,7 +2879,8 @@ let rec type_coerce_internal co d_env enforce is_explicit widen bounds t1 cs1 e
(t2,[GtEq(co,Require,b1,n_zero);LtEq(co,Require,r1,mk_c(big_int_of_int num_enums))],pure_e,
E_aux(E_case(e,
List.mapi (fun i a -> Pat_aux(Pat_exp(P_aux(P_lit(L_aux((L_num i),l)), (l,simple_annot t1)),
- E_aux(E_id(Id_aux(Id a,l)), (l, simple_annot t2))),
+ E_aux(E_id(Id_aux(Id a,l)),
+ (l, tag_annot t2 (Enum num_enums)))),
(l,simple_annot t2))) enums),
(l,simple_annot_efr t2 (get_cummulative_effects (get_eannot e)))))
| None -> eq_error l ("Type mismatch: found a " ^ (t_to_string t1) ^ " but expected " ^ (t_to_string t2)))
@@ -2891,7 +2892,8 @@ let rec type_coerce_internal co d_env enforce is_explicit widen bounds t1 cs1 e
LtEq(co,Require,b1,mk_c(big_int_of_int num_enums))],pure_e,
E_aux(E_case(e,
List.mapi (fun i a -> Pat_aux(Pat_exp(P_aux(P_lit(L_aux((L_num i),l)),(l, simple_annot t1)),
- E_aux(E_id(Id_aux(Id a,l)),(l, simple_annot t2))),
+ E_aux(E_id(Id_aux(Id a,l)),
+ (l, tag_annot t2 (Enum num_enums)))),
(l,simple_annot t2))) enums),
(l,simple_annot_efr t2 (get_cummulative_effects (get_eannot e)))))
| None -> eq_error l ("Type mismatch: found a " ^ (t_to_string t1) ^ " but expected " ^ (t_to_string t2)))
diff --git a/src/util.ml b/src/util.ml
index 0ae3fcf7..a2bd7cc0 100644
--- a/src/util.ml
+++ b/src/util.ml
@@ -80,6 +80,11 @@ let remove_dups compare eq l =
in
aux [] l'
+let rec power i tothe =
+ if tothe <= 0
+ then 1
+ else i * power i (tothe - 1)
+
let rec assoc_maybe eq l k =
match l with
| [] -> None
diff --git a/src/util.mli b/src/util.mli
index bc2a1261..45e20381 100644
--- a/src/util.mli
+++ b/src/util.mli
@@ -61,6 +61,8 @@ val remove_dups : ('a -> 'a -> int) -> ('a -> 'a -> bool) -> 'a list -> 'a list
val assoc_maybe : ('a -> 'a -> bool) -> ('a * 'b) list -> 'a -> 'b option
+val power : int -> int -> int
+
(** {2 Option Functions} *)
(** [option_map f None] returns [None], whereas