-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpa_coq.ml
72 lines (69 loc) · 2.25 KB
/
pa_coq.ml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
(* $Id: pa_coq.ml,v 1.60 2013-10-11 12:27:21 deraugla Exp $ *)
#load "pa_extend.cmo";
#load "q_MLast.cmo";
open Pcaml;
EXTEND
GLOBAL: str_item expr;
str_item:
[ [ "Fixpoint"; l = V (LIST1 coq_binding SEP "and") →
<:str_item< value rec $_list:l$ >>
| "Definition"; l = V (LIST1 coq_binding SEP "and") →
<:str_item< value $_list:l$ >> ] ]
;
coq_binding:
[ [ p = ipatt; LIST0 GIDENT; e = coq_fun_binding → (p, e) ] ]
;
coq_fun_binding:
[ RIGHTA
[ "("; pl = LIST1 LIDENT; ":"; t = ctyp; ")"; e = SELF →
List.fold_right (fun p e → <:expr< fun ($lid:p$ : $t$) → $e$ >>)
pl e
| p = ipatt; e = SELF → <:expr< fun $p$ → $e$ >>
| ":="; e = coq_expr → <:expr< $e$ >>
| ":"; t = ctyp; ":="; e = coq_expr → <:expr< ($e$ : $t$) >> ] ]
;
coq_expr:
[ [ "match"; e = SELF; "with"; l = V (LIST0 coq_match_case); "end" →
<:expr< match $e$ with [ $_list:l$ ] >>
| "let"; l = V (LIST1 coq_binding SEP "and"); "in"; x = SELF →
<:expr< let $_list:l$ in $x$ >>
| e = expr → e ] ]
;
coq_match_case:
[ [ "|"; p = patt; "=>"; e = coq_expr →
let (p, e) =
match p with
[ <:patt< S $lid:n$ >> →
(<:patt< $lid:n$ >>,
<:expr< let $lid:n$ = pred $lid:n$ in $e$ >>)
| <:patt< Term $p₁$ $lid:n$ >> →
(<:patt< Term $p₁$ $lid:n$ >>,
<:expr< let $lid:n$ = Lazy.force $lid:n$ in $e$ >>)
| _ →
(p, e) ]
in
(p, <:vala< None >>, e) ] ]
;
expr: LEVEL "simple"
[ [ GIDENT "λ"; p = ipatt; e = coq_fun_def →
<:expr< fun $p$ → $e$ >>
| "{|"; lel = V (LIST1 coq_label_expr SEP ";"); "|}" →
<:expr< { $_list:lel$ } >> ] ]
;
coq_fun_def:
[ RIGHTA
[ p = ipatt; e = SELF -> <:expr< fun $p$ -> $e$ >>
| ","; e = coq_expr -> e ] ]
;
coq_label_expr:
[ [ i = patt_label_ident; e = coq_fun_binding → (i, e) ] ]
;
patt_label_ident:
[ LEFTA
[ p1 = SELF; "."; p2 = SELF → <:patt< $p1$ . $p2$ >> ]
| "simple" RIGHTA
[ i = V UIDENT → <:patt< $_uid:i$ >>
| i = V LIDENT → <:patt< $_lid:i$ >>
| "_" → <:patt< _ >> ] ]
;
END;