src/class-output.lisp: Split up `hook-output' on `sod-class' and `:h'.
[sod] / doc / output.tex
... / ...
CommitLineData
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
28This chapter deals with actually generating output files. It will be of
29interest to programmers introducing new layout object classes, or new kinds
30of 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
36C compilers are picky about the order in which things are presented to them
37in their input; but information about the structure of our classes is
38scattered among a variety of different layout objects. It's not the case
39that a layout object only contributes to a single localized portion of the
40output: for example, a @|vtmsgs| layout object is responsible for declaring
41both the appropriate @|struct $C$__vtmsgs_$a$| structure in the header file,
42populated with method entry pointers, but also declaring its member in the
43enclosing @|struct $C$__vt_$i$| structure.
44
45One approach would be to have the various layout objects just know how to
46call each other in the right order so as to have everything come out
47properly. That would make extending the translator, e.g., to add new kinds
48of layout objects, rather difficult. And it doesn't let users insert custom
49C fragments in flexible ways.
50
51Instead, there's a clear separation between which things need to be output,
52and the order in which they're produced.
53
54Ordering is handled by a \emph{sequencer} object. A sequencer doesn't know
55anything particular about output: its job is simply to do things in a
56particular order. It's described here because Sod only uses it for output
57scheduling.
58
59A sequencer maintains a collection of named \emph{items}, each of which has a
60name and a list of functions associated with it. A name can be any Lisp
61object. Names are compared using @|equal|, so lists can be used to construct
62a hierarchical namespace.
63
64The sequencer also maintains a collection of \emph{constraints}, which take
65the 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
67the item named $N_2$, and so on, all of which must be scheduled before the
68item named $N_k$. Items with these names do not need to exist or be known to
69the sequencer. An item name may appear in any number of constraints, all of
70which apply.
71
72It might be that a collection of constraints is impossible to satisfy: for
73example, the set
74\begin{center} \codeface
75 (alice bob) \qquad (bob carol) \qquad (carol alice)
76\end{center}
77can't be satisfied, since the first constraint requires that @|alice|
78precedes @|bob|, but the third says that @|alice| must come after @|carol|,
79and 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
81fails and signals an error of type @|inconsistent-merge-error|.
82
83It is possible, but tedious, to explicitly order an entire collection of
84items by adding constraints. In the absence of explicit constraints to order
85them, items are ordered according to the order in which constraints naming
86them were first added to the sequencer. Items not named in any constraint
87are not processed at all.
88
89For 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}
96The constraints give us that $@|python| < @|icon| < @|perl| < @|java|$, and
97also $@|lisp| < @|java|$. In this case, @|lisp| precedes @|python| because
98@|lisp| is mentioned in the second constraint while @|python| isn't mentioned
99until 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{Module output} \label{output.module}
176
177\subsection{Producing output}
178
179\begin{describe}{gf}
180 {module-output-file @<module> @<output-type> @<output-dir>
181 @> @<pathname>}
182 \begin{describe*}
183 {\dhead{meth}{module,symbol}
184 {module-output-file \=(@<module> module) \\
185 \>(@<output-type> symbol) \\
186 \>@<output-dir>
187 \nlret @<pathname>}
188 \dhead{meth}{module,pathname}
189 {module-output-file \=(@<module> module) \\
190 \>(@<output-type> pathname) \\
191 \>@<output-dir>
192 \nlret @<pathname>}}
193 \end{describe*}
194\end{describe}
195
196\begin{describe}{gf}{write-dependency-file @<module> @<reason> @<output-dir>}
197\end{describe}
198
199\begin{describe}{fun}{output-module @<module> @<reason> @<stream>}
200\end{describe}
201
202
203\subsection{Managing output types} \label{output.module.manage}
204
205\begin{describe}{fun}{declare-output-type @<reason> @<pathname>}
206\end{describe}
207
208\begin{describe}{fun}{output-type-pathname @<reason> @> @<pathname>}
209\end{describe}
210
211
212\subsection{Utilities} \label{output.module.utilities}
213
214\begin{describe}{fun}{banner @<title> @<output> \&key :blank-line-p}
215\end{describe}
216
217\begin{describe}{fun}{guard-name @<filename> @> @<string>}
218\end{describe}
219
220\begin{describe}{fun}
221 {one-off-output @<token> @<sequencer> @<item-name> @<function>}
222\end{describe}
223
224%%%--------------------------------------------------------------------------
225\section{Class output} \label{output.class}
226
227\begin{describe}{var}{*instance-class*}
228\end{describe}
229
230\begin{describe}{gf}{emit-class-typedef @<class> @<stream>}
231\end{describe}
232
233\begin{describe}{gf}{emit-class-object-decl @<class> @<stream>}
234\end{describe}
235
236\begin{describe}{gf}{emit-class-conversion-macro @<class> @<super> @<stream>}
237\end{describe}
238
239\begin{describe*}
240 {\dhead{gf}{emit-message-macro @<class> @<entry> @<stream>}
241 \dhead{gf}{emit-message-macro-defn
242 \=@<class> @<entry> @<varargsp> @<me> \\
243 \>@<in-names> @<out-names> @<stream>}}
244\end{describe*}
245
246%% output for `h' files
247%%
248%% prologue
249%% guard start
250%% typedefs start
251%% typedefs
252%% typedefs end
253%% includes start
254%% includes
255%% includes end
256%% classes start
257%% early-user start
258%% early-user
259%% early-user end
260%% CLASS banner
261%% CLASS islots start
262%% CLASS islots slots
263%% CLASS islots end
264%% CLASS vtmsgs start
265%% CLASS vtmsgs CLASS start
266%% CLASS vtmsgs CLASS slots
267%% CLASS vtmsgs CLASS end
268%% CLASS vtmsgs end
269%% CLASS vtables start
270%% CLASS vtables CHAIN-HEAD start
271%% CLASS vtables CHAIN-HEAD slots
272%% CLASS vtables CHAIN-HEAD end
273%% CLASS vtables end
274%% CLASS vtable-externs
275%% CLASS vtable-externs-after
276%% CLASS methods start
277%% CLASS methods
278%% CLASS methods end
279%% CLASS ichains start
280%% CLASS ichains CHAIN-HEAD start
281%% CLASS ichains CHAIN-HEAD slots
282%% CLASS ichains CHAIN-HEAD end
283%% CLASS ichains end
284%% CLASS ilayout start
285%% CLASS ilayout slots
286%% CLASS ilayout end
287%% CLASS conversions
288%% CLASS object
289%% classes end
290%% user start
291%% user
292%% user end
293%% guard end
294%% epilogue
295
296%% output for `c' files
297%%
298%% prologue
299%% includes start
300%% includes
301%% includes end
302%% early-user start
303%% early-user
304%% early-user end
305%% classes start
306%% CLASS banner
307%% CLASS direct-methods start
308%% CLASS direct-methods METHOD start
309%% CLASS direct-methods METHOD body
310%% CLASS direct-methods METHOD end
311%% CLASS direct-methods end
312%% CLASS effective-methods
313%% CLASS vtables start
314%% CLASS vtables CHAIN-HEAD start
315%% CLASS vtables CHAIN-HEAD class-pointer METACLASS
316%% CLASS vtables CHAIN-HEAD base-offset
317%% CLASS vtables CHAIN-HEAD chain-offset TARGET-HEAD
318%% CLASS vtables CHAIN-HEAD vtmsgs CLASS start
319%% CLASS vtables CHAIN-HEAD vtmsgs CLASS slots
320%% CLASS vtables CHAIN-HEAD vtmsgs CLASS end
321%% CLASS vtables CHAIN-HEAD end
322%% CLASS vtables end
323%% CLASS object prepare
324%% CLASS object start
325%% CLASS object CHAIN-HEAD ichain start
326%% CLASS object SUPER slots start
327%% CLASS object SUPER slots
328%% CLASS object SUPER vtable
329%% CLASS object SUPER slots end
330%% CLASS object CHAIN-HEAD ichain end
331%% CLASS object end
332%% classes end
333%% user start
334%% user
335%% user end
336%% epilogue
337
338%%%----- That's all, folks --------------------------------------------------
339
340%%% Local variables:
341%%% mode: LaTeX
342%%% TeX-master: "sod.tex"
343%%% TeX-PDF-mode: t
344%%% End: