summaryrefslogtreecommitdiff
path: root/src/monomorphise.ml
diff options
context:
space:
mode:
Diffstat (limited to 'src/monomorphise.ml')
-rw-r--r--src/monomorphise.ml45
1 files changed, 40 insertions, 5 deletions
diff --git a/src/monomorphise.ml b/src/monomorphise.ml
index 53200b16..584d94a7 100644
--- a/src/monomorphise.ml
+++ b/src/monomorphise.ml
@@ -575,6 +575,32 @@ let lit_match = function
| (L_one | L_true ), (L_one | L_true ) -> true
| l1,l2 -> l1 = l2
+(* There's no undefined nexp, so replace undefined sizes with a plausible size.
+ 32 is used as a sensible default. *)
+let fabricate_nexp l = function
+ | None -> Nexp_aux (Nexp_constant 32,Unknown)
+ | Some (env,typ,_) ->
+ match Type_check.destruct_exist env typ with
+ | None -> Nexp_aux (Nexp_constant 32,Unknown)
+ | Some (kids,nc,typ') ->
+ match kids,nc,Env.expand_synonyms env typ' with
+ | ([kid],NC_aux (NC_set (kid',i::_),_),
+ Typ_aux (Typ_app (Id_aux (Id "range",_),
+ [Typ_arg_aux (Typ_arg_nexp (Nexp_aux (Nexp_var kid'',_)),_);
+ Typ_arg_aux (Typ_arg_nexp (Nexp_aux (Nexp_var kid''',_)),_)]),_))
+ when Kid.compare kid kid' = 0 && Kid.compare kid kid'' = 0 &&
+ Kid.compare kid kid''' = 0 ->
+ Nexp_aux (Nexp_constant i,Unknown)
+ | ([kid],NC_aux (NC_true,_),
+ Typ_aux (Typ_app (Id_aux (Id "range",_),
+ [Typ_arg_aux (Typ_arg_nexp (Nexp_aux (Nexp_var kid'',_)),_);
+ Typ_arg_aux (Typ_arg_nexp (Nexp_aux (Nexp_var kid''',_)),_)]),_))
+ when Kid.compare kid kid'' = 0 &&
+ Kid.compare kid kid''' = 0 ->
+ Nexp_aux (Nexp_constant 32,Unknown)
+ | _ -> raise (Reporting_basic.err_general l
+ ("Undefined value at unsupported type " ^ string_of_typ typ))
+
type 'a matchresult =
| DoesMatch of 'a
| DoesNotMatch
@@ -614,12 +640,20 @@ let can_match_with_env env (E_aux (e,(l,annot)) as exp0) cases =
let checkpat = function
| P_aux (P_lit (L_aux (lit_p, _)),_) ->
if lit_match (lit_e,lit_p) then DoesMatch ([],[]) else DoesNotMatch
- | P_aux (P_var (P_aux (P_id id,_), kid),_) ->
+ | P_aux (P_var (P_aux (P_id id,p_id_annot), kid),_) ->
begin
match lit_e with
| L_num i ->
DoesMatch ([id, E_aux (e,(l,annot))],
[kid,Nexp_aux (Nexp_constant i,Unknown)])
+ (* For undefined we fix the type-level size (because there's no good
+ way to construct an undefined size), but leave the term as undefined
+ to make the meaning clear. *)
+ | L_undef ->
+ let nexp = fabricate_nexp l annot in
+ let typ = subst_src_typ (KBindings.singleton kid nexp) (typ_of_annot p_id_annot) in
+ DoesMatch ([id, E_aux (E_cast (typ,E_aux (e,(l,None))),(l,None))],
+ [kid,nexp])
| _ ->
(Reporting_basic.print_err false true lit_l "Monomorphisation"
"Unexpected kind of literal for var match"; GiveUp)
@@ -692,7 +726,7 @@ let try_app (l,ann) (Id_aux (id,_),args) =
| _ -> None
else if id = Id "ex_int" then
match args with
- | [E_aux (E_lit (L_aux (L_num _,_)),_) as exp] -> Some exp
+ | [E_aux (E_lit lit,(l,_))] -> Some (E_aux (E_lit lit,(l,ann)))
| _ -> None
else if id = Id "vector_access" || id = Id "bitvector_access" then
match args with
@@ -1540,11 +1574,12 @@ let add_var_rebind exp (var,kid) =
(* atom('n) arguments to function calls need to be rewritten *)
let replace_with_the_value (E_aux (_,(l,_)) as exp) =
- let typ = Env.expand_synonyms (env_of exp) (typ_of exp) in
- let typ, wrap = match typ with
+ let env = env_of exp in
+ let typ, wrap = match typ_of exp with
| Typ_aux (Typ_exist (kids,nc,typ),l) -> typ, fun t -> Typ_aux (Typ_exist (kids,nc,t),l)
- | _ -> typ, fun x -> x
+ | typ -> typ, fun x -> x
in
+ let typ = Env.expand_synonyms env typ in
let mk_exp nexp l l' =
E_aux (E_cast (wrap (Typ_aux (Typ_app (Id_aux (Id "itself",Generated Unknown),
[Typ_arg_aux (Typ_arg_nexp nexp,l')]),Generated Unknown)),