Mailing list for all users of the OCaml language and system.
 help / color / mirror / Atom feed
From: Guillaume Yziquel <guillaume.yziquel@citycable.ch>
To: rixed@happyleptic.org
Cc: caml-list@inria.fr
Subject: Re: [Caml-list] Calling the toplevel from the toplevel
Date: Sun, 27 Feb 2011 03:45:20 +0100	[thread overview]
Message-ID: <20110227024520.GL18196@localhost> (raw)
In-Reply-To: <20110226214403.GA20532@yeeloong.happyleptic.org>

Le Saturday 26 Feb 2011 à 22:44:04 (+0100), rixed@happyleptic.org a écrit :
> I'm trying to build an application that's run from the toplevel, using
> the toplevel to customize the application from itself (for instance,
> setting some global parameters using the toplevel to configure the
> application behavior while it's running).
> 
> But I cannot allow the toplevel to read directly from stdin nor to
> write anything into stdout (since my application uses ncurses).
> 
> I've looked for various ways to do this, and the simpler I found to
> prevent the toplevel to use stdout is to call myself
> Toploop.execute_phrase with a custom formatter (so that I can display
> the output where and how I want).
> 
> Up to now all seams to work except for minor annoyances :
> 
> - I cannot start the application directly by linking the custom toplevel
>   with something like "let _ = start_application ()" but I have to call
>   "start_application();;" from the toplevel manually (or from the
>   .ocamlinit file), otherwise the application bindings are not
>   available.

For this, you can change the Toploop.read_interactive_input reference to
what you want to control what you input to the toplevel. You therefore
do not need to consider workarounds such as calling evaluation functions
from code evaluated from the toplevel itself.

But it's a bit surprising that application bindings are not available
when calling start_application from some code that is being loaded. If
you insist on loading a .cmo instead of a .cma, the .cmo code is
executed when loaded, while code in the .cma often seems to be executed
only when required. That may solve your issue. Dunno.

You've also got a Toplevel.toplevel_startup_hook ref that may be useful.

> - I cannot let the user uses the toplevel directives "use" and "load"
>   because both writes into stdout whatever the formatter passed to
>   Toploop.execute_phrase (for "use" this is easily solvable by shadowing
>   the toplevel implementation by another one that call Toploop.use_file
>   with my own formatter, but for "load" I would have to copy a lot of
>   code from topdirs.ml
> 
> I'd like to know if it is safe to call the Toploop evaluation functions
> from code evaluated from the toplevel itself ? Or if someone can suggest
> a better way to prevent the toplevel from using stdout ?

Well, the Toploop module provides some interesting values to control
output:

val parse_toplevel_phrase : (Lexing.lexbuf -> Parsetree.toplevel_phrase)
ref
val parse_use_file : (Lexing.lexbuf -> Parsetree.toplevel_phrase list)
ref
val print_location : formatter -> Location.t -> unit
val print_error : formatter -> Location.t -> unit
val print_warning : Location.t -> formatter -> Warnings.t -> unit
val input_name : string ref

val print_out_value :
  (formatter -> Outcometree.out_value -> unit) ref
val print_out_type :
  (formatter -> Outcometree.out_type -> unit) ref
val print_out_class_type :
  (formatter -> Outcometree.out_class_type -> unit) ref
val print_out_module_type :
  (formatter -> Outcometree.out_module_type -> unit) ref
val print_out_sig_item :
  (formatter -> Outcometree.out_sig_item -> unit) ref
val print_out_signature :
  (formatter -> Outcometree.out_sig_item list -> unit) ref
val print_out_phrase :
  (formatter -> Outcometree.out_phrase -> unit) ref

I'd also look in the toplevel code of lwt, specifically in the source
code of lwt.top package. Contains quite a lot of interesting toplevel
tricks that would likely be of use to you. I'm not so sure, but it seems
to have some amount of control over toplevel output.

-- 
     Guillaume Yziquel


  reply	other threads:[~2011-02-27  2:46 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-02-26 21:44 rixed
2011-02-27  2:45 ` Guillaume Yziquel [this message]
2011-02-27 10:52   ` rixed
2011-02-27 12:00 ` Jérémie Dimino
2011-02-28 18:28   ` rixed
2011-02-28 20:30     ` Jérémie Dimino
2011-02-28 21:14       ` Yoann Padioleau
2011-03-03 18:34   ` rixed

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=20110227024520.GL18196@localhost \
    --to=guillaume.yziquel@citycable.ch \
    --cc=caml-list@inria.fr \
    --cc=rixed@happyleptic.org \
    /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