summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/monomorphise.ml27
-rw-r--r--src/spec_analysis.ml2
-rw-r--r--src/type_check.ml9
3 files changed, 33 insertions, 5 deletions
diff --git a/src/monomorphise.ml b/src/monomorphise.ml
index 2849b466..d9ee73b8 100644
--- a/src/monomorphise.ml
+++ b/src/monomorphise.ml
@@ -558,6 +558,26 @@ let lit_eq (L_aux (l1,_)) (L_aux (l2,_)) =
| L_undef, _ | _, L_undef -> None
| _ -> Some (l1 = l2)
+(* TODO: we should really specify which functions are equality in the prelude,
+ rather than fixing them here. *)
+let eq_fns = [Id "eq_int"; Id "eq_vec"; Id "eq_string"; Id "eq_real"]
+let neq_fns = [Id "neq_anything"]
+
+let try_app (l,ann) (Id_aux (id,_),args) =
+ let is_eq = List.mem id eq_fns in
+ let is_neq = (not is_eq) && List.mem id neq_fns in
+ if is_eq || is_neq then
+ let new_l = Generated l in
+ match args with
+ | [E_aux (E_lit l1,_); E_aux (E_lit l2,_)] ->
+ let lit b = if b then L_true else L_false in
+ let lit b = lit (if is_eq then b else not b) in
+ (match lit_eq l1 l2 with
+ | None -> None
+ | Some b -> Some (E_aux (E_lit (L_aux (lit b,new_l)),(l,ann))))
+ | _ -> None
+ else None
+
let try_app_infix (l,ann) (E_aux (e1,ann1)) (Id_aux (id,_)) (E_aux (e2,ann2)) =
let i = match id with Id x -> x | DeIid x -> x in
@@ -675,8 +695,11 @@ let split_defs splits defs =
| E_cast (t,e') -> re (E_cast (t, const_prop_exp substs e'))
| E_app (id,es) ->
let es' = List.map (const_prop_exp substs) es in
- (match const_prop_try_fn (id,es') with
- | None -> re (E_app (id,es'))
+ (match try_app (l,annot) (id,es') with
+ | None ->
+ (match const_prop_try_fn (id,es') with
+ | None -> re (E_app (id,es'))
+ | Some r -> r)
| Some r -> r)
| E_app_infix (e1,id,e2) ->
let e1',e2' = const_prop_exp substs e1,const_prop_exp substs e2 in
diff --git a/src/spec_analysis.ml b/src/spec_analysis.ml
index 1475da7a..5281ef27 100644
--- a/src/spec_analysis.ml
+++ b/src/spec_analysis.ml
@@ -211,6 +211,7 @@ let rec free_type_names_t consider_var (Typ_aux (t, _)) = match t with
| Typ_tup ts -> free_type_names_ts consider_var ts
| Typ_app (name,targs) -> Nameset.add (string_of_id name) (free_type_names_t_args consider_var targs)
| Typ_wild -> mt
+ | Typ_exist (kids,_,t') -> List.fold_left (fun s kid -> Nameset.remove (string_of_kid kid) s) (free_type_names_t consider_var t') kids
and free_type_names_ts consider_var ts = nameset_bigunion (List.map (free_type_names_t consider_var) ts)
and free_type_names_maybe_t consider_var = function
| Some t -> free_type_names_t consider_var t
@@ -239,6 +240,7 @@ let rec fv_of_typ consider_var bound used (Typ_aux (t,_)) : Nameset.t =
| Typ_tup ts -> List.fold_right (fun t n -> fv_of_typ consider_var bound n t) ts used
| Typ_app(id,targs) ->
List.fold_right (fun ta n -> fv_of_targ consider_var bound n ta) targs (conditional_add_typ bound used id)
+ | Typ_exist (kids,_,t') -> fv_of_typ consider_var (List.fold_left (fun b (Kid_aux (Var v,_)) -> Nameset.add v b) bound kids) used t'
and fv_of_targ consider_var bound used (Ast.Typ_arg_aux(targ,_)) : Nameset.t = match targ with
| Typ_arg_typ t -> fv_of_typ consider_var bound used t
diff --git a/src/type_check.ml b/src/type_check.ml
index 2cfdb899..8a7983ce 100644
--- a/src/type_check.ml
+++ b/src/type_check.ml
@@ -1845,7 +1845,10 @@ let rec check_exp env (E_aux (exp_aux, (l, ())) as exp : unit exp) (Typ_aux (typ
begin
try
let nc = assert_constraint const_expr in
- check_block l (Env.add_constraint nc env) exps typ
+ let cexp = annot_exp (E_constraint nc) bool_typ in
+ let checked_msg = crule check_exp env assert_msg string_typ in
+ let texp = annot_exp (E_assert (cexp, checked_msg)) unit_typ in
+ texp :: check_block l (Env.add_constraint nc env) exps typ
with
| Not_a_constraint -> check_block l env exps typ
end
@@ -2311,11 +2314,11 @@ and bind_lexp env (LEXP_aux (lexp_aux, (l, ())) as lexp) typ =
let (Typ_aux (typ_aux, _)) = typ in
match typ_aux with
| Typ_tup typs ->
- let bind_tuple_lexp (tlexps, env) lexp typ =
+ let bind_tuple_lexp lexp typ (tlexps, env) =
let tlexp, env = bind_lexp env lexp typ in tlexp :: tlexps, env
in
let tlexps, env =
- try List.fold_left2 bind_tuple_lexp ([], env) lexps typs with
+ try List.fold_right2 bind_tuple_lexp lexps typs ([], env) with
| Invalid_argument _ -> typ_error l "Tuple l-expression and tuple type have different length"
in
annot_lexp (LEXP_tup tlexps) typ, env