我希望在我的OCaml输入文件的开头有几行代码,让toplevel始终记住上次输入的表达式,名称为
it
。 也就是说,我想要如下代码:# 3 + 4;;
val it : int = 7
# it;;
val it : int = 7
# let foo = 42;;
val foo : int = 42
# it + 130;;
val it : int = 137
#
但我不想建立一个自定义的顶层或使用camlp5或任何花哨的东西。
目前我在做什么(在OCaml版本4.02.3中,我不知道为什么我有那个版本; 但我希望确切的版本并不重要?)是以下内容:
#directory "+compiler-libs";;
#load "/opt/src/ocaml-4.02.3/utils/warnings.cmo";;
#load "/opt/src/ocaml-4.02.3/parsing/location.cmo";;
let convert_phrase x =
match x with
| Parsetree.Ptop_def
[{Parsetree.pstr_desc = Parsetree.Pstr_eval (e, a)}] ->
Parsetree.Ptop_def
([{Parsetree.pstr_desc =
Parsetree.Pstr_value (Asttypes.Nonrecursive,
[{Parsetree.pvb_pat =
{Parsetree.ppat_desc =
Parsetree.Ppat_var (Location.mknoloc "it");
Parsetree.ppat_loc = Location.none;
Parsetree.ppat_attributes = []};
Parsetree.pvb_expr = e;
Parsetree.pvb_attributes = a;
Parsetree.pvb_loc = Location.none}]);
Parsetree.pstr_loc = Location.none}])
| x -> x;;
Toploop.parse_toplevel_phrase :=
let parse_toplevel_phrase = !Toploop.parse_toplevel_phrase in
fun x -> convert_phrase (parse_toplevel_phrase x);;
这种方法似乎行得通。
我的问题是:如果我只执行#directory "+compiler-libs";;
,我可以访问Toploop
和Parsetree
模块,但我无法访问Location
模块!原因是什么?我觉得从我的源目录加载.cmo
文件非常不方便。
那么,有没有一种方法可以实现我想要的,而不需要拥有源代码树?
换句话说:为什么在这方面会有Toploop
和Location
之间的区别呢?
Parsetree.Ptop_def
是被允许的。这就是为什么我错过了Toploop
和Parsetree
之间的区别。再次感谢您的答复和进一步的澄清。 - Freek Wiedijk