Skip to content

Commit dafa761

Browse files
committed
WIP Recursive bindings
1 parent acd08b7 commit dafa761

5 files changed

Lines changed: 184 additions & 54 deletions

File tree

elab.ml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -574,6 +574,13 @@ Trace.debug (lazy ("[RecT] t = " ^ string_of_norm_typ t));
574574
| Some canonic ->
575575
ExT([], lookup_var env (canonic@@path.at)), Pure, [], IL.VarE(canonic))
576576

577+
| EL.AnnotE(e, t) ->
578+
let exp =
579+
let open Syntax in
580+
let x' = var "annot" in
581+
appE(FunE(x'@@t.at, t, VarE(x'@@t.at)@@t.at, Expl@@t.at)@@span[e.at; t.at], e)@@exp.at in
582+
elab_exp env exp l
583+
577584
(*
578585
rec (X : (b : type) => {type t; type u a}) fun (b : type) => {type t = (X int.u b, X bool.t); type u a = (a, X b.t)}
579586
s1 = ?Xt:*->*, Xu:*->*->*. !b:*. [= b] -> {t : [= Xt b], u : !a:*. [= a] => [= Xu b a]}

lexer.mll

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -108,10 +108,14 @@ module Offside = struct
108108
if column < indent - 2 then error "offside" else
109109
emit token >>
110110
get >>= inside_braces break false indent
111+
| AND ->
112+
if column < indent then error "offside" else
113+
emit token >>
114+
get >>= inside_braces break false indent
111115
| _ ->
112116
if column < indent then error "offside" else
113117
emit_if (column = indent && insert) COMMA >>
114-
nest token >>
118+
nest false token >>
115119
get >>= inside_braces break (token <> LOCAL) indent
116120

117121
and inside_local insert indent (token, column) =
@@ -128,7 +132,7 @@ module Offside = struct
128132
emit IN
129133
else
130134
emit_if (column = indent && insert) COMMA >>
131-
nest token >>
135+
nest false token >>
132136
get >>= inside_local (token <> LOCAL) indent
133137

134138
and inside_let insert indent (token, column) =
@@ -147,12 +151,12 @@ module Offside = struct
147151
inside_in false column (token, column)
148152
else
149153
emit_if (column = indent && insert) COMMA >>
150-
nest token >>
154+
nest false token >>
151155
get >>= inside_let (token <> LOCAL) indent
152156

153157
and inside_in insert indent (token, column) =
154158
match token with
155-
| RBRACE | COMMA | IN | EOF | RPAR -> unget (token, column)
159+
| RBRACE | COMMA | IN | EOF | RPAR | EQUAL -> unget (token, column)
156160
| SEMI ->
157161
if column < indent - 2 then error "offside" else
158162
emit token >>
@@ -170,18 +174,18 @@ module Offside = struct
170174
let slack = slack_of token in
171175
if column < indent - slack then unget (token, column) else
172176
emit_if (slack = 0 && column = indent && insert) SEMI >>
173-
nest token >>
177+
nest true token >>
174178
get >>= inside_in (slack = 0 && indent < column) indent
175179

176180
and inside_parens (token, column) =
177181
match token with
178182
| RPAR -> emit token
179-
| _ -> nest token >> get >>= inside_parens
183+
| _ -> nest true token >> get >>= inside_parens
180184

181-
and nest token =
185+
and nest is_expr token =
182186
match token with
183187
| FUN | REC ->
184-
emit LPAR >> emit token
188+
if is_expr then emit LPAR >> emit token else emit token
185189
| _ ->
186190
emit token >>
187191
match token with
@@ -197,7 +201,7 @@ module Offside = struct
197201
| DARROW ->
198202
get >>= fun (token, column) ->
199203
inside_in false column (token, column) >>
200-
emit RPAR
204+
if is_expr then emit RPAR else unit
201205
| EQUAL | DO ->
202206
get >>= fun (token, column) -> inside_in false column (token, column)
203207
| _ ->
@@ -251,6 +255,7 @@ rule token = parse
251255
| "import" { IMPORT }
252256
| "primitive" { PRIMITIVE }
253257
| "rec" { REC }
258+
| "and" { AND }
254259
| "then" { THEN }
255260
| "type" { TYPE }
256261
| "unwrap" { UNWRAP }

parser.mly

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ let parse_error s = raise (Source.Error (Source.nowhere_region, s))
2626
%}
2727

2828
%token HOLE PRIMITIVE
29-
%token FUN REC LET IN DO WRAP UNWRAP TYPE ELLIPSIS
29+
%token FUN REC AND LET IN DO WRAP UNWRAP TYPE ELLIPSIS
3030
%token IF THEN ELSE LOGICAL_OR LOGICAL_AND AS
3131
%token EQUAL COLON SEAL ARROW SARROW DARROW
3232
%token WITH
@@ -436,12 +436,24 @@ atbind :
436436
{ $2 }
437437
*/
438438
;
439+
atbinds :
440+
| atbind
441+
{ $1 }
442+
| atbind AND atbinds
443+
{ seqB($1, $3)@@at() }
444+
;
445+
recbind :
446+
| atbind
447+
{ $1 }
448+
| REC atbinds
449+
{ recB($2)@@at() }
450+
;
439451
bind :
440452
|
441453
{ EmptyB@@at() }
442-
| atbind
454+
| recbind
443455
{ $1 }
444-
| atbind COMMA bind
456+
| recbind COMMA bind
445457
{ seqB($1, $3)@@at() }
446458
| LOCAL bind IN bind
447459
{ letB($2, $4)@@at() }

regression.1ml

Lines changed: 32 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -156,48 +156,41 @@ type_error rec (R: {}) => {
156156
kaboom () = R
157157
}
158158

159-
Kaboom = rec (R: rec R => {kaboom: () ~> R}) => @(= R) {
160-
kaboom () = R
159+
rec Kaboom : rec R => {kaboom: () ~> R} = @(= Kaboom) {
160+
kaboom () = Kaboom
161161
}
162162

163163
;;
164164

165+
rec isEven n = n == 0 || isOdd (n-1)
166+
and isOdd n = n == 1 || (not (n == 0) && isEven (n-1))
167+
168+
;;
169+
165170
Mutually = let
166-
T = rec (R: {
167-
Even: {type t _}
168-
Odd: {type t _}
169-
}) => {
170-
Even = {
171-
type t x = {head: x, tail: R.Odd.t x}
171+
T = {
172+
rec Even = {
173+
type t x = {head: x, tail: Odd.t x}
172174
}
173-
Odd = {
174-
type t x = opt (R.Even.t x)
175+
and Odd = {
176+
type t x = opt (Even.t x)
175177
}
176178
}
177179
in {
178-
...rec (R: {
179-
Even: {
180-
size 'x: T.Even.t x ~> int
181-
}
182-
Odd: {
183-
size 'x: T.Odd.t x ~> int
184-
}
185-
}) => {
186-
Even = {
187-
...T.Even
188-
make 'x (head: x) (tail: T.Odd.t x) : T.Even.t x =
189-
@(T.Even.t x) {head, tail}
190-
size 'x (v: T.Even.t x) = 1 + R.Odd.size v.@(T.Even.t _).tail
191-
}
192-
Odd = {
193-
...T.Odd
194-
make 'x (v: opt (T.Even.t x)) : T.Odd.t x = @(T.Odd.t x) v
195-
size 'x (v: T.Odd.t x) =
196-
v.@(T.Odd.t x) |> Opt.case {
197-
none = 0
198-
some e = R.Even.size e
199-
}
200-
}
180+
rec Even = {
181+
...T.Even
182+
make 'x (head: x) (tail: T.Odd.t x) : T.Even.t x =
183+
@(T.Even.t x) {head, tail}
184+
size 'x (v: T.Even.t x) : int = 1 + Odd.size v.@(T.Even.t _).tail
185+
}
186+
and Odd = {
187+
...T.Odd
188+
make 'x (v: opt (T.Even.t x)) : T.Odd.t x = @(T.Odd.t x) v
189+
size 'x (v: T.Odd.t x) : int =
190+
v.@(T.Odd.t x) |> Opt.case {
191+
none = 0
192+
some = Even.size
193+
}
201194
}
202195

203196
one = Odd.size (Odd.make (some (Even.make true (Odd.make none))))
@@ -224,7 +217,7 @@ type (a `>>` b) c = c
224217
;;
225218

226219
Hungry = {
227-
type eat a = rec eat_a => a ~> eat_a
220+
rec type eat a = a -> eat a
228221

229222
eater 'a: eat a = rec (eater: eat a) => @(eat a) fun a => eater
230223

@@ -234,8 +227,8 @@ Hungry = {
234227
}
235228

236229
PolyRec = {
237-
type l a = rec (type t) => a | t
238-
...rec {type t a} => {type t a = a | t (a, a)}
230+
rec type l a = a | l a
231+
rec type t a = a | t (a, a)
239232

240233
t_int = t int
241234

@@ -259,7 +252,7 @@ ListN = let
259252
}
260253
type T x n (type t _ _) = (type p _) -> I x p t ~> p n
261254
in {
262-
...rec {type t _ _} => {type t x n = wrap T x n t}
255+
rec type t x n = wrap T x n t
263256

264257
case 'x 'n (type p _) (cs: I x p t) e =
265258
(unwrap e.@(t _ _): wrap T x n t) p cs
@@ -279,9 +272,9 @@ in {
279272

280273
ListN = {
281274
...ListN
282-
map 'x 'y (xy: x ~> y) = rec (map 'n: t x n ~> t y n) =>
275+
rec map 'x 'y 'n (xy: x ~> y) : t x n ~> t y n =
283276
case (t _) {
284277
nil
285-
x :: xs = xy x :: map xs
278+
x :: xs = xy x :: map xy xs
286279
}
287280
}

0 commit comments

Comments
 (0)