\chapter{Module syntax} \label{ch:syntax}
%%%--------------------------------------------------------------------------
-\section{Notation} \label{sec:syntax.notation}
-
-Fortunately, Sod is syntactically quite simple. The notation is slightly
-unusual in order to make the presentation shorter and easier to read.
-
-Anywhere a simple nonterminal name $x$ may appear in the grammar, an
-\emph{indexed} nonterminal $x[a_1, \ldots, a_n]$ may also appear. On the
-left-hand side of a production rule, the indices $a_1$, \ldots, $a_n$ are
-variables which vary over all nonterminal and terminal symbols, and the
-variables may also appear on the right-hand side in place of a nonterminal.
-Such a rule stands for a family of rules, in each variable is replaced by
-each possible simple nonterminal or terminal symbol.
-
-The letter $\epsilon$ denotes the empty nonterminal
-\begin{quote}
- \syntax{$\epsilon$ ::=}
-\end{quote}
-
-The following indexed productions are used throughout the grammar, some often
-enough that they deserve special notation.
-\begin{itemize}
-\item @[$x$@] abbreviates @<optional>$[x]$, denoting an optional occurrence
- of $x$:
- \begin{quote}
- \syntax{@[$x$@] ::= <optional>$[x]$ ::= $\epsilon$ @! $x$}
- \end{quote}
-\item $x^*$ abbreviates @<zero-or-more>$[x]$, denoting a sequence of zero or
- more occurrences of $x$:
- \begin{quote}
- \syntax{$x^*$ ::= <zero-or-more>$[x]$ ::=
- $\epsilon$ @! <zero-or-more>$[x]$ $x$}
- \end{quote}
-\item $x^+$ abbreviates @<one-or-more>$[x]$, denoting a sequence of zero or
- more occurrences of $x$:
- \begin{quote}
- \syntax{$x^+$ ::= <one-or-more>$[x]$ ::= <zero-or-more>$[x]$ $x$}
- \end{quote}
-\item @<list>$[x]$ denotes a sequence of one or more occurrences of $x$
- separated by commas:
- \begin{quote}
- \syntax{<list>$[x]$ ::= $x$ @! <list>$[x]$ "," $x$}
- \end{quote}
-\end{itemize}
-
-%%%--------------------------------------------------------------------------
\section{Lexical syntax} \label{sec:syntax.lex}
Whitespace and comments are discarded. The remaining characters are
<digit-char> ::= "0" | <nonzero-digit-char>
-<nonzero-digit-char> ::= "1" | "2" $| \cdots |$ "9"
+<nonzero-digit-char> ::= "1" | "2" $| \ldots |$ "9"
\end{grammar}
The precise definition of @<alpha-char> is left to the function
<octal-integer> ::= "0" @["o"|"O"@] @<octal-digit-char>^+
-<octal-digit-char> ::= "0" | "1" $| \cdots |$ "7"
+<octal-digit-char> ::= "0" | "1" $| \ldots |$ "7"
<hex-integer> ::= "0" @("x"|"X"@) @<hex-digit-char>^+
<not-star-or-slash> ::= any character other than "*" or "/"
-<line-comment> ::= "//" @<not-newline>^* <newline>
+<line-comment> ::= "/\,/" @<not-newline>^* <newline>
<newline> ::= a newline character
<not-newline> ::= any character other than newline
\end{grammar}
-Comments are exactly as in C99: both traditional block comments `\texttt{/*}
-\dots\ \texttt{*/}' and \Cplusplus-style `\texttt{//} \dots' comments are
-permitted and ignored.
+Comments are exactly as in C99: both traditional block comments `@|/*| \dots\
+@|*/|' and \Cplusplus-style `@|/\,/| \dots' comments are permitted and
+ignored.
\subsection{Special nonterminals} \label{sec:syntax.lex.special}
A @<module> is the top-level syntactic item. A module consists of a sequence
of definitions.
+[FIXME]
+Properties:
+\begin{description}
+\item[@"module_class"] A symbol naming the Lisp class to use to
+ represent the module.
+\item[@"guard"] An identifier to use as the guard symbol used to prevent
+ multiple inclusion in the header file.
+\end{description}
+
+
\subsection{Simple definitions} \label{sec:syntax.module.simple}
\subsubsection{Importing modules}
\subsubsection{The expression evaluator}
\begin{grammar}
-<expression> ::= <term> | <expression> "+" <term> | <expression> "-" <term>
+<expression> ::= <term> | <expression> "+" <term> | <expression> "--" <term>
<term> ::= <factor> | <term> "*" <factor> | <term> "/" <factor>
-<factor> ::= <primary> | "+" <factor> | "-" <factor>
+<factor> ::= <primary> | "+" <factor> | "--" <factor>
<primary> ::=
<integer-literal> | <string-literal> | <char-literal> | <identifier>
+\alt "<" <plain-type> ">"
\alt "?" <s-expression>
\alt "(" <expression> ")"
\end{grammar}
\alt "bool" | "_Bool"
\alt "imaginary" | "_Imaginary" | "complex" | "_Complex"
\alt <qualifier>
+\alt <storage-specifier>
\alt <atomic-type>
<qualifier> ::= <atomic> | "const" | "volatile" | "restrict"
+<plain-type> ::= @<declaration-specifier>^+ <abstract-declarator>
+
<atomic-type> ::=
- <atomic> "(" @<declaration-specifier>^+ <abstract-declarator> ")"
+ <atomic> "(" <plain-type> ")"
<atomic> ::= "atomic" | "_Atomic"
+<storage-specifier> ::= <alignas> "(" <c-fragment> ")"
+
+<alignas> ::= "alignas" "_Alignas"
+
<type-name> ::= <identifier>
\end{grammar}
Declaration specifiers may appear in any order. However, not all
combinations are permitted. A declaration specifier must consist of zero or
-more @<qualifier>s, and one of the following, up to reordering.
+more @<qualifier>s, zero or more @<storage-specifier>s, and one of the
+following, up to reordering.
\begin{itemize}
\item @<type-name>
\item @<atomic-type>
\subsubsection{Declarators}
\begin{grammar}
-<declarator>$[k]$ ::= @<pointer>^* <primary-declarator>$[k]$
+<declarator>$[k, a]$ ::= @<pointer>^* <primary-declarator>$[k, a]$
-<primary-declarator>$[k]$ ::= $k$
-\alt "(" <primary-declarator>$[k]$ ")"
-\alt <primary-declarator>$[k]$ @<declarator-suffix>
+<primary-declarator>$[k, a]$ ::= $k$
+\alt "(" <primary-declarator>$[k, a]$ ")"
+\alt <primary-declarator>$[k, a]$ @<declarator-suffix>$[a]$
<pointer> ::= "*" @<qualifier>^*
-<declarator-suffix> ::= "[" <c-fragment> "]"
-\alt "(" <arguments> ")"
+<declarator-suffix>$[a]$ ::= "[" <c-fragment> "]"
+\alt "(" $a$ ")"
-<argument-list> ::= $\epsilon$ | "..."
-\alt <list>$[\mbox{@<argument>}]$ @["," "..."@]
+<argument-list> ::= $\epsilon$ | "\dots"
+\alt <list>$[\mbox{@<argument>}]$ @["," "\dots"@]
<argument> ::= @<declaration-specifier>^+ <argument-declarator>
-<abstract-declarator> ::= <declarator>$[\epsilon]$
-
-<argument-declarator> ::= <declarator>$[\mbox{@<identifier> @! $\epsilon$}]$
+<abstract-declarator> ::= <declarator>$[\epsilon, \mbox{@<argument-list>}]$
-<simple-declarator> ::= <declarator>$[\mbox{@<identifier>}]$
+<argument-declarator> ::=
+ <declarator>$[\mbox{@<identifier> @! $\epsilon$}, \mbox{@<argument-list>}]$
-<dotted-name> ::= <identifier> "." <identifier>
+<simple-declarator> ::=
+ <declarator>$[\mbox{@<identifier>}, \mbox{@<argument-list>}]$
\end{grammar}
The declarator syntax is taken from C, but with some differences.
The remaining differences are (I hope) a matter of presentation rather than
substance.
+There is additional syntax to support messages and methods which accept
+keyword arguments.
+
+\begin{grammar}
+<keyword-argument> ::= <argument> @["=" <c-fragment>@]
+
+<keyword-argument-list> ::=
+ @[<list>$[\mbox{@<argument>}]$@]
+ "?" @[<list>$[\mbox{@<keyword-argument>}]$@]
+
+<method-argument-list> ::= <argument-list> @! <keyword-argument-list>
+
+<dotted-name> ::= <identifier> "." <identifier>
+
+<keyword-declarator>$[k]$ ::=
+ <declarator>$[k, \mbox{@<method-argument-list>}]$
+\end{grammar}
+
\subsection{Class definitions} \label{sec:syntax.module.class}
A @<class-forward-declaration> informs Sod that an @<identifier> will be used
to name a class which is currently undefined. Forward declarations are
necessary in order to resolve certain kinds of circularity. For example,
-\begin{listing}
-class Sub;
+\begin{prog}
+class Sub; \\+
-class Super : SodObject {
- Sub *sub;
-};
+class Super: SodObject \{ \\ \ind
+ Sub *sub; \-\\
+\}; \\+
-class Sub : Super {
- /* ... */
-};
-\end{listing}
+class Sub: Super \{ \\ \ind
+ /* \dots\ */ \-\\
+\};
+\end{prog}
\subsubsection{Full class definitions}
\begin{grammar}
<class-item> ::= <slot-item>
\alt <initializer-item>
+\alt <initarg-item>
+\alt <fragment-item>
\alt <message-item>
\alt <method-item>
\end{grammar}
The @<list>$[\mbox{@<identifier>}]$ names the direct superclasses for the new
class. It is an error if any of these @<identifier>s does not name a defined
-class.
+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.
The @<properties> provide additional information. The standard class
properties are as follows.
which messages it will respond to, and what its behaviour will be when it
receives them. The property value must be an identifier naming a defined
subclass of @"SodClass". The default metaclass is @"SodClass".
- %%% FIXME xref to theory
+ See \xref{sec:concepts.metaclasses} for more details.
\item[@"nick"] A nickname for the class, to be used to distinguish it from
other classes in various limited contexts. The property value must be an
identifier; the default is constructed by forcing the class name to
interpreted as being a @<message-item> or @<method-item>. Pointers to
functions are fine.
+Properties:
+\begin{description}
+\item[@"slot_class"] A symbol naming the Lisp class to use to represent the
+ direct slot.
+\item[@"initarg"] An identifier naming an initialization argument which can
+ be used to provide a value for the slot. See
+ \xref{sec:concepts.lifecycle.birth} for the details.
+\end{description}
+
An @<initializer>, if present, is treated as if a separate
@<initializer-item> containing the slot name and initializer were present.
For example,
-\begin{listing}
-[nick = eg]
-class Example : Super {
- int foo = 17;
-};
-\end{listing}
+\begin{prog}
+[nick = eg] \\
+class Example: Super \{ \\ \ind
+ int foo = 17; \-\\
+\};
+\end{prog}
means the same as
-\begin{listing}
-[nick = eg]
-class Example : Super {
- int foo;
- eg.foo = 17;
-};
-\end{listing}
+\begin{prog}
+[nick = eg] \\
+class Example: Super \{ \\ \ind
+ int foo; \\
+ eg.foo = 17; \-\\
+\};
+\end{prog}
\subsubsection{Initializer items}
\begin{grammar}
<initializer-item> ::= @["class"@] <list>$[\mbox{@<slot-initializer>}]$ ";"
-<slot-initializer> ::= <dotted-name> "=" <initializer>
+<slot-initializer> ::= <dotted-name> @["=" <initializer>@]
-<initializer> :: "{" <c-fragment> "}" | <c-fragment>
+<initializer> :: <c-fragment>
\end{grammar}
An @<initializer-item> provides an initial value for one or more slots. If
class's superclasses (including itself); the second must be the name of a
slot defined in that superclass.
-The initializer has one of two forms.
-\begin{itemize}
-\item A @<c-fragment> enclosed in braces denotes an aggregate initializer.
- This is suitable for initializing structure, union or array slots.
-\item A @<c-fragment> \emph{not} beginning with an open brace is a `bare'
- initializer, and continues until the next @`,' or @`;' which is not within
- nested brackets. Bare initializers are suitable for initializing scalar
- slots, such as pointers or integers, and strings.
-\end{itemize}
+Properties:
+\begin{description}
+\item[@"initializer_class"] A symbol naming the Lisp class to use to
+ represent the initializer.
+\item[@"initarg"] An identifier naming an initialization argument which can
+ be used to provide a value for the slot. See
+ \xref{sec:concepts.lifecycle.birth} for the details. An initializer item
+ must have either an @|initarg| property, or an initializer expression, or
+ both.
+\item[@"initarg_class"] A symbol naming the Lisp class to use to represent
+ the initarg. Only permitted if @"initarg" is also set.
+\end{description}
+
+Each class may define at most one initializer item with an explicit
+initializer expression for a given slot.
+
+\subsubsection{Initarg items}
+\begin{grammar}
+<initarg-item> ::=
+ "initarg"
+ @<declaration-specifier>^+
+ <list>$[\mbox{@<init-declarator>}]$ ";"
+\end{grammar}
+Properties:
+\begin{description}
+\item[@"initarg_class"] A symbol naming the Lisp class to use to represent
+ the initarg.
+\end{description}
+
+\subsubsection{Fragment items}
+\begin{grammar}
+<fragment-item> ::= <fragment-kind> "{" <c-fragment> "}"
+
+<fragment-kind> ::= "init" | "teardown"
+\end{grammar}
\subsubsection{Message items}
\begin{grammar}
<keyword-declarator>$[\mbox{@<identifier>}]$
@[<method-body>@]
\end{grammar}
+Properties:
+\begin{description}
+\item[@"message_class"] A symbol naming the Lisp class to use to represent
+ the message.
+\item[@"combination"] A keyword naming the aggregating method combination to
+ use.
+\item[@"most_specific"] A keyword, either @`first' or @`last', according to
+ whether the most specific applicable method should be invoked first or
+ last.
+\end{description}
+
+Properties for the @|custom| aggregating method combination:
+\begin{description}
+\item[@"retvar"] An identifier for the return value from the effective
+ method. The default is @|sod__ret|. Only permitted if the message return
+ type is not @|void|.
+\item[@"valvar"] An identifier holding each return value from a direct method
+ in the effective method. The default is @|sod__val|. Only permitted if
+ the method return type (see @"methty" below) is not @|void|.
+\item[@"methty"] A C type, which is the return type for direct methods of
+ this message.
+\item[@"decls"] A code fragment containing declarations to be inserted at the
+ head of the effective method body. The default is to insert nothing.
+\item[@"before"] A code fragment containing initialization to be performed at
+ the beginning of the effective method body. The default is to insert
+ nothing.
+\item[@"empty"] A code fragment executed if there are no primary methods;
+ it should usually store a suitable (identity) value in @<retvar>. The
+ default is not to emit an effective method at all if there are no primary
+ methods.
+\item[@"first"] A code fragment to set the return value after calling the
+ first applicable direct method. The default is to use the @"each"
+ fragment.
+\item[@"each"] A code fragment to set the return value after calling a direct
+ method. If @"first" is also set, then it is used after the first direct
+ method instead of this. The default is to insert nothing, which is
+ probably not what you want.
+\item[@"after"] A code fragment inserted at the end of the effective method
+ body. The default is to insert nothing.
+\item[@"count"] An identifier naming a variable to be declared in the
+ effective method body, of type @|size_t|, holding the number of applicable
+ methods. The default is not to provide such a variable.
+\end{description}
\subsubsection{Method items}
\begin{grammar}
<method-body> ::= "{" <c-fragment> "}" | "extern" ";"
\end{grammar}
+Properties:
+\begin{description}
+\item[@"method_class"] A symbol naming the Lisp class to use to represent
+ the direct method.
+\item[@"role"] A keyword naming the direct method's rôle. For the built-in
+ `simple' message classes, the acceptable rôle names are @|before|,
+ @|after|, and @|around|. By default, a primary method is constructed.
+\end{description}
%%%----- That's all, folks --------------------------------------------------