Skip to main content

It takes time 
to carry out a plan.

    From: London calling Europe

                           STRENGTH IN FORTH

                              part eleven

                   WHY THERE IS A TIME FOR EVERYTHING

You  saw the master's hand in the new outline of ST  NEWS  ?  You 
felt  his subtile keystroke of wit  and his fertile  programming- 
skill ?  He performed well,  didn't you think,  the new editor of 
ST NEWS, in succession to Richard Karsmakers ?  Yes, that's life, 
when there is a time for everything:  for the coming as well   as 
the going.  Pantharei,  all flows,  life flows from one hand into 
another,  again  and again and  in bare reality there is  no  way 
back.  And what's next,  when time's up ? Beyond time there is no 
such thing like time, but  all what is unlike time:  eternity. As 
it is with:  what comes next to the smallest thing of material  ?
Not  something  like material or something material is  made  of, 
as that would be material as well.  Perhaps something(?) material 
was  made  by ?  By means of our phantasy we  can  create  worlds 
beyond our time and space, but we can't imagine them without. And 
yet all human efforts are made to have a look  'behind'  time and 
space. Even FORTH cannot help to make that dream comes true. It's 
for sure,  that FORTH has his own time  for things getting ready. 
But his time is part of our time too !  

THROUGH ALL THAT

Some time  ago I told you something about the behaviour of words: 
in FORTH words may behave differently at compile-time and at run-
time.  We will go through all that again and we will now  explain 
the words connected with it.  First of all it would be an act  of 
intelligence to read the remarks in that part again. Secondly  it 
would be nice,  if some basic notions related with the subject on 
hand  would  be  clear to you.  Let's give  an example.

: EXAMPLE  CR 20 SPACES 42 EMIT ; OK

42 EMIT * OK

It's  quite  obvious,  that  the response of  {EMIT}  during  the 
compilation  of the colon-definition of {EXAMPLE} is not  at  all 
the  same as when we executed {EMIT} directly, as we did later in
42 {EMIT}.   The behaviour of {EMIT} at compile-time differs from 
that  at run-time.  Usually a FORTH-word is executed as  soon  as 
it's typed at the keyboard and Return is pressed.  You could call
that the run-time action of the word,  the normal action  so.  At 
compile-time - during  the  creation  (  not during  the  typing)
of  a  colon-definition  - the word  is  NOT   executed,  but its 
execution  address  is  added to the list  of  addresses  in  the 
parameter-field of the dictionary entry being constructed.   This 
process  continues,  until the terminating semi-colon  is  found. 
Then  normal  execution is resumed.  The same  remarks  apply  of 
course for {CR} and {SPACES}, what you may investigate yourself.   
You  must clearly distinct between the notion of compilation  and 
the  notion of compile-time.  Compilation stands for the  process 
of  creating a dictionary-entry for a new word.  Compile-time  is 
related  to the behaviour of a word during compilation.  At  run-
time  a  word  is executed and the behaviour  of  a  word  during 
execution is called run-time behaviour. So far for the notions. I 
hope you will now be able to understand what comes next.

ME AND MY EXECUTIONER

Suppose I want a word to execute at compile-time. In other words: 
I want a word with a run-time behaviour at compile-time. I am not 
interested  in the compilation of the  word's  execution-address, 
but I am interested in the word's action on immediate  execution. 
I  wouldn't  have  brought up the  subject,  if  it  hadn't  been 
possible  to define  such always executing words.  This implies - 
consequently - that FORTH has a need for such words. Well, that's 
true.  Remember that, discussing the subject of  conditional  and 
unconditional branches (see part 4),  I mentioned, that the words 
involved  should only be used inside a colon-definition and  that 
it  was  forbidden  to  use  e.g.  {IF..THEN}  outside  a  colon-
definition.  The  reason for that commandment was the  fact  that 
conditionals  have to calculate the addresses for where  to  jump 
to,  depending  on  the  condition  being  false  or  true.  This 
calculation  now has to be done immediate,  because  the  branch-
addesses have to be put in the newly  created dictionary entry as 
well.  We cannot possibly wait until a compiled word will execute 
to calculate the addresses. We could have entered many  new words 
afterwards.  Putting  these addresses in the  dictionary at  that 
time would  definitely have  overwritten other  dictionary-stuff.
The consequences would have been disastrous. 

HOW TO TELL IT FORTH

But how do I tell a word to execute immediate at compile-time and 
not to wait till run-time ?  I can't  interfere with  compilation 
and cry:  Now do it !  Execute,   love ! Nothing would happen, at 
least not as far as FORTH is concerned.  So there has to be  some 
other way to handle this. In fact there are two ways. 
This is the first one:  in the case of conditional structures  it 
was  known in advance that they should have to execute  immediate 
during  compilation.  So this kind of words simply were  made  so 
called IMMEDIATE   words at the time they were defined.  Why they 
are  called  immediate  words should be clear  to  you  from  the 
aforementioned. How they were made immediate at their 'definition 
time' is to be explained now. 
It's done by adding the word {IMMEDIATE} after the {;} you put at 
the end of your colon-definition. Unbelievable but typical FORTH, 
won't  you  think ?  That simplicity,  I  mean  !  Normally  when 
defining a word some bit in the entry of that word isn't set.  It 
is  left  to  be a zero !  Making a word immediate  -  or  rather 
defining an immediate word - will set this so called immediate or 
precedence bit to non-zero.  This bit is the sign-bit of the byte 
that containes the number of characters of a word.  This byte  is 
the first byte in the namefield of a word.  So FORTH will know at 
the  state  of that bit if a word is to be executed  rather  then 
compiled. Now {STATE} itself is a FORTH-word, it is - again - one 
of  those  mysterious user-variables.  But don't we  let  overrun 
ourselves.  We'll  spend  a word or so on user-variables  in  the 
future.  You will believe me, if I tell you that the composers of 
your FORTH-system have used the {IMMEDIATE}-word many times.  You 
will ask me,  if you are allowed to use {IMMEDIATE}. You are just 
lucky, see ! Let's make a normal word first

: .LATER  ." I was compiled !! " ; OK (a)        and execute it

.LATER I was compiled !! OK           (b) 

See, all is well aboard of {.LATER}. Now we are going to use this 
word in the definition of another word.

: LATER .LATER ; OK                   (c)

You wouldn't have expected something else,  would you ? Kitten in 
the coal-scuttle, as we like to express ourselves in Holland when 
emotions overwhelm us. Executing {LATER} gives

LATER I was compiled !! OK            (d)

When we repeat things as we did them above and this time using an 
immediate word, we will clearly see the difference. 

: .ATONCE ." I won't compile. Sorry !! " ; IMMEDIATE OK  (a')

What will happen at execution-time ? Let's find out

.ATONCE I won't compile. Sorry !! OK                     (b')

It  behaved like each other normal  word:  it  executed.  Nothing 
strange,  no hocus-pocus !!  Things will turn out to be different 
in the next code when it is entered

: HOCUS  .ATONCE ; I won't compile. Sorry !! OK          (c')

What's up now ?  You see, {.ATONCE} has been executed at the very 
moment you hit the Return-key;  it was not compiled in the  entry 
of the word {HOCUS}.  When FORTH executed {:} to make an entry in 
the  dictionary for {HOCUS},  he found out that {.ATONCE}  was an 
immediate  word and only fit for  execution.  So  FORTH  executed 
{.ATONCE}  and did not (could not) compile the  execution-address 
in  the  entry  of {HOCUS}.  Try  to  execute  {HOCUS}.  Yes,  it 
executes,  but it doesn't print any message.  It's 'empty' !!    

HOCUS OK                                                 (d')

Do  it  again and start reading at {.LATER}.  Compare  the  lines 
marked  with (x) and (x') and be aware of their  differences.  It 
will help you to understand what was going on.
I've  told you that the whole group of so called conditional  and 
unconditional  branch  structures are  all  immediate  words.  So 
immediate words don't necessarily have to print something at your 
screen or do something else that can be percepted. Most immediate 
words will work in the dark. 

THE VACOBULARIES, eeh VOCUBALERAIS eeh, uh....

Another   group  of  immediate  words  is  connected   with   the 
phenomenon of what is known in FORTH as 'vocabulary'.  It is  not 
so  difficult  a subject.  It is  quite  logical  thinking,  that 
'vocabulary'  has something to do  with  'dictionary'.  Both  are 
related with lists of words. A vocabulary is a distinct subset of 
words in the dictionary.  The dictionary is the whole of all  the 
vocabularies.  The root vocabulary - the vocabulary you start  up 
in - is called {FORTH}.  Suppose,  you just have started up  your 
FORTH. Having done that, you should now be aware of two things.
1.All words  you  will  enter are  searched for  in the  {FORTH}-
  vocabulary only.  If  a word  is NOT found,  FORTH  will  reply 
  with   xxx?,  where xxx is the name of the entered  word.  It's 
  said that {FORTH} has become the {CONTEXT} vocabulary. That is: 
  the vocabulary in which starts the search for a word.
2.All new words  you  will  define  are  entered  in  the {FORTH} 
  vocabulary.  It's said, that {FORTH} has become  the  {CURRENT} 
  vocabulary. That is: the one in which new words are entered.

|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|
|   It is possible that your FORTH will not respond to the      |
|   examples below in the way they are outlined.                |
|   If so, use [EDITOR] and [FORTH] instead of  EDITOR and      |
|   FORTH. The reason why will be explained later on.           |                      |
|_______________________________________________________________|

Each FORTH-system has more than one vocabulary.  If that was  not 
the  fact,  the  whole thing of vocabularies wouldn't  have  been 
necessary.  Two major vocabularies are {EDITOR} and  {ASSEMBLER}. 
In these lists of words are concentrated all words connected with 
editing and assembling activities respectivily. So

EDITOR OK

will bring us in the {EDITOR} vocabulary. 
1.All words you will enter from now on are FIRST searched for  in 
  the {EDITOR} vocabulary and at last, if not found, in {FORTH}. 
2.All  new words you will define,  though,  are still entered  in 
  {FORTH}. The {EDITOR} has NOT become the {CURRENT} vocabulary.
3.To  make the {EDITOR} also the {CURRENT} vocabulary you  should 
  have entered

EDITOR DEFINITIONS OK

Now  the  {EDITOR}  has become the {CONTEXT}  and  the  {CURRENT} 
vocabulary  by means of the word {DEFINITIONS}.  From now on  all 
new words will find a warm and cosy place in the  {EDITOR}.  Both 
{CONTEXT}  and  {CURRENT}  are  user-variables.  {CONTEXT}  is  a 
pointer.  It  points  to  the  vocabulary  to  be searched first. 
{CURRENT} is also a pointer. It points to the vocabulary in which 
new definitions will be entered.  These two are usually,  but not 
necessarily,  the same.  If there happens to be a 'disagreement', 
you  may use {DEFINITIONS} to set the {CURRENT} vocabulary to  be 
the same as the {CONTEXT} vocabulary.

ABOUT WAR AND PEACE

It is possible to create vocabularies of your own.  A  vocabulary 
may serve several purposes:  a utility,  a game,  an  application 
etc.  You can give all those a name of their own.  If you want to 
make any of them active,  call it by name.  It is up to your  own 
imagination ! Now  for the creation of a vocabulary !

VOCABULARY PIPO IMMEDIATE OK

We made a new vocabulary,  named PIPO.  The fact that {IMMEDIATE} 
followed  {PIPO} means that {PIPO} has become an immediate  word.
{VOCABULARY} is a defining word. It created a defining word for a 
vocabulary with the name {PIPO}.  (Remember what I told you about 
creating  a defining word that in turn creates  another  defining 
word  -  part 10).  The vocabulary {PIPO} is so  linked,  that  a 
dictionary  search will also find all words in the vocabulary  in 
which {PIPO} was originally defined. In this case it was {FORTH}. 
So, ultimately, all vocabularies therefore link to {FORTH}. It is 
always  best  to  chain  a vocabulary  directly  to  the  {FORTH} 
vocabulary as that is the root, in which any vocabulary will find 
the primitive words,   which are used most for other words to  be 
constructed.  It  is possible to create a  vocabulary  {PIPO-ONE} 
into {FORTH} and a {PIPO-TWO} into {PIPO-ONE} and a  {PIPO-THREE} 
into {PIPO-TWO} etc.  etc.,  but the search order would get  that 
very  messy,  that execution-speed and clarity would both  suffer 
considerably.  All words indicating the name of a vocabulary  are 
immediate  words by convention.  Let's stand still a  moment  and 
consider the consequences. First

PIPO OK 

We are in that {PIPO} vocabulary now as the {CONTEXT} vocabulary.
And then

: I-CRY  ." I hate war more ..." ; OK

As  {PIPO} was NOT  the {CURRENT} vocabulary when we entered  {I-
CRY}, this last word is entered in {FORTH}. Now here is a pitfall 
and  an  ambush  !  As  soon as you make  a  new  definition  the 
{CONTEXT}  vocabulary  is automatically set to be  equal  to  the 
{CURRENT}  !!!!!!!  So  {FORTH} now happens to be  {CURRENT}  and 
{CONTEXT}.  We  will now change the {CURRENT} and  the  {CONTEXT} 
vocabulary

PIPO DEFINITIONS OK

We  will  enter  a definition WITH THE SAME NAME  into  {PIPO} .

: I-CRY ." than I hate peace !!" ; I-CRY isn't unique OK

Yes,  I know you are not unique !  FORTH tells us that we entered 
two  words with the same NAME  in the DICTIONARY .  But  we  know 
that  only the name is the same and that those words were entered 
in different vocabularies.  If we now

FORTH OK                           (1)        and then 

I-CRY I hate war more... OK        (2)        and next

PIPO OK                            (3)        and at last

I-CRY than I hate peace !! OK      (4)

you should have noticed what exactly was going on. In line (1) we 
changed the {CONTEXT} from {PIPO} to {FORTH}.  So the search  for 
the  word {I-CRY} in line (2) would start in the latter.  It  did 
and when FORTH found the name {I-CRY) he executed that word.  And 
'that word' was the definition we entered in {FORTH}. In line (3) 
we  changed again and this time to {PIPO} as the  {CONTEXT}.  The 
search in line (4) started in {PIPO} and stopped when {I-CRY) was 
found  in that vocabulary.  It was the definition of  {I-CRY)  we 
entered when {PIPO} was made the {CURRENT} vocabulary.

PLEASE, BOTHA !!!

Let's  do some more typing; it'll keep you busy  

FORTH DEFINITIONS OK

Notice that new definitions will be placed in {FORTH}. Now enter

: WE-CRY  FORTH I-CRY  PIPO I-CRY ; OK               and execute

WE-CRY I hate war more...than I hate peace !! OK

When   {WE-CRY}  was  entered,   {FORTH}  set  the   searched-for 
vocabulary immediately to {FORTH},  then found the name  {I-CRY}, 
took  its execution-address and compiled it in the entry of  {WE-
CRY},  {PIPO}  was executed immediately too and so the  {CONTEXT} 
was  set to {PIPO} in which vocabulary the name of the other  {I-
CRY}  was found with another execution-address  and that  address 
was  also  compiled in the entry for {WE-CRY).  And so  it  could 
happen  that  at  last  different  vocabularies  spoke  the  same 
language.   If  both  {I-CRY}  had  been  defined  in  the   same 
vocabulary, things would have turned out quite differently.
It  just crossed my mind,  but suppose I would have  entered  the 
following definitions,  assuming {FORTH} being the {CONTEXT}  and 
{CURRENT} vocabulary

: YOU-CRY ." Mandela is still in prison !! " ;

: S-AFRICA  YOU-CRY CR ;

Executing {S-AFRICA} will type out the message of {YOU-CRY}.  The 
word  {CR}  performs  a carriage return and a  line-feed  on  the 
display. Redefining {YOU-CRY} as

: YOU-CRY  ." Mandela is free now !! " ;

will give "YOU-CRY isn't unique", because {YOU-CRY} is already in 
the dictionary. This new definition of {YOU-CRY} can then be used 
in a redefined {S-AFRICA}

: SOUTH-AFRICA YOU-CRY CR ;

Bringing this new {SOUTH-AFRICA} to life with

SOUTH-AFRICA Mandela is free now !! OK

will print out the redefined {YOU-CRY} as you can see.  But  what 
with the old {S-AFRICA} ?  Well the old one will give as could be 
expected - even from reality

S-AFRICA Mandela is still in prison !! OK

From  now on all new wor(l)ds using {YOU-CRY},  will  incorporate 
the second definition.  The old one will only be apparent in  the 
old {S-AFRICA}. May this come true in our real world as well !! 
The phenomenon of vocabularies serve two main goals
1.  It  allows us to separate the words of one  application  from 
    those of another. 
2.  It  allows  the use of same  word-name to  represent  several 
    different  actions  and  still  be  able  to  locate  earlier 
    definitions.
Of course there are more immediate words than those belonging  to 
these two groups I mentioned. 
But  - computer people are very demanding creatures - what  if  I 
once  defined a 'normal' word and I would like it to  execute  at 
compile-time  instead of being compiled ?  
Yes,  each 'normal' word can be made to execute at  compile-time. 
It is done by {[}, which is itself an immediate word. This little 
word - called left-bracket - is often, but not necessarily always 
accompanied with {]} - called right-bracket.  In general they are 
used  to  let  a  word execute that  otherwise  would  have  been 
compiled  in  a dictionary-entry.  We will examine  this  in  the 
following paragraph.

THE BRACKET-MYSTERY

We are going to use  {[} and {]}  to solve  the mystery maybe you 
encountered while entering some of the code from above. In saying 
that  vocabulary-words are made immediate by  convention,  it  is 
said meanwhile that sometimes they are not.   Conventions can  be 
broken.  Therefore conventions are mere conventions, no hard law. 
Many system will contain two versions of the word to  'open'  the 
{FORTH} vocabulary:  {FORTH},  we know,  and {[FORTH]}. The first 
one will NOT  be an immediate word,  the second one is.  If  your 
system has both versions,  it will undoubtely have more such twin 
words  like {'} and {[']}.  Remember that in the name  this  time 
also is the meaning. All '[]'-versions are immediate. This use of 
{[]  and {]} in the name of the immediate duplicate  is  deducted 
from the function of {[} and {]}.  The definition of {[FORTH]} on 
the other hand is quite simple

: [FORTH]  FORTH ; IMMEDIATE OK

And that's all !!  This method may be used,  to define  immediate 
versions of all words which originally  are not.  But there is  a 
way  in  which you haven't to make immediate duplicates  and  yet 
words inside a colon-definition will be executed instead of being 
compiled.  Assuming  that {FORTH} is NOT  an immediate  word,  we 
could redefine the definition of {WE-CRY} as follows

: WE-CRY [ FORTH ] I-CRY PIPO I-CRY ; OK

WE-CRY I hate war more...than I hate peace !! OK 

The {[} word stops the compilation of the new entry {WE-CRY}  and 
sets  back  to  execution  of  the  following  words  inside  the 
definition.  So  {FORTH}  will  be  executed as  if  it  were  an 
immediate   word.   The   right-bracket   stops   execution   and 
switches to compilation again. Until it's {PIPO} 's turn. As this 
was defined as an immediate word,  it will execute.  At last  {I-
CRY} will be compiled.  So one could say,  that words between {[} 
and {]} inside a colon-definition are always executed as if  they 
were immediate words.  I hope that now it's clear to you why  the 
immediate version of {FORTH} got its name in brackets.
The  use  of  {[} and {]} is submitted to a  very  important  and 
compelling rule:  it may never change the number of items on  the 
stack.  The items produced eventually inside {[} and {]} have  to 
be used before compilation of the current definition has  reached 
{;}.  Otherwise an error-message will be given and the definition 
is  (at least) not executionable.

THE ULTIMATE RUN-TIME BEHAVIOUR...

It  remains two words to be explained that are related  with  the 
subject  of  this eleventh part.  The first one is  an  immediate 
word,  although its name points at compiling:  {[COMPILE]} -  say 
bracket-compile-bracket.  This  word  is  used  inside  a  colon-
definition to force the compilation of an immediate  word,  which 
would otherwise execute. So if we redefine and rename the earlier 
{HOCUS}-word, then 

: HOCUS-POCUS  [COMPILE] .ATONCE ; OK

will  work  out quite different as the  old  {HOCUS}.  The  first 
thing  to strike you,  is the fact that {.ATONCE} didn't  execute 
although  it  was defined as an immediate word.  This is  due  to 
[COMPILE],  that  executed - it is immediate - and  compiled  the 
execution  address of {.ATONCE} in the entry  for  {HOCUS-POCUS}. 
This is exactly what would happen, if {.ATONCE} would have been a 
normal word. If we now

HOCUS-POCUS I won't compile !!! OK

it  is seen,  that {HOCUS-POCUS} acted as a normal  word  i.e. it 
executed {.ATONCE}.
The  second word is not immediate:  {COMPILE}.  It will cost  you 
some imagination to see what this word is all about. For instance 

: MUCHLATER  COMPILE .LATER ; OK   (e)            and

MUCHLATER OK                       (f)

What  happened ?  You might have expected that {MUCHLATER}  would 
have  printed out the message:  I was compiled  !!  contained  by 
{.LATER}.   But  nothing  of  that  kind  happened.  What  really 
happened,  you couldn't see. Read it slowly: when {MUCHLATER} was 
compiled (e),  the execution addresses of {COMPILE} and  {.LATER} 
were  added to the entry for {MUCHLATER};  when  {MUCHLATER}  was 
executed  (f),  the  code field (execution) address of  the  word 
following  {COMPILE}  -  i.e.   {.LATER} -  was  compiled  in the 
dictionary instead of executing.  
Again  the  conditional branch words could  serve  splendidly  as 
examples of {[COMPILE]} and {COMPILE}.  Let's take {IF}.  Here is 
its (possible) definition

: IF COMPILE ?BRANCH ?>MARK ; IMMEDIATE OK

Now  {?BRANCH}  is a routine that decides on the  value  atop  of 
stack if there will be a branch and {?>MARK} decides   where.  As 
{IF} is an immediate word, this could be a typical scene.

: JIFFY  1 > IF ." Bigger than 1" THEN ; OK

3 JIFFY Bigger than 1 OK

We  kept  it simple.  Read it slowly again !!  When  {JIFFY}  was 
defined,  {IF} was not compiled ( = immediate !!!),  but executed 
to  compile  the execution address of {?BRANCH} in the  entry  of 
{JIFFY} by means of {COMPILE ?BRANCH}.  You could compare it with 
this medical story.  Some virus diseases,  say  sleeping-sickness 
are  spread by a carrier-animal - in this case the tse-tse fly  - 
which  itself is not infected,  but which will infect the  living 
creature  which serves  to the  fly itself as  a  carrier-animal. 
So {IF} itself doesn't 'suffer' from {?BRANCH}, but the word that 
was 'infected' with {?BRANCH} through {IF}.  So {IF} is immediate 
in  the  sence of compiling {?BRANCH} into the body of  the  word 
being defined. I know, it is not easy to understand. Compile-time 
and run-time aren't at all absolute notions.  They can be used in 
relation to each word on its own and in relation to other  words. 
Let's consider the word {HOCUS},  for instance. To define {HOCUS} 
we  used  {.ATONCE},  an immediate  word.  It  is  obvious,  that 
{.ATONCE}  has a run-time behaviour of its own.  But relative  to 
{HOCUS} it has no run-time behaviour, but it does have a compile-
time  behaviour  i.e.  the  behaviour during the  compilation  of 
{HOCUS}  and  that  is  to  execute.   If  this  is,  you  think, 
complicated, then  watch the  next definition  I'll give you  for 
free.

: WHILE [COMPILE] IF ;

The  word [COMPILE] forces {IF} to be compiled in the  definition 
of  {WHILE}.  The rest of the story you will have to tell,  as  I 
give it to you as exercise no.  7.  I think, I owe you one single 
word. Here it is

: CAREL "£!^*&(} ;

I'll tell you its run-time behaviour........

                                      Zooooooooooffffffffffff !!
SUMMARY

|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|
|     WORDS      |    STACKACTION   |       DESCRIPTION         |
|________________|__________________|___________________________|
|                |                  |                           |
|   IMMEDIATE    | Used as::  NAME..|Sets the precedencebit  of |
|                | ...; IMMEDIATE   |the most recently defined  |
|                |                  |word so that it will be ex-|     
|                |                  |ecuted rather than being   |
|                |                  |compiled,during compilation|
|                |                  |of a word.                 |
|  VOCABULARY    | Used as:         |A defining word. It creates|
|                |VOCABULARY  NAME  |a defining word for a voca-|
|                |                  |bulary.                    | 
|  DEFINITIONS   | Used as:         |Sets the CURRENT vocabulary|
|                | NAME DEFINITIONS |to the CONTEXT. All defini-|
|                |                  |Definitions will be placed |
|                |                  |in the vocabulary with the |
|                |                  |name NAME.                 |
|    CONTEXT     |   ( --- addr )   |A user-variable,leaving the| 
|                |                  |address addr of a pointer  |
|                |                  |to the vocabulary in which |
|                |                  |dictionarysearch will start|
|    CURRENT     |   ( --- addr )   |A user-variable,leaving the|
|                |                  |address addr of a pointer  |
|                |                  |to the vocabulary in which |
|                |                  |new definitions will be    |
|                |                  |placed. As soon as a new   |
|                |                  |definition is entered the  |
|                |                  |CURRENT becomes CONTEXT too|
|    STATE       |   ( --- addr )   |Address addr holds a value |
|                |                  |either indicating execution|
|                |                  |- false - or compilation - |
|                |                  |true. A user-variable.     |
|       [        |   ( --- )        |Suspends  compilation  and |
|                |                  |allows subsequent input to |
|                |                  |be executed. Used in a co- |
|                |                  |londefinition.             |
|       ]        |   ( --- )        |Used during execution to   |
|                |                  |force subsequent input to  |
|                |                  |be compiled. Used in a co- |
|                |                  |londefinition.             |
|    COMPILE     |   ( --- )        |During execution acts to   |
|                |                  |compile the codefieldadd-  |
|                |                  |ress of the word following |
|                |                  |it into the dictionary in- |
|                |                  |stead of executing it.     |
|   [COMPILE]    |   ( --- )        |Forces the compilation of  |
|                |                  |an immediate word.         |
 ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯

EXTRAS

I  defined  a  vocabulary as a distinct subset of  words  in  the 
dictionary.  That's a fine definition,  but you must not think of 
a vocabulary as  an isolated  group of words  put  together.  The 
words belonging to the same vocabulary got a special mark at  the 
time they were defined.  The words may have been spread all  over 
the  dictionary.  At the command of the user it enables FORTH  to 
search  the dictionary for all the words with that  special  mark 
first. 

EXERCISES

1.  This is  rather difficult:  Could you tell me now, wether {:} 
    is an immediate word or not ? And why ?
2.  And  this  question is  even worse:  In which way is  a  word 
    defined with {VOCABULARY} as in {VOCABULARY} PIPO,  itself  a 
    defining word ?
3.  Somewhere in this issue  of the FORTH-course I marked a  line 
    (2).  Can you tell me  in which vocabulary new words will  be 
    placed from that point ?
4.  In which way things  would have turned out quite differently, 
    if both {I-CRY}-s had been defined in the same vocabulary ?
5.  And what about  {YOU-CRY},  when the two versions would  have 
    been defined in two different vocabularies ? 
6.  Explain  what will happen,  when we used {MUCHLATER} in  the 
    following definition and we had it executed ?
    : ATLAST CR  MUCHLATER ;
7.  Explain the definition of {WHILE}, as given above. 

SOLUTIONS TO PART 10

1. You surely did this one with your eyes closed.
   : CONSTANT  CREATE , DOES> @ ;
   Used as 123456 {CONSTANT} NOWANDTHEN.
2. You could keep your eyes closed, eh ? 
   : .STRING  COUNT TYPE ;
3. This one was to make it a real beauty-nap.
   : CVARIABLE CREATE 0 C, DOES>  ;
4. Now you had your eyes wide open; you didn't notice the rotten
   spot in {SKEWEE}, did you ? Of course not !!
   Count the number of 'E'-characters.  They are ten... and they 
   ought to be nine, as the {DO...LOOP} starts at one.
5. : VARIABLE CREATE 4 ALLOT DOES> ; not initialised.
   : VARIABLE CREATE 0 , DOES>     ; initialised.
6. You could have it replaced with {OVER} {+} {+}.
7. The error-checking can be done as follows
   : 2DIMARRAY CREATE 2DUP * , 4* ALLOT
               DOES> SWAP ROT * OVER @ 2DUP > 
               IF ." Range error - array-index over " . QUIT
               THEN DROP  4* 8 + + ;
   The  number of elements is compiled with {2DUP * ,}  and  then 
   space is  reserved {4* ALLOT}. The maximum number of  elements 
   is    compared with the actual given number of elements  {SWAP 
   ROT * OVER @ 2DUP >}. If the actual number is greater than the 
   maximum  a error message is given and the definition is  left. 
   If not then the offset in the array is calculated. 
8. : TABLE  CREATE DUP , 4* ALLOT DOES> DUP 4 + SWAP @ ;
   Use: n TABLE CLOTH, where n is  the required number of items.
9. I could have  used {W,}. As the numbers to be  compiled in the 
   dictionary do not exceed the limit of 65765, i.e. fit into one 
   machineword,  it  would have  been a  save in  memory and  an 
   increase in speed.

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.