+%%%--------------------------------------------------------------------------
+\section{Properties} \label{sec:syntax.prop}
+
+\begin{grammar}
+<properties> ::= "[" <list>$[\mbox{@<property>}]$ "]"
+
+<property> ::= <identifier> "=" <expression>
+
+<expression> ::= <logical-or>
+
+<logical-or> ::= <logical-and>
+ | <logical-or> "||" <logical-and>
+
+<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> ">" | "{" <c-fragment> "}" | "?" <s-expression>
+ | "(" <expression> ")"
+\end{grammar}
+
+\emph{Property sets} are a means for associating miscellaneous information
+with compile-time metaobjects such as modules, classes, messages, methods,
+slots, and initializers. By using property sets, additional information can
+be passed to extensions without the need to introduce idiosyncratic syntax.
+(That said, extensions can add additional first-class syntax, if necessary.)
+
+An error is reported if an unrecognized property is associated with an
+object.
+
+
+\subsection{Property values} \label{sec:syntax.prop.value}
+
+A property has a name, given as an @<identifier>, and a value computed by
+evaluating an @<expression>. The value can be one of a number of types.
+
+\begin{itemize}
+
+\item An @<integer-literal> denotes a value of type @|int|.
+
+\item Similarly @<string-literal> and @<char-literal> denote @|string| and
+ @|char| values respectively. Note that, as properties, characters are
+ quite distinct from integers, whereas in C, a character literal denotes a
+ value of type @|int|.
+
+\item There are no variables in the property-value syntax. Rather, an
+ @<identifier> denotes that identifier, as a value of type @|id|.
+
+\item A C type (a @<plain-type>, as described in \xref{sec:syntax.type})
+ between angle brackets, e.g., @|<int>|, or @|<char *>|, or @|<void (*(int,
+ void (*)(int)))(int)>|, denotes that C type, as a value of type @|type|.
+
+\item A @<c-fragment> within braces denotes the tokens between (and not
+ including) the braces, as a value of type @|c-fragment|.
+
+\end{itemize}
+
+As shown in the grammar, there are four binary operators, @"+" (addition),
+@"--" (subtraction), @"*" (multiplication), and @"/" (division);
+multiplication and division have higher precedence than addition and
+subtraction, and operators of the same precedence associate left-to-right.
+There are also unary @"+" (no effect) and @"--" (negation) operators, with
+higher precedence. All of the above operators act only on integer operands
+and yield integer results. (Although the unary @"+" operator yields its
+operand unchanged, an error is still reported if it is applied to a
+non-integer value.) There are currently no bitwise, logical, or comparison
+operators.
+
+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{gf}{decode-property}[generic
+function].
+
+
+\subsection{Property output types and coercions}
+\label{sec:syntax.prop.coerce}
+
+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{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.
+
+\begin{itemize}
+
+\item The output types @|int|, @|string|, @|char|, @|id|, and @|c-fragment|
+ correspond to the like-named value types described above. No coercions to
+ these output types are defined for the described value types.\footnote{%
+ There is a coercion to @|id| from the value type @|symbol|, but it is
+ only possible to generate a property value of type @|symbol| using Lisp.}
+
+\item The output type @|type| denotes a C type, as does the value type
+ @|type|. In addition, a value of type @|id| can be coerced to a C type if
+ it is the name of a class, a type name explicitly declared by @|typename|,
+ or it is one of: @|bool|, @|_Bool|, @|void|, @|char|, @|short|, @|int|,
+ @|signed|, @|unsigned|, @|long|, @|size_t|, @|ptrdiff_t|, @|wchar_t|,
+ or @|va_list|.
+
+\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|, @|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.
+
+ A value of type @|id| is coerced to a symbol as follows. First, the
+ identifier name is subjected to \emph{case inversion}: if all of the
+ letters in the name have the same case, either upper or lower, then they
+ are replaced with the corresponding letters in the opposite case, lower or
+ 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
+ \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
+ module.
+
+ A value of type @|string| is coerced to a symbol as follows. If the string
+ contains no colons, then it is case-inverted (but not separator-switched)
+ and interned in the current package. Otherwise, the string either has the
+ form $p @|:| q$, where $q$ does not begin with a colon (the
+ \emph{single-colon} case) or $p @|::| q$ (the \emph{double-colon} case);
+ where $p$ does not contain a colon. Both $p$ and $q$ are case-inverted
+ (but not separator-switched). If $p$ does not name a package, then an
+ error is reported; as a special case, if $p$ is empty, then it is
+ considered to name the @|keyword| package. Otherwise, $q$ is looked up as
+ a symbol name in package~$p$; in the single-colon case, if the symbol is
+ not an exported symbol in package~$p$, then an error is reported; in the
+ double-colon case, $q$ is interned in package~$p$ (and so there needn't be
+ an exported symbol -- or, indeed, and symbol at all -- named $q$
+ beforehand).
+
+\item The @|keyword| output type denotes symbols within the @|keyword|
+ package. Value of type @|id| or @|string| can be coerced to a @|keyword|
+ in the same way as to a @|symbol|, as described above, only the converted
+ name is looked up in the @|keyword| package rather than the current
+ package. (A @|string| can override this by specifying an explicit package
+ name, but this is unlikely to be very helpful.)
+
+\end{itemize}
+
+%%%--------------------------------------------------------------------------
+\section{Module syntax} \label{sec:syntax.module}