OCaml,像 Emacs 一样扩展程序
OCaml, extends a program a la Emacs
我喜欢 OCaml,我正在等待我的 Real World OCaml 副本!
我是一个初学OCaml程序员,只知道functionnal部分,有点命令式,但对模块、函子、对象等了解不多...
对于某种解释器项目,我做了一种类似于新手 emacs 的评估。我保留了一个三元组列表,其中包含作为字符串的命令名称绑定列表、一个用于描述的字符串和要调用的 ocaml 函数。主循环只是在列表中查找匹配的条目并调用函数。
那么添加新功能就非常简单了,您只需编写一个函数并在列表中添加一个条目即可。
我喜欢像 Emacs 一样可自扩展的概念,这很容易扩展,但不是真正的自扩展。
我可以使用 OCaml 使程序自扩展吗?
我该怎么做?
我知道 Emacs 是如何工作的,它是一个很大的虚拟机,所以它自己解释代码并修改它的运行时环境,但是有没有办法通过用户添加的模块向 OCaml 程序添加功能?还是别的?
ps : 如果我的项目听起来很基础,请不要笑我,但我是初学者!
谢谢
Could I make a program self extendable with OCaml?
是的,你可以做一个 self-extensible 解释器。
Is there a way to add functionnalities to an OCaml program with user added modules?
是的,但是。 OCaml 交互式提示就是这样一个可扩展的程序。 MetaOCaml 是 OCaml 的 multi-stage 编程扩展,支持在运行时增量编译新机器代码。 [Wikipedia] 除非你 piggy-back 使用其中之一,您正在查看 non-trivial 工程任务。
How would I do that?
具体取决于你想做什么,你也可以看看OCaml as Scheme or Scheme interpreter in Standard ML。然后你基本上必须构建一个 read-eval-print 循环来解析输入语言并相应地修改你的 three-tuple 。但不能直接使用 OCaml。
另一种解决方案可能是使用 Ocaml dynamic loading facilities, e.g. the Dynlink 模块。例如,每个动态加载的共享模块可以将条目添加到一些全局散列 table 将字符串名称映射到函数(相同类型)等......这个初始化 -运行 它的顶级表达式 -动态加载的模块发生在它的加载时间(当你调用 Dynlink.loadfile
时),有点像 POSIX dlopen
的旧 _init
函数
例如,您可以让您的程序在运行时发出一些 Ocaml 代码;将其编译成一个可加载的动态库 using ocamlopt -shared
;然后 Dynlink.loadfile
那个图书馆。该库的初始化部分将使用主程序中提供的一些适当函数注册闭包。
或者,在 Ocaml 中编写(或使用)一些虚拟机或解释器。
您也可以使用一些 JIT 库,例如Ollvm,并生成一些 C-like 代码(可能在主程序的某些 C 胶代码中使用 dlopen
)。
但作为 ,MetaOcaml 可能是更好的方法。
顺便说一句,也许你想要一些 Common Lisp 实现?
示例:
(未经测试的代码!一些细节可能是错误的)
您的主程序 prog.ml
将包含
let ht = Hashtbl.create 53;;
let add_name_fun (name : string) (f : int -> int) =
Hashtbl.add ht name f;;
(* here you might emit the 'plugin.ml' file and fork its compilation *)
Dynlink.loadfile "plugin.cmxs";;
(* as an example we apply every added name & function to 3 *)
Hashtbl.iter ht (fun n f) -> Printf.printf "n=%s (f 3)=%d\n" n (f 3);;
您的 prog.mli
将包含:
val : add_name_fun : string -> (int -> int) -> unit;;
您的 plugin.ml
将包含
Prog.add_name_fun "foo" (fun x -> x+3);;
但是我没有测试代码。
PS。在 POSIX 系统上,您可以使用 dlopen & dlsym. My GCC MELT is doing that. See also this.
在 C 中执行类似的操作
注意:如果您喜欢 meta-programming 方法,请阅读 J.Pitrat's blog 和书籍。
我喜欢 OCaml,我正在等待我的 Real World OCaml 副本! 我是一个初学OCaml程序员,只知道functionnal部分,有点命令式,但对模块、函子、对象等了解不多...
对于某种解释器项目,我做了一种类似于新手 emacs 的评估。我保留了一个三元组列表,其中包含作为字符串的命令名称绑定列表、一个用于描述的字符串和要调用的 ocaml 函数。主循环只是在列表中查找匹配的条目并调用函数。
那么添加新功能就非常简单了,您只需编写一个函数并在列表中添加一个条目即可。
我喜欢像 Emacs 一样可自扩展的概念,这很容易扩展,但不是真正的自扩展。
我可以使用 OCaml 使程序自扩展吗? 我该怎么做?
我知道 Emacs 是如何工作的,它是一个很大的虚拟机,所以它自己解释代码并修改它的运行时环境,但是有没有办法通过用户添加的模块向 OCaml 程序添加功能?还是别的?
ps : 如果我的项目听起来很基础,请不要笑我,但我是初学者!
谢谢
Could I make a program self extendable with OCaml?
是的,你可以做一个 self-extensible 解释器。
Is there a way to add functionnalities to an OCaml program with user added modules?
是的,但是。 OCaml 交互式提示就是这样一个可扩展的程序。 MetaOCaml 是 OCaml 的 multi-stage 编程扩展,支持在运行时增量编译新机器代码。 [Wikipedia] 除非你 piggy-back 使用其中之一,您正在查看 non-trivial 工程任务。
How would I do that?
具体取决于你想做什么,你也可以看看OCaml as Scheme or Scheme interpreter in Standard ML。然后你基本上必须构建一个 read-eval-print 循环来解析输入语言并相应地修改你的 three-tuple 。但不能直接使用 OCaml。
另一种解决方案可能是使用 Ocaml dynamic loading facilities, e.g. the Dynlink 模块。例如,每个动态加载的共享模块可以将条目添加到一些全局散列 table 将字符串名称映射到函数(相同类型)等......这个初始化 -运行 它的顶级表达式 -动态加载的模块发生在它的加载时间(当你调用 Dynlink.loadfile
时),有点像 POSIX dlopen
_init
函数
例如,您可以让您的程序在运行时发出一些 Ocaml 代码;将其编译成一个可加载的动态库 using ocamlopt -shared
;然后 Dynlink.loadfile
那个图书馆。该库的初始化部分将使用主程序中提供的一些适当函数注册闭包。
或者,在 Ocaml 中编写(或使用)一些虚拟机或解释器。
您也可以使用一些 JIT 库,例如Ollvm,并生成一些 C-like 代码(可能在主程序的某些 C 胶代码中使用 dlopen
)。
但作为
顺便说一句,也许你想要一些 Common Lisp 实现?
示例:
(未经测试的代码!一些细节可能是错误的)
您的主程序 prog.ml
将包含
let ht = Hashtbl.create 53;;
let add_name_fun (name : string) (f : int -> int) =
Hashtbl.add ht name f;;
(* here you might emit the 'plugin.ml' file and fork its compilation *)
Dynlink.loadfile "plugin.cmxs";;
(* as an example we apply every added name & function to 3 *)
Hashtbl.iter ht (fun n f) -> Printf.printf "n=%s (f 3)=%d\n" n (f 3);;
您的 prog.mli
将包含:
val : add_name_fun : string -> (int -> int) -> unit;;
您的 plugin.ml
将包含
Prog.add_name_fun "foo" (fun x -> x+3);;
但是我没有测试代码。
PS。在 POSIX 系统上,您可以使用 dlopen & dlsym. My GCC MELT is doing that. See also this.
在 C 中执行类似的操作注意:如果您喜欢 meta-programming 方法,请阅读 J.Pitrat's blog 和书籍。