Deleted Added
full compact
oo.fr (76116) oo.fr (94290)
1\ #if FICL_WANT_OOP
2\ ** ficl/softwords/oo.fr
3\ ** F I C L O - O E X T E N S I O N S
4\ ** john sadler aug 1998
5\
1\ #if FICL_WANT_OOP
2\ ** ficl/softwords/oo.fr
3\ ** F I C L O - O E X T E N S I O N S
4\ ** john sadler aug 1998
5\
6\ $FreeBSD: head/sys/boot/ficl/softwords/oo.fr 76116 2001-04-29 02:36:36Z dcs $
6\ $FreeBSD: head/sys/boot/ficl/softwords/oo.fr 94290 2002-04-09 17:45:28Z dcs $
7
817 ficl-vocabulary oop
9also oop definitions
10
11\ Design goals:
12\ 0. Traditional OOP: late binding by default for safety.
13\ Early binding if you ask for it.
14\ 1. Single inheritance

--- 10 unchanged lines hidden (view full) ---

25\ Classes are objects, too: all classes are instances of METACLASS
26\ All classes are derived (by convention) from OBJECT. This
27\ base class provides a default initializer and superclass
28\ access method
29
30\ A ficl object binds instance storage (payload) to a class.
31\ object ( -- instance class )
32\ All objects push their payload address and class address when
7
817 ficl-vocabulary oop
9also oop definitions
10
11\ Design goals:
12\ 0. Traditional OOP: late binding by default for safety.
13\ Early binding if you ask for it.
14\ 1. Single inheritance

--- 10 unchanged lines hidden (view full) ---

25\ Classes are objects, too: all classes are instances of METACLASS
26\ All classes are derived (by convention) from OBJECT. This
27\ base class provides a default initializer and superclass
28\ access method
29
30\ A ficl object binds instance storage (payload) to a class.
31\ object ( -- instance class )
32\ All objects push their payload address and class address when
33\ executed. All objects have this footprint:
34\ cell 0: first payload cell
33\ executed.
35
36\ A ficl class consists of a parent class pointer, a wordlist
37\ ID for the methods of the class, and a size for the payload
38\ of objects created by the class. A class is an object.
39\ The NEW method creates and initializes an instance of a class.
40\ Classes have this footprint:
41\ cell 0: parent class address
42\ cell 1: wordlist ID
43\ cell 2: size of instance's payload
44
45\ Methods expect an object couple ( instance class )
34
35\ A ficl class consists of a parent class pointer, a wordlist
36\ ID for the methods of the class, and a size for the payload
37\ of objects created by the class. A class is an object.
38\ The NEW method creates and initializes an instance of a class.
39\ Classes have this footprint:
40\ cell 0: parent class address
41\ cell 1: wordlist ID
42\ cell 2: size of instance's payload
43
44\ Methods expect an object couple ( instance class )
46\ on the stack.
45\ on the stack. This is by convention - ficl has no way to
46\ police your code to make sure this is always done, but it
47\ happens naturally if you use the facilities presented here.
48\
47\ Overridden methods must maintain the same stack signature as
49\ Overridden methods must maintain the same stack signature as
48\ their predecessors. Ficl has no way of enforcing this, though.
50\ their predecessors. Ficl has no way of enforcing this, either.
51\
52\ Revised Apr 2001 - Added Guy Carver's vtable extensions. Class now
53\ has an extra field for the vtable method count. Hasvtable declares
54\ refs to vtable classes
55\
56\ Revised Nov 2001 - metaclass debug method now finds only metaclass methods
57\
58\ Planned: Ficl vtable support
59\ Each class has a vtable size parameter
60\ END-CLASS allocates and clears the vtable - then it walks class's method
61\ list and inserts all new methods into table. For each method, if the table
62\ slot is already nonzero, do nothing (overridden method). Otherwise fill
63\ vtable slot. Now do same check for parent class vtable, filling only
64\ empty slots in the new vtable.
65\ Methods are now structured as follows:
66\ - header
67\ - vtable index
68\ - xt
69\ :noname definition for code
70\
71\ : is redefined to check for override, fill in vtable index, increment method
72\ count if not an override, create header and fill in index. Allot code pointer
73\ and run :noname
74\ ; is overridden to fill in xt returned by :noname
75\ --> compiles code to fetch vtable address, offset by index, and execute
76\ => looks up xt in the vtable and compiles it directly
49
77
78
79
50user current-class
510 current-class !
52
53\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
54\ ** L A T E B I N D I N G
55\ Compile the method name, and code to find and
56\ execute it at run-time...
80user current-class
810 current-class !
82
83\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
84\ ** L A T E B I N D I N G
85\ Compile the method name, and code to find and
86\ execute it at run-time...
57\ parse-method compiles the method name so that it pushes
58\ the string base address and count at run-time.
59\
60
61hide
62
87\
88
89hide
90
91\ p a r s e - m e t h o d
92\ compiles a method name so that it pushes
93\ the string base address and count at run-time.
94
63: parse-method \ name run: ( -- c-addr u )
64 parse-word
95: parse-method \ name run: ( -- c-addr u )
96 parse-word
65 postpone sliteral
97 postpone sliteral
66; compile-only
67
98; compile-only
99
100\ l o o k u p - m e t h o d
101\ takes a counted string method name from the stack (as compiled
102\ by parse-method) and attempts to look this method up in the method list of
103\ the class that's on the stack. If successful, it leaves the class on the stack
104\ and pushes the xt of the method. If not, it aborts with an error message.
105
68: lookup-method { class 2:name -- class xt }
106: lookup-method { class 2:name -- class xt }
69 name class cell+ @ ( c-addr u wid )
70 search-wordlist ( 0 | xt 1 | xt -1 )
71 0= if
72 name type ." not found in "
107 name class cell+ @ ( c-addr u wid )
108 search-wordlist ( 0 | xt 1 | xt -1 )
109 0= if
110 name type ." not found in "
73 class body> >name type
74 cr abort
111 class body> >name type
112 cr abort
75 endif
113 endif
76 class swap
77;
78
79: find-method-xt \ name ( class -- class xt )
114 class swap
115;
116
117: find-method-xt \ name ( class -- class xt )
80 parse-word lookup-method
118 parse-word lookup-method
81;
82
83set-current ( stop hiding definitions )
84
85: catch-method ( instance class c-addr u -- <method-signature> exc-flag )
86 lookup-method catch
87;
88
89: exec-method ( instance class c-addr u -- <method-signature> )
90 lookup-method execute
91;
92
93\ Method lookup operator takes a class-addr and instance-addr
94\ and executes the method from the class's wordlist if
95\ interpreting. If compiling, bind late.
96\
97: --> ( instance class -- ??? )
98 state @ 0= if
119;
120
121set-current ( stop hiding definitions )
122
123: catch-method ( instance class c-addr u -- <method-signature> exc-flag )
124 lookup-method catch
125;
126
127: exec-method ( instance class c-addr u -- <method-signature> )
128 lookup-method execute
129;
130
131\ Method lookup operator takes a class-addr and instance-addr
132\ and executes the method from the class's wordlist if
133\ interpreting. If compiling, bind late.
134\
135: --> ( instance class -- ??? )
136 state @ 0= if
99 find-method-xt execute
137 find-method-xt execute
100 else
138 else
101 parse-method postpone exec-method
139 parse-method postpone exec-method
102 endif
103; immediate
104
105\ Method lookup with CATCH in case of exceptions
106: c-> ( instance class -- ?? exc-flag )
107 state @ 0= if
140 endif
141; immediate
142
143\ Method lookup with CATCH in case of exceptions
144: c-> ( instance class -- ?? exc-flag )
145 state @ 0= if
108 find-method-xt catch
146 find-method-xt catch
109 else
147 else
110 parse-method postpone catch-method
148 parse-method postpone catch-method
111 endif
112; immediate
113
114\ METHOD makes global words that do method invocations by late binding
115\ in case you prefer this style (no --> in your code)
149 endif
150; immediate
151
152\ METHOD makes global words that do method invocations by late binding
153\ in case you prefer this style (no --> in your code)
154\ Example: everything has next and prev for array access, so...
155\ method next
156\ method prev
157\ my-instance next ( does whatever next does to my-instance by late binding )
158
116: method create does> body> >name lookup-method execute ;
117
118
119\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
120\ ** E A R L Y B I N D I N G
121\ Early binding operator compiles code to execute a method
122\ given its class at compile time. Classes are immediate,
123\ so they leave their cell-pair on the stack when compiling.
124\ Example:
125\ : get-wid metaclass => .wid @ ;
126\ Usage
127\ my-class get-wid ( -- wid-of-my-class )
128\
1291 ficl-named-wordlist instance-vars
130instance-vars dup >search ficl-set-current
131
132: => \ c:( class meta -- ) run: ( -- ??? ) invokes compiled method
159: method create does> body> >name lookup-method execute ;
160
161
162\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
163\ ** E A R L Y B I N D I N G
164\ Early binding operator compiles code to execute a method
165\ given its class at compile time. Classes are immediate,
166\ so they leave their cell-pair on the stack when compiling.
167\ Example:
168\ : get-wid metaclass => .wid @ ;
169\ Usage
170\ my-class get-wid ( -- wid-of-my-class )
171\
1721 ficl-named-wordlist instance-vars
173instance-vars dup >search ficl-set-current
174
175: => \ c:( class meta -- ) run: ( -- ??? ) invokes compiled method
133 drop find-method-xt compile, drop
176 drop find-method-xt compile, drop
134; immediate compile-only
135
136: my=> \ c:( -- ) run: ( -- ??? ) late bind compiled method of current-class
137 current-class @ dup postpone =>
138; immediate compile-only
139
177; immediate compile-only
178
179: my=> \ c:( -- ) run: ( -- ??? ) late bind compiled method of current-class
180 current-class @ dup postpone =>
181; immediate compile-only
182
183\ Problem: my=[ assumes that each method except the last is am obj: member
184\ which contains its class as the first field of its parameter area. The code
185\ detects non-obect members and assumes the class does not change in this case.
186\ This handles methods like index, prev, and next correctly, but does not deal
187\ correctly with CLASS.
140: my=[ \ same as my=> , but binds a chain of methods
141 current-class @
142 begin
188: my=[ \ same as my=> , but binds a chain of methods
189 current-class @
190 begin
143 parse-word 2dup
144 s" ]" compare while ( class c-addr u )
145 lookup-method nip dup ( xt xt )
146 compile, >body cell+ @ ( class' )
191 parse-word 2dup ( class c-addr u c-addr u )
192 s" ]" compare while ( class c-addr u )
193 lookup-method ( class xt )
194 dup compile, ( class xt )
195 dup ?object if \ If object member, get new class. Otherwise assume same class
196 nip >body cell+ @ ( new-class )
197 else
198 drop ( class )
199 endif
147 repeat 2drop drop
148; immediate compile-only
149
150
151\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
152\ ** I N S T A N C E V A R I A B L E S
153\ Instance variables (IV) are represented by words in the class's
154\ private wordlist. Each IV word contains the offset

--- 4 unchanged lines hidden (view full) ---

159\ stack for these words to update. When a class definition is
160\ complete, END-CLASS saves the final size in the class's size
161\ field, and restores the search order and compile wordlist to
162\ prior state. Note that these words are hidden in their own
163\ wordlist to prevent accidental use outside a SUB END-CLASS pair.
164\
165: do-instance-var
166 does> ( instance class addr[offset] -- addr[field] )
200 repeat 2drop drop
201; immediate compile-only
202
203
204\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
205\ ** I N S T A N C E V A R I A B L E S
206\ Instance variables (IV) are represented by words in the class's
207\ private wordlist. Each IV word contains the offset

--- 4 unchanged lines hidden (view full) ---

212\ stack for these words to update. When a class definition is
213\ complete, END-CLASS saves the final size in the class's size
214\ field, and restores the search order and compile wordlist to
215\ prior state. Note that these words are hidden in their own
216\ wordlist to prevent accidental use outside a SUB END-CLASS pair.
217\
218: do-instance-var
219 does> ( instance class addr[offset] -- addr[field] )
167 nip @ +
220 nip @ +
168;
169
170: addr-units: ( offset size "name" -- offset' )
171 create over , +
172 do-instance-var
173;
174
221;
222
223: addr-units: ( offset size "name" -- offset' )
224 create over , +
225 do-instance-var
226;
227
175: chars: \ ( offset nCells "name" -- offset' ) Create n char member.
228: chars: \ ( offset nCells "name" -- offset' ) Create n char member.
176 chars addr-units: ;
177
229 chars addr-units: ;
230
178: char: \ ( offset nCells "name" -- offset' ) Create 1 char member.
231: char: \ ( offset nCells "name" -- offset' ) Create 1 char member.
179 1 chars: ;
180
181: cells: ( offset nCells "name" -- offset' )
232 1 chars: ;
233
234: cells: ( offset nCells "name" -- offset' )
182 cells >r aligned r> addr-units:
235 cells >r aligned r> addr-units:
183;
184
185: cell: ( offset nCells "name" -- offset' )
186 1 cells: ;
187
188\ Aggregate an object into the class...
189\ Needs the class of the instance to create
190\ Example: object obj: m_obj
191\
192: do-aggregate
236;
237
238: cell: ( offset nCells "name" -- offset' )
239 1 cells: ;
240
241\ Aggregate an object into the class...
242\ Needs the class of the instance to create
243\ Example: object obj: m_obj
244\
245: do-aggregate
193 does> ( instance class pfa -- a-instance a-class )
194 2@ ( inst class a-class a-offset )
195 2swap drop ( a-class a-offset inst )
196 + swap ( a-inst a-class )
246 objectify
247 does> ( instance class pfa -- a-instance a-class )
248 2@ ( inst class a-class a-offset )
249 2swap drop ( a-class a-offset inst )
250 + swap ( a-inst a-class )
197;
198
251;
252
199: obj: ( offset class meta "name" -- offset' )
200 locals| meta class offset |
253: obj: { offset class meta -- offset' } \ "name"
201 create offset , class ,
254 create offset , class ,
202 class meta --> get-size offset +
203 do-aggregate
255 class meta --> get-size offset +
256 do-aggregate
204;
205
206\ Aggregate an array of objects into a class
207\ Usage example:
208\ 3 my-class array: my-array
209\ Makes an instance variable array of 3 instances of my-class
210\ named my-array.
211\
212: array: ( offset n class meta "name" -- offset' )
257;
258
259\ Aggregate an array of objects into a class
260\ Usage example:
261\ 3 my-class array: my-array
262\ Makes an instance variable array of 3 instances of my-class
263\ named my-array.
264\
265: array: ( offset n class meta "name" -- offset' )
213 locals| meta class nobjs offset |
214 create offset , class ,
215 class meta --> get-size nobjs * offset +
216 do-aggregate
266 locals| meta class nobjs offset |
267 create offset , class ,
268 class meta --> get-size nobjs * offset +
269 do-aggregate
217;
218
219\ Aggregate a pointer to an object: REF is a member variable
220\ whose class is set at compile time. This is useful for wrapping
221\ data structures in C, where there is only a pointer and the type
222\ it refers to is known. If you want polymorphism, see c_ref
223\ in classes.fr. REF is only useful for pre-initialized structures,
224\ since there's no supported way to set one.
225: ref: ( offset class meta "name" -- offset' )
270;
271
272\ Aggregate a pointer to an object: REF is a member variable
273\ whose class is set at compile time. This is useful for wrapping
274\ data structures in C, where there is only a pointer and the type
275\ it refers to is known. If you want polymorphism, see c_ref
276\ in classes.fr. REF is only useful for pre-initialized structures,
277\ since there's no supported way to set one.
278: ref: ( offset class meta "name" -- offset' )
226 locals| meta class offset |
227 create offset , class ,
228 offset cell+
229 does> ( inst class pfa -- ptr-inst ptr-class )
230 2@ ( inst class ptr-class ptr-offset )
231 2swap drop + @ swap
279 locals| meta class offset |
280 create offset , class ,
281 offset cell+
282 does> ( inst class pfa -- ptr-inst ptr-class )
283 2@ ( inst class ptr-class ptr-offset )
284 2swap drop + @ swap
232;
233
285;
286
287\ #if FICL_WANT_VCALL
288\ vcall extensions contributed by Guy Carver
289: vcall: ( paramcnt "name" -- )
290 current-class @ 8 + dup @ dup 1+ rot ! \ Kludge fix to get to .vtCount before it's defined.
291 create , , \ ( paramcnt index -- )
292 does> \ ( inst class pfa -- ptr-inst ptr-class )
293 nip 2@ vcall \ ( params offset inst class offset -- )
294;
295
296: vcallr: 0x80000000 or vcall: ; \ Call with return address desired.
297
298\ #if FICL_WANT_FLOAT
299: vcallf: \ ( paramcnt -<name>- f: r )
300 0x80000000 or
301 current-class @ 8 + dup @ dup 1+ rot ! \ Kludge fix to get to .vtCount before it's defined.
302 create , , \ ( paramcnt index -- )
303 does> \ ( inst class pfa -- ptr-inst ptr-class )
304 nip 2@ vcall f> \ ( params offset inst class offset -- f: r )
305;
306\ #endif /* FLOAT */
307\ #endif /* VCALL */
308
234\ END-CLASS terminates construction of a class by storing
235\ the size of its instance variables in the class's size field
236\ ( -- old-wid addr[size] 0 )
237\
238: end-class ( old-wid addr[size] size -- )
239 swap ! set-current
309\ END-CLASS terminates construction of a class by storing
310\ the size of its instance variables in the class's size field
311\ ( -- old-wid addr[size] 0 )
312\
313: end-class ( old-wid addr[size] size -- )
314 swap ! set-current
240 search> drop \ pop struct builder wordlist
315 search> drop \ pop struct builder wordlist
241;
242
243\ See resume-class (a metaclass method) below for usage
244\ This is equivalent to end-class for now, but that will change
245\ when we support vtable bindings.
246: suspend-class ( old-wid addr[size] size -- ) end-class ;
247
248set-current previous
249\ E N D I N S T A N C E V A R I A B L E S
250
251
252\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
253\ D O - D O - I N S T A N C E
254\ Makes a class method that contains the code for an
255\ instance of the class. This word gets compiled into
256\ the wordlist of every class by the SUB method.
257\ PRECONDITION: current-class contains the class address
258\ why use a state variable instead of the stack?
316;
317
318\ See resume-class (a metaclass method) below for usage
319\ This is equivalent to end-class for now, but that will change
320\ when we support vtable bindings.
321: suspend-class ( old-wid addr[size] size -- ) end-class ;
322
323set-current previous
324\ E N D I N S T A N C E V A R I A B L E S
325
326
327\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
328\ D O - D O - I N S T A N C E
329\ Makes a class method that contains the code for an
330\ instance of the class. This word gets compiled into
331\ the wordlist of every class by the SUB method.
332\ PRECONDITION: current-class contains the class address
333\ why use a state variable instead of the stack?
259\ >> Stack state is not well-defined during compilation (there are
334\ >> Stack state is not well-defined during compilation (there are
260\ >> control structure match codes on the stack, of undefined size
261\ >> easiest way around this is use of this thread-local variable
262\
263: do-do-instance ( -- )
264 s" : .do-instance does> [ current-class @ ] literal ;"
265 evaluate
266;
267
268\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
269\ ** M E T A C L A S S
270\ Every class is an instance of metaclass. This lets
271\ classes have methods that are different from those
272\ of their instances.
273\ Classes are IMMEDIATE to make early binding simpler
274\ See above...
275\
276:noname
335\ >> control structure match codes on the stack, of undefined size
336\ >> easiest way around this is use of this thread-local variable
337\
338: do-do-instance ( -- )
339 s" : .do-instance does> [ current-class @ ] literal ;"
340 evaluate
341;
342
343\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
344\ ** M E T A C L A S S
345\ Every class is an instance of metaclass. This lets
346\ classes have methods that are different from those
347\ of their instances.
348\ Classes are IMMEDIATE to make early binding simpler
349\ See above...
350\
351:noname
277 wordlist
278 create
352 wordlist
353 create
279 immediate
354 immediate
280 0 , \ NULL parent class
281 dup , \ wid
282 3 cells , \ instance size
283 ficl-set-current
284 does> dup
355 0 , \ NULL parent class
356 dup , \ wid
357\ #if FICL_WANT_VCALL
358 4 cells , \ instance size
359\ #else
360 3 cells , \ instance size
361\ #endif
362 ficl-set-current
363 does> dup
285; execute metaclass
286\ now brand OBJECT's wordlist (so that ORDER can display it by name)
287metaclass drop cell+ @ brand-wordlist
288
289metaclass drop current-class !
290do-do-instance
291
292\
293\ C L A S S M E T H O D S
294\
295instance-vars >search
296
297create .super ( class metaclass -- parent-class )
298 0 cells , do-instance-var
299
300create .wid ( class metaclass -- wid ) \ return wid of class
301 1 cells , do-instance-var
302
364; execute metaclass
365\ now brand OBJECT's wordlist (so that ORDER can display it by name)
366metaclass drop cell+ @ brand-wordlist
367
368metaclass drop current-class !
369do-do-instance
370
371\
372\ C L A S S M E T H O D S
373\
374instance-vars >search
375
376create .super ( class metaclass -- parent-class )
377 0 cells , do-instance-var
378
379create .wid ( class metaclass -- wid ) \ return wid of class
380 1 cells , do-instance-var
381
382\ #if FICL_WANT_VCALL
383create .vtCount \ Number of VTABLE methods, if any
384 2 cells , do-instance-var
385
303create .size ( class metaclass -- size ) \ return class's payload size
386create .size ( class metaclass -- size ) \ return class's payload size
387 3 cells , do-instance-var
388\ #else
389create .size ( class metaclass -- size ) \ return class's payload size
304 2 cells , do-instance-var
390 2 cells , do-instance-var
391\ #endif
305
306: get-size metaclass => .size @ ;
307: get-wid metaclass => .wid @ ;
308: get-super metaclass => .super @ ;
392
393: get-size metaclass => .size @ ;
394: get-wid metaclass => .wid @ ;
395: get-super metaclass => .super @ ;
396\ #if FICL_WANT_VCALL
397: get-vtCount metaclass => .vtCount @ ;
398: get-vtAdd metaclass => .vtCount ;
399\ #endif
309
310\ create an uninitialized instance of a class, leaving
311\ the address of the new instance and its class
312\
313: instance ( class metaclass "name" -- instance class )
314 locals| meta parent |
400
401\ create an uninitialized instance of a class, leaving
402\ the address of the new instance and its class
403\
404: instance ( class metaclass "name" -- instance class )
405 locals| meta parent |
315 create
406 create
316 here parent --> .do-instance \ ( inst class )
317 parent meta metaclass => get-size
318 allot \ allocate payload space
319;
320
321\ create an uninitialized array
322: array ( n class metaclass "name" -- n instance class )
323 locals| meta parent nobj |
407 here parent --> .do-instance \ ( inst class )
408 parent meta metaclass => get-size
409 allot \ allocate payload space
410;
411
412\ create an uninitialized array
413: array ( n class metaclass "name" -- n instance class )
414 locals| meta parent nobj |
324 create nobj
415 create nobj
325 here parent --> .do-instance \ ( nobj inst class )
326 parent meta metaclass => get-size
416 here parent --> .do-instance \ ( nobj inst class )
417 parent meta metaclass => get-size
327 nobj * allot \ allocate payload space
418 nobj * allot \ allocate payload space
328;
329
330\ create an initialized instance
331\
332: new \ ( class metaclass "name" -- )
333 metaclass => instance --> init
334;
335
336\ create an initialized array of instances
337: new-array ( n class metaclass "name" -- )
419;
420
421\ create an initialized instance
422\
423: new \ ( class metaclass "name" -- )
424 metaclass => instance --> init
425;
426
427\ create an initialized array of instances
428: new-array ( n class metaclass "name" -- )
338 metaclass => array
339 --> array-init
429 metaclass => array
430 --> array-init
340;
341
342\ Create an anonymous initialized instance from the heap
343: alloc \ ( class metaclass -- instance class )
344 locals| meta class |
345 class meta metaclass => get-size allocate ( -- addr fail-flag )
346 abort" allocate failed " ( -- addr )
347 class 2dup --> init

--- 53 unchanged lines hidden (view full) ---

401\ This method leaves the stack and search order ready for instance variable
402\ building. Pushes the instance-vars wordlist onto the search order,
403\ and sets the compilation wordlist to be the private wordlist of the
404\ new class. The class's wordlist is deliberately NOT in the search order -
405\ to prevent methods from getting used with wrong data.
406\ Postcondition: leaves the address of the new class in current-class
407: sub ( class metaclass "name" -- old-wid addr[size] size )
408 wordlist
431;
432
433\ Create an anonymous initialized instance from the heap
434: alloc \ ( class metaclass -- instance class )
435 locals| meta class |
436 class meta metaclass => get-size allocate ( -- addr fail-flag )
437 abort" allocate failed " ( -- addr )
438 class 2dup --> init

--- 53 unchanged lines hidden (view full) ---

492\ This method leaves the stack and search order ready for instance variable
493\ building. Pushes the instance-vars wordlist onto the search order,
494\ and sets the compilation wordlist to be the private wordlist of the
495\ new class. The class's wordlist is deliberately NOT in the search order -
496\ to prevent methods from getting used with wrong data.
497\ Postcondition: leaves the address of the new class in current-class
498: sub ( class metaclass "name" -- old-wid addr[size] size )
499 wordlist
409 locals| wid meta parent |
410 parent meta metaclass => get-wid
411 wid wid-set-super \ set superclass
412 create immediate \ get the subclass name
500 locals| wid meta parent |
501 parent meta metaclass => get-wid
502 wid wid-set-super \ set superclass
503 create immediate \ get the subclass name
413 wid brand-wordlist \ label the subclass wordlist
504 wid brand-wordlist \ label the subclass wordlist
414 here current-class ! \ prep for do-do-instance
415 parent , \ save parent class
416 wid , \ save wid
417 here parent meta --> get-size dup , ( addr[size] size )
418 metaclass => .do-instance
419 wid ficl-set-current -rot
420 do-do-instance
421 instance-vars >search \ push struct builder wordlist
505 here current-class ! \ prep for do-do-instance
506 parent , \ save parent class
507 wid , \ save wid
508\ #if FICL_WANT_VCALL
509 parent meta --> get-vtCount ,
510\ #endif
511 here parent meta --> get-size dup , ( addr[size] size )
512 metaclass => .do-instance
513 wid ficl-set-current -rot
514 do-do-instance
515 instance-vars >search \ push struct builder wordlist
422;
423
424\ OFFSET-OF returns the offset of an instance variable
425\ from the instance base address. If the next token is not
426\ the name of in instance variable method, you get garbage
427\ results -- there is no way at present to check for this error.
428: offset-of ( class metaclass "name" -- offset )
429 drop find-method-xt nip >body @ ;
430
431\ ID returns the string name cell-pair of its class
432: id ( class metaclass -- c-addr u )
516;
517
518\ OFFSET-OF returns the offset of an instance variable
519\ from the instance base address. If the next token is not
520\ the name of in instance variable method, you get garbage
521\ results -- there is no way at present to check for this error.
522: offset-of ( class metaclass "name" -- offset )
523 drop find-method-xt nip >body @ ;
524
525\ ID returns the string name cell-pair of its class
526: id ( class metaclass -- c-addr u )
433 drop body> >name ;
527 drop body> >name ;
434
435\ list methods of the class
436: methods \ ( class meta -- )
528
529\ list methods of the class
530: methods \ ( class meta -- )
437 locals| meta class |
438 begin
439 class body> >name type ." methods:" cr
440 class meta --> get-wid >search words cr previous
441 class meta metaclass => get-super
442 dup to class
443 0= until cr
531 locals| meta class |
532 begin
533 class body> >name type ." methods:" cr
534 class meta --> get-wid >search words cr previous
535 class meta metaclass => get-super
536 dup to class
537 0= until cr
444;
445
446\ list class's ancestors
447: pedigree ( class meta -- )
538;
539
540\ list class's ancestors
541: pedigree ( class meta -- )
448 locals| meta class |
449 begin
450 class body> >name type space
451 class meta metaclass => get-super
452 dup to class
453 0= until cr
542 locals| meta class |
543 begin
544 class body> >name type space
545 class meta metaclass => get-super
546 dup to class
547 0= until cr
454;
455
548;
549
456\ decompile a method
550\ decompile an instance method
457: see ( class meta -- )
458 metaclass => get-wid >search see previous ;
459
551: see ( class meta -- )
552 metaclass => get-wid >search see previous ;
553
460previous set-current
554\ debug a method of metaclass
555\ Eg: my-class --> debug my-method
556: debug ( class meta -- )
557 find-method-xt debug-xt ;
558
559previous set-current
461\ E N D M E T A C L A S S
462
463\ ** META is a nickname for the address of METACLASS...
464metaclass drop
465constant meta
466
467\ ** SUBCLASS is a nickname for a class's SUB method...
468\ Subclass compilation ends when you invoke end-class
469\ This method is late bound for safety...
470: subclass --> sub ;
471
560\ E N D M E T A C L A S S
561
562\ ** META is a nickname for the address of METACLASS...
563metaclass drop
564constant meta
565
566\ ** SUBCLASS is a nickname for a class's SUB method...
567\ Subclass compilation ends when you invoke end-class
568\ This method is late bound for safety...
569: subclass --> sub ;
570
571\ #if FICL_WANT_VCALL
572\ VTABLE Support extensions (Guy Carver)
573\ object --> sub mine hasvtable
574: hasvtable 4 + ; immediate
575\ #endif
472
576
577
473\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
474\ ** O B J E C T
475\ Root of all classes
476:noname
578\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
579\ ** O B J E C T
580\ Root of all classes
581:noname
477 wordlist
478 create immediate
479 0 , \ NULL parent class
480 dup , \ wid
481 0 , \ instance size
482 ficl-set-current
483 does> meta
582 wordlist
583 create immediate
584 0 , \ NULL parent class
585 dup , \ wid
586 0 , \ instance size
587 ficl-set-current
588 does> meta
484; execute object
485\ now brand OBJECT's wordlist (so that ORDER can display it by name)
486object drop cell+ @ brand-wordlist
487
488object drop current-class !
489do-do-instance
490instance-vars >search
491
492\ O B J E C T M E T H O D S
493\ Convert instance cell-pair to class cell-pair
494\ Useful for binding class methods from an instance
495: class ( instance class -- class metaclass )
589; execute object
590\ now brand OBJECT's wordlist (so that ORDER can display it by name)
591object drop cell+ @ brand-wordlist
592
593object drop current-class !
594do-do-instance
595instance-vars >search
596
597\ O B J E C T M E T H O D S
598\ Convert instance cell-pair to class cell-pair
599\ Useful for binding class methods from an instance
600: class ( instance class -- class metaclass )
496 nip meta ;
601 nip meta ;
497
498\ default INIT method zero fills an instance
499: init ( instance class -- )
500 meta
501 metaclass => get-size ( inst size )
502 erase ;
503
504\ Apply INIT to an array of NOBJ objects...
505\
506: array-init ( nobj inst class -- )
602
603\ default INIT method zero fills an instance
604: init ( instance class -- )
605 meta
606 metaclass => get-size ( inst size )
607 erase ;
608
609\ Apply INIT to an array of NOBJ objects...
610\
611: array-init ( nobj inst class -- )
507 0 dup locals| &init &next class inst |
508 \
509 \ bind methods outside the loop to save time
510 \
511 class s" init" lookup-method to &init
512 s" next" lookup-method to &next
513 drop
514 0 ?do
515 inst class 2dup
516 &init execute
517 &next execute drop to inst
518 loop
612 0 dup locals| &init &next class inst |
613 \
614 \ bind methods outside the loop to save time
615 \
616 class s" init" lookup-method to &init
617 s" next" lookup-method to &next
618 drop
619 0 ?do
620 inst class 2dup
621 &init execute
622 &next execute drop to inst
623 loop
519;
520
521\ free storage allocated to a heap instance by alloc or alloc-array
522\ NOTE: not protected against errors like FREEing something that's
523\ really in the dictionary.
524: free \ ( instance class -- )
624;
625
626\ free storage allocated to a heap instance by alloc or alloc-array
627\ NOTE: not protected against errors like FREEing something that's
628\ really in the dictionary.
629: free \ ( instance class -- )
525 drop free
526 abort" free failed "
630 drop free
631 abort" free failed "
527;
528
529\ Instance aliases for common class methods
530\ Upcast to parent class
531: super ( instance class -- instance parent-class )
532 meta metaclass => get-super ;
533
534: pedigree ( instance class -- )
632;
633
634\ Instance aliases for common class methods
635\ Upcast to parent class
636: super ( instance class -- instance parent-class )
637 meta metaclass => get-super ;
638
639: pedigree ( instance class -- )
535 object => class
640 object => class
536 metaclass => pedigree ;
537
538: size ( instance class -- sizeof-instance )
641 metaclass => pedigree ;
642
643: size ( instance class -- sizeof-instance )
539 object => class
644 object => class
540 metaclass => get-size ;
541
542: methods ( instance class -- )
645 metaclass => get-size ;
646
647: methods ( instance class -- )
543 object => class
648 object => class
544 metaclass => methods ;
545
546\ Array indexing methods...
547\ Usage examples:
548\ 10 object-array --> index
549\ obj --> next
550\
551: index ( n instance class -- instance[n] class )
649 metaclass => methods ;
650
651\ Array indexing methods...
652\ Usage examples:
653\ 10 object-array --> index
654\ obj --> next
655\
656: index ( n instance class -- instance[n] class )
552 locals| class inst |
553 inst class
657 locals| class inst |
658 inst class
554 object => class
659 object => class
555 metaclass => get-size * ( n*size )
556 inst + class ;
660 metaclass => get-size * ( n*size )
661 inst + class ;
557
558: next ( instance[n] class -- instance[n+1] class )
662
663: next ( instance[n] class -- instance[n+1] class )
559 locals| class inst |
560 inst class
664 locals| class inst |
665 inst class
561 object => class
666 object => class
562 metaclass => get-size
563 inst +
564 class ;
667 metaclass => get-size
668 inst +
669 class ;
565
566: prev ( instance[n] class -- instance[n-1] class )
670
671: prev ( instance[n] class -- instance[n-1] class )
567 locals| class inst |
568 inst class
672 locals| class inst |
673 inst class
569 object => class
674 object => class
570 metaclass => get-size
571 inst swap -
572 class ;
675 metaclass => get-size
676 inst swap -
677 class ;
573
574: debug ( 2this -- ?? )
575 find-method-xt debug-xt ;
576
577previous set-current
578\ E N D O B J E C T
579
678
679: debug ( 2this -- ?? )
680 find-method-xt debug-xt ;
681
682previous set-current
683\ E N D O B J E C T
684
580
685\ reset to default search order
581only definitions
686only definitions
687
688\ redefine oop in default search order to put OOP words in the search order and make them
689\ the compiling wordlist...
690
691: oo only also oop definitions ;
692
582\ #endif
693\ #endif