\begin{figure} \centering
\parbox{10pt}{\begin{tabbing}
- @|c-type| \\ \ind
- @|qualifiable-c-type| \\ \ind
- @|simple-c-type| \\ \ind
- @|c-class-type| \- \\
- @|tagged-c-type| \\ \ind
- @|c-struct-type| \\
- @|c-union-type| \\
- @|c-enum-type| \- \\
- @|c-atomic-type| \\
- @|c-pointer-type| \- \\
- @|c-array-type| \\
- @|c-function-type| \\ \ind
- @|c-keyword-function-type| \-
+ @|c-type| \\ \ind
+ @|qualifiable-c-type| \\ \ind
+ @|simple-c-type| \\ \ind
+ @|c-class-type| \-\\
+ @|tagged-c-type| \\ \ind
+ @|c-struct-type| \\
+ @|c-union-type| \\
+ @|c-enum-type| \-\\
+ @|c-atomic-type| \\
+ @|c-pointer-type| \-\\
+ @|c-array-type| \\
+ @|c-function-type| \\ \ind
+ @|c-keyword-function-type| \-
\end{tabbing}}
\caption{Classes representing C types}
\label{fig:codegen.c-types.classes}
not specified, clients may still not rely on receiving fresh objects.
A convenient S-expression notation is provided by the
-\descref{c-type}[macro]{mac}. Use of this macro is merely an abbreviation
+\descref{mac}{c-type}[macro]. Use of this macro is merely an abbreviation
for corresponding use of the various constructor functions, and therefore
interns type objects in the same manner. The syntax accepted by the macro
-can be extended in order to support new classes: see \descref{defctype}{mac},
-\descref{c-type-alias}{mac} and \descref{define-c-type-syntax}{mac}.
+can be extended in order to support new classes: see \descref{mac}{defctype},
+\descref{mac}{c-type-alias} and \descref{mac}{define-c-type-syntax}.
The descriptions of each of the various classes include descriptions of the
initargs which may be passed to @|make-instance| when constructing a new
There are two protocols for printing C types. Unfortunately they have
similar names.
\begin{itemize}
-\item The \descref{print-c-type}[function]{gf} prints a C type value using
+\item The \descref{gf}{print-c-type}[function] prints a C type value using
the S-expression notation. It is mainly useful for diagnostic purposes.
-\item The \descref{pprint-c-type}[function]{gf} prints a C type as a
+\item The \descref{gf}{pprint-c-type}[function] prints a C type as a
C-syntax declaration.
\end{itemize}
Neither generic function defines a default primary method; subclasses of
@|c-type| must define their own methods in order to print correctly.
+\begin{describe}{fun}{c-name-case @<name> @> @<string>}
+\end{describe}
+
\subsection{The C type root class} \label{sec:clang.c-types.root}
\end{describe}
\begin{describe}{mac}
- {defctype \=@{ @<name> @! (@<name>^+) @} @<type-spec> \+ \\
- @[[ @|:export| @<export-flag> @]]^* \-
- \nlret @<names>}
+ {defctype \=@{ @<name> @! (@<name>^+) @} @<type-spec> \+\\
+ @[[ @|:export| @<export-flag> @]]^*
+ \-\nlret @<names>}
Defines a new symbolic type specifier @<name>; if a list of @<name>s is
given, then all are defined in the same way. The type constructed by using
any of the @<name>s is as described by the type specifier @<type-spec>.
\end{describe}
\begin{describe}{mac}
- {define-c-type-syntax @<name> @<lambda-list> \\ \ind
- @[[ @<declaration>^* @! @<doc-string> @]] \\
- @<form>^* \-
- \nlret @<name>}
+ {define-c-type-syntax @<name> @<lambda-list> \\ \ind
+ @[[ @<declaration>^* @! @<doc-string> @]] \\
+ @<form>^*
+ \-\nlret @<name>}
Defines the symbol @<name> as a new type operator. When a list of the form
@|(@<name> @<argument>^*)| is used as a type specifier, the @<argument>s
are bound to fresh variables according to @<lambda-list> (a destructuring
\begin{describe}{gf}{expand-c-type-spec @<type-spec> @> @<form>}
Returns the Lisp form that @|(c-type @<type-spec>)| would expand into.
- If @<type-spec> is a list, then \descref{expand-c-type-form}{fun} is
+ If @<type-spec> is a list, then \descref{gf}{expand-c-type-form} is
invoked.
\end{describe}
\begin{describe}{gf}{expand-c-type-form @<head> @<tail> @> @<form>}
- Returns the Lisp form that @|(c-type (@<head> . @<tail>)| would expand
+ Returns the Lisp form that @|(c-type (@<head> . @<tail>))| would expand
into.
\end{describe}
The generic function @|c-type-equal-p| uses the @|and| method combination.
- \begin{describe}{meth}{c-type-equal-p @<c-type>_1 @<c-type>_2}
+ \begin{describe}{meth}{t,t}{c-type-equal-p @<c-type>_1 @<c-type>_2}
A default primary method for @|c-type-equal-p| is defined. It simply
returns @|nil|. This way, methods can specialize on both arguments
without fear that a call will fail because no methods are applicable.
\end{describe}
- \begin{describe}{ar-meth}{c-type-equal-p @<c-type>_1 @<c-type>_2}
+ \begin{describe}{ar-meth}{}{c-type-equal-p @<c-type>_1 @<c-type>_2}
A default around-method for @|c-type-equal-p| is defined. It returns
true if @<c-type>_1 and @<c-type>_2 are @|eql|; otherwise it delegates to
the primary methods. Since several common kinds of C types are interned,
directly attached. If the @<kernel> function intends to provide its own
additional declarator operators, it should check the @<priority> in order
to determine whether parentheses are necessary. See also the
- \descref{maybe-in-parens}[macro]{mac}.
+ \descref{mac}{maybe-in-parens}[macro].
The @<spacep> argument indicates whether a space needs to be printed in
order to separate the declarator from the declaration specifiers. A kernel
which contains an identifier should insert a space before the identifier
when @<spacep> is non-nil. An `empty' kernel, as found in an abstract
declarator (one that specifies no name), looks more pleasing without a
- trailing space. See also the \descref{c-type-space}[function]{fun}.
+ trailing space. See also the \descref{fun}{c-type-space}[function].
Every concrete subclass of @|c-type| is expected to provide a primary
method on this function. There is no default primary method.
- \begin{describe}{ar-meth}{pprint-c-type @<c-type> @<stream> @<kernel>}
+ \begin{describe}{ar-meth}{}{pprint-c-type @<c-type> @<stream> @<kernel>}
A default around method is defined on @|pprint-c-type| which `canonifies'
non-function @<kernel> arguments. In particular:
\begin{itemize}
\begin{table}
\begin{tabular}[C]{*2{>{\codeface}l}l} \hlx*{hv}
- \thd{\textbf{C name}} & \thd{\textbf{Lisp name}} \\ \hlx{vhv}
- _Atomic & :atomic \\
- const & :const \\
- restrict & :restrict \\
- volatile & :volatile \\ \hlx*{vh}
+ \thd{C name} & \thd{Lisp name} \\ \hlx{vhv}
+ _Atomic & :atomic \\
+ const & :const \\
+ restrict & :restrict \\
+ volatile & :volatile \\ \hlx*{vh}
\end{tabular}
\caption{C and Lisp qualifier names} \label{tab:clang.ctypes.qual}
\end{table}
The default behaviour, on output, is to convert keywords to lowercase and
hope for the best: special cases can be dealt with by adding appropriate
-methods to \descref{c-qualifier-keyword}{gf}.
+methods to \descref{gf}{c-qualifier-keyword}.
\begin{describe}{cls}{qualifiable-c-type (c-type) \&key :qualifiers}
The class @|qualifiable-c-type| describes C types which can bear
The class @|qualifiable-c-type| is abstract.
\end{describe}
+\begin{describe}{fun}
+ {canonify-qualifiers @<qualifiers> @> @<canonfied-qualifiers>}
+\end{describe}
+
\begin{describe}{gf}{c-type-qualifiers @<c-type> @> @<list>}
Returns the qualifiers of the @|qualifiable-c-type| instance @<c-type> as
an immutable list.
\end{describe}
-\begin{describe}{fun}{qualify-type @<c-type> @<qualifiers> @> @<c-type>}
+\begin{describe}{fun}{qualify-c-type @<c-type> @<qualifiers> @> @<c-type>}
The argument @<c-type> must be an instance of @|qualifiable-c-type|,
currently bearing no qualifiers, and @<qualifiers> a list of qualifier
keywords. The result is a C type object like @<c-type> except that it
methods exist for qualifier keywords which need special handling, such as
@|:atomic|; they are not listed here explicitly.
- \begin{describe}{meth}{c-qualifier-keyword @<keyword> @> @<string>}
+ \begin{describe}{meth}{keyword}
+ {c-qualifier-keyword @<keyword> @> @<string>}
Returns the @<keyword>'s print-name, in lower case. This is sufficient
for the standard qualifiers @|:const|, @|:restrict|, and @|:volatile|.
\end{describe}
Returns the Lisp form that @<spec> expands to within @|(c-type (specs
@<subtype> @<spec>))|.
- If @<spec> is a list, then \descref{expand-c-storage-specifier-form} is
+ If @<spec> is a list, then \descref{gf}{expand-c-storage-specifier-form} is
invoked.
\end{describe}
Two simple type objects are equal if and only if they have @|string=| names
and matching qualifiers.
+ \def\x#1{\desclabel{const}{c-type-#1}}
+ \x{bool} \x{char} \x{wchar-t} \x{signed-char} \x{unsigned-char} \x{short}
+ \x{unsigned-short} \x{int} \x{unsigned} \x{long} \x{unsigned-long}
+ \x{long-long} \x{unsigned-long-long} \x{size-t} \x{ptrdiff-t} \x{float}
+ \x{double} \x{long-double} \x{float-imaginary} \x{double-imaginary}
+ \x{long-double-imaginary} \x{float-complex} \x{double-complex}
+ \x{long-double-complex} \x{va-list} \x{void}
+ \crossproduct\x{{{int}{uint}}{{}{-least}{-fast}}{{8}{16}{32}{64}}{{-t}}}
+ \crossproduct\x{{{int}{uint}}{{ptr}{max}}{{-t}}}
+
A number of symbolic type specifiers for builtin types are predefined as
shown in \xref{tab:codegen.c-types.simple}. These are all defined as if by
@|define-simple-c-type|, so can be used to construct qualified types.
@|ullong| \\ \hlx{v}
@|size_t| & @|size-t| \\ \hlx{}
@|ptrdiff_t| & @|ptrdiff-t| \\ \hlx{v}
+ @|int$n$_t| & @|int$n$-t|
+ (for $n \in \{ @|8|, @|16|, @|32|, @|64| \}$)
+ \\ \hlx{}
+ @|uint$n$_t| & @|uint$n$-t| \\ \hlx{}
+ @|int_least$n$_t| & @|int_least$n$-t| \\ \hlx{}
+ @|uint_least$n$_t| & @|uint_least$n$-t| \\ \hlx{}
+ @|int_fast$n$_t| & @|int_fast$n$-t| \\ \hlx{}
+ @|uint_fast$n$_t| & @|uint_fast$n$-t| \\ \hlx{v}
+ @|intptr_t| & @|intptr-t| \\ \hlx{}
+ @|uintptr_t| & @|uintptr-t| \\ \hlx{}
+ @|intmax_t| & @|intmax-t| \\ \hlx{}
+ @|uintmax_t| & @|uintmax-t| \\ \hlx{v}
@|float| & @|float| \\ \hlx{}
@|double| & @|double| \\ \hlx{}
@|long double| & @|long-double| \\ \hlx{v}
\end{describe}
\begin{describe}{mac}
- {define-simple-c-type \=@{ @<name> @! (@<name>^+) @} @<string> \+ \\
- @[[ @|:export| @<export-flag> @]] \-
- \nlret @<name>}
+ {define-simple-c-type
+ \=@{ @<name> @! (@<name>^+) @}
+ @{ @<string> @! (@<string>^*) @} \+\\
+ @[[ @|:export| @<export-flag> @]]
+ \-\nlret @<name>}
Define type specifiers for a new simple C type. Each symbol @<name> is
defined as a symbolic type specifier for the (unique interned) simple C
- type whose name is the value of @<string>. Further, each @<name> is
- defined to be a type operator: the type specifier @|(@<name>
+ type whose name is the value of (the first) @<string>. Further, each
+ @<name> is defined to be a type operator: the type specifier @|(@<name>
@<qualifier>^*)| evaluates to the (unique interned) simple C type whose
- name is @<string> and which has the @<qualifiers> (which are evaluated).
+ name is (the first) @<string> and which has the @<qualifiers> (which are
+ evaluated).
- Furthermore, a variable @|c-type-@<name>| is defined, for the first @<name>
- only, and initialized with the newly constructed C type object.
+ Each of the @<string>s is associated with the resulting type for retrieval
+ by \descref{fun}{find-simple-c-type}. Furthermore, a variable
+ @|c-type-@<name>| is defined, for the first @<name> only, and initialized
+ with the newly constructed C type object.
If @<export-flag> is true, then the @|c-type-@<name>| variable name, and
all of the @<name>s, are exported from the current package.
\end{describe}
+\begin{describe}{fun}
+ {find-simple-c-type @<string> @> @{ @<simple-c-type> @! @|nil| @}}
+ If @<string> is the name of a simple C type, as established by the
+ \descref{mac}{define-simple-c-type}[macro], then return the corresponding
+ @|simple-c-type| object; otherwise, return @|nil|.
+\end{describe}
+
\begin{describe}{cls}{tagged-c-type (qualifiable-c-type)
\&key :qualifiers :tag}
Provides common behaviour for C tagged types. A @<tag> is a string
structs and unions.
\end{boxy}
+\begin{describe}{gf}{c-type-tag @<c-type> @> @<keyword>}
+\end{describe}
+
+\begin{describe}{fun}
+ {make-c-tagged-type @<kind> @<tag> \&optional @<qualifiers>
+ @> @<tagged-type>}
+\end{describe}
+
\begin{describe}{gf}{c-tagged-type-kind @<c-type> @> @<keyword>}
Returns a keyword classifying the tagged @<c-type>: one of @|:enum|,
@|:struct| or @|:union|. User-defined subclasses of @|tagged-c-type|
interned) enumerated type with the given @<tag> and @<qualifier>s (all
evaluated).
\end{describe}
+
\begin{describe}{fun}
{make-enum-type @<tag> \&optional @<qualifiers> @> @<c-enum-type>}
Return the (unique interned) C type object for the enumerated C type whose
interned) structured type with the given @<tag> and @<qualifier>s (all
evaluated).
\end{describe}
+
\begin{describe}{fun}
{make-struct-type @<tag> \&optional @<qualifiers> @> @<c-struct-type>}
Return the (unique interned) C type object for the structured C type whose
argument name.
A @<default> may be supplied. If the argument is used in a
- keyword-argument list (e.g., in a \descref{c-keyword-function-type}
- [object]{cls}), and the @<default> value is provided and non-nil, then its
+ keyword-argument list (e.g., in a \descref{cls}{c-keyword-function-type}
+ [object]), and the @<default> value is provided and non-nil, then its
(unescaped) printed representation is used to provide a default value if
the keyword argument is not supplied by the caller.
\end{describe}
including file from defining such names as macros. This generic function
is used to convert names into a safe form.
- \begin{describe}{meth}{commentify-argument-name (@<name> null) @> nil}
+ \begin{describe}{meth}{null}
+ {commentify-argument-name (@<name> null) @> nil}
Returns nil: if the argument name is already omitted, it's safe for use
in a header file.
\end{describe}
- \begin{describe}{meth}{commentify-argument-name (@<name> t) @> @<string>}
+ \begin{describe}{meth}{t}
+ {commentify-argument-name (@<name> t) @> @<string>}
Returns the print form of @<name> wrapped in a C comment, as
@`/*@<name>*/'.
\end{describe}
arguments; or
\item a possibly-improper list tail, beginning with an atom either as a
list item or as the final list cdr, indicating that the entire list tail
- is Lisp expression which is to be evaluated to compute the remaining
+ is a Lisp expression which is to be evaluated to compute the remaining
arguments.
\end{itemize}
A tail expression may return a list of @|argument| objects, optionally
For example,
\begin{prog}
- (c-type (fun \=(lisp (c-type-subtype other-func)) \+ \\
+ (c-type (fun \=(lisp (c-type-subtype other-func)) \+\\
("first" int) . (c-function-arguments other-func))
\end{prog}
evaluates to a function type like @|other-func|, only with an additional
argument of type @|int| added to the front of its argument list. This
could also have been written
\begin{prog}
- (let (\=(args (c-function-arguments other-func)) \+ \\
- (ret (c-type-subtype other-func))) \- \\ \ind
+ (let (\=(args (c-function-arguments other-func)) \+\\
+ (ret (c-type-subtype other-func))) \-\\ \ind
(c-type (fun \=(lisp ret) ("first" int) . args)
\end{prog}
\end{describe}
Keyword functions are never considered to be the same as ordinary
functions. Two keyword function types are considered to be the same if
- their return types are the same, and their positional argument lists consist of
- arguments with the same type, in the same order: the keyword arguments
- accepted by the functions is not significant.
+ their return types are the same, and their positional argument lists
+ consist of arguments with the same type, in the same order: the keyword
+ arguments accepted by the functions is not significant.
Keyword functions are constructed using an extended version of the @|fun|
specifier used for ordinary C function types. The extended syntax is as
follows.
\begin{prog}
(fun \=@<return-type>
- @{ (@<arg-name> @<arg-type>) @}^* \+ \\
+ @{ (@<arg-name> @<arg-type>) @}^* \+\\
@{ \=:keys @{ (@<kw-name> @<kw-type> @[@<kw-default>@]) @}^*
- @[. @<form>@] @! \+ \\
+ @[. @<form>@] @! \+\\
. @<form> @}
\end{prog}
where either the symbol @|:keys| appears literally in the specifier, or the
these circumstances obtains, then the specifier constructs an ordinary
function type.)
- See the description of \descref{c-function-type}{cls} for how a trailing
+ See the description of \descref{cls}{c-function-type} for how a trailing
@<form> is handled.
The list of @<arg-name>s and @<arg-type>s describes the positional
accepting the @<arguments>.
If the @<arguments> list contains a @|:keys| marker, then a
- \descref{c-keyword-function-type}[object]{cls} is returned: those arguments
+ \descref{cls}{c-keyword-function-type}[object] is returned: those arguments
preceding the @|:keys| marker form the positional argument list, and those
following the marker form the list of keyword arguments.
\end{describe}
\begin{describe}{gf}
{c-function-arguments @<c-function-type> @> @<arguments>}
- Return the arguments list of the @<c-function-type>.
+ Return the (non-keyword) argument list of the @<c-function-type>.
+\end{describe}
+
+\begin{describe}{gf}
+ {c-function-keywords @<c-function-type> @> @<keywords>}
+ Return the keyword-argument list of the @<c-function-type>.
\end{describe}
\begin{describe}{fun}
\begin{describe}{fun}{reify-variable-argument-tail @<arguments> @> @<list>}
If the @<argument> list contains an @|:ellipsis| marker, then replace it
with a @|va_list|. The name for the new argument, if any, is taken from
- the \descref{*sod-ap*}[variable]{var}. The new list is returned; the
+ the \descref{var}{*sod-ap*}[variable]. The new list is returned; the
original list is not modified, but may share structure with the new list.
\end{describe}
-\begin{describe}{fun}{merge-keyword-lists @<lists> @> @<list>}
+\begin{describe}{fun}
+ {merge-keyword-lists @<what-function> @<lists> @> @<list>}
Merge a number of keyword-argument lists together and return the result.
- The @<lists> parameter is a list consisting of a number of @|(@<args>
- . @<origin>)| pairs: in each pair, @<args> is a list of
- \descref{argument}{cls} objects, and @<origin> is either nil or an object
- whose printed representation describes the origin of the corresponding
- @<args> list, suitable for inclusion in an error message.
+ The @<what-function> is either nil or a function designator; see below.
+
+ The @<lists> parameter is a list consisting of a number of
+ @|(@<report-function> . @<args>)| pairs: in each pair, @<report-function>
+ is either nil or a function designator, and @<args> is a list of
+ \descref{cls}{argument} objects.
The resulting list contains exactly one argument for each distinct argument
name appearing in the input @<lists>; this argument will contain the
default value from the earliest occurrence in the input @<lists> of an
argument with that name.
- If the same name appears multiple times with different types, an error is
- signalled quoting the name, conflicting types, and (if non-nil) the origins
- of the offending argument objects.
+ If the same name appears multiple times with different types, a continuable
+ error will be signalled, and one of the conflicting argument types will be
+ chosen arbitrarily. The @<what-function> will be called to establish
+ information which will be reported to the user. It will be called with no
+ arguments and is expected to return two values:
+ \begin{itemize}
+ \item a file location @<floc> or other object acceptable to
+ \descref{gf}{file-location}, to be used as the location of the main
+ error; and
+ \item an object @<what>, whose printed representation should be a noun
+ phrase describing the object for which the argument lists are being
+ combined.
+ \end{itemize}
+ The phrasing of the error message is `type mismatch in @<what>'. Either,
+ or both, of @<floc> and @<what> may be nil, though this is considered poor
+ practice; if @<what-function> is nil, this is equivalent to a function
+ which returns two nil values. Following the error, the @<report-function>s
+ for the @<args> lists containing the conflicting argument objects are
+ called, in an arbitrary order, with a single argument which is the
+ offending @|argument| object; the function is expected to issue information
+ messages (see \descref{fun}{info}) to give more detail for diagnosing the
+ conflict. If a @<report-function> is nil, then nothing happens; this is
+ considered poor practice.
\end{describe}
\begin{describe}{fun}
arguments, if any, will be printed by @<print-args>.
The @<print-kernel> function is a standard kernel-printing function
- following the \descref{pprint-c-type}[protocol]{gf}.
+ following the \descref{gf}{pprint-c-type}[protocol].
The @<print-args> function is given a single argument, which is the
@<stream> to print on. It should not print the surrounding parentheses.
\begin{describe}{fun}{pprint-argument-list @<args> @<stream> @> @<flag>}
Print an argument list to @<stream>.
- The @<args> is a list of \descref{argument}[objects]{cls}, optionally
+ The @<args> is a list of \descref{cls}{argument}[objects], optionally
containing an @|:ellipsis| marker. The function returns true if any
arguments were actually printed.
\end{describe}
{make-class-type @<name> \&optional @<qualifiers> @> @<class-type>}
\end{describe}
-\begin{describe}{fun}
- {make-class-type @<name> \&optional @<qualifiers> @> @<class-type>}
-\end{describe}
-
\begin{describe}{fun}{find-sod-class @<name> @> @<class>}
\end{describe}
\begin{describe*}
{\dhead{gf}{var-in-use-p @<var> @> @<generalized-boolean>}
- \dhead[setf var-in-use-p]
- {gf}{setf (var-in-use-p @<var>) @<generalized-boolean>}}
+ \dhead{gf}{setf (var-in-use-p @<var>) @<generalized-boolean>}}
\end{describe*}
\subsubsection{Temporary name objects}
subclasses, but is also usable on its own.
\end{describe}
-\begin{describe}{meth}
+\begin{describe}{gf}{temp-tag @<name> @> @<tag>}
+\end{describe}
+
+\begin{describe}{meth}{temporary-name}
{commentify-argument-name (@<name> temporary-name) @> nil}
\end{describe}
\begin{table}
\begin{tabular}[C]{*2{>{\codeface}l}} \hlx*{hv}
- \thd{\textbf{Class}} & \thd{\textbf{Name format}} \\ \hlx{vhv}
- temporary-name & @<tag> \\
- temporary-argument & sod__a@<tag> \\
- temporary-function & sod__f@<tag> \\
- temporary-variable & sod__v@<tag> \\ \hlx*{vh}
+ \thd{Class} & \thd{Name format} \\ \hlx{vhv}
+ temporary-name & @<tag> \\
+ temporary-argument & sod__a@<tag> \\
+ temporary-function & sod__f@<tag> \\
+ temporary-variable & sod__v@<tag> \\ \hlx*{vh}
\end{tabular}
\caption{Temporary name formats}
\label{tab:codegen.codegen.temps-format}
\subsubsection{Well-known `temporary' names}
\begin{table}
+ \def\x#1{\desclabel{var}{#1}}
+ \x{*sod-ap*} \x{*sod-master-ap*} \x{*null-pointer*}
\begin{tabular}[C]{*2{>{\codeface}l}} \hlx*{hv}
- \thd{\textbf{Variable}} & \thd{\textbf{Name format}} \\ \hlx{vhv}
- {}*sod-ap* & sod__ap \\
- {}*sod-master-ap* & sod__master_ap \\
- {}*null-pointer* & NULL \\ \hlx*{vh}
+ \thd{Variable} & \thd{Name format} \\ \hlx{vhv}
+ {}*sod-ap* & sod__ap \\
+ {}*sod-master-ap* & sod__master_ap \\
+ {}*null-pointer* & NULL \\ \hlx*{vh}
\end{tabular}
\caption{Well-known temporary names}
\label{tab:codegen.codegen.well-known-temps}
\end{describe}
\begin{describe}{mac}
- {definst @<code> (@<streamvar> \&key @<export>) (@<arg>^*) \\ \ind
- @[[ @<declaration>^* @! @<doc-string> @]] \\
- @<form>^* \-
- \nlret @<code>}
+ {definst @<code> (@<streamvar> \&key @<export>) (@<arg>^*) \\ \ind
+ @[[ @<declaration>^* @! @<doc-string> @]] \\
+ @<form>^*
+ \-\nlret @<code>}
\end{describe}
\begin{describe}{mac}
{format-compound-statement
- (@<stream> @<child> \&optional @<morep>) \\ \ind
- @<declaration>^* \\
+ (@<stream> @<child> \&optional @<morep>) \\ \ind
+ @<declaration>^* \\
@<form>^*}
\end{describe}
\begin{table}
\begin{tabular}[C]{ll>{\codeface}l} \hlx*{hv}
\thd{Class name} &
- \thd{Arguments} &
- \thd{Output format} \\ \hlx{vhv}
+ \thd{Arguments} &
+ \thd{Output format}\\ \hlx{vhv}
@|var| & @<name> @<type> @|\&optional| @<init>
& @<type> @<name> @[= @<init>@];
\\ \hlx{v}
\label{tab:codegen.codegen.insts}
\end{table}
+\begin{describe*}
+ {\dhead*{cls}{@<code>-inst (inst) \&key \dots}
+ \dhead*{fun}{make-@<code>-inst \dots}
+ \dhead*{gf}{inst-@<slot> @<inst> @> @<value>}}
+ \def\instclass#1#2#3{%
+ #1{cls}{#3-inst}[#2]%
+ #1{fun}{make-#3-inst}[#2]%
+ }
+ \def\instslot#1#2#3{#1{gf}{inst-#3}[#2]}
+ \def\makelabels#1#2{%
+ \def\x{\instclass{#1}{#2}}
+ \x{var} \x{set} \x{update} \x{cond} \x{return} \x{break} \x{continue}
+ \x{expr} \x{call} \x{banner} \x{block} \x{if} \x{for} \x{while}
+ \x{do-while} \x{function}
+ \def\x{\instslot{#1}{#2}}
+ \x{name} \x{type} \x{init} \x{var} \x{expr} \x{op} \x{cond} \x{conseq}
+ \x{alt} \x{func} \x{args} \x{control} \x{decls} \x{body} \x{update}
+ \x{banner} \x{banner-args}
+ }
+ \makelabels{\desclabel}{|(}
+
+ Sod provides a number of built-in instruction types generated by
+ \descref{mac}{definst}: see \xref{tab:codegen.codegen.insts}.
+
+ \makelabels{\descindex}{|)}
+\end{describe*}
+
\subsection{Code generation} \label{sec:clang.codegen.codegen}
\end{describe}
\begin{describe}{mac}
- {with-temporary-var (@<codegen> @<var> @<type>) \\ \ind
- @<declaration>^* \\
- @<form>^* \-
- \nlret @<value>^*}
+ {with-temporary-var (@<codegen> @<var> @<type>) \\ \ind
+ @<declaration>^* \\
+ @<form>^*
+ \-\nlret @<value>^*}
\end{describe}
\begin{describe}{fun}{deliver-expr @<codegen> @<target> @<expr>}
\begin{describe}{cls}{c-fragment () \&key :location :text}
\end{describe}
-\begin{describe}{gf}{c-fragment-text @<fragment> @> @<string>}
-\end{describe}
+\begin{describe*}
+ {\dhead{gf}{c-fragment-text @<fragment> @> @<string>}
+ \dhead{meth}{c-fragment}
+ {file-location (@<fragment> c-fragment) @> @<floc>}}
+\end{describe*}
\begin{describe}{fun}
{scan-c-fragment @<scanner> @<end-chars>