[wg-camlp4] Matching on concrete syntax (was: Re: Camlp4 uses)

Alain Frisch alain.frisch at lexifi.com
Wed Apr 3 17:51:35 BST 2013


On 03/29/2013 02:46 PM, Gabriel Scherer wrote:
> Would it be possible to use the extension mechanism itself for
> lightweight quasiquotations?

On 03/29/2013 08:18 PM, Alain Frisch wrote:
> Something similar to
> branches/extension_points/experimental/frisch/print_gen.ml could be
> used to generate automatically an AST lifter.  The difficult part is
> to design anti-quotations, though, and since I'm not convinced by
> this approach, I'd rather put energy myself in other projects.

Ok, as usual, I've been sidetracked by your clever idea :-)

I've created a meta quotation expander (or should it be called 
"quasiquotation" ?), allowing to write AST builders using concrete 
syntax as in:

http://caml.inria.fr/cgi-bin/viewvc.cgi/ocaml/branches/extension_points/experimental/frisch/metaquot_test.ml?revision=HEAD&view=markup


The code for the ppx rewriter supporting this style is:

http://caml.inria.fr/cgi-bin/viewvc.cgi/ocaml/branches/extension_points/experimental/frisch/metaquot.ml?revision=HEAD&view=markup

It relies on a "Parsetree lifter" class (Ast_lifter.lifter). The same 
Parsetree lifter can also be used to write a Parsetree printer like the 
tool ocamlast I've described previously, but now without relying on the 
toplevel printer (which requires runtime access to parsetree.cmi, etc). 
  The code for such a printer is in:

http://caml.inria.fr/cgi-bin/viewvc.cgi/ocaml/branches/extension_points/experimental/frisch/dumpast.ml?revision=HEAD&view=markup


Ast_lifter.lifter is a partial parametrized class, whose type parameter 
describes which output is to be produced (Outcometree.value for the 
printer; Parsetree.expression for the meta quotation expander).  This 
class needs to be extended (through inheritance) in order to provide 
"builder functions" for that type, and potentially to override the 
default behavior for some type under Parsetree.  For instance, the 
printer decides to map all locations of Oval_ellipsis.  Similarly, the 
meta quotation expander detects uses of "anti-quotations" and maps them 
to the identity instead of the default lifting behavior.

The code of ast_lifter.ml looks like:

class virtual ['res] lifter =
   object (this)
     method lift_Parsetree_expression : Parsetree.expression -> 'res=
       fun
         { Parsetree.pexp_desc = pexp_desc; Parsetree.pexp_loc = pexp_loc;
           Parsetree.pexp_attributes = pexp_attributes }
          ->
         this#record "Parsetree.expression"
           [("pexp_desc", (this#lift_Parsetree_expression_desc pexp_desc));
           ("pexp_loc", (this#lift_Location_t pexp_loc));
           ("pexp_attributes",
             (this#list
                (List.map this#lift_Parsetree_attribute pexp_attributes)))]
     method lift_Parsetree_expression_desc :
       Parsetree.expression_desc -> 'res=
       function
       | Parsetree.Pexp_ident x0 ->
           this#constr "Parsetree.expression_desc"
             ("Pexp_ident", [this#lift_Asttypes_loc 
this#lift_Longident_t x0])
       | Parsetree.Pexp_constant x0 ->
           this#constr "Parsetree.expression_desc"
             ("Pexp_constant", [this#lift_Asttypes_constant x0])
       .....

which is very tedious to write by hand (and to maintain when the 
Parsetree evolves).  Of course, this code is not written by hand, it is 
generated from the definition of the Parsetree using a small tool:

http://caml.inria.fr/cgi-bin/viewvc.cgi/ocaml/branches/extension_points/experimental/frisch/dumpast.ml?revision=HEAD&view=markup

which is executed once to produce ast_lifter.ml:

./genlifter.exe -I ../../parsing -I ../../stdlib Parsetree.expression > 
ast_lifter.ml

All that can be tried by typing "make lifter" in experimental/frisch (on 
the extension_points branch, of course, after a successful "make world").

Now, one could go crazy (Camlp4-style) and use the metaquot ppx rewriter 
within genlifter.ml itself, and then get for free nasty bootstrapping 
problems :-)



Alain


More information about the wg-camlp4 mailing list