summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKathy Gray2014-02-12 15:46:06 +0000
committerKathy Gray2014-02-12 15:46:20 +0000
commit44e619d7e80e4f148febf21ebe5115dfdd56cf0f (patch)
treee80168656034165f6990259edfbd3f91e99597b1 /src
parent8fa86dcbf655746dd6f5df054df05f2f0e7ac741 (diff)
Checking assignment to a variable
Diffstat (limited to 'src')
-rw-r--r--src/test/pattern.sail4
-rw-r--r--src/type_check.ml28
-rw-r--r--src/type_internal.ml4
3 files changed, 27 insertions, 9 deletions
diff --git a/src/test/pattern.sail b/src/test/pattern.sail
index 9a71d0e3..8cdc7a3c 100644
--- a/src/test/pattern.sail
+++ b/src/test/pattern.sail
@@ -8,11 +8,11 @@ function nat main _ = {
(* works - x and y are set to 42 *)
n := 1;
y :=
- ignore((switch n {
+ (switch n {
case 0 -> { x := 21; x }
case 1 -> { x := 42; x }
case x -> { x := 99; x }
- }));
+ });
(* doesn't work - main returns 1 instead of 99 *)
n := 3;
diff --git a/src/type_check.ml b/src/type_check.ml
index a253126a..85cd59fb 100644
--- a/src/type_check.ml
+++ b/src/type_check.ml
@@ -771,7 +771,6 @@ let rec check_exp envs expect_t (E_aux(e,(l,annot)) : tannot exp) : (tannot exp
let (exp',t'',_,cs,ef) = check_exp envs t' exp in
let (t',c') = type_consistent l d_env unit_t expect_t in
(E_aux(E_assign(lexp',exp'),(l,(Some(([],unit_t),tag,cs,ef)))),unit_t,t_env',cs,ef)
- | _ -> (E_aux(e,(l,annot)),expect_t,t_env,[],pure_e)
and check_block orig_envs envs expect_t exps : ((tannot exp) list * tannot * tannot emap * nexp_range list * t * effect) =
let Env(d_env,t_env) = envs in
@@ -779,8 +778,8 @@ and check_block orig_envs envs expect_t exps : ((tannot exp) list * tannot * tan
| [] -> ([],None,orig_envs,[],unit_t,pure_e)
| [e] -> let (E_aux(e',(l,annot)),t,envs,sc,ef) = check_exp envs expect_t e in
([E_aux(e',(l,annot))],annot,orig_envs,sc,t,ef)
- | e::exps -> let (e',t',t_env,sc,ef') = check_exp envs unit_t e in
- let (exps',annot',orig_envs,sc',t,ef) = check_block orig_envs (Env(d_env,t_env)) expect_t exps in
+ | e::exps -> let (e',t',t_env',sc,ef') = check_exp envs unit_t e in
+ let (exps',annot',orig_envs,sc',t,ef) = check_block orig_envs (Env(d_env,Envmap.union t_env' t_env)) expect_t exps in
((e'::exps'),annot',orig_envs,sc@sc',t,ef) (* TODO: union effects *)
and check_cases envs check_t expect_t pexps : ((tannot pexp) list * typ * nexp_range list * effect) =
@@ -804,7 +803,26 @@ and check_cases envs check_t expect_t pexps : ((tannot pexp) list * typ * nexp_r
and check_lexp envs (LEXP_aux(lexp,(l,annot))) : (tannot lexp * typ * tannot emap * tag *effect) =
let (Env(d_env,t_env)) = envs in
match lexp with
- | LEXP_id id -> (LEXP_aux(lexp,(l,annot))),new_t(),t_env,Emp,pure_e
+ | LEXP_id id ->
+ let i = id_to_string id in
+ (match Envmap.apply t_env i with
+ | Some(Some((parms,t),tag,cs,_)) ->
+ let t,cs,_ = subst parms t cs pure_e in
+ let t,cs = match get_abbrev d_env t with
+ | None -> t,cs
+ | Some(t,cs,e) -> t,cs in
+ (match t.t with
+ | Tapp("register",[TA_typ u]) ->
+ let ef = {effect=Eset[BE_aux(BE_wreg,l)]} in
+ (LEXP_aux(lexp,(l,(Some(([],t),External,cs,ef)))),u,Envmap.empty,External,ef)
+ | Tapp("reg",[TA_typ u]) ->
+ (LEXP_aux(lexp,(l,(Some(([],t),Emp,cs,pure_e)))),u,Envmap.empty,Emp,pure_e)
+ | _ -> typ_error l ("Can only assign to identifiers with type register or reg, found identifier " ^ i ^ " with type " ^ t_to_string t))
+ | _ ->
+ let u = new_t() in
+ let t = {t=Tapp("reg",[TA_typ u])} in
+ let tannot = (Some(([],t),Emp,[],pure_e)) in
+ (LEXP_aux(lexp,(l,tannot)),u,Envmap.from_list [i,tannot],Emp,pure_e))
| LEXP_memory(id,exps) -> (LEXP_aux(lexp,(l,annot)),new_t(),t_env,Emp,pure_e)
| LEXP_vector(vec,acc) -> (LEXP_aux(lexp,(l,annot)),new_t(),t_env,Emp,pure_e)
| LEXP_vector_range(vec,base,range)-> (LEXP_aux(lexp,(l,annot))),new_t(),t_env,Emp,pure_e
@@ -981,7 +999,7 @@ let check_fundef envs (FD_aux(FD_function(recopt,tannotopt,effectopt,funcls),(l,
(List.map (fun (FCL_aux((FCL_Funcl(id,pat,exp)),(l,annot))) ->
let (pat',t_env',constraints',t') = check_pattern (Env(d_env,t_env)) pat in
let u,cs = type_consistent l d_env t' param_t in
- let exp',_,_,constraints,ef = check_exp (Env(d_env,Envmap.union t_env t_env')) ret_t exp in
+ let exp',_,_,constraints,ef = check_exp (Env(d_env,Envmap.union t_env' t_env)) ret_t exp in
(*let _ = (Pretty_print.pp_exp Format.std_formatter) exp' in*)
(FCL_aux((FCL_Funcl(id,pat',exp')),(l,tannot)),constraints'@cs@constraints)) funcls) in
match (in_env,tannot) with
diff --git a/src/type_internal.ml b/src/type_internal.ml
index 5b196e8b..f43b797c 100644
--- a/src/type_internal.ml
+++ b/src/type_internal.ml
@@ -442,7 +442,7 @@ let rec type_consistent l d_env t1 t2 =
| None,Some(t2,cs2,e2) ->
let t',cs' = type_consistent l d_env t1 t2 in
t',cs2@cs'
- | None,None -> eq_error l ("Type mismatch :" ^ (t_to_string t1) ^ " , " ^ (t_to_string t2)))
+ | None,None -> eq_error l ("Type mismatch found " ^ (t_to_string t1) ^ " but expected a " ^ (t_to_string t2)))
and type_arg_eq l d_env ta1 ta2 =
match ta1,ta2 with
@@ -540,7 +540,7 @@ let rec type_coerce l d_env t1 e t2 =
(l,Some(([],t2),Emp,[],pure_e)))),
(l,Some(([],t2),Emp,[],pure_e)))) enums),
(l,Some(([],t2),Emp,[],pure_e))))
- | None -> eq_error l ("Type mismatch: " ^ (t_to_string t1) ^ " , " ^ (t_to_string t2))))
+ | None -> eq_error l ("Type mismatch: found a " ^ (t_to_string t1) ^ " but expected " ^ (t_to_string t2))))
| Tid("bit"),Tid("bool") ->
let e' = E_aux(E_app((Id_aux(Id "is_one",l)),[e]),(l,Some(([],bool_t),External,[],pure_e))) in
(t2,[],e')