\end{describe}
\begin{table}
- \begin{tabular}[C]{|l|l|} \hlx{hv}
- \textbf{C type} & \textbf{Specifiers} \\ \hlx{vhv}
- @|void| & @|void| \\ \hlx{vhv}
+ \begin{tabular}[C]{ll} \hlx*{hv}
+ \thd{C type} & \thd{Specifiers} \\ \hlx{vhv}
+ @|void| & @|void| \\ \hlx{v}
@|char| & @|char| \\ \hlx{v}
- @|unsigned char| & @|unsigned-char|, @|uchar| \\ \hlx{v}
- @|signed char| & @|signed-char|, @|schar| \\ \hlx{vhv}
+ @|unsigned char| & @|unsigned-char|, @|uchar| \\ \hlx{}
+ @|signed char| & @|signed-char|, @|schar| \\ \hlx{v}
@|short| & @|short|, @|signed-short|, @|short-int|,
- @|signed-short-int| @|sshort| \\ \hlx{v}
+ @|signed-short-int| @|sshort| \\ \hlx{}
@|unsigned short| & @|unsigned-short|, @|unsigned-short-int|,
- @|ushort| \\ \hlx{vhv}
+ @|ushort| \\ \hlx{v}
@|int| & @|int|, @|signed|, @|signed-int|,
- @|sint| \\ \hlx{v}
- @|unsigned int| & @|unsigned|, @|unsigned-int|, @|uint| \\ \hlx{vhv}
+ @|sint| \\ \hlx{}
+ @|unsigned int| & @|unsigned|, @|unsigned-int|, @|uint| \\ \hlx{v}
@|long| & @|long|, @|signed-long|, @|long-int|,
- @|signed-long-int|, @|slong| \\ \hlx{v}
+ @|signed-long-int|, @|slong| \\ \hlx{}
@|unsigned long| & @|unsigned-long|, @|unsigned-long-int|,
- @|ulong| \\ \hlx{vhv}
+ @|ulong| \\ \hlx{v}
@|long long| & @|long-long|, @|signed-long-long|,
@|long-long-int|, \\
& \qquad @|signed-long-long-int|,
@|llong|, @|sllong| \\ \hlx{v}
@|unsigned long long|
& @|unsigned-long-long|, @|unsigned-long-long-int|,
- @|ullong| \\ \hlx{vhv}
- @|float| & @|float| \\ \hlx{v}
- @|double| & @|double| \\ \hlx{vhv}
+ @|ullong| \\ \hlx{v}
+ @|float| & @|float| \\ \hlx{}
+ @|double| & @|double| \\ \hlx{v}
@|va_list| & @|va-list| \\ \hlx{v}
@|size_t| & @|size-t| \\ \hlx{v}
- @|ptrdiff_t| & @|ptrdiff-t| \\ \hlx{vh}
+ @|ptrdiff_t| & @|ptrdiff-t| \\ \hlx*{vh}
\end{tabular}
\caption{Builtin symbolic type specifiers for simple C types}
\label{tab:codegen.c-types.simple}
evaluated). The synonyms @|ptr| and @|pointer| may be used in place of the
star @`*'.
- The symbol @|string| is a type specifier for the type of pointer to
+ The symbol @|string| is a type specifier for the type pointer to
characters; the symbol @|const-string| is a type specifier for the type
pointer to constant characters.
\end{describe}
\begin{describe}{fun}
{make-pointer-type @<c-type> \&optional @<qualifiers>
@> @<c-pointer-type>}
- Return an object describing the type of qualified pointers to @<subtype>.
+ Return an object describing the type qualified pointer to @<subtype>.
If @<subtype> is interned, then the returned pointer type object is
interned also.
\end{describe}
\subsection{Array types} \label{sec:clang.c-types.array}
-Arrays implement the compound-type protocol. The subtype of an array is the
-array element type.
+Arrays implement the compound-type protocol. The subtype of an array type is
+the array element type.
\begin{describe}{cls}{c-array-type (c-type) \&key :subtype :dimensions}
Represents a multidimensional C array type. The @<dimensions> are a list
\subsection{Function types} \label{sec:clang.c-types.fun}
+Function types implement the compound-type protocol. The subtype of a
+function type is the type of the function's return value.
+
\begin{describe}{cls}{argument}
+ Represents an ordinary function argument.
\end{describe}
\begin{describe}{fun}{argumentp @<value> @> @<generalized-boolean>}
+ Decide whether @<value> is an @<argument> object: if so, return non-nil; if
+ not return nil.
\end{describe}
\begin{describe}{fun}{make-argument @<name> @<c-type> @> @<argument>}
+ Construct and a return a new @<argument> object. The argument has type
+ @<c-type>, which must be a @|c-type| object, and is named @<name>.
+
+ The @<name> may be nil to indicate that the argument has no name: in this
+ case the argument will be formatted as an abstract declarator, which is not
+ suitable for function definitions. If @<name> is not nil, then the
+ @<name>'s print representation, with @|*print-escape*| nil, is used as the
+ argument name.
\end{describe}
-\begin{describe}{fun}{argument-name @<argument> @> @<string>}
+\begin{describe}{fun}{argument-name @<argument> @> @<name>}
+ Return the name of the @<argument>, as it was supplied to @|make-argument|.
\end{describe}
\begin{describe}{fun}{argument-type @<argument> @> @<c-type>}
+ Return the type of the @<argument>, as it was supplied to @|make-argument|.
\end{describe}
-\begin{describe}{fun}
+\begin{describe}{gf}
{commentify-argument-name @<name> @> @<commentified-name>}
-\end{describe}
+ Convert the argument name @<name> so that it's suitable to declare the
+ function in a header file.
-\begin{describe}{cls}{c-function-type (c-type) \&key :subtype :arguments}
- Represents C function types. An instance denotes the C type of a C
- function which FIXME
+ Robust header files shouldn't include literal argument names in
+ declarations of functions or function types, since this restricts the
+ 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}
+ 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>}
+ Returns the print form of @<name> wrapped in a C comment, as
+ @`/*@<name>*/'.
+ \end{describe}
\end{describe}
\begin{describe}{fun}
- {c-function-arguments @<c-function-type> @> @<arguments>}
+ {commentify-argument-names @<arguments> @> @<commentified-arguments>}
+ Convert the @<arguments> list so that it's suitable for use in a header
+ file.
+
+ The @<arguments> list should be a list whose items are @|argument| objects
+ or the keyword @|:ellipsis|. The return value is a list constructed as
+ follows. For each @|argument| object in the input list, there is a
+ corresponding @|argument| object in the returned list, with the same type,
+ and whose name is the result of @|commentify-argument-name| applied to the
+ input argument name; an @|:ellipsis| in the input list is passed through
+ unchanged.
\end{describe}
-\begin{describe}{fun}
- {make-c-type @<c-type> @<arguments> @> @<c-function-type>}
+\begin{describe}{cls}{c-function-type (c-type) \&key :subtype :arguments}
+ Represents C function types. An instance denotes the type of a C
+ function which accepts the @<arguments> and returns @<subtype>.
+
+ The @<arguments> are a possibly empty list. All but the last element of
+ the list must be @|argument| objects; the final element may instead be the
+ keyword @|:ellipsis|, which denotes a variable argument list.
+
+ An @<arguments> list consisting of a single argument with type @|void| is
+ converted into an empty list. On output as C code, an empty argument list
+ is written as @|void|. It is not possible to represent a pre-ANSI C
+ function without prototypes.
+
+ Two function types are considered to be the same if their return types are
+ the same, and their argument lists consist of arguments with the same type,
+ in the same order, and either both or neither argument list ends with
+ @|:ellipsis|; argument names are not compared.
+
+ The type specifier @|(fun @<return-type> @{ (@<arg-name> @<arg-type>) @}^*
+ @[:ellipsis @! . @<form> @])| constructs a function type. The function has
+ the subtype @<return-type>. The remaining items in the type-specifier list
+ are used to construct the argument list. The argument items are a possibly
+ improper list, beginning with zero or more \emph{explicit arguments}:
+ two-item @<arg-name>/@<arg-type> lists. For each such list, an @|argument|
+ object is constructed with the given name (evaluated) and type. Following
+ the explicit arguments, there may be
+ \begin{itemize}
+ \item nothing, in which case the function's argument list consists only of
+ the explicit arguments;
+ \item the keyword @|:ellipsis|, as the final item in the type-specifier
+ list, indicating a variable argument list may follow the explicit
+ 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
+ arguments.
+ \end{itemize}
+ A tail expression may return a list of @|argument| objects, optionally
+ followed by an @|:ellipsis|.
+
+ For example,
+ \begin{prog}
+ (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
+ (c-type (fun \=(lisp ret) ("first" int) . args)
+ \end{prog}
\end{describe}
\begin{describe}{fun}
- {commentify-argument-names @<arguments> @> @<commentified-arguments>}
+ {make-function-type @<subtype> @<arguments> @> @<c-function-type>}
+ Construct and return a new function type, returning @<subtype> and
+ accepting the @<arguments>.
+\end{describe}
+
+\begin{describe}{gf}
+ {c-function-arguments @<c-function-type> @> @<arguments>}
+ Return the arguments list of the @<c-function-type>.
\end{describe}
\begin{describe}{fun}
- {commentify-function-type @<c-type> @> @<commentified-c-type>}
+ {commentify-function-type @<c-function-type> @> @<commentified-c-type>}
+ Return a commentified version of the @<c-function-type>.
+
+ The returned type has the same subtype as the given type, and the argument
+ list of the returned type is the result of applying
+ @|commentify-argument-names| to the argument list of the given type.
\end{describe}
\subsection{Parsing C types} \label{sec:clang.c-types.parsing}
%%%--------------------------------------------------------------------------
\section{Generating C code} \label{sec:clang.codegen}
+This section deals with Sod's facilities for constructing and manipulating C
+expressions, declarations, instructions and definitions.
+
+\subsection{Temporary names} \label{sec:clang.codegen.temporaries}
+
+Many C-level objects, especially ones with external linkage or inclusion in a
+header file, are assigned names which are simple strings, perhaps fixed ones,
+perhaps constructed. Other objects don't need meaningful names, and
+suitably unique constructed names would be tedious and most likely rather
+opaque. Therefore Sod has an ability to construct \emph{temporary names}.
+
+These aren't temporary in the sense that they name C objects which have
+limited lifetimes at runtime. Rather, the idea is that the names be
+significant only to small pieces of Lisp code, which will soon forget about
+them.
+
+\subsubsection{The temporary name protocol}
+Temporary names are represented by objects which implement a simple protocol.
+
+\begin{describe}{gf}{format-temporary-name @<var> @<stream>}
+\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>}}
+\end{describe*}
+
+\subsubsection{Temporary name objects}
+
+\begin{describe}{cls}{temporary-name () \&key :tag}
+ A temporary name object. This is the root of a small collection of
+ subclasses, but is also usable on its own.
+\end{describe}
+
+\begin{describe}{meth}
+ {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}
+ \end{tabular}
+ \caption{Temporary name formats}
+ \label{tab:codegen.codegen.temps-format}
+\end{table}
+
+\begin{describe}{cls}{temporary-argument (temporary-name) \&key :tag}
+\end{describe}
+
+\begin{describe}{cls}{temporary-function (temporary-name) \&key :tag}
+\end{describe}
+
+\begin{describe}{fun}{temporary-function @> @<name>}
+\end{describe}
+
+\begin{describe}{cls}
+ {temporary-variable (temporary-name) \&key :tag :in-use-p}
+\end{describe}
+
+\subsubsection{Well-known `temporary' names}
+
+\begin{table}
+ \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 \\
+ {}*sod-tmp-ap* & sod__tmp_ap \\ \hlx*{vh}
+ \end{tabular}
+ \caption{Well-known temporary names}
+ \label{tab:codegen.codegen.well-known-temps}
+\end{table}
+
+\subsection{Instructions} \label{sec:clang.codegen.insts}
+
+\begin{describe}{cls}{inst () \&key}
+\end{describe}
+
+\begin{describe}{gf}{inst-metric @<inst>}
+\end{describe}
+
+\begin{describe}{mac}
+ {definst @<code> (@<streamvar> \&key @<export>) (@<arg>^*)
+ @<body-form>^*}
+\end{describe}
+
+\begin{describe}{mac}
+ {format-compound-statement (@<stream> @<child> \&optional @<morep>)
+ @<body-form>^*}
+\end{describe}
+
+\begin{table}
+ \begin{tabular}[C]{ll>{\codeface}l} \hlx*{hv}
+ \thd{Class name} &
+ \thd{Arguments} &
+ \thd{Output format} \\ \hlx{vhv}
+ @|var| & @<name> @<type> @<init> & @<type> @<name> @[= @<init>@];
+ \\ \hlx{v}
+ @|set| & @<var> @<expr> & @<var> = @<expr>; \\ \hlx{v}
+ @|update| & @<var> @<op> @<expr> & @<var> @<op>= @<expr>;
+ \\ \hlx{v}
+ @|return| & @<expr> & return @[@<expr>@];
+ \\ \hlx{v}
+ @|break| & --- & break; \\ \hlx{v}
+ @|continue| & --- & continue; \\ \hlx{v}
+ @|expr| & @<expr> & @<expr>; \\ \hlx{v}
+ @|call| & @<func> @<args> & @<func>(@<arg>_1,
+ $\ldots$,
+ @<arg>_n) \\ \hlx{v}
+ @|va-start| & @<ap> @<arg> & va_start(@<ap>, @<arg>);
+ \\ \hlx{v}
+ @|va-copy| & @<to> @<from> & va_copy(@<to>, @<from>);
+ \\ \hlx{v}
+ @|va-end| & @<ap> & va_end(@<ap>); \\ \hlx{vhv}
+ @|block| & @<decls> @<body> & \{ @[@<decls>@] @<body> \}
+ \\ \hlx{v}
+ @|if| & @<cond> @<conseq> @<alt> & if (@<cond>) @<conseq>
+ @[else @<alt>@] \\ \hlx{v}
+ @|while| & @<cond> @<body> & while (@<cond>) @<body>
+ \\ \hlx{v}
+ @|do-while| & @<body> @<cond> & do @<body> while (@<cond>);
+ \\ \hlx{v}
+ @|function| & @<name> @<type> @<body> &
+ @<type>_0 @<name>(@<type>_1 @<arg>_1, $\ldots$,
+ @<type>_n @<arg>_n @[, \dots@])
+ @<body> \\ \hlx*{vh}
+ \end{tabular}
+ \caption{Instruction classes}
+ \label{tab:codegen.codegen.insts}
+\end{table}
+
+\subsection{Code generation} \label{sec:clang.codegen.codegen}
+
+\begin{describe}{gf}{codegen-functions @<codegen> @> @<list>}
+\end{describe}
+
+\begin{describe}{gf}
+ {ensure-var @<codegen> @<name> @<type> \&optional @<init>}
+\end{describe}
+
+\begin{describe}{gf}{emit-inst @<codegen> @<inst>}
+\end{describe}
+
+\begin{describe}{gf}{emit-insts @<codegen> @<insts>}
+\end{describe}
+
+\begin{describe}{gf}{emit-decl @<codegen> @<decl>}
+\end{describe}
+
+\begin{describe}{gf}{emit-declss @<codegen> @<decls>}
+\end{describe}
+
+\begin{describe}{gf}{codegen-push @<codegen>}
+\end{describe}
+
+\begin{describe}{gf}{codegen-pop @<codegen> @> @<decls> @<insts>}
+\end{describe}
+
+\begin{describe}{gf}{codegen-pop-block @<codegen> @> @<block-inst>}
+\end{describe}
+
+\begin{describe}{gf}
+ {codegen-pop-function @<codegen> @<name> @<type> @> @<name>}
+\end{describe}
+
+\begin{describe}{gf}{codegen-add-function @<codegen> @<function>}
+\end{describe}
+
+\begin{describe}{fun}
+ {codegen-build-function @<codegen> @<name> @<type> @<vars> @<insts>
+ @> @<name>}
+\end{describe}
+
+\begin{describe}{gf}{temporary-var @<codegen> @<type> @> @<name>}
+\end{describe}
+
+\begin{describe}{mac}
+ {with-temporary-var (@<codegen> @<var> @<type>) @<body-form>^*
+ @> @<value>^*}
+\end{describe}
+
+\begin{describe}{fun}{deliver-expr @<codegen> @<target> @<expr>}
+\end{describe}
+
+\begin{describe}{fun}{convert-stmts @<codegen> @<target> @<type> @<func>}
+\end{describe}
+
+\begin{describe}{cls}{codegen () \&key :vars :insts (:temp-index 0)}
+\end{describe}
+
%%%----- That's all, folks --------------------------------------------------
%%% Local variables: