Глава 14 Система верхнего уровня или REPL (ocaml)
- 14.1 Параметры
- 14.2 Директивы верхнего уровня
- 14.3 Система верхнего уровня и система модулей
- 14.4 Распространённые ошибки
- 14.5 Создание пользовательских систем верхнего уровня: ocamlmktop
- 14.6 Система верхнего уровня для нативного кода: ocamlnat (экспериментальная)
В этой главе описывается система верхнего уровня OCaml, позволяющая взаимодействовать с системой OCaml интерактивно через цикл чтения-вычисления-печати (REPL). В этом режиме система многократно считывает фразы OCaml из входного потока, затем выполняет проверку типов, компиляцию и вычисление, затем выводит выведенный тип и значение результата, если таковое имеется. Система выводит приглашение # (решётка) перед чтением каждой фразы.
Входные данные в систему верхнего уровня могут занимать несколько строк. Они завершаются ;; (двойной точкой с запятой). Ввод системы верхнего уровня состоит из одной или нескольких фраз верхнего уровня со следующим синтаксисом:
|
Фраза может состоять из определения, подобного тем, которые встречаются в реализациях единиц компиляции или в выражениях модулей struct … end. Определение может связывать имена значений, имена типов, исключения, имена модулей или имена типов модулей. Система верхнего уровня выполняет привязку, затем выводит типы и значения (если таковые имеются) для определённых таким образом имён.
Фраза также может состоять из выражения значения (раздел 11.7). Оно просто вычисляется без выполнения каких-либо привязок, и его значение выводится.
Наконец, фраза также может состоять из директивы верхнего уровня, начинающейся со знака # (решётка). Эти директивы контролируют поведение системы верхнего уровня; они перечислены ниже в разделе 14.2.
Unix: Система верхнего уровня запускается командой ocaml следующим образом:ocaml options objects # interactive mode ocaml options objects scriptfile # script modeпараметры описаны ниже. объекты — это имена файлов, заканчивающиеся на .cmo или .cma; они загружаются в интерпретатор сразу после того, как будут заданы параметры. сценарий — это любое имя файла, не заканчивающееся на .cmo или .cma.Если сценарий не задан в командной строке, система верхнего уровня переходит в интерактивный режим: фразы считываются со стандартного ввода, результаты выводятся на стандартный вывод, ошибки — на стандартный поток ошибок. Конец файла на стандартном вводе завершает ocaml (см. также директиву #quit в разделе 14.2).
При запуске (до считывания первой фразы), если файл .ocamlinit существует в текущем каталоге, его содержимое считывается как последовательность фраз OCaml и выполняется в соответствии с директивой #use, описанной в разделе 14.2. Коды ошибок вычисления каждой фразы не отображаются. Если в текущем каталоге нет файла .ocamlinit, ищется файл XDG_CONFIG_HOME/ocaml/init.ml в соответствии со спецификацией XDG, и используется вместо него (в Windows это пропускается). Если этот файл не существует, используется файл [.ocamlinit] в домашнем каталоге пользователя (определяется переменной окружения HOME), если он существует.
Система верхнего уровня не выполняет редактирование строк, но её можно легко использовать совместно с внешним редактором строк, например, ledit или rlwrap. Также доступен улучшенный верхний уровень, utop. Другой вариант — использовать ocaml под Gnu Emacs, что даёт все возможности редактирования Emacs (команда run-caml из библиотеки inf-caml).
В любой момент процесс разбора, компиляции или вычисления текущей фразы можно прервать, нажав ctrl-C (или, точнее, отправив сигнал INTR процессу ocaml). Затем система верхнего уровня немедленно возвращается к приглашению #.
Если сценарий задан в командной строке для ocaml, система верхнего уровня переходит в режим сценария: содержимое файла считывается как последовательность фраз OCaml и выполняется в соответствии с директивой #use (раздел 14.2). Результат вычисления не выводится. При достижении конца файла команда ocaml завершается немедленно. Команды не считываются со стандартного ввода. Sys.argv преобразуется, игнорируя все параметры OCaml, и начинается с имени файла сценария в Sys.argv.(0).
В режиме сценария первая строка сценария игнорируется, если она начинается с #!. Таким образом, сценарий должен быть исполняемым и иметь в первой строке #!/usr/local/bin/ocaml, вызывая систему верхнего уровня автоматически при запуске сценария. Однако ocaml сам является сценарием #! на большинстве установок OCaml, и ядра Unix обычно не обрабатывают вложенные сценарии #!. Лучшее решение — поместить следующее в первую строку сценария:
#!/usr/local/bin/ocamlrun /usr/local/bin/ocaml
14.1 Параметры
Следующие параметры командной строки распознаются командой ocaml.
- -absname
- Выводить сообщения об ошибках с абсолютными путями к файлам.
- -args filename
- Читать дополнительные аргументы командной строки, завершённые символом новой строки, из файла filename. Передавать файл scriptfile в качестве аргумента невозможно.
- -args0 filename
- Читать дополнительные аргументы командной строки, завершённые нулевым символом, из файла filename. Передавать файл scriptfile в качестве аргумента невозможно.
- -I directory
- Добавить указанный каталог в список каталогов, проверяемых при поиске исходных и скомпилированных файлов. По умолчанию, сначала проверяется текущий каталог, затем каталог стандартной библиотеки. Каталоги, добавленные с помощью -I, проверяются после текущего каталога в порядке их указания в командной строке, но перед каталогом стандартной библиотеки. См. также опцию -nostdlib.
Если указанный каталог начинается с +, он считается относительным к каталогу стандартной библиотеки. Например, -I +unix добавляет подкаталог unix стандартной библиотеки в путь поиска.
Каталоги также могут быть добавлены в список после запуска toplevel с директивой #directory (раздел 14.2).
- -init file
- Загрузить указанный файл вместо файла инициализации по умолчанию. Файл по умолчанию — .ocamlinit в текущем каталоге, если он существует, в противном случае — XDG_CONFIG_HOME/ocaml/init.ml или .ocamlinit в домашнем каталоге пользователя.
- -labels
- Метки не игнорируются в типах, метки могут использоваться в приложениях, а помеченные параметры могут быть заданы в любом порядке. Это значение по умолчанию.
- -no-app-funct
- Деактивирует прикладное поведение функторов. С этой опцией каждое применение функтора генерирует новые типы в результате, и применение одного и того же функтора дважды к одному и тому же аргументу даёт две несовместимые структуры.
- -noassert
- Не компилировать проверки утверждений. Обратите внимание, что специальная форма assert false всегда компилируется, поскольку она имеет специальный тип.
- -nolabels
- Игнорировать необязательные метки в типах. Метки не могут использоваться в приложениях, и порядок параметров становится строгим.
- -noprompt
- Не отображать приглашение при ожидании ввода.
- -nopromptcont
- Не отображать дополнительное приглашение при ожидании продолжения ввода многострочных данных. Это следует использовать, например, при запуске ocaml в окне emacs.
- -nostdlib
- Не включать каталог стандартной библиотеки в список каталогов, проверяемых при поиске исходных и скомпилированных файлов.
- -ppx command
- После парсинга перенаправить абстрактное синтаксическое дерево через препроцессор command. Модуль Ast_mapper, описанный в главе 29: Ast_mapper , реализует внешний интерфейс препроцессора.
- -principal
- Проверять путь информации во время проверки типов, чтобы убедиться, что все типы получены главным образом. При использовании помеченных аргументов и/или полиморфных методов этот флаг необходим для обеспечения того, что будущие версии компилятора смогут правильно выводить типы, даже если внутренние алгоритмы изменятся. Все программы, принятые в режиме -principal, также принимаются в режиме по умолчанию с эквивалентными типами, но различными бинарными сигнатурами, и это может замедлить проверку типов; тем не менее, рекомендуется использовать его один раз перед публикацией исходного кода.
- -rectypes
- Разрешить произвольные рекурсивные типы во время проверки типов. По умолчанию поддерживаются только рекурсивные типы, где рекурсия проходит через тип объекта.
- -safe-string
- Обеспечить разделение типов string и bytes, сделав строки неизменяемыми. Это значение по умолчанию и применяется с OCaml 5.0.
- -short-paths
- Когда тип виден по нескольким путям модулей, использовать самый короткий путь при печати имени типа в выведенных интерфейсах и сообщениях об ошибках и предупреждениях. Имена идентификаторов, начинающиеся с нижнего подчеркивания _ или содержащие двойные нижние подчеркивания __, увеличивают длину на +10 при вычислении длины.
- -stdin
- Читать стандартный ввод как файл сценария вместо запуска интерактивной сессии.
- -strict-sequence
- Принудительно задать тип левой части каждой последовательности как unit.
- -strict-formats
- Отклонять недопустимые форматы, которые допускались в старых реализациях форматов. Необходимо использовать этот флаг для обнаружения и исправления таких недопустимых форматов, поскольку они будут отклоняться будущими версиями OCaml.
- -unsafe
- Отключить проверку границ для доступа к массивам и строкам (v.(i) и s.[i] конструкции). Программы, скомпилированные с -unsafe, поэтому быстрее, но небезопасны: может произойти что угодно, если программа обращается к массиву или строке за пределами его границ.
- -unsafe-string
- Идентифицировать типы string и bytes, сделав строки изменяемыми. Это предназначено для совместимости со старым исходным кодом и не должно использоваться с новым программным обеспечением. Эта опция возвращает ошибку безоговорочно с OCaml 5.0.
- -v
- Вывести номер версии компилятора и расположение каталога стандартной библиотеки, затем завершить работу.
- -verbose
- Вывести все внешние команды перед их выполнением. Полезно для отладки проблем с библиотеками C.
- -version
- Вывести строку версии и завершить работу.
- -vnum
- Вывести короткий номер версии и завершить работу.
- -no-version
- Не выводить баннер версии при запуске.
- -w warning-list
- Включить, отключить или пометить как критическое предупреждения, указанные в аргументе warning-list. Каждое предупреждение может быть включено или выключено, и каждое предупреждение может быть критическим или некритическим. Если предупреждение отключено, оно не отображается и никак не влияет на компиляцию (даже если оно критическое). Если предупреждение включено, оно обычно отображается компилятором всякий раз, когда исходный код его вызывает. Если оно включено и критическое, компилятор также остановится с ошибкой после его отображения.
Аргумент warning-list представляет собой последовательность спецификаторов предупреждений без разделителей между ними. Спецификатор предупреждения — это одно из следующего:
- +num
- Включить предупреждение номер num.
- -num
- Отключить предупреждение номер num.
- @num
- Включить и пометить как критическое предупреждение номер num.
- +num1..num2
- Включить предупреждения в заданном диапазоне.
- -num1..num2
- Отключить предупреждения в заданном диапазоне.
- @num1..num2
- Включить и пометить как критическое предупреждения в заданном диапазоне.
- +letter
- Включить набор предупреждений, соответствующих letter. Буква может быть заглавной или строчной.
- -letter
- Отключить набор предупреждений, соответствующих letter. Буква может быть заглавной или строчной.
- @letter
- Включить и пометить как критическое набор предупреждений, соответствующих letter. Буква может быть заглавной или строчной.
- uppercase-letter
- Включить набор предупреждений, соответствующих uppercase-letter.
- lowercase-letter
- Отключить набор предупреждений, соответствующих lowercase-letter.
В качестве альтернативы, warning-list может указать одно предупреждение по его мнемоническому имени (см. ниже), следующим образом:
- +name
- Включить предупреждение name.
- -name
- Отключить предупреждение name.
- @name
- Включить и пометить как критическое предупреждение name.
Номера предупреждений, буквы и имена, которые в настоящее время не определены, игнорируются. Предупреждения следующие (имя после каждого номера указывает мнемонику для данного предупреждения).
- 1 comment-start
- Подозрительная метка начала комментария.
- 2 comment-not-end
- Подозрительная метка конца комментария.
- 3
- Устаревший синоним предупреждения ’устаревший’.
- 4 fragile-match
- Хрупкое сопоставление шаблонов: сопоставление, которое останется полным, даже если к одному из типов вариантов, с которыми производится сопоставление, будут добавлены дополнительные конструкторы.
- 5 ignored-partial-application
- Частично применённая функция: выражение, результат которого имеет тип функции, и которое игнорируется.
- 6 labels-omitted
- Метка опущена в применении функции.
- 7 method-override
- Метод переопределён.
- 8 partial-match
- Частичное сопоставление: недостающие случаи в сопоставлении по образцу.
- 9 missing-record-field-pattern
- Отсутствующие поля в образце записи.
- 10 non-unit-statement
- Выражение в левой части последовательности, у которого нет типа unit (и которое не является функцией, см. предупреждение номер 5).
- 11 redundant-case
- Избыточный случай в сопоставлении по образцу (неиспользуемый случай сопоставления).
- 12 redundant-subpat
- Избыточный подшаблон в сопоставлении по образцу.
- 13 instance-variable-override
- Переменная экземпляра переопределена.
- 14 illegal-backslash
- Недопустимый обратный слэш в строковой константе.
- 15 implicit-public-methods
- Приватный метод неявно сделан публичным.
- 16 unerasable-optional-argument
- Нельзя удалить необязательный аргумент.
- 17 undeclared-virtual-method
- Необъявленный виртуальный метод.
- 18 not-principal
- Неглавный тип.
- 19 non-principal-labels
- Тип без главного типа.
- 20 ignored-extra-argument
- Неиспользуемый аргумент функции.
- 21 nonreturning-statement
- Невозвращающее выражение.
- 22 preprocessor
- Предупреждение препроцессора.
- 23 useless-record-with
- Бесполезная запись with фрагмента.
- 24 bad-module-name
- Неправильное имя модуля: имя файла исходного кода не является допустимым именем модуля OCaml.
- 25
- Игнорируется: теперь часть предупреждения 8.
- 26 unused-var
- Подозрительная неиспользуемая переменная: неиспользуемая переменная, связанная с let или as, и не начинающаяся с символа подчёркивания (_).
- 27 unused-var-strict
- Незначительная неиспользуемая переменная: неиспользуемая переменная, не связанная с let или as, и не начинающаяся с символа подчёркивания (_).
- 28 wildcard-arg-to-constant-constr
- Дикий символ-аргумент константного конструктора.
- 29 eol-in-string
- Неэкранированный конец строки в строковой константе (непереносимый код).
- 30 duplicate-definitions
- Два метки или конструктора с одинаковым именем определены в двух взаимно рекурсивных типах.
- 31 module-linked-twice
- Модуль подключается дважды в одном исполняемом файле. (с версии 4.00)
- 32 unused-value-declaration
- Неиспользуемое объявление значения. (с версии 4.00)
- 33 unused-open
- Неиспользуемое оператор открытие. (с версии 4.00)
- 34 unused-type-declaration
- Неиспользуемое объявление типа. (с версии 4.00)
- 35 unused-for-index
- Неиспользуемый индекс цикла for. (с версии 4.00)
- 36 unused-ancestor
- Неиспользуемый предковый элемент. (с версии 4.00)
- 37 unused-constructor
- Неиспользуемый конструктор. (с версии 4.00)
- 38 unused-extension
- Неиспользуемый расширяющий конструктор. (с версии 4.00)
- 39 unused-rec-flag
- Неиспользуемый флаг rec. (с версии 4.00)
- 40 name-out-of-scope
- Имя конструктора или метки используется вне области видимости. (с версии 4.01)
- 41 ambiguous-name
- Неоднозначное имя конструктора или метки. (с версии 4.01)
- 42 disambiguated-name
- Разрешение неоднозначности имени конструктора или метки (предупреждение совместимости). (с версии 4.01)
- 43 nonoptional-label
- Необязательная метка применена как необязательная. (с версии 4.01)
- 44 open-shadow-identifier
- Оператор open затеняет уже определённый идентификатор. (с версии 4.01)
- 45 open-shadow-label-constructor
- Оператор open затеняет уже определённую метку или конструктор. (с версии 4.01)
- 46 bad-env-variable
- Ошибка в переменной окружения. (с версии 4.01)
- 47 attribute-payload
- Недопустимая нагрузка атрибута. (с версии 4.02)
- 48 eliminated-optional-arguments
- Неявное удаление необязательных аргументов. (с версии 4.02)
- 49 no-cmi-file
- Отсутствует файл cmi при поиске псевдонима модуля. (с версии 4.02)
- 50 unexpected-docstring
- Неожиданный комментарий документации. (с версии 4.03)
- 51 wrong-tailcall-expectation
- Вызов функции с некорректным атрибутом @tailcall. (с версии 4.03)
- 52 fragile-literal-pattern (см. 13.5.3)
- Хрупкий шаблон константы. (с версии 4.03)
- 53 misplaced-attribute
- Атрибут не может быть использован в данном контексте. (с версии 4.03)
- 54 duplicated-attribute
- Атрибут используется более одного раза в выражении. (с версии 4.03)
- 55 inlining-impossible
- Вставка невозможна. (с версии 4.03)
- 56 unreachable-case
- Недостижимый случай в сопоставлении с образцом (на основе информации о типе). (с версии 4.03)
- 57 ambiguous-var-in-pattern-guard (см. 13.5.4)
- Размытые переменные в шаблонах с условием. (с версии 4.03)
- 58 no-cmx-file
- Отсутствует файл cmx. (с версии 4.03)
- 59 flambda-assignment-to-non-mutable-value
- Присваивание неизменяемому значению. (с версии 4.03)
- 60 unused-module
- Неиспользуемое объявление модуля. (с версии 4.04)
- 61 unboxable-type-in-prim-decl
- Нераспаковываемый тип в примитивном объявлении. (с версии 4.04)
- 62 constraint-on-gadt
- Ограничение типа на GADT. (с версии 4.06)
- 63 erroneous-printed-signature
- Ошибочная напечатанная сигнатура. (с версии 4.08)
- 64 unsafe-array-syntax-without-parsing
- -unsafe используется с препроцессором, возвращающим дерево синтаксического анализа. (с версии 4.08)
- 65 redefining-unit
- Объявление типа, определяющее новый конструктор ’()’. (с версии 4.08)
- 66 unused-open-bang
- Неиспользуемое утверждение open!. (с версии 4.08)
- 67 unused-functor-parameter
- Неиспользуемый параметр функтора. (с версии 4.10)
- 68 match-on-mutable-state-prevent-uncurry
- Сопоставление с образцом, зависящее от изменяемого состояния, препятствует развёртыванию оставшихся аргументов. (с версии 4.12)
- 69 unused-field
- Неиспользуемое поле записи. (с версии 4.13)
- 70 missing-mli
- Отсутствует интерфейсный файл. (с версии 4.13)
- 71 unused-tmc-attribute
- Неиспользуемый атрибут @tail_mod_cons. (с версии 4.14)
- 72 tmc-breaks-tailcall
- Вызов хвостовой рекурсии превращён в не хвостовой вызов преобразованием @tail_mod_cons. (с версии 4.14)
- A
- все предупреждения
- C
- предупреждения 1, 2.
- D
- Псевдоним для предупреждения 3.
- E
- Псевдоним для предупреждения 4.
- F
- Псевдоним для предупреждения 5.
- K
- предупреждения 32, 33, 34, 35, 36, 37, 38, 39.
- L
- Псевдоним для предупреждения 6.
- M
- Псевдоним для предупреждения 7.
- P
- Псевдоним для предупреждения 8.
- R
- Псевдоним для предупреждения 9.
- S
- Псевдоним для предупреждения 10.
- U
- предупреждения 11, 12.
- V
- Псевдоним для предупреждения 13.
- X
- предупреждения 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 30.
- Y
- Псевдоним для предупреждения 26.
- Z
- Псевдоним для предупреждения 27.
Значение по умолчанию — -w +a-4-6-7-9-27-29-32..42-44-45-48-50-60. Оно отображается командой -help. Обратите внимание, что предупреждения 5 и 10 не всегда срабатывают, в зависимости от внутренней работы проверяющего типов.
- -warn-error warning-list
- Отмечает как фатальные предупреждения, указанные в аргументе warning-list. Компилятор остановится с ошибкой, когда будет выведено одно из этих предупреждений. warning-list имеет тот же смысл, что и для опции -w: знак + (или заглавная буква) отмечает соответствующие предупреждения как фатальные, знак - (или строчная буква) возвращает их к нефатальным предупреждениям, а знак @ как включает, так и отмечает соответствующие предупреждения как фатальные.
Примечание: не рекомендуется использовать наборы предупреждений (т.е. буквы) в качестве аргументов для -warn-error в производственном коде, поскольку это может нарушить сборку при добавлении новых предупреждений в будущих версиях OCaml.
Значение по умолчанию — -warn-error -a+31 (только предупреждение 31 является фатальным).
- -warn-help
- Отобразить описание всех доступных номеров предупреждений.
- - file
- Использовать file в качестве имени файла скрипта, даже если оно начинается с дефиса (-).
- -help or --help
- Отобразить краткое руководство по использованию и выйти.
Unix: Следующие переменные среды также используются:
- OCAMLTOP_INCLUDE_PATH
- Дополнительные каталоги для поиска файлов скомпилированного объектного кода (.cmi, .cmo и .cma). Указанные каталоги рассматриваются слева направо после того, как были обработаны каталоги включения, указанные в командной строке через -I. Доступно начиная с OCaml 4.08.
- OCAMLTOP_UTF_8
- При печати значений строк, байты, не являющиеся ASCII ( > \0x7E ), выводятся в виде десятичного escape-последовательности, если OCAMLTOP_UTF_8 установлено в false. В противном случае, они выводятся без escape-последовательности.
- TERM
- При выводе сообщений об ошибках, система toplevel пытается визуально подчеркнуть местоположение ошибки. Она использует переменную TERM для определения типа терминала вывода и поиска его возможностей в базе данных терминалов.
- XDG_CONFIG_HOME, HOME
- Процедура поиска .ocamlinit (см. выше).
14.2 Директивы toplevel
Следующие директивы управляют поведением toplevel, загрузкой файлов в память и отслеживанием выполнения программы.
Примечание: все директивы начинаются с символа # (sharp). Этот # должен быть набран перед директивой и не должен быть перепутано с приглашением #, отображаемым интерактивной петлей. Например, ввод #quit;; завершит цикл toplevel, но ввод quit;; приведет к ошибке «неизвестное значение quit».
- Общие
-
- #help;;
- Выводит список всех доступных директив, а также соответствующий тип аргумента, если применимо.
- #quit;;
- Выход из цикла верхнего уровня и завершение команды ocaml.
- Загрузка кода
-
- #cd "имя_каталога";;
- Изменение текущей рабочей директории.
- #directory "имя_каталога";;
- Добавление указанной директории в список директорий, которые проверяются при поиске исходных и скомпилированных файлов.
- #remove_directory "имя_каталога";;
- Удаление указанной директории из списка директорий, которые проверяются при поиске исходных и скомпилированных файлов. Не делает ничего, если директория в списке отсутствует.
- #load "имя_файла";;
- Загрузка в память файла байткода (.cmo файл) или библиотечного файла (.cma файл), сгенерированного пакетным компилятором ocamlc.
- #load_rec "имя_файла";;
- Загрузка в память файла байткода (.cmo файл) или библиотечного файла (.cma файл), сгенерированного пакетным компилятором ocamlc. При загрузке файла объекта, который зависит от других модулей, которые еще не загружены, файлы .cmo для этих модулей также ищутся и загружаются рекурсивно. Порядок загрузки не определен.
- #use "имя_файла";;
- Чтение, компиляция и выполнение исходных фраз из заданного файла. Это текстовая вставка: фразы обрабатываются так же, как если бы они были введены со стандартного ввода. Чтение файла прекращается при первой встреченной ошибке.
- #use_output "команда";;
- Выполнение команды и оценка ее результата как если бы она была записана в файл и передана в #use.
- #mod_use "имя_файла";;
- Аналогично #use, но также обертывает код в модуль верхнего уровня с тем же именем, что и имя файла без расширения, используя семантику компилятора.
Для директив, принимающих имена файлов в качестве аргументов, если в имени файла не указана директория, файл ищется в следующих директориях:
- В режиме скрипта - в директории, содержащей выполняемый скрипт; в интерактивном режиме - в текущей рабочей директории.
- Директории, добавленные с помощью директивы #directory.
- Директории, заданные в командной строке с помощью опций -I.
- Директория стандартной библиотеки.
- Запросы к среде
-
- #show_class путь_класса;;
- #show_class_type путь_класса;;
- #show_exception идентификатор;;
- #show_module путь_модуля;;
- #show_module_type путь_типа_модуля;;
- #show_type тип_константы;;
- #show_val путь_значения;;
- Вывод сигнатуры соответствующего компонента.
- #show идентификатор;;
- Вывод сигнатур компонентов с именем идентификатор во всех вышеперечисленных категориях.
- Красивая печать
-
- #install_printer имя_печаталки;;
- Эта директива регистрирует функцию с именем имя_печаталки (путь к значению) как печатающую функцию для значений, типы которых совпадают с типом аргумента функции. То есть, цикл верхнего уровня вызовет имя_печаталки, когда будет нужно напечатать такое значение.
- #print_depth n;;
- Ограничение печати значений максимальной глубиной n. Части значений, глубина которых превышает n, выводятся как ... (многоточие).
- #print_length n;;
- Ограничение числа печатаемых узлов значения до n максимального. Остальные части значений выводятся как ... (многоточие).
- #remove_printer имя_печаталки;;
- Удаление указанной функции из таблицы печатающих функций верхнего уровня.
- Отслеживание
-
- #trace имя_функции;;
- После выполнения этой директивы все вызовы функции с именем имя_функции будут отслеживаться. То есть, аргумент и результат отображаются для каждого вызова, а также исключения, выходящие из функции, поднятые как самой функцией, так и другой функцией, которую она вызывает. Если функция является каррированной, каждый аргумент печатается по мере его передачи в функцию.
- #untrace имя_функции;;
- Остановка отслеживания указанной функции.
- #untrace_all;;
- Остановка отслеживания всех функций, отслеживаемых до сих пор.
- Опции компилятора
-
- #labels bool;;
- Игнорировать метки в типах функций, если аргумент равен false, или переключаться обратно на стандартное поведение (стиль коммутации), если аргумент равен true.
- #ppx "file-name";;
- После разбора передать абстрактное синтаксическое дерево в препроцессор.
- #principal bool;;
- Если аргумент равен true, проверять пути информации во время проверки типов, чтобы убедиться, что все типы получены основным способом. Если аргумент равен false, проверку путей информации не выполнять.
- #rectypes;;
- Разрешить произвольные рекурсивные типы во время проверки типов. Примечание: после включения этот параметр нельзя отключить, так как это приведёт к ненадёжности системы типов.
- #warn_error "warning-list";;
- Обрабатывать как ошибки предупреждения, включенные аргументом, и как обычные предупреждения предупреждения, отключенные аргументом.
- #warnings "warning-list";;
- Включать или отключать предупреждения в соответствии с аргументом.
14.3 Основной уровень и система модулей
Фразы основного уровня могут ссылаться на идентификаторы, определённые в единицах компиляции, с теми же механизмами, что и для отдельно скомпилированных единиц: либо с использованием квалифицированных имён (Modulename.localname), либо с использованием конструкции open и неквалифицированных имён (см. раздел 11.3).
Однако перед ссылкой на другую единицу компиляции в памяти должна быть доступна её реализация. При запуске система основного уровня содержит реализации всех модулей в стандартной библиотеке. Реализации пользовательских модулей могут быть загружены с помощью директивы #load, описанной выше. Ссылка на единицу, реализация которой не загружена, приводит к ошибке Ссылка на неопределённую глобальную переменную `...'.
Обратите внимание, что ввод open Mod просто обеспечивает доступ к скомпилированному интерфейсу (.cmi-файлу) для Mod, но не загружает реализацию Mod и не вызывает ошибок, если реализация Mod не загружена. Ошибка «ссылка на неопределённую глобальную переменную Mod» возникнет только при выполнении значения или определения модуля, которое ссылается на Mod.
14.4 Общие ошибки
В этом разделе описываются и объясняются наиболее часто встречающиеся сообщения об ошибках.
- Файл filename не найден
- Запрашиваемого файла не удалось найти ни в текущей директории, ни в директориях пути поиска.
Если filename имеет формат mod.cmi, это означает, что вы сослались на единицу компиляции mod, но её скомпилированный интерфейс не был найден. Решение: сначала скомпилируйте mod.mli или mod.ml, чтобы создать скомпилированный интерфейс mod.cmi.
Если filename имеет формат mod.cmo, это означает, что вы пытаетесь загрузить с помощью #load файл байт-кода, который ещё не существует. Решение: сначала скомпилируйте mod.ml.
Если ваша программа расположена в нескольких директориях, эта ошибка также может появиться, потому что вы не указали директории для поиска. Решение: используйте директиву #directory для добавления соответствующих директорий в путь поиска.
- Выражение имеет тип t1, но используется с типом t2
- См. раздел 13.4.
- Ссылка на неопределённую глобальную переменную mod
- Вы забыли загрузить в память реализацию модуля с помощью #load. См. раздел 14.3 выше.
14.5 Создание пользовательских систем основного уровня: ocamlmktop
Команда ocamlmktop создаёт системы основного уровня OCaml, содержащие пользовательский код, предварительно загруженный при запуске.
Команда ocamlmktop принимает в качестве аргумента набор файлов .cmo и .cma и связывает их с объектными файлами, реализующими систему основного уровня OCaml. Типичное использование:
ocamlmktop -o mytoplevel foo.cmo bar.cmo gee.cmo
Это создаёт файл байт-кода mytoplevel, содержащий систему основного уровня OCaml плюс код из трёх файлов .cmo. Этот основной уровень непосредственно выполняется и запускается командой:
./mytoplevel
Это запускает обычный цикл основного уровня, за исключением того, что код из foo.cmo, bar.cmo и gee.cmo уже загружен в память, так же как если бы вы ввели:
#load "foo.cmo";;
#load "bar.cmo";;
#load "gee.cmo";;
при входе в основной уровень. Модули Foo, Bar и Gee не открываются; вам всё равно придётся выполнить
open Foo;;
самим, если это требуется.
14.5.1 Параметры
Следующие параметры командной строки распознаются командой ocamlmktop.
- -cclib libname
- Передать параметр -llibname C-линкеру при линковке в режиме «пользовательский интерпретатор». См. соответствующий параметр для ocamlc в главе 13.
- -ccopt option
- Передать указанный параметр C-компилятору и линкеру при линковке в режиме «пользовательский интерпретатор». См. соответствующий параметр для ocamlc в главе 13.
- -custom
- Выполнить линковку в режиме «пользовательский интерпретатор». См. соответствующий параметр для ocamlc в главе 13.
- -I directory
- Добавить указанную директорию в список директорий, просматриваемых при поиске скомпилированных объектных файлов (.cmo и .cma).
- -o exec-file
- Указать имя файла основного уровня, создаваемого линковщиком. По умолчанию это a.out.
14.6 Нативный основной уровень: ocamlnat (экспериментальная версия)
В этом разделе описывается инструмент, который ещё не является официально поддерживаемым, но может оказаться полезным.
Код OCaml, выполняемый в традиционной системе основного уровня, использует интерпретатор байт-кода. Когда требуется повышенная производительность или для тестирования программ, которые будут работать только при компиляции в нативный код, можно использовать нативный основной уровень вместо этого.
Для большинства установок родной главный уровень не был установлен вместе с остальной частью инструментальной цепочки OCaml. В таких обстоятельствах потребуется создать дистрибутив OCaml из исходного кода. Из созданного исходного дерева дистрибутива вы можете использовать make natruntop для построения и выполнения родного главного уровня. (В качестве альтернативы можно использовать make ocamlnat, который выполняет только этап сборки.)
Если команда make install выполняется после построения родного главного уровня, то программа ocamlnat (либо из исходного кода, либо из каталога установки) может быть вызвана напрямую, а не используя make natruntop.
© 1995-2022 INRIA.
https://v2.ocaml.org/releases/5.0/htmlman/toplevel.html