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.