<id-start-char> ::= <alpha-char> | "_"
-<id-body-char> ::= <id-start-char> @! <digit-char>
+<id-body-char> ::= <id-start-char> | <digit-char>
-<alpha-char> ::= "A" | "B" | \dots\ | "Z"
-\alt "a" | "b" | \dots\ | "z"
-\alt <extended-alpha-char>
+<alpha-char> ::= "A" | "B" | $\cdots$ | "Z"
+ | "a" | "b" | $\cdots$ | "z"
+ | <extended-alpha-char>
<digit-char> ::= "0" | <nonzero-digit-char>
-<nonzero-digit-char> ::= "1" | "2" $| \ldots |$ "9"
+<nonzero-digit-char> ::= "1" | "2" | $\cdots$ | "9"
\end{grammar}
The precise definition of @<alpha-char> is left to the function
-\textsf{alpha-char-p} in the hosting Lisp system. For portability,
-programmers are encouraged to limit themselves to the standard ASCII letters.
+@|alpha-char-p| in the hosting Lisp system. For portability, programmers are
+encouraged to limit themselves to the standard ASCII letters.
There are no reserved words at the lexical level, but the higher-level syntax
recognizes certain identifiers as \emph{keywords} in some contexts. There is
<char-literal> ::= "'" <char-literal-char> "'"
-<string-literal-char> ::= any character other than "\\" or "\""
-\alt "\\" <char>
+<string-literal-char> :: "\\" <char>
+ | any character other than "\\" or "\""
-<char-literal-char> ::= any character other than "\\" or "'"
-\alt "\\" <char>
+<char-literal-char> :: "\\" <char>
+ | any character other than "\\" or "'"
<char> ::= any single character
\end{grammar}
\begin{grammar}
<integer-literal> ::= <decimal-integer>
-\alt <binary-integer>
-\alt <octal-integer>
-\alt <hex-integer>
+ | <binary-integer>
+ | <octal-integer>
+ | <hex-integer>
<decimal-integer> ::= "0" | <nonzero-digit-char> @<digit-char>^*
-<binary-integer> ::= "0" @("b"|"B"@) @<binary-digit-char>^+
+<binary-integer> ::= "0" @("b" | "B"@) @<binary-digit-char>^+
<binary-digit-char> ::= "0" | "1"
-<octal-integer> ::= "0" @["o"|"O"@] @<octal-digit-char>^+
+<octal-integer> ::= "0" @["o" | "O"@] @<octal-digit-char>^+
-<octal-digit-char> ::= "0" | "1" $| \ldots |$ "7"
+<octal-digit-char> ::= "0" | "1" | $\cdots$ | "7"
-<hex-integer> ::= "0" @("x"|"X"@) @<hex-digit-char>^+
+<hex-integer> ::= "0" @("x" | "X"@) @<hex-digit-char>^+
<hex-digit-char> ::= <digit-char>
-\alt "A" | "B" | "C" | "D" | "E" | "F"
-\alt "a" | "b" | "c" | "d" | "e" | "f"
+ | "A" | "B" | "C" | "D" | "E" | "F"
+ | "a" | "b" | "c" | "d" | "e" | "f"
\end{grammar}
Sod understands only integers, not floating-point numbers; its integer syntax
\subsection{Punctuation} \label{sec:syntax.lex.punct}
\begin{grammar}
-<punctuation> ::= any nonalphanumeric character other than "_", "\"" or "'"
+<punctuation> ::= "<<" | ">>" | "||" | "&&"
+ | "<=" | ">=" | "==" | "!=" | "\dots"
+\alt any nonalphanumeric character other than "_", "\"", or "'"
\end{grammar}
\subsection{Comments} \label{sec:syntax.lex.comment}
\begin{grammar}
-<comment> ::= <block-comment>
-\alt <line-comment>
+<comment> ::= <block-comment> | <line-comment>
<block-comment> ::=
"/*"
understands C comments and string and character literals.
A C fragment is terminated by one of a small number of delimiter characters
-determined by the immediately surrounding context -- usually a closing brace
-or bracket. The first such delimiter character which is not enclosed in
-brackets, braces or parenthesis ends the fragment.
+determined by the immediately surrounding context -- usually some kind of
+bracket. The first such delimiter character which is not enclosed in
+brackets, braces or parentheses ends the fragment.
%%%--------------------------------------------------------------------------
\section{C types} \label{sec:syntax.type}
<abstract-declarator> ::= <declarator>$[\epsilon, \mbox{@<argument-list>}]$
<argument-declarator> ::=
- <declarator>$[\mbox{@<identifier> @! $\epsilon$}, \mbox{@<argument-list>}]$
+ <declarator>$[\mbox{@<identifier> | $\epsilon$}, \mbox{@<argument-list>}]$
<simple-declarator> ::=
<declarator>$[\mbox{@<identifier>}, \mbox{@<argument-list>}]$
@[<list>$[\mbox{@<argument>}]$@]
"?" @[<list>$[\mbox{@<keyword-argument>}]$@]
-<method-argument-list> ::= <argument-list> @! <keyword-argument-list>
+<method-argument-list> ::= <argument-list> | <keyword-argument-list>
<dotted-name> ::= <identifier> "." <identifier>
<property> ::= <identifier> "=" <expression>
-<expression> ::= <term> | <expression> "+" <term> | <expression> "--" <term>
+<expression> ::= <logical-or>
-<term> ::= <factor> | <term> "*" <factor> | <term> "/" <factor>
+<logical-or> ::= <logical-and>
+ | <logical-or> "||" <logical-and>
-<factor> ::= <primary> | "+" <factor> | "--" <factor>
+<logical-and> ::= <bitwise-or>
+ | <logical-and> "&&" <bitwise-or>
+
+<bitwise-or> ::= <bitwise-xor>
+ | <bitwise-or> "|" <bitwise-xor>
+
+<bitwise-xor> ::= <bitwise-and>
+ | <bitwise-xor> "^" <bitwise-and>
+
+<bitwise-and> ::= <equality>
+ | <bitwise-and> "&" <equality>
+
+<equality> ::= <ordering>
+ | <equality> "==" <ordering>
+ | <equality> "!=" <ordering>
+
+<ordering> ::= <shift>
+ | <ordering> "<" <shift>
+ | <ordering> "<=" <shift>
+ | <ordering> ">=" <shift>
+ | <ordering> ">" <shift>
+
+<shift> ::= <additive>
+ | <shift> "<<" <additive>
+ | <shift> ">>" <additive>
+
+<additive> ::= <term>
+ | <additive> "+" <term>
+ | <additive> "--" <term>
+
+<term> ::= <factor>
+ | <term> "*" <factor>
+ | <term> "/" <factor>
+
+<factor> ::= <primary>
+ | "!" <factor> | "~" factor
+ | "+" <factor> | "--" <factor>
<primary> ::=
<integer-literal> | <string-literal> | <char-literal> | <identifier>
-\alt "<" <plain-type> ">"
-\alt "{" <c-fragment> "}"
-\alt "?" <s-expression>
-\alt "(" <expression> ")"
+\alt "<" <plain-type> ">" | "{" <c-fragment> "}" | "?" <s-expression>
+ | "(" <expression> ")"
\end{grammar}
\emph{Property sets} are a means for associating miscellaneous information
Finally, an S-expression preceded by @|?| causes the expression to be read in
the current package (which is always @|sod-user| at the start of a module)
and immediately evaluated (using @|eval|); the resulting value is converted
-into a property value using the \descref{decode-property}[generic
-function]{gf}.
+into a property value using the \descref{gf}{decode-property}[generic
+function].
\subsection{Property output types and coercions}
When a property value is inspected by the Sod translator, or an extension, it
is \emph{coerced} so as to conform to a requested output type. This coercion
-process is performed by the \descref{coerce-property-value}[generic
-function]{gf}, and additional output types and coercions can be defined by
+process is performed by the \descref{gf}{coerce-property-value}[generic
+function], and additional output types and coercions can be defined by
extensions. The built-in output types coercions, from the value types listed
above, are as follows.
\item The @|boolean| output type denotes a boolean value, which may be either
true or false. A value of type @|id| is considered true if it is @|true|,
- @|t|, @|yes|, @|on|, or @|verily|; or false if it is @|false|, @|nil|,
- @|no|, @|off|, or @|nowise|; it is erroneous to provide any other
- identifier where a boolean value is wanted. A value of type @|int| is
- considered true if it is nonzero, or false if it is zero.
+ @|t|, @|yes|, @|on|, @|yup|, or @|verily|; or false if it is @|false|,
+ @|nil|, @|no|, @|off|, @|nope|, or @|nowise|; it is erroneous to provide
+ any other identifier where a boolean value is wanted. A value of type
+ @|int| is considered true if it is nonzero, or false if it is zero.
\item The @|symbol| output type denotes a Lisp symbol.
upper; if the name contains letters of both cases, then it is not changed.
For example, @|foo45| becomes @|FOO45|, or \emph{vice-versa}; but @|Splat|
remains as it is. Second, the name is subjected to \emph{separator
- switching}: all underscores in the name are replaced with hyphens (and
+ switching}: all underscores in the name are replaced with hyphens (and
\emph{vice-versa}, though hyphens aren't permitted in identifiers in the
first place). Finally, the resulting name is interned in the current
package, which will usually be @|sod-user| unless changed explicitly by the
\begin{grammar}
<module> ::= @<definition>^*
-<definition> ::= <import-definition>
+<definition> ::= <property-definition> \fixme{undefined}
+\alt <import-definition>
\alt <load-definition>
\alt <lisp-definition>
\alt <code-definition>
\alt <typename-definition>
\alt <class-definition>
+\alt <other-definition> \fixme{undefined}
\end{grammar}
A @<module> is the top-level syntactic item: a source file presented to Sod
\begin{itemize}
\item The module name @<string> is converted into a filename by appending
@`.sod', if it has no extension already.\footnote{%
- Technically, what happens is \textsf{(merge-pathnames name (make-pathname
- :type "SOD" :case :common))}, so exactly what this means varies
- according to the host system.} %
+ Technically, what happens is @|(merge-pathnames name (make-pathname :type
+ "SOD" :case :common))|, so exactly what this means varies according to
+ the host system.} %
\item The file is looked for relative to the directory containing the
importing module.
\item If that fails, then the file is looked for in each directory on the
\end{itemize}
At this point, if the file has previously been imported, nothing further
happens.\footnote{%
- This check is done using \textsf{truename}, so it should see through simple
+ This check is done using @|truename|, so it should see through simple
tricks like symbolic links. However, it may be confused by fancy things
like bind mounts and so on.} %
\begin{itemize}
\item The name @<string> is converted into a filename by appending @`.lisp',
if it has no extension already.\footnote{%
- Technically, what happens is \textsf{(merge-pathnames name (make-pathname
- :type "LISP" :case :common))}, so exactly what this means varies
- according to the host system.} %
+ Technically, what happens is @|(merge-pathnames name (make-pathname :type
+ "LISP" :case :common))|, so exactly what this means varies according to
+ the host system.} %
\item A search is then made in the same manner as for module imports
(\xref{sec:syntax-module}).
\end{itemize}
-If the file is found, it is loaded using the host Lisp's \textsf{load}
-function.
+If the file is found, it is loaded using the host Lisp's @|load| function.
Note that Sod doesn't attempt to compile Lisp files, or even to look for
existing compiled files. The right way to package a substantial extension to
the Sod translator is to provide the extension as a standard ASDF system (or
similar) and leave a dropping @|foo-extension.lisp| in the module path saying
something like
-\begin{quote}
- \textsf{(asdf:load-system :foo-extension)}
-\end{quote}
+\begin{prog}
+ (asdf:load-system :foo-extension)
+\end{prog}
which will arrange for the extension to be compiled if necessary.
(This approach means that the language doesn't need to depend on any
\begin{grammar}
<code-definition> ::=
- "code" <identifier> ":" <item-name> @[<constraints>@]
+ "code" <reason> ":" <item-name> @[<constraints>@]
"{" <c-fragment> "}"
+\alt
+ "code" <reason> ":" <constraints> ";"
+
+<reason> ::= <identifier>
<constraints> ::= "[" <list>$[\mbox{@<constraint>}]$ "]"
<constraint> ::= @<item-name>^+
-<item-name> ::= <identifier> @! "(" @<identifier>^+ ")"
+<item-name> ::= <identifier> | "(" @<identifier>^+ ")"
\end{grammar}
The @<c-fragment> will be output unchanged to one of the output files.
\alt <fragment-item>
\alt <message-item>
\alt <method-item>
+\alt <other-item> \fixme{undefined}
\end{grammar}
A full class definition provides a complete description of a class.
class. It is an error if any of these @<identifier>s does not name a defined
class. The superclass list is required, and must not be empty; listing
@|SodObject| as your class's superclass is a good choice if nothing else
-seems suitable. It's not possible to define a \emph{root class} in the Sod
-language: you must use Lisp to do this, and it's quite involved.
+seems suitable. A class with no direct superclasses is called a \emph{root
+class}. It is not possible to define a root class in the Sod language: you
+must use Lisp to do this, and it's quite involved.
The @<properties> provide additional information. The standard class
properties are as follows.
\begin{description}
\item[@|message_class|] A symbol naming the Lisp class to use to represent
the message.
+\item[@|readonly|] A boolean indicating whether the message guarantees not to
+ modify its receiver. If this is true, the receiver will be declared
+ @"const".
\item[@|combination|] A keyword naming the aggregating method combination to
use.
\item[@|most_specific|] A keyword, either @`first' or @`last', according to