val execute_phrase : bool -> formatter -> Parsetree.toplevel_phrase -> bool (* Execute the given toplevel phrase. Return [true] if the phrase executed with no errors and [false] otherwise. First bool says whether the values and types of the results should be printed. Uncaught exceptions are always printed. *)
(* Hooks for external parsers and printers *)
val parse_toplevel_phrase : (Lexing.lexbuf -> Parsetree.toplevel_phrase) ref
val from_string : string -> lexbuf (** Create a lexer buffer which reads from the given string. Reading starts from the first character in the string. An end-of-input condition is generated when the end of the string is reached. *)
val std_formatter : formatter;; (** The standard formatter used by the formatting functions above. It is defined as [formatter_of_out_channel stdout]. *)
val stdbuf : Buffer.t;; (** The string buffer in which [str_formatter] writes. *)
val str_formatter : formatter;; (** A formatter to use with formatting functions below for output to the [stdbuf] string buffer. [str_formatter] is defined as [formatter_of_buffer stdbuf]. *)
val flush_str_formatter : unit -> string;; (** Returns the material printed with [str_formatter], flushes the formatter and resets the corresponding buffer. *)
ここらへんを使えばよさそう.
ふむ.なにやら道具は揃った感じ.でも使いかたがイマイチわからんので,テキトーに拾ったキーワードでぐぐってみたら,こんなジャストな話題が OCaml の ML :-) で出てた.
John Goerzen asked and Clément Capel answered:
> I am moving from Python to OCaml and one of the things I miss is > Python's eval() call. It takes a string representing a bit of Python > source code, evaluates it, and returns the result. I would like to be > able to do similar things with OCaml. > > I have observed that /usr/bin/ocaml, the interactive top-level, is > itself written in OCaml, which suggests that this should be possible. > Although I have tried to study the source for this, it seems extremely > complex and I can't figure out a way to do the simple evaluation > described above. > > Can anyone help me out here?
Try this simple example:
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;;
eval "let add1 x = x +1;;";; eval "add1 2;;";;
(compile with toplevellib.cma)
But be careful, it can break the typing system. if you use the Toploop module in the "string parameter" of the function eval or if you evaluate it in the toplevel. But it seems there's a guard with the new version (3.07+2).
Dynamically evaluating OCaml code John Goerzen asked and Basile Starynkevitch answered:
> I am moving from Python to OCaml and one of the things I miss is > Python's eval() call. It takes a string representing a bit of Python > source code, evaluates it, and returns the result. I would like to be > able to do similar things with OCaml.
As observed by others, there is a big typing issue around this (what would be the type of the eval function)?
If you really need something, you could hack the toplevel (at your own risk). I don't think it is a good idea, unless you did very well understood what you really want to do.
However, the functional values are usually enough to avoid the "eval", and an "eval" won't be really safe.
Also, you could use metaocaml, which provide constructs (inspired by eval) to typefully meta-program, ie generate programs at runtime in a rather safe manner.
dynamics (like old work from Leroy & Mauny - see X.Leroy's publication pages on http://cristal.inria.fr/~xleroy ) and runtime type information (like in Jun Furse GCaml) might also help - and are in some remote way a bit related to eval's typing.
In addition to typing issues, there is also a runtime issue: dynamic code generation really requires garbage collection of executable code, which is not available in Ocaml (and would be terrible to implement - it would mean rewrite most of the system)
あと,何やら興味深げ.今ちょっと時間が無いから,後で読む.
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"
Issac Trotts asked and Basile Starynkevitch answered:
Issac Trotts wrote: > 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
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.
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.
なんか,起動した時に,一瞬もたつくのが気になる.OCaml に特有の現象なのか,俺のコードが葛すぎるのかは今後の調査が待たれるところです (他人事) たぶん,(show_all 相当の API が見付からなかったんだけど),ウィジットが作られるたびに show されてるから,一瞬残像が残るのだろうと思う (普通は,全部オブジェクト作ってから show するんだけど… lablgtk の API がよーわからんのじゃ).
今回はガワだけしか作ってません.ボタンを押すと,新しいバッファが開くだけ.まだ何も実用的な機能は実装されていません.まぁ,サンプルコードが Web 上に少な過ぎるので,こういうのをちょこちょこ公開してみるだけでも,微妙に誰かの役に立つかもしれないし,誰も興味を持たないかもしれない (OCaml,Gtk,なおかつ資料が少ない独自 API というマイナー三重苦 !厳しすぎる !!)
5) For custom linking or native code, you need to use the export libraries in the above DLL package. There is not default place to put them, so you should specify that at link time: ocamlopt -ccopt "/link /libpath:/home/garrigue/gtk-2.6.8/lib" -I +lablgtk2 lablgtk.cmxa gtkInit.cmx testgtk.ml -o testgtk.exe or, on Mingw ocamlopt -ccopt "-L/home/garrigue/gtk-2.6.8/lib" -I +lablgtk2 \ lablgtk.cmxa gtkInit.cmx testgtk.ml -o testgtk.exe Again, if this fails you must make sure that your ocamlopt really works, and that all paths are correctly specified.
let main () = let window = GWindow.window ~border_width: 15 () in let button = GButton.button ~label:"hello, world!" ~packing: window#add () in window#connect#destroy ~callback:Main.quit; button#connect#clicked ~callback:window#destroy; window#show (); Main.main ()
let _ = Printexc.print main ()
いや,ML の M の字も知らない子なんで,文法とかはよくわからんのだけど (サンプルを書き換えて短くしただけ.というか,本家よりもサンプルコードが豊富なような.examples 以下にいっぱいあります).
とりあえず,ローカル変数が使いたかったら, let 変数 = 式 in と書けば良いということはわかった (笑) 再帰的定義がしたかったら,let rec 変数 = 式 わかりやすいのう.
Do *not* install the Mingw/MSYS development tools from www.mingw.org: these are not compatible with this Caml port (@responsefile not recognized on the command line).