This file documents GNU Forth 0.0

Copyright © 1994 GNU Forth Development Group

Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies.

Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided also that the sections entitled "Distribution" and "General Public License" are included exactly as in the original, and provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one.

Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions, except that the sections entitled "Distribution" and "General Public License" may be included in a translation approved by the author instead of in the original English.

GNU Forth is a free implementation of ANS Forth available on many personal machines. This manual corresponds to version 0.0.

License
*******

!! Insert GPL here

Goals of GNU Forth
******************

The goal of the GNU Forth Project is to develop a standard model for ANSI Forth. This can be split into several subgoals:

  * GNU Forth should conform to the ANSI Forth standard.

  * It should be a model, i.e. it should define all the implementation-dependent things.

  * It should become standard, i.e. widely accepted and used. This goal is the most difficult one.

To achieve these goals GNU Forth should be

  * Similar to previous models (fig-Forth, F83)

  * Powerful. It should provide for all the things that are considered necessary today and even some that are not yet considered necessary.

  * Efficient. It should not get the reputation of being exceptionally slow.

  * Free.

  * Available on many machines/easy to port.

Have we achieved these goals? GNU Forth conforms to the ANS Forth standard; it may be considered a model, but we have not yet documented which parts of the model are stable and which parts we are likely to change; it certainly has not yet become a de facto standard. It has some similarities and some differences to previous models; It has some powerful features, but not yet everything that we envisioned; on RISCs it is as fast as interpreters programmed in assembly, on register-starved machines it is not so fast, but still faster than any other C-based interpretive implementation; it is free and available on many machines.

Other books on ANS Forth
************************

As the standard is relatively new, there are not many books out yet. It is not recommended to learn Forth by using GNU Forth and a book that is not written for ANS Forth, as you will not know your mistakes from the deviations of the book.

There is, of course, the standard, the definite reference if you want to write ANS Forth programs. It will be available in printed form from !! somtime in spring or summer 1994. If you are lucky, you can still get dpANS6 (the draft that was approved as standard) by aftp from ftp.uu.net:/vendor/minerva/x3j14.

Forth: The new model by Jack Woehr (!! Publisher) is an introductory book based on a draft version of the standard. It does not cover the whole standard. It also contains interesting background information (Jack Woehr was in the ANS Forth Technical Committe).

Invocation
**********

You will usually just say gforth. More generally, the default GNU Forth image can be invoked like this

     gforth [--batch] [files] [-e forth-code]

The --batch option makes gforth exit after processing the command line. Also, the startup message is suppressed. files are Forth source files that are executed in the order in which they appear. The -e forth-code or --evaluate forth-code option evaluates the forth code; it can be freely mixed with the files. This option takes only one argument; if you want to evaluate more Forth words, you have to quote them or use several -es. !! option for suppressing default loading.

You can use the command line option -i file or --image-file file to specify a different image file. Note that this option must be the first in the command line. The rest of the command line is processed by the image file.

If the --image-file option is not used, GNU Forth searches for a file named gforth.fi in the path specified by the environment variable GFORTHPATH; if this does not exist, in /usr/local/lib/gforth and in /usr/lib/gforth.

Forth Words
***********

Notation
========

The Forth words are described in this section in the glossary notation that has become a de-facto standard for Forth texts, i.e.

     word     Stack effect     pronunciation   wordset Description

word
     The name of the word. BTW, GNU Forth is case insensitive, so you can type the words in in lower case.

Stack effect
     The stack effect is written in the notation before -- after, where before and after describe the top of stack entries before and after the execution of the word. The rest of the stack is not touched by the word. The top of stack is rightmost, i.e., a stack sequence is written as it is typed in. Note that GNU Forth uses a separate floating point stack, but a unified stack notation. Also, return stack effects are not shown in stack effect, but in Description. The name of a stack item describes the type and/or the function of the item. See below for a discussion of the types.

pronunciation
     How the word is pronounced

wordset
     The ANS Forth standard is divided into several wordsets. A standard system need not support all of them. So, the fewer wordsets your program uses the more portable it will be in theory. However, we suspect that most ANS Forth systems on personal machines will feature all wordsets. Words that are not defined in the ANS standard have gforth as wordset.

Description
     A description of the behaviour of the word.

The name of a stack item corresponds in the following way with its type:

name starts with
     Type

f
     Bool, i.e. false or true.

c
     Char

w
     Cell, can contain an integer or an address

n
     signed integer

u
     unsigned integer

d
     double sized signed integer

ud
     double sized unsigned integer

r
     Float

a_
     Cell-aligned address

c_
     Char-aligned address (note that a Char is two bytes in Windows NT)

f_
     Float-aligned address

df_
     Address aligned for IEEE double precision float

sf_
     Address aligned for IEEE single precision float

xt
     Execution token, same size as Cell

wid
     Wordlist ID, same size as Cell

f83name
     Pointer to a name structure

Arithmetic
==========

Forth arithmetic is not checked, i.e., you will not hear about integer overflow on addition or multiplication, you may hear about division by zero if you are lucky. The operator is written after the operands, but the operands are still in the original order. I.e., the infix 2-1 corresponds to 2 1 -. Forth offers a variety of division operators. If you perform division with potentially negative operands, you do not want to use / or /mod with its undefined behaviour, but rather fm/mod or sm/mod (probably the former).

Single precision
----------------

+ - * / mod /mod negate abs min max

Bitwise operations
------------------

and or xor invert 2* 2/

Mixed precision
---------------

m+ */ */mod m* um* m*/ um/mod fm/mod sm/rem

Double precision
----------------

d+ d- dnegate dabs dmin dmax

Stack Manipulation
==================

gforth has a data stack (aka parameter stack) for characters, cells, addresses, and double cells, a floating point stack for floating point numbers, a return stack for storing the return addresses of colon definitions and other data, and a locals stack for storing local variables. Note that while every sane Forth has a separate floating point stack, this is not strictly required; an ANS Forth system could theoretically keep floating point numbers on the data stack. As an additional difficulty, you don't know how many cells a floating point numkber takes. It is reportedly possible to write words in a way that they work also for a unified stack model, but we do not recommend trying it. Also, a Forth system is allowed to keep the local variables on the return stack. This is reasonable, as local variables usually eliminate the need to use the return stack explicitely. So, if you want to produce a standard complying program and if you are using local variables in a word, forget about return stack manipulations in that word (see the standard document for the exact rules).

Data stack
----------

drop nip dup over tuck swap rot -rot ?dup pick roll 2drop 2nip 2dup 2over 2tuck 2swap 2rot

Floating point stack
--------------------

fdrop fnip fdup fover ftuck fswap frot

Return stack
------------

>r r> r rdrop 2>r 2r>

Locals stack
------------

Stack pointer manipulation
--------------------------

sp sp! fp fp! rp rp! lp lp!

Memory access
=============

Stack-Memory transfers
----------------------

! +! c c! 2 2! f f! sf sf! df df!

Memory block access
-------------------

move erase

While the previous words work on address units, the rest works on characters.

cmove cmove> fill blank

Control Structures
==================

Control structures in Forth cannot be used in interpret state, only in compile state, i.e., in a colon definition. We do not like this limitation, but have not seen a satisfying way around it yet, although many schemes have been proposed.

Selection
---------

     FLAG
     IF
       CODE
     ENDIF

or

     FLAG
     IF
       CODE1
     ELSE
       CODE2
     ENDIF

You can use THEN instead of ENDIF. Indeed, THEN is standard, and ENDIF is not, although it is quite popular. We recommend using ENDIF, because it is less confusing for people who also know other languages (and is not prone to reinforcing negative prejudices against Forth in these people). Adding ENDIF to a system that only supplies THEN is simple:

     : endif   POSTPONE then ; immediate

[According to Webster's New Encyclopedic Dictionary, then (adv.)  has the following meanings:

     ... 2b: following next after in order ... 3d: as a necessary consequence (if you were there, then you saw them).

Forth's THEN has the meaning 2b, THEN in Pascal and many other programming languages has the meaning 3d.]

We also provide the words ?dup-if and ?dup-0=-if, so you can avoid using ?dup.

     N
     CASE
       N1 OF CODE1 ENDOF
       N2 OF CODE2 ENDOF
       ...
     ENDCASE

Executes the first CODEI, where the NI is equal to N. A default case can be added by simply writing the code after the last ENDOF. It may use N, which is on top of the stack, but must not consume it.

Simple Loops
------------

     BEGIN
       CODE1
       FLAG
     WHILE
       CODE2
     REPEAT

CODE1 is executed and FLAG is computed. If it is true, CODE2 is executed and the loop is restarted; If FLAG is false, execution continues after the REPEAT.

     BEGIN
       CODE
       FLAG
     UNTIL

CODE is executed. The loop is restarted if flag is false.

     BEGIN
       CODE
     AGAIN

This is an endless loop.

Counted Loops
-------------

The basic counted loop is:

     LIMIT START
     ?DO
       BODY
     LOOP

This performs one iteration for every integer, starting from START and up to, but excluding LIMIT. The counter, aka index, can be accessed with i. E.g., the loop

     10 0 ?DO
       i .
     LOOP

prints

     0 1 2 3 4 5 6 7 8 9

The index of the innermost loop can be accessed with i, the index of the next loop with j, and the index of the third loop with k.

The loop control data are kept on the return stack, so there are some restrictions on mixing return stack accesses and counted loop words. E.g., if you put values on the return stack outside the loop, you cannot read them inside the loop. If you put values on the return stack within a loop, you have to remove them before the end of the loop and before accessing the index of the loop.

There are several variations on the counted loop:

LEAVE leaves the innermost counted loop immediately.

LOOP can be replaced with N +LOOP; this updates the index by N instead of by 1. The loop is terminated when the border between LIMIT-1 and LIMIT is crossed. E.g.:

4 0 ?DO  i .  2 +LOOP   prints 0 2

4 1 ?DO  i .  2 +LOOP   prints 1 3

The behaviour of N +LOOP is peculiar when N is negative:

-1 0 ?DO  i .  -1 +LOOP  prints 0 -1

0 0 ?DO  i .  -1 +LOOP  prints nothing

Therefore we recommend avoiding using N +LOOP with negative N. One alternative is N S+LOOP, where the negative case behaves symmetrical to the positive case:

-2 0 ?DO  i .  -1 +LOOP  prints 0 -1

-1 0 ?DO  i .  -1 +LOOP  prints 0

0 0 ?DO  i .  -1 +LOOP  prints nothing

The loop is terminated when the border between LIMIT-SGN(N) and LIMIT is crossed. However, S+LOOP is not part of the ANS Forth standard.

?DO can be replaced by DO. DO enters the loop even when the start and the limit value are equal. We do not recommend using DO. It will just give you maintenance troubles.

UNLOOP is used to prepare for an abnormal loop exit, e.g., via EXIT. UNLOOP removes the loop control parameters from the return stack so EXIT can get to its return address.

Another counted loop is

     N
     FOR
       BODY
     NEXT

This is the preferred loop of native code compiler writers who are too lazy to optimize ?DO loops properly. In GNU Forth, this loop iterates N+1 times; i produces values starting with N and ending with 0. Other Forth systems may differently, even if they support FOR loops.