Hi all, let me continue to try to convert you :
These are four words in FORTH
that make this langage worth
These four words are actually two pairs :
CREATE ... DOES>
and
VOCABULARY --- DEFINITIONS
With these four words, I tried to show some posts above how it would be easy to make FORTH look like an object oriented environment (and remember that FORTH was invented in the early seventies !).
I will show you next an example, where I use this very simple addition to FORTH to define a CLASS 3D for three dimensionnal vectors that could be readily used to code in an object oriented way the perspective algorithm that I showed you here :
viewtopic.php?f=3&t=3238&hilit=forth&start=10#p33721
Here, the complete code to LOAD_FILE with SupperForth (as SupperForth has some strange omissions, I had to first add three words) :
Code: Select all
CR .( Three words needed to complement SupperFORTH )
CR .( mixed multiplication : two 16 bits operands 32 bits result )
: M* ( n1,n2 --- d ) 1 OVER 0< IF NEGATE SWAP NEGATE ELSE SWAP THEN >R
OVER 0< IF NEGATE SWAP NEGATE ELSE SWAP THEN R>
UM* ROT 0< IF DNEGATE THEN ;
CR .( mixed division 32 bits divident 16 bits divisor 16 bits result )
: M/ ( d1,n2 --- n ) 1 OVER 0< IF NEGATE SWAP NEGATE ELSE SWAP THEN >R
OVER 0< IF NEGATE ROT ROT DNEGATE ELSE ROT ROT THEN R>
UM/MOD SWAP DROP SWAP 0< IF 1+ NEGATE THEN ;
CR .( mixed square root : 32 bits operand 16 bits result )
: MSQRT ( d --- n,p | d = p*p + n ) 2DUP OR IF -32768 BEGIN
DUP >R DUP M* 2OVER D- R@ UM/MOD SWAP DROP 2/ R> SWAP
?DUP WHILE - REPEAT 1- >R R@ R@ M* D- DROP R> THEN ;
CR .( Words to implement object oriented programming in FORTH )
: NEW ; ( NOOP word for NEW in FORTH context )
: A_CLASS , ;
: AN_INSTANCE @ , ;
: METHOD DUP @ EXECUTE ;
: INSTANCE CREATE AN_INSTANCE DOES> METHOD ;
: CLASS CREATE A_CLASS DOES> INSTANCE ;
CR .( Example CLASS of 3D vectors )
CR .( 3D> is the VOCABULARY of the METHODs )
CR .( 3D is the name of the CLASS )
VOCABULARY 3D> ' 3D> CLASS 3D
3D> DEFINITIONS
CR .( After creating these two words, let's implement the METHODs )
CR .( first : NEW for intalling an INSTANCE - for 3D, just ALLOT 6 bytes )
: NEW 6 ALLOT DROP ;
CR .( some unary methods : ! and @ like for 16 bits scalars and X Y Z )
: ! ( x,y,z,V --- ) DUP >R 6 + ! R@ 4 + ! R> 2+ ! ;
: X ( V --- x ) 2+ @ ;
: Y ( V --- y ) 4 + @ ;
: Z ( V --- z ) 6 + @ ;
: @ ( V --- x,y,z ) 2+ DUP @ OVER 2+ @ ROT 4 + @ ;
CR .( some binary methods : )
CR .( add two vectors : overloads scalar addition )
: + ( V,V --- V ) OVER >R @ 3 ROLL @ 3 ROLL + >R ROT + >R + R> R> R@ ! R> ;
CR .( substract two vectors : overloads scalar substraction )
: - ( V,V --- V ) OVER >R @ 3 ROLL @ 3 ROLL - >R ROT - >R SWAP - R> R> R@ ! R> ;
CR .( scaled scalar product of two vectors )
: // ( V,V,s --- scalar prpduct / s ) >R SWAP @ 3 ROLL @
3 ROLL M* 2SWAP 4 ROLL M* ROT 5 ROLL M* D+ D+ R> M/ ;
CR .( scaled vector product of two vectors : overloads */ for scalars )
: */ ( V,V,s --- vector product / s ) 2 PICK >R >R SWAP @ 3 ROLL @
4 PICK OVER M* 3 PICK 6 PICK M* D- R@ M/
4 ROLL 4 PICK M* 3 ROLL 7 PICK M* D- R@ M/
5 ROLL 3 ROLL M* 4 ROLL 5 ROLL M* D- R> M/ R@ ! R> ;
CR .( modulus of a vector )
: || @ DUP M* ROT DUP M* D+ ROT DUP M* D+ MSQRT SWAP DROP ;
CR END_FILE
So, let's use this new tool :
to define an instance of class 3D, type
3D V1
and to initialise its memory space
V1 NEW
then, to put three 16 bits numbers into it :
3000 4000 0 V1 !
to instanciate another 3D you may type all this in the same sentence
3D V2 V2 NEW 0 0 1000 V2 !
You see in the code listing that you can
- add two 3D ; the result is a 3D that replaces the first one (like when you add with FORTH two numbers ; the result takes the place in the stack of the first one).
- substract two 3D ; same punishment as for +
- do the scalar product of two 3D : the result is a 16 bit number
- do the vector product of two 3D : the result is a 3D
BUT these two words adopt the same semantics as the FORTH */ word : that mutliplies two 16bit numbers but divive the 32bit result by a 16bit scale factor to get a result not overflowing.
- finally computing the modulus of a 3D, which is a 16bit positive number.
So let's play with the two instances V1 and V2 that we created :
V1 and V2 are orthogonal, so their scalar product // should be 0 ; but note the mandatory scale factor (to choose for the product not to overflow) !
V1 V2 1000 // .
0 ok
the vector product of a 3D by itself (or by a parallel 3D) is a null 3D ; the scale factor is also mandatory !
V2 V2 1000 */ @ . . .
0 0 0 ok
the two X and Y components of V1 draw a famous Pythagorean triangle, thus its modulus should be the lenght of its hypothenuse :
V1 || .
5000 ok
As you can notice, the object oriented syntax of FORTH is not quite the usual.
Usually you will code :
V1.ADD(V2) [ <instance>.<method>(<parameters>) ]
In object oriented FORTH you type :
V1 V2 + [ <instance> <parmeters> <method> ]
No need of a dot and no parentheses ; the + method has the same syntax as with numbers.
To be followed be recoding PERSPECTIVE FORTH object oriented wise ?
BYE, POLKA
and to compare with object oriented Free Pascal examples above ?