diff options
| author | Jon French | 2019-02-13 12:27:48 +0000 |
|---|---|---|
| committer | Jon French | 2019-02-13 12:27:48 +0000 |
| commit | ea39b3c674570ce5eea34067c36d5196ca201f83 (patch) | |
| tree | 516e7491bc32797a4d0ac397ea47387f2b16cf1b /src/rewrites.ml | |
| parent | ab3f3671d4dd682b2aee922d5a05e9455afd5849 (diff) | |
| parent | 24fc989891ad266eae642815646294279e2485ca (diff) | |
Merge branch 'sail2' into rmem_interpreter
Diffstat (limited to 'src/rewrites.ml')
| -rw-r--r-- | src/rewrites.ml | 377 |
1 files changed, 210 insertions, 167 deletions
diff --git a/src/rewrites.ml b/src/rewrites.ml index 284c7d67..44d99537 100644 --- a/src/rewrites.ml +++ b/src/rewrites.ml @@ -54,7 +54,6 @@ open Ast_util open Type_check open Spec_analysis open Rewriter -open Extra_pervasives let (>>) f g = fun x -> g(f(x)) @@ -239,7 +238,7 @@ let lookup_constant_kid env kid = List.fold_left check_nc None (Env.get_constraints env) let rec rewrite_nexp_ids env (Nexp_aux (nexp, l) as nexp_aux) = match nexp with - | Nexp_id id -> rewrite_nexp_ids env (Env.get_num_def id env) + | Nexp_id id -> Env.expand_nexp_synonyms env nexp_aux | Nexp_var kid -> begin match lookup_constant_kid env kid with @@ -281,27 +280,27 @@ let rewrite_defs_nexp_ids, rewrite_typ_nexp_ids = | None -> l, empty_tannot in - let rewrite_def rewriters = function - | DEF_spec (VS_aux (VS_val_spec (typschm, id, exts, b), (l, tannot))) when not (is_empty_tannot tannot) -> - let env = env_of_annot (l, tannot) in - let typ = typ_of_annot (l, tannot) in - let eff = effect_of_annot tannot in - let typschm = match typschm with - | TypSchm_aux (TypSchm_ts (tq, typ), l) -> - TypSchm_aux (TypSchm_ts (tq, rewrite_typ env typ), l) - in - let a = rewrite_annot (l, mk_tannot env typ eff) in + let rewrite_typschm env (TypSchm_aux (TypSchm_ts (tq, typ), l)) = + TypSchm_aux (TypSchm_ts (tq, rewrite_typ env typ), l) + in + + let rewrite_def env rewriters = function + | DEF_spec (VS_aux (VS_val_spec (typschm, id, exts, b), a)) -> + let typschm = rewrite_typschm env typschm in + let a = rewrite_annot a in DEF_spec (VS_aux (VS_val_spec (typschm, id, exts, b), a)) + | DEF_type (TD_aux (TD_abbrev (id, typq, typ_arg), a)) -> + DEF_type (TD_aux (TD_abbrev (id, typq, rewrite_typ_arg env typ_arg), a)) | d -> Rewriter.rewrite_def rewriters d in - rewrite_defs_base { rewriters_base with - rewrite_exp = (fun _ -> map_exp_annot rewrite_annot); rewrite_def = rewrite_def - }, + (fun env defs -> rewrite_defs_base { rewriters_base with + rewrite_exp = (fun _ -> map_exp_annot rewrite_annot); rewrite_def = rewrite_def env + } defs), rewrite_typ -let rewrite_bitvector_exps defs = +let rewrite_bitvector_exps env defs = let e_aux = function | (E_vector es, ((l, tannot) as a)) when not (is_empty_tannot tannot) -> let env = env_of_annot (l, tannot) in @@ -332,18 +331,18 @@ let rewrite_trivial_sizeof, rewrite_trivial_sizeof_exp = let extract_typ_var l env nexp (id, (_, typ)) = let var = E_aux (E_id id, (l, mk_tannot env typ no_effect)) in match destruct_atom_nexp env typ with - | Some size when prove env (nc_eq size nexp) -> Some var + | Some size when prove __POS__ env (nc_eq size nexp) -> Some var (* AA: This next case is a bit of a hack... is there a more general way to deal with trivial nexps that are offset by constants? This will resolve a 'n - 1 sizeof when 'n is in scope. *) - | Some size when prove env (nc_eq (nsum size (nint 1)) nexp) -> + | Some size when prove __POS__ env (nc_eq (nsum size (nint 1)) nexp) -> let one_exp = infer_exp env (mk_lit_exp (L_num (Big_int.of_int 1))) in Some (E_aux (E_app (mk_id "add_atom", [var; one_exp]), (gen_loc l, mk_tannot env (atom_typ (nsum size (nint 1))) no_effect))) | _ -> begin match destruct_vector env typ with - | Some (len, _, _) when prove env (nc_eq len nexp) -> + | Some (len, _, _) when prove __POS__ env (nc_eq len nexp) -> Some (E_aux (E_app (mk_id "length", [var]), (l, mk_tannot env (atom_typ len) no_effect))) | _ -> None end @@ -351,13 +350,24 @@ let rewrite_trivial_sizeof, rewrite_trivial_sizeof_exp = let rec split_nexp (Nexp_aux (nexp_aux, l) as nexp) = match nexp_aux with | Nexp_sum (n1, n2) -> - mk_exp (E_app (mk_id "add_atom", [split_nexp n1; split_nexp n2])) + mk_exp ~loc:l (E_app (mk_id "add_atom", [split_nexp n1; split_nexp n2])) | Nexp_minus (n1, n2) -> - mk_exp (E_app (mk_id "sub_atom", [split_nexp n1; split_nexp n2])) + mk_exp ~loc:l (E_app (mk_id "sub_atom", [split_nexp n1; split_nexp n2])) | Nexp_times (n1, n2) -> - mk_exp (E_app (mk_id "mult_atom", [split_nexp n1; split_nexp n2])) - | Nexp_neg nexp -> mk_exp (E_app (mk_id "negate_atom", [split_nexp nexp])) - | _ -> mk_exp (E_sizeof nexp) + mk_exp ~loc:l (E_app (mk_id "mult_atom", [split_nexp n1; split_nexp n2])) + | Nexp_neg nexp -> + mk_exp ~loc:l (E_app (mk_id "negate_atom", [split_nexp nexp])) + | Nexp_app (f, [n1; n2]) when string_of_id f = "div" -> + (* We should be more careful about the right division here *) + mk_exp ~loc:l (E_app (mk_id "div", [split_nexp n1; split_nexp n2])) + | _ -> + mk_exp ~loc:l (E_sizeof nexp) + in + let is_int_typ env v _ = function + | (_, Typ_aux (Typ_app (f, [A_aux (A_nexp (Nexp_aux (Nexp_var v', _)), _)]), _)) + when Kid.compare v v' = 0 && string_of_id f = "atom" -> + true + | _ -> false in let rec rewrite_e_aux split_sizeof (E_aux (e_aux, (l, _)) as orig_exp) = let env = env_of orig_exp in @@ -366,9 +376,13 @@ let rewrite_trivial_sizeof, rewrite_trivial_sizeof_exp = E_aux (E_lit (L_aux (L_num c, l)), (l, mk_tannot env (atom_typ nexp) no_effect)) | E_sizeof nexp -> begin + let locals = Env.get_locals env in match nexp_simp (rewrite_nexp_ids (env_of orig_exp) nexp) with | Nexp_aux (Nexp_constant c, _) -> E_aux (E_lit (L_aux (L_num c, l)), (l, mk_tannot env (atom_typ nexp) no_effect)) + | Nexp_aux (Nexp_var v, _) when Bindings.exists (is_int_typ env v) locals -> + let id = fst (Bindings.choose (Bindings.filter (is_int_typ env v) locals)) in + E_aux (E_id id, (l, mk_tannot env (atom_typ nexp) no_effect)) | _ -> let locals = Env.get_locals env in let exps = Bindings.bindings locals @@ -386,7 +400,7 @@ let rewrite_trivial_sizeof, rewrite_trivial_sizeof_exp = and rewrite_e_sizeof split_sizeof = { id_exp_alg with e_aux = (fun (exp, annot) -> rewrite_e_aux split_sizeof (E_aux (exp, annot))) } in - rewrite_defs_base { rewriters_base with rewrite_exp = (fun _ -> fold_exp (rewrite_e_sizeof true)) }, rewrite_e_aux true + (fun env -> rewrite_defs_base_parallel 4 { rewriters_base with rewrite_exp = (fun _ -> fold_exp (rewrite_e_sizeof true)) }), rewrite_e_aux true (* Rewrite sizeof expressions with type-level variables to term-level expressions @@ -395,7 +409,7 @@ let rewrite_trivial_sizeof, rewrite_trivial_sizeof_exp = be directly extracted from existing parameters of the surrounding function, a further parameter is added; calls to the function are rewritten accordingly (possibly causing further rewriting in the calling function) *) -let rewrite_sizeof (Defs defs) = +let rewrite_sizeof env (Defs defs) = let sizeof_frees exp = fst (fold_exp { (compute_exp_alg KidSet.empty KidSet.union) with @@ -462,7 +476,7 @@ let rewrite_sizeof (Defs defs) = for the given parameters in the original environment *) let inst = try instantiation_of orig_exp with - | Type_error (l, err) -> + | Type_error (_, l, err) -> raise (Reporting.err_typ l (Type_error.string_of_type_error err)) in (* Rewrite the inst using orig_kid so that each type variable has it's original name rather than a mangled typechecker name *) @@ -475,7 +489,7 @@ let rewrite_sizeof (Defs defs) = | Some (A_aux (A_nexp nexp, _)) -> let sizeof = E_aux (E_sizeof nexp, (l, mk_tannot env (atom_typ nexp) no_effect)) in (try rewrite_trivial_sizeof_exp sizeof with - | Type_error (l, err) -> + | Type_error (_, l, err) -> raise (Reporting.err_typ l (Type_error.string_of_type_error err))) (* If the type variable is Not_found then it was probably introduced by a P_var pattern, so it likely exists as @@ -996,7 +1010,7 @@ let rewrite_fun_remove_vector_concat_pat (FCL_aux (FCL_Funcl (id,pexp'),(l,annot))) in FD_aux (FD_function(recopt,tannotopt,effectopt,List.map rewrite_funcl funcls),(l,fdannot)) -let rewrite_defs_remove_vector_concat (Defs defs) = +let rewrite_defs_remove_vector_concat env (Defs defs) = let rewriters = {rewrite_exp = rewrite_exp_remove_vector_concat_pat; rewrite_pat = rewrite_pat; @@ -1325,7 +1339,7 @@ let contains_bitvector_pexp = function let remove_bitvector_pat (P_aux (_, (l, _)) as pat) = - let env = try env_of_pat pat with _ -> Env.empty in + let env = try env_of_pat pat with _ -> raise (Reporting.err_unreachable l __POS__ "Pattern without annotation found") in (* first introduce names for bitvector patterns *) let name_bitvector_roots = @@ -1565,7 +1579,7 @@ let rewrite_fun_remove_bitvector_pat | _ -> funcls in FD_aux (FD_function(recopt,tannotopt,effectopt,funcls),(l,fdannot)) -let rewrite_defs_remove_bitvector_pats (Defs defs) = +let rewrite_defs_remove_bitvector_pats env (Defs defs) = let rewriters = {rewrite_exp = rewrite_exp_remove_bitvector_pat; rewrite_pat = rewrite_pat; @@ -1590,7 +1604,7 @@ let rewrite_defs_remove_bitvector_pats (Defs defs) = (* Rewrite literal number patterns to guarded patterns Those numeral patterns are not handled very well by Lem (or Isabelle) *) -let rewrite_defs_remove_numeral_pats = +let rewrite_defs_remove_numeral_pats env = let p_lit outer_env = function | L_aux (L_num n, l) -> let id = fresh_id "l__" Parse_ast.Unknown in @@ -1623,7 +1637,7 @@ let rewrite_defs_remove_numeral_pats = rewrite_defs_base { rewriters_base with rewrite_exp = rewrite_exp; rewrite_fun = rewrite_fun } -let rewrite_defs_vector_string_pats_to_bit_list = +let rewrite_defs_vector_string_pats_to_bit_list env = let rewrite_p_aux (pat, (annot : tannot annot)) = let env = env_of_annot annot in match pat with @@ -1707,7 +1721,7 @@ let rewrite_fun_guarded_pats rewriters (FD_aux (FD_function (r,t,e,funcls),(l,fd | _ -> funcls (* TODO is the empty list possible here? *) in FD_aux (FD_function(r,t,e,funcls),(l,fdannot)) -let rewrite_defs_guarded_pats = +let rewrite_defs_guarded_pats env = rewrite_defs_base { rewriters_base with rewrite_exp = rewrite_exp_guarded_pats; rewrite_fun = rewrite_fun_guarded_pats } @@ -1776,7 +1790,7 @@ let rewrite_exp_lift_assign_intro rewriters ((E_aux (exp,((l,_) as annot))) as f | _ -> rewrite_base full_exp -let rewrite_defs_exp_lift_assign defs = rewrite_defs_base +let rewrite_defs_exp_lift_assign env defs = rewrite_defs_base {rewrite_exp = rewrite_exp_lift_assign_intro; rewrite_pat = rewrite_pat; rewrite_let = rewrite_let; @@ -1824,7 +1838,7 @@ let rewrite_register_ref_writes (Defs defs) = TODO: Maybe separate generic removal of redundant returns, and Lem-specific rewriting of early returns *) -let rewrite_defs_early_return (Defs defs) = +let rewrite_defs_early_return env (Defs defs) = let is_unit (E_aux (exp, _)) = match exp with | E_lit (L_aux (L_unit, _)) -> true | _ -> false in @@ -2022,7 +2036,7 @@ let pat_var (P_aux (paux, a)) = (* Split out function clauses for individual union constructor patterns (e.g. AST nodes) into auxiliary functions. Used for the execute function. *) -let rewrite_split_fun_constr_pats fun_name (Defs defs) = +let rewrite_split_fun_constr_pats fun_name env (Defs defs) = let rewrite_fundef typquant (FD_aux (FD_function (r_o, t_o, e_o, clauses), ((l, _) as fdannot))) = let rec_clauses, clauses = List.partition is_funcl_rec clauses in let clauses, aux_funs = @@ -2092,23 +2106,23 @@ let rewrite_split_fun_constr_pats fun_name (Defs defs) = | _ -> function_typ [args_typ] ret_typ eff in - let quant_new_tyvars qis = - let quant_tyvars = List.fold_left KidSet.union KidSet.empty (List.map tyvars_of_quant_item qis) in - let typ_tyvars = tyvars_of_typ fun_typ in - let new_tyvars = KidSet.diff typ_tyvars quant_tyvars in - List.map (mk_qi_id K_int) (KidSet.elements new_tyvars) + let quant_new_kopts qis = + let quant_kopts = List.fold_left KOptSet.union KOptSet.empty (List.map kopts_of_quant_item qis) in + let typ_kopts = kopts_of_typ fun_typ in + let new_kopts = KOptSet.diff typ_kopts quant_kopts in + List.map mk_qi_kopt (KOptSet.elements new_kopts) in let typquant = match typquant with | TypQ_aux (TypQ_tq qis, l) -> let qis = List.filter - (fun qi -> KidSet.subset (tyvars_of_quant_item qi) (tyvars_of_typ fun_typ)) + (fun qi -> KOptSet.subset (kopts_of_quant_item qi) (kopts_of_typ fun_typ)) qis - @ quant_new_tyvars qis + @ quant_new_kopts qis in TypQ_aux (TypQ_tq qis, l) | _ -> - TypQ_aux (TypQ_tq (List.map (mk_qi_id K_int) (KidSet.elements (tyvars_of_typ fun_typ))), l) + TypQ_aux (TypQ_tq (List.map mk_qi_kopt (KOptSet.elements (kopts_of_typ fun_typ))), l) in let val_spec = VS_aux (VS_val_spec @@ -2135,7 +2149,7 @@ let rewrite_split_fun_constr_pats fun_name (Defs defs) = (* Propagate effects of functions, if effect checking and propagation have not been performed already by the type checker. *) -let rewrite_fix_val_specs (Defs defs) = +let rewrite_fix_val_specs env (Defs defs) = let find_vs env val_specs id = try Bindings.find id val_specs with | Not_found -> @@ -2275,25 +2289,32 @@ let rewrite_fix_val_specs (Defs defs) = (* Turn constraints into numeric expressions with sizeof *) let rewrite_constraint = - let rec rewrite_nc (NC_aux (nc_aux, l)) = mk_exp (rewrite_nc_aux nc_aux) - and rewrite_nc_aux = function + let rec rewrite_nc env (NC_aux (nc_aux, l)) = mk_exp (rewrite_nc_aux l env nc_aux) + and rewrite_nc_aux l env = function | NC_bounded_ge (n1, n2) -> E_app_infix (mk_exp (E_sizeof n1), mk_id ">=", mk_exp (E_sizeof n2)) | NC_bounded_le (n1, n2) -> E_app_infix (mk_exp (E_sizeof n1), mk_id "<=", mk_exp (E_sizeof n2)) | NC_equal (n1, n2) -> E_app_infix (mk_exp (E_sizeof n1), mk_id "==", mk_exp (E_sizeof n2)) | NC_not_equal (n1, n2) -> E_app_infix (mk_exp (E_sizeof n1), mk_id "!=", mk_exp (E_sizeof n2)) - | NC_and (nc1, nc2) -> E_app_infix (rewrite_nc nc1, mk_id "&", rewrite_nc nc2) - | NC_or (nc1, nc2) -> E_app_infix (rewrite_nc nc1, mk_id "|", rewrite_nc nc2) + | NC_and (nc1, nc2) -> E_app_infix (rewrite_nc env nc1, mk_id "&", rewrite_nc env nc2) + | NC_or (nc1, nc2) -> E_app_infix (rewrite_nc env nc1, mk_id "|", rewrite_nc env nc2) | NC_false -> E_lit (mk_lit L_false) | NC_true -> E_lit (mk_lit L_true) | NC_set (kid, []) -> E_lit (mk_lit (L_false)) | NC_set (kid, int :: ints) -> let kid_eq kid int = nc_eq (nvar kid) (nconstant int) in - unaux_exp (rewrite_nc (List.fold_left (fun nc int -> nc_or nc (kid_eq kid int)) (kid_eq kid int) ints)) + unaux_exp (rewrite_nc env (List.fold_left (fun nc int -> nc_or nc (kid_eq kid int)) (kid_eq kid int) ints)) + | NC_app (f, [A_aux (A_bool nc, _)]) when string_of_id f = "not" -> + E_app (mk_id "not_bool", [rewrite_nc env nc]) + | NC_app (f, args) -> + unaux_exp (rewrite_nc env (Env.expand_constraint_synonyms env (mk_nc (NC_app (f, args))))) + | NC_var v -> + (* Would be better to translate change E_sizeof to take a kid, then rewrite to E_sizeof *) + E_id (id_of_kid v) in - let rewrite_e_aux (E_aux (e_aux, _) as exp) = + let rewrite_e_aux (E_aux (e_aux, (l, _)) as exp) = match e_aux with | E_constraint nc -> - check_exp (env_of exp) (rewrite_nc nc) bool_typ + locate (fun _ -> gen_loc l) (check_exp (env_of exp) (rewrite_nc (env_of exp) nc) (atom_bool_typ nc)) | _ -> exp in @@ -2308,23 +2329,25 @@ let rewrite_type_def_typs rw_typ rw_typquant (TD_aux (td, annot)) = match td with | TD_abbrev (id, typq, A_aux (A_typ typ, l)) -> TD_aux (TD_abbrev (id, rw_typquant typq, A_aux (A_typ (rw_typ typ), l)), annot) - | TD_record (id, nso, typq, typ_ids, flag) -> - TD_aux (TD_record (id, nso, rw_typquant typq, List.map (fun (typ, id) -> (rw_typ typ, id)) typ_ids, flag), annot) - | TD_variant (id, nso, typq, tus, flag) -> - TD_aux (TD_variant (id, nso, rw_typquant typq, List.map (rewrite_type_union_typs rw_typ) tus, flag), annot) - | TD_enum (id, nso, ids, flag) -> TD_aux (TD_enum (id, nso, ids, flag), annot) + | TD_abbrev (id, typq, typ_arg) -> + TD_aux (TD_abbrev (id, rw_typquant typq, typ_arg), annot) + | TD_record (id, typq, typ_ids, flag) -> + TD_aux (TD_record (id, rw_typquant typq, List.map (fun (typ, id) -> (rw_typ typ, id)) typ_ids, flag), annot) + | TD_variant (id, typq, tus, flag) -> + TD_aux (TD_variant (id, rw_typquant typq, List.map (rewrite_type_union_typs rw_typ) tus, flag), annot) + | TD_enum (id, ids, flag) -> TD_aux (TD_enum (id, ids, flag), annot) | TD_bitfield _ -> assert false (* Processed before re-writing *) (* FIXME: other reg_dec types *) let rewrite_dec_spec_typs rw_typ (DEC_aux (ds, annot)) = match ds with - | DEC_reg (typ, id) -> DEC_aux (DEC_reg (rw_typ typ, id), annot) + | DEC_reg (reffect, weffect, typ, id) -> DEC_aux (DEC_reg (reffect, weffect, rw_typ typ, id), annot) | DEC_config (id, typ, exp) -> DEC_aux (DEC_config (id, rw_typ typ, exp), annot) | _ -> assert false (* Remove overload definitions and cast val specs from the specification because the interpreter doesn't know about them.*) -let rewrite_overload_cast (Defs defs) = +let rewrite_overload_cast env (Defs defs) = let remove_cast_vs (VS_aux (vs_aux, annot)) = match vs_aux with | VS_val_spec (typschm, id, ext, _) -> VS_aux (VS_val_spec (typschm, id, ext, false), annot) @@ -2341,7 +2364,7 @@ let rewrite_overload_cast (Defs defs) = Defs (List.filter (fun def -> not (is_overload def)) defs) -let rewrite_undefined mwords = +let rewrite_undefined mwords env = let rewrite_e_aux (E_aux (e_aux, _) as exp) = match e_aux with | E_lit (L_aux (L_undef, l)) -> @@ -2351,9 +2374,9 @@ let rewrite_undefined mwords = let rewrite_exp_undefined = { id_exp_alg with e_aux = (fun (exp, annot) -> rewrite_e_aux (E_aux (exp, annot))) } in rewrite_defs_base { rewriters_base with rewrite_exp = (fun _ -> fold_exp rewrite_exp_undefined) } -let rewrite_undefined_if_gen always_bitvector defs = +let rewrite_undefined_if_gen always_bitvector env defs = if !Initial_check.opt_undefined_gen - then rewrite_undefined (always_bitvector || !Pretty_print_lem.opt_mwords) defs + then rewrite_undefined (always_bitvector || !Pretty_print_lem.opt_mwords) env defs else defs let rec simple_typ (Typ_aux (typ_aux, l) as typ) = Typ_aux (simple_typ_aux typ_aux, l) @@ -2365,6 +2388,8 @@ and simple_typ_aux = function Typ_id (mk_id "int") | Typ_app (id, [_; _]) when Id.compare id (mk_id "range") = 0 -> Typ_id (mk_id "int") + | Typ_app (id, [_]) when Id.compare id (mk_id "atom_bool") = 0 -> + Typ_id (mk_id "bool") | Typ_app (id, args) -> Typ_app (id, List.concat (List.map simple_typ_arg args)) | Typ_fn (arg_typs, ret_typ, effs) -> Typ_fn (List.map simple_typ arg_typs, simple_typ ret_typ, effs) | Typ_tup typs -> Typ_tup (List.map simple_typ typs) @@ -2376,7 +2401,7 @@ and simple_typ_arg (A_aux (typ_arg_aux, l)) = | _ -> [] (* This pass aims to remove all the Num quantifiers from the specification. *) -let rewrite_simple_types (Defs defs) = +let rewrite_simple_types env (Defs defs) = let is_simple = function | QI_aux (QI_id kopt, annot) as qi when is_typ_kopt kopt || is_order_kopt kopt -> true | _ -> false @@ -2426,7 +2451,7 @@ let rewrite_simple_types (Defs defs) = let defs = Defs (List.map simple_def defs) in rewrite_defs_base simple_defs defs -let rewrite_vector_concat_assignments defs = +let rewrite_vector_concat_assignments env defs = let assign_tuple e_aux annot = let env = env_of_annot annot in match e_aux with @@ -2472,7 +2497,7 @@ let rewrite_vector_concat_assignments defs = mk_exp (E_assign (lexp, tup)))) in begin try check_exp env e_aux unit_typ with - | Type_error (l, err) -> + | Type_error (_, l, err) -> raise (Reporting.err_typ l (Type_error.string_of_type_error err)) end else E_aux (e_aux, annot) @@ -2485,7 +2510,7 @@ let rewrite_vector_concat_assignments defs = let assign_defs = { rewriters_base with rewrite_exp = (fun _ -> fold_exp assign_exp) } in rewrite_defs_base assign_defs defs -let rewrite_tuple_assignments defs = +let rewrite_tuple_assignments env defs = let assign_tuple e_aux annot = let env = env_of_annot annot in match e_aux with @@ -2501,7 +2526,7 @@ let rewrite_tuple_assignments defs = let let_exp = mk_exp (E_let (letbind, block)) in begin try check_exp env let_exp unit_typ with - | Type_error (l, err) -> + | Type_error (_, l, err) -> raise (Reporting.err_typ l (Type_error.string_of_type_error err)) end | _ -> E_aux (e_aux, annot) @@ -2513,7 +2538,7 @@ let rewrite_tuple_assignments defs = let assign_defs = { rewriters_base with rewrite_exp = (fun _ -> fold_exp assign_exp) } in rewrite_defs_base assign_defs defs -let rewrite_simple_assignments defs = +let rewrite_simple_assignments env defs = let assign_e_aux e_aux annot = let env = env_of_annot annot in match e_aux with @@ -2530,7 +2555,7 @@ let rewrite_simple_assignments defs = let assign_defs = { rewriters_base with rewrite_exp = (fun _ -> fold_exp assign_exp) } in rewrite_defs_base assign_defs defs -let rewrite_defs_remove_blocks = +let rewrite_defs_remove_blocks env = let letbind_wild v body = let l = get_loc_exp v in let env = env_of v in @@ -2586,7 +2611,7 @@ let rec mapCont (f : 'b -> ('b -> 'a exp) -> 'a exp) (l : 'b list) (k : 'b list | [] -> k [] | exp :: exps -> f exp (fun exp -> mapCont f exps (fun exps -> k (exp :: exps))) -let rewrite_defs_letbind_effects = +let rewrite_defs_letbind_effects env = let rec value ((E_aux (exp_aux,_)) as exp) = not (effectful exp || updates_vars exp) @@ -2813,7 +2838,7 @@ let rewrite_defs_letbind_effects = rewrap (E_var (lexp,exp1,n_exp exp2 k)))) | E_internal_return exp1 -> n_exp_name exp1 (fun exp1 -> - k (rewrap (E_internal_return exp1))) + k (if effectful (propagate_exp_effect exp1) then exp1 else rewrap (E_internal_return exp1))) | E_internal_value v -> k (rewrap (E_internal_value v)) | E_return exp' -> @@ -2863,7 +2888,7 @@ let rewrite_defs_letbind_effects = ; rewrite_defs = rewrite_defs_base } -let rewrite_defs_internal_lets = +let rewrite_defs_internal_lets env = let rec pat_of_local_lexp (LEXP_aux (lexp, ((l, _) as annot))) = match lexp with | LEXP_id id -> P_aux (P_id id, annot) @@ -2879,7 +2904,13 @@ let rewrite_defs_internal_lets = (* Rewrite assignments to local variables into let bindings *) let (lhs, rhs) = rewrite_lexp_to_rhs le in let (LEXP_aux (_, lannot)) = lhs in - let ltyp = typ_of_annot lannot in + let ltyp = typ_of_annot + (* The type in the lannot might come from exp rather than being the + type of the storage, so ask the type checker what it really is. *) + (match infer_lexp (env_of_annot lannot) (strip_lexp lhs) with + | LEXP_aux (_,lexp_annot') -> lexp_annot' + | exception _ -> lannot) + in let rhs = add_e_cast ltyp (rhs exp) in E_let (LB_aux (LB_val (pat_of_local_lexp lhs, rhs), annot), body) | LB_aux (LB_val (pat,exp'),annot') -> @@ -3014,10 +3045,16 @@ let rec binding_typs_of_pat (P_aux (p_aux, p_annot) as pat) = let construct_toplevel_string_append_call env f_id bindings binding_typs guard expr = (* s# if match f#(s#) { Some (bindings) => guard, _ => false) } => let Some(bindings) = f#(s#) in expr *) let s_id = fresh_stringappend_id () in + let hack_typ (Typ_aux (aux, _) as typ) = + match aux with + | Typ_app (Id_aux (Id "atom_bool", _), [_]) -> bool_typ + | Typ_app (Id_aux (Id "atom", _), [_]) -> int_typ + | _ -> typ + in let option_typ = app_typ (mk_id "option") [A_aux (A_typ (match binding_typs with | [] -> unit_typ - | [typ] -> typ - | typs -> tuple_typ typs + | [typ] -> hack_typ typ + | typs -> tuple_typ (List.map hack_typ typs) ), unk)] in let bindings = if bindings = [] then @@ -3046,11 +3083,22 @@ let construct_toplevel_string_append_func env f_id pat = else bindings in + (* AA: Pulling the types out of a pattern with binding_typs_of_pat + is broken here because they might contain type variables that + were bound locally to the pattern, so we can't lift them out to + the top-level. As a hacky fix we can generalise types where this + is likely to happen. *) + let hack_typ (Typ_aux (aux, _) as typ) = + match aux with + | Typ_app (Id_aux (Id "atom_bool", _), [_]) -> bool_typ + | Typ_app (Id_aux (Id "atom", _), [_]) -> int_typ + | _ -> typ + in let option_typ = app_typ (mk_id "option") [A_aux (A_typ (match binding_typs with | [] -> unit_typ - | [typ] -> typ - | typs -> tuple_typ typs - ), unk)] + | [typ] -> hack_typ typ + | typs -> tuple_typ (List.map hack_typ typs) + ), unk)] in let fun_typ = (mk_typ (Typ_fn ([string_typ], option_typ, no_effect))) in let new_val_spec = VS_aux (VS_val_spec (mk_typschm (TypQ_aux (TypQ_no_forall, unk)) fun_typ, f_id, [], false), unkt) in @@ -3107,7 +3155,7 @@ let construct_toplevel_string_append_func env f_id pat = let mapping_inner_typ = match Env.get_val_spec (mk_id mapping_prefix_func) env with | (_, Typ_aux (Typ_fn (_, Typ_aux (Typ_app (_, [A_aux (A_typ typ, _)]), _), _), _)) -> typ - | _ -> typ_error Parse_ast.Unknown "mapping prefix func without correct function type?" + | _ -> raise (Reporting.err_unreachable Parse_ast.Unknown __POS__ "mapping prefix func without correct function type?") in let s_id = fresh_stringappend_id () in @@ -3133,7 +3181,7 @@ let construct_toplevel_string_append_func env f_id pat = let some_pat = annot_pat (P_app (mk_id "Some", [tup_arg_pat; annot_pat (P_id len_id) unk env nat_typ])) - unk env opt_typ in + unk env opt_typ in let some_pat, some_pat_env, _ = bind_pat env (strip_pat some_pat) opt_typ in (* need to add the Some(...) env to tup_arg_pats for pat_to_exp below as it calls the typechecker *) @@ -3166,7 +3214,7 @@ let construct_toplevel_string_append_func env f_id pat = let new_fun_def, env = Type_check.check_fundef env new_fun_def in List.flatten [new_val_spec; new_fun_def] -let rewrite_defs_toplevel_string_append (Defs defs) = +let rewrite_defs_toplevel_string_append env (Defs defs) = let new_defs = ref ([] : tannot def list) in let rec rewrite_pexp (Pat_aux (pexp_aux, pexp_annot) as pexp) = (* merge cases of Pat_exp and Pat_when *) @@ -3203,7 +3251,7 @@ let rewrite_defs_toplevel_string_append (Defs defs) = Defs (List.map rewrite defs |> List.flatten) -let rec rewrite_defs_pat_string_append = +let rec rewrite_defs_pat_string_append env = let rec rewrite_pat env ((pat : tannot pat), (guards : tannot exp list), (expr : tannot exp)) = let guards_ref = ref guards in let expr_ref = ref expr in @@ -3283,7 +3331,7 @@ let rec rewrite_defs_pat_string_append = let mapping_inner_typ = match Env.get_val_spec (mk_id mapping_prefix_func) env with | (_, Typ_aux (Typ_fn (_, Typ_aux (Typ_app (_, [A_aux (A_typ typ, _)]), _), _), _)) -> typ - | _ -> typ_error Parse_ast.Unknown "mapping prefix func without correct function type?" + | _ -> typ_error env Parse_ast.Unknown "mapping prefix func without correct function type?" in let s_id = fresh_stringappend_id () in @@ -3453,7 +3501,7 @@ let fresh_mappingpatterns_id () = mappingpatterns_counter := !mappingpatterns_counter + 1; id -let rewrite_defs_mapping_patterns = +let rewrite_defs_mapping_patterns env = let rec rewrite_pat env (pat, guards, expr) = let guards_ref = ref guards in let expr_ref = ref expr in @@ -3518,7 +3566,7 @@ let rewrite_defs_mapping_patterns = let false_exp = annot_exp (E_lit (L_aux (L_false, unk))) unk env bool_typ in let new_other_guards = annot_exp (E_if (new_guard, - (annot_exp (E_let (new_letbind, fold_typed_guards env guards)) unk env bool_typ), + (annot_exp (E_let (new_letbind, annot_exp (E_cast (bool_typ, fold_typed_guards env guards)) unk env bool_typ)) unk env bool_typ), false_exp)) unk env bool_typ in annot_pat (P_typ (mapping_in_typ, annot_pat (P_id s_id) unk env mapping_in_typ)) unk env mapping_in_typ, [new_guard; new_other_guards], new_let @@ -3606,7 +3654,7 @@ let rewrite_lit_ocaml (L_aux (lit, _)) = match lit with | L_num _ | L_string _ | L_hex _ | L_bin _ | L_real _ | L_unit -> false | _ -> true -let rewrite_defs_pat_lits rewrite_lit = +let rewrite_defs_pat_lits rewrite_lit env = let rewrite_pexp (Pat_aux (pexp_aux, annot) as pexp) = let guards = ref [] in let counter = ref 0 in @@ -3732,24 +3780,22 @@ let rec rewrite_var_updates ((E_aux (expaux,((l,_) as annot))) as exp) = |> mk_var_exps_pats pl env in let exp4 = rewrite_var_updates (add_vars overwrite exp4 vars) in - let ord_exp, kids, constr, lower, upper, lower_exp, upper_exp = - match destruct_numeric (Env.expand_synonyms env (typ_of exp1)), destruct_numeric (Env.expand_synonyms env (typ_of exp2)) with - | None, _ | _, None -> - raise (Reporting.err_unreachable el __POS__ "Could not determine loop bounds") - | Some (kids1, constr1, n1), Some (kids2, constr2, n2) -> - let kids = kids1 @ kids2 in - let constr = nc_and constr1 constr2 in - let ord_exp, lower, upper, lower_exp, upper_exp = - if is_order_inc order - then (annot_exp (E_lit (mk_lit L_true)) el env bool_typ, n1, n2, exp1, exp2) - else (annot_exp (E_lit (mk_lit L_false)) el env bool_typ, n2, n1, exp2, exp1) - in - ord_exp, kids, constr, lower, upper, lower_exp, upper_exp - in (* Bind the loop variable in the body, annotated with constraints *) let lvar_kid = mk_kid ("loop_" ^ string_of_id id) in - let lvar_nc = nc_and constr (nc_and (nc_lteq lower (nvar lvar_kid)) (nc_lteq (nvar lvar_kid) upper)) in - let lvar_typ = mk_typ (Typ_exist (List.map (mk_kopt K_int) (lvar_kid :: kids), lvar_nc, atom_typ (nvar lvar_kid))) in + let lower_id = mk_id ("loop_" ^ string_of_id id ^ "_lower") in + let upper_id = mk_id ("loop_" ^ string_of_id id ^ "_upper") in + let lower_kid = mk_kid ("loop_" ^ string_of_id id ^ "_lower") in + let upper_kid = mk_kid ("loop_" ^ string_of_id id ^ "_upper") in + let lower_id_exp = annot_exp (E_id lower_id) el env (atom_typ (nvar lower_kid)) in + let upper_id_exp = annot_exp (E_id upper_id) el env (atom_typ (nvar upper_kid)) in + let annot_bool_lit lit = annot_exp (E_lit lit) el env bool_typ in + let ord_exp, lower_exp, upper_exp, exp1, exp2 = + if is_order_inc order + then annot_bool_lit (mk_lit L_true), exp1, exp2, lower_id_exp, upper_id_exp + else annot_bool_lit (mk_lit L_false), exp2, exp1, upper_id_exp, lower_id_exp + in + let lvar_nc = nc_and (nc_lteq (nvar lower_kid) (nvar lvar_kid)) (nc_lteq (nvar lvar_kid) (nvar upper_kid)) in + let lvar_typ = mk_typ (Typ_exist (List.map (mk_kopt K_int) [lvar_kid], lvar_nc, atom_typ (nvar lvar_kid))) in let lvar_pat = unaux_pat (add_p_typ lvar_typ (annot_pat (P_var ( annot_pat (P_id id) el env (atom_typ (nvar lvar_kid)), TP_aux (TP_var lvar_kid, gen_loc el))) el env lvar_typ)) in @@ -3765,23 +3811,21 @@ let rec rewrite_var_updates ((E_aux (expaux,((l,_) as annot))) as exp) = that would force the loop to be effectful, so we use an if-expression instead. This code assumes that the loop bounds have (possibly existential) atom types, and the loop body has type unit. *) - let lower_kid = mk_kid ("loop_" ^ string_of_id id ^ "_lower") in - let lower_pat = P_var (annot_pat P_wild el env (typ_of lower_exp), mk_typ_pat (TP_app (mk_id "atom", [mk_typ_pat (TP_var lower_kid)]))) in + let lower_pat = P_var (annot_pat (P_id lower_id) el env (typ_of lower_exp), mk_typ_pat (TP_app (mk_id "atom", [mk_typ_pat (TP_var lower_kid)]))) in let lb_lower = annot_letbind (lower_pat, lower_exp) el env (typ_of lower_exp) in - let upper_kid = mk_kid ("loop_" ^ string_of_id id ^ "_upper") in - let upper_pat = P_var (annot_pat P_wild el env (typ_of upper_exp), mk_typ_pat (TP_app (mk_id "atom", [mk_typ_pat (TP_var upper_kid)]))) in + let upper_pat = P_var (annot_pat (P_id upper_id) el env (typ_of upper_exp), mk_typ_pat (TP_app (mk_id "atom", [mk_typ_pat (TP_var upper_kid)]))) in let lb_upper = annot_letbind (upper_pat, upper_exp) el env (typ_of upper_exp) in let guard = annot_exp (E_constraint (nc_lteq (nvar lower_kid) (nvar upper_kid))) el env bool_typ in let unit_exp = annot_exp (E_lit (mk_lit L_unit)) el env unit_typ in let skip_val = tuple_exp (if overwrite then vars else unit_exp :: vars) in - let guarded_body = + let guarded_body = fix_eff_exp (annot_exp (E_if (guard, body, skip_val)) el env (typ_of exp4)) in + let v = fix_eff_exp (annot_exp (E_let (lb_lower, fix_eff_exp (annot_exp (E_let (lb_upper, - fix_eff_exp (annot_exp (E_if (guard, body, skip_val)) + fix_eff_exp (annot_exp (E_app (mk_id "foreach", [exp1; exp2; exp3; ord_exp; tuple_exp vars; guarded_body])) el env (typ_of exp4)))) el env (typ_of exp4)))) el env (typ_of exp4)) in - let v = fix_eff_exp (annot_exp (E_app (mk_id "foreach", [exp1; exp2; exp3; ord_exp; tuple_exp vars; guarded_body])) el env (typ_of body)) in Added_vars (v, tuple_pat (if overwrite then varpats else pat :: varpats)) | E_loop(loop,cond,body) -> (* Find variables that might be updated in the loop body and are used @@ -3851,12 +3895,10 @@ let rec rewrite_var_updates ((E_aux (expaux,((l,_) as annot))) as exp) = let v = fix_eff_exp (annot_exp expaux pl env typ) in Added_vars (v, tuple_pat (if overwrite then varpats else pat :: varpats)) | E_assign (lexp,vexp) -> - let mk_id_pat id = match Env.lookup_id id env with - | Local (_, typ) -> - add_p_typ typ (annot_pat (P_id id) pl env typ) - | _ -> - raise (Reporting.err_unreachable pl __POS__ - ("Failed to look up type of variable " ^ string_of_id id)) in + let mk_id_pat id = + let typ = lvar_typ (Env.lookup_id id env) in + add_p_typ typ (annot_pat (P_id id) pl env typ) + in if effectful exp then Same_vars (E_aux (E_assign (lexp,vexp),annot)) else @@ -3949,7 +3991,7 @@ let remove_reference_types exp = -let rewrite_defs_remove_superfluous_letbinds = +let rewrite_defs_remove_superfluous_letbinds env = let e_aux (exp,annot) = match exp with | E_let (LB_aux (LB_val (pat, exp1), _), exp2) -> @@ -3969,6 +4011,17 @@ let rewrite_defs_remove_superfluous_letbinds = E_aux (E_internal_return (exp1),e1annot) | _ -> E_aux (exp,annot) end + | E_internal_plet (_, E_aux (E_throw e, a), _) -> E_aux (E_throw e, a) + | E_internal_plet (pat, (E_aux (E_assert (c, msg), a) as assert_exp), _) -> + begin match typ_of c with + | Typ_aux (Typ_app (Id_aux (Id "atom_bool", _), [A_aux (A_bool nc, _)]), _) + when prove __POS__ (env_of c) (nc_not nc) -> + (* Drop rest of block after an 'assert(false)' *) + let exit_exp = E_aux (E_exit (infer_exp (env_of c) (mk_lit_exp L_unit)), a) in + E_aux (E_internal_plet (pat, assert_exp, exit_exp), annot) + | _ -> + E_aux (exp, annot) + end | _ -> E_aux (exp,annot) in let alg = { id_exp_alg with e_aux = e_aux } in @@ -3983,7 +4036,7 @@ let rewrite_defs_remove_superfluous_letbinds = } (* FIXME: We shouldn't allow nested not-patterns *) -let rewrite_defs_not_pats = +let rewrite_defs_not_pats env = let rewrite_pexp (pexp_aux, annot) = let rewrite_pexp' pat exp orig_guard = let guards = ref [] in @@ -4032,7 +4085,7 @@ let rewrite_defs_not_pats = let rw_exp = { id_exp_alg with pat_aux = rewrite_pexp } in rewrite_defs_base { rewriters_base with rewrite_exp = (fun _ -> fold_exp rw_exp) } -let rewrite_defs_remove_superfluous_returns = +let rewrite_defs_remove_superfluous_returns env = let add_opt_cast typopt1 typopt2 annot exp = match typopt1, typopt2 with @@ -4085,7 +4138,7 @@ let rewrite_defs_remove_superfluous_returns = } -let rewrite_defs_remove_e_assign (Defs defs) = +let rewrite_defs_remove_e_assign env (Defs defs) = let (Defs loop_specs) = fst (Type_error.check Env.empty (Defs (List.map gen_vs [("foreach", "forall ('vars : Type). (int, int, int, bool, 'vars, 'vars) -> 'vars"); ("while", "forall ('vars : Type). (bool, 'vars, 'vars) -> 'vars"); @@ -4102,7 +4155,7 @@ let rewrite_defs_remove_e_assign (Defs defs) = ; rewrite_defs = rewrite_defs_base } (Defs (loop_specs @ defs)) -let merge_funcls (Defs defs) = +let merge_funcls env (Defs defs) = let merge_function (FD_aux (FD_function (r,t,e,fcls),ann) as f) = match fcls with | [] | [_] -> f @@ -4176,7 +4229,7 @@ and fpats_of_mfpats mfpats = in List.map fpat_of_mfpat mfpats -let rewrite_defs_realise_mappings (Defs defs) = +let rewrite_defs_realise_mappings _ (Defs defs) = let realise_mpexps forwards mpexp1 mpexp2 = let mpexp_pat, mpexp_exp = if forwards then mpexp1, mpexp2 @@ -4285,12 +4338,12 @@ let rewrite_defs_realise_mappings (Defs defs) = (* We need to make sure we get the environment for the last mapping clause *) let env = match List.rev mapcls with | MCL_aux (_, mapcl_annot) :: _ -> env_of_annot mapcl_annot - | _ -> Type_check.typ_error l "mapping with no clauses?" + | _ -> raise (Reporting.err_unreachable l __POS__ "mapping with no clauses?") in let (typq, bidir_typ) = Env.get_val_spec id env in let (typ1, typ2, l) = match bidir_typ with | Typ_aux (Typ_bidir (typ1, typ2), l) -> typ1, typ2, l - | _ -> Type_check.typ_error l "non-bidir type of mapping?" + | _ -> raise (Reporting.err_unreachable l __POS__ "non-bidir type of mapping?") in let forwards_typ = Typ_aux (Typ_fn ([typ1], typ2, no_effect), l) in let forwards_matches_typ = Typ_aux (Typ_fn ([typ1], bool_typ, no_effect), l) in @@ -4618,7 +4671,7 @@ let check_cases process is_wild loc_of cases = let rec aux rps acc = function | [] -> acc, rps | [p] when is_wild p && match rps with [] -> true | _ -> false -> - let () = Reporting.print_err false false + let () = Reporting.print_err (loc_of p) "Match checking" "Redundant wildcard clause" in acc, [] | h::t -> aux (process rps h) (h::acc) t @@ -4658,7 +4711,7 @@ let rewrite_case (e,ann) = let _ = if !opt_coq_warn_nonexhaustive - then Reporting.print_err false false + then Reporting.print_err (fst ann) "Non-exhaustive matching" ("Example: " ^ string_of_rp example) in let l = Parse_ast.Generated Parse_ast.Unknown in @@ -4678,7 +4731,7 @@ let rewrite_case (e,ann) = | (example::_) -> let _ = if !opt_coq_warn_nonexhaustive - then Reporting.print_err false false + then Reporting.print_err (fst ann) "Non-exhaustive let" ("Example: " ^ string_of_rp example) in let l = Parse_ast.Generated Parse_ast.Unknown in let p = P_aux (P_wild, (l, empty_tannot)) in @@ -4708,7 +4761,7 @@ let rewrite_fun rewriters (FD_aux (FD_function (r,t,e,fcls),f_ann)) = | (example::_) -> let _ = if !opt_coq_warn_nonexhaustive - then Reporting.print_err false false + then Reporting.print_err (fst f_ann) "Non-exhaustive matching" ("Example: " ^ string_of_rp example) in let l = Parse_ast.Generated Parse_ast.Unknown in @@ -4719,9 +4772,8 @@ let rewrite_fun rewriters (FD_aux (FD_function (r,t,e,fcls),f_ann)) = let default = FCL_aux (FCL_Funcl (id,Pat_aux (Pat_exp (p,b),(l,empty_tannot))),fcl_ann) in FD_aux (FD_function (r,t,e,fcls'@[default]),f_ann) - -let rewrite = +let rewrite env = let alg = { id_exp_alg with e_aux = rewrite_case } in rewrite_defs_base { rewrite_exp = (fun _ -> fold_exp alg) @@ -4740,7 +4792,7 @@ end new functions that appear to be recursive but are not. This checks to see if the flag can be turned off. Doesn't handle mutual recursion for now. *) -let minimise_recursive_functions (Defs defs) = +let minimise_recursive_functions env (Defs defs) = let funcl_is_rec (FCL_aux (FCL_Funcl (id,pexp),_)) = fold_pexp { (pure_exp_alg false (||)) with @@ -4763,7 +4815,7 @@ let minimise_recursive_functions (Defs defs) = | d -> d in Defs (List.map rewrite_def defs) -let move_termination_measures (Defs defs) = +let move_termination_measures env (Defs defs) = let scan_for id defs = let rec aux = function | [] -> None @@ -4794,7 +4846,7 @@ let move_termination_measures (Defs defs) = (* Make recursive functions with a measure use the measure as an explicit recursion limit, enforced by an assertion. *) -let rewrite_explicit_measure (Defs defs) = +let rewrite_explicit_measure env (Defs defs) = let scan_function measures = function | FD_aux (FD_function (Rec_aux (Rec_measure (mpat,mexp),rl),topt,effopt, FCL_aux (FCL_Funcl (id,_),_)::_),ann) -> @@ -4931,14 +4983,15 @@ let rewrite_explicit_measure (Defs defs) = in Defs (List.flatten (List.map rewrite_def defs)) -let recheck_defs defs = fst (Type_error.check initial_env defs) -let recheck_defs_without_effects defs = +let recheck_defs env defs = fst (Type_error.check initial_env defs) +let recheck_defs_without_effects env defs = + let old = !opt_no_effects in let () = opt_no_effects := true in let result,_ = Type_error.check initial_env defs in - let () = opt_no_effects := false in + let () = opt_no_effects := old in result -let remove_mapping_valspecs (Defs defs) = +let remove_mapping_valspecs env (Defs defs) = let allowed_def def = match def with | DEF_spec (VS_aux (VS_val_spec (TypSchm_aux (TypSchm_ts (_, Typ_aux (Typ_bidir _, _)), _), _, _, _), _)) -> false @@ -4950,12 +5003,12 @@ let remove_mapping_valspecs (Defs defs) = let opt_mono_rewrites = ref false let opt_mono_complex_nexps = ref true -let mono_rewrites defs = +let mono_rewrites env defs = if !opt_mono_rewrites then Monomorphise.mono_rewrites defs else defs -let rewrite_toplevel_nexps defs = +let rewrite_toplevel_nexps env defs = if !opt_mono_complex_nexps then Monomorphise.rewrite_toplevel_nexps defs else defs @@ -4966,7 +5019,7 @@ let opt_auto_mono = ref false let opt_dall_split_errors = ref false let opt_dmono_continue = ref false -let monomorphise defs = +let monomorphise env defs = let open Monomorphise in monomorphise { auto = !opt_auto_mono; @@ -4976,14 +5029,14 @@ let monomorphise defs = !opt_mono_split defs -let if_mono f defs = +let if_mono f env defs = match !opt_mono_split, !opt_auto_mono with | [], false -> defs - | _, _ -> f defs + | _, _ -> f env defs (* Also turn mwords stages on when we're just trying out mono *) -let if_mwords f defs = - if !Pretty_print_lem.opt_mwords then f defs else if_mono f defs +let if_mwords f env defs = + if !Pretty_print_lem.opt_mwords then f env defs else if_mono f env defs let rewrite_defs_lem = [ ("realise_mappings", rewrite_defs_realise_mappings); @@ -4996,8 +5049,8 @@ let rewrite_defs_lem = [ ("rewrite_toplevel_nexps", if_mono rewrite_toplevel_nexps); ("monomorphise", if_mono monomorphise); ("recheck_defs", if_mwords recheck_defs); - ("add_bitvector_casts", if_mwords Monomorphise.add_bitvector_casts); - ("rewrite_atoms_to_singletons", if_mono Monomorphise.rewrite_atoms_to_singletons); + ("add_bitvector_casts", if_mwords (fun _ -> Monomorphise.add_bitvector_casts)); + ("rewrite_atoms_to_singletons", if_mono (fun _ -> Monomorphise.rewrite_atoms_to_singletons)); ("recheck_defs", if_mwords recheck_defs); ("rewrite_undefined", rewrite_undefined_if_gen false); ("rewrite_defs_vector_string_pats_to_bit_list", rewrite_defs_vector_string_pats_to_bit_list); @@ -5019,9 +5072,9 @@ let rewrite_defs_lem = [ ("exp_lift_assign", rewrite_defs_exp_lift_assign); (* ("constraint", rewrite_constraint); *) (* ("remove_assert", rewrite_defs_remove_assert); *) - ("top_sort_defs", top_sort_defs); + ("top_sort_defs", fun _ -> top_sort_defs); ("trivial_sizeof", rewrite_trivial_sizeof); - ("sizeof", rewrite_sizeof); + (* ("sizeof", rewrite_sizeof); *) ("early_return", rewrite_defs_early_return); ("fix_val_specs", rewrite_fix_val_specs); (* early_return currently breaks the types *) @@ -5064,7 +5117,7 @@ let rewrite_defs_coq = [ (* ("constraint", rewrite_constraint); *) (* ("remove_assert", rewrite_defs_remove_assert); *) ("move_termination_measures", move_termination_measures); - ("top_sort_defs", top_sort_defs); + ("top_sort_defs", fun _ -> top_sort_defs); ("trivial_sizeof", rewrite_trivial_sizeof); ("sizeof", rewrite_sizeof); ("early_return", rewrite_defs_early_return); @@ -5087,7 +5140,7 @@ let rewrite_defs_coq = [ let rewrite_defs_ocaml = [ (* ("undefined", rewrite_undefined); *) - ("no_effect_check", (fun defs -> opt_no_effects := true; defs)); + ("no_effect_check", (fun _ defs -> opt_no_effects := true; defs)); ("realise_mappings", rewrite_defs_realise_mappings); ("toplevel_string_append", rewrite_defs_toplevel_string_append); ("pat_string_append", rewrite_defs_pat_string_append); @@ -5103,17 +5156,14 @@ let rewrite_defs_ocaml = [ ("remove_bitvector_pats", rewrite_defs_remove_bitvector_pats); ("remove_numeral_pats", rewrite_defs_remove_numeral_pats); ("exp_lift_assign", rewrite_defs_exp_lift_assign); - ("top_sort_defs", top_sort_defs); - ("constraint", rewrite_constraint); - ("trivial_sizeof", rewrite_trivial_sizeof); - ("sizeof", rewrite_sizeof); + ("top_sort_defs", fun _ -> top_sort_defs); ("simple_types", rewrite_simple_types); ("overload_cast", rewrite_overload_cast); (* ("separate_numbs", rewrite_defs_separate_numbs) *) ] let rewrite_defs_c = [ - ("no_effect_check", (fun defs -> opt_no_effects := true; defs)); + ("no_effect_check", (fun _ defs -> opt_no_effects := true; defs)); ("realise_mappings", rewrite_defs_realise_mappings); ("toplevel_string_append", rewrite_defs_toplevel_string_append); ("pat_string_append", rewrite_defs_pat_string_append); @@ -5127,17 +5177,13 @@ let rewrite_defs_c = [ ("simple_assignments", rewrite_simple_assignments); ("remove_vector_concat", rewrite_defs_remove_vector_concat); ("remove_bitvector_pats", rewrite_defs_remove_bitvector_pats); - ("guarded_pats", rewrite_defs_guarded_pats); ("exp_lift_assign", rewrite_defs_exp_lift_assign); - ("constraint", rewrite_constraint); - ("trivial_sizeof", rewrite_trivial_sizeof); - ("sizeof", rewrite_sizeof); ("merge_function_clauses", merge_funcls); - ("recheck_defs", Optimize.recheck) + ("recheck_defs", fun _ -> Optimize.recheck) ] let rewrite_defs_interpreter = [ - ("no_effect_check", (fun defs -> opt_no_effects := true; defs)); + ("no_effect_check", (fun _ defs -> opt_no_effects := true; defs)); ("realise_mappings", rewrite_defs_realise_mappings); ("toplevel_string_append", rewrite_defs_toplevel_string_append); ("pat_string_append", rewrite_defs_pat_string_append); @@ -5145,10 +5191,7 @@ let rewrite_defs_interpreter = [ ("rewrite_undefined", rewrite_undefined_if_gen false); ("vector_concat_assignments", rewrite_vector_concat_assignments); ("tuple_assignments", rewrite_tuple_assignments); - ("simple_assignments", rewrite_simple_assignments); - ("constraint", rewrite_constraint); - ("trivial_sizeof", rewrite_trivial_sizeof); - ("sizeof", rewrite_sizeof); + ("simple_assignments", rewrite_simple_assignments) ] let rewrite_check_annot = @@ -5164,7 +5207,7 @@ let rewrite_check_annot = else ()); exp with - Type_error (l, err) -> raise (Reporting.err_typ l (Type_error.string_of_type_error err)) + Type_error (_, l, err) -> raise (Reporting.err_typ l (Type_error.string_of_type_error err)) in let check_pat pat = prerr_endline ("CHECKING PAT: " ^ string_of_pat pat ^ " : " ^ string_of_typ (typ_of_pat pat)); @@ -5179,5 +5222,5 @@ let rewrite_check_annot = rewrite_pat = (fun _ -> check_pat) } let rewrite_defs_check = [ - ("check_annotations", rewrite_check_annot); + ("check_annotations", fun _ -> rewrite_check_annot); ] |
