\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}
<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}
\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}
<qualifier> ::= <atomic> | "const" | "volatile" | "restrict"
+<plain-type> ::= @<declaration-specifier>^+ <abstract-declarator>
+
<atomic-type> ::=
- <atomic> "(" @<declaration-specifier>^+ <abstract-declarator> ")"
+ <atomic> "(" <plain-type> ")"
<atomic> ::= "atomic" | "_Atomic"
\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]$
+<abstract-declarator> ::= <declarator>$[\epsilon, \mbox{@<argument-list>}]$
<argument-declarator> ::= <declarator>$[\mbox{@<identifier> @! $\epsilon$}]$
-<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.
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}
+An @|initarg| property may be set on an instance slot initializer (or a
+direct slot definition). See \xref{sec:concepts.lifecycle.birth} for the
+details. An initializer item must have either an @|initarg| property, or an
+initializer expression, or both.
+
+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}
+
+\subsubsection{Fragment items}
+\begin{grammar}
+<fragment-item> ::= <fragment-kind> "{" <c-fragment> "}"
+
+<fragment-kind> ::= "init" | "teardown"
+\end{grammar}
\subsubsection{Message items}
\begin{grammar}