Dynamic usage of Ocaml evaluator?

From: Jan Skibinski (jans@numeric-quest.com)
Date: Thu Jun 18 1998 - 10:48:42 MET DST

Date: Thu, 18 Jun 1998 03:48:42 -0500 (CDT)
From: Jan Skibinski <jans@numeric-quest.com>
To: caml-list@inria.fr
Subject: Dynamic usage of Ocaml evaluator?

I'm sorry for this unilingual message - I do not speak French.

I am in a process of writing a portable dynamic writer of Adobe PDF
documents. The package contains series of scripts for three functional
languages: Q, Haskell and Ocaml, which all interface to the same C
driver. The driver does the low level work of talking to PDFlib
- a freely available third party library.

The scripts make use of ascii files with data for plots, tables,
plain text and HTML-like tag annotated information. The data is
portable in a sense that any of those languages use the same
sources and produce the same output - the PDF documents. One special
pair of tags <eval> and </eval> admits sequences of a universal code,
which look alike in all three languages, and if this is not possible
because of the syntax differences, then the language specific tags can
be used, such as <ocaml> and </ocaml>.

The obvious way of parsing the code from the external files is to
take an advantage of the evaluators residing in the specific
interpreters (toplevels). With Q there is no problem at all:
it accepts strings containing Q expressions, compiles them on the
fly and evaluates them within the current environment.

Ocaml requires that the code should reside in a *.ml file, therefore
I create such a file on the fly, say "phrases.ml", write required "open"
instructions, copy code from tagged file to "phrases.ml", close the
file and finally invoke 'Toploop.run_script "phrases.ml"' to evaluate
the expressions from this file. They usually plot something, draw
tables, etc.

Is there any better way to do it? Is the code below correct? It works,
but I am afraid that it might leave the toplevel in some unstable state.
Normally I do exit from the toplevel after I finished producing the
document (70 or so pages), but I wonder what might go wrong on a long
Jan Skibinski
Huntsville, Ontario, Canada

val eval_until : string -> out_channel -> number list
                -> string -> unit
let eval_until t f lv s =
        (* --------------------------------- *)
        (* Read lines from file "f", ignore *)
        (* empty lines and comments, and *)
        (* evaluate lines of Ocaml code *)
        (* until tag "t" is found. *)
        (* --------------------------------- *)
        let temp = open_out "phrases.ml" in
        output_string temp "open Pdf;;\n";
        output_string temp "open Html;;\n";
        eval_until2 t f temp lv ""; (* copy code from f to temp *)
        close_out temp;
        Toploop.run_script "phrases.ml"

This archive was generated by hypermail 2b29 : Sun Jan 02 2000 - 11:58:14 MET