10 hereby transferred. |
10 hereby transferred. |
11 " |
11 " |
12 "{ Package: 'stx:libcomp' }" |
12 "{ Package: 'stx:libcomp' }" |
13 |
13 |
14 Object subclass:#Structure |
14 Object subclass:#Structure |
15 instanceVariableNames:'superclass flags methodDictionary instSize i1 i2 i3 i4 i5 i6 i7 |
15 instanceVariableNames:'superclass flags methodDictionary lookupFunction instSize i1 i2 i3 i4 i5 i6 i7 |
16 i8 i9 i10 i11 i12 i13 i14 i15 i16 i17 i18 i19 i20 i21 i22 i23 i24 |
16 i8 i9 i10 i11 i12 i13 i14 i15 i16 i17 i18 i19 i20 i21 i22 i23 i24 |
17 i25 i26 i27 i28 i29 i30 i31 i32 i33 i34 i35 i36 i37 i38 i39 i40 |
17 i25 i26 i27 i28 i29 i30 i31 i32 i33 i34 i35 i36 i37 i38 i39 i40 |
18 i41 i42 i43 i44 i45 i46 i47 i48 i49 i50' |
18 i41 i42 i43 i44 i45 i46 i47 i48 i49 i50' |
19 classVariableNames:'OneInstance DummyClass ReadAccessMethods WriteAccessMethods |
19 classVariableNames:'OneInstance DummyClass ReadAccessMethods WriteAccessMethods |
20 OtherMethods OtherSelectors' |
20 OtherMethods OtherSelectors' |
21 poolDictionaries:'' |
21 poolDictionaries:'' |
22 category:'Programming-Support' |
22 category:'Programming-Support' |
23 ! |
23 ! |
24 |
24 |
25 !Structure class methodsFor:'documentation'! |
25 !Structure class methodsFor:'documentation'! |
26 |
26 |
27 copyright |
27 copyright |
60 retVal foo |
60 retVal foo |
61 retVal bar |
61 retVal bar |
62 |
62 |
63 Implementation note: |
63 Implementation note: |
64 this is a very tricky (but fully legal) implementation, |
64 this is a very tricky (but fully legal) implementation, |
65 creating an object which is its own class. |
65 creating an object which is its own class. |
66 Therefore, no additional overhead by extra (class) objects is involved. |
66 Therefore, no additional overhead by extra (class) objects is involved. |
67 These are very lightweight objects. |
67 These are very lightweight objects. |
68 |
68 |
69 Another prove that smalltalk is a powerful & flexible programming language. |
69 Another prove that smalltalk is a powerful & flexible programming language. |
70 However, some smalltalk systems crash if your try this ;-) |
70 However, some smalltalk systems crash if your try this ;-) |
120 |
120 |
121 !Structure class methodsFor:'initialization'! |
121 !Structure class methodsFor:'initialization'! |
122 |
122 |
123 initialize |
123 initialize |
124 OneInstance isNil ifTrue:[ |
124 OneInstance isNil ifTrue:[ |
125 Behavior instSize ~~ 4 ifTrue:[ |
125 "/ check if the first few instvars correspond to Behavior's definition: |
126 self halt:'must change definition of this class'. |
126 |
|
127 (Behavior instSize + 1) == (self instanceVariableNames indexOf:#i1) ifFalse:[ |
|
128 self halt:'you must change the definition of this class (instvars before i1 must match behavior''s)'. |
127 ]. |
129 ]. |
128 |
130 |
129 OneInstance := self basicNew. |
131 OneInstance := self basicNew. |
130 |
132 |
131 DummyClass := Behavior shallowCopy. |
133 DummyClass := Behavior shallowCopy. |
132 DummyClass flags:(Behavior flagBehavior bitOr:Behavior flagPointers). |
134 DummyClass flags:(Behavior flagBehavior bitOr:Behavior flagPointers). |
133 DummyClass setName:#DummyClass. |
135 DummyClass setName:#DummyClass. |
134 |
136 |
135 ReadAccessMethods := (1 to:50) |
137 ReadAccessMethods := (1 to:50) |
136 collect:[:i | |m| |
138 collect:[:i | |m| |
137 m := self compiledMethodAt:('i', i printString) asSymbol. |
139 m := self compiledMethodAt:('i', i printString) asSymbol. |
138 (m notNil and:[m isLazyMethod]) ifTrue:[m makeRealMethod]. |
140 (m notNil and:[m isLazyMethod]) ifTrue:[m makeRealMethod]. |
139 m |
141 m |
140 ]. |
142 ]. |
141 WriteAccessMethods := (1 to:50) |
143 WriteAccessMethods := (1 to:50) |
142 collect:[:i | |m| |
144 collect:[:i | |m| |
143 m := self compiledMethodAt:('i', i printString , ':') asSymbol. |
145 m := self compiledMethodAt:('i', i printString , ':') asSymbol. |
144 (m notNil and:[m isLazyMethod]) ifTrue:[m makeRealMethod]. |
146 (m notNil and:[m isLazyMethod]) ifTrue:[m makeRealMethod]. |
145 m |
147 m |
146 ]. |
148 ]. |
147 |
149 |
148 OtherMethods := OrderedCollection new. |
150 OtherMethods := OrderedCollection new. |
149 OtherMethods |
151 OtherMethods |
150 add:(self compiledMethodAt:#doesNotUnderstand:); |
152 add:(self compiledMethodAt:#doesNotUnderstand:); |
151 add:(Object compiledMethodAt:#class); |
153 add:(Object compiledMethodAt:#class); |
152 add:(Object compiledMethodAt:#identityHash); |
154 add:(Object compiledMethodAt:#identityHash); |
153 add:(Object compiledMethodAt:#at:); |
155 add:(Object compiledMethodAt:#at:); |
154 add:(Object compiledMethodAt:#at:put:); |
156 add:(Object compiledMethodAt:#at:put:); |
164 add:(Object compiledMethodAt:#perform:); |
166 add:(Object compiledMethodAt:#perform:); |
165 add:(Object compiledMethodAt:#perform:with:); |
167 add:(Object compiledMethodAt:#perform:with:); |
166 add:(Object compiledMethodAt:#isBoolean). |
168 add:(Object compiledMethodAt:#isBoolean). |
167 OtherMethods := OtherMethods asArray. |
169 OtherMethods := OtherMethods asArray. |
168 |
170 |
169 OtherSelectors := #(#doesNotUnderstand: |
171 OtherSelectors := #(#doesNotUnderstand: |
170 #class #identityHash |
172 #class #identityHash |
171 #at: #at:put: #basicAt: #basicAt:put: |
173 #at: #at:put: #basicAt: #basicAt:put: |
172 #printString #printOn: #basicPrintOn: |
174 #printString #printOn: #basicPrintOn: |
173 #addDependent: #removeDependent: #dependents #dependents: |
175 #addDependent: #removeDependent: #dependents #dependents: |
174 #perform: #perform:with: |
176 #perform: #perform:with: |
175 #isBoolean). |
177 #isBoolean). |
176 ]. |
178 ]. |
210 |
212 |
211 sels := names collect:[:nm | nm asSymbol]. |
213 sels := names collect:[:nm | nm asSymbol]. |
212 sels := sels , (names collect:[:nm | (nm , ':') asSymbol]). |
214 sels := sels , (names collect:[:nm | (nm , ':') asSymbol]). |
213 sels := sels , OtherSelectors. |
215 sels := sels , OtherSelectors. |
214 |
216 |
215 mthds := ReadAccessMethods copyTo:nInsts. |
217 mthds := ReadAccessMethods copyTo:nInsts. |
216 mthds := mthds , (WriteAccessMethods copyTo:nInsts). |
218 mthds := mthds , (WriteAccessMethods copyTo:nInsts). |
217 mthds := mthds , OtherMethods. |
219 mthds := mthds , OtherMethods. |
218 |
220 |
219 "/ create a prototype object as an array ... |
221 "/ create a prototype object as an array ... |
220 "/ the object will be its own class, and have the indexable flag bit set; |
222 "/ the object will be its own class, and have the indexable flag bit set; |
224 |
226 |
225 arr := Array new:(behviorsInstSize + nInsts). |
227 arr := Array new:(behviorsInstSize + nInsts). |
226 arr at:1 put:nil. "/ superclass |
228 arr at:1 put:nil. "/ superclass |
227 arr at:2 put:(Behavior flagBehavior bitOr:Behavior flagPointers). "/ flags |
229 arr at:2 put:(Behavior flagBehavior bitOr:Behavior flagPointers). "/ flags |
228 arr at:3 put:(MethodDictionary withKeys:sels andValues:mthds). "/ selectors & methods |
230 arr at:3 put:(MethodDictionary withKeys:sels andValues:mthds). "/ selectors & methods |
229 arr at:4 put:behviorsInstSize. "/ instSize |
231 arr at:4 put:behviorsInstSize. "/ instSize |
230 |
232 |
231 "/ now, the big trick ... |
233 "/ now, the big trick ... |
232 |
234 |
233 arr changeClassTo:DummyClass. |
235 arr changeClassTo:DummyClass. |
234 arr changeClassTo:arr. |
236 arr changeClassTo:arr. |
262 |
264 |
263 with:assoc1 with:assoc2 |
265 with:assoc1 with:assoc2 |
264 "return a new structure with two fields, named as defined by the arguments' |
266 "return a new structure with two fields, named as defined by the arguments' |
265 keys, and and initialized with the assocs' values." |
267 keys, and and initialized with the assocs' values." |
266 |
268 |
267 ^ self newWith:(Array with:assoc1 key with:assoc2 key) |
269 ^ self newWith:(Array with:assoc1 key with:assoc2 key) |
268 values:(Array with:assoc1 value with:assoc2 value) |
270 values:(Array with:assoc1 value with:assoc2 value) |
269 |
271 |
270 " |
272 " |
271 Structure with:#foo->'foo' with:#bar->'bar' |
273 Structure with:#foo->'foo' with:#bar->'bar' |
272 " |
274 " |
274 |
276 |
275 with:assoc1 with:assoc2 with:assoc3 |
277 with:assoc1 with:assoc2 with:assoc3 |
276 "return a new structure with three fields, named as defined by the arguments' |
278 "return a new structure with three fields, named as defined by the arguments' |
277 keys, and and initialized with the assocs' values." |
279 keys, and and initialized with the assocs' values." |
278 |
280 |
279 ^ self newWith:(Array with:assoc1 key with:assoc2 key with:assoc3 key) |
281 ^ self newWith:(Array with:assoc1 key with:assoc2 key with:assoc3 key) |
280 values:(Array with:assoc1 value with:assoc2 value with:assoc3 value) |
282 values:(Array with:assoc1 value with:assoc2 value with:assoc3 value) |
281 |
283 |
282 " |
284 " |
283 Structure with:#foo->'foo' with:#bar->'bar' with:#baz->'baz' |
285 Structure with:#foo->'foo' with:#bar->'bar' with:#baz->'baz' |
284 " |
286 " |
286 |
288 |
287 with:assoc1 with:assoc2 with:assoc3 with:assoc4 |
289 with:assoc1 with:assoc2 with:assoc3 with:assoc4 |
288 "return a new structure with four fields, named as defined by the arguments' |
290 "return a new structure with four fields, named as defined by the arguments' |
289 keys, and and initialized with the assocs' values." |
291 keys, and and initialized with the assocs' values." |
290 |
292 |
291 ^ self newWith:(Array with:assoc1 key with:assoc2 key |
293 ^ self newWith:(Array with:assoc1 key with:assoc2 key |
292 with:assoc3 key with:assoc4 key) |
294 with:assoc3 key with:assoc4 key) |
293 values:(Array with:assoc1 value with:assoc2 value |
295 values:(Array with:assoc1 value with:assoc2 value |
294 with:assoc3 value with:assoc4 value) |
296 with:assoc3 value with:assoc4 value) |
295 |
297 |
296 " |
298 " |
297 Structure with:#foo->'foo' with:#bar->'bar' with:#baz->'baz' with:#hello->'hello' |
299 Structure with:#foo->'foo' with:#bar->'bar' with:#baz->'baz' with:#hello->'hello' |
298 " |
300 " |
300 |
302 |
301 with:assoc1 with:assoc2 with:assoc3 with:assoc4 with:assoc5 |
303 with:assoc1 with:assoc2 with:assoc3 with:assoc4 with:assoc5 |
302 "return a new structure with five fields, named as defined by the arguments' |
304 "return a new structure with five fields, named as defined by the arguments' |
303 keys, and and initialized with the assocs' values." |
305 keys, and and initialized with the assocs' values." |
304 |
306 |
305 ^ self newWith:(Array with:assoc1 key with:assoc2 key |
307 ^ self newWith:(Array with:assoc1 key with:assoc2 key |
306 with:assoc3 key with:assoc4 key |
308 with:assoc3 key with:assoc4 key |
307 with:assoc5 key) |
309 with:assoc5 key) |
308 values:(Array with:assoc1 value with:assoc2 value |
310 values:(Array with:assoc1 value with:assoc2 value |
309 with:assoc3 value with:assoc4 value |
311 with:assoc3 value with:assoc4 value |
310 with:assoc5 value) |
312 with:assoc5 value) |
311 |
313 |
312 " |
314 " |
313 Structure with:#foo->'foo' with:#bar->'bar' with:#baz->'baz' with:#hello->'hello' with:#world->'world' |
315 Structure with:#foo->'foo' with:#bar->'bar' with:#baz->'baz' with:#hello->'hello' with:#world->'world' |
314 " |
316 " |
316 |
318 |
317 with:assoc1 with:assoc2 with:assoc3 with:assoc4 with:assoc5 with:assoc6 |
319 with:assoc1 with:assoc2 with:assoc3 with:assoc4 with:assoc5 with:assoc6 |
318 "return a new structure with five fields, named as defined by the arguments' |
320 "return a new structure with five fields, named as defined by the arguments' |
319 keys, and and initialized with the assocs' values." |
321 keys, and and initialized with the assocs' values." |
320 |
322 |
321 ^ self newWith:(Array with:assoc1 key with:assoc2 key |
323 ^ self newWith:(Array with:assoc1 key with:assoc2 key |
322 with:assoc3 key with:assoc4 key |
324 with:assoc3 key with:assoc4 key |
323 with:assoc5 key with:assoc6 key) |
325 with:assoc5 key with:assoc6 key) |
324 values:(Array with:assoc1 value with:assoc2 value |
326 values:(Array with:assoc1 value with:assoc2 value |
325 with:assoc3 value with:assoc4 value |
327 with:assoc3 value with:assoc4 value |
326 with:assoc5 value with:assoc6 value) |
328 with:assoc5 value with:assoc6 value) |
327 |
329 |
328 " |
330 " |
329 Structure with:#foo->'foo' with:#bar->'bar' with:#baz->'baz' with:#hello->'hello' with:#world->'world' |
331 Structure with:#foo->'foo' with:#bar->'bar' with:#baz->'baz' with:#hello->'hello' with:#world->'world' |
330 " |
332 " |
332 |
334 |
333 with:assoc1 with:assoc2 with:assoc3 with:assoc4 with:assoc5 with:assoc6 with:assoc7 |
335 with:assoc1 with:assoc2 with:assoc3 with:assoc4 with:assoc5 with:assoc6 with:assoc7 |
334 "return a new structure with five fields, named as defined by the arguments' |
336 "return a new structure with five fields, named as defined by the arguments' |
335 keys, and and initialized with the assocs' values." |
337 keys, and and initialized with the assocs' values." |
336 |
338 |
337 ^ self newWith:(Array with:assoc1 key with:assoc2 key |
339 ^ self newWith:(Array with:assoc1 key with:assoc2 key |
338 with:assoc3 key with:assoc4 key |
340 with:assoc3 key with:assoc4 key |
339 with:assoc5 key with:assoc6 key |
341 with:assoc5 key with:assoc6 key |
340 with:assoc7 key) |
342 with:assoc7 key) |
341 values:(Array with:assoc1 value with:assoc2 value |
343 values:(Array with:assoc1 value with:assoc2 value |
342 with:assoc3 value with:assoc4 value |
344 with:assoc3 value with:assoc4 value |
343 with:assoc5 value with:assoc6 value |
345 with:assoc5 value with:assoc6 value |
344 with:assoc7 value) |
346 with:assoc7 value) |
345 |
347 |
346 " |
348 " |
347 Structure with:#foo->'foo' with:#bar->'bar' with:#baz->'baz' with:#hello->'hello' with:#world->'world' |
349 Structure with:#foo->'foo' with:#bar->'bar' with:#baz->'baz' with:#hello->'hello' with:#world->'world' |
1431 ! ! |
1433 ! ! |
1432 |
1434 |
1433 !Structure class methodsFor:'documentation'! |
1435 !Structure class methodsFor:'documentation'! |
1434 |
1436 |
1435 version |
1437 version |
1436 ^ '$Header: /cvs/stx/stx/libcomp/Structure.st,v 1.23 2009-10-08 14:01:57 mb Exp $' |
1438 ^ '$Header: /cvs/stx/stx/libcomp/Structure.st,v 1.24 2010-04-07 14:53:33 cg Exp $' |
1437 ! |
1439 ! |
1438 |
1440 |
1439 version_CVS |
1441 version_CVS |
1440 ^ '$Header: /cvs/stx/stx/libcomp/Structure.st,v 1.23 2009-10-08 14:01:57 mb Exp $' |
1442 ^ '$Header: /cvs/stx/stx/libcomp/Structure.st,v 1.24 2010-04-07 14:53:33 cg Exp $' |
1441 ! ! |
1443 ! ! |
1442 |
1444 |
1443 Structure initialize! |
1445 Structure initialize! |