Встраивание интерпретатора ocaml

У меня есть небольшой язык, который в основном является расширением OCaml (на самом деле это расширение подмножества OCaml, но это не имеет значения). Для упрощения у меня есть одно «escape-выражение», которое переносит литералы OCaml на мой язык (следовательно, вы можете встраивать произвольный код OCaml в этот язык). Скомпилировать такое выражение в OCaml означало бы просто развернуть строку, но как ее оценить?

Конечно, я понимаю, что OCaml - это язык со статической типизацией, и как эта система типов работает в целом. Следовательно, мне также нужно иметь возможность предоставить среду и проверить предполагаемый тип выражения (или, по крайней мере, справиться с ошибками типа). Я также осознаю необходимость управления состоянием интерпретатора и т. Д. Давайте предположим, что встроенные выражения не имеют побочных эффектов.

Очевидно, это возможно, поскольку и utop, и верхний уровень реализованы в OCaml сами. Итак, моей первой идеей было просто выбрать одну из них и адаптировать под свои нужды. Теперь о моих проблемах:

  • toplevel, очевидно, является частью основного дистрибутива. Хотя существует toplevel.mli с необходимыми функциями и даже .mllib, я не могу найти toplevel как упакованную библиотеку - есть ли дополнительные настройки конфигурации, необходимые для получения "интерпретатора как библиотеки" упаковка?

  • utop, кажется, делает еще более странные вещи. Насколько я могу судить по источникам, он копирует некоторые библиотеки компиляторов в свой исходный каталог во время сборки. Это кажется довольно странным: если он знает во время сборки, как найти эти библиотеки компилятора, почему бы просто не связать?

Итак, есть ли какой-нибудь разумно установленный способ встраивать интерпретатор OCaml в программу OCaml?


person choeger    schedule 14.10.2014    source источник
comment
Не содержит то, что вам нужно, 'compiler-libs.toplevel'?   -  person rafix    schedule 14.10.2014
comment
В самом деле, я не знал точного названия библиотеки. Не могли бы вы дать ответ, чтобы я принял его?   -  person choeger    schedule 14.10.2014
comment
@choeger Я думаю, что это нормально делать самому. (Я не хотел бы красть кредит кармы, но все равно был бы признателен за правильный ответ.)   -  person DomQ    schedule 19.08.2016


Ответы (1)


Самый простой способ, afaik, - скомпилировать предоставленный код в модуль с помощью компилятора байтового кода, а затем загрузить его с помощью dynlink и выполнить. Вы также можете скомпилировать его с помощью собственного компилятора, но это потребует от вас установки.

Обновлять

Вы можете скомпилировать свой файл любым способом, включая команду system, но вы также можете напрямую обращаться к интерфейсу компилятора [1]:

Compile.implementation Format.std_formatter "test.ml" "test";;

Это создаст файлы test.cmo и test.cmi в том же каталоге, что и файл "test.ml". После этого вы можете загрузить его с помощью Dynlink:

Dynlink.loadfile "test.cmo";;

[1] Этот модуль находится где-то в compiler-libs библиотеке, возможно "compiler-libs.bytecomp"

person ivg    schedule 14.10.2014
comment
И какие API-интерфейсы предоставляют эту функциональность? - person choeger; 14.10.2014
comment
Я добавил пример к своему ответу. - person ivg; 14.10.2014