summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlasdair2018-12-12 00:49:32 +0000
committerAlasdair2018-12-12 00:49:32 +0000
commitc65aecd008d34102f4c95649113ed7f9afcc903b (patch)
tree71386fec2d39ffc7f73b219b70c2fc49d5adbb10 /src
parentab4b9ca4f7cab45b6a2a13d0ef125dcf9c276a06 (diff)
Fix various boolean type-variable related issues
Remove some dead code in Pretty_print_common Start thinking a bit about Minisail-esque syntactic sugar in initial_check
Diffstat (limited to 'src')
-rw-r--r--src/ast_util.ml8
-rw-r--r--src/ast_util.mli4
-rw-r--r--src/initial_check.ml5
-rw-r--r--src/parse_ast.ml1
-rw-r--r--src/parser.mly2
-rw-r--r--src/pretty_print_common.ml128
-rw-r--r--src/pretty_print_sail.ml10
-rw-r--r--src/type_check.ml10
8 files changed, 33 insertions, 135 deletions
diff --git a/src/ast_util.ml b/src/ast_util.ml
index 8544700b..6c67e6e7 100644
--- a/src/ast_util.ml
+++ b/src/ast_util.ml
@@ -143,6 +143,10 @@ let is_typ_kopt = function
| KOpt_aux (KOpt_kind (K_aux (K_type, _), _), _) -> true
| _ -> false
+let is_bool_kopt = function
+ | KOpt_aux (KOpt_kind (K_aux (K_bool, _), _), _) -> true
+ | _ -> false
+
let string_of_kid = function
| Kid_aux (Var v, _) -> v
@@ -321,6 +325,9 @@ let mk_infix_id str = Id_aux (DeIid str, Parse_ast.Unknown)
let mk_id_typ id = Typ_aux (Typ_id id, Parse_ast.Unknown)
+let mk_kopt kind_aux id =
+ KOpt_aux (KOpt_kind (K_aux (kind_aux, Parse_ast.Unknown), id), Parse_ast.Unknown)
+
let mk_ord ord_aux = Ord_aux (ord_aux, Parse_ast.Unknown)
let unknown_typ = mk_typ Typ_internal_unknown
@@ -673,6 +680,7 @@ and string_of_typ_aux = function
| Typ_var kid -> string_of_kid kid
| Typ_tup typs -> "(" ^ string_of_list ", " string_of_typ typs ^ ")"
| Typ_app (id, args) when Id.compare id (mk_id "atom") = 0 -> "int(" ^ string_of_list ", " string_of_typ_arg args ^ ")"
+ | Typ_app (id, args) when Id.compare id (mk_id "atom_bool") = 0 -> "bool(" ^ string_of_list ", " string_of_typ_arg args ^ ")"
| Typ_app (id, args) -> string_of_id id ^ "(" ^ string_of_list ", " string_of_typ_arg args ^ ")"
| Typ_fn ([typ_arg], typ_ret, eff) ->
string_of_typ typ_arg ^ " -> " ^ string_of_typ typ_ret ^ " effect " ^ string_of_effect eff
diff --git a/src/ast_util.mli b/src/ast_util.mli
index fe36dfb6..c0123ce1 100644
--- a/src/ast_util.mli
+++ b/src/ast_util.mli
@@ -90,6 +90,7 @@ val mk_qi_nc : n_constraint -> quant_item
val mk_qi_kopt : kinded_id -> quant_item
val mk_fexp : id -> unit exp -> unit fexp
val mk_letbind : unit pat -> unit exp -> unit letbind
+val mk_kopt : kind_aux -> kid -> kinded_id
val unaux_exp : 'a exp -> 'a exp_aux
val unaux_pat : 'a pat -> 'a pat_aux
@@ -110,7 +111,8 @@ val kopt_kid : kinded_id -> kid
val is_nat_kopt : kinded_id -> bool
val is_order_kopt : kinded_id -> bool
val is_typ_kopt : kinded_id -> bool
-
+val is_bool_kopt : kinded_id -> bool
+
(* Some handy utility functions for constructing types. *)
val mk_typ : typ_aux -> typ
val mk_typ_arg : typ_arg_aux -> typ_arg
diff --git a/src/initial_check.ml b/src/initial_check.ml
index 44f36892..da6c7b84 100644
--- a/src/initial_check.ml
+++ b/src/initial_check.ml
@@ -96,7 +96,7 @@ let to_ast_id (P.Id_aux(id, l)) =
| P.DeIid x -> DeIid x),
l)
-let to_ast_var (P.Kid_aux(P.Var v,l)) = Kid_aux(Var v,l)
+let to_ast_var (P.Kid_aux (P.Var v, l)) = Kid_aux (Var v, l)
let to_ast_effects = function
| P.ATyp_aux (P.ATyp_set effects, l) ->
@@ -161,6 +161,8 @@ let rec to_ast_typ ctx (P.ATyp_aux (aux, l)) =
let kids = List.map to_ast_var kids in
let ctx = { ctx with kinds = List.fold_left (fun kinds kid -> KBindings.add kid K_int kinds) ctx.kinds kids } in
Typ_exist (kids, to_ast_constraint ctx nc, to_ast_typ ctx atyp)
+ | P.ATyp_base (id, kind, nc) ->
+ raise (Reporting.err_unreachable l __POS__ "TODO")
| _ -> raise (Reporting.err_typ l "Invalid type")
in
Typ_aux (aux, l)
@@ -763,6 +765,7 @@ let initial_ctx = {
("atom", [K_int]);
("implicit", [K_int]);
("itself", [K_int]);
+ ("not", [K_bool]);
];
kinds = KBindings.empty;
scattereds = Bindings.empty;
diff --git a/src/parse_ast.ml b/src/parse_ast.ml
index c57daa26..a5dbf66e 100644
--- a/src/parse_ast.ml
+++ b/src/parse_ast.ml
@@ -164,6 +164,7 @@ atyp_aux = (* expressions of all kinds, to be translated to types, nats, orders
| ATyp_tup of (atyp) list (* Tuple type *)
| ATyp_app of id * (atyp) list (* type constructor application *)
| ATyp_exist of kid list * atyp * atyp
+ | ATyp_base of id * atyp * atyp
and atyp =
ATyp_aux of atyp_aux * l
diff --git a/src/parser.mly b/src/parser.mly
index 83e6936d..544438c0 100644
--- a/src/parser.mly
+++ b/src/parser.mly
@@ -555,6 +555,8 @@ atomic_typ:
{ mk_typ (ATyp_exist ($2, ATyp_aux (ATyp_lit (L_aux (L_true, loc $startpos $endpos)), loc $startpos $endpos), $4)) $startpos $endpos }
| Lcurly kid_list Comma typ Dot typ Rcurly
{ mk_typ (ATyp_exist ($2, $4, $6)) $startpos $endpos }
+ | Lcurly id Colon typ Dot typ Rcurly
+ { mk_typ (ATyp_base ($2, $4, $6)) $startpos $endpos }
typ_list:
| typ
diff --git a/src/pretty_print_common.ml b/src/pretty_print_common.ml
index 0f1dee90..c01896ac 100644
--- a/src/pretty_print_common.ml
+++ b/src/pretty_print_common.ml
@@ -94,133 +94,5 @@ let rec doc_range (BF_aux(r,_)) = match r with
| BF_range(i1,i2) -> doc_op dotdot (doc_int i1) (doc_int i2)
| BF_concat(ir1,ir2) -> (doc_range ir1) ^^ comma ^^ (doc_range ir2)
-let doc_effect (BE_aux (e,_)) =
- string (match e with
- | BE_rreg -> "rreg"
- | BE_wreg -> "wreg"
- | BE_rmem -> "rmem"
- | BE_rmemt -> "rmemt"
- | BE_wmem -> "wmem"
- | BE_wmv -> "wmv"
- | BE_wmvt -> "wmvt"
- (*| BE_lset -> "lset"
- | BE_lret -> "lret"*)
- | BE_eamem -> "eamem"
- | BE_exmem -> "exmem"
- | BE_barr -> "barr"
- | BE_depend -> "depend"
- | BE_escape -> "escape"
- | BE_undef -> "undef"
- | BE_unspec -> "unspec"
- | BE_nondet -> "nondet"
- | BE_config -> "config")
-
-let doc_effects (Effect_aux(e,_)) = match e with
- | Effect_set [] -> string "pure"
- | Effect_set s -> braces (separate_map comma_sp doc_effect s)
-
-let doc_ord (Ord_aux(o,_)) = match o with
- | Ord_var v -> doc_var v
- | Ord_inc -> string "inc"
- | Ord_dec -> string "dec"
-
-let doc_typ, doc_atomic_typ, doc_nexp, doc_nexp_constraint =
- (* 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(args,ret,efct) ->
- separate space [parens (separate_map (comma ^^ space) tup_typ args); arrow; fn_typ ret; string "effect"; doc_effects efct]
- | Typ_bidir (t1, t2) ->
- separate space [tup_typ t1; bidir; tup_typ t2]
- | _ -> tup_typ ty
- and tup_typ ((Typ_aux (t, _)) as ty) = match t with
- | Typ_exist (kids, nc, ty) ->
- separate space [string "exist"; separate_map space doc_var kids ^^ comma; nexp_constraint nc ^^ dot; typ ty]
- | Typ_tup typs -> parens (separate_map comma_sp app_typ typs)
- | _ -> app_typ ty
- and app_typ ((Typ_aux (t, _)) as ty) = match t with
- | Typ_app(Id_aux (Id "range", _), [
- A_aux(A_nexp (Nexp_aux(Nexp_constant n, _)), _);
- A_aux(A_nexp m, _);]) ->
- (squarebars (if Big_int.equal n Big_int.zero then nexp m else doc_op colon (doc_int n) (nexp m)))
- | Typ_app(Id_aux (Id "atom", _), [A_aux(A_nexp n,_)]) ->
- (squarecolons (nexp n))
- | Typ_app(id,args) ->
- (* trailing space to avoid >> token in case of nested app types *)
- (doc_id id) ^^ (angles (separate_map comma_sp doc_typ_arg args)) ^^ space
- | _ -> atomic_typ ty (* for simplicity, skip vec_typ - which is only sugar *)
- and atomic_typ ((Typ_aux (t, _)) as ty) = match t with
- | Typ_id id -> doc_id id
- | Typ_var v -> doc_var v
- | Typ_app _ | Typ_tup _ | Typ_fn _ | Typ_bidir _ | Typ_exist _ ->
- (* exhaustiveness matters here to avoid infinite loops
- * if we add a new Typ constructor *)
- group (parens (typ ty))
- | Typ_internal_unknown -> string "UNKNOWN"
-
- and doc_typ_arg (A_aux(t,_)) = match t with
- (* Be careful here because typ_arg is implemented as nexp in the
- * parser - in practice falling through app_typ after all the proper nexp
- * cases; so A_typ has the same precedence as a Typ_app *)
- | A_typ t -> app_typ t
- | A_nexp n -> nexp n
- | A_order o -> doc_ord o
-
- (* same trick to handle precedence of nexp *)
- and nexp ne = sum_typ ne
- and sum_typ ((Nexp_aux(n,_)) as ne) = match n with
- | Nexp_sum(n1,n2) -> doc_op plus (sum_typ n1) (star_typ n2)
- | Nexp_minus(n1,n2) -> doc_op minus (sum_typ n1) (star_typ n2)
- | _ -> star_typ ne
- and star_typ ((Nexp_aux(n,_)) as ne) = match n with
- | Nexp_times(n1,n2) -> doc_op star (star_typ n1) (exp_typ n2)
- | _ -> exp_typ ne
- and exp_typ ((Nexp_aux(n,_)) as ne) = match n with
- | Nexp_exp n1 -> doc_unop (string "2**") (atomic_nexp_typ n1)
- | _ -> neg_typ ne
- and neg_typ ((Nexp_aux(n,_)) as ne) = match n with
- | Nexp_neg n1 ->
- (* XXX this is not valid Sail, only an internal representation -
- * work around by commenting it *)
- let minus = concat [string "(*"; minus; string "*)"] in
- minus ^^ (atomic_nexp_typ n1)
- | _ -> atomic_nexp_typ ne
- and atomic_nexp_typ ((Nexp_aux(n,_)) as ne) = match n with
- | Nexp_var v -> doc_var v
- | Nexp_id i -> braces (doc_id i)
- | Nexp_app (op, args) -> doc_id op ^^ parens (separate_map (comma ^^ space) nexp args)
- | Nexp_constant i -> if Big_int.less i Big_int.zero then parens(doc_int i) else doc_int i
- | Nexp_neg _ | Nexp_exp _ | Nexp_times _ | Nexp_sum _ | Nexp_minus _->
- group (parens (nexp ne))
-
- and nexp_constraint (NC_aux(nc,_)) = match nc with
- | NC_equal(n1,n2) -> doc_op equals (nexp n1) (nexp n2)
- | NC_not_equal (n1, n2) -> doc_op (string "!=") (nexp n1) (nexp n2)
- | NC_bounded_ge(n1,n2) -> doc_op (string ">=") (nexp n1) (nexp n2)
- | NC_bounded_le(n1,n2) -> doc_op (string "<=") (nexp n1) (nexp n2)
- | NC_set(v,bounds) ->
- doc_op (string "IN") (doc_var v)
- (braces (separate_map comma_sp doc_int bounds))
- | NC_or (nc1, nc2) ->
- parens (separate space [nexp_constraint nc1; string "|"; nexp_constraint nc2])
- | NC_and (nc1, nc2) ->
- separate space [nexp_constraint nc1; string "&"; nexp_constraint nc2]
- | NC_true -> string "true"
- | NC_false -> string "false"
-
- (* expose doc_typ, doc_atomic_typ, doc_nexp and doc_nexp_constraint *)
- in typ, atomic_typ, nexp, nexp_constraint
-
-let pp_format_id (Id_aux(i,_)) =
- match i with
- | Id(i) -> i
- | DeIid(x) -> "(deinfix " ^ x ^ ")"
-
-let rec list_format (sep : string) (fmt : 'a -> string) (ls : 'a list) : string =
- match ls with
- | [] -> ""
- | [a] -> fmt a
- | a::ls -> (fmt a) ^ sep ^ (list_format sep fmt ls)
-
let print ?(len=100) channel doc = ToChannel.pretty 1. len channel doc
let to_buf ?(len=100) buf doc = ToBuffer.pretty 1. len buf doc
diff --git a/src/pretty_print_sail.ml b/src/pretty_print_sail.ml
index 94bcd54b..f756f3d2 100644
--- a/src/pretty_print_sail.ml
+++ b/src/pretty_print_sail.ml
@@ -113,7 +113,7 @@ let rec doc_nexp =
in
nexp0
-let doc_nc nc =
+let rec doc_nc nc =
let nc_op op n1 n2 = separate space [doc_nexp n1; string op; doc_nexp n2] in
let rec atomic_nc (NC_aux (nc_aux, _) as nc) =
match nc_aux with
@@ -125,7 +125,10 @@ let doc_nc nc =
| NC_bounded_le (n1, n2) -> nc_op "<=" n1 n2
| NC_set (kid, ints) ->
separate space [doc_kid kid; string "in"; braces (separate_map (comma ^^ space) doc_int ints)]
- | _ -> nc0 ~parenthesize:true nc
+ | NC_app (id, args) ->
+ doc_id id ^^ parens (separate_map (comma ^^ space) doc_typ_arg args)
+ | NC_var kid -> doc_kid kid
+ | NC_or _ | NC_and _ -> nc0 ~parenthesize:true nc
and nc0 ?parenthesize:(parenthesize=false) (NC_aux (nc_aux, _) as nc) =
(* Rather than parens (nc0 x) we use nc0 ~parenthesize:true x, because if
we rewrite a disjunction as a set constraint, then we can
@@ -151,7 +154,7 @@ let doc_nc nc =
in
atomic_nc (constraint_simp nc)
-let rec doc_typ ?(simple=false) (Typ_aux (typ_aux, l)) =
+and doc_typ ?(simple=false) (Typ_aux (typ_aux, l)) =
match typ_aux with
| Typ_id id -> doc_id id
| Typ_app (id, []) -> doc_id id
@@ -186,6 +189,7 @@ and doc_typ_arg (A_aux (ta_aux, _)) =
| A_typ typ -> doc_typ typ
| A_nexp nexp -> doc_nexp nexp
| A_order o -> doc_ord o
+ | A_bool nc -> doc_nc nc
and doc_arg_typs = function
| [typ] -> doc_typ typ
| typs -> parens (separate_map (comma ^^ space) doc_typ typs)
diff --git a/src/type_check.ml b/src/type_check.ml
index 51625d4a..2f4561b5 100644
--- a/src/type_check.ml
+++ b/src/type_check.ml
@@ -449,7 +449,8 @@ end = struct
("real", []);
("list", [K_type]);
("string", []);
- ("itself", [K_int])
+ ("itself", [K_int]);
+ ("atom_bool", [K_bool])
]
let builtin_mappings =
@@ -499,6 +500,8 @@ end = struct
subst_args kopts args
| kopt :: kopts, A_aux (A_order arg, _) :: args when is_order_kopt kopt ->
subst_args kopts args
+ | kopt :: kopts, A_aux (A_bool arg, _) :: args when is_bool_kopt kopt ->
+ subst_args kopts args
| [], [] -> ncs
| _, A_aux (_, l) :: _ -> typ_error l ("Error when processing type quantifer arguments " ^ string_of_typquant typq)
| _, _ -> typ_error Parse_ast.Unknown ("Error when processing type quantifer arguments " ^ string_of_typquant typq)
@@ -1624,8 +1627,9 @@ let rec alpha_equivalent env typ1 typ2 =
in
Typ_aux (relabelled_aux, l)
and relabel_arg (A_aux (aux, l) as arg) =
+ (* FIXME relabel constraint *)
match aux with
- | A_nexp _ | A_order _ -> arg
+ | A_nexp _ | A_order _ | A_bool _ -> arg
| A_typ typ -> A_aux (A_typ (relabel typ), l)
in
@@ -1729,6 +1733,8 @@ let rec subtyp l env typ1 typ2 =
match typ_aux1, typ_aux2 with
| _, Typ_internal_unknown when Env.allow_unknowns env -> ()
+ | Typ_app (id1, _), Typ_id id2 when string_of_id id1 = "atom_bool" && string_of_id id2 = "bool" -> ()
+
| Typ_tup typs1, Typ_tup typs2 when List.length typs1 = List.length typs2 ->
List.iter2 (subtyp l env) typs1 typs2