Version française
Home     About     Download     Resources     Contact us    
Browse thread
[Caml-list] scripting ocaml from inside of ocaml
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Chris GauthierDickey <chrisg@c...>
Subject: [Caml-list] scripting ocaml from inside of ocaml
Hi all,

  Just a disclaimer--this is a long message.

  I've searched the FAQs, manuals, and mailing lists to no avail. I have an
application that I'm writing in ocaml, and I need to do some scripting for
the program. I'd like to use ocaml as the scripting language. I've seen
references to using ocaml to interpret scripts from files, etc, but these
all assume that your environment is closed to the scripting. In particular,
I would like to be able to use ocaml to interpret scripts, have scripts
refer to objects that I import into their environment, and be able to take
values from their bindings in the scripts environment and use them in my
ocaml code.

  In some ways, the toplevel program does some of what I want, so using the
actual ocaml source, I created a library with the following functions:


exception ScriptError

let eval_script doprint ppf script =
  (* first, create a lexical buffer *)
  let lbuf = Lexing.from_string script in
    try
      let phrase = try !parse_toplevel_phrase lbuf with Exit -> raise
ScriptError in
         if !Clflags.dump_parsetree then Printast.top_phrase ppf phrase;
         ignore(execute_phrase true ppf phrase)
    with
      | End_of_file -> exit 0
      | Sys.Break -> fprintf ppf "Interrupted.@."
      | ScriptError -> ()
      | x -> Errors.report_error ppf x

let init_scripting () =
  Sys.interactive := false;
  Compile.init_path();
  initialize_toplevel_env ()

In this way, I can use Toploop.toplevel_env to store the environment that is
created from evaluating the script. Toploop also has a few other functions
to check the environment, such as:

Toploop.getvalue : str -> Obj.t
and
Toploop.setvalue : str -> Obj.t -> unit

so, all of these allow me to do something like:

let main () =
  (* set up the environment for scripting *)
  init_scripting();
  run_script true Format.std_formatter "let add x y = x + y;;";
  run_script true Format.std_formatter "let x = add 2 3;;"
in
  main () ;;

and this adds a binding to add for the function, and x for the result in
Toploop.toplevel_env.

However, my dilema is this: How can I add my own bindings to Obj.t in
Toploop.toplevel_env
and how can I retrieve values from Obj.t?  Taking a look under the bytecomp
directory under
the source distribution seems to indicate that Obj.t is an abstract type
that represents all types
in bytecode. Does anyone know of a way I can manipulate Obj.t and create my
own bindings
and extract the results?

Thanks for listening (=,
Chris


-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners