Skip to content

Commit 6483fcf

Browse files
committed
Type annotated getters/setters
This commit introduces the following syntax: - `m.[:(ty) k]` for `(m.[k] :~ ty)` - `m.[:(ty) k <- v]` for `m.[k <- (v :~ ty)]` - `m.[:(ty) k] <- k` for `m.[k] <- (v :~ ty)` This helps disambiguate the selection of getters and setters using the type of the map's values.
1 parent 3a030af commit 6483fcf

File tree

5 files changed

+88
-20
lines changed

5 files changed

+88
-20
lines changed

src/ecParser.mly

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,30 @@
4545
let pfapp_symb loc s ti es =
4646
PFapp(mk_pfid_symb loc s ti, es)
4747

48-
let pfget loc ti e1 e2 =
49-
pfapp_symb loc EcCoreLib.s_get ti [e1;e2]
50-
51-
let pfset loc ti e1 e2 e3 =
52-
pfapp_symb loc EcCoreLib.s_set ti [e1;e2;e3]
48+
let pfget
49+
(lc : EcLocation.t)
50+
(ti : ptyannot option)
51+
(codom : pty option)
52+
(map : pformula)
53+
(k : pformula)
54+
=
55+
ofold
56+
(fun codom map -> PFcast (mk_loc lc map, codom))
57+
(pfapp_symb lc EcCoreLib.s_get ti [map; k])
58+
codom
59+
60+
let pfset
61+
(lc : EcLocation.t)
62+
(ti : ptyannot option)
63+
(codom : pty option)
64+
(map : pformula)
65+
(k : pformula)
66+
(v : pformula)
67+
=
68+
let v =
69+
ofold (fun codom v -> mk_loc (loc v) (PFcast (v, codom)))
70+
v codom
71+
in pfapp_symb lc EcCoreLib.s_set ti [map; k; v]
5372

5473
let pf_nil loc ti =
5574
mk_pfid_symb loc EcCoreLib.s_nil ti
@@ -1053,15 +1072,19 @@ sform_u(P):
10531072
| x=mident
10541073
{ PFmem x }
10551074

1056-
| se=sform_r(P) DLBRACKET ti=tvars_app? e=loc(plist1(form_r(P), COMMA)) RBRACKET
1075+
| se=sform_r(P) DLBRACKET
1076+
ti=tvars_app? codom=prefix(COLON, paren(loc(type_exp)))?
1077+
e=loc(plist1(form_r(P), COMMA))
1078+
RBRACKET
10571079
{ let e = List.reduce1 (fun _ -> lmap (fun x -> PFtuple x) e) (unloc e) in
1058-
pfget (EcLocation.make $startpos $endpos) ti se e }
1080+
pfget (EcLocation.make $startpos $endpos) ti codom se e }
10591081

10601082
| se=sform_r(P) DLBRACKET
1061-
ti=tvars_app? e1=loc(plist1(form_r(P), COMMA))LARROW e2=form_r(P)
1083+
ti=tvars_app? codom=prefix(COLON, paren(loc(type_exp)))?
1084+
e1=loc(plist1(form_r(P), COMMA)) LARROW e2=form_r(P)
10621085
RBRACKET
10631086
{ let e1 = List.reduce1 (fun _ -> lmap (fun x -> PFtuple x) e1) (unloc e1) in
1064-
pfset (EcLocation.make $startpos $endpos) ti se e1 e2 }
1087+
pfset (EcLocation.make $startpos $endpos) ti codom se e1 e2 }
10651088

10661089
| x=sform_r(P) s=pside_force
10671090
{ PFside (x, s) }
@@ -1296,8 +1319,11 @@ lvalue_u:
12961319
| LPAREN p=plist2(qident, COMMA) RPAREN
12971320
{ PLvTuple p }
12981321

1299-
| x=lvalue_var DLBRACKET ti=tvars_app? e=plist1(expr, COMMA) RBRACKET
1300-
{ PLvMap (x, ti, e) }
1322+
| x=lvalue_var DLBRACKET
1323+
ti=tvars_app? codom=prefix(COLON, paren(loc(type_exp)))?
1324+
e=plist1(expr, COMMA)
1325+
RBRACKET
1326+
{ PLvMap (x, ti, codom, e) }
13011327

13021328
%inline lvalue:
13031329
| x=loc(lvalue_u) { x }

src/ecParsetree.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ type glob_or_var =
148148
type plvalue_r =
149149
| PLvSymbol of pqsymbol
150150
| PLvTuple of pqsymbol list
151-
| PLvMap of pqsymbol * ptyannot option * pexpr list
151+
| PLvMap of pqsymbol * ptyannot option * pty option * pexpr list
152152

153153
and plvalue = plvalue_r located
154154

src/ecTyping.ml

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2779,14 +2779,17 @@ and translvalue ue (env : EcEnv.env) lvalue =
27792779
let ty = ttuple (List.map snd xs) in
27802780
Lval (LvTuple xs), ty
27812781

2782-
| PLvMap (x, tvi, es) ->
2782+
| PLvMap (x, tvi, codom, es) ->
27832783
let tvi = tvi |> omap (transtvi env ue) in
2784-
let codomty = UE.fresh ue in
2784+
let codom = Option.map (transty tp_relax env ue) codom in
2785+
let codom = ofdfl (fun () -> UE.fresh ue) codom in
27852786
let pv, xty = trans_pv env x in
27862787
let e, ety = List.split (List.map (transexp env `InProc ue) es) in
2788+
27872789
let e, ety = e_tuple e, ttuple ety in
2790+
27882791
let name = ([], EcCoreLib.s_set) in
2789-
let esig = [xty; ety; codomty] in
2792+
let esig = [xty; ety; codom] in
27902793
let ops = select_exp_op env `InProc None name ue tvi (esig, None) in
27912794

27922795
match ops with
@@ -2801,7 +2804,7 @@ and translvalue ue (env : EcEnv.env) lvalue =
28012804
let esig = Tuni.subst_dom uidmap esig in
28022805
let esig = toarrow esig xty in
28032806
unify_or_fail env ue lvalue.pl_loc ~expct:esig opty;
2804-
LvMap ((p, tys), pv, e, xty), codomty
2807+
LvMap ((p, tys), pv, e, xty), codom
28052808

28062809
| [_] ->
28072810
let uidmap = UE.assubst ue in
@@ -3063,7 +3066,7 @@ and trans_form_or_pattern env mode ?mv ?ps ue pf tt =
30633066

30643067
| PFcast (pf, pty) ->
30653068
let ty = transty tp_relax env ue pty in
3066-
let aout = transf env pf in
3069+
let aout = transf env ~tt:ty pf in
30673070
unify_or_fail env ue pf.pl_loc ~expct:ty aout.f_ty; aout
30683071

30693072
| PFmem _ -> tyerror f.pl_loc env MemNotAllowed
@@ -3554,8 +3557,8 @@ and trans_memtype env ue (pmemtype : pmemtype) : memtype =
35543557
List.fold_left add_decl mt pmemtype
35553558

35563559
(* -------------------------------------------------------------------- *)
3557-
and transexp env mode ue { pl_desc = Expr e; pl_loc = loc; } =
3558-
let f = trans_form_or_pattern env (`Expr mode) ue e None in
3560+
and transexp env ?tt mode ue { pl_desc = Expr e; pl_loc = loc; } =
3561+
let f = trans_form_or_pattern env (`Expr mode) ue e tt in
35593562
let m = Option.value ~default:mhr (EcEnv.Memory.get_active env) in
35603563
let e =
35613564
try

src/ecTyping.mli

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ val trans_gbinding : env -> EcUnify.unienv -> pgtybindings ->
213213

214214
(* -------------------------------------------------------------------- *)
215215
val transexp :
216-
env -> [`InProc|`InOp] -> EcUnify.unienv -> pexpr -> expr * ty
216+
env -> ?tt:ty -> [`InProc|`InOp] -> EcUnify.unienv -> pexpr -> expr * ty
217217

218218
val transexpcast :
219219
env -> [`InProc|`InOp] -> EcUnify.unienv -> ty -> pexpr -> expr

tests/annotated-getter-setter.ec

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
(* -------------------------------------------------------------------- *)
2+
require import AllCore.
3+
4+
type u32, u64.
5+
6+
type key.
7+
type map.
8+
9+
theory GS32.
10+
op "_.[_]" : map -> key -> u32.
11+
op "_.[_<-_]" : map -> key -> u32 -> map.
12+
end GS32.
13+
14+
theory GS64.
15+
op "_.[_]" : map -> key -> u64.
16+
op "_.[_<-_]" : map -> key -> u64 -> map.
17+
end GS64.
18+
19+
import GS32 GS64.
20+
21+
op myget32 (m : map) k = m.[:(u32) k].
22+
23+
op myset32 (m : map) k v = m.[:(u32) k <- v].
24+
25+
op myget64 (m : map) k = m.[:(u64) k].
26+
27+
op myset64 (m : map) k v = m.[:(u64) k <- v].
28+
29+
module M = {
30+
proc f32(m : map, k, v) = {
31+
m.[:(u32) k] <- v;
32+
return m;
33+
}
34+
35+
proc f64(m : map, k, v) = {
36+
m.[:(u64) k] <- v;
37+
return m;
38+
}
39+
}.

0 commit comments

Comments
 (0)