On 5/22/12 3:39 AM, Gerry Jackson wrote:
> Are you going to post the code for this slimmed down micro-FMS? I'm
> interested in seeing it.
Could be trimmed even further but it then becomes painful to use, IMO.
-Doug
\ micro-FMS2 Douglas B. Hoffman 05/18/12
\ Full encapsulation of data and methods.
\ Polymorphism with no restrictions on inheritance order.
\ Dynamic (late) binding of methods.
\ Duck typing.
\ Class variables.
\ Instantiate objects in the dictionary or the heap.
\ No juggling of object in method definitions.
\ 1428 bytes on Carbon MacForth
\ 32 lines of code
0 value self
0 value ^class
: dfa ( class -- a) cell+ ;
: sfa ( class -- a) 2 cells + ;
: wida ( class -- a) 3 cells + ;
4 cells constant classSize
: fm ( sel class -- xt) begin @ dup while 2dup cell+ @ =
if [ 2 cells ] literal + nip @ exit then repeat throw ;
create object 0 , 0 ,
: <super ( -- wn..w1 n) here to ^class classSize allot ' >body
dup ^class classSize move ^class sfa ! get-order wordlist dup
set-current ^class wida ! ^class >r get-order begin r@ wida @
swap 1+ r> sfa @ >r r@ object = until r> drop set-order ;
: selector ( name --) create does> over 1 cells - @ fm
self >r swap to self execute r> to self ;
: getselect ( -- sel) >in @ bl word find
if >body nip else drop >in ! selector here then ;
: :m ( name -- a xt) forth-wordlist set-current
getselect ^class here over @ , swap ! , here 0 , :noname ;
: ;m ( a xt --) postpone ; swap ! ; immediate
: super ( name --) ' >body ^class sfa @ fm compile, ; immediate
: (ivar) ( name -- a) create immediate ,
does> @ postpone literal postpone self postpone + ;
: bytes ( n name --) ^class dfa @ (ivar) ^class dfa +! ;
: dict-allot ( n+cell -- o) align here swap ( n ) allot ;
: heap-allocate ( n+cell -- o) allocate throw ;
defer allotocate ( n+cell -- o)
: (mo) ( cls - o) dup dfa @ cell+ allotocate tuck ! cell+ ;
: mo ( name xt - o) is allotocate ' >body state @
if postpone literal postpone (mo) else (mo) then ;
: dict> ['] dict-allot mo ; immediate
: heap> ['] heap-allocate mo ; immediate
: <free ( o --) 1 cells - free throw ;
\ example classes
1 cells constant cell
create var <super object \ var is subclass of object
cell bytes data
:m !: ( n -- ) data ! ;m
:m +: ( n -- ) data +! ;m
:m @: ( -- n ) data @ ;m
:m p: ( -- ) self @: . ;m \ print self
:m init: 0 data ! ;m
set-order
dict> var value x
33 x !:
cr .( print var x )
x p:
heap> var value hx
hx init:
cr .( print var hx )
hx p:
hx <free
create ptr <super var
cell bytes size \ size, in bytes, of memory allocated
variable ptr-cnt 0 ptr-cnt ! \ class variable
:m size: ( -- n ) size @ ;m
:m free:
self @ ?dup if free throw 0 self ! then
0 size ! -1 ptr-cnt +! ;m
:m new: ( size -- )
dup allocate throw self ! size !
1 ptr-cnt +! ;m
:m resize: ( newsize -- )
self @ over resize throw self ! size ! ;m
:m cnt: ( -- n) ptr-cnt @ ;m
set-order
create string <super ptr
:m new: ( addr len -- )
dup super new: ( addr len ) self @ swap ( addr self len ) move ;m
:m add: ( addr len -- ) \ add text to end of string
dup ( addr-src len len )
size @ dup >r + self resize: \ addr-src len
self @ r> + ( addr-src len dest) swap move ;m
:m @: ( -- addr len ) self @ size @ ;m
:m p: self @: type ;m
:m +: ( char -- ) \ add char to end of string
size @ 1+ self resize: self @: + 1- c! ;m
set-order
dict> string value s
s" hello" s new:
cr .( print s )
s p:
cr .( print s )
s" world" s add: s p:
cr .( print s )
char ! s +: s p:
cr .( inspect class variable )
s cnt: .
heap> string value hs
s" goodbye" hs new:
cr .( print hs )
hs p:
cr .( inspect class variable )
hs cnt: .
s free:
hs free: hs <free
cr .( inspect class variable )
s cnt: .