ocamlabstract-syntax-treecamlp4

Printing OCaml AST as OCaml Code


I have this piece of code that contains a camlp4 quotation.

let f_name = "my_func"
<:str_item< value $lid:f_name$ a = a * 2 >>

After running this through camlp4of, it produces this:

  Ast.StExp (_loc,
    (Ast.ExApp (_loc,
       (Ast.ExApp (_loc, (Ast.ExId (_loc, (Ast.IdLid (_loc, "=")))),
          (Ast.ExApp (_loc,
             (Ast.ExApp (_loc,
                (Ast.ExId (_loc, (Ast.IdLid (_loc, "value")))),
                (Ast.ExId (_loc, (Ast.IdLid (_loc, f_name)))))),
             (Ast.ExId (_loc, (Ast.IdLid (_loc, "a")))))))),
       (Ast.ExApp (_loc,
          (Ast.ExApp (_loc, (Ast.ExId (_loc, (Ast.IdLid (_loc, "*")))),
             (Ast.ExId (_loc, (Ast.IdLid (_loc, "a")))))),
          (Ast.ExInt (_loc, "2")))))))

My question is this, is there anyway to print the generated ocaml code? What camlp4of command or option should I use to show the code? What I expect to see from the above example is:

value my_func a = a * 2

Is that possible? The reason is because I want to do some debugging to see how the generated ocaml code looks like.


Solution

  • That's a good question I asked myself a few days ago.

    You can use `Camlp4.PreCast.Printers.OCaml.print_implem which has the type

    value print_implem : ?input_file:string -> ?output_file:string ->
                         Ast.str_item -> unit;
    

    For example, in the toplevel (with only the output of the last command shown):

    # #use "topfind";;
    # #require "camlp4";;
    # #load "camlp4of.cma";;
    # open Camlp4.PreCast;;
    # let _loc = Loc.ghost;;
    # let test =
        let f_name = "my_func" in
        <:str_item< value $lid:f_name$ a = a * 2 >>;;
    # Printers.OCaml.print_implem test;;
    let _ = (value my_func a) = (a * 2);;
    - : unit = ()
    

    Another solution is to craft a syntax extension that will produce the output you're looking for. For example, a Camlp4AstFilter that would just ignore its input, and return your stuff as output, so you can use camlp4of my_filter.cmo -str '' to get the AST you're looking for.