OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-binutils/] [binutils-2.19.1/] [cgen/] [cos.scm] - Blame information for rev 6

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 6 jlechner
; Cgen's Object System.
2
; Copyright (C) 2000, 2009 Red Hat, Inc.
3
; This file is part of CGEN.
4
; See file COPYING.CGEN for details.
5
;
6
; When Guile has an official object implementation that is stable, things will
7
; be switched over then.  Until such time, there's no point in getting hyper
8
; (although doing so is certainly fun, but only to a point).
9
; If the Guile team decides there won't be any official object system
10
; (which isn't unreasonable) then we'll pick the final object system then.
11
; Until such time, there are better things to do than trying to build a
12
; better object system.  If this is important enough to you, help the Guile
13
; team finish the module(/object?) system.
14
;
15
; Classes look like:
16
;
17
; #(class-tag
18
;   class-name
19
;   parent-name-list
20
;   elm-alist
21
;   method-alist
22
;   full-elm-initial-list
23
;   full-method-alist ; ??? not currently used
24
;   class-descriptor)
25
;
26
; PARENT-NAME-LIST is a list of the names of parent classes (the inheritance
27
; tree).
28
;
29
; ELM-ALIST is an alist of (symbol private? vector-index . initial-value)
30
; for this class only.
31
; Values can be looked up by name, via elm-make-[gs]etter routines, or
32
; methods can use elm-get/set! for speed.
33
; Various Lisp (or Lisp-like) OOP systems (e.g. CLOS, Dylan) call these
34
; "slots".  Maybe for consistency "slot" would be a better name.  Some might
35
; confuse that with intentions at directions.  Given that something better
36
; will eventually happen, being deliberately different is useful.
37
;
38
; METHOD-ALIST is an alist of (symbol . (virtual? . procedure)) for this
39
; class only.
40
;
41
; FULL-ELM-INITIAL-LIST is the elements of the flattened inheritance tree.
42
; Initially it is #f meaning it hasn't been computed yet.
43
; It is computed when the class is first instantiated.  During development,
44
; it can be reset to #f after some module has been reloaded (requires all
45
; object instantiation happens later of course).
46
;
47
; FULL-METHOD-ALIST is an alist of the methods of the flattened inheritance
48
; tree.  Each element is (symbol . (parent-list-entry . method)).
49
; Initially it is #f meaning it hasn't been computed yet.
50
; It is computed when the class is first instantiated.  During development,
51
; it can be reset to #f after some module has been reloaded (requires all
52
; object instantiation happens later of course).
53
;
54
; CLASS-DESCRIPTOR is the processed form of parent-name-list.
55
; There is an entry for the class and one for each parent (recursively):
56
; (class mi? (base-offset . delta) child-backpointer (parent1-entry) ...).
57
; mi? is #t if the class or any parent class has multiple inheritance.
58
; This is used by the element access routines.
59
; base-offset is the offset in the element vector of the baseclass (or first
60
; baseclass in the mi case).
61
; delta is the offset from base-offset of the class's own elements
62
; (as opposed to elements in any parent class).
63
; child-backpointer is #f in the top level object.
64
; ??? child->subclass, parent->superclass?
65
; Initially the class-descriptor is #f meaning it hasn't been computed yet.
66
; It is computed when the class is first instantiated.  During development,
67
; it can be reset to #f after some module has been reloaded (requires all
68
; object instantiation to happen later of course).
69
;
70
; An object is a vector of 2 elements: #(object-elements class-descriptor).
71
; ??? Things would be simpler if objects were a pair but that makes eval'ing
72
; them trickier.  Vectors are nice in that they're self-evaluating, though
73
; due to the self-referencing, which Guile 1.2 can't handle, apps have to
74
; be careful.
75
; ??? We could use smobs/records/whatever but the difference isn't big enough
76
; for me to care at this point in time.
77
;
78
; `object-elements' looks like:
79
;
80
; #(object-tag
81
;   class
82
;   element1
83
;   element2
84
;   ...)
85
;
86
; CLASS is the class the object is an instance of.
87
;
88
; User visible procs:
89
;
90
; (class-make name parents elements methods) -> class
91
;
92
; Create a class.  The result is then passed back by procedures requiring
93
; a class argument.  Note however that PARENTS is a list of class names,
94
; not the class data type.  This allows reloading the definition of a
95
; parent class without having to reload any subclasses.  To implement this
96
; classes are recorded internally, and `object-init!' must be called if any
97
; class has been redefined.
98
;
99
; (class-list) -> list of all defined classes
100
;
101
; (class-name class) -> name of CLASS
102
;
103
; (class-lookup class-name) -> class
104
;
105
; (class-instance? class object) -> #t if OBJECT is an instance of CLASS
106
;
107
; (object-class object) -> class of OBJECT
108
;
109
; (object-class-name object) -> class name of OBJECT
110
;
111
; (send object method-name . args) -> result of invoking METHOD-NAME
112
;
113
; (send-next object method-name . args) -> result of invoking next METHOD-NAME
114
;
115
; (new class) -> instantiate CLASS
116
;
117
; The object is initialized with values specified when CLASS
118
; (and its parent classes) was defined.
119
;
120
; (vmake class . args) -> instantiate class and initialize it with 'vmake!
121
;
122
; This is shorthand for (send (new class) 'vmake! args).
123
; ARGS is a list of option names and arguments (a la CLOS).
124
; ??? Not implemented yet.
125
;
126
; (method-vmake! object . args) -> modify OBJECT from ARGS
127
;
128
; This is the standard 'vmake! method, available for use by user-written
129
; 'vmake! methods.
130
; ??? Not implemented yet.
131
;
132
; (make class . args) -> instantiate CLASS and initialize it with 'make!
133
;
134
; This is shorthand for (send (new class) 'make! arg1 ...).
135
; This is a positional form of `new'.
136
;
137
; (method-make-make! class elm1-name elm2-name ...) -> unspecified
138
;
139
; Create a 'make! method that sets the specified elements.
140
;
141
; (object-copy object) -> copy of OBJ
142
;
143
; ??? Whether to discard the parent or keep it and retain specialization
144
; is undecided.
145
;
146
; (object-copy-top object) -> copy of OBJECT with spec'n discarded
147
;
148
; (object-parent object parent-path) -> parent object in OBJECT via PARENT-PATH
149
;
150
; (class? foo) -> return #t if FOO is a class
151
;
152
; (object? foo) -> return #t if FOO is an object
153
;
154
; (method-make! class name lambda) -> unspecified
155
;
156
; Add method NAME to CLASS.
157
;
158
; (method-make-virtual! class name lambda) -> unspecified
159
;
160
; Add virtual method NAME to CLASS.
161
;
162
; (method-make-forward! class elm-name methods) -> unspecified
163
;
164
; Add METHODS to CLASS that pass the "message" onto the object in element
165
; ELM-NAME.
166
;
167
; (method-make-virtual-forward! class elm-name methods) -> unspecified
168
;
169
; Add virtual METHODS to CLASS that pass the "message" onto the object in
170
; element ELM-NAME.
171
;
172
; (elm-get object elm-name) -> value of element ELM-NAME in OBJ
173
;
174
; Can only be used in methods.
175
;
176
; (elm-set! object elm-name new-value) -> unspecified
177
;
178
; Set element ELM-NAME in OBJECT to NEW-VALUE.
179
; Can only be used in methods.
180
;
181
; (elm-make-getter class elm-name) -> lambda
182
;
183
; Return lambda to get the value of ELM-NAME in CLASS.
184
;
185
; (elm-make-setter class elm-name) -> lambda
186
;
187
; Return lambda to set the value of ELM-NAME in CLASS.
188
;
189
; Conventions used in this file:
190
; - procs/vars internal to this file are prefixed with "-"
191
;   [Of course this could all be put in a module; later if ever since
192
;   once Guile has its own official object system we'll convert.  Note that
193
;   it currently does not.]
194
; - except for a few exceptions, public procs begin with one of
195
;   class-, object-, elm-, method-.
196
;   The exceptions are make, new, parent, send.
197
 
198
; ??? Were written as a procedures for Hobbit's sake (I think).
199
; Associative list of classes to be traced.
200
 
201
; Associative list of messages to be traced.
202
 
203
; Cover fn to set verbosity.
204
 
205
"not a class""not an object"; X is any arbitrary Scheme data.
206
": "" (class: "", name: """")"""""; Low level class operations.
207
; Return boolean indicating if X is a class.
208
 
209
; Make a class.
210
 
211
; Lookup a class given its name.
212
 
213
; Return a list of all direct parent classes of CLASS.
214
 
215
; The proc name we pass here is made up as we don't
216
 
217
"class""not a class"; Cover proc of -class-name for the outside world to use.
218
 
219
; We could issue an error here, but to be consistent with object-class-name
220
 
221
; Return a boolean indicating if CLASS or any parent class has
222
 
223
; Class descriptor utilities.
224
 
225
; (class mi? (base-offset . delta) child-backpointer (parent1-entry) ...)
226
 
227
;   (append (list class offset bkptr) parents)
228
;)
229
; Note that this is an assq on the classes themselves, not their names.
230
 
231
; Compute the class descriptor of CLASS.
232
 
233
; We can assume the parents of CLASS have already been initialized.
234
;
235
; A class-descriptor is:
236
; (class mi? (base-offset . delta) child-backpointer (parent1-entry) ...)
237
; MI? is a boolean indicating if multiple inheritance is present.
238
; BASE-OFFSET is the offset into the object vector of the baseclass's elements
239
; (or first baseclass in the mi case).
240
; DELTA is the offset from BASE-OFFSET of the class's own elements.
241
; CHILD is the backlink to the direct child class or #f for the top class.
242
; ??? Is the use of `top' backwards from traditional usage?
243
; OFFSET must be global to the calculation because it is continually
244
; incremented as we recurse down through the hierarchy (actually, as we
245
; traverse back up).  At any point in time it is the offset from the start
246
; of the element vector of the next class's elements.
247
; Object elements are laid out using a depth first traversal of the
248
; inheritance tree.
249
; Build the result first, then build our parents so that our parents have
250
; the right value for the CHILD-BACKPOINTER field.
251
; Use a bogus value for mi? and offset for the moment.
252
; The correct values are set later.
253
 
254
; We use `append!' here as the location of `result' is now fixed so
255
; that our parent's child-backpointer remains stable.
256
; The proc name we pass here is made up as we don't
257
; want it to be the name of an internal proc.
258
"class""not a class"; Return the top level class-descriptor of CLASS-DESC.
259
; Pretty print a class descriptor.
260
"Class: ""  mi?:         ""  base offset: ""  delta:       ""  child:       ""-top-""Top level class: "; Low level object utilities.
261
; Make an object.
262
; All elements get initial (or unbound) values.
263
; Make an object using VALUES.
264
; VALUES must specify all elements in the class (and parent classes).
265
; Copy an object.
266
; If TOP?, the copy is of the top level object with any specialization
267
; discarded.
268
; WARNING: A shallow copy is currently done on the elements!
269
 
270
; The result is the same object, but with a different view (confined to
271
 
272
; Accessors.
273
 
274
; Return boolean indicating if X is an object.
275
; Return the class of an object.
276
"object-class"; Cover proc of -object-class-name for the outside world to use.
277
 
278
; Class operations.
279
 
280
; The result does not include parent classes.
281
; Initialize class if not already done.
282
; FIXME: Need circularity check.  Later.
283
; This should be fast the second time through, so don't do any
284
; computation until we know it's necessary.
285
; First pass ensures all parents are initialized.
286
; Next pass initializes the initial value list.
287
 
288
; Object elements begin at offset 2 in the element vector.
289
; Make a class.
290
;
291
 
292
; exist yet, though they must exist when the class is first instantiated.
293
; ELMS is a either a list of either element names or name/value pairs.
294
; Elements without initial values are marked as "unbound".
295
 
296
; method-make!.
297
; Mark elements without initial values as unbound, and
298
; compute indices into the element vector (relative to the class's
299
 
300
; Elements are recorded as (symbol initial-value private? . vector-index)
301
; FIXME: For now all elements are marked as "public".
302
; done
303
 
304
; The caller can override afterwards if desired.
305
; Note that if there are any parent classes then we don't know the names
306
; of all of the elements yet, that is only known after the class has been
307
 
308
; This method won't be called until that happens though so we're safe.
309
; This is written without knowledge of the names, it just initializes
310
; all elements.
311
 
312
"make!""""wrong number of arguments to method `make!'"; Create an object of a class CLASS.
313
"new""Instantiating class "".\n"; Make a copy of OBJ.
314
 
315
"object-copy"; Make a copy of OBJ.
316
; This makes a copy of top level object, with any specialization discarded.
317
; WARNING: A shallow copy is done on the elements!
318
"object-copy-top"; Utility to define a standard `make!' method.
319
; A standard make! method is one in which all it does is initialize
320
; fields from args.
321
; The "standard" way to invoke `make!' is (send (new class) 'make! ...).
322
; This puts all that in a cover function.
323
 
324
; Return #t if OBJECT is an instance of CLASS.
325
; This does not signal an error if OBJECT is not an object as this is
326
 
327
"class-instance?"; Element operations.
328
 
329
; The result is (class-desc . (private? . elm-offset)) or #f if not found.
330
 
331
; is restricted to this section of the source.
332
; Given the result of -class-lookup-element, return the element's delta
333
; from base-offset.
334
; Return a boolean indicating if ELM is bound in OBJ.
335
"elm-bound?"; Subroutine of elm-get.
336
"elm-get""elm-get""element not present: "; Get an element from an object.
337
; If OBJ is `self' then the caller is required to be a method and we emit
338
; memoized code.  Otherwise we do things the slow way.
339
; ??? There must be a better way.
340
; What this does is turn
341
; (elm-get self 'foo)
342
; into
343
; ((-elm-make-method-get self 'foo) self)
344
 
345
; foo and returns a memoizing macro that returns the code to perform the
346
; operation with O(1).  Cute, but I'm hoping there's an easier/better way.
347
; Subroutine of elm-set!.
348
"elm-set!""elm-set!""element not present: "; Set an element in an object.
349
 
350
; See the comments for `elm-get'!
351
; Get an element from an object.
352
; This is for invoking from outside a method, and without having to
353
; use elm-make-getter.  It should be used sparingly.
354
"elm-xget"; FIXME: check private?
355
 
356
; This is for invoking from outside a method, and without having to
357
; use elm-make-setter.  It should be used sparingly.
358
 
359
"elm-xset!""element not present: "; Return a boolean indicating if object OBJ has element NAME.
360
"elm-present?"; Return lambda to get element NAME in CLASS.
361
; FIXME: validate name.
362
 
363
; initialized yet.
364
; ??? Should be able to use fast-index in mi case.
365
; ??? Need to involve CLASS in lookup.
366
 
367
; FIXME: validate name.
368
"elm-make-setter"; We use delay here as we can't assume parent classes have been
369
; initialized yet.
370
; ??? Should be able to use fast-index in mi case.
371
; ??? Need to involve CLASS in lookup.
372
; Return a list of all elements in OBJ.
373
; Method operations.
374
; Lookup the next method in a class.
375
; This means begin the search in the parents.
376
; ??? What should this do for virtual methods.  At present we treat them as
377
; non-virtual.
378
; Lookup a method in a class.
379
; The result is (class-desc . method).  If the method is found in a parent
380
; class, the associated parent class descriptor is returned.  If the method is
381
; a virtual method, the appropriate subclass's class descriptor is returned.
382
; VIRTUAL? is #t if virtual methods are to be treated as such.
383
; Otherwise they're treated as normal methods.
384
 
385
; FIXME: We don't yet implement the method cache.
386
"Looking up method "" in "".\n"; virtual?
387
; Traverse back up the inheritance chain looking for overriding
388
; methods.  The closest one to the top is the one to use.
389
"Looking up virtual method "" in "".\n"; Method found, update goal object and method.
390
; Method not found at this level.
391
; Went all the way up to the top.
392
; Non-virtual, done.
393
; Method not found, search parents.
394
; Return a boolean indicating if object OBJ has method NAME.
395
"method-present?"; Return method NAME of CLASS or #f if not present.
396
; ??? Assumes CLASS has been initialized.
397
 
398
; FIXME: ensure method-name is a symbol
399
 
400
; FIXME: ensure method-name is a symbol
401
"method-make-virtual!""method-make-virtual!""method must be a procedure"; Utility to create "forwarding" methods.
402
; METHODS are forwarded to class member ELM-NAME, assumed to be an object.
403
; The created methods take a variable number of arguments.
404
; Argument length checking will be done by the receiving method.
405
; FIXME: ensure elm-name is a symbol
406
 
407
; FIXME: ensure elm-name is a symbol
408
 
409
"Sending "" to"" object """""" class "".\n"; Invoke a method in an object.
410
; When the method is invoked, the (possible parent class) object in which the
411
; method is found is passed to the method.
412
; ??? The word `send' comes from "sending messages".  Perhaps should pick
413
 
414
"send""send""not a method name""""send""method not supported: "; Invoke the next method named METHOD-NAME in the heirarchy of OBJ.
415
; i.e. the method that would have been invoked if the calling method
416
 
417
; This may only be called by a method.
418
; ??? Ideally we shouldn't need the METHOD-NAME argument.  It could be
419
; removed with a bit of effort, but is it worth it?
420
 
421
; Subroutine of `parent' to lookup a (potentially nested) parent class.
422
; The result is the parent's class-descriptor or #f if not found.
423
; Subroutine of `parent' to lookup a parent via a path.
424
; PARENT-PATH, a list, is the exact path to the parent class.
425
; The result is the parent's class-descriptor or #f if not found.
426
; For completeness' sake, if PARENT-PATH is empty, CLASS-DESC is returned.
427
; Lookup a parent class of object OBJ.
428
; CLASS is either a class or a list of classes.
429
; If CLASS is a list, it is a (possibly empty) "path" to the parent.
430
; Otherwise it is any parent and is searched for breadth-first.
431
; ??? Methinks this should be depth-first.
432
; The result is OBJ, specialized to the found parent.
433
"object-parent""object-parent""object-parent""invalid parent path"; Hobbit generates C code that passes the function
434
; -class-parent-via-path or -class-parent, not the appropriate
435
; SCM object.
436
; (let ((result ((if (or (null? class) (pair? class))
437
;                    -class-parent-via-path
438
;                    -class-parent)
439
 
440
; So it's rewritten like this.
441
"object-parent""parent not present"; FIXME: should print path in error message.
442
; Make PARENT-NAME a parent of CLASS, cons'd unto the front of the search
443
; order.  This is used to add a parent class to a class after it has already
444
 
445
; The parent is added to the front of the current parent list (affects
446
; method lookup).
447
 
448
; This is used to add a parent class to a class after it has already been
449
 
450
; The parent is added to the end of the current parent list (affects
451
; method lookup).
452
"class-append-parent!""class-append-parent!""not a class name"; Miscellaneous publically accessible utilities.
453
; Reset the object system (delete all classes).
454
; Call once to initialize the object system.
455
 
456
; instantiated.  This usually happens during development only.
457
 
458
; Utility to map over a class and all its parent classes, recursively.
459
; Return class tree of a class or object.
460
"class-tree""not a class or object"; Return names of each alist.
461
; Return complete layout of class-or-object.
462
"class-layout""not a class or object"; Like assq but based on the `name' element.
463
; WARNING: Slow.
464
; Like memq but based on the `name' element.
465
; WARNING: Slow.
466
; Misc. internal utilities.
467
; We need a fast vector copy operation.
468
; If `vector-copy' doesn't exist (which is assumed to be the fast one),
469
; provide a simple version.
470
; FIXME: Need deep copier instead.
471
; Profiling support
472
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.