2016-05-20 1 views
3

Я хотел бы иметь несколько строк кода в начале моего входного файла OCaml, чтобы иметь в памяти весь последний символ, набранный все время под именем it. Т.е., я хочу иметь:Открытие модулей из компилятора OCaml без создания пользовательского toplevel

# 3 + 4;; 
val it : int = 7 
# it;; 
val it : int = 7 
# let foo = 42;; 
val foo : int = 42 
# it + 130;; 
val it : int = 137 
# 

Но я не хотите построить собственный TopLevel или использовать 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, в этом отношении?

ответ

8

Короче говоря, вы должны загрузить это не отдельные файлы, но .cmo

#load "ocamlcommon.cma";; 

, который находится в +compiler-libs каталоге.

Различия между Parsetree, Toploop и Location тонкие ...

В OCaml, типы данных и их конструкторы становятся доступными только при добавлении его каталог к ​​пути загрузки (по #directory "<dir>"). Для них не требуется загрузка объектного кода (на #load).

Parsetree так называемый «только модуль mli»: он имеет только определения типа данных и не определены значения. Поэтому все в Parsetree доступно только путем помещения его в путь загрузки.

Location определяет типы и значения. Его типы данных и конструкторы доступны без загрузки объектного файла, но значения требуют загрузки. В этом случае объект location.cmo загружается при загрузке ocamlcommon.cma, который архивирует его.

Toploop является сложной задачей. Вы можете получить доступ к значениям Toploop даже без загрузки toploop.cmo, так как Toploop связан и уже доступен в OCaml toplevel.

+0

Спасибо за отличный ответ! Это полностью решило мою проблему. –

+1

Мое замешательство заключалось в том, что в качестве пользователя Coq я думаю о конструкторах и функциях как о подобных вещах, а 'Parsetree.Ptop_def' * разрешен. Вот почему я пропустил разницу между «Toploop» и «Parsetree». Еще раз спасибо за ответ и за дальнейшие разъяснения. –

 Смежные вопросы

  • Нет связанных вопросов^_^