1 (* module LambdaSyntax = struct
2 module Loc = Camlp4.PreCast.Loc
5 | Ant of Loc.t * string
10 | Int of int antiquotable
11 |+ Why you don't want an antiquotation case here:
12 * Basically it seems natural that since an antiquotation of expression
13 * can be at any expression place. One can be a
14 * .... in fact not I not against that...
15 | Anti of Loc.t * string
17 and term = term' antiquotable
18 and var = string antiquotable
20 module Antiquotable = struct
21 module Loc = Camlp4.PreCast.Loc
24 | Ant of Loc.t * string
26 module Identity_type_functor = struct
29 module MakeLambdaSyntax(Node : sig type 'a t end) = struct
35 and term = term' Node.t
37 and var = string Node.t
39 module AntiquotableLambdaSyntax = MakeLambdaSyntax(Antiquotable);;
40 module LambdaSyntax = MakeLambdaSyntax(Identity_type_functor);;
41 module LambdaParser = struct
43 open AntiquotableLambdaSyntax;;
46 module LambdaGram = MakeGram(Lexer);;
48 let term = LambdaGram.Entry.mk "term";;
49 let term_eoi = LambdaGram.Entry.mk "lambda term quotation";;
51 Camlp4_config.antiquotations := true;;
53 let mkLam _loc v t = Val(_loc, Lam(v, t));;
54 let mkApp _loc f x = Val(_loc, App(f, x));;
55 let mkVar _loc x = Val(_loc, Var(x));;
56 let mkInt _loc v = Val(_loc, Int(v));;
59 GLOBAL: term term_eoi;
62 [ "fun"; v = var; "->"; t = term -> mkLam _loc v t ]
64 [ t1 = SELF; t2 = SELF -> mkApp _loc t1 t2 ]
66 [ `ANTIQUOT((""|"term"), a) -> Ant(_loc, a)
67 | i = int -> mkInt _loc i
68 | v = var -> mkVar _loc v
69 | "("; t = term; ")" -> t ]
72 [[ v = LIDENT -> Val(_loc, v)
73 | `ANTIQUOT((""|"var"), a) -> Ant(_loc, a)
76 [[ `INT(i, _) -> Val(_loc, i)
77 | `ANTIQUOT((""|"int"), a) -> Ant(_loc, a)
80 [[ t = term; `EOI -> t ]];
83 let parse_string = LambdaGram.parse_string term_eoi
85 module LambdaLifter = struct
87 open AntiquotableLambdaSyntax;;
89 Camlp4OCamlParser.Make(
90 Camlp4OCamlRevisedParser.Make(
94 module Ast = Camlp4.PreCast.Ast
95 let expr_of_string = CamlSyntax.Gram.parse_string CamlSyntax.expr_eoi;;
96 let patt_of_string = CamlSyntax.Gram.parse_string CamlSyntax.patt_eoi;;
99 << fun x -> $3$ >> -> Lam(VAtom"x", 3)
101 (* compilo.ml -pp lam.cmo *)
103 | << (fun $x$ -> $e1$) $e2$ >> -> << $subst ...$ >>
106 (* This part can be generated use SwitchValRepr *)
107 let rec term_to_expr = function
108 | Val(_loc, Lam(v, t)) -> <:expr< Lam($var_to_expr v$, $term_to_expr t$) >>
109 | Val(_loc, App(t1, t2)) -> <:expr< App($term_to_expr t1$, $term_to_expr t2$) >>
110 | Val(_loc, Var(v)) -> <:expr< Var($var_to_expr v$) >>
111 | Val(_loc, Int(i)) -> <:expr< Int($int_to_expr i$) >>
112 | Ant(_loc, a) -> expr_of_string _loc a
113 and var_to_expr = function
114 | Val(_loc, v) -> <:expr< $str:v$ >>
115 | Ant(_loc, s) -> expr_of_string _loc s
116 and int_to_expr = function
117 | Val(_loc, v) -> <:expr< $`int:v$ >>
118 | Ant(_loc, s) -> expr_of_string _loc s
121 let rec term_to_patt = function
122 | Val(_loc, Lam(v, t)) -> <:patt< Lam($var_to_patt v$, $term_to_patt t$) >>
123 | Val(_loc, App(t1, t2)) -> <:patt< App($term_to_patt t1$, $term_to_patt t2$) >>
124 | Val(_loc, Var(v)) -> <:patt< Var($var_to_patt v$) >>
125 | Val(_loc, Int(i)) -> <:patt< Int($int_to_patt i$) >>
126 | Ant(_loc, a) -> patt_of_string _loc a
127 and var_to_patt = function
128 | Val(_loc, v) -> <:patt< $str:v$ >>
129 | Ant(_loc, s) -> patt_of_string _loc s
130 and int_to_patt = function
131 | Val(_loc, v) -> <:patt< $`int:v$ >>
132 | Ant(_loc, s) -> patt_of_string _loc s
136 Arrow(Var"a", Var"b")
141 let ( ^-> ) t1 t2 = Arrow(t1, t2)
145 module LambadExpander = struct
146 module Q = Camlp4.PreCast.Syntax.Quotation;;
147 let expand_lambda_quot_expr loc _loc_name_opt quotation_contents =
148 LambdaLifter.term_to_expr
149 (LambdaParser.parse_string loc quotation_contents)
151 Q.add "lam" Q.DynAst.expr_tag expand_lambda_quot_expr;;
152 let expand_lambda_quot_patt loc _loc_name_opt quotation_contents =
153 LambdaLifter.term_to_patt
154 (LambdaParser.parse_string loc quotation_contents)
156 Q.add "lam" Q.DynAst.patt_tag expand_lambda_quot_patt;;