\documentclass{article}
\usepackage{fullpage}

\title{mlt manual}
\author{Adam Chlipala}

\begin{document}

\maketitle

\section{Introduction}

This system is currently in need of a good name. I will use either ``mlt'' or generic terms to refer to it for now.

mlt is a system for the creation of dynamic web sites based around Standard ML. The meat of the system deals with compiling a template language. This language is purposely simplistic. It's not possible to create a non-terminating template without the complicity of SML code that it calls. Templates look like HTML source files with SML-like code inserted in strategic places. They are capable of full interaction with all types and values in any SML structures. The current implementation interfaces with web servers via the standard CGI protocol.

\section{Tool usage}

\begin{enumerate}
	\item Choose a directory to hold the sources for the dynamic web site project.
	\item Edit a {\tt mlt.conf} file in that directory to set project options, including which SML/NJ CM libraries to use, where to put some generated SML sources and binary files, and where to publish the actual CGI scripts.
	\item Create a set of Standard ML support files.
	\item Create a set of templates with {\tt .mlt} filename extensions. Each {\tt {\it page}.mlt} will become a CGI script named {\tt {\it page}}, and they may interact with libraries and project SML sources.
	\item Run the {\tt mlt} command-line program with no arguments.
	\item If it reports any errors, correct them and repeat the last step.
	\item Access your site from the base URL corresponding to the directory you chose for script output. (Probably a ``cgi-bin'' directory of some sort)
\end{enumerate}

\section{{\tt mlt.conf} files}

Settings concerning compilation and publishing of projects are controlled by {\tt mlt.conf} files. There will generally be two files that influence a particular project: a system-wide file (probably in {\tt /etc/mlt.conf}) and the {\tt mlt.conf} file in the project directory. Single-value option settings from the project configuration override the system-wide configuration when there is a conflict.

Files consist of a sequence of the following kinds of lines in any order:

\begin{itemize}
	\item {\tt in {\it directory}}: Treat {\it directory} as the project directory. This defaults to the current working directory.

	\item {\tt out {\it directory}}: Use {\it directory} as the working directory. Among other things, a {\tt heap.x86-linux} file will be placed here that must be readable by the web server that you intend to use. (If the server runs your CGI scripts as your user, like Apache does with suexec, then you probably don't need to worry about this.) This defaults to the current working directory.

	\item {\tt pub {\it directory}}: Publish CGI scripts to {\it directory}. Each will be a {\tt sh} shell script that runs SML/NJ with the generated {\tt heap.x86-linux} and appropriate arguments. This defaults to the current working directory.

	\item {\tt lib {\it file}}: {\it file} is the path to the {\tt .cm} file for the mlt template library. This is the library built from the {\tt src/lib/} tree. It defaults to {\tt /usr/local/share/mlt/src/lib/sources.cm}.

	\item {\tt compiler {\it file}}: {\it file} is the path to the {\tt .cm} file for the mlt compiler library. This is the library built from the {\tt src/} tree. It defaults to {\tt /usr/local/share/mlt/src/sources.cm}.

	\item {\tt sml {\it directory}}: {\it directory} is the path to the SML/NJ {\tt bin} directory. It defaults to {\tt /usr/local/sml/bin}.
 
	\item {\tt cm {\it file}}: {\it file} is the path to a file that the SML/NJ Compilation Manager understands (i.e., {\tt .cm}, {\tt .sml}, {\tt .sig}, {\tt .grm}, {\tt .lex}). This file is to be made available to templates in the project.

	\item {\tt print {\it type} = {\it code}}: This declares that the given {\it code} is an SML expression that evaluates to an appropriate function for printing values of the SML {\it type}. The {\it code} should usually be the name of a function defined in a library or project SML source file.

	\item {\tt before {\it template}}: Run {\it template} before every normally-requested template, including its output at the beginning of the final output. This can be used to set up project-wide global state. Performing initialization inside project SML files will not generally be good enough. This is because all of the structure definitions these contain are evaluated at ``compile time,'' causing their code not found inside function definitions to be run only once.

	\item {\tt after {\it template}}: Run {\it template} after every successfully executing template, including its output at the end.

	\item {\tt exn {\it template}}: Run {\it template} when an exception goes uncaught during normal template execution. The function {\tt Web.getExn : unit -> exn} can be used to retrieve the causing exception from within {\it template}. The {\tt before} and {\tt after} templates are not run in the {\tt exn} template when it is executed because of an uncaught exception.
\end{itemize}

\section{The template language}

The template language at the moment is a somewhat ad-hoc mixture of SML-style and Java-style syntax. The exact typing rules for the constructs described below should be clear to anyone with a good knowledge of SML.

\subsection{Grammar}

Template files (denoted by the filename extension {\tt .mlt}) are HTML source files with embedded declarations and statements in an SML-like language. Statements and declarations are separated by semicolons where necessary to disambiguate. The exact grammar can be found in ml-yacc form in {\tt src/mlt.grm}.

\subsection{Expressions}

\subsubsection{Constants}

Base type constants such as 1, $\sim 2$, and {\tt "some string"} are available, with identical types and meanings as in Standard ML. Character constants are denoted like 'x'.

\subsubsection{Variables}

User-defined variables are denoted the same way as in SML, except that the apostrophe character is disallowed in their identifiers.

\subsubsection{Paths}

While templates cannot define their own structures, they may access structures from imported libraries and project SML sources. The syntax for this is identical to the SML syntax, i.e., {\tt Posix.FileSys.opendir} or {\tt valOf}. The second example is treated as a path projecting the {\tt valOf} function from the top-level environment.

\subsubsection{Binary operators}

There is no mechanism for user definition of infix operators, but the following binary operators are supported: $+$, $-$, $*$, $/$, $\%$, $=$, $<>$, $<$, $<=$, $>$, $>=$, $::$, \^{}, {\tt and}, and {\tt or}. They are identical to SML operators, save that SML {\tt div} becomes $/$, {\tt mod} becomes $\%$, {\tt andalso} becomes {\tt and}, and {\tt orelse} becomes {\tt or}.

\subsubsection{Unary operators}

In addition to SML's $\sim$ prefix negation operator, there is a \$ operator for CGI parameter extraction. \$ has type {\tt string -> string}, so you can use it like {\tt \$"name"} to retrieve the value of the form field {\tt name}. \$ returns {\tt ""} for unset parameters.

\subsubsection{Applications}

Function application is like SML application.

\subsubsection{Tuples}

Tuple and {\tt ()} expressions are handled identically to how they are in SML.

\subsubsection{Records}

The syntax for creating records and extracting their fields is identical to SML's, with a few added conveniences. Record fields given in a record constructor without values are assigned the values of variables of the same names. For example, if there is a variable {\tt x} in scope, then the expressions {\tt \{x = x\}} and {\tt \{x\}} are equivalent. There are also O'Caml style functional record update expressions, such as {\tt \{myRecord with a = 1, b = 2\}} to construct a record identical to {\tt myRecord} except for the given field replacements.

\subsubsection{Template calls}

Where {\tt temp} is the name of a template in the current project, {\tt @temp} evaluates to a function {\tt (string * string) list -> unit} that takes in a list of name-value pairs for CGI parameters to modify and runs {\tt temp} with those changes. The Compilation Manager will prevent template calls from being used to implement any sort of recursion.

\subsubsection{Anonymous functions}

Anonymous {\tt fn} functions are available with the SML syntax.

\subsubsection{\tt case}

SML {\tt case} expressions are supported.

\subsubsection{\tt iff}

SML {\tt if} expressions are supported, except that the keyword that introduces them is {\tt iff}, to disambiguate from {\tt if} statements.

\subsubsection{\tt raise}

SML {\tt raise} expressions are supported.

\subsubsection{\tt let}

SML {\tt let} expressions are supported.

\subsection{Patterns}

Patterns are identical to SML patterns without support for user-defined infix constructors, though {\tt ::} is supported. Record patterns can include field names with no assigned patterns (the pattern for such a field is taken to be the field name) and "flex record" {\tt ...}'s to stand for unused fields.

\subsection{Statements and declarations}

\subsubsection{\tt Expressions}

An expression appearing in a statement position is evaluated and printed into the web page output. The function used to print it is found among the {\tt print} directives in {\tt mlt.conf} files.

\subsubsection{\tt open}

This construct is identical to SML's and is used as a convenience to import all bindings from a list of structures into the environment for the enclosing block.

\subsubsection{\tt val}

{\tt val} bindings are identical to those in SML.

\subsubsection{References}

Variables with reference type are introduced with {\tt ref} declarations, which give lists of identifiers and their initial values. An example is {\tt ref x = 1, y = 2}. Where such a definition is in scope, the defined reference variables are used like normal variables with no need to explicitly dereference them. The value of a reference variable is updated with the usual {\tt :=} operator, with the difference that such update assignments are separate kinds of statements, not expressions with {\tt unit} type.

\subsubsection{{\tt if}..{\tt then}..{\tt else}}

If statements are in the usual imperative style, meaning that else clauses are optional. They are of the form:

\begin{verbatim}
if condition1 then
	block1
else if condition 2 then
	block 2
else
	block 3
end
\end{verbatim}

The {\tt block}s are sequences of statements and declarations. Every {\tt if} statement is followed by zero or more {\tt else if}'s and one or zero {\tt else}'s.

\subsubsection{\tt foreach}

All looping is done via {\tt foreach} statements, which have two forms. One is:

\begin{verbatim}
foreach var in exp do
	block
end
\end{verbatim}

Where {\tt exp} has type {\tt t list}, {\tt block} is executed for each of {\tt exp}'s elements, binding {\tt var} to each of them in order from first to last.

There is also a shortcut integer iteration form:

\begin{verbatim}
for var in fromExp .. toExp do
	block
end
\end{verbatim}

{\tt fromExp} and {\tt toExp} must have type {\tt int}. {\tt block} is evaluated with {\tt var} bound in sequence to each integer in the range defined by {\tt fromExp} and {\tt toExp}.

\subsubsection{\tt switch}

{\tt switch} statements are imperative equivalents of {\tt case} expressions, such as:

\begin{verbatim}
switch exp of
  pat1 => block1
| pat2 => block2
end
\end{verbatim}

\subsubsection{{\tt try}..{\tt with}}

This construction is to SML's {\tt handle} what {\tt switch} is to {\tt case}. For example:

\begin{verbatim}
try
	block1
with pat1 => block2
| pat2 => block3
end
\end{verbatim}

\end{document}