Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[Caml-list] HOWTO create and install a new printer with camlp4 3.10

5 views
Skip to first unread message

Hendrik Tews

unread,
Mar 28, 2007, 6:12:03 PM3/28/07
to caml...@inria.fr

Posted in the hope to save somebody's time before the new camlp4
documentation gets out.


First a word on side effects: I mean those side effects that
newly loaded modules perform inside camlp4 to register their
functions in the camlp4 engine.

In the good old times one simply used assignments for that, for
instance
Pcaml.print_implem := f
has always been used to install f as printer for a .ml file.

In the new camlp4 (some of) these side effects are performed not
by the user but by camlp4 itself. The user only supplies the
structure. It works the following way: The user defines a
functor Make that maps some structure to a structure that defines
the entities that camlp4 should use:

module Make (some arg) = struct
let important_fun ...
end

The user then uses Make in a functor application with a
higher-order, registering functor from camlp4:

module IgnoreResult = Camlp4.Register.Purpose(Make)

where Purpose is one of the functors that Camlp4.Register
provides. On invocation Purpose applies the user supplied Make to
the right arguments, obtains a structure with important_fun and,
finally, performs the side effect to register important_fun in
the right hook. Actually the story is a bit more complicated,
because the side effects are delayed: First Make is registered as
a loaded module inside camlp4 together with a function that will
perform the necessary side effects some time later. See for
example functor Printer in camlp4/Camlp4/Register.ml line 73.


In order to install a new camlp4 printer we only have to find the
right registering functor and apply it to our arguments, put
everything into some file and compile it into a .cmo.

To install a new printer I chose Register.Printer, which takes
two arguments: an identification module and a Make functor with
my new printer functions inside.

Here is the complete code:

(* identification module *)
module Id = struct
(* name is printed with the -loaded-modules switch *)
let name = "Printer HOWTO"
(* cvs id's seem to be the preferred version string *)
let version = "$Id: howto verion 1 $"
end


(* the real thing containing the real functions *)
module Make (Syntax : Camlp4.Sig.Syntax) :
Camlp4.Sig.Printer with module Ast = Syntax.Ast =
struct
module Ast = Syntax.Ast

let opt_string = function
| None -> "<None>"
| Some s -> s

let info ?input_file ?output_file name =
Printf.eprintf
"printer on %s\n input : %s\n output : %s\n"
name
(opt_string input_file)
(opt_string output_file)

(* print_interf shall be called on .mli files *)
let print_interf ?input_file ?output_file ast =
info ?input_file ?output_file "signature"

(* print_implem shall be called on .ml files *)
let print_implem ?input_file ?output_file ast =
info ?input_file ?output_file "structure"
end

(* apply everything to register the new printer *)
module M = Camlp4.Register.Printer(Id)(Make)

(* end of source *)

Put the source into a file printer.ml and compile with

ocamlc -c -I `camlp4 -where` printer.ml

Use examples:

gromit otags 7> camlp4o printer.cmo printer.ml
printer on structure
input : printer.ml
output : <None>

gromit otags 8> camlp4o -o output_file printer.cmo printer.ml
printer on structure
input : printer.ml
output : output_file

gromit otags 9> ocamlc -pp 'camlp4o printer.cmo' printer.ml
printer on structure
input : printer.ml
output : <None>


Happy printing,

Hendrik

_______________________________________________
Caml-list mailing list. Subscription management:
http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list
Archives: http://caml.inria.fr
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
Bug reports: http://caml.inria.fr/bin/caml-bugs

Nicolas Pouillard

unread,
Mar 29, 2007, 5:19:44 AM3/29/07
to Hendrik Tews
On 3/29/07, Hendrik Tews <H.T...@cs.ru.nl> wrote:
>
> Posted in the hope to save somebody's time before the new camlp4
> documentation gets out.

[...]

Thanks, a lot for your contribution!

--
Nicolas Pouillard

Nicolas Pouillard

unread,
Mar 30, 2007, 10:15:39 AM3/30/07
to Hendrik Tews
On 3/29/07, Hendrik Tews <H.T...@cs.ru.nl> wrote:
>
> Posted in the hope to save somebody's time before the new camlp4
> documentation gets out.

I'm making a little change.

[...]

> (* the real thing containing the real functions *)
> module Make (Syntax : Camlp4.Sig.Syntax) :

> Camlp4.Sig.Printer with module Ast = Syntax.Ast =

Will be
Camlp4.Sig.Printer(Syntax.Ast).S =

[...]

Since 3.10 is not officially out the sooner is the better.

--
Nicolas Pouillard

0 new messages