Static instance support.
[sod] / doc / output.tex
1 %%% -*-latex-*-
2 %%%
3 %%% Output machinery
4 %%%
5 %%% (c) 2015 Straylight/Edgeware
6 %%%
7
8 %%%----- Licensing notice ---------------------------------------------------
9 %%%
10 %%% This file is part of the Sensible Object Design, an object system for C.
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{The output system} \label{ch:output}
27
28 This chapter deals with actually generating output files. It will be of
29 interest to programmers introducing new layout object classes, or new kinds
30 of output files. An understanding of the material in
31 \xref{sec:structures.layout} will prove valuable.
32
33 %%%--------------------------------------------------------------------------
34 \section{Output sequencing} \label{sec:output.sequencer}
35
36 C compilers are picky about the order in which things are presented to them
37 in their input; but information about the structure of our classes is
38 scattered among a variety of different layout objects. It's not the case
39 that a layout object only contributes to a single localized portion of the
40 output: for example, a @|vtmsgs| layout object is responsible for declaring
41 both the appropriate @|struct $C$__vtmsgs_$a$| structure in the header file,
42 populated with method entry pointers, but also declaring its member in the
43 enclosing @|struct $C$__vt_$i$| structure.
44
45 One approach would be to have the various layout objects just know how to
46 call each other in the right order so as to have everything come out
47 properly. That would make extending the translator, e.g., to add new kinds
48 of layout objects, rather difficult. And it doesn't let users insert custom
49 C fragments in flexible ways.
50
51 Instead, there's a clear separation between which things need to be output,
52 and the order in which they're produced.
53
54 Ordering is handled by a \emph{sequencer} object. A sequencer doesn't know
55 anything particular about output: its job is simply to do things in a
56 particular order. It's described here because Sod only uses it for output
57 scheduling.
58
59 A sequencer maintains a collection of named \emph{items}, each of which has a
60 name and a list of functions associated with it. A name can be any Lisp
61 object. Names are compared using @|equal|, so lists can be used to construct
62 a hierarchical namespace.
63
64 The sequencer also maintains a collection of \emph{constraints}, which take
65 the form of lists of item names. A constraint of the form @|($N_1$, $N_2$,
66 $\ldots$, $N_k$)| requires that the item named $N_1$ must be scheduled before
67 the item named $N_2$, and so on, all of which must be scheduled before the
68 item named $N_k$. Items with these names do not need to exist or be known to
69 the sequencer. An item name may appear in any number of constraints, all of
70 which apply.
71
72 It might be that a collection of constraints is impossible to satisfy: for
73 example, the set
74 \begin{center} \codeface
75 (alice bob) \qquad (bob carol) \qquad (carol alice)
76 \end{center}
77 can't be satisfied, since the first constraint requires that @|alice|
78 precedes @|bob|, but the third says that @|alice| must come after @|carol|,
79 and the second that @|carol| comes after @|bob|: it's not possible that
80 @|alice| comes before @|bob| and after @|bob|. In this case, the sequencer
81 fails and signals an error of type @|inconsistent-merge-error|.
82
83 It is possible, but tedious, to explicitly order an entire collection of
84 items by adding constraints. In the absence of explicit constraints to order
85 them, items are ordered according to the order in which constraints naming
86 them were first added to the sequencer. Items not named in any constraint
87 are not processed at all.
88
89 For example, suppose we have the following constraints.
90 \begin{center} \codeface
91 (perl java) \qquad
92 (lisp java) \qquad
93 (python icon) \qquad
94 (icon perl)
95 \end{center}
96 The constraints give us that $@|python| < @|icon| < @|perl| < @|java|$, and
97 also $@|lisp| < @|java|$. In this case, @|lisp| precedes @|python| because
98 @|lisp| is mentioned in the second constraint while @|python| isn't mentioned
99 until the third. So the final processing order is
100 \begin{center}
101 @|lisp|, \quad
102 @|python|, \quad
103 @|icon|, \quad
104 @|perl|, \quad
105 @|java|
106 \end{center}
107
108
109 \begin{describe}{cls}{sequencer-item}
110 An object of class @|sequencer-item| represents a sequencer item.
111 Sequencer items maintain a \emph{name} and a list of \emph{functions}.
112 Names are compared using @|equal|.
113
114 The functions are maintained in \emph{reverse order}, because it's
115 convenient to be able to add new functions using @|push|.
116 \end{describe}
117
118 \begin{describe}{fun}{sequencer-item-p @<object> @> @<generalized-boolean>}
119 Return non-nil if and only if @<object> is a @|sequencer-item|.
120 \end{describe}
121
122 \begin{describe}{fun}
123 {make-sequencer-item @<name> \&optional @<functions> @> @<item>}
124 Create and return a new sequencer item with the given @<name> and list of
125 @<functions>; the list of functions defaults to nil if omitted.
126 \end{describe}
127
128 \begin{describe*}
129 {\dhead{fun}{sequencer-item-name @<item> @> @<name>}
130 \dhead{fun}{sequencer-item-functions @<item> @> @<list>}
131 \dhead{fun}{setf (sequencer-item-functions @<item>) @<list>}}
132 These functions read or modify the state of a sequencer @<item>, as
133 originally established by @|make-sequencer-item|.
134
135 It is an error to modify an item's list of functions during a call to
136 @|invoke-sequencer-items| on the item's owning sequencer.
137 \end{describe*}
138
139 \begin{describe}{cls}{sequencer () \&key :constraints}
140 \end{describe}
141
142 \begin{describe*}
143 {\dhead{fun}{sequencer-constraints @<sequencer> @> @<list>}
144 \dhead{fun}{setf (sequencer-constraints @<sequencer>) @<list>}
145 \dhead{fun}{sequencer-table @<sequencer> @> @<hash-table>}}
146 \end{describe*}
147
148 \begin{describe}{fun}{ensure-sequencer-item @<sequencer> @<name> @> @<item>}
149 \end{describe}
150
151 \begin{describe}{fun}{add-sequencer-constraint @<sequencer> @<constraint>}
152 \end{describe}
153
154 \begin{describe}{fun}
155 {add-sequencer-item-function @<sequencer> @<name> @<function>}
156 \end{describe}
157
158 \begin{describe}{fun}
159 {invoke-sequencer-items @<sequencer> \&rest @<arguments>}
160 \end{describe}
161
162 \begin{describe}{gf}{hook-output @<object> @<reason> @<sequencer>}
163 \begin{describe}{meth}{t,t}
164 {hook-output (@<object> t) (@<reason> t) @<sequencer>}
165 \end{describe}
166 \end{describe}
167
168 \begin{describe}{mac}
169 {sequence-output (@<stream-var> @<sequencer>) \\ \ind
170 @[ :constraint (@<item-name>^*) @] \\
171 @{ (@<item-name> @<form>^*) @}^*}
172 \end{describe}
173
174 %%%--------------------------------------------------------------------------
175 \section{Output structure} \label{output.structure}
176
177 The structures of the header and implementation files produced by the
178 translator are detailed in tables~\ref{tab:output.structure.header}
179 and~\ref{tab:output.structure.impl}, respectively.
180
181 The following notes may be helpful.
182 \begin{itemize}
183 \item The `specializers' shown in the tables identify the method of the
184 @|hook-output| function responsible for producing the corresponding
185 `contents'. Subclasses can extend or override the listed methods (with
186 appropriate care).
187 \item A row showing an `item' but no `specializers' indicate that the
188 translator does not prodice output for that item. It may be present for
189 ordering purposes, or as a place for user output.
190 \item A row showing `specializers' but (apparently) no `contents' indicates
191 that a blank line is emitted at that point.
192 \end{itemize}
193
194 \begingroup
195 \LTleft=-\leftindent plus 1fil minus 1fil
196 \LTright=0pt plus 1fil minus 1fil
197 \small
198 \def\banner#1{\hbox to\hsize{/*@-@-@-@-@- #1
199 \rlap{@-}\leaders\hbox{@-}\hfil\llap{@-}*/}}
200 \def\fmtspecs#1, #2 {@|#1|, @|(eql #2)|}
201 \def\slotlabel#1#2{\leavevmode\hbox to30mm{\kern#1em/* #2\hfil= */}}
202
203 \clearpage
204 \begin{longtable}{>{\codeface}p{41mm}>{\fmtspecs}l>{\codeface}p{65mm}}
205 \caption{Header file output structure}
206 \label{tab:output.structure.header} \\ \hlx{hv}
207 \thd{Sequencer item} & \thd{@|hook-output| specializers}
208 & \thd{Output} \\ \hlx{vhv}
209 \endfirsthead
210 \caption[]{Header file output structure \emph{(cont.)}} \\ \hlx{hv}
211 \thd{Sequencer item} & \thd{@|hook-output| specializers}
212 & \thd{Contents} \\ \hlx{vhv}
213 \endhead
214 \hlx{vh}
215 \endfoot
216 x & sod-class-effective-slot, 'class & x \kill
217 %
218 :prologue & module, :h
219 & \begin{nprog}
220 /\=* @-*@- mode: c; indent-tabs-mode: nil @-*@- \\
221 \>* \\
222 \>* Header file generated by SOD for @<module> \\
223 \>*/ \\
224 \end{nprog} \\ \hlx{v/}
225 (:guard :start) & module, :h
226 & \begin{nprog}
227 \#ifndef @<MODULE>{}_H \\
228 \#define @<MODULE>{}_H \\+
229 \#ifdef __cplusplus \\ \ind
230 extern "C" \{ \-\\
231 \#endif \\
232 \end{nprog} \\ \hlx{v/}
233 %
234 (:typedefs :start) & module, :h
235 & \begin{nprog} \banner{Forward type declarations} \\ \end{nprog}
236 \\*\hlx{v}
237 :typedefs & sod-class, :h
238 & typedef struct @<class>{}__ichain_@<cls> @<class>; \\*\hlx{v}
239 (:typedefs :end) & module, :h \\ \hlx{v/}
240 %
241 (:includes :start) & module, :h
242 & \begin{nprog} \banner{External header files} \\ \end{nprog}
243 \\*\hlx{v}
244 :includes \\*\hlx{v}
245 :early-decls & sod-class, :h
246 & SOD__VARARGS_MACRO_PREAMBLE \\*\hlx{v}
247 (:includes :end) & module, :h \\*\hlx{v}
248 %
249 (:early-user :start) \\*
250 :early \\*
251 (:early-user :end) \\ \hlx{v/}
252 %
253 (:classes :start) \\*\hlx{v}
254 %
255 (@<class> :banner) & sod-class, :h
256 & \begin{nprog} \banner{Class @<class>} \\ \end{nprog} \\*\hlx{v}
257 %
258 (@<class> :islots :start) & sod-class, :h
259 & \begin{nprog}
260 /* Instance slots. */ \\
261 struct @<class>{}__islots \{
262 \end{nprog} \\*\hlx{v}
263 (@<class> :islots :slots) & sod-slot, 'islots
264 & \quad @<type> @<slot-name>; \\*\hlx{v}
265 (@<class> :islots :end) & sod-class, :h
266 & \begin{nprog} \}; \\ \end{nprog} \\ \hlx{v/}
267 %
268 (@<class> :vtmsgs :start) \\*
269 (@<class> :vtmsgs @<super> :start) & vtmsgs, 'vtmsgs
270 & \begin{nprog}
271 /* Messages protocol from class @<super>. */ \\*
272 struct @<class>{}__vtmsgs_@<s> \{
273 \end{nprog} \\*\hlx{v}
274 (@<class> :vtmsgs @<super> :slots) & method-entry, 'vtmsgs
275 & \quad @<type> (*msg)(@<class> *, \dots); \\*\hlx{v}
276 (@<class> :vtmsgs @<super> :end) & vtmsgs, 'vtmsgs
277 & \begin{nprog} \}; \\ \end{nprog} \\*
278 (@<class> :vtmsgs :end) \\ \hlx{v/}
279 %
280 (@<class> :vtables :start) \\*
281 \begin{nprog}
282 (@<class> \=:vtable \\
283 \>@<chain-head> :start)
284 \end{nprog} & vtable, :h
285 & \begin{nprog}
286 /* Vtable structure. */ \\*
287 struct @<class>{}__vt_@<h> \{
288 \end{nprog} \\*\hlx{v}
289 \begin{nprog}
290 (@<class> \=:vtable \\
291 \>@<chain-head> :slots)
292 \end{nprog} & class-pointer, :h
293 & \quad const @<meta> *_class; \\*
294 \begin{nprog}
295 (@<class> \=:vtable \\
296 \>@<chain-head> :slots)
297 \end{nprog} & class-pointer, :h
298 & \quad const @<meta> *_cls_@<n>; \\*
299 \begin{nprog}
300 (@<class> \=:vtable \\
301 \>@<chain-head> :slots)
302 \end{nprog} & base-offset, :h
303 & \quad size_t _base; \\*
304 \begin{nprog}
305 (@<class> \=:vtable \\
306 \>@<chain-head> :slots)
307 \end{nprog} & chain-offset, :h
308 & \quad ptrdiff_t _off_@<h>; \\*
309 \begin{nprog}
310 (@<class> \=:vtable \\
311 \>@<chain-head> :slots)
312 \end{nprog} & vmsgs, :h
313 & \quad struct @<class>{}__vtmsgs_@<s> @<s>; \\*\hlx{v}
314 \begin{nprog}
315 (@<class> \=:vtable \\
316 \>@<chain-head> :end)
317 \end{nprog} & vtable, :h
318 & \begin{nprog}
319 \}; \\+
320 /* Union of equivalent superclass vtables. */ \\
321 union @<class>{}__vtu_@<h> \{ \\ \ind
322 struct @<super>{}__vt_@<h> @<s>; \\
323 \quad $\vdots$ \-\\
324 \}; \\
325 \end{nprog} \\*
326 (@<class> :vtables :end) \\
327 %
328 (@<class> :vtable-externs) & sod-class, :h
329 & /* Vtable structures. */ \\*
330 (@<class> :vtable-externs) & vtable, :h
331 & extern const union @<class>{}__vtu_@<h> @<class>{}__vtable_@<h>;
332 \\*
333 (@<class> :vtable-externs-after) & sod-class, :h \\ \hlx{v/}
334 %
335 (@<class> :methods :start) & sod-class, :h
336 & /* Direct methods. */ \\*
337 (@<class> :methods :defs) & sod-method, :h
338 & \begin{nprog}
339 struct @<class>{}__@<role>{}_suppliedp_@<s>{}__@<msg> \{ \\ \ind
340 unsigned @<arg>: 1; \\
341 \quad $\vdots$ \-\\
342 \}; \\
343 \end{nprog} \\*\hlx{v}
344 (@<class> :methods) & sod-method, :h
345 & struct @<class>{}__@<role>{}_method_@<s>{}__@<msg>(\dots);
346 \\*\hlx{v}
347 (@<class> :methods :end) & sod-class, :h \\ \hlx{v/}
348 %
349 (@<class> :ichains :start) \\*
350 \begin{nprog}
351 (@<class> \=:ichains \\
352 \>@<chain-head> :start)
353 \end{nprog} & ichain, :h
354 & \begin{nprog}
355 /* Instance chain structure. */ \\
356 struct @<class>{}__ichain_@<h> \{
357 \end{nprog} \\*\hlx{v}
358 \begin{nprog}
359 (@<class> \=:ichains \\
360 \>@<chain-head> :slots)
361 \end{nprog} & vtable-pointer, :h
362 & \quad const struct @<class>{}__vt_@<h> *_vt; \\*
363 \begin{nprog}
364 (@<class> \=:ichains \\
365 \>@<chain-head> :slots)
366 \end{nprog} & islots, :h
367 & \quad struct @<class>{}__islots @<c>; \\*\hlx{v}
368 \begin{nprog}
369 (@<class> \=:ichains \\
370 \>@<chain-head> :end)
371 \end{nprog} & vtable, :h
372 & \begin{nprog}
373 \}; \\+
374 /* Union of equivalent superclass chains. */ \\
375 union @<class>{}__ichainu_@<h> \{ \\ \ind
376 struct @<super>{}__ichain_@<h> @<s>; \\
377 \quad $\vdots$ \-\\
378 \}; \\
379 \end{nprog} \\*
380 (@<class> :ichains :end) \\ \hlx{v/}
381 %
382 (@<class> :ilayout :start) & ilayout, :h
383 & \begin{nprog}
384 /* Instance layout. */ \\
385 struct @<class>{}__ilayout \{
386 \end{nprog} \\*\hlx{v}
387 (@<class> :ilayout :slots) & ichain, 'ilayout
388 & \quad union @<class>{}__ichainu_@<h>; \\*\hlx{v}
389 (@<class> :ilayout :end) & ilayout, :h
390 & \begin{nprog} \}; \\ \end{nprog} \\ \hlx{v/}
391 %
392 (@<class> :conversions) & sod-class, :h
393 & \begin{nprog}
394 /* Conversion macros. */ \\
395 \#define @<CLASS>{}__CONV_@<S>(_obj) \dots \\
396 \quad $\vdots$ \\
397 \end{nprog} \\ \hlx{v/}
398 %
399 (@<class> :message-macros) & sod-class, :h
400 & \begin{nprog}
401 /* Message invocation macros. */ \\
402 \#define @<class>{}_@<msg>(me, \dots) \dots \\
403 \quad $\vdots$ \\
404 \end{nprog} \\ \hlx{v/}
405 %
406 (@<class> :object) & sod-class, :h
407 & \begin{nprog}
408 /* The class object. */ \\
409 extern const struct @<meta>{}__ilayout @<class>{}__classobj; \\
410 \#define @<class>{}__class (\&\dots) \\
411 \#define @<class>{}__cls_@<n> (\&\dots) \\
412 \quad $\vdots$ \\
413 \end{nprog} \\*\hlx{v}
414 %
415 (:classes :end) \\ \hlx{v/}
416 %
417 (:static-instances :start) & static-instance, :h
418 & \begin{nprog} \banner{Public static instances} \\ \end{nprog}
419 \\*\hlx{v}
420 :static-instances & static-instance, :h
421 & \begin{nprog}
422 extern $[@"const"]$ struct @<class>{}__ilayout
423 @<inst>{}__instance; \\
424 \#define @<inst> (\&@<inst>{}__instance.@<h>.@<c>)
425 \end{nprog} \\*
426 (:static-instances :end) & static-instance, :h
427 & \\ \hlx{v/}
428 %
429 (:user :start) \\*
430 :user \\*
431 (:user :end) \\ \hlx{v/}
432 %
433 (:guard :end) & module, :h
434 & \begin{nprog}
435 \banner{That's all, folks} \\+
436 \#ifdef __cplusplus \\ \ind
437 \} \-\\
438 \#endif \\+
439 \#endif
440 \end{nprog} \\*\hlx{v}
441 %
442 :epilogue \\
443 \end{longtable}
444
445 \clearpage
446 \begin{longtable}{>{\codeface}p{41mm}>{\fmtspecs}l>{\codeface}p{65mm}}
447 \caption{Implementation file output structure}
448 \label{tab:output.structure.impl} \\ \hlx{hv}
449 \thd{Sequencer item} & \thd{@|hook-output| specializers}
450 & \thd{Contents} \\ \hlx{vhv}
451 \endfirsthead
452 \caption[]{Implementation file output structure \emph{(cont.)}}
453 \\ \hlx{hv}
454 \thd{Sequencer item} & \thd{@|hook-output| specializers}
455 & \thd{Contents} \\ \hlx{vhv}
456 \endhead
457 \hlx{vh}
458 \endfoot
459 %
460 :prologue & module, :c
461 & \begin{nprog}
462 /\=* @-*@- mode: c; indent-tabs-mode: nil @-*@- \\
463 \>* \\
464 \>* Implementation file generated by SOD for @<module> \\
465 \>*/ \\
466 \end{nprog} \\ \hlx{v/}
467 %
468 (:includes :start) & module, :c
469 & \begin{nprog}
470 \banner{External header files} \\
471 \end{nprog} \\*\hlx{v}
472 :includes \\*\hlx{v}
473 (:includes :end) & module, :c \\*\hlx{v}
474 %
475 (:early-user :start) \\*
476 :early \\*
477 (:early-user :end) \\ \hlx{v/}
478 %
479 (:static-instances :start) & static-instance, :c
480 & \begin{nprog} \banner{Static instance definitions} \\ \end{nprog}
481 \\*\hlx{v}
482 (:static-instances :decls) & static-instance, :c
483 & \begin{nprog}
484 /* Forward declarations. */ \\+
485 static $[@"const"]$ struct @<class>{}__ilayout
486 @<inst>{}__instance; \\
487 \#define @<inst> (\&@<inst>{}__instance.@<h>.@<c>)
488 \end{nprog} \\*
489 (:static-instances :gap) & static-instance, :c
490 & \\
491 (@<inst> :start) & sod-class, 'static-instance
492 & \begin{nprog}
493 /* Static instance `@<inst>'. */ \\
494 $[@"static"]$ $[@"const"]$ struct @<inst>{}__ilayout
495 @<inst>{}__instance = \{
496 \end{nprog} \\*\hlx{v}
497 (@<inst> :chain @<chain-head> :start) & ichain, 'static-instance
498 & \quad \{ \{ /* @<n> ichain */ \\*
499 (@<inst> :vtable @<chain-head>) & vtable-pointer, 'static-instance
500 & \slotlabel{3}{_vt} \&@<class>{}__vtable_@<h>.@<c>, \\*
501 (@<inst> :slots @<super> :start) & islots, 'static-instance
502 & \quad\quad \{ /* Class @<super> */ \\*
503 (@<inst> :slots @<super>) & effective-slot, 'static-instance
504 & \slotlabel{4}{@<slot>} @<value>, \\*
505 (@<inst> :slots @<super> :end) & islots, 'static-instance
506 & \quad\quad \}, \\*
507 (@<inst> :chain @<chain-head> :end) & ichain, 'static-instance
508 & \quad \} \}, \\*
509 (@<inst> :end) & sod-class, 'static-instance
510 & \begin{nprog} \}; \\ \end{nprog} \\ \hlx{v/}
511 %
512 (:classes :start) \\*\hlx{v}
513 %
514 (@<class> :banner) & sod-class, :c
515 & \begin{nprog} \banner{Class @<class>} \\ \end{nprog} \\*\hlx{v}
516 %
517 (@<class> :direct-methods :start) \\*\hlx{v}
518 \begin{nprog}
519 (@<class> \=:direct-method \\
520 \>@<method> :banner)
521 \end{nprog} & sod-method, :c
522 & /* Direct @<role> method on `@<s>.@<msg>' defined by @<class>. */
523 \\*\hlx{v}
524 \begin{nprog}
525 (@<class> \=:direct-method \\
526 \>@<method> :start)
527 \end{nprog} & delegating-direct-method, :c
528 & \#define CALL_NEXT_METHOD (next_method(\dots)) \\*\hlx{v}
529 \begin{nprog}
530 (@<class> \=:direct-method \\
531 \>@<method> :body)
532 \end{nprog} & sod-method, :c
533 & \begin{nprog}
534 @<type> @<class>{}__@<role>{}_method_@<s>{}__@<msg>(\dots) \\
535 \{ \\ \ind
536 $\vdots$ \-\\
537 \}
538 \end{nprog} \\*\hlx{v}
539 \begin{nprog}
540 (@<class> \=:direct-method \\
541 \>@<method> :end)
542 \end{nprog} & delegating-direct-method, :c
543 & \#undef CALL_NEXT_METHOD \\*
544 \begin{nprog}
545 (@<class> \=:direct-method \\
546 \>@<method> :end)
547 \end{nprog} & sod-method, :c \\*\hlx{v}
548 (@<class> :direct-methods :end) \\ \hlx{v/}
549 %
550 (@<class> :effective-methods) & basic-effective-method, :c
551 & \begin{nprog}
552 /\=* Keyword argument structure for `@<s>.@<msg>' defined \\
553 \>* on class @<class>. \\
554 \>*/ \\
555 struct @<class>{}__keywords_@<s>{}__@<msg> \{ \\ \ind
556 unsigned @<arg>{}__suppliedp: 1; \\
557 \quad $\vdots$ \\
558 @<type> @<arg>; \\
559 \quad $\vdots$ \-\\
560 \}; \\+
561 @<effective-method-functions> \\
562 \end{nprog} \\ \hlx{v/}
563 %
564 (@<class> :vtables :start) \\*\hlx{v}
565 (@<class> :vtable @<chain-head> :start) & vtable, :c
566 & \begin{nprog}
567 /* Vtable for @<chain-head> chain. */ \\
568 const union @<class>{}__vtu_@<h> @<class>{}__vtable_@<h> = \{
569 \end{nprog} \\*\hlx{v}
570 \begin{nprog}
571 (@<class> \=:vtable @<chain-head> \\
572 \>:class-pointer @<meta>)
573 \end{nprog} & class-pointer, :c
574 & \slotlabel{1}{_class} \&@<cls>{}__classobj.@<n>.@<n>, \\*
575 \begin{nprog}
576 (@<class> \=:vtable @<chain-head> \\
577 \>:class-pointer @<meta>)
578 \end{nprog} & class-pointer, :c
579 & \slotlabel{1}{_cls_@<n>} \&@<cls>{}__classobj.@<n>.@<n>, \\*
580 \begin{nprog}
581 (@<class> \=:vtable @<chain-head> \\
582 \>:base-offset)
583 \end{nprog} & base-offset, :c
584 & \slotlabel{1}{_base} offsetof(\dots), \\*
585 \begin{nprog}
586 (@<class> \=:vtable @<chain-head> \\
587 \>:chain-offset @<target-chain>)
588 \end{nprog} & chain-offset, :c
589 & \slotlabel{1}{_off_@<i>} SOD_OFFSETDIFF(\dots), \\*
590 \begin{nprog}
591 (@<class> \=:vtable @<chain-head> \\
592 \>:vtmsgs @<super> :start)
593 \end{nprog} & vtmsgs, :c
594 & \quad \{ /* Method entries for @<super> messags. */ \\*
595 \begin{nprog}
596 (@<class> \=:vtable @<chain-head> \\
597 \>:vtmsgs @<super> :slots)
598 \end{nprog} & method-entry, :c
599 & \slotlabel{2}{@<mentry>} @<mentry-func>, \\
600 \begin{nprog}
601 (@<class> \=:vtable @<chain-head> \\
602 \>:vtmsgs @<super> :end)
603 \end{nprog} & vtmsgs, :c
604 & \quad \}, \\*
605 (@<class> :vtable @<chain-head> :end) & vtable, :c
606 & \}; \\*\hlx{v}
607 (@<class> :vtables :end) \\ \hlx{v/}
608 %
609 (@<class> :object :prepare) & sod-class-effective-slot, 'class
610 & @<definitions> \\*\hlx{v}
611 %
612 (@<class> :object :start) & sod-class, :c
613 & \begin{nprog}
614 /* The class object. */ \\
615 const struct @<meta>{}__ilayout @<class>{}__classobj = \{
616 \end{nprog} \\*\hlx{v}
617 %
618 \begin{nprog}
619 (@<class> \=:object \\
620 \>@<meta-head> :ichain :start)
621 \end{nprog} & ichain, 'class
622 & \quad \{ \{ /* @<n> ichain */ \\*
623 \begin{nprog}
624 (@<class> \=:object \\
625 \>@<meta-head> :ichain :start)
626 \end{nprog} & vtable-pointer, 'class
627 & \slotlabel{3}{_vt} \&@<meta>{}__vtable_@<n>.@<m>, \\*
628 \begin{nprog}
629 (@<class> \=:object \\
630 \>@<meta> :slots :start)
631 \end{nprog} & islots, 'class
632 & \quad\quad\quad \{ /* Class @<meta> */ \\*
633 \begin{nprog}
634 (@<class> \=:object \\
635 \>@<meta> :slots)
636 \end{nprog} & effective-slot, 'class
637 & \slotlabel{4}{@<slot>} @<value> \\*
638 \begin{nprog}
639 (@<class> \=:object \\
640 \>@<meta> :slots :end)
641 \end{nprog} & islots, 'class
642 & \quad\quad\quad \} \\*
643 \begin{nprog}
644 (@<class> \=:object \\
645 \>@<meta-head> :ichain :end)
646 \end{nprog} & ichain, 'class
647 & \quad \} \}, \\*
648 (@<class> :object :end) & sod-class, :c
649 & \}; \\*\hlx{v}
650 %
651 (:classes :end) \\ \hlx{v/}
652 %
653 (:user :start) \\*
654 :user \\*
655 (:user :end) \\ \hlx{v/}
656 %
657 :epilogue & module, :c
658 & \banner{That's all, folks} \\
659 \end{longtable}
660 \endgroup
661
662 %%%--------------------------------------------------------------------------
663 \section{Module output} \label{output.module}
664
665 \subsection{Producing output}
666
667 \begin{describe}{gf}
668 {module-output-file @<module> @<output-type> @<output-dir>
669 @> @<pathname>}
670 \begin{describe*}
671 {\dhead{meth}{module,symbol}
672 {module-output-file \=(@<module> module) \\
673 \>(@<output-type> symbol) \\
674 \>@<output-dir>
675 \nlret @<pathname>}
676 \dhead{meth}{module,pathname}
677 {module-output-file \=(@<module> module) \\
678 \>(@<output-type> pathname) \\
679 \>@<output-dir>
680 \nlret @<pathname>}}
681 \end{describe*}
682 \end{describe}
683
684 \begin{describe}{gf}{write-dependency-file @<module> @<reason> @<output-dir>}
685 \end{describe}
686
687 \begin{describe}{fun}{output-module @<module> @<reason> @<stream>}
688 \end{describe}
689
690
691 \subsection{Managing output types} \label{output.module.manage}
692
693 \begin{describe}{fun}{declare-output-type @<reason> @<pathname>}
694 \end{describe}
695
696 \begin{describe}{fun}{output-type-pathname @<reason> @> @<pathname>}
697 \end{describe}
698
699
700 \subsection{Utilities} \label{output.module.utilities}
701
702 \begin{describe}{fun}{banner @<title> @<output> \&key :blank-line-p}
703 \end{describe}
704
705 \begin{describe}{fun}{guard-name @<filename> @> @<string>}
706 \end{describe}
707
708 \begin{describe}{fun}
709 {one-off-output @<token> @<sequencer> @<item-name> @<function>}
710 \end{describe}
711
712 %%%--------------------------------------------------------------------------
713 \section{Class output} \label{output.class}
714
715 \begin{describe}{var}{*instance-class*}
716 \end{describe}
717
718 \begin{describe}{gf}{emit-class-typedef @<class> @<stream>}
719 \end{describe}
720
721 \begin{describe}{gf}{emit-class-object-decl @<class> @<stream>}
722 \end{describe}
723
724 \begin{describe}{gf}{emit-class-conversion-macro @<class> @<super> @<stream>}
725 \end{describe}
726
727 \begin{describe*}
728 {\dhead{gf}{emit-message-macro @<class> @<entry> @<stream>}
729 \dhead{gf}{emit-message-macro-defn
730 \=@<class> @<entry> @<varargsp> @<me> \\
731 \>@<in-names> @<out-names> @<stream>}}
732 \end{describe*}
733
734 \begin{describe}{var}{*static-instance*}
735 \end{describe}
736
737 \begin{describe}{gf}{declare-static-instance @<static-instance> @<stream>}
738 \end{describe}
739
740 \begin{describe}{gf}
741 {output-static-instance-initializer @<static-instance> @<effective-slot>
742 @<stream>}
743 \end{describe}
744
745 %%%----- That's all, folks --------------------------------------------------
746
747 %%% Local variables:
748 %%% mode: LaTeX
749 %%% TeX-master: "sod.tex"
750 %%% TeX-PDF-mode: t
751 %%% End: