caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* HOWTO create and install a new printer with camlp4 3.10
@ 2007-03-28 22:10 Hendrik Tews
  2007-03-29  9:18 ` [Caml-list] " Nicolas Pouillard
  2007-03-30 14:14 ` Nicolas Pouillard
  0 siblings, 2 replies; 3+ messages in thread
From: Hendrik Tews @ 2007-03-28 22:10 UTC (permalink / raw)
  To: caml-list


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


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [Caml-list] HOWTO create and install a new printer with camlp4 3.10
  2007-03-28 22:10 HOWTO create and install a new printer with camlp4 3.10 Hendrik Tews
@ 2007-03-29  9:18 ` Nicolas Pouillard
  2007-03-30 14:14 ` Nicolas Pouillard
  1 sibling, 0 replies; 3+ messages in thread
From: Nicolas Pouillard @ 2007-03-29  9:18 UTC (permalink / raw)
  To: Hendrik Tews; +Cc: caml-list

On 3/29/07, Hendrik Tews <H.Tews@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


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [Caml-list] HOWTO create and install a new printer with camlp4 3.10
  2007-03-28 22:10 HOWTO create and install a new printer with camlp4 3.10 Hendrik Tews
  2007-03-29  9:18 ` [Caml-list] " Nicolas Pouillard
@ 2007-03-30 14:14 ` Nicolas Pouillard
  1 sibling, 0 replies; 3+ messages in thread
From: Nicolas Pouillard @ 2007-03-30 14:14 UTC (permalink / raw)
  To: Hendrik Tews; +Cc: caml-list

On 3/29/07, Hendrik Tews <H.Tews@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


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2007-03-30 14:14 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-03-28 22:10 HOWTO create and install a new printer with camlp4 3.10 Hendrik Tews
2007-03-29  9:18 ` [Caml-list] " Nicolas Pouillard
2007-03-30 14:14 ` Nicolas Pouillard

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).