Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

OOP packages

156 views
Skip to first unread message

hwf...@gmail.com

unread,
May 8, 2012, 12:31:39 PM5/8/12
to
Hi All,

Which OOP packages are common to both the VFX and SwiftForth communities? I know of SWOOP but there could be others.

-Brad

Elizabeth D. Rather

unread,
May 8, 2012, 3:10:00 PM5/8/12
to
SWOOP is only in SwiftForth. VFX's OOP is quite different.

Cheers,
Elizabeth

--
==================================================
Elizabeth D. Rather (US & Canada) 800-55-FORTH
FORTH Inc. +1 310.999.6784
5959 West Century Blvd. Suite 700
Los Angeles, CA 90045
http://www.forth.com

"Forth-based products and Services for real-time
applications since 1973."
==================================================

BruceMcF

unread,
May 8, 2012, 3:39:23 PM5/8/12
to
I know that Mini-OOF, included with gforth, is Forth94 and works with
both VFX and Swiftforth ~ gforth also includes OOF and objects that
are both advertised as "written in ANS Forth and can be used with any
other ANS Forth", though I've never tested that out.

Doug Hoffman

unread,
May 8, 2012, 3:56:39 PM5/8/12
to
On 5/8/12 12:31 PM, hwf...@gmail.com wrote:

> Which OOP packages are common to both the VFX and SwiftForth communities? I know of SWOOP but there could be others.

FMS is ANS compatible and has been thoroughly tested on VFX, SwiftForth,
Gforth, iForth, Win32Forth, and Carbon MacForth.

http://soton.mpeforth.com/flag/fms/index.html

-Doug

Stephen Pelc

unread,
May 8, 2012, 4:17:42 PM5/8/12
to
On Tue, 08 May 2012 09:10:00 -1000, "Elizabeth D. Rather"
<era...@forth.com> wrote:

>> Which OOP packages are common to both the VFX and SwiftForth
>> communities? I know of SWOOP but there could be others.
>
>SWOOP is only in SwiftForth. VFX's OOP is quite different.

With Leon's permission, there are versions of SWOOP for both
SwiftForth and VFX at FLAG
http://soton.mpeforth.com/flag/

FLAG also has Doug Hoffman's FMS, which is probably the most
widely ported OOP system of them all.

Stephen


--
Stephen Pelc, steph...@mpeforth.com
MicroProcessor Engineering Ltd - More Real, Less Time
133 Hill Lane, Southampton SO15 5AF, England
tel: +44 (0)23 8063 1441, fax: +44 (0)23 8033 9691
web: http://www.mpeforth.com - free VFX Forth downloads

hwf...@gmail.com

unread,
May 8, 2012, 9:26:05 PM5/8/12
to steph...@invalid.mpeforth.com
On Tuesday, May 8, 2012 1:17:42 PM UTC-7, Stephen Pelc wrote:
> FLAG also has Doug Hoffman's FMS, which is probably the most
> widely ported OOP system of them all.

That's a enough good endorsement for me, seeing that Doug is no Johnny Come Lately. I'll have a look.

Anton Ertl

unread,
May 9, 2012, 7:34:52 AM5/9/12
to
steph...@mpeforth.com (Stephen Pelc) writes:
>FLAG also has Doug Hoffman's FMS, which is probably the most
>widely ported OOP system of them all.

On what evidence do you base this claim?

- anton
--
M. Anton Ertl http://www.complang.tuwien.ac.at/anton/home.html
comp.lang.forth FAQs: http://www.complang.tuwien.ac.at/forth/faq/toc.html
New standard: http://www.forth200x.org/forth200x.html
EuroForth 2011: http://www.euroforth.org/ef11/

Doug Hoffman

unread,
May 9, 2012, 8:00:18 AM5/9/12
to
On 5/9/12 7:34 AM, Anton Ertl wrote:
> steph...@mpeforth.com (Stephen Pelc) writes:
>> FLAG also has Doug Hoffman's FMS, which is probably the most
>> widely ported OOP system of them all.
>
> On what evidence do you base this claim?

Stephen properly qualified the statement with "probably".
It's a reasonable statement, given that implementation-specific build
harnesses are provided for each Forth mentioned along with a generic
build harness. Over 15 pre-defined classes are provided (collections,
object containers, strings, arrays, balanced tree) along with a Hayes
test harness to exercise them all, with the test harness tuned to each
Forth.

If someone has done something similar with another full featured objects
extension (encapsulation, late binding, etc.) they should speak up.

-Doug

Bernd Paysan

unread,
May 9, 2012, 1:49:02 PM5/9/12
to
Doug Hoffman wrote:
> If someone has done something similar with another full featured
> objects extension (encapsulation, late binding, etc.) they should
> speak up.

Well, BerndOOF is available as plain ANS Forth source, without any
harness needed (part of Gforth). It does not come with a predefined set
of classes, though.

--
Bernd Paysan
"If you want it done right, you have to do it yourself"
http://bernd-paysan.de/

Hugh Aguilar

unread,
May 10, 2012, 5:26:51 AM5/10/12
to
On May 9, 6:00 am, Doug Hoffman <glide...@gmail.com> wrote:
> On 5/9/12 7:34 AM, Anton Ertl wrote:
>
My novice package provides a crude step toward OOP. I don't have
polymorphism. I basically just have inheritance. It is possible to
clone data structures, even if they contain a variety of data types
(that is the whole point of ALLOCATION). It is pretty simple, but it
works well for me. It is also quite fast.

The 2 predefined classes that I have are lists and balanced trees (I
use lists for pretty much everything). I also have arrays, but that
isn't really OOP, as every element is the same data type (they pretty
much have to be, with arrays).

Anton Ertl

unread,
May 10, 2012, 7:39:50 AM5/10/12
to
Doug Hoffman <glid...@gmail.com> writes:
>On 5/9/12 7:34 AM, Anton Ertl wrote:
>> steph...@mpeforth.com (Stephen Pelc) writes:
>>> FLAG also has Doug Hoffman's FMS, which is probably the most
>>> widely ported OOP system of them all.
>>
>> On what evidence do you base this claim?
>
>Stephen properly qualified the statement with "probably".

Do you mean that no evidence is needed then? Why not?

>It's a reasonable statement, given that implementation-specific build
>harnesses are provided for each Forth mentioned along with a generic
>build harness.

Why does it need implementation-specific build harnesses?

>If someone has done something similar with another full featured objects
>extension (encapsulation, late binding, etc.) they should speak up.

No implementation-specific build harnesses for objects.fs, it's just
written in standard Forth, i.e., it is portable.

Doug Hoffman

unread,
May 10, 2012, 12:48:53 PM5/10/12
to
On 5/10/12 7:39 AM, Anton Ertl wrote:

> Why does it need implementation-specific build harnesses?

User convenience mostly. Needed? No. I found it cleaner to use
separate files. Could have used conditional compilation like s" gforth"
environment? [if] ...

It seems Forths use different file load schemes, e.g.,
- include %idir%/fmsHarnxxx.f , invoke from console menu
- or myfolder.include" fmsHarnxxx.f"
- or include fmsHarnxxx.f , invoke from console menu
- or include e:\<pathname>\fmsBuildxx.f , invoke by paste to console
or place all files in a default diectory

One of the Forths prefers a USER variable instead of a VALUE for a
specific variable.

Some Forth's have issue with the maximum number of wordlists available
for SET-ORDER. If objects.fs provided a library of classes along with a
comprehensive Hayes testing suite it may also have bumped into this
issue if also tested on that Forth.

At least one Forth needs a specific utility file loaded to support DEFER.

Having a build file also consolidates the FMS options to one place for
things like the following:
- Turn error checking on/off (array indexes and
message-not-understood handling).
- Run the Hayes test suite or not.

Other issues like the above.


> No implementation-specific build harnesses for objects.fs, it's just
> written in standard Forth, i.e., it is portable.

FMS is written in standard Forth and FMS is portable.

-Doug

hwf...@gmail.com

unread,
May 10, 2012, 8:04:52 PM5/10/12
to
I may have asked the wrong question. It's hard to evaluate the many OOPs out there. Maybe what I'm looking for is a sample problem that is solved in several dialects of OOP. That would provide some metrics.

Having spent the day in C#, the object.method syntax is starting to grow on me. But that's just encapsulation. A Forth could take a foo.bar syntax to mean "look for bar only in the foo wordlists". After all, Foo can have more than one wordlist depending on its ancestry. AFAIK some of the OOPs support FOO.BAR as FOO BAR to avoid patching the interpreter.

The base class could have some toolkit words: foo.words lists the words in the foo wordlist(s), foo.help lists a glossary, or foo.edit opens the source in an editor.

Maybe I'm oversimpifying. Many OOP features are less important to supply in Forth because load order and CREATE DOES> provide much of their functionality already.

The primary use of OOP seems to be encapsulation, followed by its cousin polymorphism. Rather than adopt an OOP with hundreds of LOC, I might adopt one with tens of lines.

But that takes me back to Stephen's point that nobody can write OOP-based libraries because of the Babel of OOPs. I'm looking for one to emerge from the primordial soup. Something that doesn't eat up a lot of RAM in an embedded system, for starters.

-Brad

Hugh Aguilar

unread,
May 11, 2012, 5:02:17 AM5/11/12
to
On May 10, 5:04 pm, hwfw...@gmail.com wrote:
> I may have asked the wrong question. It's hard to evaluate the many OOPs out there. Maybe what I'm looking for is a sample problem that is solved in several dialects of OOP. That would provide some metrics.

Use this sample problem:
https://groups.google.com/group/comp.lang.forth/browse_thread/thread/dd8e30fcc7589749?hl=en#

That is a simple example of inheritance --- I have classes derived
from SEQ or SSEQ in there.

> I'm looking for one to emerge from the primordial soup. Something that doesn't eat up a lot of RAM in an embedded system, for starters.

Mine is crude, but it is very simple --- it would work on a micro-
controller with little RAM --- all you need is enough for a heap,
which could be as little as 4K.

Albert van der Horst

unread,
May 15, 2012, 6:32:48 AM5/15/12
to
In article <11255290.346.1336694692356.JavaMail.geo-discussion-forums@vbjb10>,
<hwf...@gmail.com> wrote:
<SNIP>
>
>Maybe I'm oversimpifying. Many OOP features are less important to supply in=
> Forth because load order and CREATE DOES> provide much of their functional=
>ity already.=20
>
>The primary use of OOP seems to be encapsulation, followed by its cousin po=
>lymorphism. Rather than adopt an OOP with hundreds of LOC, I might adopt on=
>e with tens of lines.
>
>But that takes me back to Stephen's point that nobody can write OOP-based l=
>ibraries because of the Babel of OOPs. I'm looking for one to emerge from t=
>he primordial soup. Something that doesn't eat up a lot of RAM in an embedd=
>ed system, for starters.

I'm still fond of my two screen OOP. It served me quite well in the
MANX (playing tunes on metallophones) and ciasdis projects.
Doesn't cost much resources.
It is certainly lightweight: 2 screens in ciforth.

>
>-Brad

Groetjes Albert
--
--
Albert van der Horst, UTRECHT,THE NETHERLANDS
Economic growth -- being exponential -- ultimately falters.
albert@spe&ar&c.xs4all.nl &=n http://home.hccnet.nl/a.w.m.van.der.horst

Doug Hoffman

unread,
May 15, 2012, 8:35:06 AM5/15/12
to
On 5/10/12 8:04 PM, hwf...@gmail.com wrote:

> I may have asked the wrong question. It's hard to evaluate the many
> OOPs out there. Maybe what I'm looking for is a sample problem that
> is solved in several dialects of OOP. That would provide some
> metrics.

It helps to know exactly what you want. Everyone seems to have their
own definition of what constitutes a minimum set of behaviors for object
programming.

> Having spent the day in C#, the object.method syntax is starting to
> grow on me.

> The primary use of OOP seems to be encapsulation, followed by its
> cousin polymorphism. Rather than adopt an OOP with hundreds of LOC, I
> might adopt one with tens of lines.

~40 lines or less? (compiles to 1652 bytes on Carbon MacForth)

-Doug


\ micro-FMS Douglas B. Hoffman 05/15/12 largely untested

\ Full encapsulation of data and methods.
\ Polymorphism with no restrictions on inheritance order.
\ Dynamic (late) binding of methods.
\ Duck typing.
\ Instantiate objects in the dictionary or the heap.

0 value self
0 value ^class
: dfa 1 cells + ;
: sfa 2 cells + ;
: wida 3 cells + ;
4 cells constant classSize
: find-method ( sel class -- xt)
begin @ dup while 2dup cell+ @ = if 2 cells + nip @ exit then
repeat throw ;
: execute-method ( o xt --) self >r swap to self execute r> to self ;
create object classSize here over allot swap erase
: set-search-order ^class >r get-order begin r@ wida @ swap 1+
r> sfa @ >r r@ object = until r> drop set-order ;
: :class ( "name" --) create ;
: <super ( -- wn..w1 n)
here to ^class classSize allot ' >body dup ^class classSize move
^class sfa ! get-order wordlist ^class wida ! set-search-order ;
: ;class ( wn..w1 n --) set-order ;
: send ( o sel --) over 1 cells - @ find-method execute-method ;
: selector ( "name" --) create does> send ;
: getselect ( -- sel) >in @ bl word find
if >body nip else drop >in ! selector here then ;
: :m ( "name" -- a xt) forth-wordlist set-current
getselect align ^class here over @ , swap ! , here 0 , :noname ;
: ;m ( a xt --) postpone ; swap ! ; immediate
: super ( "name" --) ' >body ^class sfa @ find-method compile, ; immediate
: (ivar) ( "name" -- a) create immediate ,
does> @ postpone literal postpone self postpone + ;
: bytes ( n "name" --) align ^class wida @ set-current
^class dfa @ (ivar) ^class dfa +! ;
: pre-obj ( ^class -- n class n+cell) dup dfa @ swap over cell+ ;
: post-obj ( n class o -- o) dup cell+ >r ! r@ swap erase r> ;
defer allotocate ( n+cell -- o)
: makeobj ( class -- o) pre-obj allotocate post-obj ;
: dict-allot ( n+cell -- o) align here swap ( n ) allot ;
: heap-allocate ( n+cell -- o) allocate throw ;
: make ( xt -- o) is allotocate ' >body state @
if postpone literal postpone makeobj else makeobj then ;
: dict> ( class --o) ['] dict-allot make ; immediate
: heap> ( class --o) ['] heap-allocate make ; immediate
: <free ( o --) 1 cells - free throw ;

\ examples

:class var <super object
1 cells bytes data
:m !: ( n -- ) data ! ;m
:m @: ( -- n ) data @ ;m
:m p: self @: . ;m \ print self
:m init: 5 self !: ;m
;class

dict> var value x
x init: ok
x p: 5 ok

heap> var value h
55 h !: ok
h p: 55 ok
h <free ok

:class var2 <super var
1 cells bytes data2
1 cells bytes data3
:m dump: data dup . @ . data2 dup . @ . data3 dup . @ p: ;m
:m init: super init: dict> var data3 ! ;m \ embed object in ivar
:m test: data3 @ p: ;m
;class

dict> var2 value v2

v2 init: ok

v2 dump:
16864328 5 16864332 0 16864336 0 ok

v2 test: 0 ok

Marcel Hendrix

unread,
May 15, 2012, 2:37:40 PM5/15/12
to
Doug Hoffman <glid...@gmail.com> writes Re: OOP packages

> On 5/10/12 8:04 PM, hwf...@gmail.com wrote:
[..]

> ~40 lines or less? (compiles to 1652 bytes on Carbon MacForth)

FORTH> include class.frt
5
55
19200624 5 19200632 0 19200640 0
0 ok
[9]FORTH> .s
Data: 5 55 16864328 5 16864332 0 16864336 0 0 ---
System: ---
Float: --- ok

I think this is correct, but why does the stack have copies
of each printed number?

(I could not fix the source myself in a reasonable amount of time).

-marcel

Doug Hoffman

unread,
May 15, 2012, 3:22:38 PM5/15/12
to
On 5/15/12 2:37 PM, Marcel Hendrix wrote:
> Doug Hoffman<glid...@gmail.com> writes Re: OOP packages
>
>> On 5/10/12 8:04 PM, hwf...@gmail.com wrote:
> [..]
>
>> ~40 lines or less? (compiles to 1652 bytes on Carbon MacForth)
>
> FORTH> include class.frt
> 5
> 55
> 19200624 5 19200632 0 19200640 0
> 0 ok
> [9]FORTH> .s
> Data: 5 55 16864328 5 16864332 0 16864336 0 0 ---
> System: ---
> Float: --- ok
>
> I think this is correct, but why does the stack have copies
> of each printed number?

Hence the meaning of "Largely untested".
Don't know. It runs fine and without the extra stack items on VFX
Forth, Gforth, SwiftForth, Alex's w32f, and Carbon MacForth. I just now
tried it on iForth and I can't even get it to compile. I'll take a look
at it. I expect it's something not serious. Thanks for the report.

Another question I have is does this get at the OP's issue?

-Doug

p.s. With this "minimalist" extension one has to be careful about
message names. For example if you already have a "dump:" defined for
something else then that will cause a bug. Easy to fix with more lines
of code, which the OP was wanting to avoid.

Doug Hoffman

unread,
May 15, 2012, 9:50:24 PM5/15/12
to
On 5/15/12 2:37 PM, Marcel Hendrix wrote:
try replacing the one DEFER word with a value, then change the two other
definitions affected (changes in UPPER CASE):

0 VALUE allotocate
: makeobj ( class -- o) pre-obj allotocate EXECUTE post-obj ;
: make ( xt -- o) TO allotocate ' >body state @
if postpone literal postpone makeobj else makeobj then ;

This then compiled and ran fine for me on my version of iForth, no
extraneous stack items.

-Doug

Marcel Hendrix

unread,
May 17, 2012, 2:11:38 AM5/17/12
to
Doug Hoffman <glid...@gmail.com> wrote Re: OOP packages

> On 5/15/12 2:37 PM, Marcel Hendrix wrote:
>> Doug Hoffman<glid...@gmail.com> writes Re: OOP packages
[..]

> try replacing the one DEFER word with a value, then change the two other
> definitions affected (changes in UPPER CASE):

> 0 VALUE allotocate
> : makeobj ( class -- o) pre-obj allotocate EXECUTE post-obj ;
> : make ( xt -- o) TO allotocate ' >body state @
> if postpone literal postpone makeobj else makeobj then ;

> This then compiled and ran fine for me on my version of iForth, no
> extraneous stack items.

Actually, only one change is necessary: iForth's compiled IS is
written as [IS], like this:

: make ( xt -- o) [is] allotocate ' >body state @
if postpone literal postpone makeobj else makeobj then ;

The problem with the extra stack items was my test:
it was based on insufficient understanding of your code. I should
not have pasted the output of your posting verbatim.

\ Original (wrong) test
dict> var value x
x .s init: \ ok
cr x p: 5 \ ok

\ New test
dict> var value x
x .s init: \ ok
cr x p: \ 5 ok

Sorry about that.

Conclusion: This OOP package works on all major Forths with only
a single cosmetic (is DEFER standard already?) change.

-marcel

Doug Hoffman

unread,
May 17, 2012, 8:55:02 AM5/17/12
to
On 5/17/12 2:11 AM, Marcel Hendrix wrote:


> Actually, only one change is necessary: iForth's compiled IS is
> written as [IS], like this:

I don't see [IS] in the standard or a restriction on using IS in
compilation. Maybe I'm using the wrong reference: forth11-1.pdf.

> Conclusion: This OOP package works on all major Forths with only
> a single cosmetic (is DEFER standard already?) change.

I do see DEFER in the standard, at least in the same reference as above.

-Doug

p.s. micro-FMS is now down to about ~30 lines of code

Peter Knaggs

unread,
May 17, 2012, 2:31:24 PM5/17/12
to
Marcel Hendrix wrote:
>
> Conclusion: This OOP package works on all major Forths with only
> a single cosmetic (is DEFER standard already?) change.

DEFER (and IS) was one of the first proposals to be accepted into
the 200x standard way back in 2005.

--
Peter Knaggs

Hugh Aguilar

unread,
May 18, 2012, 12:59:59 AM5/18/12
to
In my novice package I provide DEFER and IS because they are
traditional.

I also provide VECTOR which is much more efficient.

digital.w...@googlemail.com

unread,
May 18, 2012, 4:51:33 AM5/18/12
to
Is there a more recent comparison of object oriented packages than Brad Rodriguez's survey?

http://www.bradrodriguez.com/papers/oofs.htm

Thanks,

John

Gerry Jackson

unread,
May 22, 2012, 3:39:56 AM5/22/12
to
Are you going to post the code for this slimmed down micro-FMS? I'm
interested in seeing it.

--
Gerry

Doug Hoffman

unread,
May 22, 2012, 7:02:03 AM5/22/12
to
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: .



Gerry Jackson

unread,
May 22, 2012, 8:14:53 AM5/22/12
to
On 22/05/2012 12:02, Doug Hoffman wrote:
> 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.
>

[...]

Thanks, I'll have a detailed look at it.

--
Gerry

Coos Haak

unread,
May 22, 2012, 12:11:41 PM5/22/12
to
Op Tue, 22 May 2012 07:02:03 -0400 schreef Doug Hoffman:

<snip>
> \ 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 ;

Why this not working (0) THROW ? Do you mean DROP THROW ?


--
Coos

CHForth, 16 bit DOS applications
http://home.hccnet.nl/j.j.haak/forth.html

Doug Hoffman

unread,
May 22, 2012, 2:23:16 PM5/22/12
to
On 5/22/12 12:11 PM, Coos Haak wrote:
> Op Tue, 22 May 2012 07:02:03 -0400 schreef Doug Hoffman:
>
> <snip>
>> \ 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 ;
>
> Why this not working (0) THROW ? Do you mean DROP THROW ?

You should only get to the throw on an error condition (message not found).

Does the code run without error as received?

If not, does your Forth have any already-defined words that conflict
with any of the message names ( !: +: @: p: init: etc.)? If so, then
you must force the redefinition by using, e.g., "selector !:" prior to
the class definition.

-Doug

Coos Haak

unread,
May 23, 2012, 1:47:18 PM5/23/12
to
Op Tue, 22 May 2012 14:23:16 -0400 schreef Doug Hoffman:

> On 5/22/12 12:11 PM, Coos Haak wrote:
>> Op Tue, 22 May 2012 07:02:03 -0400 schreef Doug Hoffman:
>>
>> <snip>
>>> \ 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 ;
>>
>> Why this not working (0) THROW ? Do you mean DROP THROW ?
>
> You should only get to the throw on an error condition (message not found).
>
> Does the code run without error as received?

Your definition is like this
: fm ( sel class -- xt ) begin @ dup while <left out success> repeat throw ;
When '@ DUP' detects a zero, WHILE jumps to after REPEAT and THROW finds a
zero, so nothing happens and sel is left on the stack

: fm begin @ dup while <..> repeat drop throw ; would work
: fm begin @ ?dup while <..> repeat throw ; would work too.

Doug Hoffman

unread,
May 23, 2012, 2:58:34 PM5/23/12
to
On 5/23/12 1:47 PM, Coos Haak wrote:

> Your definition is like this
> : fm ( sel class -- xt ) begin @ dup while<left out success> repeat throw ;
> When '@ DUP' detects a zero, WHILE jumps to after REPEAT and THROW finds a
> zero, so nothing happens and sel is left on the stack
>
> : fm begin @ dup while<..> repeat drop throw ; would work
> : fm begin @ ?dup while<..> repeat throw ; would work too.

You're right. Either of the above would be better.

Thank you.

-Doug


Doug Hoffman

unread,
May 31, 2012, 7:43:01 AM5/31/12
to
Re: microFMS

It's now down to about 1200 bytes on Carbon MacForth and under 30 lines
of code. Provides fast dynamic binding and more examples.

http://soton.mpeforth.com/flag/fms/microFMS.f

-Doug

0 new messages