Skip to content

Commit ff9eee5

Browse files
allow binding both an explicit and an implicit name
With placeholder syntax
1 parent d4f702d commit ff9eee5

File tree

8 files changed

+47
-18
lines changed

8 files changed

+47
-18
lines changed

src/lowering/desugar.ml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1045,6 +1045,7 @@ and pat p = phrase pat' p
10451045

10461046
and pat' = function
10471047
| S.VarP v -> I.VarP v.it
1048+
| S.GivenP { id; _ } -> I.VarP id.it
10481049
| S.WildP -> I.WildP
10491050
| S.LitP l -> I.LitP (lit !l)
10501051
| S.SignP (o, l) -> I.LitP (lit (apply_sign o (!l)))

src/mo_def/syntax.ml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ type pat = (pat', Type.typ) Source.annotated_phrase
107107
and pat' =
108108
| WildP (* wildcard *)
109109
| VarP of id (* variable *)
110+
| GivenP of given (* implicit *)
110111
| LitP of lit ref (* literal *)
111112
| SignP of unop * lit ref (* signed literal *)
112113
| TupP of pat list (* tuple *)
@@ -120,6 +121,8 @@ and pat' =
120121
| AsP of pat * pat (* conjunctive *)
121122
*)
122123

124+
and given = { implicit : id; id : id }
125+
123126
and pat_field = pat_field' Source.phrase
124127
and pat_field' =
125128
| ValPF of id * pat

src/mo_frontend/coverage.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ let skip_pat at sets =
192192
let rec match_pat ctxt desc pat t sets =
193193
T.span t = Some 0 && skip_pat pat.at sets ||
194194
match pat.it with
195-
| WildP | VarP _ ->
195+
| WildP | VarP _ | GivenP _ ->
196196
if T.inhabited t then
197197
succeed ctxt desc sets
198198
else

src/mo_frontend/definedness.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ and exp_field msgs ef : f = exp msgs ef.it.exp
148148

149149
and pat msgs p : fd = match p.it with
150150
| WildP -> (M.empty, S.empty)
151-
| VarP i -> (M.empty, S.singleton i.it)
151+
| VarP id | GivenP { id;_ } -> (M.empty, S.singleton id.it)
152152
| TupP ps -> pats msgs ps
153153
| ObjP pfs -> pat_fields msgs pfs
154154
| AnnotP (p, _)

src/mo_frontend/parser.mly

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -905,6 +905,8 @@ pat_plain :
905905
{ WildP @! at $sloc }
906906
| x=id
907907
{ VarP(x) @! at $sloc }
908+
| x=id WITH y=id
909+
{ GivenP { id = x; implicit = y } @! at $sloc }
908910
| l=lit
909911
{ LitP(ref l) @! at $sloc }
910912
| LPAR ps=seplist(pat_bin, COMMA) RPAR

src/mo_frontend/typing.ml

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1066,7 +1066,7 @@ let is_explicit_lit l =
10661066

10671067
let rec is_explicit_pat p =
10681068
match p.it with
1069-
| WildP | VarP _ -> false
1069+
| WildP | VarP _ | GivenP _ -> false
10701070
| LitP l | SignP (_, l) -> is_explicit_lit !l
10711071
| OptP p1 | TagP (_, p1) | ParP p1 -> is_explicit_pat p1
10721072
| TupP ps -> List.for_all is_explicit_pat ps
@@ -1313,6 +1313,7 @@ and combine_pat_srcs env t pat : unit =
13131313
match pat.it with
13141314
| WildP -> ()
13151315
| VarP id -> combine_id_srcs env t id
1316+
| GivenP id -> combine_id_srcs env t id.id
13161317
| LitP _ -> ()
13171318
| SignP _ -> ()
13181319
| TupP pats ->
@@ -3186,7 +3187,7 @@ and infer_pat' name_types env pat : T.typ * Scope.val_env =
31863187
match pat.it with
31873188
| WildP ->
31883189
error env pat.at "M0102" "cannot infer type of wildcard"
3189-
| VarP _ ->
3190+
| VarP _ | GivenP _ ->
31903191
error env pat.at "M0103" "cannot infer type of variable"
31913192
| LitP lit ->
31923193
T.Prim (infer_lit env lit pat.at), T.Env.empty
@@ -3304,6 +3305,8 @@ and check_pat_aux' env t pat val_kind : Scope.val_env =
33043305
T.Env.empty
33053306
| VarP id ->
33063307
T.Env.singleton id.it (None, t, id.at, val_kind)
3308+
| GivenP { id; implicit } ->
3309+
T.Env.singleton id.it (Some implicit.it, t, id.at, val_kind)
33073310
| LitP lit ->
33083311
if not env.pre then begin
33093312
let t' = if eq env pat.at t T.nat then T.int else t in (* account for Nat <: Int *)
@@ -3584,7 +3587,7 @@ and vis_dec src dec xs : visibility_env =
35843587
and vis_pat src pat xs : visibility_env =
35853588
match pat.it with
35863589
| WildP | LitP _ | SignP _ -> xs
3587-
| VarP id -> vis_val_id src id xs
3590+
| VarP id | GivenP { id; _} -> vis_val_id src id xs
35883591
| TupP pats -> List.fold_right (vis_pat src) pats xs
35893592
| ObjP pfs -> List.fold_right (vis_pat_field src) pfs xs
35903593
| AltP (pat1, _)
@@ -4282,7 +4285,7 @@ and gather_dec env scope dec : Scope.t =
42824285
| VarP id -> Scope.adjoin scope (Scope.mixin id.it (imports, args, t, decs))
42834286
| _ -> error env pat.at "M0229" "mixins may only be imported by binding to a name"
42844287
)
4285-
| VarD (id, _) -> Scope.adjoin_val_env scope (gather_id env scope.Scope.val_env id Scope.Declaration)
4288+
| VarD (id, _) -> Scope.adjoin_val_env scope (gather_id env scope.Scope.val_env id None Scope.Declaration)
42864289
| TypD (id, binds, _) | ClassD (_, _, _, id, binds, _, _, _, _) ->
42874290
let open Scope in
42884291
if T.Env.mem id.it scope.typ_env then
@@ -4342,7 +4345,8 @@ and gather_pat env (scope : Scope.t) pat : Scope.t =
43424345
and gather_pat_aux env val_kind scope pat : Scope.t =
43434346
match pat.it with
43444347
| WildP | LitP _ | SignP _ -> scope
4345-
| VarP id -> Scope.adjoin_val_env scope (gather_id env scope.Scope.val_env id val_kind)
4348+
| VarP id -> Scope.adjoin_val_env scope (gather_id env scope.Scope.val_env id None val_kind)
4349+
| GivenP { id; implicit } -> Scope.adjoin_val_env scope (gather_id env scope.Scope.val_env id (Some implicit.it) val_kind)
43464350
| TupP pats -> List.fold_left (gather_pat env) scope pats
43474351
| ObjP pfs -> List.fold_left (gather_pat_field env) scope pfs
43484352
| TagP (_, pat1) | AltP (pat1, _) | OptP pat1
@@ -4354,11 +4358,10 @@ and gather_pat_field env scope pf : Scope.t =
43544358
| ValPF (id, pat) -> gather_pat_aux env val_kind scope pat
43554359
| TypPF id -> gather_typ_id env scope id
43564360

4357-
and gather_id env ve id val_kind : Scope.val_env =
4361+
and gather_id env ve id implicit val_kind : Scope.val_env =
43584362
if T.Env.mem id.it ve then
43594363
error_duplicate env "" id;
4360-
(* TODO *)
4361-
T.Env.add id.it (None, T.Pre, id.at, val_kind) ve
4364+
T.Env.add id.it (implicit, T.Pre, id.at, val_kind) ve
43624365

43634366
and gather_typ_id env scope id : Scope.t =
43644367
let open Scope in
@@ -4423,13 +4426,17 @@ and infer_dec_typdecs env dec : Scope.t =
44234426
(match infer_val_path env exp with
44244427
| None -> Scope.empty
44254428
| Some t ->
4426-
let open Scope in
4427-
(* TODO *)
44284429
match T.promote t with
4429-
| T.Obj (_, _) as t' -> { Scope.empty with val_env = singleton id None t' }
4430-
| _ -> { Scope.empty with val_env = singleton id None T.Pre }
4431-
)
4432-
end
4430+
| T.Obj (_, _) as t' -> Scope.{ empty with val_env = singleton id None t' }
4431+
| _ -> Scope.{ empty with val_env = singleton id None T.Pre }
4432+
) end
4433+
| LetD ({it = GivenP { id; implicit }; _}, exp, _) ->
4434+
(match infer_val_path env exp with
4435+
| None -> Scope.empty
4436+
| Some t ->
4437+
match T.promote t with
4438+
| T.Obj (_, _) as t' -> Scope.{ empty with val_env = singleton id (Some implicit.it) t' }
4439+
| _ -> Scope.{ empty with val_env = singleton id (Some implicit.it) T.Pre })
44334440
| LetD (pat, exp, _) ->
44344441
begin match infer_val_path env exp with
44354442
| Some t ->

src/mo_interpreter/interpret.ml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -827,7 +827,7 @@ and declare_id id =
827827
and declare_pat pat : val_env =
828828
match pat.it with
829829
| WildP | LitP _ | SignP _ -> V.Env.empty
830-
| VarP id -> declare_id id
830+
| VarP id | GivenP { id; _ } -> declare_id id
831831
| TupP pats -> declare_pats pats V.Env.empty
832832
| ObjP pfs -> declare_pat_fields pfs V.Env.empty
833833
| OptP pat1
@@ -896,7 +896,7 @@ and match_lit lit v : bool =
896896
and match_pat pat v : val_env option =
897897
match pat.it with
898898
| WildP -> Some V.Env.empty
899-
| VarP id -> Some (V.Env.singleton id.it (Lib.Promise.make_fulfilled v))
899+
| VarP id | GivenP { id; _ } -> Some (V.Env.singleton id.it (Lib.Promise.make_fulfilled v))
900900
| LitP lit ->
901901
if match_lit lit v
902902
then Some V.Env.empty

test/run/implicit-pat.mo

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
let z with value : Nat = 0;
2+
3+
func addOne(value : (implicit : Int)) : Int {
4+
value + 1
5+
};
6+
7+
func two() {
8+
switch (+1) {
9+
case x with value {
10+
assert addOne() == 2;
11+
};
12+
};
13+
};
14+
15+
two();
16+
assert addOne() == 1;

0 commit comments

Comments
 (0)