\chapter{The PE Script Language}

\begin{framed}
I did not invent the PE scripting language, and the person who did never
fully specified or documented it.  This documentation is based partly on
reverse engineering; is descriptive, not prescriptive; and may not be
complete, nor even correct as far as it goes.  The only way to be sure
what a PE script will really do is to run it and find out, like
Rikki-Tikki-Tavi.
\end{framed}

\section{Basic syntax}

Scripts are text files.  The traditional filename extension is \texttt{.pe}~;
scripts in the wild have also been seen using a \texttt{.ff} extension.

Comments may be marked in any of these ways:
\begin{verbatim}
# hash for shell-like line comment

// two slashes for C++-like line comment

/*
C-style comment delimiters,
which may cover multiple lines.
*/
\end{verbatim}

\begin{framed}
Newlines are syntactically significant, marking the ends of
statements.
To continue a statement onto more than one line, you must use a backslash to
escape the newline.  
\end{framed}

FontForge \FFdiff processes line-continuation backslashes in a separate
abstraction layer before the main interpreter sees them, which causes some
effects that language users may not expect.  For instance, in FontForge a
line-based comment started by \texttt{\#} or \texttt{//} may be continued
onto a new line by a backslash, without any \texttt{\#} or \texttt{//} on
the continuation line.  FontAnvil instead processes
line-continuation backslashes in the main tokenizer.  They may not be used
to continue a line-based comment onto a new line, and they may not be used
in the middle of a token (such as a function name) without having the effect
of splitting it into two tokens.  However, they may be used within string
constants.

Semicolons also mark the ends of statements, and may be used to join
multiple statements onto a single line.  Semicolons at the ends of lines
create empty statements, which are ignored.

\begin{framed}
PE script is case sensitive for reserved words, variable names,
and built-in function names.
\end{framed}

\section{Data types, variables, and scope}

Values have associated types.  Variables can hold values of arbitrary type
and remember what type they are.  The types are:
\begin{itemize}
\item integer
\item floating-point number
\item Unicode code point (note that this is a distinct data type from
``integer'')
\item string (of bytes, usually assumed to be UTF-8; null terminated)
\item array
\item void
\end{itemize}

Syntax for constant values looks like this:
\begin{verbatim}
# integers in decimal, hexadecimal, or
# octal, using C syntax
123     # first digit nonzero for decimal
0x52    # 0x prefix for hex
041     # 0 prefix but not hex means octal

# floating-point numbers indicated by the
# decimal point; note the decimal point
# is always . regardless of locale
123.45  # basic decimal float
4.9e5   # scientific notation, = 490000.0

# Unicode code points are hexadecimal
# numbers marked by 0u
0u1f4a9 # everybody's favourite

# strings have single or double quotes
'Single'
"double"
"foo\nbar" # \n for newline, in both
"foo\
bar" # backslash continues string past
     # a line break, this is "foobar"
"foo\\bar" # backslash makes other chars
           # literal, this is "foo\bar" 
'"' # same quote starts and ends string

# unescaped newline also validly ends a
# string, but don't do this!
# current FontAnvil supports it for
# FontForge compatibility only
"foo

# square brackets and commas for arrays
[1,2,3,0uABC,'foo']
\end{verbatim}

\begin{framed}
Literal string constants in PE script syntax are limited to 256 characters. 
You can, however, construct longer strings with multiple literals and the
concatenation operator.
\end{framed}

\begin{framed}
The language seems intended to allow arrays to have more than one dimension
(i.e.\ each element of an array may itself be an array) but such arrays are
currently broken in both FontForge and FontAnvil, and usually cause the
interpreter to crash.  I hope to fix this bug in FontAnvil, but if I fix it
and FontForge doesn't, then any scripts that make use of multidimensional
arrays will be incompatible with FontForge.
\end{framed}

\section{Operators}

FIXME

\section{Control structures}

FIXME
