X-Git-Url: https://git.distorted.org.uk/~mdw/sod/blobdiff_plain/64d1ecf751f542782b5ffb9c9469c70d92f423de..fcb6c0fb72f7e2211322cfc303ee403bdf3ddd7d:/doc/clang.tex

diff --git a/doc/clang.tex b/doc/clang.tex
index 8a21449..bd1053f 100644
--- a/doc/clang.tex
+++ b/doc/clang.tex
@@ -347,35 +347,35 @@ In Sod, the leaf types are
 \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}
@@ -513,7 +513,7 @@ to.
   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}
@@ -521,15 +521,15 @@ to.
 \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
@@ -569,44 +569,144 @@ array element type.
 
 \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}
@@ -614,6 +714,200 @@ array element type.
 %%%--------------------------------------------------------------------------
 \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:
