This chapter describes the toplevel system for Objective Caml, that permits interactive use of the Objective Caml system
through a read-eval-print loop. In this mode, the system repeatedly
reads Caml phrases from the input, then typechecks, compile and
evaluate them, then prints the inferred type and result value, if
any. The system prints a # (sharp) prompt before reading each
phrase.
Input to the toplevel can span several lines. It is terminated by ;; (a
double-semicolon). The toplevel input consists in one or several
toplevel phrases, with the following syntax:
toplevel-input |
::= |
{ toplevel-phrase } ;; |
toplevel-phrase |
::= |
definition |
|
| |
expr |
|
| |
# ident directive-argument |
definition |
::= |
let [rec] let-binding { and let-binding } |
|
| |
external value-name : typexpr = external-declaration |
|
| |
type-definition |
|
| |
exception-definition |
|
| |
module module-name [ : module-type ] = module-expr |
|
| |
module type modtype-name = module-type |
|
| |
open module-path |
directive-argument |
::= |
nothing |
|
| |
string-literal |
|
| |
integer-literal |
|
| |
value-path |
A phrase can consist of a definition, similar to those found in
implementations of compilation units or in struct ... end
module expressions. The definition can bind value names, type names,
an exception, a module name, or a module type name. The toplevel
system performs the bindings, then prints the types and values (if
any) for the names thus defined.
A phrase may also consist in a open directive (see
section 6.11), or a value expression
(section 6.7). Expressions are simply evaluated,
without performing any bindings, and the value of the expression is
printed.
Finally, a phrase can also consist in a toplevel directive,
starting with # (the sharp sign). These directives control the
behavior of the toplevel; they are listed below in
section 9.2.
Unix:
The toplevel system is started by the command ocaml, as follows:
ocaml options objects # interactive mode
ocaml options objects scriptfile # script mode
options are described below.
objects are filenames ending in .cmo or .cma; they are
loaded into the interpreter immediately after options are set.
scriptfile is any file name not ending in .cmo or .cma.
If no scriptfile is given on the command line, the toplevel system
enters interactive mode: phrases are read on standard input, results
are printed on standard output, errors on standard error. End-of-file
on standard input terminates ocaml (see also the #quit directive
in section 9.2).
On start-up (before the first phrase is read), if the file
.ocamlinit exists in the current directory,
its contents are read as a sequence of Objective Caml phrases
and executed as per the #use directive
described in section 9.2.
The evaluation outcode for each phrase are not displayed.
The toplevel system does not perform line editing, but it can
easily be used in conjunction with an external line editor such as
fep; just run fep -emacs ocaml or fep -vi ocaml.
Another option is to use ocaml under Gnu Emacs, which gives the
full editing power of Emacs (see the subdirectory emacs of the
Objective Caml distribution).
At any point, the parsing, compilation or evaluation of the current
phrase can be interrupted by pressing ctrl-C (or, more precisely,
by sending the sigintr signal to the ocaml process). The toplevel
then immediately returns to the # prompt.
If scriptfile is given on the command-line to ocaml, the toplevel
system enters script mode: the contents of the file are read as a
sequence of Objective Caml phrases and executed, as per the #use
directive (section 9.2). The outcome of the
evaluation is not printed. On reaching the end of file, the ocaml
command exits immediately. No commands are read from standard input.
Sys.argv is transformed, ignoring all Objective Caml parameters, and
starting with the script file name in Sys.argv.(0).
In script mode, the first line of the script is ignored if it starts
with #!. Thus, it is theoretically possible to make the script
itself executable and put as first line #!/usr/local/bin/ocaml,
thus calling the toplevel system automatically when the script is
run. However, ocaml itself is a #! script on most installations
of Objective Caml, and Unix kernels usually do not handle nested #!
scripts.
Windows:
In addition to the text-only command ocaml.exe, which works exactly
as under Unix (see above), a graphical user interface for the
toplevel is available under the name ocamlwin.exe. It should be
launched from the Windows file manager or program manager.
The ``Terminal'' windows is split in two panes. Phrases are entered
and edited in the bottom pane. The top pane displays a copy of the
input phrases as they are processed by the Objective Caml toplevel,
interspersed with the toplevel responses. The ``Return'' key sends the
contents of the bottom pane to the Objective Caml toplevel. The ``Enter''
key inserts a newline without sending the contents of the Input
window. (This can be configured with the ``Preferences'' menu item.)
The contents of the input window can be edited at all times, with the
standard Windows interface. An history of previously entered phrases
is maintained and displayed in a separate window.
To quit the Camlwin application, either select ``Quit'' from
the ``File'' menu, or use the quit function described below.
At any point, the parsing, compilation or evaluation of the current
phrase can be interrupted by selecting the ``Interrupt Objective Caml''
menu item. This goes back to the # prompt.
The following command-line options are recognized by the ocaml command.
- -I directory
-
Add the given directory to the list of directories searched for
source and compiled files. By default, the current directory is
searched first, then the standard library directory. Directories added
with -I are searched after the current directory, in the order in
which they were given on the command line, but before the standard
library directory.
If the given directory starts with +, it is taken relative to the
standard library directory. For instance, -I +labltk adds the
subdirectory labltk of the standard library to the search path.
Directories can also be added to the search path once
the toplevel is running with the #directory directive
(section 9.2).
- -nolabels
-
Ignore non-optional labels in types. Labels cannot be used in
applications, and parameter order becomes strict.
- -principal
-
Check information path during type-checking, to make sure that all
types are derived in a principal way. All programs accepted in
-principal mode are also accepted in default mode with equivalent
types.
- -rectypes
-
Allow arbitrary recursive types during type-checking. By default,
only recursive types where the recursion goes through an object type
are supported.
- -unsafe
-
See the corresponding option for ocamlc, chapter 8.
Turn bound checking off on array and string accesses (the v.(i) and
s.[i] constructs). Programs compiled with -unsafe are therefore
slightly faster, but unsafe: anything can happen if the program
accesses an array or string outside of its bounds.
- -w warning-list
-
Enable or disable warnings according to the argument warning-list.
Unix:
The following environment variables are also consulted:
-
LC_CTYPE
- If set to iso_8859_1, accented characters (from the
ISO Latin-1 character set) in string and character literals are
printed as is; otherwise, they are printed as decimal escape sequences
(\ddd).
- TERM
- When printing error messages, the toplevel system
attempts to underline visually the location of the error. It
consults the TERM variable to determines the type of output terminal
and look up its capabilities in the terminal database.
The following directives control the toplevel behavior, load files in
memory, and trace program execution.
Note: all directives start with a # (sharp) symbol. This #
must be typed before the directive, and must not be confused with the
# prompt displayed by the interactive loop. For instance,
typing #quit;; will exit the toplevel loop, but typing quit;;
will result in an ``unbound value quit'' error.
- #quit;;
-
Exit the toplevel loop and terminate the ocaml command.
- #labels bool;;
-
Ignore labels in function types if argument is false, or switch back
to default behaviour (commuting style) if argument is true.
- #warnings "warning-list";;
-
Enable or disable warnings according to the argument.
- #directory "dir-name";;
-
Add the given directory to the list of directories searched for
source and compiled files.
- #cd "dir-name";;
-
Change the current working directory.
- #load "file-name";;
-
Load in memory a bytecode object file (.cmo file) produced by
the batch compiler ocamlc.
- #use "file-name";;
-
Read, compile and execute source phrases from the given file.
This is textual inclusion: phrases are processed just as if
they were typed on standard input. The reading of the file stops at
the first error encountered.
- #install_printer printer-name;;
-
This directive registers the function named printer-name (a
value path) as a printer for values whose types match the argument
type of the function. That is, the toplevel loop will call
printer-name when it has such a value to print.
The printing function printer-name should have type
Format.formatter -> t -> unit, where t is the
type for the values to be printed, and should output its textual
representation for the value of type t on the given formatter,
using the functions provided by the Format library. For backward
compatibility, printer-name can also have type
t -> unit and should then output on the standard
formatter, but this usage is deprecated.
- #remove_printer printer-name;;
-
Remove the named function from the table of toplevel printers.
- #trace function-name;;
-
After executing this directive, all calls to the function named
function-name will be ``traced''. That is, the argument and the
result are displayed for each call, as well as the exceptions escaping
out of the function, raised either by the function itself or by
another function it calls. If the function is curried, each argument
is printed as it is passed to the function.
- #untrace function-name;;
-
Stop tracing the given function.
- #untrace_all;;
-
Stop tracing all functions traced so far.
- #print_depth n;;
-
Limit the printing of values to a maximal depth of n.
The parts of values whose depth exceeds n are printed as ...
(ellipsis).
- #print_length n;;
-
Limit the number of value nodes printed to at most n.
Remaining parts of values are printed as ... (ellipsis).
9.3 |
The toplevel and the module system |
|
Toplevel phrases can refer to identifiers defined in compilation units
with the same mechanisms as for separately compiled units: either by
using qualified names (Modulename.localname), or by using
the open construct and unqualified names (see section 6.3).
However, before referencing another compilation unit, an
implementation of that unit must be present in memory.
At start-up, the toplevel system contains implementations for all the
modules in the the standard library. Implementations for user modules
can be entered with the #load directive described above. Referencing
a unit for which no implementation has been provided
results in the error ``Reference to undefined global `...' ''.
Note that entering open mod merely accesses the compiled
interface (.cmi file) for mod, but does not load the
implementation of mod, and does not cause any error if no
implementation of mod has been loaded. The error
``reference to undefined global mod'' will occur only when
executing a value or module definition that refers to mod.
This section describes and explains the most frequently encountered
error messages.
- Cannot find file filename
-
The named file could not be found in the current directory, nor in the
directories of the search path.
If filename has the format mod.cmi, this
means you have referenced the compilation unit mod, but its
compiled interface could not be found. Fix: compile mod.mli or
mod.ml first, to create the compiled interface mod.cmi.
If filename has the format mod.cmo, this
means you are trying to load with #load a bytecode object file that
does not exist yet. Fix: compile mod.ml first.
If your program spans several directories, this error can also appear
because you haven't specified the directories to look into. Fix: use
the #directory directive to add the correct directories to the
search path.
- This expression has type t1, but is used with type t2
-
See section 8.4.
- Reference to undefined global mod
-
You have neglected to load in memory an implementation for a module
with #load. See section 9.3 above.
9.5 |
Building custom toplevel systems: ocamlmktop |
|
The ocamlmktop command builds Objective Caml toplevels that
contain user code preloaded at start-up.
The ocamlmktop command takes as argument a set of .cmo and .cma
files, and links them with the object files that implement the Objective Caml toplevel. The typical use is:
ocamlmktop -o mytoplevel foo.cmo bar.cmo gee.cmo
This creates the bytecode file mytoplevel, containing the Objective Caml toplevel system, plus the code from the three .cmo
files. This toplevel is directly executable and is started by:
./mytoplevel
This enters a regular toplevel loop, except that the code from
foo.cmo, bar.cmo and gee.cmo is already loaded in memory, just as
if you had typed:
#load "foo.cmo";;
#load "bar.cmo";;
#load "gee.cmo";;
on entrance to the toplevel. The modules Foo, Bar and Gee are
not opened, though; you still have to do
open Foo;;
yourself, if this is what you wish.
The following command-line options are recognized by ocamlmktop.
- -cclib libname
-
Pass the -llibname option to the C linker when linking in
``custom runtime'' mode. See the corresponding option for
ocamlc, in chapter 8.
- -ccopt option
-
Pass the given option to the C compiler and linker, when linking in
``custom runtime'' mode. See the corresponding option for
ocamlc, in chapter 8.
- -custom
-
Link in ``custom runtime'' mode. See the corresponding option for
ocamlc, in chapter 8.
- -I directory
-
Add the given directory to the list of directories searched for
compiled object code files (.cmo and .cma).
- -o exec-file
-
Specify the name of the toplevel file produced by the linker.
The default is a.out.