Reputation: 167
I have implemented a pretty-printer for a module. Currently I start up utop
, load the dependencies then do #install_printer pp_custom;;
where pp_custom
is the pretty-printer.
I would like to automate this so that I can have it in a way that is similar to the lacaml
library where the pretty-printer for the matrix is "installed" by default.
How would I go about to doing that?
Upvotes: 1
Views: 986
Reputation: 35210
In short, you need to run #install_printer
directive whenever you load your library in the top. I'm using the following code to evaluate code in the toplevel:
open Core_kernel.Std
open Or_error
let eval_exn str =
let lexbuf = Lexing.from_string str in
let phrase = !Toploop.parse_toplevel_phrase lexbuf in
Toploop.execute_phrase false Format.err_formatter phrase
let eval str = try_with (fun () -> eval_exn str)
It depends on Core_kernel
, but you can get rid of this easily, by just using eval_exn
instead of eval
(the last one wraps a possible exception into the Or_error
monad). Once you've got the eval
function, it can be used to load your printers:
let () = eval (sprintf "#install_printer %s;;" printer)
where printer
is the name of the pretty printing function (usually qualified with a module name). Usually, one put such code into the separate library, named library.top
, where library
is the name of your library.
For further automation, you can require all types, that you want to be auto-printable in toplevel, to register itself in a central registry, and then call all registered printers, instead of enumerating them by hand. To see all this working at once, you can take a look at the BAP library. It has a sublibrary called bap.top
that automatically installs all printers. Each type that is desired to be printable implements Printable
signature, using Printable.Make
functor, that not only derives many printing functions from the basic definition, but also registers the generated pretty-printers in Core_kernel's Pretty_printer
registry (you can use your own registry, this is just a set of strings, nothing more). When bap.top
library is loaded into the toplevel (using require
or load
directive), it enumerates all registered printers and install them.
Upvotes: 5