Version française
Home     About     Download     Resources     Contact us    
Browse thread
[Caml-list] Dynamically evaluating OCaml code
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Issac Trotts <ijtrotts@u...>
Subject: Re: [Caml-list] Dynamically evaluating OCaml code
On Thu, Apr 08, 2004 at 09:10:38AM +0200, Basile Starynkevitch wrote:
> On Thu, Jan 03, 2002 at 04:43:56PM -0800, Issac Trotts wrote:
> > On Wed, Apr 07, 2004 at 11:05:24PM +0200, Basile Starynkevitch wrote:
> 
> > > However, for the beginner, the good answer (at least as given by Ocaml
> > > gurus here) to the usual "I want eval" request is simply "no you don't
> > > really need it"
> > 
> > That being so, how would you use OCaml as an extension language for a C
> > program?  
> 
> I'm not sure to understand your point. Many applications coded in C
> embed Ocaml inside. The simplest way is to give the application a
> compiled ocaml bytecode file (which can be choosen at runtime) invoked
> thru ocaml_main
> 
> See section 18.7.4 Main program in C of
> http://caml.inria.fr/ocaml/htmlman/manual032.html

OK, please see below.

> An alternative is to have the application being a custum ocaml
> program, with lots of C primitives. This means that the ocaml runtime
> system has the control and invoke appropriately the C primitives
> provided by the application.

This won't do what I have in mind.  I would like to run arbitrary OCaml
code strings, given by the user, from within a C program.

> If you ask about embedding the ocaml toplevel into your application,
> it is a different question. I agree that extending or embedding or
> customizing the toplevel is not very well documented.

Below is the listing of what I tried.  It gave this error:

Initializing Caml code...
Fatal error: exception Sys_error(": No such file or directory")

As far as I can tell, the error is coming from Env.read_pers_struct
in ocaml-3.07/typing/.  

=== Makefile ===
CFLAGS=-I $(OCAML)
objects:=cmcaml.o cmstub.o cmmain.o
cced: $(objects)
	gcc -o $@ $(objects) -L $(OCAML) -lcamlrun -lm -ldl -ltermcap
cmcaml.o: cmcaml.ml
	ocamlc -g -output-obj -o cmcaml.o toplevellib.cma cmcaml.ml 
clean:
	rm -f *.o *.cmo *.cmi cced

=== cmcaml.ml ===
(* Caml part of the code *)

Toploop.initialize_toplevel_env();;
                                                                                
let eval txt = 
    let lb = (Lexing.from_string txt) in
    let phr = !Toploop.parse_toplevel_phrase lb in
    Toploop.execute_phrase true Format.std_formatter phr;;

(* Registration *)
let _ = Callback.register "eval" eval;;
 
=== cmmain.c ===
/* Based on cmmain.c in ocaml-3.07/test/Moretest */

#include <stdio.h>
#include <stdlib.h>
#include <caml/callback.h>

extern void eval(char const * code);

int main(int argc, char ** argv)
{
    printf("Initializing Caml code...\n");
    caml_startup(argv);
    printf("Back in C code...\n");
    while(1) {
        char buf[80*40];
        fprintf(stderr,"> ");
        if(fgets(buf,sizeof(buf)-1,stdin)==NULL) {
            break; 
        }
        eval(buf);
    }
    return 0;
}

=== cmstub.c ===
#include <string.h>
#include <caml/mlvalues.h>
#include <caml/callback.h>

/* Oops, this should be called exec. */
void eval(char const * str)
{
  value * closure = caml_named_value("eval");
  (void) callback(*closure, copy_string(str)); /* leaky? */
}

--
Issac Trotts
http://mallorn.ucdavis.edu/~ijtrotts
(w) 530-757-8789

-------------------
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