summaryrefslogtreecommitdiff
path: root/src/ast_util.ml
diff options
context:
space:
mode:
authorAlasdair Armstrong2019-02-12 18:18:05 +0000
committerAlasdair Armstrong2019-02-12 18:18:05 +0000
commit24fc989891ad266eae642815646294279e2485ca (patch)
treed533fc26b5980d1144ee4d7849d3dd0f2a1b0e95 /src/ast_util.ml
parentb847a472a1f853d783d1af5f8eb033b97f33be5b (diff)
parent974494b1dda38c1ee5c1502cc6e448e67a7374ac (diff)
Merge remote-tracking branch 'origin/asl_flow2' into sail2
Diffstat (limited to 'src/ast_util.ml')
-rw-r--r--src/ast_util.ml221
1 files changed, 210 insertions, 11 deletions
diff --git a/src/ast_util.ml b/src/ast_util.ml
index d45dd307..5746a242 100644
--- a/src/ast_util.ml
+++ b/src/ast_util.ml
@@ -236,6 +236,11 @@ let rec is_nexp_constant (Nexp_aux (nexp, _)) = match nexp with
| Nexp_exp n | Nexp_neg n -> is_nexp_constant n
| Nexp_app (_, nexps) -> List.for_all is_nexp_constant nexps
+let int_of_nexp_opt nexp =
+ match nexp with
+ | Nexp_aux(Nexp_constant i,_) -> Some i
+ | _ -> None
+
let rec nexp_simp (Nexp_aux (nexp, l)) = Nexp_aux (nexp_simp_aux nexp, l)
and nexp_simp_aux = function
(* (n - (n - m)) often appears in foreach loops *)
@@ -321,10 +326,23 @@ let rec constraint_simp (NC_aux (nc_aux, l)) =
| NC_aux (nc, _), NC_aux (NC_true, _) -> NC_true
| _, _ -> NC_or (nc1, nc2)
end
+
| NC_bounded_ge (nexp1, nexp2) ->
- NC_bounded_ge (nexp_simp nexp1, nexp_simp nexp2)
+ let nexp1, nexp2 = nexp_simp nexp1, nexp_simp nexp2 in
+ begin match nexp1, nexp2 with
+ | Nexp_aux (Nexp_constant c1, _), Nexp_aux (Nexp_constant c2, _) ->
+ if Big_int.greater_equal c1 c2 then NC_true else NC_false
+ | _, _ -> NC_bounded_ge (nexp1, nexp2)
+ end
+
| NC_bounded_le (nexp1, nexp2) ->
- NC_bounded_le (nexp_simp nexp1, nexp_simp nexp2)
+ let nexp1, nexp2 = nexp_simp nexp1, nexp_simp nexp2 in
+ begin match nexp1, nexp2 with
+ | Nexp_aux (Nexp_constant c1, _), Nexp_aux (Nexp_constant c2, _) ->
+ if Big_int.less_equal c1 c2 then NC_true else NC_false
+ | _, _ -> NC_bounded_le (nexp1, nexp2)
+ end
+
| _ -> nc_aux
in
NC_aux (nc_aux, l)
@@ -361,10 +379,13 @@ let app_typ id args = mk_typ (Typ_app (id, args))
let register_typ typ = mk_typ (Typ_app (mk_id "register", [mk_typ_arg (A_typ typ)]))
let atom_typ nexp =
mk_typ (Typ_app (mk_id "atom", [mk_typ_arg (A_nexp (nexp_simp nexp))]))
+let implicit_typ nexp =
+ mk_typ (Typ_app (mk_id "implicit", [mk_typ_arg (A_nexp (nexp_simp nexp))]))
let range_typ nexp1 nexp2 =
mk_typ (Typ_app (mk_id "range", [mk_typ_arg (A_nexp (nexp_simp nexp1));
mk_typ_arg (A_nexp (nexp_simp nexp2))]))
let bool_typ = mk_id_typ (mk_id "bool")
+let atom_bool_typ nc = mk_typ (Typ_app (mk_id "atom_bool", [mk_typ_arg (A_bool nc)]))
let string_typ = mk_id_typ (mk_id "string")
let list_typ typ = mk_typ (Typ_app (mk_id "list", [mk_typ_arg (A_typ typ)]))
let tuple_typ typs = mk_typ (Typ_tup typs)
@@ -609,7 +630,6 @@ let exp_loc = function
| E_aux (_, (l, _)) -> l
let def_loc = function
- | DEF_kind (KD_aux (_, (l, _)))
| DEF_type (TD_aux (_, (l, _)))
| DEF_fundef (FD_aux (_, (l, _)))
| DEF_mapdef (MD_aux (_, (l, _)))
@@ -622,6 +642,7 @@ let def_loc = function
| DEF_overload (Id_aux (_, l), _) -> l
| DEF_internal_mutrec _ -> Parse_ast.Unknown
| DEF_pragma (_, _, l) -> l
+ | DEF_measure (id, _, _) -> id_loc id
let string_of_id = function
| Id_aux (Id v, _) -> v
@@ -895,8 +916,8 @@ and string_of_letbind (LB_aux (lb, l)) =
let rec string_of_index_range (BF_aux (ir, _)) =
match ir with
- | BF_single n -> Big_int.to_string n
- | BF_range (n, m) -> Big_int.to_string n ^ " .. " ^ Big_int.to_string m
+ | BF_single n -> string_of_nexp n
+ | BF_range (n, m) -> string_of_nexp n ^ " .. " ^ string_of_nexp m
| BF_concat (ir1, ir2) -> "(" ^ string_of_index_range ir1 ^ ") : (" ^ string_of_index_range ir2 ^ ")"
@@ -934,9 +955,9 @@ let id_of_fundef (FD_aux (FD_function (_, _, _, funcls), (l, _))) =
let id_of_type_def_aux = function
| TD_abbrev (id, _, _)
- | TD_record (id, _, _, _, _)
- | TD_variant (id, _, _, _, _)
- | TD_enum (id, _, _, _)
+ | TD_record (id, _, _, _)
+ | TD_variant (id, _, _, _)
+ | TD_enum (id, _, _)
| TD_bitfield (id, _, _) -> id
let id_of_type_def (TD_aux (td_aux, _)) = id_of_type_def_aux td_aux
@@ -944,17 +965,16 @@ let id_of_val_spec (VS_aux (VS_val_spec (_, id, _, _), _)) = id
let id_of_dec_spec (DEC_aux (ds_aux, _)) =
match ds_aux with
- | DEC_reg (_, id) -> id
+ | DEC_reg (_, _, _, id) -> id
| DEC_config (id, _, _) -> id
| DEC_alias (id, _) -> id
| DEC_typ_alias (_, id, _) -> id
let ids_of_def = function
- | DEF_kind (KD_aux (KD_nabbrev (_, id, _, _), _)) -> IdSet.singleton id
| DEF_type td -> IdSet.singleton (id_of_type_def td)
| DEF_fundef fd -> IdSet.singleton (id_of_fundef fd)
| DEF_val (LB_aux (LB_val (pat, _), _)) -> pat_ids pat
- | DEF_reg_dec (DEC_aux (DEC_reg (_, id), _)) -> IdSet.singleton id
+ | DEF_reg_dec (DEC_aux (DEC_reg (_, _, _, id), _)) -> IdSet.singleton id
| DEF_spec vs -> IdSet.singleton (id_of_val_spec vs)
| DEF_internal_mutrec fds -> IdSet.of_list (List.map id_of_fundef fds)
| _ -> IdSet.empty
@@ -1183,6 +1203,72 @@ let equal_effects e1 e2 =
| Effect_aux (Effect_set base_effs1, _), Effect_aux (Effect_set base_effs2, _) ->
BESet.compare (BESet.of_list base_effs1) (BESet.of_list base_effs2) = 0
+let subseteq_effects e1 e2 =
+ match e1, e2 with
+ | Effect_aux (Effect_set base_effs1, _), Effect_aux (Effect_set base_effs2, _) ->
+ BESet.subset (BESet.of_list base_effs1) (BESet.of_list base_effs2)
+
+let rec kopts_of_nexp (Nexp_aux (nexp,_)) =
+ match nexp with
+ | Nexp_id _
+ | Nexp_constant _ -> KOptSet.empty
+ | Nexp_var kid -> KOptSet.singleton (mk_kopt K_int kid)
+ | Nexp_times (n1,n2)
+ | Nexp_sum (n1,n2)
+ | Nexp_minus (n1,n2) -> KOptSet.union (kopts_of_nexp n1) (kopts_of_nexp n2)
+ | Nexp_exp n
+ | Nexp_neg n -> kopts_of_nexp n
+ | Nexp_app (_, nexps) -> List.fold_left KOptSet.union KOptSet.empty (List.map kopts_of_nexp nexps)
+
+let kopts_of_order (Ord_aux (ord, _)) =
+ match ord with
+ | Ord_var kid -> KOptSet.singleton (mk_kopt K_order kid)
+ | Ord_inc | Ord_dec -> KOptSet.empty
+
+let rec kopts_of_constraint (NC_aux (nc, _)) =
+ match nc with
+ | NC_equal (nexp1, nexp2)
+ | NC_bounded_ge (nexp1, nexp2)
+ | NC_bounded_le (nexp1, nexp2)
+ | NC_not_equal (nexp1, nexp2) ->
+ KOptSet.union (kopts_of_nexp nexp1) (kopts_of_nexp nexp2)
+ | NC_set (kid, _) -> KOptSet.singleton (mk_kopt K_int kid)
+ | NC_or (nc1, nc2)
+ | NC_and (nc1, nc2) ->
+ KOptSet.union (kopts_of_constraint nc1) (kopts_of_constraint nc2)
+ | NC_app (id, args) ->
+ List.fold_left (fun s t -> KOptSet.union s (kopts_of_typ_arg t)) KOptSet.empty args
+ | NC_var kid -> KOptSet.singleton (mk_kopt K_bool kid)
+ | NC_true | NC_false -> KOptSet.empty
+
+and kopts_of_typ (Typ_aux (t,_)) =
+ match t with
+ | Typ_internal_unknown -> KOptSet.empty
+ | Typ_id _ -> KOptSet.empty
+ | Typ_var kid -> KOptSet.singleton (mk_kopt K_type kid)
+ | Typ_fn (ts, t, _) -> List.fold_left KOptSet.union (kopts_of_typ t) (List.map kopts_of_typ ts)
+ | Typ_bidir (t1, t2) -> KOptSet.union (kopts_of_typ t1) (kopts_of_typ t2)
+ | Typ_tup ts ->
+ List.fold_left (fun s t -> KOptSet.union s (kopts_of_typ t))
+ KOptSet.empty ts
+ | Typ_app (_,tas) ->
+ List.fold_left (fun s ta -> KOptSet.union s (kopts_of_typ_arg ta))
+ KOptSet.empty tas
+ | Typ_exist (kopts, nc, t) ->
+ let s = KOptSet.union (kopts_of_typ t) (kopts_of_constraint nc) in
+ KOptSet.diff s (KOptSet.of_list kopts)
+and kopts_of_typ_arg (A_aux (ta,_)) =
+ match ta with
+ | A_nexp nexp -> kopts_of_nexp nexp
+ | A_typ typ -> kopts_of_typ typ
+ | A_order ord -> kopts_of_order ord
+ | A_bool nc -> kopts_of_constraint nc
+
+let kopts_of_quant_item (QI_aux (qi, _)) = match qi with
+ | QI_id kopt ->
+ KOptSet.singleton kopt
+ | QI_const nc -> kopts_of_constraint nc
+
let rec tyvars_of_nexp (Nexp_aux (nexp,_)) =
match nexp with
| Nexp_id _
@@ -1729,3 +1815,116 @@ let typquant_subst_kid_aux sv subst = function
| TypQ_no_forall -> TypQ_no_forall
let typquant_subst_kid sv subst (TypQ_aux (typq, l)) = TypQ_aux (typquant_subst_kid_aux sv subst typq, l)
+
+let rec simp_loc = function
+ | Parse_ast.Unknown -> None
+ | Parse_ast.Unique (_, l) -> simp_loc l
+ | Parse_ast.Generated l -> simp_loc l
+ | Parse_ast.Range (p1, p2) -> Some (p1, p2)
+ | Parse_ast.Documented (_, l) -> simp_loc l
+
+let before p1 p2 =
+ let open Lexing in
+ p1.pos_fname = p2.pos_fname && p1.pos_cnum <= p2.pos_cnum
+
+let subloc sl l =
+ match sl, simp_loc l with
+ | _, None -> false
+ | None, _ -> false
+ | Some (p1a, p1b), Some (p2a, p2b) ->
+ before p2a p1a && before p1b p2b
+
+let rec option_mapm f = function
+ | [] -> None
+ | x :: xs ->
+ begin match f x with
+ | Some y -> Some y
+ | None -> option_mapm f xs
+ end
+
+let option_chain opt1 opt2 =
+ begin match opt1 with
+ | None -> opt2
+ | _ -> opt1
+ end
+
+let rec find_annot_exp sl (E_aux (aux, (l, annot)) as exp) =
+ if not (subloc sl l) then None else
+ let result = match aux with
+ | E_block exps | E_tuple exps ->
+ option_mapm (find_annot_exp sl) exps
+ | E_app (id, exps) ->
+ option_mapm (find_annot_exp sl) exps
+ | E_let (LB_aux (LB_val (pat, exp), _), body) ->
+ option_chain (find_annot_pat sl pat) (option_mapm (find_annot_exp sl) [exp; body])
+ | E_assign (lexp, exp) ->
+ option_chain (find_annot_lexp sl lexp) (find_annot_exp sl exp)
+ | E_var (lexp, exp1, exp2) ->
+ option_chain (find_annot_lexp sl lexp) (option_mapm (find_annot_exp sl) [exp1; exp2])
+ | _ -> None
+ in
+ match result with
+ | None -> Some (l, annot)
+ | _ -> result
+
+and find_annot_lexp sl (LEXP_aux (aux, (l, annot))) =
+ if not (subloc sl l) then None else
+ let result = match aux with
+ | LEXP_vector_range (lexp, exp1, exp2) ->
+ option_chain (find_annot_lexp sl lexp) (option_mapm (find_annot_exp sl) [exp1; exp2])
+ | LEXP_deref exp ->
+ find_annot_exp sl exp
+ | LEXP_tup lexps ->
+ option_mapm (find_annot_lexp sl) lexps
+ | LEXP_memory (id, exps) ->
+ option_mapm (find_annot_exp sl) exps
+ | _ -> None
+ in
+ match result with
+ | None -> Some (l, annot)
+ | _ -> result
+
+and find_annot_pat sl (P_aux (aux, (l, annot))) =
+ if not (subloc sl l) then None else
+ let result = match aux with
+ | _ -> None
+ in
+ match result with
+ | None -> Some (l, annot)
+ | _ -> result
+
+and find_annot_pexp sl (Pat_aux (aux, (l, annot))) =
+ if not (subloc sl l) then None else
+ match aux with
+ | Pat_exp (pat, exp) ->
+ find_annot_exp sl exp
+ | Pat_when (pat, guard, exp) ->
+ None
+
+let find_annot_funcl sl (FCL_aux (FCL_Funcl (id, pexp), (l, annot))) =
+ if not (subloc sl l) then
+ None
+ else
+ match find_annot_pexp sl pexp with
+ | None -> Some (l, annot)
+ | result -> result
+
+let find_annot_fundef sl (FD_aux (FD_function (_, _, _, funcls), (l, annot))) =
+ if not (subloc sl l) then
+ None
+ else
+ match option_mapm (find_annot_funcl sl) funcls with
+ | None -> Some (l, annot)
+ | result -> result
+
+let rec find_annot_defs sl = function
+ | DEF_fundef fdef :: defs ->
+ begin match find_annot_fundef sl fdef with
+ | None -> find_annot_defs sl defs
+ | result -> result
+ end
+ | _ :: defs ->
+ find_annot_defs sl defs
+ | [] -> None
+
+let rec find_annot_ast sl (Defs defs) = find_annot_defs sl defs