From: Jeremie Dimino <jdimino@janestreet.com>
To: Kenichi Asai <asai@is.ocha.ac.jp>
Cc: caml users <caml-list@inria.fr>
Subject: Re: [Caml-list] a simple example of compiler-libs.toplevel?
Date: Fri, 5 Mar 2021 09:44:50 +0000 [thread overview]
Message-ID: <CANhEzE500WBfKuJaML35XECExZoa-oHHMXyhSq-sFV418oJJCA@mail.gmail.com> (raw)
In-Reply-To: <20210305050509.GA97697@pllab.is.ocha.ac.jp>
[-- Attachment #1: Type: text/plain, Size: 3915 bytes --]
Hi Kenichi,
It is possible to do this kind of thing. If you only want to change the
character for the prompt, you can set the Toploop.read_interactive_input
function. Then to create a custom toplevel, you need to call [Topmain.main]
and link your program with the compiler-libs.toplevel library. Here is a
complete example where I copied and adapted the default
[read_interactive_input] function from the compiler libraries, and used
dune to build a custom toplevel:
$ cat mytop.ml
let read_input prompt buffer len =
let prompt =
if prompt <> "" && prompt.[0] = '#' then
String.mapi (fun i c -> if i = 0 then '%' else c) prompt
else
prompt
in
output_string stdout prompt; flush stdout;
let i = ref 0 in
try
while true do
if !i >= len then raise Exit;
let c = input_char stdin in
Bytes.set buffer !i c;
Option.iter (fun b -> Buffer.add_char b c)
!Location.input_phrase_buffer;
incr i;
if c = '\n' then raise Exit;
done;
(!i, false)
with
| End_of_file ->
(!i, true)
| Exit ->
(!i, false)
let () =
Toploop.read_interactive_input := read_input;
Topmain.main ()
$ cat dune
(executable
(name mytop)
(libraries compiler-libs.toplevel)
(link_flags :standard -linkall)
(modes byte))
$ dune exec ./mytop.exe
OCaml version 4.11.1
% 1 + 1;;
- : int = 2
FTR, the compiler invocation to build myutop.exe is:
$ ocamlc -linkall -I +compiler-libs ocamlcommon.cma ocamlbytecomp.cma
ocamltoplevel.cma mytop.ml -o mytop.exe
$ ./mytop.exe
OCaml version 4.11.1
% 1 + 1;;
- : int = 2
If you want to go further, there are few projects that add line edition
support to the toplevel, colors etc, using similar methods:
- utop: https://github.com/ocaml-community/utop
- down: https://erratique.ch/software/down
Finally, if you'd like to improve the toplevel API so that doing this kind
of thing is easier in the future, a PR is always welcome :)
Happy hacking,
Jeremie
On Fri, Mar 5, 2021 at 5:05 AM Kenichi Asai <asai@is.ocha.ac.jp> wrote:
> Is there a simple (but complete) example that uses
> compiler-libs.toplevel, like creating an OCaml toplevel that uses a
> different character for a prompt? When I tried:
>
> - copy toplevel/topstart.ml to my_topstart.ml and change Topmain in it
> to My_topmain
> - copy toplevel/topmain.ml to my_topmain.ml and change Toploop in it
> to My_toploop
> - copy toplevel/toploop.ml to my_toploop.ml and change the prompt
> character in it
> - optionally, copy toplevel/topdirs.ml to my_topdirs.ml and change
> Toploop, etc., to My_toploop (this does not affect the story below)
>
> I ran into the following error:
>
> The ocamltoplevel.cma library from compiler-libs cannot be loaded
> inside the OCaml toplevel
>
> When I disable it (by removing the expression that raises this error
> in my_toploop.ml), I can launch the new toplevel, but I cannot define
> a new name:
>
> let a = 3
>
> results in "Fatal error: a unbound at toplevel". Is it possible to do
> this kind of creating a new OCaml toplevel using compiler-libs.toplevel?
> Or is the compiler-libs.toplevel intended for something else?
>
> A bit of background. I am developing an OCaml type debugger:
>
> http://pllab.is.ocha.ac.jp/~asai/TypeDebugger/
>
> and am currently trying to port it to a newer version of OCaml. For
> the current type debugger, I inserted code for type debugging into the
> main loop in toploop.ml. However, inserting code directly into the
> OCaml source requires me to recompile whole (or at least the core of)
> the OCaml. If I could do the same with compiler-libs, that would be
> great.
>
> Any help is welcome. (I also welcome the negative information saying
> that it is impossible to do this kind of thing. Then, I would fall
> back to the old way of compiling whole the OCaml.)
>
> Thank you in advance.
>
> Sincerely,
>
> --
> Kenichi Asai
>
--
Jeremie
[-- Attachment #2: Type: text/html, Size: 7107 bytes --]
next prev parent reply other threads:[~2021-03-05 9:45 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-03-05 5:05 Kenichi Asai
2021-03-05 9:44 ` Jeremie Dimino [this message]
2021-03-05 14:03 ` Kenichi Asai
2021-03-05 17:11 ` Jeremie Dimino
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=CANhEzE500WBfKuJaML35XECExZoa-oHHMXyhSq-sFV418oJJCA@mail.gmail.com \
--to=jdimino@janestreet.com \
--cc=asai@is.ocha.ac.jp \
--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