X-Git-Url: https://git.distorted.org.uk/~mdw/sod/blobdiff_plain/4fc52153b366aae911eede7c404c24b0e74ab604..f458e64e36509fa8c204f1dbcafff1d3dc059619:/doc/syntax.tex?ds=inline

diff --git a/doc/syntax.tex b/doc/syntax.tex
index a9dd695..73a353a 100644
--- a/doc/syntax.tex
+++ b/doc/syntax.tex
@@ -26,51 +26,6 @@
 \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
@@ -104,7 +59,7 @@ could be a token.
 
 <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
@@ -157,7 +112,7 @@ discouraged.
 
 <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>^+
 
@@ -196,16 +151,16 @@ binary.  However, length and signedness indicators are not permitted.
 
 <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}
@@ -255,6 +210,16 @@ brackets, braces or parenthesis ends the fragment.
 A @<module> is the top-level syntactic item.  A module consists of a sequence
 of definitions.
 
+\fixme{describe syntax; expand}
+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}
@@ -407,14 +372,15 @@ though the only operators currently defined act on integer values only.
 
 \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}
@@ -451,8 +417,21 @@ recognized.
 \alt "bool" | "_Bool"
 \alt "imaginary" | "_Imaginary" | "complex" | "_Complex"
 \alt <qualifier>
+\alt <storage-specifier>
+\alt <atomic-type>
 
-<qualifier> ::= "const" | "volatile" | "restrict"
+<qualifier> ::= <atomic> | "const" | "volatile" | "restrict"
+
+<plain-type> ::= @<declaration-specifier>^+ <abstract-declarator>
+
+<atomic-type> ::=
+  <atomic> "(" <plain-type> ")"
+
+<atomic> ::= "atomic" | "_Atomic"
+
+<storage-specifier> ::= <alignas> "(" <c-fragment> ")"
+
+<alignas> ::= "alignas" "_Alignas"
 
 <type-name> ::= <identifier>
 \end{grammar}
@@ -469,9 +448,11 @@ defined in the built-in module.
 
 Declaration specifiers may appear in any order.  However, not all
 combinations are permitted.  A declaration specifier must consist of zero or
-more @<qualifiers>, 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>
 \item @"struct" @<identifier>, @"union" @<identifier>, @"enum" @<identifier>
 \item @"void"
 \item @"_Bool", @"bool"
@@ -493,27 +474,29 @@ All of these have their usual C meanings.
 
 \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>
 
-<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.
@@ -528,6 +511,24 @@ 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}
 
@@ -544,17 +545,17 @@ substance.
 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}
@@ -567,6 +568,8 @@ class Sub : Super {
 
 <class-item> ::= <slot-item>
 \alt <initializer-item>
+\alt <initarg-item>
+\alt <fragment-item>
 \alt <message-item>
 \alt <method-item>
 \end{grammar}
@@ -580,7 +583,10 @@ names, to distinguish them from other kinds of identifiers.
 
 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.
@@ -595,7 +601,7 @@ 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
@@ -622,31 +628,42 @@ It is not possible to declare a slot with function type: such an item is
 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.
+\item[@"initarg_class"] A symbol naming the Lisp class to use to represent
+  the initarg.  Only permitted if @"initarg" is also set.
+\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
@@ -657,15 +674,41 @@ The first component of the @<dotted-name> must be the nickname of one of the
 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}
@@ -674,6 +717,49 @@ The initializer has one of two forms.
   <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.  The default is the return type of the 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}
@@ -684,6 +770,14 @@ The initializer has one of two forms.
 
 <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 --------------------------------------------------
 
