chiark / gitweb /
src/c-types-impl.lisp, src/c-types-parse.lisp: Support C11 `_Alignas'.
[sod] / src / classes.lisp
CommitLineData
abdf50aa
MW
1;;; -*-lisp-*-
2;;;
dea4d055 3;;; Class definitions for main classes
abdf50aa
MW
4;;;
5;;; (c) 2009 Straylight/Edgeware
6;;;
7
8;;;----- Licensing notice ---------------------------------------------------
9;;;
e0808c47 10;;; This file is part of the Sensible Object Design, an object system for C.
abdf50aa
MW
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(cl:in-package #:sod)
27
59146e6e
MW
28;;; Note! You'll notice that none of the classes defined here store property
29;;; sets persistently, even though there's a `:pset' keyword argument
30;;; accepted by many of the classes' initialization methods. That's because
31;;; part of the pset protocol involves checking that there are no unused
32;;; properties, and this typically happens shortly after the appropriate
33;;; objects are constructed. It would be tempting to stash the pset at
34;;; initialization time, and then pick some property from it out later -- but
35;;; that won't work in general because an error might have been signalled
36;;; about that property. It wouldn't surprise me greatly to discover that
37;;; `most' code paths resulted in the property being looked up in time to
38;;; avoid the unused-property error, but a subtle change in circumstances
39;;; then causes a thing done on demand to be done later, leading to
40;;; irritating and misleading errors being reported to the user. So please
41;;; don't do that.
42
abdf50aa 43;;;--------------------------------------------------------------------------
1f1d88f5 44;;; Classes.
abdf50aa 45
dea4d055
MW
46(export '(sod-class sod-class-name sod-class-nickname
47 sod-class-type sod-class-metaclass
48 sod-class-direct-superclasses sod-class-precedence-list
49 sod-class-chain-link sod-class-chain-head
50 sod-class-chain sod-class-chains
51 sod-class-slots
52 sod-class-instance-initializers sod-class-class-initializers
53 sod-class-messages sod-class-methods
54 sod-class-state
55 sod-class-ilayout sod-class-vtables))
abdf50aa 56(defclass sod-class ()
77027cca
MW
57 ((name :initarg :name :type string :reader sod-class-name)
58 (location :initarg :location :initform (file-location nil)
59 :type file-location :reader file-location)
60 (nickname :initarg :nick :type string :reader sod-class-nickname)
61 (direct-superclasses :initarg :superclasses :type list
abdf50aa 62 :reader sod-class-direct-superclasses)
77027cca 63 (chain-link :initarg :link :type (or sod-class null)
1f1d88f5 64 :reader sod-class-chain-link)
77027cca 65 (metaclass :initarg :metaclass :type sod-class
abdf50aa 66 :reader sod-class-metaclass)
77027cca
MW
67 (slots :initarg :slots :initform nil
68 :type list :accessor sod-class-slots)
69 (instance-initializers :initarg :instance-initializers :initform nil
abdf50aa 70 :type list
abdf50aa 71 :accessor sod-class-instance-initializers)
77027cca
MW
72 (class-initializers :initarg :class-initializers :initform nil
73 :type list :accessor sod-class-class-initializers)
74 (messages :initarg :messages :initform nil
75 :type list :accessor sod-class-messages)
76 (methods :initarg :methods :initform nil
77 :type list :accessor sod-class-methods)
abdf50aa 78
16f9fb72 79 (class-precedence-list :type list :reader sod-class-precedence-list)
abdf50aa 80
16f9fb72 81 (%type :type c-class-type :reader sod-class-type)
ddee4bb1 82
16f9fb72
MW
83 (chain-head :type sod-class :reader sod-class-chain-head)
84 (chain :type list :reader sod-class-chain)
85 (chains :type list :reader sod-class-chains)
abdf50aa 86
16f9fb72
MW
87 (%ilayout :type ilayout :reader sod-class-ilayout)
88 (effective-methods :type list :reader sod-class-effective-methods)
89 (vtables :type list :reader sod-class-vtables)
1f1d88f5 90
1645e433 91 (state :initform nil :type (member nil :finalized :broken)
16f9fb72 92 :reader sod-class-state))
abdf50aa
MW
93 (:documentation
94 "Classes describe the layout and behaviour of objects.
95
1f1d88f5 96 The NAME, LOCATION, NICKNAME, DIRECT-SUPERCLASSES, CHAIN-LINK and
abdf50aa
MW
97 METACLASS slots are intended to be initialized when the class object is
98 constructed:
99
100 * The NAME is the identifier associated with the class in the user's
101 source file. It is used verbatim in the generated C code as a type
102 name, and must be distinct from other file-scope names in any source
103 file which includes the class definition. Furthermore, other names
104 are derived from the class name (most notably the class object
105 NAME__class), which have external linkage and must therefore be
106 distinct from all other identifiers in the program. It is forbidden
107 for a class NAME to begin with an underscore or to contain two
108 consecutive underscores.
109
110 * The LOCATION identifies where in the source the class was defined. It
111 gets used in error messages.
112
113 * The NICKNAME is a shorter identifier used to name the class in some
114 circumstances. The uniqueness requirements on NICKNAME are less
115 strict, which allows them to be shorter: no class may have two classes
116 with the same nickname on its class precedence list. Nicknames are
117 used (user-visibly) to distinguish slots and messages defined by
118 different classes, and (invisibly) in the derived names of direct
119 methods. It is forbidden for a nickname to begin with an underscore,
120 or to contain two consecutive underscores.
121
122 * The DIRECT-SUPERCLASSES are a list of the class's direct superclasses,
123 in the order that they were declared in the source. The class
124 precedence list is computed from the DIRECT-SUPERCLASSES lists of all
125 of the superclasses involved.
126
1f1d88f5
MW
127 * The CHAIN-LINK is either NIL or one of the DIRECT-SUPERCLASSES. Class
128 chains are a means for recovering most of the benefits of simple
129 hierarchy lost by the introduction of multiple inheritance. A class's
130 superclasses (including itself) are partitioned into chains,
131 consisting of a class, its CHAIN-LINK superclass, that class's
132 CHAIN-LINK, and so on. It is an error if two direct subclasses of any
133 class appear in the same chain (a global property which requires
134 global knowledge of an entire program's class hierarchy in order to
135 determine sensibly). Slots of superclasses in the same chain can be
136 accessed efficiently; there is an indirection needed to access slots
137 of superclasses in other chains. Furthermore, an indirection is
138 required to perform a cross-chain conversion (i.e., converting a
139 pointer to an instance of some class into a pointer to an instance of
140 one of its superclasses in a different chain), an operation which
141 occurs implicitly in effective methods in order to call direct methods
142 defined on cross-chain superclasses.
abdf50aa
MW
143
144 * The METACLASS is the class of the class object. Classes are objects
145 in their own right, and therefore must be instances of some class;
146 this class is the metaclass. Metaclasses can define additional slots
147 and methods to be provided by their instances; a class definition can
148 provide (C constant expression) initial values for the metaclass
149 instance.
150
151 The next few slots can't usually be set at object-construction time, since
152 the objects need to contain references to the class object itself.
153
154 * The SLOTS are a list of the slots defined by the class (instances of
dea4d055 155 `sod-slot'). (The class will also define all of the slots defined by
abdf50aa
MW
156 its superclasses.)
157
158 * The INSTANCE-INITIALIZERS and CLASS-INITIALIZERS are lists of
dea4d055
MW
159 initializers for slots (see `sod-initializer' and subclasses),
160 providing initial values for instances of the class, and for the
161 class's class object itself, respectively.
abdf50aa
MW
162
163 * The MESSAGES are a list of the messages recognized by the class
dea4d055 164 (instances of `sod-message' and subclasses). (Note that the message
abdf50aa
MW
165 need not have any methods defined on it. The class will also
166 recognize all of the messages defined by its superclasses.)
167
168 * The METHODS are a list of (direct) methods defined on the class
dea4d055 169 (instances of `sod-method' and subclasses). Each method provides
abdf50aa
MW
170 behaviour to be invoked by a particular message recognized by the
171 class.
172
173 Other slots are computed from these in order to describe the class's
dea4d055 174 layout and effective methods; this is done by `finalize-sod-class'.
abdf50aa 175
1f1d88f5 176 * The CLASS-PRECEDENCE-LIST is a list of superclasses in a linear order.
dea4d055
MW
177 It is computed by `compute-class-precedence-list', whose default
178 implementation ensures that the order of superclasses is such that (a)
179 subclasses appear before their superclasses; (b) the direct
180 superclasses of a given class appear in the order in which they were
181 declared by the programmer; and (c) classes always appear in the same
182 relative order in all class precedence lists in the same superclass
183 graph.
1f1d88f5
MW
184
185 * The CHAIN-HEAD is the least-specific class in the class's chain. If
186 there is no link class then the CHAIN-HEAD is the class itself. This
187 slot, like the next two, is computed by the generic function
dea4d055 188 `compute-chains'.
1f1d88f5
MW
189
190 * The CHAIN is the list of classes on the complete primary chain,
191 starting from this class and ending with the CHAIN-HEAD.
192
193 * The CHAINS are the complete collection of chains (most-to-least
194 specific) for the class and all of its superclasses.
195
dea4d055 196 Finally, slots concerning the instance and vtable layout of the class are
6e6b0958 197 computed on demand (see `define-on-demand-slot').
dea4d055 198
1f1d88f5 199 * The ILAYOUT describes the layout for an instance of the class. It's
2aa51854 200 quite complicated; see the documentation of the `ilayout' class for
1f1d88f5
MW
201 detais.
202
203 * The EFFECTIVE-METHODS are a list of effective methods, specialized for
204 the class.
205
206 * The VTABLES are a list of descriptions of vtables for the class. The
2aa51854
MW
207 individual elements are `vtable' objects, which are even more
208 complicated than `ilayout' structures. See the class documentation
209 for details."))
abdf50aa
MW
210
211(defmethod print-object ((class sod-class) stream)
1f1d88f5
MW
212 (maybe-print-unreadable-object (class stream :type t)
213 (princ (sod-class-name class) stream)))
214
215;;;--------------------------------------------------------------------------
216;;; Slots and initializers.
217
dea4d055 218(export '(sod-slot sod-slot-name sod-slot-class sod-slot-type))
1f1d88f5 219(defclass sod-slot ()
77027cca
MW
220 ((name :initarg :name :type string :reader sod-slot-name)
221 (location :initarg :location :initform (file-location nil)
222 :type file-location :reader file-location)
4b8e5c03
MW
223 (%class :initarg :class :type sod-class :reader sod-slot-class)
224 (%type :initarg :type :type c-type :reader sod-slot-type))
1f1d88f5
MW
225 (:documentation
226 "Slots are units of information storage in instances.
227
228 Each class defines a number of slots, which function similarly to (data)
229 members in structures. An instance contains all of the slots defined in
230 its class and all of its superclasses.
231
232 A slot carries the following information.
233
234 * A NAME, which distinguishes it from other slots defined by the same
235 class. Unlike most (all?) other object systems, slots defined in
236 different classes are in distinct namespaces. There are no special
237 restrictions on slot names.
238
239 * A LOCATION, which states where in the user's source the slot was
240 defined. This gets used in error messages.
241
242 * A CLASS, which states which class defined the slot. The slot is
243 available in instances of this class and all of its descendents.
244
245 * A TYPE, which is the C type of the slot. This must be an object type
246 (certainly not a function type, and it must be a complete type by the
247 time that the user header code has been scanned)."))
248
249(defmethod print-object ((slot sod-slot) stream)
250 (maybe-print-unreadable-object (slot stream :type t)
251 (pprint-c-type (sod-slot-type slot) stream
252 (format nil "~A.~A"
253 (sod-class-nickname (sod-slot-class slot))
254 (sod-slot-name slot)))))
255
dea4d055
MW
256(export '(sod-initializer sod-initializer-slot sod-initializer-class
257 sod-initializer-value-kind sod-initializer-value-form))
1f1d88f5 258(defclass sod-initializer ()
77027cca
MW
259 ((slot :initarg :slot :type sod-slot :reader sod-initializer-slot)
260 (location :initarg :location :initform (file-location nil)
261 :type file-location :reader file-location)
4b8e5c03 262 (%class :initarg :class :type sod-class :reader sod-initializer-class)
77027cca 263 (value-kind :initarg :value-kind :type keyword
1f1d88f5 264 :reader sod-initializer-value-kind)
77027cca 265 (value-form :initarg :value-form :type c-fragment
1f1d88f5
MW
266 :reader sod-initializer-value-form))
267 (:documentation
268 "Provides an initial value for a slot.
269
270 The slots of an initializer are as follows.
271
272 * The SLOT specifies which slot this initializer is meant to initialize.
273
274 * The LOCATION states the position in the user's source file where the
275 initializer was found. This gets used in error messages. (Depending
276 on the source layout style, this might differ from the location in the
277 VALUE-FORM C fragment.)
278
279 * The CLASS states which class defined this initializer. For instance
dea4d055
MW
280 slot initializers (`sod-instance-initializer'), this will be the same
281 as the SLOT's class, or be one of its descendants. For class slot
282 initializers (`sod-class-initializer'), this will be an instance of
283 the SLOT's class, or an instance of one of its descendants.
1f1d88f5
MW
284
285 * The VALUE-KIND states what manner of initializer we have. It can be
dea4d055 286 either `:single', indicating a standalone expression, or `:compound',
1f1d88f5
MW
287 indicating a compound initializer which must be surrounded by braces
288 on output.
289
290 * The VALUE-FORM gives the text of the initializer, as a C fragment.
291
292 Typically you'll see instances of subclasses of this class in the wild
dea4d055
MW
293 rather than instances of this class directly. See `sod-class-initializer'
294 and `sod-instance-initializer'."))
1f1d88f5
MW
295
296(defmethod print-object ((initializer sod-initializer) stream)
882412cf
MW
297 (with-slots (slot value-kind value-form) initializer
298 (if *print-escape*
299 (print-unreadable-object (initializer stream :type t)
300 (format stream "~A = ~A" slot value-form))
301 (format stream "~:[{~A}~;~A~]" (eq value-kind :single) value-form))))
1f1d88f5 302
dea4d055 303(export 'sod-class-initializer)
1f1d88f5
MW
304(defclass sod-class-initializer (sod-initializer)
305 ()
306 (:documentation
307 "Provides an initial value for a class slot.
308
309 A class slot initializer provides an initial value for a slot in the class
310 object (i.e., one of the slots defined by the class's metaclass). Its
311 VALUE-FORM must have the syntax of an initializer, and its consituent
312 expressions must be constant expressions.
313
dea4d055 314 See `sod-initializer' for more details."))
1f1d88f5 315
dea4d055 316(export 'sod-instance-initializer)
1f1d88f5
MW
317(defclass sod-instance-initializer (sod-initializer)
318 ()
319 (:documentation
320 "Provides an initial value for a slot in all instances.
321
322 An instance slot initializer provides an initial value for a slot in
323 instances of the class. Its VALUE-FORM must have the syntax of an
324 initializer. Furthermore, if the slot has aggregate type, then you'd
325 better be sure that your compiler supports compound literals (6.5.2.5)
326 because that's what the initializer gets turned into.
327
dea4d055 328 See `sod-initializer' for more details."))
1f1d88f5
MW
329
330;;;--------------------------------------------------------------------------
331;;; Messages and methods.
abdf50aa 332
dea4d055 333(export '(sod-message sod-message-name sod-message-class sod-message-type))
abdf50aa 334(defclass sod-message ()
77027cca
MW
335 ((name :initarg :name :type string :reader sod-message-name)
336 (location :initarg :location :initform (file-location nil)
337 :type file-location :reader file-location)
4b8e5c03
MW
338 (%class :initarg :class :type sod-class :reader sod-message-class)
339 (%type :initarg :type :type c-function-type :reader sod-message-type))
abdf50aa 340 (:documentation
bf090e02 341 "Messages are the means for stimulating an object to behave.
abdf50aa
MW
342
343 SOD is a single-dispatch object system, like Smalltalk, C++, Python and so
344 on, but unlike CLOS and Dylan. Behaviour is invoked by `sending messages'
345 to objects. A message carries a name (distinguishing it from other
346 messages recognized by the same class), and a number of arguments; the
347 object may return a value in response. Sending a message therefore looks
348 very much like calling a function; indeed, each message bears the static
349 TYPE signature of a function.
350
351 An object reacts to being sent a message by executing an `effective
352 method', constructed from the direct methods defined on the recpient's
353 (run-time, not necessarily statically-declared) class and its superclasses
354 according to the message's `method combination'.
355
dea4d055 356 Much interesting work is done by subclasses of `sod-message', which (for
abdf50aa
MW
357 example) specify method combinations.
358
359 The slots are as follows.
360
361 * The NAME distinguishes the message from others defined by the same
362 class. Unlike most (all?) other object systems, messages defined in
363 different classes are in distinct namespaces. It is forbidden for a
364 message name to begin with an underscore, or to contain two
365 consecutive underscores. (Final underscores are fine.)
366
367 * The LOCATION states where in the user's source the slot was defined.
368 It gets used in error messages.
369
370 * The CLASS states which class defined the message.
371
372 * The TYPE is a function type describing the message's arguments and
373 return type.
374
375 Subclasses can (and probably will) define additional slots."))
376
1f1d88f5
MW
377(defmethod print-object ((message sod-message) stream)
378 (maybe-print-unreadable-object (message stream :type t)
379 (pprint-c-type (sod-message-type message) stream
380 (format nil "~A.~A"
381 (sod-class-nickname (sod-message-class message))
382 (sod-message-name message)))))
383
dea4d055
MW
384(export '(sod-method sod-method-message sod-method-class sod-method-type
385 sod-method-body))
abdf50aa 386(defclass sod-method ()
77027cca
MW
387 ((message :initarg :message :type sod-message :reader sod-method-message)
388 (location :initarg :location :initform (file-location nil)
389 :type file-location :reader file-location)
4b8e5c03
MW
390 (%class :initarg :class :type sod-class :reader sod-method-class)
391 (%type :initarg :type :type c-function-type :reader sod-method-type)
77027cca 392 (body :initarg :body :type (or c-fragment null) :reader sod-method-body))
abdf50aa
MW
393 (:documentation
394 "(Direct) methods are units of behaviour.
395
396 Methods are the unit of behaviour in SOD. Classes define direct methods
397 for particular messages.
398
399 When a message is received by an instance, all of the methods defined for
400 that message on that instance's (run-time, not static) class and its
401 superclasses are `applicable'. The applicable methods are gathered
402 together and invoked in some way; the details of this are left to the
dea4d055 403 `method combination', determined by the subclass of `sod-message'.
abdf50aa
MW
404
405 The slots are as follows.
406
407 * The MESSAGE describes which meessage invokes the method's behaviour.
408 The method is combined with other methods on the same message
409 according to the message's method combination, to form an `effective
410 method'.
411
412 * The LOCATION states where, in the user's source, the method was
413 defined. This gets used in error messages. (Depending on the user's
414 coding style, this location might be subtly different from the BODY's
415 location.)
416
417 * The CLASS specifies which class defined the method. This will be
418 either the class of the message, or one of its descendents.
419
420 * The TYPE gives the type of the method, including its arguments. This
421 will, in general, differ from the type of the message for several
422 reasons.
423
bf090e02
MW
424 -- The method type must include names for all of the method's
425 parameters. The message definition can omit the parameter
426 names (in the same way as a function declaration can). Formally,
427 the message definition can contain abstract declarators, whereas
428 method definitions must not.
abdf50aa
MW
429
430 -- Method combinations may require different parameter or return
bf090e02
MW
431 types. For example, `before' and `after' methods don't
432 contribute to the message's return value, so they must be defined
433 as returning `void'.
abdf50aa
MW
434
435 -- Method combinations may permit methods whose parameter and/or
bf090e02
MW
436 return types don't exactly match the corresponding types of the
437 message. For example, one might have methods with covariant
438 return types and contravariant parameter types. (This sounds
439 nice, but it doesn't actually seem like such a clever idea when
440 you consider that the co-/contravariance must hold among all the
441 applicable methods ordered according to the class precedence
442 list. As a result, a user might have to work hard to build
443 subclasses whose CPLs match the restrictions implied by the
444 method types.)
abdf50aa
MW
445
446 Method objects are fairly passive in the SOD translator. However,
dea4d055
MW
447 subclasses of `sod-message' may (and probably will) construct instances of
448 subclasses of `sod-method' in order to carry the additional metadata they
abdf50aa
MW
449 need to keep track of."))
450
1f1d88f5
MW
451(defmethod print-object ((method sod-method) stream)
452 (maybe-print-unreadable-object (method stream :type t)
453 (format stream "~A ~@_~A"
454 (sod-method-message method)
455 (sod-method-class method))))
abdf50aa 456
abdf50aa 457;;;----- That's all, folks --------------------------------------------------