dtlc

dependently-typed lambda calculus toy
git clone git://git.rr3.xyz/dtlc
Log | Files | Refs | README | LICENSE

commit 54b7bd3a98514dfd174af3d9cc56a6951ecd4b31
parent 008e2cfcb987935ecfd7e9ba10446aa38b529807
Author: Robert Russell <robertrussell.72001@gmail.com>
Date:   Tue,  5 Dec 2023 23:47:08 -0800

Save progress, because I'm about to change a bunch of stuff

Diffstat:
A.gitignore | 3+++
Acommon.ml | 6++++++
Acore.ml | 20++++++++++++++++++++
Aelab.ml | 99+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aeval.ml | 34++++++++++++++++++++++++++++++++++
Aparser.ml | 415+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mparser.mly | 11+++++++----
Msurf.ml | 8++++----
Avalue.ml | 12++++++++++++
9 files changed, 600 insertions(+), 8 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -0,0 +1,3 @@ +*.cm* +*.mli +test diff --git a/common.ml b/common.ml @@ -0,0 +1,6 @@ +type ident = string +type index = int +type level = int + +(* Readable helper function for creating closures. *) +let capture env body = (env, body) diff --git a/core.ml b/core.ml @@ -0,0 +1,20 @@ +open Common + +type term = +| Let of ident * term * term +| Fn of ident * term +| Pi of ident * term * term +| App of term * term +| Var of index +| Int of Z.t + +(* +TODO: +1. copy over elab code +2. test +3. add support for constants +4. add support for ADTs +5. staging +6. ... +7. quantities (0, ω) +*) diff --git a/elab.ml b/elab.ml @@ -0,0 +1,99 @@ +open Common +module S = Surf +module C = Core +module V = Value + +type context = { + env: V.environ; + free: (ident * V.value) list; +} + +let let_bind ctx x t v = { + env = v :: ctx.env; + free = (x, t) :: ctx.free; +} + +let var_bind ctx x t = let_bind ctx x t (V.Var (List.length ctx.env)) + +let rec check ctx a t = match a, t with +| S.Let (p, a, b), t -> + let (ca, ta, x) = infer_with_patt ctx a p in + let va = eval ctx.env ca in + let cb = check (let_bind ctx x ta va) sb t in + C.Let (x, ca, cb) +| S.Fn (p, a), V.Pi (_, dom, cod) -> + let x = check_patt ctx p dom in + let ca = check (var_bind ctx x dom) a (apply cod (V.Var (List.length ctx.env))) in + C.Fn (x, ca) +| a, t -> + let (ca, u) = infer ctx a in + if conv (List.length ctx.env) t u then ca else failwith "type error" + +and infer ctx a = match a with +| S.Let (p, a, b) -> + let (ca, ta, x) = infer_with_patt ctx a p in + let va = eval ctx.env ca in + let (cb, tb) = infer (let_bind ctx x ta va) sb in + (C.Let (x, ca, cb), tb) +| S.Fn (p, a) -> + let (x, t) = infer_patt ctx p in + let (ca, u) = infer (var_bind ctx x t) a in + (C.Fn (x, ca), V.Pi ("α", t, capture ctx.env (quote (List.length ctx.env) u))) +| S.Pi (x, dom, cod) -> + let cdom = check ctx dom V.Type in + let vdom = eval ctx.env cdom in + let ccod = check (var_bind ctx x vdom) cod V.Type in + (C.Pi (x, cdom, ccod), V.Type) +| S.Hint (a, b) -> + let cb = check ctx b V.Type in + let vb = eval ctx.env cb in + let ca = check ctx a vb in + (ca, vb) +| S.Plus (a, b) -> infer ctx (App ()) + let c0 = check ctx s0 VNat in + let c1 = check ctx s1 VNat in + (CAdd (c0, c1), VNat) + +| SVar x -> + let rec go i = function + | [] -> failwith ("variable '" ^ x ^ "' out of scope") + | (y, v) :: rest -> if x = y then (CVar i, v) else go (i + 1) rest in + go 0 ctx.free +| SType -> (CType, VType) +| SApp (s0, s1) -> + let (c0, t0) = infer ctx s0 in + begin match t0 with + | VPi (dom, cod) -> + let c1 = check ctx s1 dom in + (CApp (c0, c1), apply cod (eval ctx.env c1)) + | _ -> failwith "expected function type in application" + end +| SNat -> (CNat, VType) +| SLit n -> (CLit n, VNat) + +and infer_with_patt ctx a p = match p with +| S.Annot (p, b) -> + let cb = check ctx b V.Type in + let vb = eval ctx.env cb in + let x = check_patt ctx p vb in + let ca = check ctx a vb in + (ca, vb, x) +| S.Wild x -> let (ca, t) = infer ctx a in (ca, t, x) + +and check_patt ctx p t = match p with +| S.Annot (p, a) -> + let ca = check ctx a V.Type in + let va = eval ctx.env ca in + if conv (List.length ctx.env) t va then + check_patt ctx p t + else + failwith "patt_check fail" +| S.Wild x -> x + +and infer_patt ctx p = match p with +| S.Annot (p, a) -> + let ca = check ctx a V.Type in + let va = eval ctx.env ca in + let x = check_patt ctx p va in + (x, va) +| S.Wild _ -> failwith "can not infer type for wild pattern" diff --git a/eval.ml b/eval.ml @@ -0,0 +1,34 @@ +open Common +module C = Core +module V = Value + +let rec eval env = function +| C.Let (_, a, b) -> eval (eval env a :: env) b +| C.Fn (x, body) -> V.Fn (x, capture env body) +| C.Pi (x, dom, cod) -> V.Pi (x, eval env dom, capture env cod) +| C.App (f, a) -> + begin match eval env f, eval env a with + | V.Fn (_, fclo), va -> apply fclo va + | vf, va -> V.App (vf, va) + end +| C.Var i -> List.nth env i +| C.Int n -> V.Int n + +and apply (env, a) v = eval (v :: env) a + +let rec quote l = function +| V.Fn (x, clo) -> C.Fn (x, quote (l + 1) (apply clo (V.Var l))) +| V.Pi (x, dom, cod) -> C.Pi (x, quote l dom, quote (l + 1) (apply cod (V.Var l))) +| V.App (f, a) -> C.App (quote l f, quote l a) +| V.Var k -> C.Var (l - k - 1) +| V.Int z -> C.Int z + +let rec conv l a b = match a, b with +(* no η for fn *) +| V.Fn (_, aclo), V.Fn(_, bclo) -> conv (l + 1) (apply aclo (V.Var l)) (apply bclo (V.Var l)) +| V.Pi (_, dom0, cod0), V.Pi (_, dom1, cod1) -> conv l dom0 dom1 + && conv (l + 1) (apply cod0 (V.Var l)) (apply cod1 (V.Var l)) +| V.App (a0, a1), V.App (b0, b1) -> conv l a0 b0 && conv l a1 b1 +| V.Var x, V.Var y -> x = y +| V.Int n, V.Int m -> Z.equal n m +| _, _ -> false diff --git a/parser.ml b/parser.ml @@ -0,0 +1,415 @@ +type token = + | EOF + | COLON + | EQ + | SEMICOLON + | SINGLE_ARROW + | DOUBLE_ARROW + | AT_LPAREN + | HASH_LPAREN + | LPAREN + | RPAREN + | LBRACK + | RBRACK + | LBRACE + | RBRACE + | PLUS + | ASTERISK + | LET + | IF + | THEN + | ELSE + | IDENT of ( +# 16 "parser.mly" + Surf.ident +# 26 "parser.ml" +) + | INT of ( +# 17 "parser.mly" + Z.t +# 31 "parser.ml" +) + +open Parsing +let _ = parse_error;; +# 2 "parser.mly" +open Surf +# 38 "parser.ml" +let yytransl_const = [| + 0 (* EOF *); + 257 (* COLON *); + 258 (* EQ *); + 259 (* SEMICOLON *); + 260 (* SINGLE_ARROW *); + 261 (* DOUBLE_ARROW *); + 262 (* AT_LPAREN *); + 263 (* HASH_LPAREN *); + 264 (* LPAREN *); + 265 (* RPAREN *); + 266 (* LBRACK *); + 267 (* RBRACK *); + 268 (* LBRACE *); + 269 (* RBRACE *); + 270 (* PLUS *); + 271 (* ASTERISK *); + 272 (* LET *); + 273 (* IF *); + 274 (* THEN *); + 275 (* ELSE *); + 0|] + +let yytransl_block = [| + 276 (* IDENT *); + 277 (* INT *); + 0|] + +let yylhs = "\255\255\ +\001\000\001\000\001\000\003\000\003\000\003\000\004\000\004\000\ +\004\000\005\000\005\000\006\000\006\000\007\000\007\000\008\000\ +\008\000\008\000\002\000\002\000\009\000\009\000\000\000" + +let yylen = "\002\000\ +\006\000\006\000\001\000\005\000\003\000\001\000\007\000\005\000\ +\001\000\003\000\001\000\003\000\001\000\002\000\001\000\001\000\ +\001\000\003\000\003\000\001\000\001\000\003\000\002\000" + +let yydefred = "\000\000\ +\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\ +\017\000\023\000\003\000\000\000\000\000\000\000\000\000\015\000\ +\000\000\021\000\000\000\000\000\000\000\000\000\000\000\000\000\ +\000\000\000\000\000\000\000\000\014\000\000\000\000\000\000\000\ +\000\000\000\000\018\000\000\000\000\000\005\000\000\000\000\000\ +\022\000\000\000\019\000\000\000\000\000\000\000\000\000\004\000\ +\000\000\008\000\000\000\000\000\000\000\001\000\002\000\007\000" + +let yydgoto = "\002\000\ +\010\000\019\000\011\000\012\000\013\000\014\000\015\000\016\000\ +\020\000" + +let yysindex = "\006\000\ +\005\255\000\000\254\254\036\255\005\255\254\254\031\255\000\000\ +\000\000\000\000\000\000\009\255\000\255\012\255\252\254\000\000\ +\254\254\000\000\006\255\032\255\052\255\023\255\045\255\056\255\ +\037\255\031\255\252\254\252\254\000\000\054\255\060\255\031\255\ +\031\255\061\255\000\000\031\255\031\255\000\000\012\255\252\254\ +\000\000\031\255\000\000\057\255\039\255\066\255\051\255\000\000\ +\067\255\000\000\005\255\031\255\039\255\000\000\000\000\000\000" + +let yyrindex = "\000\000\ +\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ +\000\000\000\000\000\000\009\000\045\000\023\000\001\000\000\000\ +\000\000\000\000\000\000\027\255\053\255\000\000\000\000\000\000\ +\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ +\000\000\000\000\000\000\000\000\000\000\000\000\042\000\020\000\ +\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ +\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + +let yygindex = "\000\000\ +\253\255\002\000\254\255\252\255\000\000\048\000\044\000\244\255\ +\000\000" + +let yytablesize = 320 +let yytable = "\022\000\ +\013\000\023\000\029\000\005\000\025\000\017\000\001\000\024\000\ +\006\000\026\000\003\000\004\000\005\000\027\000\031\000\008\000\ +\009\000\018\000\030\000\012\000\006\000\007\000\011\000\038\000\ +\008\000\009\000\028\000\029\000\020\000\043\000\044\000\034\000\ +\032\000\046\000\047\000\020\000\003\000\004\000\005\000\048\000\ +\050\000\010\000\004\000\005\000\009\000\004\000\005\000\054\000\ +\056\000\055\000\008\000\009\000\033\000\035\000\037\000\021\000\ +\009\000\036\000\008\000\009\000\016\000\016\000\041\000\042\000\ +\045\000\049\000\016\000\016\000\051\000\052\000\053\000\040\000\ +\016\000\016\000\039\000\000\000\000\000\000\000\000\000\000\000\ +\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ +\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ +\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ +\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ +\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ +\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ +\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ +\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ +\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ +\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ +\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ +\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ +\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ +\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ +\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ +\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ +\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ +\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ +\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ +\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ +\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ +\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\ +\000\000\013\000\013\000\013\000\000\000\000\000\000\000\000\000\ +\000\000\013\000\006\000\006\000\000\000\000\000\013\000\013\000\ +\000\000\006\000\013\000\013\000\012\000\012\000\012\000\011\000\ +\011\000\011\000\006\000\006\000\012\000\000\000\000\000\011\000\ +\000\000\012\000\012\000\000\000\011\000\012\000\012\000\000\000\ +\011\000\011\000\010\000\010\000\010\000\009\000\009\000\009\000\ +\000\000\000\000\010\000\000\000\000\000\009\000\000\000\010\000\ +\000\000\000\000\000\000\010\000\010\000\000\000\009\000\009\000" + +let yycheck = "\004\000\ +\000\000\005\000\015\000\008\001\007\000\008\001\001\000\006\000\ +\000\000\001\001\006\001\007\001\008\001\014\001\009\001\020\001\ +\021\001\020\001\017\000\000\000\016\001\017\001\000\000\026\000\ +\020\001\021\001\015\001\040\000\002\001\032\000\033\000\009\001\ +\001\001\036\000\037\000\009\001\006\001\007\001\008\001\042\000\ +\045\000\000\000\007\001\008\001\000\000\007\001\008\001\051\000\ +\053\000\052\000\020\001\021\001\001\001\009\001\018\001\020\001\ +\021\001\002\001\020\001\021\001\008\001\009\001\009\001\004\001\ +\004\001\009\001\014\001\015\001\003\001\019\001\004\001\028\000\ +\020\001\021\001\027\000\255\255\255\255\255\255\255\255\255\255\ +\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\ +\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\ +\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\ +\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\ +\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\ +\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\ +\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\ +\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\ +\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\ +\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\ +\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\ +\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\ +\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\ +\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\ +\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\ +\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\ +\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\ +\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\ +\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\ +\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\ +\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\ +\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\ +\255\255\001\001\002\001\003\001\255\255\255\255\255\255\255\255\ +\255\255\009\001\002\001\003\001\255\255\255\255\014\001\015\001\ +\255\255\009\001\018\001\019\001\001\001\002\001\003\001\001\001\ +\002\001\003\001\018\001\019\001\009\001\255\255\255\255\009\001\ +\255\255\014\001\015\001\255\255\014\001\018\001\019\001\255\255\ +\018\001\019\001\001\001\002\001\003\001\001\001\002\001\003\001\ +\255\255\255\255\009\001\255\255\255\255\009\001\255\255\014\001\ +\255\255\255\255\255\255\018\001\019\001\255\255\018\001\019\001" + +let yynames_const = "\ + EOF\000\ + COLON\000\ + EQ\000\ + SEMICOLON\000\ + SINGLE_ARROW\000\ + DOUBLE_ARROW\000\ + AT_LPAREN\000\ + HASH_LPAREN\000\ + LPAREN\000\ + RPAREN\000\ + LBRACK\000\ + RBRACK\000\ + LBRACE\000\ + RBRACE\000\ + PLUS\000\ + ASTERISK\000\ + LET\000\ + IF\000\ + THEN\000\ + ELSE\000\ + " + +let yynames_block = "\ + IDENT\000\ + INT\000\ + " + +let yyact = [| + (fun _ -> failwith "parser") +; (fun __caml_parser_env -> + let _2 = (Parsing.peek_val __caml_parser_env 4 : 'patt0) in + let _4 = (Parsing.peek_val __caml_parser_env 2 : 'expr1) in + let _6 = (Parsing.peek_val __caml_parser_env 0 : Surf.expr) in + Obj.repr( +# 25 "parser.mly" + ( Let (_2, _4, _6) ) +# 234 "parser.ml" + : Surf.expr)) +; (fun __caml_parser_env -> + let _2 = (Parsing.peek_val __caml_parser_env 4 : 'expr1) in + let _4 = (Parsing.peek_val __caml_parser_env 2 : 'expr1) in + let _6 = (Parsing.peek_val __caml_parser_env 0 : 'expr1) in + Obj.repr( +# 26 "parser.mly" + ( If (_2, _4, _6) ) +# 243 "parser.ml" + : Surf.expr)) +; (fun __caml_parser_env -> + let _1 = (Parsing.peek_val __caml_parser_env 0 : 'expr1) in + Obj.repr( +# 27 "parser.mly" + ( _1 ) +# 250 "parser.ml" + : Surf.expr)) +; (fun __caml_parser_env -> + let _2 = (Parsing.peek_val __caml_parser_env 3 : 'patt0) in + let _5 = (Parsing.peek_val __caml_parser_env 0 : 'expr1) in + Obj.repr( +# 29 "parser.mly" + ( Fn (_2, _5) ) +# 258 "parser.ml" + : 'expr1)) +; (fun __caml_parser_env -> + let _1 = (Parsing.peek_val __caml_parser_env 2 : 'expr2) in + let _3 = (Parsing.peek_val __caml_parser_env 0 : 'expr1) in + Obj.repr( +# 30 "parser.mly" + ( Hint (_1, _3) ) +# 266 "parser.ml" + : 'expr1)) +; (fun __caml_parser_env -> + let _1 = (Parsing.peek_val __caml_parser_env 0 : 'expr2) in + Obj.repr( +# 31 "parser.mly" + ( _1 ) +# 273 "parser.ml" + : 'expr1)) +; (fun __caml_parser_env -> + let _2 = (Parsing.peek_val __caml_parser_env 5 : Surf.ident) in + let _4 = (Parsing.peek_val __caml_parser_env 3 : 'expr1) in + let _7 = (Parsing.peek_val __caml_parser_env 0 : 'expr2) in + Obj.repr( +# 33 "parser.mly" + ( Pi (Some _2, _4, _7) ) +# 282 "parser.ml" + : 'expr2)) +; (fun __caml_parser_env -> + let _2 = (Parsing.peek_val __caml_parser_env 3 : 'expr2) in + let _5 = (Parsing.peek_val __caml_parser_env 0 : 'expr2) in + Obj.repr( +# 34 "parser.mly" + ( Pi (None, _2, _5) ) +# 290 "parser.ml" + : 'expr2)) +; (fun __caml_parser_env -> + let _1 = (Parsing.peek_val __caml_parser_env 0 : 'expr3) in + Obj.repr( +# 35 "parser.mly" + ( _1 ) +# 297 "parser.ml" + : 'expr2)) +; (fun __caml_parser_env -> + let _1 = (Parsing.peek_val __caml_parser_env 2 : 'expr3) in + let _3 = (Parsing.peek_val __caml_parser_env 0 : 'expr4) in + Obj.repr( +# 37 "parser.mly" + ( Plus (_1, _3) ) +# 305 "parser.ml" + : 'expr3)) +; (fun __caml_parser_env -> + let _1 = (Parsing.peek_val __caml_parser_env 0 : 'expr4) in + Obj.repr( +# 38 "parser.mly" + ( _1 ) +# 312 "parser.ml" + : 'expr3)) +; (fun __caml_parser_env -> + let _1 = (Parsing.peek_val __caml_parser_env 2 : 'expr4) in + let _3 = (Parsing.peek_val __caml_parser_env 0 : 'expr5) in + Obj.repr( +# 40 "parser.mly" + ( Asterisk (_1, _3) ) +# 320 "parser.ml" + : 'expr4)) +; (fun __caml_parser_env -> + let _1 = (Parsing.peek_val __caml_parser_env 0 : 'expr5) in + Obj.repr( +# 41 "parser.mly" + ( _1 ) +# 327 "parser.ml" + : 'expr4)) +; (fun __caml_parser_env -> + let _1 = (Parsing.peek_val __caml_parser_env 1 : 'expr5) in + let _2 = (Parsing.peek_val __caml_parser_env 0 : 'expr6) in + Obj.repr( +# 43 "parser.mly" + ( Apposition (_1, _2) ) +# 335 "parser.ml" + : 'expr5)) +; (fun __caml_parser_env -> + let _1 = (Parsing.peek_val __caml_parser_env 0 : 'expr6) in + Obj.repr( +# 44 "parser.mly" + ( _1 ) +# 342 "parser.ml" + : 'expr5)) +; (fun __caml_parser_env -> + let _1 = (Parsing.peek_val __caml_parser_env 0 : Surf.ident) in + Obj.repr( +# 46 "parser.mly" + ( Var _1 ) +# 349 "parser.ml" + : 'expr6)) +; (fun __caml_parser_env -> + let _1 = (Parsing.peek_val __caml_parser_env 0 : Z.t) in + Obj.repr( +# 47 "parser.mly" + ( Int _1 ) +# 356 "parser.ml" + : 'expr6)) +; (fun __caml_parser_env -> + let _2 = (Parsing.peek_val __caml_parser_env 1 : Surf.expr) in + Obj.repr( +# 48 "parser.mly" + ( _2 ) +# 363 "parser.ml" + : 'expr6)) +; (fun __caml_parser_env -> + let _1 = (Parsing.peek_val __caml_parser_env 2 : 'patt1) in + let _3 = (Parsing.peek_val __caml_parser_env 0 : 'expr1) in + Obj.repr( +# 51 "parser.mly" + ( Annot (_1, _3) ) +# 371 "parser.ml" + : 'patt0)) +; (fun __caml_parser_env -> + let _1 = (Parsing.peek_val __caml_parser_env 0 : 'patt1) in + Obj.repr( +# 52 "parser.mly" + ( _1 ) +# 378 "parser.ml" + : 'patt0)) +; (fun __caml_parser_env -> + let _1 = (Parsing.peek_val __caml_parser_env 0 : Surf.ident) in + Obj.repr( +# 54 "parser.mly" + ( Wild _1 ) +# 385 "parser.ml" + : 'patt1)) +; (fun __caml_parser_env -> + let _2 = (Parsing.peek_val __caml_parser_env 1 : 'patt0) in + Obj.repr( +# 55 "parser.mly" + ( _2 ) +# 392 "parser.ml" + : 'patt1)) +(* Entry expr0 *) +; (fun __caml_parser_env -> raise (Parsing.YYexit (Parsing.peek_val __caml_parser_env 0))) +|] +let yytables = + { Parsing.actions=yyact; + Parsing.transl_const=yytransl_const; + Parsing.transl_block=yytransl_block; + Parsing.lhs=yylhs; + Parsing.len=yylen; + Parsing.defred=yydefred; + Parsing.dgoto=yydgoto; + Parsing.sindex=yysindex; + Parsing.rindex=yyrindex; + Parsing.gindex=yygindex; + Parsing.tablesize=yytablesize; + Parsing.table=yytable; + Parsing.check=yycheck; + Parsing.error_function=parse_error; + Parsing.names_const=yynames_const; + Parsing.names_block=yynames_block } +let expr0 (lexfun : Lexing.lexbuf -> token) (lexbuf : Lexing.lexbuf) = + (Parsing.yyparse yytables 1 lexfun lexbuf : Surf.expr) +;; diff --git a/parser.mly b/parser.mly @@ -27,19 +27,22 @@ expr0: | expr1 { $1 } expr1: | AT_LPAREN patt0 RPAREN SINGLE_ARROW expr1 { Fn ($2, $5) } - | HASH_LPAREN patt0 RPAREN SINGLE_ARROW expr1 { Pi ($2, $5) } | expr2 COLON expr1 { Hint ($1, $3) } | expr2 { $1 } expr2: - | expr2 PLUS expr3 { Plus ($1, $3) } + | HASH_LPAREN IDENT COLON expr1 RPAREN SINGLE_ARROW expr2 { Pi (Some $2, $4, $7) } + | HASH_LPAREN expr2 RPAREN SINGLE_ARROW expr2 { Pi (None, $2, $5) } | expr3 { $1 } expr3: - | expr3 ASTERISK expr4 { Asterisk ($1, $3) } + | expr3 PLUS expr4 { Plus ($1, $3) } | expr4 { $1 } expr4: - | expr4 expr5 { Apply ($1, $2) } + | expr4 ASTERISK expr5 { Asterisk ($1, $3) } | expr5 { $1 } expr5: + | expr5 expr6 { Apposition ($1, $2) } + | expr6 { $1 } +expr6: | IDENT { Var $1 } | INT { Int $1 } | LPAREN expr0 RPAREN { $2 } diff --git a/surf.ml b/surf.ml @@ -1,14 +1,14 @@ -type ident = string +open Common type expr = | Let of patt * expr * expr | If of expr * expr * expr | Fn of patt * expr -| Pi of patt * expr +| Pi of ident * expr * expr | Hint of expr * expr | Plus of expr * expr | Asterisk of expr * expr -| Apply of expr * expr +| Apposition of expr * expr | Var of ident | Int of Z.t and patt = @@ -26,7 +26,7 @@ let rec string_of_expr m e = | Hint (a, b) -> (1, se 2 a ^ " : " ^ se 1 b) | Plus (a, b) -> (2, se 2 a ^ " + " ^ se 3 b) | Asterisk (a, b) -> (3, se 3 a ^ " * " ^ se 4 b) - | Apply (a, b) -> (4, se 4 a ^ " " ^ se 5 b) + | Apposition (a, b) -> (4, se 4 a ^ " " ^ se 5 b) | Var x -> (5, x) | Int z -> (5, Z.to_string z) in if c < m then "(" ^ s ^ ")" else s diff --git a/value.ml b/value.ml @@ -0,0 +1,12 @@ +open Common + +type value = +| Type +| Fn of ident * closure +| Pi of ident * value * closure +| App of value * value +| Var of level (* TODO: rename this to "generic" or something? *) +| Nat +| Int of Z.t +and closure = environ * Core.term +and environ = value list