* toplevel with pre-installed printers @ 2006-01-19 16:28 Andrej Bauer 2006-01-19 16:53 ` [Caml-list] " Daniel Bünzli ` (2 more replies) 0 siblings, 3 replies; 13+ messages in thread From: Andrej Bauer @ 2006-01-19 16:28 UTC (permalink / raw) To: Caml list This seems like a trivial question, but I do not know the answer: how do I create either a toplevel (or a shell script which appears to be a toplevel) with pre-installed pretty-printers (and pre-opened modules, for that matter)? Andrej ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Caml-list] toplevel with pre-installed printers 2006-01-19 16:28 toplevel with pre-installed printers Andrej Bauer @ 2006-01-19 16:53 ` Daniel Bünzli 2006-01-19 16:57 ` Eric Stokes 2006-01-20 8:29 ` [Caml-list] " Jean-Christophe Filliatre 2 siblings, 0 replies; 13+ messages in thread From: Daniel Bünzli @ 2006-01-19 16:53 UTC (permalink / raw) To: Andrej.Bauer; +Cc: Caml list The toplevel tries to read toplevel phrases from an .ocamlinit file present in the current directoy or, if not, from $HOME/.ocamlinit. Read there [1], under Unix. Best, Daniel [1] <http://caml.inria.fr/pub/docs/manual-ocaml/manual023.html> ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Caml-list] toplevel with pre-installed printers 2006-01-19 16:28 toplevel with pre-installed printers Andrej Bauer 2006-01-19 16:53 ` [Caml-list] " Daniel Bünzli @ 2006-01-19 16:57 ` Eric Stokes 2006-01-19 17:08 ` Andrej Bauer 2006-01-20 8:29 ` [Caml-list] " Jean-Christophe Filliatre 2 siblings, 1 reply; 13+ messages in thread From: Eric Stokes @ 2006-01-19 16:57 UTC (permalink / raw) To: Andrej.Bauer; +Cc: Caml list When the toplevel starts up, it evaluates (on unix) ~/.ocamlinit, which can contain arbitrary ocaml expressions. On Jan 19, 2006, at 8:28 AM, Andrej Bauer wrote: > This seems like a trivial question, but I do not know the answer: > how do I create either a toplevel (or a shell script which appears > to be > a toplevel) with pre-installed pretty-printers (and pre-opened > modules, > for that matter)? > > Andrej > > _______________________________________________ > 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 ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Caml-list] toplevel with pre-installed printers 2006-01-19 16:57 ` Eric Stokes @ 2006-01-19 17:08 ` Andrej Bauer 2006-01-19 17:49 ` Richard Jones 2006-01-20 14:13 ` code17 0 siblings, 2 replies; 13+ messages in thread From: Andrej Bauer @ 2006-01-19 17:08 UTC (permalink / raw) To: Eric Stokes; +Cc: Caml list Eric Stokes wrote: > When the toplevel starts up, it evaluates (on unix) ~/.ocamlinit, > which can contain arbitrary ocaml expressions. Sorry, I was not clear enough. I know about .ocamlinit. I am going to have several custom ocamltop's and they can't all share the same .ocamlinit. What now? Andrej P.S. Ocaml toplevel could use a bit of improvements. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Caml-list] toplevel with pre-installed printers 2006-01-19 17:08 ` Andrej Bauer @ 2006-01-19 17:49 ` Richard Jones 2006-01-19 19:12 ` Eric Cooper 2006-01-20 14:13 ` code17 1 sibling, 1 reply; 13+ messages in thread From: Richard Jones @ 2006-01-19 17:49 UTC (permalink / raw) To: Andrej Bauer; +Cc: Eric Stokes, Caml list On Thu, Jan 19, 2006 at 06:08:06PM +0100, Andrej Bauer wrote: > Eric Stokes wrote: > > When the toplevel starts up, it evaluates (on unix) ~/.ocamlinit, > > which can contain arbitrary ocaml expressions. > > Sorry, I was not clear enough. I know about .ocamlinit. I am going to > have several custom ocamltop's and they can't all share the same > .ocamlinit. What now? We tried to do the same thing and couldn't find a way. One rather nasty suggestion involved a surrounding shell script which would launch the right toplevel in the right directory with the right .ocamlinit. It's not pleasant. Rich. -- Richard Jones, CTO Merjis Ltd. Merjis - web marketing and technology - http://merjis.com Team Notepad - intranets and extranets for business - http://team-notepad.com ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Caml-list] toplevel with pre-installed printers 2006-01-19 17:49 ` Richard Jones @ 2006-01-19 19:12 ` Eric Cooper 2006-01-19 20:18 ` Richard Jones 0 siblings, 1 reply; 13+ messages in thread From: Eric Cooper @ 2006-01-19 19:12 UTC (permalink / raw) To: caml-list, Caml list On Thu, Jan 19, 2006 at 05:49:07PM +0000, Richard Jones wrote: > On Thu, Jan 19, 2006 at 06:08:06PM +0100, Andrej Bauer wrote: > > Eric Stokes wrote: > > > When the toplevel starts up, it evaluates (on unix) ~/.ocamlinit, > > > which can contain arbitrary ocaml expressions. > > > > Sorry, I was not clear enough. I know about .ocamlinit. I am going to > > have several custom ocamltop's and they can't all share the same > > .ocamlinit. What now? > > We tried to do the same thing and couldn't find a way. One rather > nasty suggestion involved a surrounding shell script which would > launch the right toplevel in the right directory with the right > .ocamlinit. It's not pleasant. In a single "master" .ocamlinit, you could dispatch on Sys.executable_name, and perhaps Sys.getcwd. Still a hack, but it might avoid (non-OCaml) wrapper scripts. -- Eric Cooper e c c @ c m u . e d u ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Caml-list] toplevel with pre-installed printers 2006-01-19 19:12 ` Eric Cooper @ 2006-01-19 20:18 ` Richard Jones 2006-01-20 2:24 ` skaller 0 siblings, 1 reply; 13+ messages in thread From: Richard Jones @ 2006-01-19 20:18 UTC (permalink / raw) To: caml-list On Thu, Jan 19, 2006 at 02:12:59PM -0500, Eric Cooper wrote: > In a single "master" .ocamlinit, you could dispatch on > Sys.executable_name, and perhaps Sys.getcwd. Still a hack, but it > might avoid (non-OCaml) wrapper scripts. This is a clever idea. However one of the other problems is that people could run the toplevel from another directory. This is particularly important in the case where we install the toplevel as a binary in, say, /usr/bin. Rich. -- Richard Jones, CTO Merjis Ltd. Merjis - web marketing and technology - http://merjis.com Team Notepad - intranets and extranets for business - http://team-notepad.com ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Caml-list] toplevel with pre-installed printers 2006-01-19 20:18 ` Richard Jones @ 2006-01-20 2:24 ` skaller 2006-01-20 16:49 ` David Brown 0 siblings, 1 reply; 13+ messages in thread From: skaller @ 2006-01-20 2:24 UTC (permalink / raw) To: Richard Jones; +Cc: caml-list On Thu, 2006-01-19 at 20:18 +0000, Richard Jones wrote: > On Thu, Jan 19, 2006 at 02:12:59PM -0500, Eric Cooper wrote: > > In a single "master" .ocamlinit, you could dispatch on > > Sys.executable_name, and perhaps Sys.getcwd. Still a hack, but it > > might avoid (non-OCaml) wrapper scripts. > > This is a clever idea. It's an old one too. gcc does it. The problem is portability. You simply look at argv[0] which on some Unix systems is the full path name of the invoked executable. In particular, its the path name of the symlink to the executable, not the binary. Thus, you can find the directory containing the symlink, and thus the resources associated with that particular symlink. All you need is a unique symlink for every context, and a fixed way of finding files relative to the location of the symlink. The problem is that there is no guarantee argv[0] is in fact the full pathname of the symlink on all Unix systems .. it works on Linux though. The two other techniques commonly used to solve this problem are (a) a wrapper script passing a command line argument (b) an environment variable ./ocamlinit script can certainly read an environment variable. It can also read the command line arguments .. so all you really need is to ask for a patch to the toplevel which allows you to pass it an argument it totally ignores! -- John Skaller <skaller at users dot sf dot net> Felix, successor to C++: http://felix.sf.net ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Caml-list] toplevel with pre-installed printers 2006-01-20 2:24 ` skaller @ 2006-01-20 16:49 ` David Brown 2006-01-20 19:29 ` skaller 0 siblings, 1 reply; 13+ messages in thread From: David Brown @ 2006-01-20 16:49 UTC (permalink / raw) To: skaller; +Cc: Richard Jones, caml-list On Fri, Jan 20, 2006 at 01:24:03PM +1100, skaller wrote: > You simply look at argv[0] which on some Unix systems > is the full path name of the invoked executable. Actually, argv[0] is almost never a full path. It is the path used to invoke the executable. So, if the program is in the user's path, then it will just be the filename, with no path information. In order to find itself, a program has to search for argv[0] in $PATH. If you don't believe me, try it: hello.c: #include <stdio.h> int main (int argc, char **argv) { printf ("Program name: %s\n", argv[0]); } % gcc -o ~/bin/hello hello.c % hello Program name: hello Dave ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Caml-list] toplevel with pre-installed printers 2006-01-20 16:49 ` David Brown @ 2006-01-20 19:29 ` skaller 0 siblings, 0 replies; 13+ messages in thread From: skaller @ 2006-01-20 19:29 UTC (permalink / raw) To: David Brown; +Cc: caml-list, Richard Jones On Fri, 2006-01-20 at 08:49 -0800, David Brown wrote: > On Fri, Jan 20, 2006 at 01:24:03PM +1100, skaller wrote: > > > You simply look at argv[0] which on some Unix systems > > is the full path name of the invoked executable. > > Actually, argv[0] is almost never a full path. You're right. Hmm .. but your example is complicated, here's a simpler version: skaller@rosella:/work/felix/flx$ echo $0 bash .. clearly not the full path. -- John Skaller <skaller at users dot sf dot net> Felix, successor to C++: http://felix.sf.net ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: toplevel with pre-installed printers 2006-01-19 17:08 ` Andrej Bauer 2006-01-19 17:49 ` Richard Jones @ 2006-01-20 14:13 ` code17 1 sibling, 0 replies; 13+ messages in thread From: code17 @ 2006-01-20 14:13 UTC (permalink / raw) To: caml-list Andrej Bauer <Andrej.Bauer@andrej.com> writes: > Sorry, I was not clear enough. I know about .ocamlinit. I am going to > have several custom ocamltop's and they can't all share the same > .ocamlinit. What now? I recently worked on a problem about customized toplevel. I need a generic toplevel with various kinds of preloaded modules and open them beforehand. So I can't produce these toplevels statically using ocamlmktop, I have to launch them with various configurations on the fly. Maybe this is also your situation. Here are some results I've got (especially from the beginner's list, hi Richard Jones :-) Case 1: Suppose your requirement is quite simple: pre-load variant modules, open them, execute some evaluations and primitives without showing the feedback ... and you don't have to do complex interpretation between the user input as well as feedback from the real ocaml toplevel. You would probably like to use the undocumented(why?) option "-init", then wrap your executable as a shell script or programs. Use it like the default .ocamlinit except now you can indicate who is the script for initialization. E.g. <code> tmp/init.ml: # load "bigarray.cma";; open Bigarray.Genarray;; (* You may even delete it after execution, maybe dangerous *) Sys.command "rm tmp/init.ml";; </code> <command> ocaml -init tmp/init.ml </command> <toplevel> Objective Caml version 3.09.0 # create;; - : ('a, 'b) Bigarray.kind -> 'c Bigarray.layout -> int array -> ('a, 'b, 'c) Bigarray.Genarray.t = <fun> # </toplevel> Obviously you can have different configuration for different toplevels you want, and even produce the configuration on the fly. Case 2: If you want to do complex interpretation between your user and the real ocaml toplevel, e.g. you want "My own topleve" instead of "Objective Caml version 3.09" showing at the beginning, you want to interpret the user's input secretly before feeding them to the toplevel (maybe camlp4 help to do anything possible here?) and hide or modify feedback from ocaml (maybe personalized pretty printer can solve any problem here?). Either you are quite familiar with toplevel source and hack by yourself, or like me really provide a program acting as translator, i.e. another process active between user and the background running toplevel. Then you can do anything as you want. I've done so, and wish to provide some of the generic functionality as library when I've got time to clean my code. Wish it helps! code17 ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Caml-list] toplevel with pre-installed printers 2006-01-19 16:28 toplevel with pre-installed printers Andrej Bauer 2006-01-19 16:53 ` [Caml-list] " Daniel Bünzli 2006-01-19 16:57 ` Eric Stokes @ 2006-01-20 8:29 ` Jean-Christophe Filliatre 2006-01-20 13:13 ` Gerd Stolpmann 2 siblings, 1 reply; 13+ messages in thread From: Jean-Christophe Filliatre @ 2006-01-20 8:29 UTC (permalink / raw) To: Andrej.Bauer; +Cc: Caml list Hello, Andrej Bauer writes: > This seems like a trivial question, but I do not know the answer: > how do I create either a toplevel (or a shell script which appears to be > a toplevel) with pre-installed pretty-printers (and pre-opened modules, > for that matter)? I learnt a trick to do that from David Monniaux's GMP interface. First define your pretty-printers using the Ocaml module Format. For instance, the GMP pretty-printers look like == gmp_pp.ml ========================================================= open Gmp open Format let z z = print_string (Z.string_from z) let q q = ... ====================================================================== then introduce another file installing the pretty-printers: == install_gmp_pp.ml ================================================= (* This is a hack to install the pretty-printers in the customized toplevel. *) (* Caml longidents. *) type t = | Lident of string | Ldot of t * string | Lapply of t * t let _ = Topdirs.dir_directory "+creal" let _ = Topdirs.dir_install_printer Format.std_formatter (Obj.magic (Ldot (Lident "Gmp_pp", "z")) : 'a) let _ = Topdirs.dir_install_printer Format.std_formatter (Obj.magic (Ldot (Lident "Gmp_pp", "q")) : 'a) ====================================================================== Finally, build your ocaml toplevel the usual way, linking the two files above: ====================================================================== ocamlgmp: gmp.cma gmp_pp.cmo install_gmp_pp.cmo ocamlmktop -custom -o $@ $^ ====================================================================== I know this is a hack (the infamous Obj.magic is used and the Caml longident type could change in a next ocaml version) but it works fine. Hope this helps, -- Jean-Christophe Filliâtre (http://www.lri.fr/~filliatr) ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Caml-list] toplevel with pre-installed printers 2006-01-20 8:29 ` [Caml-list] " Jean-Christophe Filliatre @ 2006-01-20 13:13 ` Gerd Stolpmann 0 siblings, 0 replies; 13+ messages in thread From: Gerd Stolpmann @ 2006-01-20 13:13 UTC (permalink / raw) To: Jean-Christophe Filliatre; +Cc: Andrej.Bauer, Caml list Am Freitag, den 20.01.2006, 09:29 +0100 schrieb Jean-Christophe Filliatre: > First define your pretty-printers using the Ocaml module Format. For > instance, the GMP pretty-printers look like In Ocamlnet, we use a similar trick, but get around Obj.magic: let exec s = let l = Lexing.from_string s in let ph = !Toploop.parse_toplevel_phrase l in assert(Toploop.execute_phrase false Format.err_formatter ph) ;; exec "#install_printer Mimestring.print_s_param;;";; exec "#install_printer Neturl.print_url;;";; exec "#install_printer Netbuffer.print_buffer;;";; exec "#install_printer Netstream.print_in_obj_stream;;";; This module can be simply compiled to bytecode and can be loaded into the toplevel. As we are using findlib, a second trick automates this. In META we have archive(byte,toploop) = "netstring.cma netstring_top.cmo" where netstring.cma contains the generic code and netstring_top.cma the toplevel-specific code. So when the user types #require "netstring" the toplevel printers are automatically available. Gerd > > == gmp_pp.ml ========================================================= > open Gmp > open Format > let z z = print_string (Z.string_from z) > let q q = ... > ====================================================================== > > then introduce another file installing the pretty-printers: > > == install_gmp_pp.ml ================================================= > (* This is a hack to install the pretty-printers in the customized toplevel. *) > > (* Caml longidents. *) > type t = > | Lident of string > | Ldot of t * string > | Lapply of t * t > > let _ = Topdirs.dir_directory "+creal" > > let _ = Topdirs.dir_install_printer Format.std_formatter > (Obj.magic (Ldot (Lident "Gmp_pp", "z")) : 'a) > > let _ = Topdirs.dir_install_printer Format.std_formatter > (Obj.magic (Ldot (Lident "Gmp_pp", "q")) : 'a) > ====================================================================== > > Finally, build your ocaml toplevel the usual way, linking the two > files above: > > ====================================================================== > ocamlgmp: gmp.cma gmp_pp.cmo install_gmp_pp.cmo > ocamlmktop -custom -o $@ $^ > ====================================================================== > > I know this is a hack (the infamous Obj.magic is used and the Caml > longident type could change in a next ocaml version) but it works > fine. > > Hope this helps, -- ------------------------------------------------------------ Gerd Stolpmann * Viktoriastr. 45 * 64293 Darmstadt * Germany gerd@gerd-stolpmann.de http://www.gerd-stolpmann.de Telefon: 06151/153855 Telefax: 06151/997714 ------------------------------------------------------------ ^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2006-01-20 19:29 UTC | newest] Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2006-01-19 16:28 toplevel with pre-installed printers Andrej Bauer 2006-01-19 16:53 ` [Caml-list] " Daniel Bünzli 2006-01-19 16:57 ` Eric Stokes 2006-01-19 17:08 ` Andrej Bauer 2006-01-19 17:49 ` Richard Jones 2006-01-19 19:12 ` Eric Cooper 2006-01-19 20:18 ` Richard Jones 2006-01-20 2:24 ` skaller 2006-01-20 16:49 ` David Brown 2006-01-20 19:29 ` skaller 2006-01-20 14:13 ` code17 2006-01-20 8:29 ` [Caml-list] " Jean-Christophe Filliatre 2006-01-20 13:13 ` Gerd Stolpmann
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox