This section explains some of the basic elements of using the Standard ML of New Jersey compiler as an interactive system into which you enter declarations and expressions or load code from source files. This is the most accessible mode of using the compiler, but for any programs of nontrivial size we recommend that the Compilation Manager be used to organize the compilation process.We assume below that you are using the compiler under Unix. The behavior will be somewhat different under MS Windows or the Macintosh OS.
Running Standard ML
Type ``sml
'' from the shell. This puts you into the interactive system. The top level prompt is ``-'', and the secondary prompt (printed when input is incomplete) is ``=''. If you get the secondary prompt when you don't expect it, typing ``;
return'' will often complete your input, or typing your interrupt character (e.g., control-C) will cancel your input and return to the ML top level.If ``
sml
'' doesn't work, ask wheresml
has been installed on your machine and use the appropriate path name or redefine your PATH environment variable.Interactive input
Input to the top level interpreter (i.e., declarations and expressions) must be terminated by a semicolon (and carriage return) before the system will evaluate it. The system then prints out a response indicating the effect of the evaluation. Expressions are treated as implicit declarations of a standard variableit
. For example,This means that the value of the last top level expression evaluated can be referred to using the variable ``
- 3;
user input after prompt val it = 3 : int
system response it
.''Interrupting compilation or execution
Typing the interrupt character (typically control-C) should interrupt the compiler and return you to top level.Exiting the interactive system.
Typing control-D (EOF) at top level will cause an exit to the shell (or the parent process from whichsml
was run). One can also terminate by callingOS.Process.exit(OS.Process.success)
.Loading ML source text from a file
The functionuse: string -> unit
interprets its argument as a file name relative tosml
's current directory and loads the text from that file as though it had been typed in. This should normally be executed at top level, but the loaded files can also contain calls ofuse
to recursively load other files. It is a bad idea to calluse
within an expression or declaration, because the effects are not well-defined.For industrial-strength multi-module software systems, the the Compilation Manager is more appropriate than
use
.Error messages
The compiler attempts to recover from syntactic errors so that it can also produce semantic (type-checking) errors during the same compilation. Syntactic error recovery is more accurate for source files loaded byuse
or CM than it is from declarations typed directly into the interactive system -- this is because lookahead is not possible when text is entered one line at a time.When compiling files, the error messages include line numbers and character positions within the line. For example:
- if true = then 5 true = else 6; std_in:7.6-7.11 Error: operator is not a function operator: int in expression: 5 true -Here the location informationstd_in:7.6-7.11
indicates that the erroneous expression ``5 true
'' occupies characters 6 through 11 of the 7th line of input fromstd_in
. For simple syntactic errors this position information is usually accurate or perhaps off by just one line. For some classes of errors the line numbers may not be very useful, because they delineate a potentially large declaration containing the error. If the error occurs in a file being loaded byuse
, the line numbers will refer to lines in the file being loaded.There are a number of different forms of type error message, and it may require some practice before you become adept at interpreting them. The most common form indicates a mismatch between the type of a function (or operator) and its argument (or operand). A representation of the offending expression is usually included, but this is an image of the internal abstract syntax for the expression and may differ significantly from the original source code. For instance, an expression ``
if
e1then
e2else
e3'' is represented internally as acase
expression over a boolean value: ``$case
e1of true =>
e2| false =>
e3.''All the error messages produced by SML/NJ are documented in the SML/NJ Error and Warning Messages page.
Compiler interface
Most users will interact with the compiler by loading code via theuse
command or under control of the Compilation Manager. However, some control of individual compiler phases is possible through theCompiler.Control
structure.Printing
The structureCompiler.Control.Print
contains several useful flags and functions with which you can control or redirect compiler error, diagnostic, and result messages. Among other things, there is a variableprintDepth
that controls the depth of printing of large structured values.Interacting with the operating system
The structuresIO
,OS
, and others contain functions for such tasks as executing other programs from withinsml
and changing the current directory. These are documented in The Standard ML Basis Library manual.Emacs support
The directory contrib/emacs contains Matthew J. Morley's sml-mode package that supports editing SML source code and interacting withsml
under GNU emacs. The sml-mode package is available at our ftp site.