FORTH
from Your Computer, January 1985

K Wierstra shows you how to get a fairly
complete version of Forth on a Spectrum.


THE PROGRAM PRESENTED here is a fairly complete version of the Forth
language, written for the Spectrum 48K. This article is not meant to teach
you Forth. You may learn Forth from one of the many available books. Once
you've grasped the concept of the stack and the way of adding and removing
numbers to and from the stack, you'll quickly find your way through the
dictionary by experiment and a little thought.

The compiler shown here is very well suited for this purpose. The main
omissions of my version from Standard Forth are:
* There are no defining words like Create and Does>, but there is no problem
creating constants, variables and arrays.
* There are no double precision numbers.

The object of this article is to explain some of the functions of the
compiler, particularly the  non-standard  compiler commands and some Forth
words which I included to reflect the possibilities of the Spectrum. But
first of all you will have to cope with the task of entering the program.
Start with typing the BASIC Interference given in Figure 1 and save it, with:
	SAVE "runner" LINE 9003

Now enter the hex-loader listed in Figure 2. The machine code in Figure 3 may
now be entered starting with address 37032. Type a whole line of nine
hexadecimal numbers without spaces. The ninth number is a control code. If
you made a mistake the last starting address will be shown on the screen and
you may try again. Once it all has been typed in save the code with:
	SAVE "FORTH" CODE 37032,3672

After rewinding the tape and typing:
	LOAD "runner"
the whole system should start. You will now see the title of the program [No,
you don't. JimG] and a flashing cursor, a black square which may be
considered as a disguise of the C cursor.

In aiphanumerical form

As you will expect all inputs have to be in alphanumerical form, so a Forth
word like Then should be entered by pressing four different keys. All words
and numbers have to be separated by at least one space or an ENTER.

Inserting and deleting is done in the usual way, moving the cursor with the
cursor keys and deleting with DELETE. Just like in BASIC the editor is at the
same time ready to accept commands and new definitions, variables etc. A
direct command may be one of the editor commands listed in Figure 4, or a
sequence of one or more Forth words or numbers. An example of an editor
command is DLIST. Type this in and you'll see a list of all predefined
Forth words.

Afer the execution of your command the cursor will reappear on the bottom of
the screen, indicating that all is OK, as far as the computer is concerned. I
have refrained from constantly reporting OK  or fine, excellent  since such
a message will soon lose its encouraging meaning.

All input will he screened by the editor; lines containing non-acceptable
items - undefined words, numbers out of range  will be sent back to the
screen together with an error message. The cursor will bc positioned just
before the unacceptable word or digit to enable you to correct your input. A
list of all the error messages is given in Figure 5.

The definition of a word starts with : and ends with ; - don't forget the
spaces. A word may consist of several lines separated by ENTERs. Variables
and constants arc defined using VARIABLE and CONSTANT; eg.:
	3 CONSTANT THREE

If you know anything about Forth you probably wonder how to create arrays,
lacking the words Create and Does>. The point is that you have to define
every array again. If you need, for instanc,e an array of 20 bytes, then type:
	VARIABLE INSTANCE 18 ALLOT
The operation of VARIABLE reserves 2 bytes of INSTANCE and 18 ALLOT adds
another 18 bytes. The array is defined by:
	: ARRAY + * INSTANCE + 1 ;
Now if you type 3 ARRAY the address of the fourth component of the array (2
bytes) will be pushed onto the stack.

You may inspect the values of the defined constants and the addresses of the
variables by giving the command VLIST   see also Figure 4.

Editing a word is done as follows: Since there are no line or word numbers,
the Spectrum EDIT key has been disabled, instead you have to type EDIT ARRAY
and you'll find the definition back on the screen, together with the cursor,
willing to accept your editing commands. If the word consists of several
lines, the lines will be shown successively and you can step through the word
pressing ENTER.

Comments may be included using ( and ). ENTERs are now allowed inside a
comment. It is possible to insert machine-code in a word or a direct command.
The code should start with # and has to be entered in hexadecimal form. As
an example I give the definition of the Standard Forth word 1+ :
	: 1+ #CD119923CDEC98 ;
no spaces allowed after #; in mnemonics:
	CALL POPSTACK, INC HL, CALL PUSHSTACK

When the computer is executing a command and it does not produce the expected
output  or no output at all  it is usually possible to interrupt the system
by pressing CAPS SHIFT and BREAK. During every loop (Do...Loop, Do...+Loop,
Begin...Until, Begin...While...Repeat) a check is made whether BREAK has been
pressed, and the machine will halt accordingly. If a definition does not
contain any loops, but has for instance a recursive structure  which means a
word calling itself, see also Figure 6  you may insert  during testing and
debugging  the word BREAK. This word will perform the same operation as the
automatic loop control.

In Figure 6 I have given a few examples to illustrate the use of the
compiler. In Figure 7 some special Forth words are described.

Some additional information concerning the compiler  eg. making it
Microdrive compatible  I can supply if you send an envelope with your
address to K. Wierstra, [address deleted], Holland. Please include 1. For
3.50 I will send you a tape of the Forth compiler.


-- Figure 4: Editor commands

LIST - lists all word definitions. LIST EXAMPLE will list from the word EXAMPLE.
LLIST - the listing will be sent to the printer (also LLIST EXAMPLE is possible).
VLIST - this lists all constants and variables, together with their values
	and memory addresses respectively. A comparison of the addresses gives you
	the opportunity to inspect the reserved room for arrays.
DLIST - lists the whole dictionary.
FORGET - clears all word definitions from the source but leaves the compiled
	words in the dictionary. FORGET EXAMPLE clears the word definitions from the
	start of the source to the word EXAMPLE inclusive.
CLEAR - clears the stack.
EDIT EXAMPLE - this gives the possibility to edit the word definition.
RESET - clears the whole system and will perform a restart.
EXIT - returns to BASIC. You can restart the compiler using RUN - leaving all
definitions, etc. intact - or run 9002 - resetting everything.
SAVE NAME - saves the source to tape - don't use quotation marks.
LOAD NAME - loads the source and compiles it into the dictionary - this may
take one or two seconds. If you omit the filename then the first file found
will be loaded.

--

-- Figure 5: Compiler error messages

Integer out of range - a number outside the range -32768 to 65535.
Undefined word - a word is not recognised.
Illegal name - the name of a word is not available; eg. try VARIABLE I - I
	is a pre-defined word.
Pardon? - given on various occasions; eg. SAVE without a file name.
Out of memory - this is just a warning. The last word will usually be
	entered, but memory is scarce and you should do something about it,
	perhaps by forgetting some words.

Runtime error messages:
Stack empty
Stack overflow
Division by zero
Break (the program has been interrupted, or an illegal command has been
	given; eg. 30 30 AT)

--

-- Figure 6:

Example 1:
: PLANE 176 0
	DO I 256 0
		DO DUP I SWAP PLOT
		LOOP DROP
	LOOP
(THIS WORD FILLS THE SCREEN WITH PLOT) ;

Example 2:
VARIABLE N VARIABLE F
: FAC N @ 1 >
	IF N @ 1 - N ! FAC (RECURSION)
		N @ 1 + DUP N !
		F @ * F !
ELSE 1 F !
THEN ;
: FACTORIAL ."GIVE A NUMBER <9"
	KEY 48 - N ! FAC
	CR N @ . ."! = " F @ U.
(THESE WORDS CALCULATE THE FACTORIAL OF A NUMBER) ;

Example 3:
VARIABLE LINE$ 30 ALLOT
: STR! (THESE WORDS SHOW THE USE OF SOME STRING HANDLING WORDS)
	OVER C@ 1 + CMOVE ;
: INPUT ."TYPE SOME LINE"
	QUERY 13 WORD
	LINE$ STR! ;
: .STR COUNT TYPE CR
	(THIS WORD PRINTS THE LINE) ;
: REVERSE COUNT 1 - -1 SWAP
	DO DUP I + C@ EMIT
	-1 +LOOP DROP
	(THE LINE WILL BE WRITTEN IN REVERSE ORDER) ;
: SHOW INPUT CR
	LINE$ .STR
	LINE$ REVERSE ;

--

-- Figure 7: Non-standard Spectrum Forth words

UDG - pushes the address of the first user-defined graphic on the stack.
CLS - clears the screen.
10 10 BEEP - equivalent to ZX BASIC's BEEP 1,10. Mind the difference between
	the first two parameters; in Forth the duration of the BEEP has to be
	given in tenths of a second.
10 20 PLOT - equivalent to PLOT 10,20
3 7 AT - equivalent to PRINT AT 7,3;.
RANDOM - puts a pseudo-random number between 0 and 127 on the stack - you
	should judge the randomness yourself.
24 EMIT - output will be sent to the printer if the screen is in use and vice
	versa.

--
