From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Original-To: caml-list@sympa.inria.fr Delivered-To: caml-list@sympa.inria.fr Received: from mail2-relais-roc.national.inria.fr (mail2-relais-roc.national.inria.fr [192.134.164.83]) by sympa.inria.fr (Postfix) with ESMTPS id 9F1E581792 for ; Tue, 9 Jul 2013 11:27:07 +0200 (CEST) Received-SPF: None (mail2-smtp-roc.national.inria.fr: no sender authenticity information available from domain of michipili@gmail.com) identity=pra; client-ip=209.85.212.170; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="michipili@gmail.com"; x-sender="michipili@gmail.com"; x-conformance=sidf_compatible Received-SPF: Pass (mail2-smtp-roc.national.inria.fr: domain of michipili@gmail.com designates 209.85.212.170 as permitted sender) identity=mailfrom; client-ip=209.85.212.170; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="michipili@gmail.com"; x-sender="michipili@gmail.com"; x-conformance=sidf_compatible; x-record-type="v=spf1" Received-SPF: None (mail2-smtp-roc.national.inria.fr: no sender authenticity information available from domain of postmaster@mail-wi0-f170.google.com) identity=helo; client-ip=209.85.212.170; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="michipili@gmail.com"; x-sender="postmaster@mail-wi0-f170.google.com"; x-conformance=sidf_compatible X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AokBAAHX21HRVdSqk2dsb2JhbABagzsBwVOBHRYOAQEBAQcLCwkUBCSCJAEFJwsBBQgBGxELAgMMBgULFhYPCQMCAQIBEREBBQEcEwgCh3gBAw8EnA6MTYJ/hFkKGScNWIdzAQUMjyw6g3IDjxSIP4EphHqJQD+EOQ X-IPAS-Result: AokBAAHX21HRVdSqk2dsb2JhbABagzsBwVOBHRYOAQEBAQcLCwkUBCSCJAEFJwsBBQgBGxELAgMMBgULFhYPCQMCAQIBEREBBQEcEwgCh3gBAw8EnA6MTYJ/hFkKGScNWIdzAQUMjyw6g3IDjxSIP4EphHqJQD+EOQ X-IronPort-AV: E=Sophos;i="4.87,1027,1363129200"; d="scan'208";a="25151949" Received: from mail-wi0-f170.google.com ([209.85.212.170]) by mail2-smtp-roc.national.inria.fr with ESMTP/TLS/RC4-SHA; 09 Jul 2013 11:26:53 +0200 Received: by mail-wi0-f170.google.com with SMTP id ey16so10931621wid.5 for ; Tue, 09 Jul 2013 02:26:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=message-id:date:from:user-agent:mime-version:to:subject:references :in-reply-to:content-type:content-transfer-encoding; bh=HEo21Mx/hZeCa21IoWvRUOSKz5kA0J9S0waUuGqqsKI=; b=zHMYytmeXuJgBzdxtlqzw5b5CfAxqBCjdJqd2Cb0ftiuATKvLEoUihHdUxXUC2o40u k0DAMFHUC16PtKLlgU4mVFOc4ABf0u0o8AMJK0c/yuTBvRqYNnCZZfTiB+sznWpeCvqY 7dqPOhjsX4wJURCO+8ZLWMGd6OfMwnjUG0jSku39mwrqz2XwWbvSwCdd+oUa1mQiIPeI YJ3PJzAKtH27jUCLlLe+j8jnJ2kceeVgs4ZXNydGaxePVdCrac/mud68Nv5KGLPpfj1c 0b0bKmRQ6mtwFEymYNc8uY4F5mnXGHStDev337stJGM/yjqzpwQUFUx8+SwSMSSpp27G ABtA== X-Received: by 10.194.238.199 with SMTP id vm7mr14103830wjc.37.1373362013753; Tue, 09 Jul 2013 02:26:53 -0700 (PDT) Received: from [127.0.0.1] ([213.168.79.58]) by mx.google.com with ESMTPSA id a6sm11624673wib.10.2013.07.09.02.26.51 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Tue, 09 Jul 2013 02:26:52 -0700 (PDT) Message-ID: <51DBD740.3020109@gmail.com> Date: Tue, 09 Jul 2013 11:26:24 +0200 From: Michael User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:22.0) Gecko/20100101 Firefox/22.0 SeaMonkey/2.19 MIME-Version: 1.0 To: caml-list@inria.fr References: In-Reply-To: Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 8bit Subject: [Caml-list] Re: Opening a module from toploop startup 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----