Commit | Line | Data |
---|---|---|
dea4d055 MW |
1 | %%% -*-latex-*- |
2 | %%% | |
3 | %%% Description of the internal class structure and protocol | |
4 | %%% | |
5 | %%% (c) 2009 Straylight/Edgeware | |
6 | %%% | |
7 | ||
8 | %%%----- Licensing notice --------------------------------------------------- | |
9 | %%% | |
10 | %%% This file is part of the Simple Object Definition system. | |
11 | %%% | |
12 | %%% SOD is free software; you can redistribute it and/or modify | |
13 | %%% it under the terms of the GNU General Public License as published by | |
14 | %%% the Free Software Foundation; either version 2 of the License, or | |
15 | %%% (at your option) any later version. | |
16 | %%% | |
17 | %%% SOD is distributed in the hope that it will be useful, | |
18 | %%% but WITHOUT ANY WARRANTY; without even the implied warranty of | |
19 | %%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
20 | %%% GNU General Public License for more details. | |
21 | %%% | |
22 | %%% You should have received a copy of the GNU General Public License | |
23 | %%% along with SOD; if not, write to the Free Software Foundation, | |
24 | %%% Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
25 | ||
26 | \chapter{Protocol overview} \label{ch:proto} | |
27 | ||
28 | This chapter provides an overview of the Sod translator's internal object | |
29 | model. It describes most of the important classes and generic functions, how | |
30 | they are used to build a model of a Sod module and produce output code, and | |
31 | how an extension might modify the translator's behaviour. | |
32 | ||
33 | I assume familiarity with the Common Lisp Object System (CLOS). Familiarity | |
34 | with the CLOS Metaobject Protocol isn't necessary but may be instructive. | |
35 | ||
36 | %%%-------------------------------------------------------------------------- | |
37 | \section{A tour through the translator} | |
38 | ||
39 | At the very highest level, the Sod translator works in two phases: it | |
40 | \emph{parses} source files into an internal representation, and then it | |
41 | \emph{generates} output files from the internal representation. | |
42 | ||
43 | The function @|read-module| is given a pathname for a file: it opens the | |
44 | file, parses the program text, and returns a @|module| instance describing | |
45 | the classes and other items found. | |
46 | ||
47 | At the other end, the main output function is @|output-module|, which is | |
48 | given a module, an output stream and a | |
49 | ||
50 | ||
51 | %%%-------------------------------------------------------------------------- | |
52 | \section{Specification conventions} \label{sec:proto.conventions} | |
53 | ||
54 | Throughout this specification, the phrase `it is an error' indicates that a | |
55 | particular circumstance is erroneous and results in unspecified and possibly | |
56 | incorrect behaviour. In particular, the situation need not be immediately | |
57 | diagnosed, and the consequences may be far-reaching. | |
58 | ||
59 | The following conventions apply throughout this specification. | |
60 | ||
61 | \begin{itemize} | |
62 | ||
63 | \item If a specification describes an argument as having a particular type or | |
64 | syntax, then it is an error to provide an argument not having that | |
65 | particular type or syntax. | |
66 | ||
67 | \item If a specification describes a function then that function might be | |
68 | implemented as a generic function; it is an error to attempt to (re)define | |
69 | it as a generic function, or to attempt to add methods to it. A function | |
70 | specified as being a generic function will certainly be so; if user methods | |
71 | are permitted on the generic function then this will be specified. | |
72 | ||
73 | \item Where a class precedence list is specified, either explicitly or | |
74 | implicitly by a class hierarchy, the implementation may include additional | |
75 | superclasses not specified here. Such additional superclasses will not | |
76 | affect the order of specified classes in the class precedence lists either | |
77 | of specified classes themselves or of user-defined subclasses of specified | |
78 | classes. | |
79 | ||
80 | \item Unless otherwise specified, generic functions use the standard method | |
81 | combination. | |
82 | ||
83 | \item The specifications for methods are frequently brief; they should be | |
84 | read in conjunction with and in the context of the specification for the | |
85 | generic function and specializing classes, if any. | |
86 | ||
87 | \item An object $o$ is a \emph{direct instance} of a class $c$ if @|(eq | |
88 | (class-of $o$) $c$)|; $o$ is an \emph{instance} of $c$ if it is a direct | |
89 | instance of any subclass of $c$. | |
90 | ||
91 | \item If a class is specified as being \emph{abstract} then it is an error to | |
92 | construct direct instances of it, e.g., using @|make-instance|. | |
93 | ||
94 | \item If an object is specified as being \emph{immutable} then it is an error | |
95 | to mutate it, e.g., using @|(setf (slot-value \ldots) \ldots)|. Programs | |
96 | may rely on immutable objects retaining their state. | |
97 | ||
98 | \item A value is \emph{fresh} if it is guaranteed to be not @|eql| to any | |
99 | previously existing value. | |
100 | ||
101 | \item Unless otherwise specified, it is an error to change the class of an | |
102 | instance of any class described here; and it is an error to change the | |
103 | class of an object to a class described here. | |
104 | ||
105 | \end{itemize} | |
106 | ||
107 | \subsection{Format of the entries} \label{sec:proto.conventions.format} | |
108 | ||
109 | Most symbols defined by the protocol have their own entries. An entry begins | |
110 | with a header line, showing a synopsis of the symbol on the left, and the | |
111 | category (function, class, macro, etc.) on the right. | |
112 | ||
113 | \begin{describe}{fun}{example-function @<required> | |
114 | \&optional @<optional> | |
115 | \&rest @<rest> | |
116 | \&key :keyword} | |
117 | The synopsis for a function, generic function or method describes the | |
118 | function's lambda-list using the usual syntax. Note that keyword arguments | |
119 | are shown by naming their keywords; in the description, the value passed | |
120 | for the keyword argument @|keyword| is shown as @<keyword>. | |
121 | ||
122 | For a method, specializers are shown using the usual @|defmethod| syntax, | |
123 | e.g., | |
124 | \begin{quote} | |
125 | some-generic-function ((@<specialized> list) @<unspecialized>) | |
126 | \end{quote} | |
127 | \end{describe} | |
128 | ||
129 | \begin{describe}{mac}{example-macro | |
130 | ( @{ @<symbol> @! (@<symbol> @<form>) @}^* ) \\ \push | |
131 | @[[ @<declaration>^* @! @<documentation-string> @]] \\ | |
132 | @<body-form>^*} | |
133 | The synopsis for a macro describes the acceptable syntax using the | |
134 | following notation. | |
135 | \begin{itemize} | |
136 | \item Literal symbols, e.g., keywords and parenthesis, are shown in | |
137 | @|monospace|. | |
138 | \item Metasyntactic variables are shown in @<italics>. | |
139 | \item Items are grouped together by braces `@{ $\dots$ @}'. The notation | |
140 | `@{ $\dots$ @}^*' indicates that the enclosed items may be repeated zero | |
141 | or more times; `@{ $\dots$ @}^+' indicates that the enclosed items may be | |
142 | repeated one or more times. This notation may be applied to a single | |
143 | item without the braces. | |
144 | \item Optional items are shown enclosed in brackets `@[ $\dots$ @]'. | |
145 | \item Alternatives are separated by vertical bars `@!'; the vertical bar | |
146 | has low precedence, so alternatives extend as far as possible between | |
147 | bars and up to the enclosing brackets if any. | |
148 | \item A sequence of alternatives enclosed in double-brackets `@[[ $\ldots$ | |
149 | @]]' indicates that the alternatives may occur in any order, but each may | |
150 | appear at most once unless marked by a star. | |
151 | \end{itemize} | |
152 | For example, the notation at the head of this example describes syntax | |
153 | for @|let|. | |
154 | \end{describe} | |
155 | ||
156 | ||
157 | \begin{describe}{cls}{example-class (direct-super other-direct-super) \&key | |
158 | :initarg} | |
159 | The synopsis for a class lists the class's direct superclasses, and the | |
160 | acceptable initargs in the form of a lambda-list. The initargs may be | |
161 | passed to @|make-instance| when constructing an instance of the class or a | |
162 | subclass of it. If instances of the class may be reinitialized, or if | |
163 | objects can be changed to be instances of the class, then these initargs | |
164 | may also be passed to @|reinitialize-instance| and/or @|change-class| as | |
165 | applicable; the class description will state explicitly when these | |
166 | operations are allowed. | |
167 | \end{describe} | |
168 | ||
169 | %%%-------------------------------------------------------------------------- | |
170 | \section{C type representation} \label{sec:proto.c-types} | |
171 | ||
172 | \subsection{Overview} \label{sec:proto.c-types.over} | |
173 | ||
174 | The Sod translator represents C types in a fairly simple and direct way. | |
175 | However, because it spends a fair amount of its time dealing with C types, it | |
176 | provides a number of useful operations and macros. | |
177 | ||
178 | The class hierarchy is shown in~\xref{fig:proto.c-types}. | |
179 | ||
180 | \begin{figure} \centering | |
181 | \parbox{10pt}{\begin{tabbing} | |
182 | @|c-type| \\ \push | |
183 | @|qualifiable-c-type| \\ \push | |
184 | @|simple-c-type| \\ \push | |
185 | @|c-class-type| \- \\ | |
186 | @|tagged-c-type| \\ \push | |
187 | @|c-struct-type| \\ | |
188 | @|c-union-type| \\ | |
189 | @|c-enum-type| \- \\ | |
190 | @|c-pointer-type| \- \\ | |
191 | @|c-array-type| \\ | |
192 | @|c-function-type| | |
193 | \end{tabbing}} | |
194 | \caption{Classes representing C types} | |
195 | \label{fig:proto.c-types} | |
196 | \end{figure} | |
197 | ||
198 | C type objects are immutable unless otherwise specified. | |
199 | ||
200 | \subsubsection{Constructing C type objects} | |
201 | There is a constructor function for each non-abstract class of C type object. | |
202 | Note, however, that constructor functions need not generate a fresh type | |
203 | object if a previously existing type object is suitable. In this case, we | |
204 | say that the objects are \emph{interned}. Some constructor functions are | |
205 | specified to return interned objects: programs may rely on receiving the same | |
206 | (@|eq|) type object for similar (possibly merely @|equal|) arguments. Where | |
207 | not specified, clients may still not rely on receiving fresh objects. | |
208 | ||
209 | A convenient S-expression notation is provided by the @|c-type| macro. Use | |
210 | of this macro is merely an abbreviation for corresponding use of the various | |
211 | constructor functions, and therefore interns type objects in the same manner. | |
212 | The syntax accepted by the macro can be extended in order to support new | |
213 | classes: see @|defctype|, @|c-type-alias| and @|define-c-type-syntax|. | |
214 | ||
215 | The descriptions of each of the various classes include descriptions of the | |
216 | initargs which may be passed to @|make-instance| when constructing a new | |
217 | instance of the class. However, the constructor functions and S-expression | |
218 | syntax are strongly recommended over direct use of @|make-instance|. | |
219 | ||
220 | \subsubsection{Printing} | |
221 | There are two protocols for printing C types. Unfortunately they have | |
222 | similar names. | |
223 | \begin{itemize} | |
224 | \item The @|print-c-type| function prints a C type value using the | |
225 | S-expression notation. It is mainly useful for diagnostic purposes. | |
226 | \item The @|pprint-c-type| function prints a C type as a C-syntax | |
227 | declaration. | |
228 | \end{itemize} | |
229 | Neither generic function defines a default primary method; subclasses of | |
230 | @|c-type| must define their own methods in order to print correctly. | |
231 | ||
232 | \subsection{The C type root class} \label{sec:proto.c-types.root} | |
233 | ||
234 | \begin{describe}{cls}{c-type ()} | |
235 | The class @|c-type| marks the root of the built-in C type hierarchy. | |
236 | ||
237 | Users may define subclasses of @|c-type|. All non-abstract subclasses must | |
238 | have a primary method defined on @|pprint-c-type|; unless instances of the | |
239 | subclass are interned, a method on @|c-type-equal-p| is also required. | |
240 | ||
241 | The class @|c-type| is abstract. | |
242 | \end{describe} | |
243 | ||
244 | \subsection{C type S-expression notation} \label{sec:proto.c-types.sexp} | |
245 | ||
246 | The S-expression representation of a type is described syntactically as a | |
247 | type specifier. Type specifiers fit into two syntactic categories. | |
248 | \begin{itemize} | |
249 | \item A \emph{symbolic type specifier} consists of a symbol. It has a | |
250 | single, fixed meaning: if @<name> is a symbolic type specifier, then each | |
251 | use of @<name> in a type specifier evaluates to the same (@|eq|) type | |
252 | object, until the @<name> is redefined. | |
253 | \item A \emph{type operator} is a symbol; the corresponding specifier is a | |
254 | list whose @|car| is the operator. The remaining items in the list are | |
255 | arguments to the type operator. | |
256 | \end{itemize} | |
257 | ||
258 | \begin{describe}{mac}{c-type @<type-spec> @to @<type>} | |
259 | Evaluates to a C type object, as described by the type specifier | |
260 | @<type-spec>. | |
261 | \end{describe} | |
262 | ||
263 | \begin{describe}{mac}{ | |
264 | defctype @{ @<name> @! (@<name>^*) @} @<type-spec> @to @<names>} | |
265 | Defines a new symbolic type specifier @<name>; if a list of @<name>s is | |
266 | given, then all are defined in the same way. The type constructed by using | |
267 | any of the @<name>s is as described by the type specifier @<type-spec>. | |
268 | ||
269 | The resulting type object is constructed once, at the time that the macro | |
270 | expansion is evaluated; the same (@|eq|) value is used each time any | |
271 | @<name> is used in a type specifier. | |
272 | \end{describe} | |
273 | ||
274 | \begin{describe}{mac}{c-type-alias @<original> @<alias>^* @to @<aliases>} | |
275 | Defines each @<alias> as being a type operator identical in behaviour to | |
276 | @<original>. If @<original> is later redefined then the behaviour of the | |
277 | @<alias>es changes too. | |
278 | \end{describe} | |
279 | ||
280 | \begin{describe}{mac}{% | |
281 | define-c-type-syntax @<name> @<lambda-list> \\ \push | |
282 | @<form>^* \-\\ | |
283 | @to @<name>} | |
284 | Defines the symbol @<name> as a new type operator. When a list of the form | |
285 | @|(@<name> @<argument>^*)| is used as a type specifier, the @<argument>s | |
286 | are bound to fresh variables according to @<lambda-list> (a destructuring | |
287 | lambda-list) and the @<form>s evaluated in order in the resulting lexical | |
288 | environment as an implicit @|progn|. The value should be a Lisp form which | |
289 | will evaluate to the type specified by the arguments. | |
290 | ||
291 | The @<form>s may call @|expand-c-type-spec| in order to recursively expand | |
292 | type specifiers among its arguments. | |
293 | \end{describe} | |
294 | ||
295 | \begin{describe}{fun}{expand-c-type-spec @<type-spec> @to @<form>} | |
296 | Returns the Lisp form that @|(c-type @<type-spec>)| would expand into. | |
297 | \end{describe} | |
298 | ||
299 | \begin{describe}{gf}{% | |
300 | print-c-type @<stream> @<type> \&optional @<colon> @<atsign>} | |
301 | Print the C type object @<type> to @<stream> in S-expression form. The | |
302 | @<colon> and @<atsign> arguments may be interpreted in any way which seems | |
303 | appropriate: they are provided so that @|print-c-type| may be called via | |
304 | @|format|'s @|\char`\~/\dots/| command; they are not set when | |
305 | @|print-c-type| is called by Sod functions. | |
306 | ||
307 | There should be a method defined for every C type class; there is no | |
308 | default method. | |
309 | \end{describe} | |
310 | ||
311 | \subsection{Comparing C types} \label{sec:proto.c-types.cmp} | |
312 | ||
313 | It is necessary to compare C types for equality, for example when checking | |
314 | argument lists for methods. This is done by @|c-type-equal-p|. | |
315 | ||
316 | \begin{describe}{gf}{c-type-equal-p @<type>_1 @<type>_2 @to @<boolean>} | |
317 | The generic function @|c-type-equal-p| compares two C types @<type>_1 and | |
318 | @<type>_2 for equality; it returns true if the two types are equal and | |
319 | false if they are not. | |
320 | ||
321 | Two types are equal if they are structurally similar, where this property | |
322 | is defined by methods for each individual class; see the descriptions of | |
323 | the classes for the details. | |
324 | ||
325 | The generic function @|c-type-equal-p| uses the @|and| method combination. | |
326 | ||
327 | \begin{describe}{meth}{c-type-equal-p @<type>_1 @<type>_2} | |
328 | A default primary method for @|c-type-equal-p| is defined. It simply | |
329 | returns @|nil|. This way, methods can specialize on both arguments | |
330 | without fear that a call will fail because no methods are applicable. | |
331 | \end{describe} | |
332 | \begin{describe}{ar-meth}{c-type-equal-p @<type>_1 @<type>_2} | |
333 | A default around-method for @|c-type-equal-p| is defined. It returns | |
334 | true if @<type>_1 and @<type>_2 are @|eql|; otherwise it delegates to the | |
335 | primary methods. Since several common kinds of C types are interned, | |
336 | this is a common case worth optimizing. | |
337 | \end{describe} | |
338 | \end{describe} | |
339 | ||
340 | \subsection{Outputting C types} \label{sec:proto.c-types.output} | |
341 | ||
342 | \begin{describe}{gf}{pprint-c-type @<type> @<stream> @<kernel>} | |
343 | The generic function @|pprint-c-type| pretty-prints to @<stream> a C-syntax | |
344 | declaration of an object or function of type @<type>. The result is | |
345 | written to @<stream>. | |
346 | ||
347 | A C declaration has two parts: a sequence of \emph{declaration specifiers} | |
348 | and a \emph{declarator}. The declarator syntax involves parentheses and | |
349 | operators, in order to reflect the operators applicable to the declared | |
350 | variable. For example, the name of a pointer variable is preceded by @`*'; | |
351 | the name of an array is followed by dimensions enclosed in @`['\dots @`]'. | |
352 | ||
353 | The @<kernel> argument must be a function designator (though see the | |
354 | standard around-method); it is invoked as | |
355 | \begin{quote} \codeface | |
356 | (funcall @<kernel> @<stream> @<priority> @<spacep>) | |
357 | \end{quote} | |
358 | It should write to @<stream> -- which may not be the same stream originally | |
359 | passed into the generic function -- the `kernel' of the declarator, i.e., | |
360 | the part to which prefix and/or postfix operators are attached to form the | |
361 | full declarator. | |
362 | ||
363 | The methods on @|pprint-c-type| specialized for compound types work by | |
364 | recursively calling @|pprint-c-type| on the subtype, passing down a closure | |
365 | which prints the necessary additional declarator operators before calling | |
366 | the original @<kernel> function. The additional arguments @<priority> and | |
367 | @<spacep> support this implementation technique. | |
368 | ||
369 | The @<priority> argument describes the surrounding operator context. It is | |
370 | zero if no type operators are directly attached to the kernel (i.e., there | |
371 | are no operators at all, or the kernel is enclosed in parentheses), one if | |
372 | a prefix operator is directly attached, or two if a postfix operator is | |
373 | directly attached. If the @<kernel> function intends to provide its own | |
374 | additional declarator operators, it should check the @<priority> in order | |
375 | to determine whether parentheses are necessary. See also the | |
376 | @|maybe-in-parens| macro (page~\pageref{mac:maybe-in-parens}). | |
377 | ||
378 | The @<spacep> argument indicates whether a space needs to be printed in | |
379 | order to separate the declarator from the declaration specifiers. A kernel | |
380 | which contains an identifier should insert a space before the identifier | |
381 | when @<spacep> is non-nil. An `empty' kernel, as found in an abstract | |
382 | declarator (one that specifies no name), looks more pleasing without a | |
383 | trailing space. See also the @|c-type-space| function | |
384 | (page~\pageref{fun:c-type-space}). | |
385 | ||
386 | Every concrete subclass of @|c-type| is expected to provide a primary | |
387 | method on this function. There is no default primary method. | |
388 | ||
389 | \begin{describe}{ar-meth}{pprint-c-type @<type> @<stream> @<kernel>} | |
390 | A default around method is defined on @|pprint-c-type| which `canonifies' | |
391 | non-function @<kernel> arguments. In particular: | |
392 | \begin{itemize} | |
393 | \item if @<kernel> is nil, then @|pprint-c-type| is called recursively | |
394 | with a @<kernel> function that does nothing; and | |
395 | \item if @<kernel> is any other kind of object, then @|pprint-c-type| is | |
396 | called recursively with a @<kernel> function that prints the object as | |
397 | if by @|princ|, preceded if necessary by space using @|c-type-space|. | |
398 | \end{itemize} | |
399 | \end{describe} | |
400 | \end{describe} | |
401 | ||
402 | \begin{describe}{fun}{c-type-space @<stream>} | |
403 | Writes a space and other pretty-printing instructions to @<stream> in order | |
404 | visually to separate a declarator from the preceding declaration | |
405 | specifiers. The precise details are subject to change. | |
406 | \end{describe} | |
407 | ||
408 | \begin{describe}{mac}{% | |
409 | maybe-in-parens (@<stream-var> @<guard-form>) \\ \push | |
410 | @<form>^*} | |
411 | The @<guard-form> is evaluated, and then the @<form>s are evaluated in | |
412 | sequence within a pretty-printer logical block writing to the stream named | |
413 | by the symbol @<stream-var>. If the @<guard-form> evaluates to nil, then | |
414 | the logical block has empty prefix and suffix strings; if it evaluates to a | |
415 | non-nil value, then the logical block has prefix and suffix @`(' and @`)' | |
416 | respectively. | |
417 | ||
418 | Note that this may cause @<stream> to be bound to a different stream object | |
419 | within the @<form>s. | |
420 | \end{describe} | |
421 | ||
422 | \subsection{Type qualifiers and qualifiable types} | |
423 | \label{sec:proto.ctypes.qual} | |
424 | ||
425 | \begin{describe}{cls}{qualifiable-c-type (c-type) \&key :qualifiers} | |
426 | The class @|qualifiable-c-type| describes C types which can bear | |
427 | `qualifiers' (\Cplusplus\ calls them `cv-qualifiers'): @|const|, | |
428 | @|restrict| and @|volatile|. | |
429 | ||
430 | The @<qualifiers> are a list of keyword symbols @|:const|, @|:restrict| and | |
431 | @|:volatile|. There is no built-in limitation to these particular | |
432 | qualifiers; others keywords may be used, though this isn't recommended. | |
433 | ||
434 | Two qualifiable types are equal only if they have \emph{matching | |
435 | qualifiers}: i.e., every qualifier attached to one is also attached to | |
436 | the other: order is not significant, and neither is multiplicity. | |
437 | ||
438 | The class @|qualifiable-c-type| is abstract. | |
439 | \end{describe} | |
440 | ||
441 | \begin{describe}{gf}{c-type-qualifiers @<type> @to @<list>} | |
442 | Returns the qualifiers of the @|qualifiable-c-type| instance @<type> as an | |
443 | immutable list. | |
444 | \end{describe} | |
445 | ||
446 | \begin{describe}{fun}{qualify-type @<type> @<qualifiers>} | |
447 | The argument @<type> must be an instance of @|qualifiable-c-type|, | |
448 | currently bearing no qualifiers, and @<qualifiers> a list of qualifier | |
449 | keywords. The result is a C type object like @<c-type> except that it | |
450 | bears the given @<qualifiers>. | |
451 | ||
452 | The @<type> is not modified. If @<type> is interned, then the returned | |
453 | type will be interned. | |
454 | \end{describe} | |
455 | ||
456 | \begin{describe}{fun}{format-qualifiers @<qualifiers>} | |
457 | Returns a string containing the qualifiers listed in @<qualifiers> in C | |
458 | syntax, with a space after each. In particular, if @<qualifiers> is | |
459 | non-null then the final character of the returned string will be a space. | |
460 | \end{describe} | |
461 | ||
462 | \subsection{Leaf types} \label{sec:proto.c-types.leaf} | |
463 | ||
464 | A \emph{leaf type} is a type which is not defined in terms of another type. | |
465 | In Sod, the leaf types are | |
466 | \begin{itemize} | |
467 | \item \emph{simple types}, including builtin types like @|int| and @|char|, | |
468 | as well as type names introduced by @|typename|, because Sod isn't | |
469 | interested in what the type name means, merely that it names a type; and | |
470 | \item \emph{tagged types}, i.e., enum, struct and union types which are named | |
471 | by a keyword identifying the kind of type, and a \emph{tag}. | |
472 | \end{itemize} | |
473 | ||
474 | \begin{describe}{cls}{simple-c-type (qualifiable-c-type) | |
475 | \&key :qualifiers :name} | |
476 | The class of `simple types'; an instance denotes the type @<qualifiers> | |
477 | @<name>. | |
478 | ||
479 | A simple type object maintains a \emph{name}, which is a string whose | |
480 | contents are the C name for the type. The initarg @|:name| may be used to | |
481 | provide this name when calling @|make-instance|. | |
482 | ||
483 | Two simple type objects are equal if and only if they have @|string=| names | |
484 | and matching qualifiers. | |
485 | ||
486 | A number of symbolic type specifiers for builtin types are predefined as | |
487 | shown in \xref{tab:proto.c-types.simple}. These are all defined as if by | |
488 | @|define-simple-c-type|, so can be used to construct qualified types. | |
489 | \end{describe} | |
490 | ||
491 | \begin{table} | |
492 | \begin{tabular}[C]{|l|l|} \hlx{hv} | |
493 | \textbf{C type} & \textbf{Specifiers} \\ \hlx{vhv} | |
494 | @|void| & @|void| \\ \hlx{vhv} | |
495 | @|char| & @|char| \\ \hlx{v} | |
496 | @|unsigned char| & @|unsigned-char|, @|uchar| \\ \hlx{v} | |
497 | @|signed char| & @|signed-char|, @|schar| \\ \hlx{vhv} | |
498 | @|short| & @|short|, @|signed-short|, @|short-int|, | |
499 | @|signed-short-int| @|sshort| \\ \hlx{v} | |
500 | @|unsigned short| & @|unsigned-short|, @|unsigned-short-int|, | |
501 | @|ushort| \\ \hlx{vhv} | |
502 | @|int| & @|int|, @|signed|, @|signed-int|, | |
503 | @|sint| \\ \hlx{v} | |
504 | @|unsigned int| & @|unsigned|, @|unsigned-int|, @|uint| \\ \hlx{vhv} | |
505 | @|long| & @|long|, @|signed-long|, @|long-int|, | |
506 | @|signed-long-int|, @|slong| \\ \hlx{v} | |
507 | @|unsigned long| & @|unsigned-long|, @|unsigned-long-int|, | |
508 | @|ulong| \\ \hlx{vhv} | |
509 | @|long long| & @|long-long|, @|signed-long-long|, | |
510 | @|long-long-int|, \\ | |
511 | & \qquad @|signed-long-long-int|, | |
512 | @|llong|, @|sllong| \\ \hlx{v} | |
513 | @|unsigned long long| | |
514 | & @|unsigned-long-long|, @|unsigned-long-long-int|, | |
515 | @|ullong| \\ \hlx{vhv} | |
516 | @|float| & @|float| \\ \hlx{v} | |
517 | @|double| & @|double| \\ \hlx{vhv} | |
518 | @|va_list| & @|va-list| \\ \hlx{v} | |
519 | @|size_t| & @|size-t| \\ \hlx{v} | |
520 | @|ptrdiff_t| & @|ptrdiff-t| \\ \hlx{vh} | |
521 | \end{tabular} | |
522 | \caption{Builtin symbolic type specifiers for simple C types} | |
523 | \label{tab:proto.c-types.simple} | |
524 | \end{table} | |
525 | ||
526 | \begin{describe}{fun}{make-simple-type @<name> \&optional @<qualifiers>} | |
527 | Return the (unique interned) simple C type object for the C type whose name | |
528 | is @<name> (a string) and which has the given @<qualifiers> (a list of | |
529 | keywords). | |
530 | \end{describe} | |
531 | ||
532 | \begin{describe}{gf}{c-type-name @<type>} | |
533 | Returns the name of a @|simple-c-type| instance @<type> as an immutable | |
534 | string. | |
535 | \end{describe} | |
536 | ||
537 | \begin{describe}{mac}{% | |
538 | define-simple-c-type @{ @<name> @! (@<name>^*) @} @<string>} | |
539 | Define type specifiers for a new simple C type. Each symbol @<name> is | |
540 | defined as a symbolic type specifier for the (unique interned) simple C | |
541 | type whose name is the value of @<string>. Further, each @<name> is | |
542 | defined to be a type operator: the type specifier @|(@<name> | |
543 | @<qualifier>^*)| evaluates to the (unique interned) simple C type whose | |
544 | name is @<string> and which has the @<qualifiers> (which are evaluated). | |
545 | \end{describe} | |
546 | ||
547 | \begin{describe}{cls}{tagged-c-type (qualifiable-c-type) | |
548 | \&key :qualifiers :tag} | |
549 | Provides common behaviour for C tagged types. A @<tag> is a string | |
550 | containing a C identifier. | |
551 | ||
552 | Two tagged types are equal if and only if they have the same class, their | |
553 | @<tag>s are @|string=|, and they have matching qualifiers. (User-defined | |
554 | subclasses may have additional methods on @|c-type-equal-p| which impose | |
555 | further restrictions.) | |
556 | \end{describe} | |
557 | \begin{boxy}[Bug] | |
558 | Sod maintains distinct namespaces for the three kinds of tagged types. In | |
559 | C, there is only one namespace for tags which is shared between enums, | |
560 | structs and unions. | |
561 | \end{boxy} | |
562 | ||
563 | \begin{describe}{gf}{c-tagged-type-kind @<type>} | |
564 | Returns a symbol classifying the tagged @<type>: one of @|enum|, @|struct| | |
565 | or @|union|. User-defined subclasses of @|tagged-c-type| should return | |
566 | their own classification symbols. It is intended that @|(string-downcase | |
567 | (c-tagged-type-kind @<type>))| be valid C syntax.\footnote{% | |
568 | Alas, C doesn't provide a syntactic category for these keywords; | |
569 | \Cplusplus\ calls them a @<class-key>.} % | |
570 | \end{describe} | |
571 | ||
572 | \begin{describe}{cls}{c-enum-type (tagged-c-type) \&key :qualifiers :tag} | |
573 | Represents a C enumerated type. An instance denotes the C type @|enum| | |
574 | @<tag>. See the direct superclass @|tagged-c-type| for details. | |
575 | ||
576 | The type specifier @|(enum @<tag> @<qualifier>^*)| returns the (unique | |
577 | interned) enumerated type with the given @<tag> and @<qualifier>s (all | |
578 | evaluated). | |
579 | \end{describe} | |
580 | \begin{describe}{fun}{make-enum-type @<tag> \&optional @<qualifiers>} | |
581 | Return the (unique interned) C type object for the enumerated C type whose | |
582 | tag is @<tag> (a string) and which has the given @<qualifiers> (a list of | |
583 | keywords). | |
584 | \end{describe} | |
585 | ||
586 | \begin{describe}{cls}{c-struct-type (tagged-c-type) \&key :qualifiers :tag} | |
587 | Represents a C structured type. An instance denotes the C type @|struct| | |
588 | @<tag>. See the direct superclass @|tagged-c-type| for details. | |
589 | ||
590 | The type specifier @|(struct @<tag> @<qualifier>^*)| returns the (unique | |
591 | interned) structured type with the given @<tag> and @<qualifier>s (all | |
592 | evaluated). | |
593 | \end{describe} | |
594 | \begin{describe}{fun}{make-struct-type @<tag> \&optional @<qualifiers>} | |
595 | Return the (unique interned) C type object for the structured C type whose | |
596 | tag is @<tag> (a string) and which has the given @<qualifiers> (a list of | |
597 | keywords). | |
598 | \end{describe} | |
599 | ||
600 | \begin{describe}{cls}{c-union-type (tagged-c-type) \&key :qualifiers :tag} | |
601 | Represents a C union type. An instance denotes the C type @|union| | |
602 | @<tag>. See the direct superclass @|tagged-c-type| | |
603 | for details. | |
604 | ||
605 | The type specifier @|(union @<tag> @<qualifier>^*)| returns the (unique | |
606 | interned) union type with the given @<tag> and @<qualifier>s (all | |
607 | evaluated). | |
608 | \end{describe} | |
609 | \begin{describe}{fun}{make-union-type @<tag> \&optional @<qualifiers>} | |
610 | Return the (unique interned) C type object for the union C type whose tag | |
611 | is @<tag> (a string) and which has the given @<qualifiers> (a list of | |
612 | keywords). | |
613 | \end{describe} | |
614 | ||
615 | \subsection{Pointers and arrays} \label{sec:proto.c-types.ptr-array} | |
616 | ||
617 | Pointers and arrays are \emph{compound types}: they're defined in terms of | |
618 | existing types. A pointer describes the type of objects it points to; an | |
619 | array describes the type of array element. | |
620 | \begin{describe}{gf}{c-type-subtype @<type>} | |
621 | Returns the underlying type of a compound type @<type>. Precisely what | |
622 | this means depends on the class of @<type>. | |
623 | \end{describe} | |
624 | ||
625 | \begin{describe}{cls}{c-pointer-type (qualifiable-c-type) | |
626 | \&key :qualifiers :subtype} | |
627 | Represents a C pointer type. An instance denotes the C type @<subtype> | |
628 | @|*|@<qualifiers>. | |
629 | ||
630 | The @<subtype> may be any C type. Two pointer types are equal if and only | |
631 | if their subtypes are equal and they have matching qualifiers. | |
632 | ||
633 | The type specifier @|(* @<type-spec> @<qualifier>^*)| returns a type | |
634 | qualified pointer-to-@<subtype>, where @<subtype> is the type specified by | |
635 | @<type-spec> and the @<qualifier>s are qualifier keywords (which are | |
636 | evaluated). The synonyms @|ptr| and @|pointer| may be used in place of the | |
637 | star @`*'. | |
638 | ||
639 | The symbol @|string| is a type specifier for the type of pointer to | |
640 | characters; the symbol @|const-string| is a type specifier for the type | |
641 | pointer to constant characters. | |
642 | \end{describe} | |
643 | \begin{describe}{fun}{make-pointer-type @<subtype> \&optional @<qualifiers>} | |
644 | Return an object describing the type of qualified pointers to @<subtype>. | |
645 | If @<subtype> is interned, then the returned pointer type object is | |
646 | interned also. | |
647 | \end{describe} | |
648 | ||
649 | \begin{describe}{cls}{c-array-type (c-type) \&key :subtype :dimensions} | |
650 | Represents a multidimensional C array type. The @<dimensions> are a list | |
651 | of dimension specifiers $d_0$, $d_1$, \ldots, $d_{n-1}$; an instance then | |
652 | denotes the C type @<subtype> @|[$d_0$][$d_1$]$\ldots$[$d_{n-1}$]|. An | |
653 | individual dimension specifier is either a string containing a C integral | |
654 | constant expression, or nil which is equivalent to an empty string. Only | |
655 | the first (outermost) dimension $d_0$ should be empty. | |
656 | ||
657 | C doesn't actually have multidimensional arrays as a primitive notion; | |
658 | rather, it permits an array (with known extent) to be the element type of | |
659 | an array, which achieves an equivalent effect. C arrays are stored in | |
660 | row-major order: i.e., if we write down the indices of the elements of an | |
661 | array in order of ascending address, the rightmost index varies fastest; | |
662 | hence, the type constructed is more accurately an array of $d_0$ arrays of | |
663 | $d_1$ of \ldots\ arrays of $d_{n-1}$ elements of type @<subtype>. We shall | |
664 | continue to abuse terminology and refer to multidimensional arrays. | |
665 | ||
666 | The type specifier @|([] @<type-spec> @<dimension>^*)| constructs a | |
667 | multidimensional array with the given @<dimension>s whose elements have the | |
668 | type specified by @<type-spec>. If no dimensions are given then a | |
669 | single-dimensional array with unspecified extent. The synonyms @|array| | |
670 | and @|vector| may be used in place of the brackets @`[]'. | |
671 | \end{describe} | |
672 | \begin{describe}{fun}{make-array-type @<subtype> @<dimensions>} | |
673 | Return an object describing the type of arrays with given @<dimensions> and | |
674 | with element type @<subtype> (an instance of @|c-type|). The @<dimensions> | |
675 | argument is a list whose elements are strings or nil; see the description | |
676 | of the class @|c-array-type| above for details. | |
677 | \end{describe} | |
678 | \begin{describe}{gf}{c-array-dimensions @<type>} | |
679 | Returns the dimensions of @<type>, an array type, as an immutable list. | |
680 | \end{describe} | |
681 | ||
682 | \subsection{Function types} \label{sec:proto.c-types.fun} | |
683 | ||
684 | \begin{describe}{cls}{c-function-type (c-type) \&key :subtype :arguments} | |
685 | Represents C function types. An instance denotes the C type of a C | |
686 | function which | |
687 | \end{describe} | |
688 | ||
689 | %%%----- That's all, folks -------------------------------------------------- | |
690 | ||
691 | %%% Local variables: | |
692 | %%% mode: LaTeX | |
693 | %%% TeX-master: "sod.tex" | |
694 | %%% TeX-PDF-mode: t | |
695 | %%% End: |