ForthLanguage provides low-level access to control flow and memory access primitives, making it easy to create an
ObjectOriented Forth (OOF). Dozens of implementations exist which explore many different object concepts.
One of the best OOFs (in the C++/Java style) is available at
http://www.complang.tuwien.ac.at/forth/objects/ (see objects.html for the manual). In under 20K of heavily commented Forth code it implements:
- Extensible data structures
- Early (compile-time) and late (virtual) method lookup
- Public and protected methods and variables
- Constructors
- Single inheritance
- Interfaces (a class can implement multiple interfaces)
Other popular OOFs implement a
SmallTalk style of method lookup at runtime, and some OOFs are just plain strange (smile, DREAMS).
For a simpler example, here is the
complete implementation of "HYPE", a simple OOF using standard
AnsForth. See
http://home.netsurf.de/helge.horch/hype.html for more information on HYPE.
: LIT, ( x) POSTPONE LITERAL ;
: >SIZE ( ta - n) CELL+ @ ;
0 VALUE SELF
: SELF+ ( n - a) SELF + ;
: SEND ( a xt) SELF >R SWAP TO SELF EXECUTE R> TO SELF ;
VARIABLE CLS ( contains ta)
: SIZE^ ( - aa) CLS @ ?DUP 0= ABORT" scope?" CELL+ ;
: MFIND ( ta ca u - xt n) 2>R BEGIN DUP WHILE DUP @ 2R@ ROT
SEARCH-WORDLIST ?DUP IF ROT DROP 2R> 2DROP EXIT THEN
CELL+ CELL+ @ REPEAT -1 ABORT" can't?" ;
: SEND' ( a ta "m ") BL WORD COUNT MFIND 0< STATE @ AND
IF SWAP LIT, LIT, POSTPONE SEND ELSE SEND THEN ;
: SUPER ( "m ") SIZE^ CELL+ @ BL WORD COUNT MFIND 0>
IF EXECUTE ELSE COMPILE, THEN ; IMMEDIATE
: DEFS ( n "f ") CREATE SIZE^ @ , SIZE^ +! IMMEDIATE
DOES> @ STATE @ IF LIT, POSTPONE SELF+ ELSE SELF+ THEN ;
: METHODS ( ta) DUP CLS ! @ DUP SET-CURRENT
>R GET-ORDER R> SWAP 1+ SET-ORDER ; ( ALSO CONTEXT !)
: CLASS ( "c ") CREATE HERE 0 , 0 , 0 ,
WORDLIST OVER ! METHODS ;
: SUBCLASS ( ta "c ") CLASS SIZE^ OVER >SIZE OVER ! CELL+ ! ;
: END ( ) SIZE^ DROP PREVIOUS DEFINITIONS 0 CLS ! ;
: NEW ( ta "name ") CREATE DUP , >SIZE ALLOT IMMEDIATE
DOES> DUP CELL+ SWAP @ SEND' ;
Notes:
- This code implements classes and subclasses, with public methods and instance variables.
- This is one of the simplest object-oriented Forths that is reasonably usable. The code is not pretty, but it is standard, compact, and reasonably well-factored.
- The programmer is not SHOUTING--uppercase is required for *strict* AnsForth compliance. (Lowercase letter support is common, but optional.)
- HYPE compiles into less than 2K of code on almost any Forth (1147 bytes on Win32Forth). On several platforms it would use less than 500 bytes.
Given the code above, a Forth programmer can write code like:
: VAR 1 CELLS DEFS ; \ Helper for creating instance vars
CLASS BUTTON
VAR TEXT
VAR LEN
VAR X
VAR Y
: DRAW ( )
X @ Y @ AT-XY \ Get X and Y, and position cursor on screen
TEXT @ LEN @ TYPE ; \ Get TEXT and LENgth, and type it
: INIT ( ca u) 0 X ! 0 Y ! LEN ! TEXT ! ;
END
: BOLD 27 EMIT ." [1m" ; \ Emit code to turn on BOLD TEXT
: NORMAL 27 EMIT ." [0m" ; \ Emit code to return to normal text
BUTTON SUBCLASS BOLD-BUTTON
: DRAW ( ) BOLD SUPER DRAW NORMAL ;
END
...which could be used like:
BUTTON NEW FOO \ creates new button "FOO"
S" thin foo" FOO INIT \ calls init method on FOO with string arg.
PAGE \ clear the screen
FOO DRAW \ draw FOO
BOLD-BUTTON NEW BAR \ create new bold-button
S" fat bar" BAR INIT \ initialize
1 BAR Y ! \ change the Y instance variable
BAR DRAW \ draw the BAR button
The preceding object system is an example of an
object method syntax. The default object system in
NeonLanguage,
MopsLanguage, and Win32Forth instead uses a
method: object syntax.
:class Point <super Object
int x
int y
:m ClassInit: ( -- )
ClassInit: super
0 to x 0 to y
;m
:m set-xy: ( x y -- ) to y to x ;m
:m show: ( -- ) ." ( " x . y . ." )" ;m
;class
Point pt
2 3 set-xy: pt
show: pt \ ( 2 3 )
See also:
NeonLanguage MopsLanguage,
NeonAndYerkAsStackBasedOo
CategoryForth