Skip to main content

Some dozens make a long dozen,
but they won't make  thirteen.  
          Some wise guy


                        STRENGTH IN FORTH

                           part twelve

                EXTENDED REMARKS ON ELEVEN PARTS

I  decided  to give part twelve of this  FORTH-course  the  above 
title after many deliberations.  I thought it was getting time to 
give you an overall view on the FORTH-system.  That means we have 
to  put things together,  which have been scattered all over  the 
course  and we have to explain things we left in the darkness  of 
'coming  soon'.  This time we are going to discuss three  smaller 
subjects: a) how a FORTH-system could look like; b) how a word is 
placed in the dictionary and c) how it is searched for. I hope, I 
can  manage to put it all into a First Word file of 32K.  At  the 
end of this part you will find the solutions to part eleven,  but 
there will not be any new exercises, as the  subject of this part 
isn't fit for it.
 
FORTH IN DISGUISH
            
It may have occurred to you,  that FORTH has many faces, although 
you   will  recognise a FORTH-system at the moment you  see  one. 
What I do not mean with the word "system" here,  is what could be 
better described as the "package" you get when you buy a FORTH or 
when  you  get one of the many FORTHs,  available in  the  Public 
Domain.  In  this last department - as far as I know - are  three 
FORTH-packages  which  use a 16-bit  stack.  Those  are  COMFORTH 
(september-87-version),VOLKSFORTH  vs  3.8  and  ST-FORTH.  There 
happens  to be only one PD-FORTH which uses 32-bit  stacks.  This 
FORTH  is called UNIX-FORTH-83.  It is not available in  any  PD-
library in the Kingdom of The Netherlands.  This is due, I think, 
to   the fact  that three files of the version  which  circulates 
among  ST-owners,  are irrepairably damaged.  These files can  be 
well  left  out  and  yet you will  have  a  perfectly  operating 
FORTH. One of my FORTH pen-diskfriends - I don't own a modem - is 
constantly  working to enrich this UNIX-FORTH with new items. The 
other day he has develloped a marvelous editor and he now is busy 
all  day   programming a GEM-library.  This 32-bit FORTH  can  be 
obtained  by modem-owners through the BBS ST HAARLEM  phone  023-
340077.   In the commercial war-zone there is a fight between  at 
least  one (1 !) 16-bit and two (2 !) 32-bit  FORTHs,  which  are 
called ST-FORTH - same name as the one PD - 32-FORTH and  4*FORTH 
respectivily. All FORTHs mentioned here are  very well documented 
except  for  the UNIX-FORTH.  But I am working to  overcome  this 
shortcomings. I've just finished a Glossary of all the words used 
in the Kernel.  This Glossary contains a description - in  ASCII-
order  - of the stackaction,  the name of the word,  the use  and 
further  details of all( minus 6) Kernel words.  As soon as  I've 
completed this huge task by adding all user-words of the Utility- 
and Assembler-files,  you will hear from me. I will - of course - 
see to it,  that this Glossary will be PD.  Soon there will be  a 
pre-release  to give some smarter guys than me an opportunity  to 
comment to that Glossary.   It must be said,  that a FORTH with a 
32-bit stack does not quite match the  83-Standard.  I think it a 
minor  difference  for the user.  Instead of using  the  optional 
Double  Number Set in the 16-bit configuration to  handle  larger 
numbers (larger than 16 bit can hold),  the 32-bit FORTH provides 
facilities to meet with explicit 16-bit values. So, it is in some 
respect the other way round.  All these FORTHs provide a Kernel - 
the naked system - some editing facilities and an Assembler.  And 
often  much  more !!  But we are not really interested  in  these 
elements.  Here and now I will link your attention on the  memory 
allocation  of FORTH when the system has been installed  in  your 
ST.  I will not mention absolute memory-addresses,  as these  may 
vary widely,  depending on the system in use, nor is it to you to 
take the given description as a  prescription to which a FORTH is 
pinned down.  At the end of my description of a  FORTH-system,  I 
hope  you'll be able to 'decode' any FORTH in  the  future.

AT L(E)AST: SOME ART !

First of all I'll better draw a memory-allocation map of a FORTH-
system,  based  on  UNIX-FORTH-83.  Just for illustrating  a  few 
points, eh !!

    ?                                     ?
   /|\                                   /|\
    |              video ram              |
 _____________________________________________
|                                             |
|                 Free Memory                 |
|   ^                                     ^   |
|¯¯¯v¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯v¯¯¯|
|________^____________Pad____________^________| 
|        v                           v        |
|                                             |
|        ^            Here           ^        |
|¯¯¯¯¯¯¯¯v¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯v¯¯¯¯¯¯¯¯|
|                                             |
|           Applications Dictionary           |
|¯ ¯ ¯ ¯ ¯ ¯ ¯ ¯ ¯ ¯ ¯ ¯ ¯ ¯ ¯ ¯ ¯ ¯ ¯ ¯ ¯ ¯ ¯|
|===================Fence=====================|
|                                             |
|              Kernel or Nucleus              |       
|                 Dictionary                  |
|                                             |
|___________________Origin____________________|
|                                             |
|                                             |
|_up0___^___________User Area_________^___up0_|
| rp0   v          Return Stack       v   rp0 |
|                                             |
|                                             |
|_'tib__^_______________Tib___________^__'tib_|
| sp0   v         Parameter Stack     v   sp0 |
|                                             |
|                                             |
|                                             | 
|                                             |
|_______________Next_Free_Memory______________|
|      v                               v      |
|                  Free Memory                |
|                                             |
|_____________________________________________|
|       |                             |       |
|       v          Used by GEM        v       | 
|                                             |
|                                             |    

I told you once, I could do some nice painting....Well....?!
To give you an idea about the amount of space my configuration of 
this UNIX-FORTH uses to settle down,  imagine HERE is at  address 
427152,  ORIGIN at 327680 and SP0 at 326684.  The v- and  ^-signs 
are to be considered as arrows, maybe  pointing up,  maybe  down. 
Let's  begin  where each carreer  starts....at  the  bottom.  And 
secondly,  let's give GEM,  what it belongs:  the memory-space in 
the deep dungeons of your ST.  All memory up to Next-Free-Memory, 
not  used  by GEM,  may be used by you.  Climbing up  our  Social 
Memory  Staircase we arrive at Parameter Stack and Tib.  On  both 
sides of these words are sp0 and 'tib.  If we should  investigate 
these  two  little  words,  which we will,  we  are  to  discover 
something strange.  Both words are user-variables. They hold some 
value,  where variables are made for, and they both hold the same 
value. That value is a memory-address. This address now indicates 
the  start of the Parameter Stack (hold by sp0),  the so   called 
bottom of the stack,  and the start of the Terminal Input  Buffer 
(hold by 'tib) as well.  As you can see the arrows point down  in 
the stack area and up in the buffer area. The meaning of this is, 
that  putting  values on the stack will cause the stack  to  grow 
downwards.  Every  next value is put at a lower address than  its 
predecessor. This movement is closely watched by another pointer-
word {SP@).  We used this word in one of the first issues of this 
course.   It  will  print  the  address  of  the  next  available 
stackspace,  when used as {SP@} {.}.  If we were able to increase 
the pointer, held in {SP@}, FORTH would think that the next value 
was  to  be put at that higher address and  would  overwrite  the 
value already there.  Putting values onto the stack and  DROPping 
them  again  is made possible by increasing  and  decreasing  the 
address held in that Stack Pointer.  So,  if you get the  message 
Stack  Empty,  then  it is not to inform you that  there  are  no 
values in the address space of the Parameter Stack,  but to  tell 
you that the Stack Pointer points to the bottom of the stack.  In 
the case of the Terminal Input Buffer  the terminal input  starts 
at the bottom,  called Tib and moves upwards. This buffer is only 
a minor one.  Mostly it is as large as 80 bytes.  Still higher we 
see a similar situation.  This time the Return Stack and the User 
Area  are involved.  The functions of the Return Stack have  been 
explained  earlier.  As  you can see it grows downward  to  lower 
memory-addresses.  Starting at up0 and moving to higher memory is 
the User-Area. Here live those mysterious user-variables. Now the 
time  has come to throw some light on those  peculiar  creatures, 
which  you  met  frequently,   but  which  I  nevertheless   left 
unexplained.  A user-variable is a system variable.  This  means, 
that the value linked to such a variable - a number or an address 
- is of high importance for the welfare of the system. Many user-
variables  are initialised on a cold start of  the  FORTH-system, 
and  should  not  be  used for plain  variables  in  an  ordinary 
application. Only if you intend to make system modifications, you 
are  allowed to modify user-variables or to create new  ones.  It 
should be perfectly clear,  that user-variables are  specifically 
not  intended to be used and certainly not by the user  In  UNIX-
FORTH  the  User  Area is exactly 1024  bytes  high.  That  means 
whereas for a 32-bit FORTH every value counts 4 bytes,  that  256 
different  user-variables can be hold in this  residence.  That's 
fair enough !   Let's look still closer by creating a fancy user-
variable.  We  need the word {NUSER}.  100 {NUSER} IPL  OK  .  We 
created  a new word {IPL}.  So {NUSER} is a  defining  word.  Two 
things  happened.  First:  the name of the new user-variable  was 
placed  in the DICTIONARY as usual. Secondly: space was allocated 
(4 bytes),  in a separate User Area,  in which the value of {IPL} 
will  have to be stored at a later date.  This value will not  be 
100,  as you might have expected.  It could be 100,  but it  will 
never be that 100 we used to define the variable {IPL}.  That 100 
is an offset. Hundred times 4 bytes are added to the address held 
in  {UP0}  - the start of the User Area - and then  4  bytes  are 
allocated  to  hold the value of {IPL}.  This last value  is  not 
initialised.  If you execute {IPL},  you will get the address  in 
the User Area in which is stored the value of {IPL}. If you {IPL} 
{?},  then  the  value  at {IPL}'s address in the  User  Area  is 
displayed  at  your screen.  At this moment it can  be  anything. 
It  is not said,  that your system provides the word  {NUSER}.  I 
used it from that UNIX-FORTH.  Two more additional words  may  be 
used  to  define  a user-variable  in  that  system:  {USER}  and 
{TUSER}.  The  basic  word is {USER}.  {NUSER}  and  {TUSER}  are 
basically equivalent,  but their names are chosen merely for  the 
sake of easy understanding. To get the same result with {USER} as 
with  {NUSER} I should have entered 100 {4*} {USER} IPL.  May  be 
that  100 {USER} IPL will do in other systems.  Some very  common 
user-variables are:

 Name  |  contains             Name | contains
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
UP0     start of User Area     SP0     start of parameter stack
RP0     start of return stack  DP      first free dictionary byte
FENCE   barrier for forgetting CONTEXT vocabulary searched first
CURRENT voc for definitions    STATE   compile or interprete ?
BASE    for numeric in- output DPL     numeric input punctuation
LAST    nfa of latest def.     HLD     points to last char in PAD

and there are several more.

ABOUT STATIONS AND BARRIERS..AND SOME SCRATCHING !

The  next  station  we  will visit on our  race  to  the  top  is 
{ORIGIN}. Here is the start of the Kernel, the Nucleus, the Root. 
All  addresses in a FORTH-system are derived from {ORIGIN}, which 
on  execution  gives  the address of  the  beginning  of  FORTH's 
precompiled portion of the dictionary.  Going up we meet {FENCE}. 
As  you just saw,  {FENCE} is a user-variable.  Its value  is  an 
address between {ORIGIN} and {HERE},  between start and finish of 
all the code compiled in the dictionary,  the Root as well as the 
applications' part.  This address acts like a barrier.  When  you 
instruct {FORGET} to forget a word,  {FORGET} will do the job, if 
it can find that word between {FENCE} and {HERE}.  If the word to 
{FORGET} is situated beneath {FENCE}, there will be a message and 
the system will {ABORT}. The dictionary part between {ORIGIN} and 
{FENCE}  is a restricted area for {FORGET}.  You may  change  the 
barrier-address in {FENCE} to a higher or a lower address: {HERE} 
{FENCE} {!} will store the address of the first free space in the 
dictionary in {FENCE}. As long as you will be programming in this 
new configuration,  only the words you will enter afterwards, can 
be forgotten.  This method is recommended if you want to add some 
application  to the dictionary for good.  In this case  you  will 
have to save this configuration to disk,  of course. Most systems 
provide words to do so:  {SAVE-SYSTEM} or the like. Of course you 
can  act  like this:  {ORIGIN} {FENCE} {!} OK and  then  {FORGET} 
{ORIGIN} OK.  It won't harm anybody personally,  except you !  If 
you  fully  back-upped your system,  then you  may  recover  your 
FORTH.  Otherwise  you are through and done !!   As you can  see, 
{HERE} fluctuates.  It can go up, it can go down on the rhythm of 
adding to and deleting words from the dictionary. And with {HERE} 
{PAD}  moves  up and down in the same  rhythm.  {PAD}  is  simply 
defined  as :  PAD   HERE 50 + ;  in this  UNIX-FORTH.  {PAD}  is 
really a scratch-pad.  It allows two different kinds of  use.  It 
may be used as a scratch-pad for numeric output conversion.  As a 
numeric pad {PAD} stores its data downwards. If the scratching is 
done with text,  then {PAD} stores the data upwards.  The  FORTH-
dictionary  may grow until the end of 'normal' memory is  reached 
and  the video-ram begins.  How much room there is left for  your 
own applications depends on the system you use.  ( And the  Atari 
you can afford !!)
 
FORTH DID IT HIS WAY

The second item we were to discuss in this issue, was the item of 
how  FORTH  places  a  word in  the  dictionary.  I've  told  you 
something about it,  but not those very intimate details.  So  if 
you are over eightteen,  keep on reading,  otherwise ask your dad 
or mum. First lesson: every FORTH has his own way ! I told you so 
in  part  10 of this course.  Then we were  discussing  the  word 
{MBUF}.  So look back and read it again.  It was said there, that 
my magnificent 1STWORD-drawing of an dictionary-entry was not the 
one and only permitted.  Several differently constructed  entry's 
are  possible.  But there are always a number of  elements  which 
can't  be  left  out  in any entry.  Every word  has  to  have  a 
christian  name.  Christianed  or not.  Some  FORTH's  have  some 
limitations on the length of the name:  a maximum of 4 characters 
e.g.  Others don't care what length, as long as a particular name 
doesn't  exceed 31 characters.  Some of those  will place only  a 
limited amount of that 31 characters in the NAMEFIELD, others are 
more  tolerant and will take them all 31.  So there has to  be  a 
namefield. The startaddress of this field is shorthened to {NFA}. 
In  this namefield the first byte helds the number of  characters 
stored in the namefield. Secondly there has to be PARAMETERFIELD, 
even  if  it  hasn't  been initialised.  In this  field  data  is 
stored.  The startingaddress of this area is shortened to  {PFA}. 
The  data  in the parameterfield can be a number ( all  data  are 
numbers of course,  but I mean a real number,  a value),  or they 
can  be addresses.  The third field is  called  LINKFIELD.  {LFA} 
stands for the startaddress of this field.  For the simple-minded 
Dutch: not only is it  a field that by means of an address stored 
in  that  place links the whole dictionary together,  but  it  is 
really  a "link" (for simple-minded English-speaking  "tricky"  ) 
field.  More later !! The fourth (beautiful word !!) field is the 
CODEFIELD  or COMPILATIONFIELD.  I prefer  codefield,  because  I 
can't type very fast.  The short form for the startingaddress  of 
the codefield is {CFA}.  This field holds a pointer to the  start 
of  some  code.  To  what code depends  on  the  action,  that  a 
particular  word has to perform.  Don't think that a  computer  - 
even loaded with FORTH -  has a basketful of such codes: NO ! 
FORTH  has some words to switch from namefield to  linkfield  and 
from  codefield to parameterfield etc.  A list is to be found  at 
SUMMARY.

This  four  fields are used to make a word and  with  many  words 
together a dictionary in each FORTH. In the middle of two fields, 
or in the front of all four,  or at the  back will be inserted  a 
byte !  In this byte resides the immediate bit,  or not,  if  the 
word is not immediate.  Which bit will be honoured with this task 
is  of no importance.(For instance in that UNIX-FORTH it  is  the 
sixth  one,  but  it  could  as  well  have  been  the  fifth  ). 
Principally it is of no importance either,  in which order  those 
four fields are grouped. In the WYCOVE-FORTH the linkfield is the 
second  one after the namefield has been set up,  as it  is  FIG-
FORTH.  In UNIX-FORTH the linkfield is the first field,  standing 
in front of the namefield.  So we have a name,  data and specific 
code which can handle the data.  As I said the most tricky  field 
is the linkfield.  This field 'chains' the dictionary. But not in 
the way you thought it would do. Suppose our dictionary has grown 
to  some  extend  of 1000 words and we  want  a  particular  word 
executed. So
 
{."} Linkfield {"} Linkfield OK

will  print out at your screen "Linkfield".  It was done  by  the 
word {."}.  Before FORTH can execute that word, FORTH has to look 
it  up in the dictionary.  And FORTH has to find the right  word, 
not some ' this will also do'-word.  So FORTH has to  investigate 
the  whole dictionary,  if a word happens to be deep  in  FORTH's 
dungeons ?? NO !! Perhaps you would, FORTH won't. In this respect 
FORTH is a junk,  he uses HASH.  This HASH-function is that  very 
tricky  way in which FORTH succeeds to minimalise the  amount  of 
dictionary-words  to find its way through,  to come to the  right 
desired  word  and  that beyond any  doubt.  It  depends  on  the 
'depth' of the HASH-function,  but at any 'depth' it will save an 
enormous  amount  of searching in the dictionary and  thus  time, 
time and time again.  Simply said,  the hash-function divides all 
words  that will be entered in the dictionary  into  groups.  How 
many groups depends.  My lovely UNIX-FORTH has four groups, but a 
FORTH like 4*FORTH has some 16 (!).  The forming of the groups is 
simply  done by looking at the first character of the  word.  And 
{HASH} - in UNIX-FORTH - is a normal word. Or should better I say 
spell ?

THE SECRET YOU SHARE WITH HASH

Problably  the  supersonic  speed at  which  FORTH  searches  the 
dictionary for a particular word,   have struck you.  Partly it's 
the language's speed itself. For a (much greater) part it is - as 
I described above - the {HASH}-trick that does it. This trick has 
a  double  effect.  At  first it works when  you  enter  a  word, 
afterwards - when there is a search for a word - it makes use  of 
the  information  that  {HASH}  provided  and  that  was   stored 
in.....the LINKFIELD !!    The dictionary is not really a  simple 
chain  of  words,  one after another as they have  been  entered. 
Actually the dictionary is splitted up in vocabularies ( See part 
11).  A  vocabulary consists of a group of words that for some  - 
most logical - criterion has been brought together:  the  Editor, 
the Assembler.  But such a vocabulary itself isn't a compact list 
of all the words belonging to itself too.
Vocabularies can be into  two very different states. A vocabulary 
can be the {CONTEXT} vocabulary.  That means that the search  for 
words  starts  in  this  vocabulary.   As  all  vocabularies  are 
connected  - similar as the words are linked -,  a search  for  a 
word will continue in the next linked vocabulary, if a word can't 
be found in the {CONTEXT} vocabulary.  In the other situation the 
vocabulary   is  indicated  as {CURRENT}.   It  means  that   new 
definitions  are placed in that vocabulary.  And as we  mentioned 
above, at the creation of new entries {HASH} gets  the lead.

A TRICKY PART
  
So let's reveal {HASH}'s secret in the UNIX-FORTH. Assuming, that 
EDITOR is the {CONTEXT} vocabulary,  {EDITOR} {DEFINITIONS}  will 
make  it  the  {CURRENT} one,  in which new  definitions  can  be 
placed.  Because  {HASH} is part of {CREATE} (and that  last  one 
part of the  {:}-word), we can study the mechanism by which a new 
word  is placed in the {CURRENT} vocabulary  best,  by  analysing 
{CREATE}. First of all, {CREATE} has to accept a namestring. That 
will be the name of the new word.  This string will be moved then 
to   the  buffer  called  {WORD}.   {WORD}  always   leaves   the 
startingaddress  of  that string on the stack.  This  address  is 
going to be {DUP}ed first and one of the two stringaddresses will 
be  used to check if the name of the new word you want to  create 
already exists. If, then a message is given: .....isn't Unique or 
the  like.  The  next thing to do,  is to 'even' the  address  of 
{HERE},  then  the  address  of {HERE} is  put  onto  the  stack. 
Remember {HERE} is at the top of the dictionary !! At the address 
of  {HERE},  {CREATE} puts a zero.  So {CREATE} keeps that  place 
occupied, because {CREATE} will use this place within a second or 
less  to store the linkaddress.  What is to come now  ,  is  very 
important  for to understand what follows afterwards.  You  know, 
yes you know,  that when {CREATE} put that occupying zero at  the 
address  of {HERE},  {HERE} was incremented ( with  4,  as  UNIX-
FORTH's numbers counts 4 bytes = 32 bits),  to form a new-{HERE}. 
This  new-{HERE} is {DUP}ed,  one is put onto the stack and  with 
the help of {!} the other one in {LAST}.  This is done because in 
this  UNIX-FORTH  the  namefield comes after  the  linkfield  and 
{CREATE}  is  going  to use this  new-{HERE}  as  the  {NFA}.  So 
recapitulating: on the stack are two items: on top the old-{HERE} 
and beneath the {NFA} of the namestring of the new word.  We say: 
the new word is called {PIPO}.  Now {CREATE} {SWAP}s the items on 
the stack.  The stringaddress is on top now.  The use of  {COUNT} 
{HERE} takes care of a stack on which the items are well fit  for 
the work {PACK} has to do.  This word is a character-moving word. 
{PACK} gets the namestring - the countbyte as well - and puts  it 
on  the  address of new-{HERE} and in one go {PACK}  places  this 
new-{HERE}-address on the stack.
_________________________________________________________________ 
NOW TAKE AN EASY CHAIR (PLAYGIRL ?!) AND A CUP OF VERY STRONG 
COFFEE AND LEAN BACK FOR A WHILE.  You earned it !!
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
On   the  stack  are  old-HERE -  {LFA} - and new-HERE -   {NFA}. 
{CREATE}  now puts the address of {CURRENT} on top of the  stack. 
The pointer to the vocabulary into we want to place the new  word 
PIPO  is hided in that address. The stack shows {LFA} -  {NFA}  - 
vocabulary-pointer,  all prepared well for {HASH}.  {HASH}  takes 
the voc-pointer and puts it into the D1-register van de 68000-mc.
The  stringaddress  goes to A0.  This register  -  that  is,  the 
address  in the register - is incremented with one to  jump  over 
the countbyte.  You know,  strings do have countbytes; they count 
the  characters of the string.  We are at the first character  of 
the name of the word. It was getting time !! That first letter is 
the 'p'.  And this 'p' is bytemoved to register D0. As a register 
counts 32 bits,  the rest - 24 - has to be turned to zeroes. This 
D0-register now looks like:
 
0 0 0 0 0 0 0 0- 0 0 0 0 0 0 0 0- 0 0 0 0 0 0 0 0-0 1 1 1 0 0 0 0 
 
This configuration is ANDed  with 3,  binary 11.  Three,  because 
UNIX-FORTH  has  four - 0 1 2 3 - threads.  The  meaning  of  the 
thread-word  will  be  explained in  a  moment.  Let's  take  the 
contents of register D0. We only take the right byte: 0 1 1 1 0 0 
0 0.  This is the binary code for lowercase 'p'.  The other three 
bytes  on  the  left side are always  zero.  The  rightmost  byte 
changes  if  the first letter of the new word  changes.  In  this 
rightmost  byte the only important bits are those  two  rightmost 
bits,  as  these bits are the ones that may be changed by  ANDing 
with 3.  The number 3 itself also consists of 32 bits, but the 30 
leftmost  ones  are  always  zero  and  in  this  context  of  no 
importance.  These two rightmost bits of the first letter of  the 
new word in register D0 can look like the following:
 
                      0 0     0 1     1 0     1 1  
ANDing with 3         1 1     1 1     1 1     1 1
Result                0 0     0 1     1 0     1 1
 
The result in decimal:  0 1 2 or 3. Thus in D0 stands,  depending 
on  the first letter 0 1 2 of 3.  By adding D0 twice  to  itself, 
the D0-register will show  0 4 8 of 12.  All characters that  can 
serve  as  the first character of a FORTH-word are  divided  into 
four  groups in this simple way !!  The  characters   d h l p are 
part  of  the group of 0, a e i n in the contrary  belongs  to 4. 
All characters belonging to the  same group are called a  THREAD. 
So there can be 4 threads or 10 or 16. You should experiment with 
the ANDing, to see how you will get 8 groups of characters. Let's 
stick  with 4 groups.  The result of the ANDing is added then  to 
the  voc-pointer.   In the  case of PIPO  the  result  was  0 and 
therefore   the voc-pointer remains   unchanged. Out   of    this 
pointer is   destilled  an  address. NOW  THIS  ADDRESS  IS   THE 
LINKADDRESS OF a) THE PREVIOUS WORD THAT HAS BEEN DEFINED AND  b) 
THAT BELONGED TO THE SAME THREAD.
    So in voc-pointer+0  is  the 
linkaddress of the previous defined word beginning with  d h l  p 
or  another  character of this thread.  In voc-pointer+4  is  the 
linkaddress  of  the  group of a.o.  the characters  a e  i  n  . 
Etcetera.  After all that  the address of old-HERE is placed into 
this voc-pointer,  so the following word of the 0-thread can  use 
it  as  a  link.  Remember:  in the  voc-pointer  is  always  the 
linkaddress of the latest word of a specific thread that has been 
defined. We  have  the linkaddress of  the  previous  word.  This 
address  is  put into the address of  old-{HERE},  the  {LFA}  of 
{PIPO}. As each vocabulary has its own {CONTEXT}-address, it also 
has its own thread-addresses.  How vocabularies are chained is in 
relation  to  {CREATE}  of  no  importance;   that  subject  gets 
important when a particular word has to be searched by {FIND}. At 
last  we  have got so far,  that we  can  gladly  announce,  that 
{CREATE}  has done the job it was hired for.  The only  remaining 
thing for {CREATE} to do is to construct the immediate-byte.  But 
explaining  that  we would go to deep into  the  UNIX-FORTH.  The 
facts are that after the nfa of {PIPO} a so called flag-byte   is 
inserted and initialised to zero.  Is an IMMEDIATE word involved, 
then the word {IMMEDIATE} will set one of the bits into the flag-
byte.  In  all  other cases all bits will be zero.  At  last  the 
codefield   and  the parameterfield are installed.  And  so  dear 
countrymen and lovers an entry has become something like this:

                       |¯¯¯¯¯¯¯¯¯¯¯¯¯¯|
                       |     LFA      |
                       |              |
                       |¯¯¯¯¯¯¯¯¯¯¯¯¯¯|
                       |     NFA      |
                       |              |
                       |¯¯¯¯¯¯¯¯¯¯¯¯¯¯|
                       |  FLAG BYTE   |  
                       |              |
                       |¯¯¯¯¯¯¯¯¯¯¯¯¯¯|
                       |     CFA      |
                       |              |
                       |¯¯¯¯¯¯¯¯¯¯¯¯¯¯|
                       |     PFA      |
                       |______________|

We saw,  how {CREATE} made use of {HASH} to build 4 little 'sub'-
vocabularies  into a vocabulary.  Each 'sub' is a linked list  of 
those  words that have the two same rightmost bits of  the  first 
character of their name in common state. As the words provided to 
do the search- part of FORTH's job, make use of that same {HASH}, 
the  word  asked  for  can be found -  in  the  most  unfriendish 
circumstances  - by searching 25 % of ALL words.  This  increases 
the  searching speed with 300 % at worst  conditions.  And  these 
last seven sentences will have to form the third item of which  I 
promised  to  tell  you  about:  searching  the  dictionary.  But 
Statistics gives Bytes 33K and that's too much. I hope things are 
clear now, although I doubt it.
_________________________________________________________________
NOW TAKE TWO EASY CHAIRS, TWO (PAPER)PLAYGIRLS AND A WHOLE POT OF 
VERY STRONG COFFEE !! AND HATE ME !!!!
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
                                      With doubtful greetings !
SUMMARY

 {N>LINK} changes nfa to lfa ******* {L>NAME} changes lfa to nfa
 {NAME>}     "    nfa to cfa ******* {LINK>}     "    lfa to cfa
 {BODY>}     "    pfa to cfa ******* {>BODY}     "    cfa to nfa
 {>NAME}     "    cfa to nfa ******* {>LINK}     "    cfa to lfa

   
EXTRAS

This is going to be the most very special EXTRAS ever written  in 
this course,  because somebody has to stop Richard Karsmakers for 
going on and on about that booklet of mr.  Tolkien,  The Lord  of 
the Rings. I hope this will reach him before it's too late. Do me 
a  favour,  dear  Richard  and  read  The  Chronicals  of  Thomas 
Covenant.  There are six (6) volumes, over 2300 pages of the most 
marvelous  story I ever happened to read.  The author's  name  is 
Stephen Donaldson.  The volumes are published by Ballantine Book, 
U.S.A. The title of the first volume of the first episode is Lord 
Foul's Bane. Every episode counts three volumes and there are two 
episodes. Especially for Dutch readers it's be written here, that 
the  translation into Dutch of most volumes has been done by  Max 
Schuchart,  who was honoured with the Nyhoffprijs for translation 
(  in  magnificant DUTCH ) of The Lord Of The  Rings.  The  Dutch 
title of the first volume of  'De kronieken van Thomas  Covenant' 
is De Vloek van Heer Veil.  Published by Sirius en Siderius,  Den 
Haag,  ISBN 906441033x.  If you liked The Lord Of The Rings,  you 
are going to swallow the epos of Thomas Covenant. And in the case 
of you,  Richard,  it will purify your thoughts - nobody has been 
named SAG in that epos.  I can testify about the healing power of 
this  book,  because I didn't SENT(!!) a very angry letter to  ST 
NEWS
  for two reasons.  The first one is called Thomas  Covenant. 
The  other  one is,  because I felt writing angry  and  ferocious 
letters  is the easiest thing a man can do not to solve the  real 
problem;  if there is one.  The last - milder - letter you  wrote 
about  the SAG,  was a wise decision.  You,  Stefan and  all  the 
others involved in ST NEWS in which way whatsoever,  you,  - we - 
have  to write a better worldwide diskmagazine,  not to  fight  a 
personal local war. So read it (THEM books, I mean !!).

SOLUTIONS TO PART ELEVEN

1.  As  you might have expected,  {:} is an immediate  word.  The 
    reason why ? Well {:} has to be executed immediately to 
2.  Each  'plain'  defining word adds something  specific  to all  
    the  words it defines. They become 'family' Each word entered 
    into a vocabulary gets some mark, one could say. If the  word 
    {PIPO}  has  been  marked  as  belonging  to  the  {CLOWNS}-
    vocabulary, it has something in common with all words entered 
    in that vocabulary. In this way there is some agreement.
3.  In {PIPO}, of course. Just look 7 lines higher. 
4.  In  that  case only the {I-CRY}-word that  had  been  defined 
    last,  would have been used in other words,  that would  make 
    use of {I-CRY}.  Only all the older words than that last  {I-
    CRY}, would make use of that first one.
5.  This answer should be the opposite of the answer to  exercise 
    4.  If the two {YOU-CRY}  had been defined into  a  different 
    vocabulary,  each  execution of {YOU-CRY} in the  appropriate 
    vocabulary would result in a different response. 
6.  This definition is the usual definition of {WHILE}.  There is 
    nothing special about it.  Or  it  should be the simple  fact, 
    that  there is little or no difference between these two loop-
    starting words.

Disclaimer
The text of the articles is identical to the originals like they appeared in old ST NEWS issues. Please take into consideration that the author(s) was (were) a lot younger and less responsible back then. So bad jokes, bad English, youthful arrogance, insults, bravura, over-crediting and tastelessness should be taken with at least a grain of salt. Any contact and/or payment information, as well as deadlines/release dates of any kind should be regarded as outdated. Due to the fact that these pages are not actually contained in an Atari executable here, references to scroll texts, featured demo screens and hidden articles may also be irrelevant.