I am testing out quotations in Camlp4. My tester.ml program is as follows:
open Camlp4.PreCast;;
let x = <:Cstm< x = 1 + 2 >>;;
let y = <:expr< let y = 1 + 2 >>;;
print_string "done";;
I have tried compiling this in various ways, eg.
ocamlc -pp "camlp4of pa_extend.cmo -loc" -I +camlp4 tester.ml
however the executable produced doesn't print out "done" as expected. How should I compile this file?
camlp4 --help
says:
-loc <name> Name of the location variable (default: _loc).
You forget the argument for -loc
. You can check the consequence of this by ocamlc
's -verbose
option. (-verbose
is really handy to find out what are exactly happening in the compilation):
$ ocamlc -verbose -pp "camlp4of pa_extend.cmo -loc" -I +camlp4 tester.ml
+ camlp4of pa_extend.cmo -loc "tester.ml" > /blahblah//ocamlpp2f0635
The input file name tester.ml
is not treated as a file name but is considered as the name of location variables. With the empty input camlp4of
outputs an empty program and it is compiled by ocamlc
. That's why the final executable does nothing.
You code contains a strange quotation name Cstrm
, and let y = 1 + 2
is not an expression but a structure item. The following is one of the nearest codes which compile:
(* compilable by ocamlc -pp "camlp4of pa_extend.cmo" -I +camlp4 tester.ml *)
open Camlp4.PreCast;;
let x _loc = <:expr< x = 1 + 2 >>;;
let y _loc = <:str_item< let y = 1 + 2 >>;;
print_string "done";;
You can check the output of CamlP4 in a human readable form with -printer Camlp4OCamlPrinter
option. This is another important technique to work with CamlP4:
$ camlp4of pa_extend.cmo -printer Camlp4OCamlPrinter tester.ml
open Camlp4.PreCast
let x _loc =
Ast.ExApp (_loc,
(Ast.ExApp (_loc, (Ast.ExId (_loc, (Ast.IdLid (_loc, "=")))),
(Ast.ExId (_loc, (Ast.IdLid (_loc, "x")))))),
(Ast.ExApp (_loc,
(Ast.ExApp (_loc, (Ast.ExId (_loc, (Ast.IdLid (_loc, "+")))),
(Ast.ExInt (_loc, "1")))),
(Ast.ExInt (_loc, "2")))))
let y _loc =
Ast.StVal (_loc, Ast.ReNil,
(Ast.BiEq (_loc, (Ast.PaId (_loc, (Ast.IdLid (_loc, "y")))),
(Ast.ExApp (_loc,
(Ast.ExApp (_loc, (Ast.ExId (_loc, (Ast.IdLid (_loc, "+")))),
(Ast.ExInt (_loc, "1")))),
(Ast.ExInt (_loc, "2")))))))
let _ = print_string "done"