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