caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: Michael <michipili@gmail.com>
To: caml-list@inria.fr
Subject: [Caml-list] Re: Opening a module from toploop startup
Date: Tue, 09 Jul 2013 11:26:24 +0200	[thread overview]
Message-ID: <51DBD740.3020109@gmail.com> (raw)
In-Reply-To: <CAA9EyWkxpDzoyh-jMd_SWHR2mKR7-fFR-WG8Lm4-V4vL5J688g@mail.gmail.com>

Just a gentle ping on this one…

Maybe could someone suggest an open-source project where customisation 
of the toplevel takes place?

Also I am sorry about the poor formatting of my original message, I got 
tripped by HTML editing. The clean code is:
~~~~~~~~~
open Format

module Tag =
struct
   type t = int
   let format fft tag =
     fprintf fft "Tag#%d" tag
   let test_open_module () =
     true
end

let libdir = [
   "/usr/local/lib/ocaml/compiler-libs";
]

let execute_phrase ident phrase =
   if Toploop.execute_phrase false Format.std_formatter phrase
   then
     ()
   else
     failwith ident

let rec make_path_rev p =
   match p with
   | [] -> invalid_arg "make_path_rev"
   | h :: [] -> Longident.Lident h
   | h :: t -> Longident.Ldot (make_path_rev t, h)

let make_path p =
   make_path_rev (List.rev p)

let install_printer path =
   let longident = make_path_rev ("format" :: List.rev path) in
   let phrase = Parsetree.Ptop_dir(
     "install_printer", Parsetree.Pdir_ident longident
   )
   in
   execute_phrase "install_printer" phrase


let open_module p =
   let open Parsetree in
   let open Location in
   let open Asttypes in
   let loc = {
     loc_start = Lexing.dummy_pos;
     loc_end = Lexing.dummy_pos;
     loc_ghost = false
   }
   in
   let phrase = Ptop_def [
     {
       pstr_desc =
     Pstr_open {
       txt = make_path p;
       loc;
     };
       pstr_loc = loc
     };
   ]
   in
   execute_phrase "open_module" phrase

let startup () =
   begin
     List.iter Topdirs.dir_directory libdir;
     List.iter install_printer [["Demonstrate"; "Tag"]];
     List.iter open_module [["Demonstrate"]; ["Demonstrate"; "Tag" ]];
   end

let _ =
   Toploop.toplevel_startup_hook := startup
~~~~~~~~~

Michael Le Barbier Grünewald schrieb:
> Dear Camlers,
>
> I am learning to produce customised toplevel loops and, while I was able
> to automatically add custom printers, could not open modules.
>
> Obviously, there is something I should know, and don't… could someone
> help me?
>
> My code (working example, see below) is a bit long, so let me outline it:
>
> The _startup_ procedure issues a few toploop directives, adding search
> directories, installing printers for the given modules (currently one)
> and opening them.
>
> _open_module_ and _install_printer_ produce and interpret toplevel
> phrases corresponding to the directives with the same name.
>
> Tank you for your help,
> Michael
>
>
> ----8<----
> Compile:
>
>      |ocamlfind ocamlc -c -package "compiler-libs" -o demonstrate.cmo
>      demonstrate.ml|||
>      |||ocamlfind ocamlmktop -package "compiler-libs" -custom -linkall
>      -dllpath-all -linkpkg -package "compiler-libs" demonstrate.cmo -o
>      mytoplevel|||
>      ||
>
> Demonstrate that the Demonstrate.Tag module is not opened:
>
>      |> ./mytoplevel|||
>      |||        OCaml version 4.00.1|||
>      ||||
>      |||# test_open_module;;|||
>      |||Error: Unbound value test_open_module|||
>      |||# ^D|||
>      ||
>
> Demonstrate that the custom printer is installed:
>
>      |> ./mytoplevel|||
>      |||        OCaml version 4.00.1|||
>      ||||
>      |||# open Demonstrate;;|||
>      |||# (5 : Tag.t);;|||
>      |||- : Demonstrate.Tag.t = Tag#5|||
>      |||# ^D|
>
> The whole code:
> ~~~~
> |open Format||
> ||
> ||module Tag =||
> ||struct||
> ||  type t = int||
> ||  let format fft tag =||
> ||    fprintf fft "Tag#%d" tag||
> ||  let test_open_module () =||
> ||    true||
> ||end||
> ||
> ||let libdir = [||
> ||  "/usr/local/lib/ocaml/compiler-libs";||
> ||]||
> ||
> ||let execute_phrase ident phrase =||
> ||  if Toploop.execute_phrase false Format.std_formatter phrase||
> ||  then||
> ||    ()||
> ||  else||
> ||    failwith ident||
> ||
> ||let rec make_path_rev p =||
> ||  match p with||
> ||  | [] -> invalid_arg "make_path_rev"||
> ||  | h :: [] -> Longident.Lident h||
> ||  | h :: t -> Longident.Ldot (make_path_rev t, h)||
> ||
> ||let make_path p =||
> ||  make_path_rev (List.rev p)||
> ||    ||
> ||let install_printer path =||
> ||  let longident = make_path_rev ("format" :: List.rev path) in||
> ||  let phrase = Parsetree.Ptop_dir(||
> ||    "install_printer", Parsetree.Pdir_ident longident||
> ||  )||
> ||  in||
> ||  execute_phrase "install_printer" phrase||
> ||
> ||
> ||let open_module p =||
> ||  let open Parsetree in||
> ||  let open Location in||
> ||  let open Asttypes in||
> ||  let loc = {||
> ||    loc_start = Lexing.dummy_pos;||
> ||    loc_end = Lexing.dummy_pos;||
> ||    loc_ghost = false||
> ||  }||
> ||  in||
> ||  let phrase = Ptop_def [||
> ||    {||
> ||      pstr_desc =||
> ||    Pstr_open {||
> ||      txt = make_path p;||
> ||      loc;||
> ||    };||
> ||      pstr_loc = loc||
> ||    };||
> ||  ]||
> ||  in||
> ||  execute_phrase "open_module" phrase||
> ||
> ||let startup () =||
> ||  begin||
> ||    List.iter Topdirs.dir_directory libdir;||
> ||    List.iter install_printer [["Demonstrate"; "Tag"]];||
> ||    List.iter open_module [["Demonstrate"]; ["Demonstrate"; "Tag" ]];||
> ||  end||
> ||
> ||let _ =||
> ||  Toploop.toplevel_startup_hook := startup|
> ---->8----


  reply	other threads:[~2013-07-09  9:27 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-07-01 21:30 [Caml-list] " Michael Le Barbier Grünewald
2013-07-09  9:26 ` Michael [this message]
2013-07-09  9:33   ` [Caml-list] " Daniel Bünzli
2013-07-14 18:23     ` Michael
2013-07-09  9:36   ` Anil Madhavapeddy

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=51DBD740.3020109@gmail.com \
    --to=michipili@gmail.com \
    --cc=caml-list@inria.fr \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).