Setting Forth

Setting FORTH title art with footprints
Setting FORTH title art with footprints

FORTH is a computer language that uses less memory and runs at higher speeds than most high-level languages. In many ways, it is similar to BASIC, and is used with many computers. The following is a summary of its properties.

  • FORTH commands can be issued in an immediate execution mode or included as statements for later execution.
  • FORTH statements are compiled and contain high-level structured constructs such as
IF ... ENDIF
IF ... ELSE ... ENDIF
DO ... LOOP (like BASIC FOR/NEXT)
DO ... +LOOP (like BASIC FOR/NEXT/STEP)
BEGIN ... AGAIN
BEGIN ... UNTIL
BEGIN ... WHILE ... REPEAT
  • The execution speed of FORTH commands approaches that of assembler programs.
  • FORTH is highly portable — it can be easily transferred from one hardware host to another.
  • There are no barriers between the compiler, system, or applications code. FORTHs are frequently implemented as language systems as opposed to being included under operating systems.
  • FORTH uses an efficient virtual memory system.
  • FORTHs are frequently multitasking.
  • FORTHs permit easy user definition of new data types and structures.
  • New verbs can be added to the language either in terms of existing verbs or assembly language of the host processor.
  • FORTHs are frequently in the public domain and as a result do not require software licensing for their reproduction. A team of systems level programmers in 1978 created a portable model of FORTH which they originally implemented on nine different microcomputers. This FORTH model became known as fig-FORTH (FORTH Interest Group). There is a fig-FORTH 1979 standard and upcoming 1983 standard.

How FORTH works

The fundamental goal of a FORTH is to transform any computer into a standard FORTH stack computer. The computer code required for this transformation can be a combination of FORTH and machine language.

FORTHs can be viewed as composed of three stacks. These stacks are:

1. A parameter stack which is normally two bytes wide. This stack expands downward in memory.

2. A return stack which is normally two bytes wide. This stack expands downward in memory.

3. A word dictionary which behaves much like a stack with variable width elements but is a linear linked list. The word dictionary expands upward in memory.

The following programming examples in FORTH will make clear some of its powerful features. Spaces are the delimiter in FORTH text. OK is FORTH’s prompt for input from a system console. All responses from FORTH will be printed in bold. A carriage return keyed by the programmer causes a transition from input to the bold output of FORTH in these examples.

Example 1:

2 3 + .5 OK

This example adds 2 to 3 and prints the result on the console output device. The number 2 is identified as a number, converted to a two-byte binary number and placed on the top of the parameter stack. The same process occurs for the number 3. At this point in the FORTH interpretation, the parameter stack is

Parameter stack holding 2 and 3
Parameter stack holding 2 and 3

The + is identified as a verb and is executed immediately. The + verb adds the top two values of the parameter stack, discards both, then pushes the sum on top of the parameter stack. The words “Uses – Leaves” or “Before – After” are frequently used to describe the contents of the parameter stack prior to and after the execution of a word. In this case.

Before - After stack for +
Before – After stack for +

The . verb prints the signed number at the top of the parameter stack and has the Before – After parameter stack.

Before - After stack for .
Before – After stack for .

FORTH requires that expressions be written in reverse Polish as is done when using Hewlett-Packard calculators. The expression (A + B)*(C – D) would be written A B + C D – * for evaluation in FORTH.

A FORTH “WORD” is much like a line number in BASIC or a label in a language like PL/I. A FORTH word can be defined for later execution. The next example contains a definition of a user-defined FORTH word named CUBE which is designed to take the cube of the number located at the top of the parameter stack. The : is similar to a line number in BASIC.

Example 2:

: CUBE DUP DUP * * ; OK

The : informs FORTH that the word following the : is to be compiled into the FORTH language. DUP is part of the core FORTH language and this verb causes a copy of the top number on the parameter stack to be pushed on the parameter stack. If X is a number, then the Before – After parameter stack values for DUP are

Before - After stack for DUP
Before – After stack for DUP

The FORTH word * is part of the core language and has the Before – After parameter stack values

Before - After stack for *
Before – After stack for *

for numbers A and B where A*B is the product of A times B. The ; ends the definition of CUBE. When CUBE is issued as a command in the form

3 CUBE .27 OK

3 is placed on the parameter stack then CUBE is invoked. A rough execution trace of 3 CUBE . is

Execution trace of 3 CUBE .
Execution trace of 3 CUBE .

FORTH is used in video games, word processors, cameras …

Example 3:

The control structure DO … LOOP is used within the user-defined word TEST.

: TEST 1 DO I . LOOP ; OK

Execution of the command sequence 10 TEST gives

10 TEST 1 2 3 4 5 6 7 8 9 OK

TEST contained three new words; DO, LOOP, and I. The FORTH core word I makes a copy of the value on the top of the return stack and places it on the parameter stack. The functions of DO and LOOP are best examined by looking at a rough trace of execution of 10 TEST.

Execution trace of 10 TEST
Execution trace of 10 TEST

This process continues until

Execution trace of 10 TEST, end of loop
Execution trace of 10 TEST, end of loop

When in value of the INDEX – LIMIT> = 0, the INDEX and LIMIT are popped off the return stack and program control continues at the statement following LOOP which, although not covered yet, is the execution time code for ;.

Example 4:

The next example illustrates specification of both execution time and compile time behavior of a FORTH word. The attribute of specification of both execution time and compile time behavior sets FORTHs apart from other languages in terms of power (performing what is needed easily). Before specifying compile and execution time behavior of a word, the definitions

: RED ." RED" ; : WHITE ." WHITE" ; : BLUE ." BLUE" ; OK

When you type in red, the following will appear on the screen:

RED REDOK

The FORTH words <BUILDS and DOES> are used respectively to specify compile time and execution time behavior of a new FORTH word. The : definition

: :CASE <BUILDS ] DOES> SWAP 2 * + @ EXECUTE ; OK

defines a new word :CASE. When :CASE is executed, <BUILDS causes the word following :CASE to be included in the FORTH language. The ] causes FORTH to enter the compile mode. DOES> terminates compile time portion of the : definition and initiates the execution time portion of the definition.

The functions of <BUILDS and DOES> are best understood by looking at an example of a new word, COLOR. The compile time behavior of COLOR can be defined with :CASE by

:CASE COLOR RED WHITE BLUE [ OK

where [ means “enter the interpret state”. :CASE is executed directly by issuing the above command sequence. Its first action is to execute <BUILDS which creates a new FORTH word called COLOR. The ] places FORTH in the compile state. All subsequent words encountered are compiled rather than executed until the [ places FORTH back in the interpret state.

FORTH uses less memory and runs at higher speeds than most high-level languages

FORTH object code can frequently be decompiled. :CASE, RED, WHITE, and BLUE were decompiled using a decompiler written in FORTH. This decompiler was unable to decompile DOES> because it was written largely in machine code and COLOR. COLOR was dumped in hexadecimal to the screen and manually decompiled. Decompilations of these words are shown below. The ;S is the execution time code of ; and : stands for the execution time code (DOCOL) of : . DODOES is the execution time code of DOES>.

Decompilations of :CASE, RED, WHITE, BLUE, DOES> and COLOR
Decompilations of :CASE, RED, WHITE, BLUE, DOES> and COLOR

DODOES causes (1) a pointer to the pointer to RED to be placed at the top of the parameter stack; (2) SWAP to be executed. COLOR can be exercised by

0 COLOR REDOK
1 COLOR WHITEOK
2 COLOR BLUEOK

and the execution time behavior of :CASE can be understood by tracing execution of its DOES> portion for 1 COLOR. At the beginning of execution of SWAP the parameter stack contains the material shown in figure 1.

Figure 1. Parameter stack trace of the DOES> portion of :CASE for 1 COLOR
Figure 1. Parameter stack trace of the DOES> portion of :CASE for 1 COLOR

Assembler programs can be written in FORTH without leaving FORTH. The Z80 Stack Pointer register, SP, points to the top of the Z80 FORTH parameter stack. A FORTH assembler routine which doubles the number at the top of the parameter stack is

CODE DOUBLE HL POP HL, HL ADD HL PUSH NEXT OK

DOUBLE can be used like this:

2 DOUBLE .4 OK

and within a FORTH high-level statement. For example,

: IDOUBLE 1 DO I DOUBLE . LOOP ; OK

exercised by 10 IDOUBLE

2 4 6 8 10 12 14 16 18 OK

Even FORTH’s assembler requires writing the Z80 mnemonics in a type of reverse Polish: HL POP for POP HL; HL, HL ADD for ADD HL,HL; and HL PUSH for PUSH HL.

Most FORTHs include a line editor, a mini full screen editor, and complete full screen editor.

Sinclair’s FORTH

This introductory description of the FORTH software technology will give enough background that readers can understand how Sinclair’s software engineers put the FORTH software technology to use to write ZX81 BASIC.

Sinclair’s FORTH can be viewed as composed of three stacks. These stacks are

1. A parameter stack which is five bytes wide (also called the calculator stack. This stack expands upward in memory.

2. A return stack which is normally two bytes wide. This stack expands downward in memory and is the Z80 machine stack which is pointed to by stack pointer register SP.

3. A word dictionary stack which is one byte wide and expands upward in memory.

Values on a BASIC parameter stack are assigned a type attribute. ZX81 BASIC has the type attributes of number and string. Two data structures contained in the five-byte values on the parameter stack are shown in figure 2.

Figure 2

        Number                              String
Offset                              Offset
  0     Sign and value of exponent    0     Unused
                                      1-2   Pointer to start of string
  1-4   Sign and value of mantissa    3-4   Length of string

The type attribute is contained in bit 6 of the ZX81 system variable called FLAGS (Bit 6 = 1 for a number and 0 for a string).

Sinclair’s one byte FORTH word dictionary operates by ZX81 BASIC doubling the byte value and using the resulting number as an offset into a table which contains a pointer to the executable word code.

As an example of some of the values in the table, their Sinclair definition, and comparable FORTH definition:

Value   Sinclair       FORTH
        definition     definition
 00     Jump-true
 01     exchange       SWAP
 02     delete         DROP
 03     subtract       —
 04     multiply       *
 05     division       /
  •        •           •
  •        •           •
 2D     duplicate      DUP
  •        •           •
  •        •           •
 3C     get-mem-O etc.

An example of a :-type high-level language Sinclair FORTH program contained in the ZX81 BASIC is N mod M. N mod M is not available for use through normal T/S1000,ZX81 keyboard entries but is available for use through USR calls. N mod M computes both a quotient and remainder of N divided by M. For example 5 divided by 3 leaves a quotient of 1 and a remainder of 2. In terms of Before and After stack frames (several stack values considered as a unit)

Before - After stack frames for 5 mod 3
Before – After stack frames for 5 mod 3

Sinclair’s FORTH allows storing or retrieving numbers from or to the top of the parameter stack. GETO and STOREO respectively fetch the contents of memory 0 to the top of the parameter stack and stores the value at the top of the parameter stack to memory 0. The definition of N mod M written with FORTH-like mnemonics is

N mod M trace: word, parameter stack and memory 0
N mod M trace: word, parameter stack and memory 0
N mod M trace: word, parameter stack and memory 0
N mod M trace: word, parameter stack and memory 0

Sinclair’s FORTH words of INT, *, / and — are available from the keyboard but SWAP, DUP, DROP, STOREO, and GETO are not. While N mod M was a high-level language word definition, many of Sinclair’s FORTH words are CODE-type (machine language) definitions or even combinations of both.

Sinclair’s FORTH decomposes numbers into numbers and logical types. A numeric O is a logical FALSE while a non-zero numeric is logical type TRUE.

Numbers can be compared in Sinclair’s FORTH and forward or backward conditional jumps can be made depending on the logical value contained at the top of the parameter stack.

Sinclair’s FORTH facilitates compiling constants into a compiled :-type definition, and pushing several predefined constants such as Pi onto the parameter stack.

In summary, the T/S1000’s BASIC was implemented in large part using the advanced FORTH software technology. FORTH is currently regarded as an underground language. FORTH resides in video games, word processors, camera controllers, and so on. The FORTH software technology resides in likely the most widely distributed software package ever written. This is the T/S1000’s ZX81 BASIC language system.

For further reading

The FORTH programs contained in this article were written in Laboratory Microsystems ZX80 FORTH implemented on a CD110 and PC FORTH implemented for the IBM PC. The bulletined FORTH attributes were adapted from Peter Kogge’s article Architectural trail to threaded codes languages, IEEE Computer, March 1982 and Ray Duncan’s PC FORTH documentation. Ian Logan‘s Sinclair ZX81 ROM Disassembly, Part A 0000H-0F54H Melbourne House, 1981 and Ian Logan’s and Frank O’Hara‘s Sinclair ZX81 ROM Disassembly, Part B 0F55H-1DFFH, Melbourne House, 1982, gives detailed comments on the ZX81 BASIC language Z80 machine language disassembly. I recommend Starting FORTH by Leo Brodie, published by Prentice-Hall, 1981, for learning introductory FORTH, FORTH Encyclopedia by Mitch Derick and Linda Baker, published by Mountain View Press, 1982, for learning FORTH internals, and Implementing BASICs: How Basics Work by William and Patricia Payne, published by Reston/Prentice-Hall, 1982, for learning about BASIC language system design.