This is gforth.info, produced by makeinfo version 4.13 from gforth.texi.

This manual is for Gforth (version 0.7.3, June 14, 2014), a fast and
portable implementation of the ANS Forth language.  It serves as
reference manual, but it also contains an introduction to Forth and a
Forth tutorial.

   Copyright (C) 1995, 1996, 1997, 1998, 2000, 2003,
2004,2005,2006,2007,2008 Free Software Foundation, Inc.

     Permission is granted to copy, distribute and/or modify this
     document under the terms of the GNU Free Documentation License,
     Version 1.1 or any later version published by the Free Software
     Foundation; with no Invariant Sections, with the Front-Cover texts
     being "A GNU Manual," and with the Back-Cover Texts as in (a)
     below.  A copy of the license is included in the section entitled
     "GNU Free Documentation License."

     (a) The FSF's Back-Cover Text is: "You have freedom to copy and
     modify this GNU Manual, like GNU software.  Copies published by
     the Free Software Foundation raise funds for GNU development."

INFO-DIR-SECTION Software development
START-INFO-DIR-ENTRY
* Gforth: (gforth).             A fast interpreter for the Forth language.
END-INFO-DIR-ENTRY


File: gforth.info,  Node: Top,  Next: Goals,  Prev: (dir),  Up: (dir)

Gforth
******

This manual is for Gforth (version 0.7.3, June 14, 2014), a fast and
portable implementation of the ANS Forth language.  It serves as
reference manual, but it also contains an introduction to Forth and a
Forth tutorial.

   Copyright (C) 1995, 1996, 1997, 1998, 2000, 2003,
2004,2005,2006,2007,2008 Free Software Foundation, Inc.

     Permission is granted to copy, distribute and/or modify this
     document under the terms of the GNU Free Documentation License,
     Version 1.1 or any later version published by the Free Software
     Foundation; with no Invariant Sections, with the Front-Cover texts
     being "A GNU Manual," and with the Back-Cover Texts as in (a)
     below.  A copy of the license is included in the section entitled
     "GNU Free Documentation License."

     (a) The FSF's Back-Cover Text is: "You have freedom to copy and
     modify this GNU Manual, like GNU software.  Copies published by
     the Free Software Foundation raise funds for GNU development."

* Menu:

* Goals::                       About the Gforth Project
* Gforth Environment::          Starting (and exiting) Gforth
* Tutorial::                    Hands-on Forth Tutorial
* Introduction::                An introduction to ANS Forth
* Words::                       Forth words available in Gforth
* Error messages::              How to interpret them
* Tools::                       Programming tools
* ANS conformance::             Implementation-defined options etc.
* Standard vs Extensions::      Should I use extensions?
* Model::                       The abstract machine of Gforth
* Integrating Gforth::          Forth as scripting language for applications
* Emacs and Gforth::            The Gforth Mode
* Image Files::                 `.fi' files contain compiled code
* Engine::                      The inner interpreter and the primitives
* Cross Compiler::              The Cross Compiler
* Bugs::                        How to report them
* Origin::                      Authors and ancestors of Gforth
* Forth-related information::   Books and places to look on the WWW
* Licenses::
* Word Index::                  An item for each Forth word
* Concept Index::               A menu covering many topics

 --- The Detailed Node Listing ---

Gforth Environment

* Invoking Gforth::             Getting in
* Leaving Gforth::              Getting out
* Command-line editing::
* Environment variables::       that affect how Gforth starts up
* Gforth Files::                What gets installed and where
* Gforth in pipes::
* Startup speed::               When 35ms is not fast enough ...

Forth Tutorial

* Starting Gforth Tutorial::
* Syntax Tutorial::
* Crash Course Tutorial::
* Stack Tutorial::
* Arithmetics Tutorial::
* Stack Manipulation Tutorial::
* Using files for Forth code Tutorial::
* Comments Tutorial::
* Colon Definitions Tutorial::
* Decompilation Tutorial::
* Stack-Effect Comments Tutorial::
* Types Tutorial::
* Factoring Tutorial::
* Designing the stack effect Tutorial::
* Local Variables Tutorial::
* Conditional execution Tutorial::
* Flags and Comparisons Tutorial::
* General Loops Tutorial::
* Counted loops Tutorial::
* Recursion Tutorial::
* Leaving definitions or loops Tutorial::
* Return Stack Tutorial::
* Memory Tutorial::
* Characters and Strings Tutorial::
* Alignment Tutorial::
* Floating Point Tutorial::
* Files Tutorial::
* Interpretation and Compilation Semantics and Immediacy Tutorial::
* Execution Tokens Tutorial::
* Exceptions Tutorial::
* Defining Words Tutorial::
* Arrays and Records Tutorial::
* POSTPONE Tutorial::
* Literal Tutorial::
* Advanced macros Tutorial::
* Compilation Tokens Tutorial::
* Wordlists and Search Order Tutorial::

An Introduction to ANS Forth

* Introducing the Text Interpreter::
* Stacks and Postfix notation::
* Your first definition::
* How does that work?::
* Forth is written in Forth::
* Review - elements of a Forth system::
* Where to go next::
* Exercises::

Forth Words

* Notation::
* Case insensitivity::
* Comments::
* Boolean Flags::
* Arithmetic::
* Stack Manipulation::
* Memory::
* Control Structures::
* Defining Words::
* Interpretation and Compilation Semantics::
* Tokens for Words::
* Compiling words::
* The Text Interpreter::
* The Input Stream::
* Word Lists::
* Environmental Queries::
* Files::
* Blocks::
* Other I/O::
* OS command line arguments::
* Locals::
* Structures::
* Object-oriented Forth::
* Programming Tools::
* C Interface::
* Assembler and Code Words::
* Threading Words::
* Passing Commands to the OS::
* Keeping track of Time::
* Miscellaneous Words::

Arithmetic

* Single precision::
* Double precision::            Double-cell integer arithmetic
* Bitwise operations::
* Numeric comparison::
* Mixed precision::             Operations with single and double-cell integers
* Floating Point::

Stack Manipulation

* Data stack::
* Floating point stack::
* Return stack::
* Locals stack::
* Stack pointer manipulation::

Memory

* Memory model::
* Dictionary allocation::
* Heap Allocation::
* Memory Access::
* Address arithmetic::
* Memory Blocks::

Control Structures

* Selection::                   IF ... ELSE ... ENDIF
* Simple Loops::                BEGIN ...
* Counted Loops::               DO
* Arbitrary control structures::
* Calls and returns::
* Exception Handling::

Defining Words

* CREATE::
* Variables::                   Variables and user variables
* Constants::
* Values::                      Initialised variables
* Colon Definitions::
* Anonymous Definitions::       Definitions without names
* Supplying names::             Passing definition names as strings
* User-defined Defining Words::
* Deferred Words::              Allow forward references
* Aliases::

User-defined Defining Words

* CREATE..DOES> applications::
* CREATE..DOES> details::
* Advanced does> usage example::
* Const-does>::

Interpretation and Compilation Semantics

* Combined words::

Tokens for Words

* Execution token::             represents execution/interpretation semantics
* Compilation token::           represents compilation semantics
* Name token::                  represents named words

Compiling words

* Literals::                    Compiling data values
* Macros::                      Compiling words

The Text Interpreter

* Input Sources::
* Number Conversion::
* Interpret/Compile states::
* Interpreter Directives::

Word Lists

* Vocabularies::
* Why use word lists?::
* Word list example::

Files

* Forth source files::
* General files::
* Redirection::
* Search Paths::

Search Paths

* Source Search Paths::
* General Search Paths::

Other I/O

* Simple numeric output::       Predefined formats
* Formatted numeric output::    Formatted (pictured) output
* String Formats::              How Forth stores strings in memory
* Displaying characters and strings::  Other stuff
* Terminal output::             Cursor positioning etc.
* Single-key input::
* Line input and conversion::
* Pipes::                       How to create your own pipes
* Xchars and Unicode::          Non-ASCII characters

Locals

* Gforth locals::
* ANS Forth locals::

Gforth locals

* Where are locals visible by name?::
* How long do locals live?::
* Locals programming style::
* Locals implementation::

Structures

* Why explicit structure support?::
* Structure Usage::
* Structure Naming Convention::
* Structure Implementation::
* Structure Glossary::
* Forth200x Structures::

Object-oriented Forth

* Why object-oriented programming?::
* Object-Oriented Terminology::
* Objects::
* OOF::
* Mini-OOF::
* Comparison with other object models::

The `objects.fs' model

* Properties of the Objects model::
* Basic Objects Usage::
* The Objects base class::
* Creating objects::
* Object-Oriented Programming Style::
* Class Binding::
* Method conveniences::
* Classes and Scoping::
* Dividing classes::
* Object Interfaces::
* Objects Implementation::
* Objects Glossary::

The `oof.fs' model

* Properties of the OOF model::
* Basic OOF Usage::
* The OOF base class::
* Class Declaration::
* Class Implementation::

The `mini-oof.fs' model

* Basic Mini-OOF Usage::
* Mini-OOF Example::
* Mini-OOF Implementation::

Programming Tools

* Examining::                   Data and Code.
* Forgetting words::            Usually before reloading.
* Debugging::                   Simple and quick.
* Assertions::                  Making your programs self-checking.
* Singlestep Debugger::         Executing your program word by word.

C Interface

* Calling C Functions::
* Declaring C Functions::
* Calling C function pointers::
* Defining library interfaces::
* Declaring OS-level libraries::
* Callbacks::
* C interface internals::
* Low-Level C Interface Words::

Assembler and Code Words

* Code and ;code::
* Common Assembler::            Assembler Syntax
* Common Disassembler::
* 386 Assembler::               Deviations and special cases
* Alpha Assembler::             Deviations and special cases
* MIPS assembler::              Deviations and special cases
* PowerPC assembler::           Deviations and special cases
* ARM Assembler::               Deviations and special cases
* Other assemblers::            How to write them

Tools

* ANS Report::                  Report the words used, sorted by wordset.
* Stack depth changes::         Where does this stack item come from?

ANS conformance

* The Core Words::
* The optional Block word set::
* The optional Double Number word set::
* The optional Exception word set::
* The optional Facility word set::
* The optional File-Access word set::
* The optional Floating-Point word set::
* The optional Locals word set::
* The optional Memory-Allocation word set::
* The optional Programming-Tools word set::
* The optional Search-Order word set::

The Core Words

* core-idef::                   Implementation Defined Options
* core-ambcond::                Ambiguous Conditions
* core-other::                  Other System Documentation

The optional Block word set

* block-idef::                  Implementation Defined Options
* block-ambcond::               Ambiguous Conditions
* block-other::                 Other System Documentation

The optional Double Number word set

* double-ambcond::              Ambiguous Conditions

The optional Exception word set

* exception-idef::              Implementation Defined Options

The optional Facility word set

* facility-idef::               Implementation Defined Options
* facility-ambcond::            Ambiguous Conditions

The optional File-Access word set

* file-idef::                   Implementation Defined Options
* file-ambcond::                Ambiguous Conditions

The optional Floating-Point word set

* floating-idef::               Implementation Defined Options
* floating-ambcond::            Ambiguous Conditions

The optional Locals word set

* locals-idef::                 Implementation Defined Options
* locals-ambcond::              Ambiguous Conditions

The optional Memory-Allocation word set

* memory-idef::                 Implementation Defined Options

The optional Programming-Tools word set

* programming-idef::            Implementation Defined Options
* programming-ambcond::         Ambiguous Conditions

The optional Search-Order word set

* search-idef::                 Implementation Defined Options
* search-ambcond::              Ambiguous Conditions

Emacs and Gforth

* Installing gforth.el::        Making Emacs aware of Forth.
* Emacs Tags::                  Viewing the source of a word in Emacs.
* Hilighting::                  Making Forth code look prettier.
* Auto-Indentation::            Customizing auto-indentation.
* Blocks Files::                Reading and writing blocks files.

Image Files

* Image Licensing Issues::      Distribution terms for images.
* Image File Background::       Why have image files?
* Non-Relocatable Image Files::  don't always work.
* Data-Relocatable Image Files::  are better.
* Fully Relocatable Image Files::  better yet.
* Stack and Dictionary Sizes::  Setting the default sizes for an image.
* Running Image Files::         `gforth -i file' or file.
* Modifying the Startup Sequence::  and turnkey applications.

Fully Relocatable Image Files

* gforthmi::                    The normal way
* cross.fs::                    The hard way

Engine

* Portability::
* Threading::
* Primitives::
* Performance::

Threading

* Scheduling::
* Direct or Indirect Threaded?::
* Dynamic Superinstructions::
* DOES>::

Primitives

* Automatic Generation::
* TOS Optimization::
* Produced code::

Cross Compiler

* Using the Cross Compiler::
* How the Cross Compiler Works::

Licenses

* GNU Free Documentation License::  License for copying this manual.
* Copying::                     GPL (for copying this software).


File: gforth.info,  Node: Goals,  Next: Gforth Environment,  Prev: Top,  Up: Top

1 Goals of Gforth
*****************

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

   * Gforth should conform to the ANS 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 Gforth 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? Gforth 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, but it
appears to be quite popular. It has some similarities to and some
differences from previous models. It has some powerful features, but not
yet everything that we envisioned. We certainly have achieved our
execution speed goals (*note Performance::)(1).  It is free and
available on many machines.

   ---------- Footnotes ----------

   (1) However, in 1998 the bar was raised when the major commercial
Forth vendors switched to native code compilers.


File: gforth.info,  Node: Gforth Environment,  Next: Tutorial,  Prev: Goals,  Up: Top

2 Gforth Environment
********************

Note: ultimately, the Gforth man page will be auto-generated from the
material in this chapter.

* Menu:

* Invoking Gforth::             Getting in
* Leaving Gforth::              Getting out
* Command-line editing::
* Environment variables::       that affect how Gforth starts up
* Gforth Files::                What gets installed and where
* Gforth in pipes::
* Startup speed::               When 35ms is not fast enough ...

   For related information about the creation of images see *note Image
Files::.


File: gforth.info,  Node: Invoking Gforth,  Next: Leaving Gforth,  Prev: Gforth Environment,  Up: Gforth Environment

2.1 Invoking Gforth
===================

Gforth is made up of two parts; an executable "engine" (named `gforth'
or `gforth-fast') and an image file. To start it, you will usually just
say `gforth' - this automatically loads the default image file
`gforth.fi'. In many other cases the default Gforth image will be
invoked like this:
     gforth [file | -e forth-code] ...
   This interprets the contents of the files and the Forth code in the
order they are given.

   In addition to the `gforth' engine, there is also an engine called
`gforth-fast', which is faster, but gives less informative error
messages (*note Error messages::) and may catch some errors (in
particular, stack underflows and integer division errors) later or not
at all.  You should use it for debugged, performance-critical programs.

   Moreover, there is an engine called `gforth-itc', which is useful in
some backwards-compatibility situations (*note Direct or Indirect
Threaded?::).

   In general, the command line looks like this:

     gforth[-fast] [engine options] [image options]

   The engine options must come before the rest of the command line.
They are:

`--image-file file'
`-i file'
     Loads the Forth image file instead of the default `gforth.fi'
     (*note Image Files::).

`--appl-image file'
     Loads the image file and leaves all further command-line arguments
     to the image (instead of processing them as engine options).  This
     is useful for building executable application images on Unix,
     built with `gforthmi --application ...'.

`--path path'
`-p path'
     Uses path for searching the image file and Forth source code files
     instead of the default in the environment variable `GFORTHPATH' or
     the path specified at installation time (e.g.,
     `/usr/local/share/gforth/0.2.0:.'). A path is given as a list of
     directories, separated by `:' (on Unix) or `;' (on other OSs).

`--dictionary-size size'
`-m size'
     Allocate size space for the Forth dictionary space instead of
     using the default specified in the image (typically 256K). The
     size specification for this and subsequent options consists of an
     integer and a unit (e.g., `4M'). The unit can be one of `b'
     (bytes), `e' (element size, in this case Cells), `k' (kilobytes),
     `M' (Megabytes), `G' (Gigabytes), and `T' (Terabytes). If no unit
     is specified, `e' is used.

`--data-stack-size size'
`-d size'
     Allocate size space for the data stack instead of using the
     default specified in the image (typically 16K).

`--return-stack-size size'
`-r size'
     Allocate size space for the return stack instead of using the
     default specified in the image (typically 15K).

`--fp-stack-size size'
`-f size'
     Allocate size space for the floating point stack instead of using
     the default specified in the image (typically 15.5K). In this case
     the unit specifier `e' refers to floating point numbers.

`--locals-stack-size size'
`-l size'
     Allocate size space for the locals stack instead of using the
     default specified in the image (typically 14.5K).

`--vm-commit'
     Normally, Gforth tries to start up even if there is not enough
     virtual memory for the dictionary and the stacks (using
     `MAP_NORESERVE' on OSs that support it); so you can ask for a
     really big dictionary and/or stacks, and as long as you don't use
     more virtual memory than is available, everything will be fine
     (but if you use more, processes get killed).  With this option you
     just use the default allocation policy of the OS; for OSs that
     don't overcommit (e.g., Solaris), this means that you cannot and
     should not ask for as big dictionary and stacks, but once Gforth
     successfully starts up, out-of-memory won't kill it.

`--help'
`-h'
     Print a message about the command-line options

`--version'
`-v'
     Print version and exit

`--debug'
     Print some information useful for debugging on startup.

`--offset-image'
     Start the dictionary at a slightly different position than would
     be used otherwise (useful for creating data-relocatable images,
     *note Data-Relocatable Image Files::).

`--no-offset-im'
     Start the dictionary at the normal position.

`--clear-dictionary'
     Initialize all bytes in the dictionary to 0 before loading the
     image (*note Data-Relocatable Image Files::).

`--die-on-signal'
     Normally Gforth handles most signals (e.g., the user interrupt
     SIGINT, or the segmentation violation SIGSEGV) by translating it
     into a Forth `THROW'. With this option, Gforth exits if it
     receives such a signal. This option is useful when the engine
     and/or the image might be severely broken (such that it causes
     another signal before recovering from the first); this option
     avoids endless loops in such cases.

`--no-dynamic'

`--dynamic'
     Disable or enable dynamic superinstructions with replication
     (*note Dynamic Superinstructions::).

`--no-super'
     Disable dynamic superinstructions, use just dynamic replication;
     this is useful if you want to patch threaded code (*note Dynamic
     Superinstructions::).

`--ss-number=N'
     Use only the first N static superinstructions compiled into the
     engine (default: use them all; note that only `gforth-fast' has
     any).  This option is useful for measuring the performance impact
     of static superinstructions.

`--ss-min-codesize'

`--ss-min-ls'

`--ss-min-lsu'

`--ss-min-nexts'
     Use specified metric for determining the cost of a primitive or
     static superinstruction for static superinstruction selection.
     `Codesize' is the native code size of the primive or static
     superinstruction, `ls' is the number of loads and stores, `lsu' is
     the number of loads, stores, and updates, and `nexts' is the
     number of dispatches (not taking dynamic superinstructions into
     account), i.e. every primitive or static superinstruction has cost
     1. Default: `codesize' if you use dynamic code generation,
     otherwise `nexts'.

`--ss-greedy'
     This option is useful for measuring the performance impact of
     static superinstructions.  By default, an optimal shortest-path
     algorithm is used for selecting static superinstructions.  With
     `--ss-greedy' this algorithm is modified to assume that anything
     after the static superinstruction currently under consideration is
     not combined into static superinstructions.  With `--ss-min-nexts'
     this produces the same result as a greedy algorithm that always
     selects the longest superinstruction available at the moment.
     E.g., if there are superinstructions AB and BCD, then for the
     sequence A B C D the optimal algorithm will select A BCD and the
     greedy algorithm will select AB C D.

`--print-metrics'
     Prints some metrics used during static superinstruction selection:
     `code size' is the actual size of the dynamically generated code.
     `Metric codesize' is the sum of the codesize metrics as seen by
     static superinstruction selection; there is a difference from `code
     size', because not all primitives and static superinstructions are
     compiled into dynamically generated code, and because of markers.
     The other metrics correspond to the `ss-min-...' options.  This
     option is useful for evaluating the effects of the `--ss-...'
     options.


   As explained above, the image-specific command-line arguments for the
default image `gforth.fi' consist of a sequence of filenames and `-e
FORTH-CODE' options that are interpreted in the sequence in which they
are given. The `-e FORTH-CODE' or `--evaluate FORTH-CODE' option
evaluates the Forth code. This option takes only one argument; if you
want to evaluate more Forth words, you have to quote them or use `-e'
several times. To exit after processing the command line (instead of
entering interactive mode) append `-e bye' to the command line.  You
can also process the command-line arguments with a Forth program (*note
OS command line arguments::).

   If you have several versions of Gforth installed, `gforth' will
invoke the version that was installed last. `gforth-version' invokes a
specific version. If your environment contains the variable
`GFORTHPATH', you may want to override it by using the `--path' option.

   Not yet implemented: On startup the system first executes the system
initialization file (unless the option `--no-init-file' is given; note
that the system resulting from using this option may not be ANS Forth
conformant). Then the user initialization file `.gforth.fs' is
executed, unless the option `--no-rc' is given; this file is searched
for in `.', then in `~', then in the normal path (see above).


File: gforth.info,  Node: Leaving Gforth,  Next: Command-line editing,  Prev: Invoking Gforth,  Up: Gforth Environment

2.2 Leaving Gforth
==================

You can leave Gforth by typing `bye' or `Ctrl-d' (at the start of a
line) or (if you invoked Gforth with the `--die-on-signal' option)
`Ctrl-c'. When you leave Gforth, all of your definitions and data are
discarded.  For ways of saving the state of the system before leaving
Gforth see *note Image Files::.

`bye'       -         tools-ext       "bye"
   Return control to the host operating system (if any).


File: gforth.info,  Node: Command-line editing,  Next: Environment variables,  Prev: Leaving Gforth,  Up: Gforth Environment

2.3 Command-line editing
========================

Gforth maintains a history file that records every line that you type to
the text interpreter. This file is preserved between sessions, and is
used to provide a command-line recall facility; if you type `Ctrl-P'
repeatedly you can recall successively older commands from this (or
previous) session(s). The full list of command-line editing facilities
is:

   * `Ctrl-p' ("previous") (or up-arrow) to recall successively older
     commands from the history buffer.

   * `Ctrl-n' ("next") (or down-arrow) to recall successively newer
     commands from the history buffer.

   * `Ctrl-f' (or right-arrow) to move the cursor right,
     non-destructively.

   * `Ctrl-b' (or left-arrow) to move the cursor left,
     non-destructively.

   * `Ctrl-h' (backspace) to delete the character to the left of the
     cursor, closing up the line.

   * `Ctrl-k' to delete ("kill") from the cursor to the end of the line.

   * `Ctrl-a' to move the cursor to the start of the line.

   * `Ctrl-e' to move the cursor to the end of the line.

   * <RET> (`Ctrl-m') or <LFD> (`Ctrl-j') to submit the current line.

   * <TAB> to step through all possible full-word completions of the
     word currently being typed.

   * `Ctrl-d' on an empty line line to terminate Gforth (gracefully,
     using `bye').

   * `Ctrl-x' (or `Ctrl-d' on a non-empty line) to delete the character
     under the cursor.

   When editing, displayable characters are inserted to the left of the
cursor position; the line is always in "insert" (as opposed to
"overstrike") mode.

   On Unix systems, the history file is `~/.gforth-history' by
default(1). You can find out the name and location of your history file
using:

     history-file type \ Unix-class systems

     history-file type \ Other systems
     history-dir  type

   If you enter long definitions by hand, you can use a text editor to
paste them out of the history file into a Forth source file for reuse at
a later time.

   Gforth never trims the size of the history file, so you should do
this periodically, if necessary.

   ---------- Footnotes ----------

   (1) i.e. it is stored in the user's home directory.


File: gforth.info,  Node: Environment variables,  Next: Gforth Files,  Prev: Command-line editing,  Up: Gforth Environment

2.4 Environment variables
=========================

Gforth uses these environment variables:

   * `GFORTHHIST' - (Unix systems only) specifies the directory in
     which to open/create the history file, `.gforth-history'. Default:
     `$HOME'.

   * `GFORTHPATH' - specifies the path used when searching for the
     gforth image file and for Forth source-code files.

   * `LANG' - see `LC_CTYPE'

   * `LC_ALL' - see `LC_CTYPE'

   * `LC_CTYPE' - If this variable contains "UTF-8" on Gforth startup,
     Gforth uses the UTF-8 encoding for strings internally and expects
     its input and produces its output in UTF-8 encoding, otherwise the
     encoding is 8bit (see *note Xchars and Unicode::).  If this
     environment variable is unset, Gforth looks in `LC_ALL', and if
     that is unset, in `LANG'.

   * `GFORTHSYSTEMPREFIX' - specifies what to prepend to the argument
     of `system' before passing it to C's `system()'.  Default:
     `"./$COMSPEC /c "' on Windows, `""' on other OSs.  The prefix and
     the command are directly concatenated, so if a space between them
     is necessary, append it to the prefix.

   * `GFORTH' - used by `gforthmi', *Note gforthmi::.

   * `GFORTHD' - used by `gforthmi', *Note gforthmi::.

   * `TMP', `TEMP' - (non-Unix systems only) used as a potential
     location for the history file.

   All the Gforth environment variables default to sensible values if
they are not set.


File: gforth.info,  Node: Gforth Files,  Next: Gforth in pipes,  Prev: Environment variables,  Up: Gforth Environment

2.5 Gforth files
================

When you install Gforth on a Unix system, it installs files in these
locations by default:

   * `/usr/local/bin/gforth'

   * `/usr/local/bin/gforthmi'

   * `/usr/local/man/man1/gforth.1' - man page.

   * `/usr/local/info' - the Info version of this manual.

   * `/usr/local/lib/gforth/<version>/...' - Gforth `.fi' files.

   * `/usr/local/share/gforth/<version>/TAGS' - Emacs TAGS file.

   * `/usr/local/share/gforth/<version>/...' - Gforth source files.

   * `.../emacs/site-lisp/gforth.el' - Emacs gforth mode.

   You can select different places for installation by using
`configure' options (listed with `configure --help').


File: gforth.info,  Node: Gforth in pipes,  Next: Startup speed,  Prev: Gforth Files,  Up: Gforth Environment

2.6 Gforth in pipes
===================

Gforth can be used in pipes created elsewhere (described here).  It can
also create pipes on its own (*note Pipes::).

   If you pipe into Gforth, your program should read with `read-file'
or `read-line' from `stdin' (*note General files::).  `Key' does not
recognize the end of input.  Words like `accept' echo the input and are
therefore usually not useful for reading from a pipe.  You have to
invoke the Forth program with an OS command-line option, as you have no
chance to use the Forth command line (the text interpreter would try to
interpret the pipe input).

   You can output to a pipe with `type', `emit', `cr' etc.

   When you write to a pipe that has been closed at the other end,
Gforth receives a SIGPIPE signal ("pipe broken").  Gforth translates
this into the exception `broken-pipe-error'.  If your application does
not catch that exception, the system catches it and exits, usually
silently (unless you were working on the Forth command line; then it
prints an error message and exits).  This is usually the desired
behaviour.

   If you do not like this behaviour, you have to catch the exception
yourself, and react to it.

   Here's an example of an invocation of Gforth that is usable in a
pipe:

     gforth -e ": foo begin pad dup 10 stdin read-file throw dup while \
      type repeat ; foo bye"

   This example just copies the input verbatim to the output.  A very
simple pipe containing this example looks like this:

     cat startup.fs |
     gforth -e ": foo begin pad dup 80 stdin read-file throw dup while \
      type repeat ; foo bye"|
     head

   Pipes involving Gforth's `stderr' output do not work.


File: gforth.info,  Node: Startup speed,  Prev: Gforth in pipes,  Up: Gforth Environment

2.7 Startup speed
=================

If Gforth is used for CGI scripts or in shell scripts, its startup
speed may become a problem.  On a 300MHz 21064a under Linux-2.2.13 with
glibc-2.0.7, `gforth -e bye' takes about 24.6ms user and 11.3ms system
time.

   If startup speed is a problem, you may consider the following ways to
improve it; or you may consider ways to reduce the number of startups
(for example, by using Fast-CGI).

   An easy step that influences Gforth startup speed is the use of the
`--no-dynamic' option; this decreases image loading speed, but
increases compile-time and run-time.

   Another step to improve startup speed is to statically link Gforth,
by building it with `XLDFLAGS=-static'.  This requires more memory for
the code and will therefore slow down the first invocation, but
subsequent invocations avoid the dynamic linking overhead.  Another
disadvantage is that Gforth won't profit from library upgrades.  As a
result, `gforth-static -e bye' takes about 17.1ms user and 8.2ms system
time.

   The next step to improve startup speed is to use a non-relocatable
image (*note Non-Relocatable Image Files::).  You can create this image
with `gforth -e "savesystem gforthnr.fi bye"' and later use it with
`gforth -i gforthnr.fi ...'.  This avoids the relocation overhead and a
part of the copy-on-write overhead.  The disadvantage is that the
non-relocatable image does not work if the OS gives Gforth a different
address for the dictionary, for whatever reason; so you better provide a
fallback on a relocatable image.  `gforth-static -i gforthnr.fi -e bye'
takes about 15.3ms user and 7.5ms system time.

   The final step is to disable dictionary hashing in Gforth.  Gforth
builds the hash table on startup, which takes much of the startup
overhead. You can do this by commenting out the `include hash.fs' in
`startup.fs' and everything that requires `hash.fs' (at the moment
`table.fs' and `ekey.fs') and then doing `make'.  The disadvantages are
that functionality like `table' and `ekey' is missing and that text
interpretation (e.g., compiling) now takes much longer. So, you should
only use this method if there is no significant text interpretation to
perform (the script should be compiled into the image, amongst other
things).  `gforth-static -i gforthnrnh.fi -e bye' takes about 2.1ms
user and 6.1ms system time.


File: gforth.info,  Node: Tutorial,  Next: Introduction,  Prev: Gforth Environment,  Up: Top

3 Forth Tutorial
****************

The difference of this chapter from the Introduction (*note
Introduction::) is that this tutorial is more fast-paced, should be
used while sitting in front of a computer, and covers much more
material, but does not explain how the Forth system works.

   This tutorial can be used with any ANS-compliant Forth; any
Gforth-specific features are marked as such and you can skip them if you
work with another Forth.  This tutorial does not explain all features of
Forth, just enough to get you started and give you some ideas about the
facilities available in Forth.  Read the rest of the manual and the
standard when you are through this.

   The intended way to use this tutorial is that you work through it
while sitting in front of the console, take a look at the examples and
predict what they will do, then try them out; if the outcome is not as
expected, find out why (e.g., by trying out variations of the example),
so you understand what's going on.  There are also some assignments
that you should solve.

   This tutorial assumes that you have programmed before and know what,
e.g., a loop is.

* Menu:

* Starting Gforth Tutorial::
* Syntax Tutorial::
* Crash Course Tutorial::
* Stack Tutorial::
* Arithmetics Tutorial::
* Stack Manipulation Tutorial::
* Using files for Forth code Tutorial::
* Comments Tutorial::
* Colon Definitions Tutorial::
* Decompilation Tutorial::
* Stack-Effect Comments Tutorial::
* Types Tutorial::
* Factoring Tutorial::
* Designing the stack effect Tutorial::
* Local Variables Tutorial::
* Conditional execution Tutorial::
* Flags and Comparisons Tutorial::
* General Loops Tutorial::
* Counted loops Tutorial::
* Recursion Tutorial::
* Leaving definitions or loops Tutorial::
* Return Stack Tutorial::
* Memory Tutorial::
* Characters and Strings Tutorial::
* Alignment Tutorial::
* Floating Point Tutorial::
* Files Tutorial::
* Interpretation and Compilation Semantics and Immediacy Tutorial::
* Execution Tokens Tutorial::
* Exceptions Tutorial::
* Defining Words Tutorial::
* Arrays and Records Tutorial::
* POSTPONE Tutorial::
* Literal Tutorial::
* Advanced macros Tutorial::
* Compilation Tokens Tutorial::
* Wordlists and Search Order Tutorial::


File: gforth.info,  Node: Starting Gforth Tutorial,  Next: Syntax Tutorial,  Prev: Tutorial,  Up: Tutorial

3.1 Starting Gforth
===================

You can start Gforth by typing its name:

     gforth

   That puts you into interactive mode; you can leave Gforth by typing
`bye'.  While in Gforth, you can edit the command line and access the
command line history with cursor keys, similar to bash.


File: gforth.info,  Node: Syntax Tutorial,  Next: Crash Course Tutorial,  Prev: Starting Gforth Tutorial,  Up: Tutorial

3.2 Syntax
==========

A "word" is a sequence of arbitrary characters (except white space).
Words are separated by white space.  E.g., each of the following lines
contains exactly one word:

     word
     !@#$%^&*()
     1234567890
     5!a

   A frequent beginner's error is to leave away necessary white space,
resulting in an error like `Undefined word'; so if you see such an
error, check if you have put spaces wherever necessary.

     ." hello, world" \ correct
     ."hello, world"  \ gives an "Undefined word" error

   Gforth and most other Forth systems ignore differences in case (they
are case-insensitive), i.e., `word' is the same as `Word'.  If your
system is case-sensitive, you may have to type all the examples given
here in upper case.


File: gforth.info,  Node: Crash Course Tutorial,  Next: Stack Tutorial,  Prev: Syntax Tutorial,  Up: Tutorial

3.3 Crash Course
================

Type

     0 0 !
     here execute
     ' catch >body 20 erase abort
     ' (quit) >body 20 erase

   The last two examples are guaranteed to destroy parts of Gforth (and
most other systems), so you better leave Gforth afterwards (if it has
not finished by itself).  On some systems you may have to kill gforth
from outside (e.g., in Unix with `kill').

   Now that you know how to produce crashes (and that there's not much
to them), let's learn how to produce meaningful programs.


File: gforth.info,  Node: Stack Tutorial,  Next: Arithmetics Tutorial,  Prev: Crash Course Tutorial,  Up: Tutorial

3.4 Stack
=========

The most obvious feature of Forth is the stack.  When you type in a
number, it is pushed on the stack.  You can display the content of the
stack with `.s'.

     1 2 .s
     3 .s

   `.s' displays the top-of-stack to the right, i.e., the numbers
appear in `.s' output as they appeared in the input.

   You can print the top of stack element with `.'.

     1 2 3 . . .

   In general, words consume their stack arguments (`.s' is an
exception).

     Assignment: What does the stack contain after `5 6 7 .'?


File: gforth.info,  Node: Arithmetics Tutorial,  Next: Stack Manipulation Tutorial,  Prev: Stack Tutorial,  Up: Tutorial

3.5 Arithmetics
===============

The words `+', `-', `*', `/', and `mod' always operate on the top two
stack items:

     2 2 .s
     + .s
     .
     2 1 - .
     7 3 mod .

   The operands of `-', `/', and `mod' are in the same order as in the
corresponding infix expression (this is generally the case in Forth).

   Parentheses are superfluous (and not available), because the order of
the words unambiguously determines the order of evaluation and the
operands:

     3 4 + 5 * .
     3 4 5 * + .

     Assignment: What are the infix expressions corresponding to the
     Forth code above?  Write `6-7*8+9' in Forth notation(1).

   To change the sign, use `negate':

     2 negate .

     Assignment: Convert -(-3)*4-5 to Forth.

   `/mod' performs both `/' and `mod'.

     7 3 /mod . .

   Reference: *note Arithmetic::.

   ---------- Footnotes ----------

   (1) This notation is also known as Postfix or RPN (Reverse Polish
Notation).


File: gforth.info,  Node: Stack Manipulation Tutorial,  Next: Using files for Forth code Tutorial,  Prev: Arithmetics Tutorial,  Up: Tutorial

3.6 Stack Manipulation
======================

Stack manipulation words rearrange the data on the stack.

     1 .s drop .s
     1 .s dup .s drop drop .s
     1 2 .s over .s drop drop drop
     1 2 .s swap .s drop drop
     1 2 3 .s rot .s drop drop drop

   These are the most important stack manipulation words.  There are
also variants that manipulate twice as many stack items:

     1 2 3 4 .s 2swap .s 2drop 2drop

   Two more stack manipulation words are:

     1 2 .s nip .s drop
     1 2 .s tuck .s 2drop drop

     Assignment: Replace `nip' and `tuck' with combinations of other
     stack manipulation words.

          Given:          How do you get:
          1 2 3           3 2 1
          1 2 3           1 2 3 2
          1 2 3           1 2 3 3
          1 2 3           1 3 3
          1 2 3           2 1 3
          1 2 3 4         4 3 2 1
          1 2 3           1 2 3 1 2 3
          1 2 3 4         1 2 3 4 1 2
          1 2 3
          1 2 3           1 2 3 4
          1 2 3           1 3

     5 dup * .

     Assignment: Write 17^3 and 17^4 in Forth, without writing `17'
     more than once.  Write a piece of Forth code that expects two
     numbers on the stack (A and B, with B on top) and computes
     `(a-b)(a+1)'.

   Reference: *note Stack Manipulation::.


File: gforth.info,  Node: Using files for Forth code Tutorial,  Next: Comments Tutorial,  Prev: Stack Manipulation Tutorial,  Up: Tutorial

3.7 Using files for Forth code
==============================

While working at the Forth command line is convenient for one-line
examples and short one-off code, you probably want to store your source
code in files for convenient editing and persistence.  You can use your
favourite editor (Gforth includes Emacs support, *note Emacs and
Gforth::) to create FILE.FS and use

     s" FILE.FS" included

   to load it into your Forth system.  The file name extension I use for
Forth files is `.fs'.

   You can easily start Gforth with some files loaded like this:

     gforth FILE1.FS FILE2.FS

   If an error occurs during loading these files, Gforth terminates,
whereas an error during `INCLUDED' within Gforth usually gives you a
Gforth command line.  Starting the Forth system every time gives you a
clean start every time, without interference from the results of earlier
tries.

   I often put all the tests in a file, then load the code and run the
tests with

     gforth CODE.FS TESTS.FS -e bye

   (often by performing this command with `C-x C-e' in Emacs).  The `-e
bye' ensures that Gforth terminates afterwards so that I can restart
this command without ado.

   The advantage of this approach is that the tests can be repeated
easily every time the program ist changed, making it easy to catch bugs
introduced by the change.

   Reference: *note Forth source files::.


File: gforth.info,  Node: Comments Tutorial,  Next: Colon Definitions Tutorial,  Prev: Using files for Forth code Tutorial,  Up: Tutorial

3.8 Comments
============

     \ That's a comment; it ends at the end of the line
     ( Another comment; it ends here: )  .s

   `\' and `(' are ordinary Forth words and therefore have to be
separated with white space from the following text.

     \This gives an "Undefined word" error

   The first `)' ends a comment started with `(', so you cannot nest
`('-comments; and you cannot comment out text containing a `)' with `(
... )'(1).

   I use `\'-comments for descriptive text and for commenting out code
of one or more line; I use `('-comments for describing the stack
effect, the stack contents, or for commenting out sub-line pieces of
code.

   The Emacs mode `gforth.el' (*note Emacs and Gforth::) supports these
uses by commenting out a region with `C-x \', uncommenting a region
with `C-u C-x \', and filling a `\'-commented region with `M-q'.

   Reference: *note Comments::.

   ---------- Footnotes ----------

   (1) therefore it's a good idea to avoid `)' in word names.


File: gforth.info,  Node: Colon Definitions Tutorial,  Next: Decompilation Tutorial,  Prev: Comments Tutorial,  Up: Tutorial

3.9 Colon Definitions
=====================

are similar to procedures and functions in other programming languages.

     : squared ( n -- n^2 )
        dup * ;
     5 squared .
     7 squared .

   `:' starts the colon definition; its name is `squared'.  The
following comment describes its stack effect.  The words `dup *' are
not executed, but compiled into the definition.  `;' ends the colon
definition.

   The newly-defined word can be used like any other word, including
using it in other definitions:

     : cubed ( n -- n^3 )
        dup squared * ;
     -5 cubed .
     : fourth-power ( n -- n^4 )
        squared squared ;
     3 fourth-power .

     Assignment: Write colon definitions for `nip', `tuck', `negate',
     and `/mod' in terms of other Forth words, and check if they work
     (hint: test your tests on the originals first).  Don't let the
     `redefined'-Messages spook you, they are just warnings.

   Reference: *note Colon Definitions::.


File: gforth.info,  Node: Decompilation Tutorial,  Next: Stack-Effect Comments Tutorial,  Prev: Colon Definitions Tutorial,  Up: Tutorial

3.10 Decompilation
==================

You can decompile colon definitions with `see':

     see squared
     see cubed

   In Gforth `see' shows you a reconstruction of the source code from
the executable code.  Informations that were present in the source, but
not in the executable code, are lost (e.g., comments).

   You can also decompile the predefined words:

     see .
     see +


File: gforth.info,  Node: Stack-Effect Comments Tutorial,  Next: Types Tutorial,  Prev: Decompilation Tutorial,  Up: Tutorial

3.11 Stack-Effect Comments
==========================

By convention the comment after the name of a definition describes the
stack effect: The part in front of the `--' describes the state of the
stack before the execution of the definition, i.e., the parameters that
are passed into the colon definition; the part behind the `--' is the
state of the stack after the execution of the definition, i.e., the
results of the definition.  The stack comment only shows the top stack
items that the definition accesses and/or changes.

   You should put a correct stack effect on every definition, even if
it is just `( -- )'.  You should also add some descriptive comment to
more complicated words (I usually do this in the lines following `:').
If you don't do this, your code becomes unreadable (because you have to
work through every definition before you can understand any).

     Assignment: The stack effect of `swap' can be written like this:
     `x1 x2 -- x2 x1'.  Describe the stack effect of `-', `drop', `dup',
     `over', `rot', `nip', and `tuck'.  Hint: When you are done, you
     can compare your stack effects to those in this manual (*note Word
     Index::).

   Sometimes programmers put comments at various places in colon
definitions that describe the contents of the stack at that place (stack
comments); i.e., they are like the first part of a stack-effect
comment. E.g.,

     : cubed ( n -- n^3 )
        dup squared  ( n n^2 ) * ;

   In this case the stack comment is pretty superfluous, because the
word is simple enough.  If you think it would be a good idea to add
such a comment to increase readability, you should also consider
factoring the word into several simpler words (*note Factoring:
Factoring Tutorial.), which typically eliminates the need for the stack
comment; however, if you decide not to refactor it, then having such a
comment is better than not having it.

   The names of the stack items in stack-effect and stack comments in
the standard, in this manual, and in many programs specify the type
through a type prefix, similar to Fortran and Hungarian notation.  The
most frequent prefixes are:

`n'
     signed integer

`u'
     unsigned integer

`c'
     character

`f'
     Boolean flags, i.e. `false' or `true'.

`a-addr,a-'
     Cell-aligned address

`c-addr,c-'
     Char-aligned address (note that a Char may have two bytes in
     Windows NT)

`xt'
     Execution token, same size as Cell

`w,x'
     Cell, can contain an integer or an address.  It usually takes 32,
     64 or 16 bits (depending on your platform and Forth system). A
     cell is more commonly known as machine word, but the term _word_
     already means something different in Forth.

`d'
     signed double-cell integer

`ud'
     unsigned double-cell integer

`r'
     Float (on the FP stack)

   You can find a more complete list in *note Notation::.

     Assignment: Write stack-effect comments for all definitions you
     have written up to now.


File: gforth.info,  Node: Types Tutorial,  Next: Factoring Tutorial,  Prev: Stack-Effect Comments Tutorial,  Up: Tutorial

3.12 Types
==========

In Forth the names of the operations are not overloaded; so similar
operations on different types need different names; e.g., `+' adds
integers, and you have to use `f+' to add floating-point numbers.  The
following prefixes are often used for related operations on different
types:

`(none)'
     signed integer

`u'
     unsigned integer

`c'
     character

`d'
     signed double-cell integer

`ud, du'
     unsigned double-cell integer

`2'
     two cells (not-necessarily double-cell numbers)

`m, um'
     mixed single-cell and double-cell operations

`f'
     floating-point (note that in stack comments `f' represents flags,
     and `r' represents FP numbers).

   If there are no differences between the signed and the unsigned
variant (e.g., for `+'), there is only the prefix-less variant.

   Forth does not perform type checking, neither at compile time, nor at
run time.  If you use the wrong oeration, the data are interpreted
incorrectly:

     -1 u.

   If you have only experience with type-checked languages until now,
and have heard how important type-checking is, don't panic!  In my
experience (and that of other Forthers), type errors in Forth code are
usually easy to find (once you get used to it), the increased vigilance
of the programmer tends to catch some harder errors in addition to most
type errors, and you never have to work around the type system, so in
most situations the lack of type-checking seems to be a win (projects to
add type checking to Forth have not caught on).


File: gforth.info,  Node: Factoring Tutorial,  Next: Designing the stack effect Tutorial,  Prev: Types Tutorial,  Up: Tutorial

3.13 Factoring
==============

If you try to write longer definitions, you will soon find it hard to
keep track of the stack contents.  Therefore, good Forth programmers
tend to write only short definitions (e.g., three lines).  The art of
finding meaningful short definitions is known as factoring (as in
factoring polynomials).

   Well-factored programs offer additional advantages: smaller, more
general words, are easier to test and debug and can be reused more and
better than larger, specialized words.

   So, if you run into difficulties with stack management, when writing
code, try to define meaningful factors for the word, and define the word
in terms of those.  Even if a factor contains only two words, it is
often helpful.

   Good factoring is not easy, and it takes some practice to get the
knack for it; but even experienced Forth programmers often don't find
the right solution right away, but only when rewriting the program.
So, if you don't come up with a good solution immediately, keep trying,
don't despair.


File: gforth.info,  Node: Designing the stack effect Tutorial,  Next: Local Variables Tutorial,  Prev: Factoring Tutorial,  Up: Tutorial

3.14 Designing the stack effect
===============================

In other languages you can use an arbitrary order of parameters for a
function; and since there is only one result, you don't have to deal
with the order of results, either.

   In Forth (and other stack-based languages, e.g., PostScript) the
parameter and result order of a definition is important and should be
designed well.  The general guideline is to design the stack effect such
that the word is simple to use in most cases, even if that complicates
the implementation of the word.  Some concrete rules are:

   * Words consume all of their parameters (e.g., `.').

   * If there is a convention on the order of parameters (e.g., from
     mathematics or another programming language), stick with it (e.g.,
     `-').

   * If one parameter usually requires only a short computation (e.g.,
     it is a constant), pass it on the top of the stack.  Conversely,
     parameters that usually require a long sequence of code to compute
     should be passed as the bottom (i.e., first) parameter.  This
     makes the code easier to read, because the reader does not need to
     keep track of the bottom item through a long sequence of code (or,
     alternatively, through stack manipulations). E.g., `!' (store,
     *note Memory::) expects the address on top of the stack because it
     is usually simpler to compute than the stored value (often the
     address is just a variable).

   * Similarly, results that are usually consumed quickly should be
     returned on the top of stack, whereas a result that is often used
     in long computations should be passed as bottom result.  E.g., the
     file words like `open-file' return the error code on the top of
     stack, because it is usually consumed quickly by `throw';
     moreover, the error code has to be checked before doing anything
     with the other results.


   These rules are just general guidelines, don't lose sight of the
overall goal to make the words easy to use.  E.g., if the convention
rule conflicts with the computation-length rule, you might decide in
favour of the convention if the word will be used rarely, and in favour
of the computation-length rule if the word will be used frequently
(because with frequent use the cost of breaking the computation-length
rule would be quite high, and frequent use makes it easier to remember
an unconventional order).


File: gforth.info,  Node: Local Variables Tutorial,  Next: Conditional execution Tutorial,  Prev: Designing the stack effect Tutorial,  Up: Tutorial

3.15 Local Variables
====================

You can define local variables (_locals_) in a colon definition:

     : swap { a b -- b a }
       b a ;
     1 2 swap .s 2drop

   (If your Forth system does not support this syntax, include
`compat/anslocal.fs' first).

   In this example `{ a b -- b a }' is the locals definition; it takes
two cells from the stack, puts the top of stack in `b' and the next
stack element in `a'.  `--' starts a comment ending with `}'.  After
the locals definition, using the name of the local will push its value
on the stack.  You can leave the comment part (`-- b a') away:

     : swap ( x1 x2 -- x2 x1 )
       { a b } b a ;

   In Gforth you can have several locals definitions, anywhere in a
colon definition; in contrast, in a standard program you can have only
one locals definition per colon definition, and that locals definition
must be outside any control structure.

   With locals you can write slightly longer definitions without running
into stack trouble.  However, I recommend trying to write colon
definitions without locals for exercise purposes to help you gain the
essential factoring skills.

     Assignment: Rewrite your definitions until now with locals

   Reference: *note Locals::.


File: gforth.info,  Node: Conditional execution Tutorial,  Next: Flags and Comparisons Tutorial,  Prev: Local Variables Tutorial,  Up: Tutorial

3.16 Conditional execution
==========================

In Forth you can use control structures only inside colon definitions.
An `if'-structure looks like this:

     : abs ( n1 -- +n2 )
         dup 0 < if
             negate
         endif ;
     5 abs .
     -5 abs .

   `if' takes a flag from the stack.  If the flag is non-zero (true),
the following code is performed, otherwise execution continues after the
`endif' (or `else').  `<' compares the top two stack elements and
produces a flag:

     1 2 < .
     2 1 < .
     1 1 < .

   Actually the standard name for `endif' is `then'.  This tutorial
presents the examples using `endif', because this is often less
confusing for people familiar with other programming languages where
`then' has a different meaning.  If your system does not have `endif',
define it with

     : endif postpone then ; immediate

   You can optionally use an `else'-part:

     : min ( n1 n2 -- n )
       2dup < if
         drop
       else
         nip
       endif ;
     2 3 min .
     3 2 min .

     Assignment: Write `min' without `else'-part (hint: what's the
     definition of `nip'?).

   Reference: *note Selection::.


File: gforth.info,  Node: Flags and Comparisons Tutorial,  Next: General Loops Tutorial,  Prev: Conditional execution Tutorial,  Up: Tutorial

3.17 Flags and Comparisons
==========================

In a false-flag all bits are clear (0 when interpreted as integer).  In
a canonical true-flag all bits are set (-1 as a twos-complement signed
integer); in many contexts (e.g., `if') any non-zero value is treated
as true flag.

     false .
     true .
     true hex u. decimal

   Comparison words produce canonical flags:

     1 1 = .
     1 0= .
     0 1 < .
     0 0 < .
     -1 1 u< . \ type error, u< interprets -1 as large unsigned number
     -1 1 < .

   Gforth supports all combinations of the prefixes `0 u d d0 du f f0'
(or none) and the comparisons `= <> < > <= >='.  Only a part of these
combinations are standard (for details see the standard, *note Numeric
comparison::, *note Floating Point:: or *note Word Index::).

   You can use `and or xor invert' as operations on canonical flags.
Actually they are bitwise operations:

     1 2 and .
     1 2 or .
     1 3 xor .
     1 invert .

   You can convert a zero/non-zero flag into a canonical flag with
`0<>' (and complement it on the way with `0=').

     1 0= .
     1 0<> .

   You can use the all-bits-set feature of canonical flags and the
bitwise operation of the Boolean operations to avoid `if's:

     : foo ( n1 -- n2 )
       0= if
         14
       else
         0
       endif ;
     0 foo .
     1 foo .

     : foo ( n1 -- n2 )
       0= 14 and ;
     0 foo .
     1 foo .

     Assignment: Write `min' without `if'.

   For reference, see *note Boolean Flags::, *note Numeric
comparison::, and *note Bitwise operations::.


File: gforth.info,  Node: General Loops Tutorial,  Next: Counted loops Tutorial,  Prev: Flags and Comparisons Tutorial,  Up: Tutorial

3.18 General Loops
==================

The endless loop is the most simple one:

     : endless ( -- )
       0 begin
         dup . 1+
       again ;
     endless

   Terminate this loop by pressing `Ctrl-C' (in Gforth).  `begin' does
nothing at run-time, `again' jumps back to `begin'.

   A loop with one exit at any place looks like this:

     : log2 ( +n1 -- n2 )
     \ logarithmus dualis of n1>0, rounded down to the next integer
       assert( dup 0> )
       2/ 0 begin
         over 0> while
           1+ swap 2/ swap
       repeat
       nip ;
     7 log2 .
     8 log2 .

   At run-time `while' consumes a flag; if it is 0, execution continues
behind the `repeat'; if the flag is non-zero, execution continues
behind the `while'.  `Repeat' jumps back to `begin', just like `again'.

   In Forth there are many combinations/abbreviations, like `1+'.
However, `2/' is not one of them; it shifts its argument right by one
bit (arithmetic shift right):

     -5 2 / .
     -5 2/ .

   `assert(' is no standard word, but you can get it on systems other
than Gforth by including `compat/assert.fs'.  You can see what it does
by trying

     0 log2 .

   Here's a loop with an exit at the end:

     : log2 ( +n1 -- n2 )
     \ logarithmus dualis of n1>0, rounded down to the next integer
       assert( dup 0 > )
       -1 begin
         1+ swap 2/ swap
         over 0 <=
       until
       nip ;

   `Until' consumes a flag; if it is non-zero, execution continues at
the `begin', otherwise after the `until'.

     Assignment: Write a definition for computing the greatest common
     divisor.

   Reference: *note Simple Loops::.


File: gforth.info,  Node: Counted loops Tutorial,  Next: Recursion Tutorial,  Prev: General Loops Tutorial,  Up: Tutorial

3.19 Counted loops
==================

     : ^ ( n1 u -- n )
     \ n = the uth power of n1
       1 swap 0 u+do
         over *
       loop
       nip ;
     3 2 ^ .
     4 3 ^ .

   `U+do' (from `compat/loops.fs', if your Forth system doesn't have
it) takes two numbers of the stack `( u3 u4 -- )', and then performs
the code between `u+do' and `loop' for `u3-u4' times (or not at all, if
`u3-u4<0').

   You can see the stack effect design rules at work in the stack
effect of the loop start words: Since the start value of the loop is
more frequently constant than the end value, the start value is passed
on the top-of-stack.

   You can access the counter of a counted loop with `i':

     : fac ( u -- u! )
       1 swap 1+ 1 u+do
         i *
       loop ;
     5 fac .
     7 fac .

   There is also `+do', which expects signed numbers (important for
deciding whether to enter the loop).

     Assignment: Write a definition for computing the nth Fibonacci
     number.

   You can also use increments other than 1:

     : up2 ( n1 n2 -- )
       +do
         i .
       2 +loop ;
     10 0 up2

     : down2 ( n1 n2 -- )
       -do
         i .
       2 -loop ;
     0 10 down2

   Reference: *note Counted Loops::.


File: gforth.info,  Node: Recursion Tutorial,  Next: Leaving definitions or loops Tutorial,  Prev: Counted loops Tutorial,  Up: Tutorial

3.20 Recursion
==============

Usually the name of a definition is not visible in the definition; but
earlier definitions are usually visible:

     1 0 / . \ "Floating-point unidentified fault" in Gforth on some platforms
     : / ( n1 n2 -- n )
       dup 0= if
         -10 throw \ report division by zero
       endif
       /           \ old version
     ;
     1 0 /

   For recursive definitions you can use `recursive' (non-standard) or
`recurse':

     : fac1 ( n -- n! ) recursive
      dup 0> if
        dup 1- fac1 *
      else
        drop 1
      endif ;
     7 fac1 .

     : fac2 ( n -- n! )
      dup 0> if
        dup 1- recurse *
      else
        drop 1
      endif ;
     8 fac2 .

     Assignment: Write a recursive definition for computing the nth
     Fibonacci number.

   Reference (including indirect recursion): *Note Calls and returns::.


File: gforth.info,  Node: Leaving definitions or loops Tutorial,  Next: Return Stack Tutorial,  Prev: Recursion Tutorial,  Up: Tutorial

3.21 Leaving definitions or loops
=================================

`EXIT' exits the current definition right away.  For every counted loop
that is left in this way, an `UNLOOP' has to be performed before the
`EXIT':

     : ...
      ... u+do
        ... if
          ... unloop exit
        endif
        ...
      loop
      ... ;

   `LEAVE' leaves the innermost counted loop right away:

     : ...
      ... u+do
        ... if
          ... leave
        endif
        ...
      loop
      ... ;

   Reference: *note Calls and returns::, *note Counted Loops::.


File: gforth.info,  Node: Return Stack Tutorial,  Next: Memory Tutorial,  Prev: Leaving definitions or loops Tutorial,  Up: Tutorial

3.22 Return Stack
=================

In addition to the data stack Forth also has a second stack, the return
stack; most Forth systems store the return addresses of procedure calls
there (thus its name).  Programmers can also use this stack:

     : foo ( n1 n2 -- )
      .s
      >r .s
      r@ .
      >r .s
      r@ .
      r> .
      r@ .
      r> . ;
     1 2 foo

   `>r' takes an element from the data stack and pushes it onto the
return stack; conversely, `r>' moves an elementm from the return to the
data stack; `r@' pushes a copy of the top of the return stack on the
data stack.

   Forth programmers usually use the return stack for storing data
temporarily, if using the data stack alone would be too complex, and
factoring and locals are not an option:

     : 2swap ( x1 x2 x3 x4 -- x3 x4 x1 x2 )
      rot >r rot r> ;

   The return address of the definition and the loop control parameters
of counted loops usually reside on the return stack, so you have to take
all items, that you have pushed on the return stack in a colon
definition or counted loop, from the return stack before the definition
or loop ends.  You cannot access items that you pushed on the return
stack outside some definition or loop within the definition of loop.

   If you miscount the return stack items, this usually ends in a crash:

     : crash ( n -- )
       >r ;
     5 crash

   You cannot mix using locals and using the return stack (according to
the standard; Gforth has no problem).  However, they solve the same
problems, so this shouldn't be an issue.

     Assignment: Can you rewrite any of the definitions you wrote until
     now in a better way using the return stack?

   Reference: *note Return stack::.


File: gforth.info,  Node: Memory Tutorial,  Next: Characters and Strings Tutorial,  Prev: Return Stack Tutorial,  Up: Tutorial

3.23 Memory
===========

You can create a global variable `v' with

     variable v ( -- addr )

   `v' pushes the address of a cell in memory on the stack.  This cell
was reserved by `variable'.  You can use `!' (store) to store values
into this cell and `@' (fetch) to load the value from the stack into
memory:

     v .
     5 v ! .s
     v @ .

   You can see a raw dump of memory with `dump':

     v 1 cells .s dump

   `Cells ( n1 -- n2 )' gives you the number of bytes (or, more
generally, address units (aus)) that `n1 cells' occupy.  You can also
reserve more memory:

     create v2 20 cells allot
     v2 20 cells dump

   creates a word `v2' and reserves 20 uninitialized cells; the address
pushed by `v2' points to the start of these 20 cells.  You can use
address arithmetic to access these cells:

     3 v2 5 cells + !
     v2 20 cells dump

   You can reserve and initialize memory with `,':

     create v3
       5 , 4 , 3 , 2 , 1 ,
     v3 @ .
     v3 cell+ @ .
     v3 2 cells + @ .
     v3 5 cells dump

     Assignment: Write a definition `vsum ( addr u -- n )' that
     computes the sum of `u' cells, with the first of these cells at
     `addr', the next one at `addr cell+' etc.

   You can also reserve memory without creating a new word:

     here 10 cells allot .
     here .

   `Here' pushes the start address of the memory area.  You should
store it somewhere, or you will have a hard time finding the memory area
again.

   `Allot' manages dictionary memory.  The dictionary memory contains
the system's data structures for words etc. on Gforth and most other
Forth systems.  It is managed like a stack: You can free the memory that
you have just `allot'ed with

     -10 cells allot
     here .

   Note that you cannot do this if you have created a new word in the
meantime (because then your `allot'ed memory is no longer on the top of
the dictionary "stack").

   Alternatively, you can use `allocate' and `free' which allow freeing
memory in any order:

     10 cells allocate throw .s
     20 cells allocate throw .s
     swap
     free throw
     free throw

   The `throw's deal with errors (e.g., out of memory).

   And there is also a garbage collector
(http://www.complang.tuwien.ac.at/forth/garbage-collection.zip), which
eliminates the need to `free' memory explicitly.

   Reference: *note Memory::.


File: gforth.info,  Node: Characters and Strings Tutorial,  Next: Alignment Tutorial,  Prev: Memory Tutorial,  Up: Tutorial

3.24 Characters and Strings
===========================

On the stack characters take up a cell, like numbers.  In memory they
have their own size (one 8-bit byte on most systems), and therefore
require their own words for memory access:

     create v4
       104 c, 97 c, 108 c, 108 c, 111 c,
     v4 4 chars + c@ .
     v4 5 chars dump

   The preferred representation of strings on the stack is `addr
u-count', where `addr' is the address of the first character and
`u-count' is the number of characters in the string.

     v4 5 type

   You get a string constant with

     s" hello, world" .s
     type

   Make sure you have a space between `s"' and the string; `s"' is a
normal Forth word and must be delimited with white space (try what
happens when you remove the space).

   However, this interpretive use of `s"' is quite restricted: the
string exists only until the next call of `s"' (some Forth systems keep
more than one of these strings, but usually they still have a limited
lifetime).

     s" hello," s" world" .s
     type
     type

   You can also use `s"' in a definition, and the resulting strings
then live forever (well, for as long as the definition):

     : foo s" hello," s" world" ;
     foo .s
     type
     type

     Assignment: `Emit ( c -- )' types `c' as character (not a number).
     Implement `type ( addr u -- )'.

   Reference: *note Memory Blocks::.


File: gforth.info,  Node: Alignment Tutorial,  Next: Floating Point Tutorial,  Prev: Characters and Strings Tutorial,  Up: Tutorial

3.25 Alignment
==============

On many processors cells have to be aligned in memory, if you want to
access them with `@' and `!' (and even if the processor does not
require alignment, access to aligned cells is faster).

   `Create' aligns `here' (i.e., the place where the next allocation
will occur, and that the `create'd word points to).  Likewise, the
memory produced by `allocate' starts at an aligned address.  Adding a
number of `cells' to an aligned address produces another aligned
address.

   However, address arithmetic involving `char+' and `chars' can create
an address that is not cell-aligned.  `Aligned ( addr -- a-addr )'
produces the next aligned address:

     v3 char+ aligned .s @ .
     v3 char+ .s @ .

   Similarly, `align' advances `here' to the next aligned address:

     create v5 97 c,
     here .
     align here .
     1000 ,

   Note that you should use aligned addresses even if your processor
does not require them, if you want your program to be portable.

   Reference: *note Address arithmetic::.


File: gforth.info,  Node: Floating Point Tutorial,  Next: Files Tutorial,  Prev: Alignment Tutorial,  Up: Tutorial

3.26 Floating Point
===================

Floating-point (FP) numbers and arithmetic in Forth works mostly as one
might expect, but there are a few things worth noting:

   The first point is not specific to Forth, but so important and yet
not universally known that I mention it here: FP numbers are not reals.
Many properties (e.g., arithmetic laws) that reals have and that one
expects of all kinds of numbers do not hold for FP numbers.  If you
want to use FP computations, you should learn about their problems and
how to avoid them; a good starting point is `David Goldberg, What Every
Computer Scientist Should Know About Floating-Point Arithmetic
(http://docs.sun.com/source/806-3568/ncg_goldberg.html), ACM Computing
Surveys 23(1):5-48, March 1991'.

   In Forth source code literal FP numbers need an exponent, e.g.,
`1e0'; this can also be written shorter as `1e', `+1.0e+0', and many
variations in between.  The reason for this is that, for historical
reasons, Forth interprets a decimal point alone (e.g., `1.') as
indicating a double-cell integer.  Another requirement for literal FP
numbers is that the current base is decimal; with a hex base `1e' is
interpreted as an integer.

   Forth has a separate stack for FP numbers.(1)  One advantage of this
model is that cells are not in the way when accessing FP values, and
vice versa.  Forth has a set of words for manipulating the FP stack:
`fdup fswap fdrop fover frot' and (non-standard) `fnip ftuck fpick'.

   FP arithmetic words are prefixed with `F'.  There is the usual set
`f+ f- f* f/ f** fnegate' as well as a number of words for other
functions, e.g., `fsqrt fsin fln fmin'.  One word that you might expect
is `f='; but `f=' is non-standard, because FP computation results are
usually inaccurate, so exact comparison is usually a mistake, and one
should use approximate comparison.  Unfortunately, `f~', the standard
word for that purpose, is not well designed, so Gforth provides `f~abs'
and `f~rel' as well.

   And of course there are words for accessing FP numbers in memory
(`f@ f!'), and for address arithmetic (`floats float+ faligned').
There are also variants of these words with an `sf' and `df' prefix for
accessing IEEE format single-precision and double-precision numbers in
memory; their main purpose is for accessing external FP data (e.g.,
that has been read from or will be written to a file).

   Here is an example of a dot-product word and its use:

     : v* ( f_addr1 nstride1 f_addr2 nstride2 ucount -- r )
       >r swap 2swap swap 0e r> 0 ?DO
         dup f@ over + 2swap dup f@ f* f+ over + 2swap
       LOOP
       2drop 2drop ;

     create v 1.23e f, 4.56e f, 7.89e f,

     v 1 floats  v 1 floats  3  v* f.

     Assignment: Write a program to solve a quadratic equation.  Then
     read `Henry G. Baker, You Could Learn a Lot from a Quadratic
     (http://home.pipeline.com/~hbaker1/sigplannotices/sigcol05.ps.gz),
     ACM SIGPLAN Notices, 33(1):30-39, January 1998', and see if you
     can improve your program.  Finally, find a test case where the
     original and the improved version produce different results.

   Reference: *note Floating Point::; *note Floating point stack::;
*note Number Conversion::; *note Memory Access::; *note Address
arithmetic::.

   ---------- Footnotes ----------

   (1) Theoretically, an ANS Forth system may implement the FP stack on
the data stack, but virtually all systems implement a separate FP
stack; and programming in a way that accommodates all models is so
cumbersome that nobody does it.


File: gforth.info,  Node: Files Tutorial,  Next: Interpretation and Compilation Semantics and Immediacy Tutorial,  Prev: Floating Point Tutorial,  Up: Tutorial

3.27 Files
==========

This section gives a short introduction into how to use files inside
Forth. It's broken up into five easy steps:

  1. Opened an ASCII text file for input

  2. Opened a file for output

  3. Read input file until string matched (or some other condition
     matched)

  4. Wrote some lines from input ( modified or not) to output

  5. Closed the files.

   Reference: *note General files::.

3.27.1 Open file for input
--------------------------

     s" foo.in"  r/o open-file throw Value fd-in

3.27.2 Create file for output
-----------------------------

     s" foo.out" w/o create-file throw Value fd-out

   The available file modes are r/o for read-only access, r/w for
read-write access, and w/o for write-only access. You could open both
files with r/w, too, if you like. All file words return error codes; for
most applications, it's best to pass there error codes with `throw' to
the outer error handler.

   If you want words for opening and assigning, define them as follows:

     0 Value fd-in
     0 Value fd-out
     : open-input ( addr u -- )  r/o open-file throw to fd-in ;
     : open-output ( addr u -- )  w/o create-file throw to fd-out ;

   Usage example:

     s" foo.in" open-input
     s" foo.out" open-output

3.27.3 Scan file for a particular line
--------------------------------------

     256 Constant max-line
     Create line-buffer  max-line 2 + allot

     : scan-file ( addr u -- )
       begin
           line-buffer max-line fd-in read-line throw
       while
              >r 2dup line-buffer r> compare 0=
          until
       else
          drop
       then
       2drop ;

   `read-line ( addr u1 fd -- u2 flag ior )' reads up to u1 bytes into
the buffer at addr, and returns the number of bytes read, a flag that is
false when the end of file is reached, and an error code.

   `compare ( addr1 u1 addr2 u2 -- n )' compares two strings and
returns zero if both strings are equal. It returns a positive number if
the first string is lexically greater, a negative if the second string
is lexically greater.

   We haven't seen this loop here; it has two exits. Since the `while'
exits with the number of bytes read on the stack, we have to clean up
that separately; that's after the `else'.

   Usage example:

     s" The text I search is here" scan-file

3.27.4 Copy input to output
---------------------------

     : copy-file ( -- )
       begin
           line-buffer max-line fd-in read-line throw
       while
           line-buffer swap fd-out write-line throw
       repeat ;

3.27.5 Close files
------------------

     fd-in close-file throw
     fd-out close-file throw

   Likewise, you can put that into definitions, too:

     : close-input ( -- )  fd-in close-file throw ;
     : close-output ( -- )  fd-out close-file throw ;

     Assignment: How could you modify `copy-file' so that it copies
     until a second line is matched? Can you write a program that
     extracts a section of a text file, given the line that starts and
     the line that terminates that section?


File: gforth.info,  Node: Interpretation and Compilation Semantics and Immediacy Tutorial,  Next: Execution Tokens Tutorial,  Prev: Files Tutorial,  Up: Tutorial

3.28 Interpretation and Compilation Semantics and Immediacy
===========================================================

When a word is compiled, it behaves differently from being interpreted.
E.g., consider `+':

     1 2 + .
     : foo + ;

   These two behaviours are known as compilation and interpretation
semantics.  For normal words (e.g., `+'), the compilation semantics is
to append the interpretation semantics to the currently defined word
(`foo' in the example above).  I.e., when `foo' is executed later, the
interpretation semantics of `+' (i.e., adding two numbers) will be
performed.

   However, there are words with non-default compilation semantics,
e.g., the control-flow words like `if'.  You can use `immediate' to
change the compilation semantics of the last defined word to be equal to
the interpretation semantics:

     : [FOO] ( -- )
      5 . ; immediate

     [FOO]
     : bar ( -- )
       [FOO] ;
     bar
     see bar

   Two conventions to mark words with non-default compilation semantics
are names with brackets (more frequently used) and to write them all in
upper case (less frequently used).

   In Gforth (and many other systems) you can also remove the
interpretation semantics with `compile-only' (the compilation semantics
is derived from the original interpretation semantics):

     : flip ( -- )
      6 . ; compile-only \ but not immediate
     flip

     : flop ( -- )
      flip ;
     flop

   In this example the interpretation semantics of `flop' is equal to
the original interpretation semantics of `flip'.

   The text interpreter has two states: in interpret state, it performs
the interpretation semantics of words it encounters; in compile state,
it performs the compilation semantics of these words.

   Among other things, `:' switches into compile state, and `;'
switches back to interpret state.  They contain the factors `]' (switch
to compile state) and `[' (switch to interpret state), that do nothing
but switch the state.

     : xxx ( -- )
       [ 5 . ]
     ;

     xxx
     see xxx

   These brackets are also the source of the naming convention mentioned
above.

   Reference: *note Interpretation and Compilation Semantics::.


File: gforth.info,  Node: Execution Tokens Tutorial,  Next: Exceptions Tutorial,  Prev: Interpretation and Compilation Semantics and Immediacy Tutorial,  Up: Tutorial

3.29 Execution Tokens
=====================

`' word' gives you the execution token (XT) of a word.  The XT is a
cell representing the interpretation semantics of a word.  You can
execute this semantics with `execute':

     ' + .s
     1 2 rot execute .

   The XT is similar to a function pointer in C.  However, parameter
passing through the stack makes it a little more flexible:

     : map-array ( ... addr u xt -- ... )
     \ executes xt ( ... x -- ... ) for every element of the array starting
     \ at addr and containing u elements
       { xt }
       cells over + swap ?do
         i @ xt execute
       1 cells +loop ;

     create a 3 , 4 , 2 , -1 , 4 ,
     a 5 ' . map-array .s
     0 a 5 ' + map-array .
     s" max-n" environment? drop .s
     a 5 ' min map-array .

   You can use map-array with the XTs of words that consume one element
more than they produce.  In theory you can also use it with other XTs,
but the stack effect then depends on the size of the array, which is
hard to understand.

   Since XTs are cell-sized, you can store them in memory and manipulate
them on the stack like other cells.  You can also compile the XT into a
word with `compile,':

     : foo1 ( n1 n2 -- n )
        [ ' + compile, ] ;
     see foo

   This is non-standard, because `compile,' has no compilation
semantics in the standard, but it works in good Forth systems.  For the
broken ones, use

     : [compile,] compile, ; immediate

     : foo1 ( n1 n2 -- n )
        [ ' + ] [compile,] ;
     see foo

   `'' is a word with default compilation semantics; it parses the next
word when its interpretation semantics are executed, not during
compilation:

     : foo ( -- xt )
       ' ;
     see foo
     : bar ( ... "word" -- ... )
       ' execute ;
     see bar
     1 2 bar + .

   You often want to parse a word during compilation and compile its XT
so it will be pushed on the stack at run-time.  `[']' does this:

     : xt-+ ( -- xt )
       ['] + ;
     see xt-+
     1 2 xt-+ execute .

   Many programmers tend to see `'' and the word it parses as one unit,
and expect it to behave like `[']' when compiled, and are confused by
the actual behaviour.  If you are, just remember that the Forth system
just takes `'' as one unit and has no idea that it is a parsing word
(attempts to convenience programmers in this issue have usually
resulted in even worse pitfalls, see `State'-smartness--Why it is evil
and How to Exorcise it
(http://www.complang.tuwien.ac.at/papers/ertl98.ps.gz)).

   Note that the state of the interpreter does not come into play when
creating and executing XTs.  I.e., even when you execute `'' in compile
state, it still gives you the interpretation semantics.  And whatever
that state is, `execute' performs the semantics represented by the XT
(i.e., for XTs produced with `'' the interpretation semantics).

   Reference: *note Tokens for Words::.


File: gforth.info,  Node: Exceptions Tutorial,  Next: Defining Words Tutorial,  Prev: Execution Tokens Tutorial,  Up: Tutorial

3.30 Exceptions
===============

`throw ( n -- )' causes an exception unless n is zero.

     100 throw .s
     0 throw .s

   `catch ( ... xt -- ... n )' behaves similar to `execute', but it
catches exceptions and pushes the number of the exception on the stack
(or 0, if the xt executed without exception).  If there was an
exception, the stacks have the same depth as when entering `catch':

     .s
     3 0 ' / catch .s
     3 2 ' / catch .s

     Assignment: Try the same with `execute' instead of `catch'.

   `Throw' always jumps to the dynamically next enclosing `catch', even
if it has to leave several call levels to achieve this:

     : foo 100 throw ;
     : foo1 foo ." after foo" ;
     : bar ['] foo1 catch ;
     bar .

   It is often important to restore a value upon leaving a definition,
even if the definition is left through an exception.  You can ensure
this like this:

     : ...
        save-x
        ['] word-changing-x catch ( ... n )
        restore-x
        ( ... n ) throw ;

   However, this is still not safe against, e.g., the user pressing
`Ctrl-C' when execution is between the `catch' and `restore-x'.

   Gforth provides an alternative exception handling syntax that is safe
against such cases: `try ... restore ... endtry'.  If the code between
`try' and `endtry' has an exception, the stack depths are restored, the
exception number is pushed on the stack, and the execution continues
right after `restore'.

   The safer equivalent to the restoration code above is

     : ...
       save-x
       try
         word-changing-x 0
       restore
         restore-x
       endtry
       throw ;

   Reference: *note Exception Handling::.


File: gforth.info,  Node: Defining Words Tutorial,  Next: Arrays and Records Tutorial,  Prev: Exceptions Tutorial,  Up: Tutorial

3.31 Defining Words
===================

`:', `create', and `variable' are definition words: They define other
words.  `Constant' is another definition word:

     5 constant foo
     foo .

   You can also use the prefixes `2' (double-cell) and `f' (floating
point) with `variable' and `constant'.

   You can also define your own defining words.  E.g.:

     : variable ( "name" -- )
       create 0 , ;

   You can also define defining words that create words that do
something other than just producing their address:

     : constant ( n "name" -- )
       create ,
     does> ( -- n )
       ( addr ) @ ;

     5 constant foo
     foo .

   The definition of `constant' above ends at the `does>'; i.e.,
`does>' replaces `;', but it also does something else: It changes the
last defined word such that it pushes the address of the body of the
word and then performs the code after the `does>' whenever it is called.

   In the example above, `constant' uses `,' to store 5 into the body
of `foo'.  When `foo' executes, it pushes the address of the body onto
the stack, then (in the code after the `does>') fetches the 5 from
there.

   The stack comment near the `does>' reflects the stack effect of the
defined word, not the stack effect of the code after the `does>' (the
difference is that the code expects the address of the body that the
stack comment does not show).

   You can use these definition words to do factoring in cases that
involve (other) definition words.  E.g., a field offset is always added
to an address.  Instead of defining

     2 cells constant offset-field1

   and using this like

     ( addr ) offset-field1 +

   you can define a definition word

     : simple-field ( n "name" -- )
       create ,
     does> ( n1 -- n1+n )
       ( addr ) @ + ;

   Definition and use of field offsets now look like this:

     2 cells simple-field field1
     create mystruct 4 cells allot
     mystruct .s field1 .s drop

   If you want to do something with the word without performing the code
after the `does>', you can access the body of a `create'd word with
`>body ( xt -- addr )':

     : value ( n "name" -- )
       create ,
     does> ( -- n1 )
       @ ;
     : to ( n "name" -- )
       ' >body ! ;

     5 value foo
     foo .
     7 to foo
     foo .

     Assignment: Define `defer ( "name" -- )', which creates a word
     that stores an XT (at the start the XT of `abort'), and upon
     execution `execute's the XT.  Define `is ( xt "name" -- )' that
     stores `xt' into `name', a word defined with `defer'.  Indirect
     recursion is one application of `defer'.

   Reference: *note User-defined Defining Words::.


File: gforth.info,  Node: Arrays and Records Tutorial,  Next: POSTPONE Tutorial,  Prev: Defining Words Tutorial,  Up: Tutorial

3.32 Arrays and Records
=======================

Forth has no standard words for defining data structures such as arrays
and records (structs in C terminology), but you can build them yourself
based on address arithmetic.  You can also define words for defining
arrays and records (*note Defining Words: Defining Words Tutorial.).

   One of the first projects a Forth newcomer sets out upon when
learning about defining words is an array defining word (possibly for
n-dimensional arrays).  Go ahead and do it, I did it, too; you will
learn something from it.  However, don't be disappointed when you later
learn that you have little use for these words (inappropriate use would
be even worse).  I have not found a set of useful array words yet; the
needs are just too diverse, and named, global arrays (the result of
naive use of defining words) are often not flexible enough (e.g.,
consider how to pass them as parameters).  Another such project is a set
of words to help dealing with strings.

   On the other hand, there is a useful set of record words, and it has
been defined in `compat/struct.fs'; these words are predefined in
Gforth.  They are explained in depth elsewhere in this manual (see
*note Structures::).  The `simple-field' example above is simplified
variant of fields in this package.


File: gforth.info,  Node: POSTPONE Tutorial,  Next: Literal Tutorial,  Prev: Arrays and Records Tutorial,  Up: Tutorial

3.33 `POSTPONE'
===============

You can compile the compilation semantics (instead of compiling the
interpretation semantics) of a word with `POSTPONE':

     : MY-+ ( Compilation: -- ; Run-time of compiled code: n1 n2 -- n )
      POSTPONE + ; immediate
     : foo ( n1 n2 -- n )
      MY-+ ;
     1 2 foo .
     see foo

   During the definition of `foo' the text interpreter performs the
compilation semantics of `MY-+', which performs the compilation
semantics of `+', i.e., it compiles `+' into `foo'.

   This example also displays separate stack comments for the
compilation semantics and for the stack effect of the compiled code.
For words with default compilation semantics these stack effects are
usually not displayed; the stack effect of the compilation semantics is
always `( -- )' for these words, the stack effect for the compiled code
is the stack effect of the interpretation semantics.

   Note that the state of the interpreter does not come into play when
performing the compilation semantics in this way.  You can also perform
it interpretively, e.g.:

     : foo2 ( n1 n2 -- n )
      [ MY-+ ] ;
     1 2 foo .
     see foo

   However, there are some broken Forth systems where this does not
always work, and therefore this practice was been declared non-standard
in 1999.

   Here is another example for using `POSTPONE':

     : MY-- ( Compilation: -- ; Run-time of compiled code: n1 n2 -- n )
      POSTPONE negate POSTPONE + ; immediate compile-only
     : bar ( n1 n2 -- n )
       MY-- ;
     2 1 bar .
     see bar

   You can define `ENDIF' in this way:

     : ENDIF ( Compilation: orig -- )
       POSTPONE then ; immediate

     Assignment: Write `MY-2DUP' that has compilation semantics
     equivalent to `2dup', but compiles `over over'.


File: gforth.info,  Node: Literal Tutorial,  Next: Advanced macros Tutorial,  Prev: POSTPONE Tutorial,  Up: Tutorial

3.34 `Literal'
==============

You cannot `POSTPONE' numbers:

     : [FOO] POSTPONE 500 ; immediate

   Instead, you can use `LITERAL (compilation: n --; run-time: -- n )':

     : [FOO] ( compilation: --; run-time: -- n )
       500 POSTPONE literal ; immediate

     : flip [FOO] ;
     flip .
     see flip

   `LITERAL' consumes a number at compile-time (when it's compilation
semantics are executed) and pushes it at run-time (when the code it
compiled is executed).  A frequent use of `LITERAL' is to compile a
number computed at compile time into the current word:

     : bar ( -- n )
       [ 2 2 + ] literal ;
     see bar

     Assignment: Write `]L' which allows writing the example above as
     `: bar ( -- n ) [ 2 2 + ]L ;'


File: gforth.info,  Node: Advanced macros Tutorial,  Next: Compilation Tokens Tutorial,  Prev: Literal Tutorial,  Up: Tutorial

3.35 Advanced macros
====================

Reconsider `map-array' from *note Execution Tokens: Execution Tokens
Tutorial.  It frequently performs `execute', a relatively expensive
operation in some Forth implementations.  You can use `compile,' and
`POSTPONE' to eliminate these `execute's and produce a word that
contains the word to be performed directly:

     : compile-map-array ( compilation: xt -- ; run-time: ... addr u -- ... )
     \ at run-time, execute xt ( ... x -- ... ) for each element of the
     \ array beginning at addr and containing u elements
       { xt }
       POSTPONE cells POSTPONE over POSTPONE + POSTPONE swap POSTPONE ?do
         POSTPONE i POSTPONE @ xt compile,
       1 cells POSTPONE literal POSTPONE +loop ;

     : sum-array ( addr u -- n )
      0 rot rot [ ' + compile-map-array ] ;
     see sum-array
     a 5 sum-array .

   You can use the full power of Forth for generating the code; here's
an example where the code is generated in a loop:

     : compile-vmul-step ( compilation: n --; run-time: n1 addr1 -- n2 addr2 )
     \ n2=n1+(addr1)*n, addr2=addr1+cell
       POSTPONE tuck POSTPONE @
       POSTPONE literal POSTPONE * POSTPONE +
       POSTPONE swap POSTPONE cell+ ;

     : compile-vmul ( compilation: addr1 u -- ; run-time: addr2 -- n )
     \ n=v1*v2 (inner product), where the v_i are represented as addr_i u
       0 postpone literal postpone swap
       [ ' compile-vmul-step compile-map-array ]
       postpone drop ;
     see compile-vmul

     : a-vmul ( addr -- n )
     \ n=a*v, where v is a vector that's as long as a and starts at addr
      [ a 5 compile-vmul ] ;
     see a-vmul
     a a-vmul .

   This example uses `compile-map-array' to show off, but you could
also use `map-array' instead (try it now!).

   You can use this technique for efficient multiplication of large
matrices.  In matrix multiplication, you multiply every line of one
matrix with every column of the other matrix.  You can generate the code
for one line once, and use it for every column.  The only downside of
this technique is that it is cumbersome to recover the memory consumed
by the generated code when you are done (and in more complicated cases
it is not possible portably).


File: gforth.info,  Node: Compilation Tokens Tutorial,  Next: Wordlists and Search Order Tutorial,  Prev: Advanced macros Tutorial,  Up: Tutorial

3.36 Compilation Tokens
=======================

This section is Gforth-specific.  You can skip it.

   `' word compile,' compiles the interpretation semantics.  For words
with default compilation semantics this is the same as performing the
compilation semantics.  To represent the compilation semantics of other
words (e.g., words like `if' that have no interpretation semantics),
Gforth has the concept of a compilation token (CT, consisting of two
cells), and words `comp'' and `[comp']'.  You can perform the
compilation semantics represented by a CT with `execute':

     : foo2 ( n1 n2 -- n )
        [ comp' + execute ] ;
     see foo

   You can compile the compilation semantics represented by a CT with
`postpone,':

     : foo3 ( -- )
       [ comp' + postpone, ] ;
     see foo3

   `[ comp' word postpone, ]' is equivalent to `POSTPONE word'.
`comp'' is particularly useful for words that have no interpretation
semantics:

     ' if
     comp' if .s 2drop

   Reference: *note Tokens for Words::.


File: gforth.info,  Node: Wordlists and Search Order Tutorial,  Prev: Compilation Tokens Tutorial,  Up: Tutorial

3.37 Wordlists and Search Order
===============================

The dictionary is not just a memory area that allows you to allocate
memory with `allot', it also contains the Forth words, arranged in
several wordlists.  When searching for a word in a wordlist,
conceptually you start searching at the youngest and proceed towards
older words (in reality most systems nowadays use hash-tables); i.e., if
you define a word with the same name as an older word, the new word
shadows the older word.

   Which wordlists are searched in which order is determined by the
search order.  You can display the search order with `order'.  It
displays first the search order, starting with the wordlist searched
first, then it displays the wordlist that will contain newly defined
words.

   You can create a new, empty wordlist with `wordlist ( -- wid )':

     wordlist constant mywords

   `Set-current ( wid -- )' sets the wordlist that will contain newly
defined words (the _current_ wordlist):

     mywords set-current
     order

   Gforth does not display a name for the wordlist in `mywords' because
this wordlist was created anonymously with `wordlist'.

   You can get the current wordlist with `get-current ( -- wid)'.  If
you want to put something into a specific wordlist without overall
effect on the current wordlist, this typically looks like this:

     get-current mywords set-current ( wid )
     create someword
     ( wid ) set-current

   You can write the search order with `set-order ( wid1 .. widn n --
)' and read it with `get-order ( -- wid1 .. widn n )'.  The first
searched wordlist is topmost.

     get-order mywords swap 1+ set-order
     order

   Yes, the order of wordlists in the output of `order' is reversed
from stack comments and the output of `.s' and thus unintuitive.

     Assignment: Define `>order ( wid -- )' with adds `wid' as first
     searched wordlist to the search order.  Define `previous ( -- )',
     which removes the first searched wordlist from the search order.
     Experiment with boundary conditions (you will see some crashes or
     situations that are hard or impossible to leave).

   The search order is a powerful foundation for providing features
similar to Modula-2 modules and C++ namespaces.  However, trying to
modularize programs in this way has disadvantages for debugging and
reuse/factoring that overcome the advantages in my experience (I don't
do huge projects, though).  These disadvantages are not so clear in
other languages/programming environments, because these languages are
not so strong in debugging and reuse.

   Reference: *note Word Lists::.


File: gforth.info,  Node: Introduction,  Next: Words,  Prev: Tutorial,  Up: Top

4 An Introduction to ANS Forth
******************************

The difference of this chapter from the Tutorial (*note Tutorial::) is
that it is slower-paced in its examples, but uses them to dive deep into
explaining Forth internals (not covered by the Tutorial).  Apart from
that, this chapter covers far less material.  It is suitable for reading
without using a computer.

   The primary purpose of this manual is to document Gforth. However,
since Forth is not a widely-known language and there is a lack of
up-to-date teaching material, it seems worthwhile to provide some
introductory material.  For other sources of Forth-related information,
see *note Forth-related information::.

   The examples in this section should work on any ANS Forth; the
output shown was produced using Gforth. Each example attempts to
reproduce the exact output that Gforth produces. If you try out the
examples (and you should), what you should type is shown `like this'
and Gforth's response is shown `like this'. The single exception is
that, where the example shows <RET> it means that you should press the
"carriage return" key. Unfortunately, some output formats for this
manual cannot show the difference between `this' and `this' which will
make trying out the examples harder (but not impossible).

   Forth is an unusual language. It provides an interactive development
environment which includes both an interpreter and compiler. Forth
programming style encourages you to break a problem down into many small
fragments ("factoring"), and then to develop and test each fragment
interactively. Forth advocates assert that breaking the
edit-compile-test cycle used by conventional programming languages can
lead to great productivity improvements.

* Menu:

* Introducing the Text Interpreter::
* Stacks and Postfix notation::
* Your first definition::
* How does that work?::
* Forth is written in Forth::
* Review - elements of a Forth system::
* Where to go next::
* Exercises::


File: gforth.info,  Node: Introducing the Text Interpreter,  Next: Stacks and Postfix notation,  Prev: Introduction,  Up: Introduction

4.1 Introducing the Text Interpreter
====================================

When you invoke the Forth image, you will see a startup banner printed
and nothing else (if you have Gforth installed on your system, try
invoking it now, by typing `gforth<RET>'). Forth is now running its
command line interpreter, which is called the "Text Interpreter" (also
known as the "Outer Interpreter").  (You will learn a lot about the
text interpreter as you read through this chapter, for more detail
*note The Text Interpreter::).

   Although it's not obvious, Forth is actually waiting for your input.
Type a number and press the <RET> key:

     45<RET>  ok

   Rather than give you a prompt to invite you to input something, the
text interpreter prints a status message after it has processed a line
of input. The status message in this case ("` ok'" followed by
carriage-return) indicates that the text interpreter was able to process
all of your input successfully. Now type something illegal:

     qwer341<RET>
     *the terminal*:2: Undefined word
     >>>qwer341<<<
     Backtrace:
     $2A95B42A20 throw
     $2A95B57FB8 no.extensions

   The exact text, other than the "Undefined word" may differ slightly
on your system, but the effect is the same; when the text interpreter
detects an error, it discards any remaining text on a line, resets
certain internal state and prints an error message. For a detailed
description of error messages see *note Error messages::.

   The text interpreter waits for you to press carriage-return, and then
processes your input line. Starting at the beginning of the line, it
breaks the line into groups of characters separated by spaces. For each
group of characters in turn, it makes two attempts to do something:

   * It tries to treat it as a command. It does this by searching a
     "name dictionary". If the group of characters matches an entry in
     the name dictionary, the name dictionary provides the text
     interpreter with information that allows the text interpreter
     perform some actions. In Forth jargon, we say that the group of
     characters names a "word", that the dictionary search returns an
     "execution token (xt)" corresponding to the "definition" of the
     word, and that the text interpreter executes the xt. Often, the
     terms "word" and "definition" are used interchangeably.

   * If the text interpreter fails to find a match in the name
     dictionary, it tries to treat the group of characters as a number
     in the current number base (when you start up Forth, the current
     number base is base 10). If the group of characters legitimately
     represents a number, the text interpreter pushes the number onto a
     stack (we'll learn more about that in the next section).

   If the text interpreter is unable to do either of these things with
any group of characters, it discards the group of characters and the
rest of the line, then prints an error message. If the text interpreter
reaches the end of the line without error, it prints the status message
"` ok'" followed by carriage-return.

   This is the simplest command we can give to the text interpreter:

     <RET>  ok

   The text interpreter did everything we asked it to do (nothing)
without an error, so it said that everything is "` ok'". Try a slightly
longer command:

     12 dup fred dup<RET>
     *the terminal*:3: Undefined word
     12 dup >>>fred<<< dup
     Backtrace:
     $2A95B42A20 throw
     $2A95B57FB8 no.extensions

   When you press the carriage-return key, the text interpreter starts
to work its way along the line:

   * When it gets to the space after the `2', it takes the group of
     characters `12' and looks them up in the name dictionary(1). There
     is no match for this group of characters in the name dictionary,
     so it tries to treat them as a number. It is able to do this
     successfully, so it puts the number, 12, "on the stack" (whatever
     that means).

   * The text interpreter resumes scanning the line and gets the next
     group of characters, `dup'. It looks it up in the name dictionary
     and (you'll have to take my word for this) finds it, and executes
     the word `dup' (whatever that means).

   * Once again, the text interpreter resumes scanning the line and
     gets the group of characters `fred'. It looks them up in the name
     dictionary, but can't find them. It tries to treat them as a
     number, but they don't represent any legal number.

   At this point, the text interpreter gives up and prints an error
message. The error message shows exactly how far the text interpreter
got in processing the line. In particular, it shows that the text
interpreter made no attempt to do anything with the final character
group, `dup', even though we have good reason to believe that the text
interpreter would have no problem looking that word up and executing it
a second time.

   ---------- Footnotes ----------

   (1) We can't tell if it found them or not, but assume for now that
it did not


File: gforth.info,  Node: Stacks and Postfix notation,  Next: Your first definition,  Prev: Introducing the Text Interpreter,  Up: Introduction

4.2 Stacks, postfix notation and parameter passing
==================================================

In procedural programming languages (like C and Pascal), the
building-block of programs is the "function" or "procedure". These
functions or procedures are called with "explicit parameters". For
example, in C we might write:

     total = total + new_volume(length,height,depth);

where new_volume is a function-call to another piece of code, and total,
length, height and depth are all variables. length, height and depth are
parameters to the function-call.

   In Forth, the equivalent of the function or procedure is the
"definition" and parameters are implicitly passed between definitions
using a shared stack that is visible to the programmer. Although Forth
does support variables, the existence of the stack means that they are
used far less often than in most other programming languages. When the
text interpreter encounters a number, it will place ("push") it on the
stack. There are several stacks (the actual number is
implementation-dependent ...) and the particular stack used for any
operation is implied unambiguously by the operation being performed.
The stack used for all integer operations is called the "data stack"
and, since this is the stack used most commonly, references to "the
data stack" are often abbreviated to "the stack".

   The stacks have a last-in, first-out (LIFO) organisation. If you
type:

     1 2 3<RET>  ok

   Then this instructs the text interpreter to placed three numbers on
the (data) stack. An analogy for the behaviour of the stack is to take a
pack of playing cards and deal out the ace (1), 2 and 3 into a pile on
the table. The 3 was the last card onto the pile ("last-in") and if you
take a card off the pile then, unless you're prepared to fiddle a bit,
the card that you take off will be the 3 ("first-out"). The number that
will be first-out of the stack is called the "top of stack", which is
often abbreviated to "TOS".

   To understand how parameters are passed in Forth, consider the
behaviour of the definition `+' (pronounced "plus"). You will not be
surprised to learn that this definition performs addition. More
precisely, it adds two number together and produces a result. Where does
it get the two numbers from? It takes the top two numbers off the
stack. Where does it place the result? On the stack. You can act-out the
behaviour of `+' with your playing cards like this:

   * Pick up two cards from the stack on the table

   * Stare at them intently and ask yourself "what is the sum of these
     two numbers"

   * Decide that the answer is 5

   * Shuffle the two cards back into the pack and find a 5

   * Put a 5 on the remaining ace that's on the table.

   If you don't have a pack of cards handy but you do have Forth
running, you can use the definition `.s' to show the current state of
the stack, without affecting the stack. Type:

     clearstacks 1 2 3<RET> ok
     .s<RET> <3> 1 2 3  ok

   The text interpreter looks up the word `clearstacks' and executes
it; it tidies up the stacks and removes any entries that may have been
left on it by earlier examples. The text interpreter pushes each of the
three numbers in turn onto the stack. Finally, the text interpreter
looks up the word `.s' and executes it. The effect of executing `.s' is
to print the "<3>" (the total number of items on the stack) followed by
a list of all the items on the stack; the item on the far right-hand
side is the TOS.

   You can now type:

     + .s<RET> <2> 1 5  ok

which is correct; there are now 2 items on the stack and the result of
the addition is 5.

   If you're playing with cards, try doing a second addition: pick up
the two cards, work out that their sum is 6, shuffle them into the pack,
look for a 6 and place that on the table. You now have just one item on
the stack. What happens if you try to do a third addition? Pick up the
first card, pick up the second card - ah! There is no second card. This
is called a "stack underflow" and consitutes an error. If you try to do
the same thing with Forth it often reports an error (probably a Stack
Underflow or an Invalid Memory Address error).

   The opposite situation to a stack underflow is a "stack overflow",
which simply accepts that there is a finite amount of storage space
reserved for the stack. To stretch the playing card analogy, if you had
enough packs of cards and you piled the cards up on the table, you would
eventually be unable to add another card; you'd hit the ceiling. Gforth
allows you to set the maximum size of the stacks. In general, the only
time that you will get a stack overflow is because a definition has a
bug in it and is generating data on the stack uncontrollably.

   There's one final use for the playing card analogy. If you model your
stack using a pack of playing cards, the maximum number of items on
your stack will be 52 (I assume you didn't use the Joker). The maximum
value of any item on the stack is 13 (the King). In fact, the only
possible numbers are positive integer numbers 1 through 13; you can't
have (for example) 0 or 27 or 3.52 or -2. If you change the way you
think about some of the cards, you can accommodate different numbers.
For example, you could think of the Jack as representing 0, the Queen
as representing -1 and the King as representing -2. Your range remains
unchanged (you can still only represent a total of 13 numbers) but the
numbers that you can represent are -2 through 10.

   In that analogy, the limit was the amount of information that a
single stack entry could hold, and Forth has a similar limit. In Forth,
the size of a stack entry is called a "cell". The actual size of a cell
is implementation dependent and affects the maximum value that a stack
entry can hold. A Standard Forth provides a cell size of at least
16-bits, and most desktop systems use a cell size of 32-bits.

   Forth does not do any type checking for you, so you are free to
manipulate and combine stack items in any way you wish. A convenient way
of treating stack items is as 2's complement signed integers, and that
is what Standard words like `+' do. Therefore you can type:

     -5 12 + .s<RET> <1> 7  ok

   If you use numbers and definitions like `+' in order to turn Forth
into a great big pocket calculator, you will realise that it's rather
different from a normal calculator. Rather than typing 2 + 3 = you had
to type 2 3 + (ignore the fact that you had to use `.s' to see the
result). The terminology used to describe this difference is to say that
your calculator uses "Infix Notation" (parameters and operators are
mixed) whilst Forth uses "Postfix Notation" (parameters and operators
are separate), also called "Reverse Polish Notation".

   Whilst postfix notation might look confusing to begin with, it has
several important advantages:

   * it is unambiguous

   * it is more concise

   * it fits naturally with a stack-based system

   To examine these claims in more detail, consider these sums:

     6 + 5 * 4 =
     4 * 5 + 6 =

   If you're just learning maths or your maths is very rusty, you will
probably come up with the answer 44 for the first and 26 for the
second. If you are a bit of a whizz at maths you will remember the
convention that multiplication takes precendence over addition, and
you'd come up with the answer 26 both times. To explain the answer 26
to someone who got the answer 44, you'd probably rewrite the first sum
like this:

     6 + (5 * 4) =

   If what you really wanted was to perform the addition before the
multiplication, you would have to use parentheses to force it.

   If you did the first two sums on a pocket calculator you would
probably get the right answers, unless you were very cautious and
entered them using these keystroke sequences:

   6 + 5 = * 4 = 4 * 5 = + 6 =

   Postfix notation is unambiguous because the order that the operators
are applied is always explicit; that also means that parentheses are
never required. The operators are active (the act of quoting the
operator makes the operation occur) which removes the need for "=".

   The sum 6 + 5 * 4 can be written (in postfix notation) in two
equivalent ways:

     6 5 4 * +      or:
     5 4 * 6 +

   An important thing that you should notice about this notation is that
the order of the numbers does not change; if you want to subtract 2
from 10 you type `10 2 -'.

   The reason that Forth uses postfix notation is very simple to
explain: it makes the implementation extremely simple, and it follows
naturally from using the stack as a mechanism for passing parameters.
Another way of thinking about this is to realise that all Forth
definitions are active; they execute as they are encountered by the text
interpreter. The result of this is that the syntax of Forth is trivially
simple.


File: gforth.info,  Node: Your first definition,  Next: How does that work?,  Prev: Stacks and Postfix notation,  Up: Introduction

4.3 Your first Forth definition
===============================

Until now, the examples we've seen have been trivial; we've just been
using Forth as a bigger-than-pocket calculator. Also, each calculation
we've shown has been a "one-off" - to repeat it we'd need to type it in
again(1) In this section we'll see how to add new words to Forth's
vocabulary.

   The easiest way to create a new word is to use a "colon definition".
We'll define a few and try them out before worrying too much about how
they work. Try typing in these examples; be careful to copy the spaces
accurately:

     : add-two 2 + . ;
     : greet ." Hello and welcome" ;
     : demo 5 add-two ;

Now try them out:

     greet<RET> Hello and welcome  ok
     greet greet<RET> Hello and welcomeHello and welcome  ok
     4 add-two<RET> 6  ok
     demo<RET> 7  ok
     9 greet demo add-two<RET> Hello and welcome7 11  ok

   The first new thing that we've introduced here is the pair of words
`:' and `;'. These are used to start and terminate a new definition,
respectively. The first word after the `:' is the name for the new
definition.

   As you can see from the examples, a definition is built up of words
that have already been defined; Forth makes no distinction between
definitions that existed when you started the system up, and those that
you define yourself.

   The examples also introduce the words `.' (dot), `."' (dot-quote)
and `dup' (dewp). Dot takes the value from the top of the stack and
displays it. It's like `.s' except that it only displays the top item
of the stack and it is destructive; after it has executed, the number
is no longer on the stack. There is always one space printed after the
number, and no spaces before it. Dot-quote defines a string (a sequence
of characters) that will be printed when the word is executed. The
string can contain any printable characters except `"'. A `"' has a
special function; it is not a Forth word but it acts as a delimiter
(the way that delimiters work is described in the next section).
Finally, `dup' duplicates the value at the top of the stack. Try typing
`5 dup .s' to see what it does.

   We already know that the text interpreter searches through the
dictionary to locate names. If you've followed the examples earlier, you
will already have a definition called `add-two'. Lets try modifying it
by typing in a new definition:

     : add-two dup . ." + 2 =" 2 + . ;<RET> redefined add-two  ok

   Forth recognised that we were defining a word that already exists,
and printed a message to warn us of that fact. Let's try out the new
definition:

     9 add-two<RET> 9 + 2 =11  ok

All that we've actually done here, though, is to create a new
definition, with a particular name. The fact that there was already a
definition with the same name did not make any difference to the way
that the new definition was created (except that Forth printed a warning
message). The old definition of add-two still exists (try `demo' again
to see that this is true). Any new definition will use the new
definition of `add-two', but old definitions continue to use the
version that already existed at the time that they were `compiled'.

   Before you go on to the next section, try defining and redefining
some words of your own.

   ---------- Footnotes ----------

   (1) That's not quite true. If you press the up-arrow key on your
keyboard you should be able to scroll back to any earlier command, edit
it and re-enter it.


File: gforth.info,  Node: How does that work?,  Next: Forth is written in Forth,  Prev: Your first definition,  Up: Introduction

4.4 How does that work?
=======================

Now we're going to take another look at the definition of `add-two'
from the previous section. From our knowledge of the way that the text
interpreter works, we would have expected this result when we tried to
define `add-two':

     : add-two 2 + . ;<RET>
     *the terminal*:4: Undefined word
     : >>>add-two<<< 2 + . ;

   The reason that this didn't happen is bound up in the way that `:'
works. The word `:' does two special things. The first special thing
that it does prevents the text interpreter from ever seeing the
characters `add-two'. The text interpreter uses a variable called `>IN'
(pronounced "to-in") to keep track of where it is in the input line.
When it encounters the word `:' it behaves in exactly the same way as
it does for any other word; it looks it up in the name dictionary,
finds its xt and executes it. When `:' executes, it looks at the input
buffer, finds the word `add-two' and advances the value of `>IN' to
point past it. It then does some other stuff associated with creating
the new definition (including creating an entry for `add-two' in the
name dictionary). When the execution of `:' completes, control returns
to the text interpreter, which is oblivious to the fact that it has
been tricked into ignoring part of the input line.

   Words like `:' - words that advance the value of `>IN' and so
prevent the text interpreter from acting on the whole of the input line
- are called "parsing words".

   The second special thing that `:' does is change the value of a
variable called `state', which affects the way that the text
interpreter behaves. When Gforth starts up, `state' has the value 0,
and the text interpreter is said to be "interpreting". During a colon
definition (started with `:'), `state' is set to -1 and the text
interpreter is said to be "compiling".

   In this example, the text interpreter is compiling when it processes
the string "`2 + . ;'". It still breaks the string down into character
sequences in the same way. However, instead of pushing the number `2'
onto the stack, it lays down ("compiles") some magic into the
definition of `add-two' that will make the number `2' get pushed onto
the stack when `add-two' is "executed". Similarly, the behaviours of
`+' and `.' are also compiled into the definition.

   One category of words don't get compiled. These so-called "immediate
words" get executed (performed now) regardless of whether the text
interpreter is interpreting or compiling. The word `;' is an immediate
word. Rather than being compiled into the definition, it executes. Its
effect is to terminate the current definition, which includes changing
the value of `state' back to 0.

   When you execute `add-two', it has a "run-time effect" that is
exactly the same as if you had typed `2 + . <RET>' outside of a
definition.

   In Forth, every word or number can be described in terms of two
properties:

   * Its "interpretation semantics" describe how it will behave when the
     text interpreter encounters it in "interpret" state. The
     interpretation semantics of a word are represented by an "execution
     token".

   * Its "compilation semantics" describe how it will behave when the
     text interpreter encounters it in "compile" state. The compilation
     semantics of a word are represented in an implementation-dependent
     way; Gforth uses a "compilation token".

Numbers are always treated in a fixed way:

   * When the number is "interpreted", its behaviour is to push the
     number onto the stack.

   * When the number is "compiled", a piece of code is appended to the
     current definition that pushes the number when it runs. (In other
     words, the compilation semantics of a number are to postpone its
     interpretation semantics until the run-time of the definition that
     it is being compiled into.)

   Words don't behave in such a regular way, but most have default
semantics which means that they behave like this:

   * The "interpretation semantics" of the word are to do something
     useful.

   * The "compilation semantics" of the word are to append its
     "interpretation semantics" to the current definition (so that its
     run-time behaviour is to do something useful).

   The actual behaviour of any particular word can be controlled by
using the words `immediate' and `compile-only' when the word is
defined. These words set flags in the name dictionary entry of the most
recently defined word, and these flags are retrieved by the text
interpreter when it finds the word in the name dictionary.

   A word that is marked as "immediate" has compilation semantics that
are identical to its interpretation semantics. In other words, it
behaves like this:

   * The "interpretation semantics" of the word are to do something
     useful.

   * The "compilation semantics" of the word are to do something useful
     (and actually the same thing); i.e., it is executed during
     compilation.

   Marking a word as "compile-only" prohibits the text interpreter from
performing the interpretation semantics of the word directly; an attempt
to do so will generate an error. It is never necessary to use
`compile-only' (and it is not even part of ANS Forth, though it is
provided by many implementations) but it is good etiquette to apply it
to a word that will not behave correctly (and might have unexpected
side-effects) in interpret state. For example, it is only legal to use
the conditional word `IF' within a definition. If you forget this and
try to use it elsewhere, the fact that (in Gforth) it is marked as
`compile-only' allows the text interpreter to generate a helpful error
message rather than subjecting you to the consequences of your folly.

   This example shows the difference between an immediate and a
non-immediate word:

     : show-state state @ . ;
     : show-state-now show-state ; immediate
     : word1 show-state ;
     : word2 show-state-now ;

   The word `immediate' after the definition of `show-state-now' makes
that word an immediate word. These definitions introduce a new word:
`@' (pronounced "fetch"). This word fetches the value of a variable,
and leaves it on the stack. Therefore, the behaviour of `show-state' is
to print a number that represents the current value of `state'.

   When you execute `word1', it prints the number 0, indicating that
the system is interpreting. When the text interpreter compiled the
definition of `word1', it encountered `show-state' whose compilation
semantics are to append its interpretation semantics to the current
definition. When you execute `word1', it performs the interpretation
semantics of `show-state'.  At the time that `word1' (and therefore
`show-state') are executed, the system is interpreting.

   When you pressed <RET> after entering the definition of `word2', you
should have seen the number -1 printed, followed by "` ok'". When the
text interpreter compiled the definition of `word2', it encountered
`show-state-now', an immediate word, whose compilation semantics are
therefore to perform its interpretation semantics. It is executed
straight away (even before the text interpreter has moved on to process
another group of characters; the `;' in this example). The effect of
executing it are to display the value of `state' at the time that the
definition of `word2' is being defined. Printing -1 demonstrates that
the system is compiling at this time. If you execute `word2' it does
nothing at all.

   Before leaving the subject of immediate words, consider the
behaviour of `."' in the definition of `greet', in the previous
section. This word is both a parsing word and an immediate word. Notice
that there is a space between `."' and the start of the text `Hello and
welcome', but that there is no space between the last letter of
`welcome' and the `"' character. The reason for this is that `."' is a
Forth word; it must have a space after it so that the text interpreter
can identify it. The `"' is not a Forth word; it is a "delimiter". The
examples earlier show that, when the string is displayed, there is
neither a space before the `H' nor after the `e'. Since `."' is an
immediate word, it executes at the time that `greet' is defined. When
it executes, its behaviour is to search forward in the input line
looking for the delimiter. When it finds the delimiter, it updates
`>IN' to point past the delimiter. It also compiles some magic code
into the definition of `greet'; the xt of a run-time routine that
prints a text string. It compiles the string `Hello and welcome' into
memory so that it is available to be printed later. When the text
interpreter gains control, the next word it finds in the input stream
is `;' and so it terminates the definition of `greet'.


File: gforth.info,  Node: Forth is written in Forth,  Next: Review - elements of a Forth system,  Prev: How does that work?,  Up: Introduction

4.5 Forth is written in Forth
=============================

When you start up a Forth compiler, a large number of definitions
already exist. In Forth, you develop a new application using bottom-up
programming techniques to create new definitions that are defined in
terms of existing definitions. As you create each definition you can
test and debug it interactively.

   If you have tried out the examples in this section, you will probably
have typed them in by hand; when you leave Gforth, your definitions will
be lost. You can avoid this by using a text editor to enter Forth source
code into a file, and then loading code from the file using `include'
(*note Forth source files::). A Forth source file is processed by the
text interpreter, just as though you had typed it in by hand(1).

   Gforth also supports the traditional Forth alternative to using text
files for program entry (*note Blocks::).

   In common with many, if not most, Forth compilers, most of Gforth is
actually written in Forth. All of the `.fs' files in the installation
directory(2) are Forth source files, which you can study to see
examples of Forth programming.

   Gforth maintains a history file that records every line that you
type to the text interpreter. This file is preserved between sessions,
and is used to provide a command-line recall facility. If you enter long
definitions by hand, you can use a text editor to paste them out of the
history file into a Forth source file for reuse at a later time (for
more information *note Command-line editing::).

   ---------- Footnotes ----------

   (1) Actually, there are some subtle differences - see *note The Text
Interpreter::.

   (2) For example, `/usr/local/share/gforth...'


File: gforth.info,  Node: Review - elements of a Forth system,  Next: Where to go next,  Prev: Forth is written in Forth,  Up: Introduction

4.6 Review - elements of a Forth system
=======================================

To summarise this chapter:

   * Forth programs use "factoring" to break a problem down into small
     fragments called "words" or "definitions".

   * Forth program development is an interactive process.

   * The main command loop that accepts input, and controls both
     interpretation and compilation, is called the "text interpreter"
     (also known as the "outer interpreter").

   * Forth has a very simple syntax, consisting of words and numbers
     separated by spaces or carriage-return characters. Any additional
     syntax is imposed by "parsing words".

   * Forth uses a stack to pass parameters between words. As a result,
     it uses postfix notation.

   * To use a word that has previously been defined, the text
     interpreter searches for the word in the "name dictionary".

   * Words have "interpretation semantics" and "compilation semantics".

   * The text interpreter uses the value of `state' to select between
     the use of the "interpretation semantics" and the  "compilation
     semantics" of a word that it encounters.

   * The relationship between the "interpretation semantics" and
     "compilation semantics" for a word depend upon the way in which
     the word was defined (for example, whether it is an "immediate"
     word).

   * Forth definitions can be implemented in Forth (called "high-level
     definitions") or in some other way (usually a lower-level language
     and as a result often called "low-level definitions", "code
     definitions" or "primitives").

   * Many Forth systems are implemented mainly in Forth.


File: gforth.info,  Node: Where to go next,  Next: Exercises,  Prev: Review - elements of a Forth system,  Up: Introduction

4.7 Where To Go Next
====================

Amazing as it may seem, if you have read (and understood) this far, you
know almost all the fundamentals about the inner workings of a Forth
system. You certainly know enough to be able to read and understand the
rest of this manual and the ANS Forth document, to learn more about the
facilities that Forth in general and Gforth in particular provide. Even
scarier, you know almost enough to implement your own Forth system.
However, that's not a good idea just yet... better to try writing some
programs in Gforth.

   Forth has such a rich vocabulary that it can be hard to know where to
start in learning it. This section suggests a few sets of words that are
enough to write small but useful programs. Use the word index in this
document to learn more about each word, then try it out and try to write
small definitions using it. Start by experimenting with these words:

   * Arithmetic: `+ - * / /MOD */ ABS INVERT'

   * Comparison: `MIN MAX ='

   * Logic: `AND OR XOR NOT'

   * Stack manipulation: `DUP DROP SWAP OVER'

   * Loops and decisions: `IF ELSE ENDIF ?DO I LOOP'

   * Input/Output: `. ." EMIT CR KEY'

   * Defining words: `: ; CREATE'

   * Memory allocation words: `ALLOT ,'

   * Tools: `SEE WORDS .S MARKER'

   When you have mastered those, go on to:

   * More defining words: `VARIABLE CONSTANT VALUE TO CREATE DOES>'

   * Memory access: `@ !'

   When you have mastered these, there's nothing for it but to read
through the whole of this manual and find out what you've missed.


File: gforth.info,  Node: Exercises,  Prev: Where to go next,  Up: Introduction

4.8 Exercises
=============

TODO: provide a set of programming excercises linked into the stuff done
already and into other sections of the manual. Provide solutions to all
the exercises in a .fs file in the distribution.


File: gforth.info,  Node: Words,  Next: Error messages,  Prev: Introduction,  Up: Top

5 Forth Words
*************

* Menu:

* Notation::
* Case insensitivity::
* Comments::
* Boolean Flags::
* Arithmetic::
* Stack Manipulation::
* Memory::
* Control Structures::
* Defining Words::
* Interpretation and Compilation Semantics::
* Tokens for Words::
* Compiling words::
* The Text Interpreter::
* The Input Stream::
* Word Lists::
* Environmental Queries::
* Files::
* Blocks::
* Other I/O::
* OS command line arguments::
* Locals::
* Structures::
* Object-oriented Forth::
* Programming Tools::
* C Interface::
* Assembler and Code Words::
* Threading Words::
* Passing Commands to the OS::
* Keeping track of Time::
* Miscellaneous Words::


File: gforth.info,  Node: Notation,  Next: Case insensitivity,  Prev: Words,  Up: Words

5.1 Notation
============

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

word     Stack effect   wordset   pronunciation
   Description

WORD
     The name of the word.

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 Gforth 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.

     All words have two stack effects: A compile-time stack effect and a
     run-time stack effect. The compile-time stack-effect of most words
     is  - . If the compile-time stack-effect of a word deviates from
     this standard behaviour, or the word does other unusual things at
     compile time, both stack effects are shown; otherwise only the
     run-time stack effect is shown.

PRONUNCIATION
     How the word is pronounced.

WORDSET
     The ANS Forth standard is divided into several word sets. A
     standard system need not support all of them. Therefore, in
     theory, the fewer word sets your program uses the more portable it
     will be. However, we suspect that most ANS Forth systems on
     personal machines will feature all word sets. Words that are not
     defined in ANS Forth have `gforth' or `gforth-internal' as word
     set. `gforth' describes words that will work in future releases of
     Gforth; `gforth-internal' words are more volatile. Environmental
     query strings are also displayed like words; you can recognize
     them by the `environment' in the word set field.

DESCRIPTION
     A description of the behaviour of the word.

   The type of a stack item is specified by the character(s) the name
starts with:

`f'
     Boolean flags, 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 (on the FP stack)

`a-'
     Cell-aligned address

`c-'
     Char-aligned address (note that a Char may have 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'
     Word list ID, same size as Cell

`ior, wior'
     I/O result code, cell-sized.  In Gforth, you can `throw' iors.

`f83name'
     Pointer to a name structure

`"'
     string in the input stream (not on the stack). The terminating
     character is a blank by default. If it is not a blank, it is shown
     in `<>' quotes.


File: gforth.info,  Node: Case insensitivity,  Next: Comments,  Prev: Notation,  Up: Words

5.2 Case insensitivity
======================

Gforth is case-insensitive; you can enter definitions and invoke
Standard words using upper, lower or mixed case (however, *note
Implementation-defined options: core-idef.).

   ANS Forth only requires implementations to recognise Standard words
when they are typed entirely in upper case. Therefore, a Standard
program must use upper case for all Standard words. You can use whatever
case you like for words that you define, but in a Standard program you
have to use the words in the same case that you defined them.

   Gforth supports case sensitivity through `table's (case-sensitive
wordlists, *note Word Lists::).

   Two people have asked how to convert Gforth to be case-sensitive;
while we think this is a bad idea, you can change all wordlists into
tables like this:

     ' table-find forth-wordlist wordlist-map  !

   Note that you now have to type the predefined words in the same case
that we defined them, which are varying.  You may want to convert them
to your favourite case before doing this operation (I won't explain how,
because if you are even contemplating doing this, you'd better have
enough knowledge of Forth systems to know this already).


File: gforth.info,  Node: Comments,  Next: Boolean Flags,  Prev: Case insensitivity,  Up: Words

5.3 Comments
============

Forth supports two styles of comment; the traditional in-line comment,
`(' and its modern cousin, the comment to end of line; `\'.

`('       compilation 'ccc<close-paren>' - ; run-time -         core,file       "paren"
   Comment, usually till the next `)': parse and discard all subsequent
characters in the parse area until ")" is encountered. During
interactive input, an end-of-line also acts as a comment terminator.
For file input, it does not; if the end-of-file is encountered whilst
parsing for the ")" delimiter, Gforth will generate a warning.

`\'       compilation 'ccc<newline>' - ; run-time -         core-ext,block-ext       "backslash"
   Comment till the end of the line if `BLK' contains 0 (i.e., while
not loading a block), parse and discard the remainder of the parse
area. Otherwise, parse and discard all subsequent characters in the
parse area corresponding to the current line.

`\G'       compilation 'ccc<newline>' - ; run-time -         gforth       "backslash-gee"
   Equivalent to `\' but used as a tag to annotate definition comments
into documentation.


File: gforth.info,  Node: Boolean Flags,  Next: Arithmetic,  Prev: Comments,  Up: Words

5.4 Boolean Flags
=================

A Boolean flag is cell-sized. A cell with all bits clear represents the
flag `false' and a flag with all bits set represents the flag `true'.
Words that check a flag (for example, `IF') will treat a cell that has
any bit set as `true'.

`true'       - f         core-ext       "true"
   `Constant' - f is a cell with all bits set.

`false'       - f         core-ext       "false"
   `Constant' - f is a cell with all bits clear.

`on'       a-addr -         gforth       "on"
   Set the (value of the) variable  at a-addr to `true'.

`off'       a-addr -         gforth       "off"
   Set the (value of the) variable at a-addr to `false'.


File: gforth.info,  Node: Arithmetic,  Next: Stack Manipulation,  Prev: Boolean Flags,  Up: Words

5.5 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, *note Mixed precision::).

* Menu:

* Single precision::
* Double precision::            Double-cell integer arithmetic
* Bitwise operations::
* Numeric comparison::
* Mixed precision::             Operations with single and double-cell integers
* Floating Point::


File: gforth.info,  Node: Single precision,  Next: Double precision,  Prev: Arithmetic,  Up: Arithmetic

5.5.1 Single precision
----------------------

By default, numbers in Forth are single-precision integers that are one
cell in size. They can be signed or unsigned, depending upon how you
treat them. For the rules used by the text interpreter for recognising
single-precision integers see *note Number Conversion::.

   These words are all defined for signed operands, but some of them
also work for unsigned numbers: `+', `1+', `-', `1-', `*'.

`+'       n1 n2 - n        core       "plus"

`1+'       n1 - n2        core       "one-plus"

`under+'       n1 n2 n3 - n n2        gforth       "under-plus"
   add n3 to n1 (giving n)

`-'       n1 n2 - n        core       "minus"

`1-'       n1 - n2        core       "one-minus"

`*'       n1 n2 - n        core       "star"

`/'       n1 n2 - n        core       "slash"

`mod'       n1 n2 - n        core       "mod"

`/mod'       n1 n2 - n3 n4        core       "slash-mod"

`negate'       n1 - n2        core       "negate"

`abs'       n - u        core       "abs"

`min'       n1 n2 - n        core       "min"

`max'       n1 n2 - n        core       "max"

`FLOORED'       - f         environment       "FLOORED"
   True if `/' etc. perform floored division


File: gforth.info,  Node: Double precision,  Next: Bitwise operations,  Prev: Single precision,  Up: Arithmetic

5.5.2 Double precision
----------------------

For the rules used by the text interpreter for recognising
double-precision integers, see *note Number Conversion::.

   A double precision number is represented by a cell pair, with the
most significant cell at the TOS. It is trivial to convert an unsigned
single to a double: simply push a `0' onto the TOS. Since numbers are
represented by Gforth using 2's complement arithmetic, converting a
signed single to a (signed) double requires sign-extension across the
most significant cell. This can be achieved using `s>d'. The moral of
the story is that you cannot convert a number without knowing whether
it represents an unsigned or a signed number.

   These words are all defined for signed operands, but some of them
also work for unsigned numbers: `d+', `d-'.

`s>d'       n - d         core       "s-to-d"

`d>s'       d - n         double       "d-to-s"

`d+'       d1 d2 - d        double       "d-plus"

`d-'       d1 d2 - d        double       "d-minus"

`dnegate'       d1 - d2        double       "d-negate"

`dabs'       d - ud         double       "d-abs"

`dmin'       d1 d2 - d         double       "d-min"

`dmax'       d1 d2 - d         double       "d-max"


File: gforth.info,  Node: Bitwise operations,  Next: Numeric comparison,  Prev: Double precision,  Up: Arithmetic

5.5.3 Bitwise operations
------------------------

`and'       w1 w2 - w        core       "and"

`or'       w1 w2 - w        core       "or"

`xor'       w1 w2 - w        core       "x-or"

`invert'       w1 - w2        core       "invert"

`lshift'       u1 n - u2        core       "l-shift"

`rshift'       u1 n - u2        core       "r-shift"
   Logical shift right by n bits.

`2*'       n1 - n2        core       "two-star"
   Shift left by 1; also works on unsigned numbers

`d2*'       d1 - d2        double       "d-two-star"
   Shift left by 1; also works on unsigned numbers

`2/'       n1 - n2        core       "two-slash"
   Arithmetic shift right by 1.  For signed numbers this is a floored
division by 2 (note that `/' not necessarily floors).

`d2/'       d1 - d2        double       "d-two-slash"
   Arithmetic shift right by 1.  For signed numbers this is a floored
division by 2.


File: gforth.info,  Node: Numeric comparison,  Next: Mixed precision,  Prev: Bitwise operations,  Up: Arithmetic

5.5.4 Numeric comparison
------------------------

Note that the words that compare for equality (`= <> 0= 0<> d= d<> d0=
d0<>') work for for both signed and unsigned numbers.

`<'       n1 n2 - f        core       "less-than"

`<='       n1 n2 - f        gforth       "less-or-equal"

`<>'       n1 n2 - f        core-ext       "not-equals"

`='       n1 n2 - f        core       "equals"

`>'       n1 n2 - f        core       "greater-than"

`>='       n1 n2 - f        gforth       "greater-or-equal"

`0<'       n - f        core       "zero-less-than"

`0<='       n - f        gforth       "zero-less-or-equal"

`0<>'       n - f        core-ext       "zero-not-equals"

`0='       n - f        core       "zero-equals"

`0>'       n - f        core-ext       "zero-greater-than"

`0>='       n - f        gforth       "zero-greater-or-equal"

`u<'       u1 u2 - f        core       "u-less-than"

`u<='       u1 u2 - f        gforth       "u-less-or-equal"

`u>'       u1 u2 - f        core-ext       "u-greater-than"

`u>='       u1 u2 - f        gforth       "u-greater-or-equal"

`within'       u1 u2 u3 - f        core-ext       "within"
   u2=<u1<u3 or: u3=<u2 and u1 is not in [u3,u2).  This works for
unsigned and signed numbers (but not a mixture).  Another way to think
about this word is to consider the numbers as a circle (wrapping around
from `max-u' to 0 for unsigned, and from `max-n' to min-n for signed
numbers); now consider the range from u2 towards increasing numbers up
to and excluding u3 (giving an empty range if u2=u3); if u1 is in this
range, `within' returns true.

`d<'       d1 d2 - f        double       "d-less-than"

`d<='       d1 d2 - f        gforth       "d-less-or-equal"

`d<>'       d1 d2 - f        gforth       "d-not-equals"

`d='       d1 d2 - f        double       "d-equals"

`d>'       d1 d2 - f        gforth       "d-greater-than"

`d>='       d1 d2 - f        gforth       "d-greater-or-equal"

`d0<'       d - f        double       "d-zero-less-than"

`d0<='       d - f        gforth       "d-zero-less-or-equal"

`d0<>'       d - f        gforth       "d-zero-not-equals"

`d0='       d - f        double       "d-zero-equals"

`d0>'       d - f        gforth       "d-zero-greater-than"

`d0>='       d - f        gforth       "d-zero-greater-or-equal"

`du<'       ud1 ud2 - f        double-ext       "d-u-less-than"

`du<='       ud1 ud2 - f        gforth       "d-u-less-or-equal"

`du>'       ud1 ud2 - f        gforth       "d-u-greater-than"

`du>='       ud1 ud2 - f        gforth       "d-u-greater-or-equal"


File: gforth.info,  Node: Mixed precision,  Next: Floating Point,  Prev: Numeric comparison,  Up: Arithmetic

5.5.5 Mixed precision
---------------------

`m+'       d1 n - d2        double       "m-plus"

`*/'       n1 n2 n3 - n4        core       "star-slash"
   n4=(n1*n2)/n3, with the intermediate result being double.

`*/mod'       n1 n2 n3 - n4 n5        core       "star-slash-mod"
   n1*n2=n3*n5+n4, with the intermediate result (n1*n2) being double.

`m*'       n1 n2 - d        core       "m-star"

`um*'       u1 u2 - ud        core       "u-m-star"

`m*/'       d1 n2 u3 - dquot         double       "m-star-slash"
   dquot=(d1*n2)/u3, with the intermediate result being
triple-precision.  In ANS Forth u3 can only be a positive signed number.

`um/mod'       ud u1 - u2 u3        core       "u-m-slash-mod"
   ud=u3*u1+u2, u1>u2>=0

`fm/mod'       d1 n1 - n2 n3        core       "f-m-slash-mod"
   Floored division: d1 = n3*n1+n2, n1>n2>=0 or 0>=n2>n1.

`sm/rem'       d1 n1 - n2 n3        core       "s-m-slash-rem"
   Symmetric division: d1 = n3*n1+n2, sign(n2)=sign(d1) or 0.


File: gforth.info,  Node: Floating Point,  Prev: Mixed precision,  Up: Arithmetic

5.5.6 Floating Point
--------------------

For the rules used by the text interpreter for recognising
floating-point numbers see *note Number Conversion::.

   Gforth has a separate floating point stack, but the documentation
uses the unified notation.(1)

   Floating point numbers have a number of unpleasant surprises for the
unwary (e.g., floating point addition is not associative) and even a
few for the wary. You should not use them unless you know what you are
doing or you don't care that the results you get are totally bogus. If
you want to learn about the problems of floating point numbers (and how
to avoid them), you might start with `David Goldberg, What Every
Computer Scientist Should Know About Floating-Point Arithmetic
(http://docs.sun.com/source/806-3568/ncg_goldberg.html), ACM Computing
Surveys 23(1):5-48, March 1991'.

`d>f'       d - r        float       "d-to-f"

`f>d'       r - d        float       "f-to-d"

`f+'       r1 r2 - r3        float       "f-plus"

`f-'       r1 r2 - r3        float       "f-minus"

`f*'       r1 r2 - r3        float       "f-star"

`f/'       r1 r2 - r3        float       "f-slash"

`fnegate'       r1 - r2        float       "f-negate"

`fabs'       r1 - r2        float-ext       "f-abs"

`fmax'       r1 r2 - r3        float       "f-max"

`fmin'       r1 r2 - r3        float       "f-min"

`floor'       r1 - r2        float       "floor"
   Round towards the next smaller integral value, i.e., round toward
negative infinity.

`fround'       r1 - r2        float       "f-round"
   Round to the nearest integral value.

`f**'       r1 r2 - r3        float-ext       "f-star-star"
   r3 is r1 raised to the r2th power.

`fsqrt'       r1 - r2        float-ext       "f-square-root"

`fexp'       r1 - r2        float-ext       "f-e-x-p"

`fexpm1'       r1 - r2        float-ext       "f-e-x-p-m-one"
   r2=e**r1-1

`fln'       r1 - r2        float-ext       "f-l-n"

`flnp1'       r1 - r2        float-ext       "f-l-n-p-one"
   r2=ln(r1+1)

`flog'       r1 - r2        float-ext       "f-log"
   The decimal logarithm.

`falog'       r1 - r2        float-ext       "f-a-log"
   r2=10**r1

`f2*'       r1 - r2         gforth       "f2*"
   Multiply r1 by 2.0e0

`f2/'       r1 - r2         gforth       "f2/"
   Multiply r1 by 0.5e0

`1/f'       r1 - r2         gforth       "1/f"
   Divide 1.0e0 by r1.

`precision'       - u         float-ext       "precision"
   u is the number of significant digits currently used by `F.' `FE.'
and `FS.'

`set-precision'       u -         float-ext       "set-precision"
   Set the number of significant digits currently used by `F.' `FE.'
and `FS.' to u.

   Angles in floating point operations are given in radians (a full
circle has 2 pi radians).

`fsin'       r1 - r2        float-ext       "f-sine"

`fcos'       r1 - r2        float-ext       "f-cos"

`fsincos'       r1 - r2 r3        float-ext       "f-sine-cos"
   r2=sin(r1), r3=cos(r1)

`ftan'       r1 - r2        float-ext       "f-tan"

`fasin'       r1 - r2        float-ext       "f-a-sine"

`facos'       r1 - r2        float-ext       "f-a-cos"

`fatan'       r1 - r2        float-ext       "f-a-tan"

`fatan2'       r1 r2 - r3        float-ext       "f-a-tan-two"
   r1/r2=tan(r3). ANS Forth does not require, but probably intends this
to be the inverse of `fsincos'. In gforth it is.

`fsinh'       r1 - r2        float-ext       "f-cinch"

`fcosh'       r1 - r2        float-ext       "f-cosh"

`ftanh'       r1 - r2        float-ext       "f-tan-h"

`fasinh'       r1 - r2        float-ext       "f-a-cinch"

`facosh'       r1 - r2        float-ext       "f-a-cosh"

`fatanh'       r1 - r2        float-ext       "f-a-tan-h"

`pi'       - r         gforth       "pi"
   `Fconstant' - r is the value pi; the ratio of a circle's area to its
diameter.

   One particular problem with floating-point arithmetic is that
comparison for equality often fails when you would expect it to
succeed.  For this reason approximate equality is often preferred (but
you still have to know what you are doing).  Also note that IEEE NaNs
may compare differently from what you might expect.  The comparison
words are:

`f~rel'       r1 r2 r3 - flag         gforth       "f~rel"
   Approximate equality with relative error: |r1-r2|<r3*|r1+r2|.

`f~abs'       r1 r2 r3 - flag         gforth       "f~abs"
   Approximate equality with absolute error: |r1-r2|<r3.

`f~'       r1 r2 r3 - flag         float-ext       "f-proximate"
   ANS Forth medley for comparing r1 and r2 for equality: r3>0:
`f~abs'; r3=0: bitwise comparison; r3<0: `fnegate f~rel'.

`f='       r1 r2 - f        gforth       "f-equals"

`f<>'       r1 r2 - f        gforth       "f-not-equals"

`f<'       r1 r2 - f        float       "f-less-than"

`f<='       r1 r2 - f        gforth       "f-less-or-equal"

`f>'       r1 r2 - f        gforth       "f-greater-than"

`f>='       r1 r2 - f        gforth       "f-greater-or-equal"

`f0<'       r - f        float       "f-zero-less-than"

`f0<='       r - f        gforth       "f-zero-less-or-equal"

`f0<>'       r - f        gforth       "f-zero-not-equals"

`f0='       r - f        float       "f-zero-equals"

`f0>'       r - f        gforth       "f-zero-greater-than"

`f0>='       r - f        gforth       "f-zero-greater-or-equal"

   ---------- Footnotes ----------

   (1) It's easy to generate the separate notation from that by just
separating the floating-point numbers out: e.g. `( n r1 u r2 -- r3 )'
becomes `( n u -- ) ( F: r1 r2 -- r3 )'.


File: gforth.info,  Node: Stack Manipulation,  Next: Memory,  Prev: Arithmetic,  Up: Words

5.6 Stack Manipulation
======================

Gforth maintains a number of separate stacks:

   * A data stack (also known as the "parameter stack") - for
     characters, cells, addresses, and double cells.

   * A floating point stack - for holding floating point (FP) numbers.

   * A return stack - for holding the return addresses of colon
     definitions and other (non-FP) data.

   * A locals stack - for holding local variables.

* Menu:

* Data stack::
* Floating point stack::
* Return stack::
* Locals stack::
* Stack pointer manipulation::


File: gforth.info,  Node: Data stack,  Next: Floating point stack,  Prev: Stack Manipulation,  Up: Stack Manipulation

5.6.1 Data stack
----------------

`drop'       w -        core       "drop"

`nip'       w1 w2 - w2        core-ext       "nip"

`dup'       w - w w        core       "dupe"

`over'       w1 w2 - w1 w2 w1        core       "over"

`tuck'       w1 w2 - w2 w1 w2        core-ext       "tuck"

`swap'       w1 w2 - w2 w1        core       "swap"

`pick'       S:... u - S:... w        core-ext       "pick"
   Actually the stack effect is ` x0 ... xu u -- x0 ... xu x0 '.

`rot'       w1 w2 w3 - w2 w3 w1        core       "rote"

`-rot'       w1 w2 w3 - w3 w1 w2        gforth       "not-rote"

`?dup'       w - S:... w        core       "question-dupe"
   Actually the stack effect is: `( w -- 0 | w w )'.  It performs a
`dup' if w is nonzero.

`roll'       x0 x1 .. xn n - x1 .. xn x0         core-ext       "roll"

`2drop'       w1 w2 -        core       "two-drop"

`2nip'       w1 w2 w3 w4 - w3 w4        gforth       "two-nip"

`2dup'       w1 w2 - w1 w2 w1 w2        core       "two-dupe"

`2over'       w1 w2 w3 w4 - w1 w2 w3 w4 w1 w2        core       "two-over"

`2tuck'       w1 w2 w3 w4 - w3 w4 w1 w2 w3 w4        gforth       "two-tuck"

`2swap'       w1 w2 w3 w4 - w3 w4 w1 w2        core       "two-swap"

`2rot'       w1 w2 w3 w4 w5 w6 - w3 w4 w5 w6 w1 w2        double-ext       "two-rote"


File: gforth.info,  Node: Floating point stack,  Next: Return stack,  Prev: Data stack,  Up: Stack Manipulation

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

Whilst every sane Forth has a separate floating-point stack, it 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 number 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. Instead, just
say that your program has an environmental dependency on a separate
floating-point stack.

`floating-stack'       - n         environment       "floating-stack"
   N is non-zero, showing that Gforth maintains a separate
floating-point stack of depth N.

`fdrop'       r -        float       "f-drop"

`fnip'       r1 r2 - r2        gforth       "f-nip"

`fdup'       r - r r        float       "f-dupe"

`fover'       r1 r2 - r1 r2 r1        float       "f-over"

`ftuck'       r1 r2 - r2 r1 r2        gforth       "f-tuck"

`fswap'       r1 r2 - r2 r1        float       "f-swap"

`fpick'       f:... u - f:... r        gforth       "fpick"
   Actually the stack effect is ` r0 ... ru u -- r0 ... ru r0 '.

`frot'       r1 r2 r3 - r2 r3 r1        float       "f-rote"


File: gforth.info,  Node: Return stack,  Next: Locals stack,  Prev: Floating point stack,  Up: Stack Manipulation

5.6.3 Return stack
------------------

A Forth system is allowed to keep local variables on the return stack.
This is reasonable, as local variables usually eliminate the need to
use the return stack explicitly. So, if you want to produce a standard
compliant program and you are using local variables in a word, forget
about return stack manipulations in that word (refer to the standard
document for the exact rules).

`>r'       w - R:w        core       "to-r"

`r>'       R:w - w        core       "r-from"

`r@'       - w ; R: w - w         core       "r-fetch"

`rdrop'       R:w -        gforth       "rdrop"

`2>r'       d - R:d        core-ext       "two-to-r"

`2r>'       R:d - d        core-ext       "two-r-from"

`2r@'       R:d - R:d d        core-ext       "two-r-fetch"

`2rdrop'       R:d -        gforth       "two-r-drop"


File: gforth.info,  Node: Locals stack,  Next: Stack pointer manipulation,  Prev: Return stack,  Up: Stack Manipulation

5.6.4 Locals stack
------------------

Gforth uses an extra locals stack.  It is described, along with the
reasons for its existence, in *note Locals implementation::.


File: gforth.info,  Node: Stack pointer manipulation,  Prev: Locals stack,  Up: Stack Manipulation

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

`sp0'       - a-addr         gforth       "sp0"
`User' variable - initial value of the data stack pointer.  OBSOLETE
alias of `sp0'

`sp@'       S:... - a-addr        gforth       "sp-fetch"

`sp!'       a-addr - S:...        gforth       "sp-store"

`fp0'       - a-addr         gforth       "fp0"
   `User' variable - initial value of the floating-point stack pointer.

`fp@'       f:... - f-addr        gforth       "fp-fetch"

`fp!'       f-addr - f:...        gforth       "fp-store"

`rp0'       - a-addr         gforth       "rp0"
   `User' variable - initial value of the return stack pointer.
OBSOLETE alias of `rp0'

`rp@'       - a-addr        gforth       "rp-fetch"

`rp!'       a-addr -        gforth       "rp-store"

`lp0'       - a-addr         gforth       "lp0"
   `User' variable - initial value of the locals stack pointer.
OBSOLETE alias of `lp0'

`lp@'       - addr         gforth       "lp-fetch"

`lp!'       c-addr -        gforth       "lp-store"


File: gforth.info,  Node: Memory,  Next: Control Structures,  Prev: Stack Manipulation,  Up: Words

5.7 Memory
==========

* Menu:

* Memory model::
* Dictionary allocation::
* Heap Allocation::
* Memory Access::
* Address arithmetic::
* Memory Blocks::

   In addition to the standard Forth memory allocation words, there is
also a garbage collector
(http://www.complang.tuwien.ac.at/forth/garbage-collection.zip).


File: gforth.info,  Node: Memory model,  Next: Dictionary allocation,  Prev: Memory,  Up: Memory

5.7.1 ANS Forth and Gforth memory models
----------------------------------------

ANS Forth considers a Forth system as consisting of several address
spaces, of which only "data space" is managed and accessible with the
memory words.  Memory not necessarily in data space includes the
stacks, the code (called code space) and the headers (called name
space). In Gforth everything is in data space, but the code for the
primitives is usually read-only.

   Data space is divided into a number of areas: The (data space
portion of the) dictionary(1), the heap, and a number of
system-allocated buffers.

   In ANS Forth data space is also divided into contiguous regions.  You
can only use address arithmetic within a contiguous region, not between
them.  Usually each allocation gives you one contiguous region, but the
dictionary allocation words have additional rules (*note Dictionary
allocation::).

   Gforth provides one big address space, and address arithmetic can be
performed between any addresses. However, in the dictionary headers or
code are interleaved with data, so almost the only contiguous data space
regions there are those described by ANS Forth as contiguous; but you
can be sure that the dictionary is allocated towards increasing
addresses even between contiguous regions.  The memory order of
allocations in the heap is platform-dependent (and possibly different
from one run to the next).

   ---------- Footnotes ----------

   (1) Sometimes, the term "dictionary" is used to refer to the search
data structure embodied in word lists and headers, because it is used
for looking up names, just as you would in a conventional dictionary.


File: gforth.info,  Node: Dictionary allocation,  Next: Heap Allocation,  Prev: Memory model,  Up: Memory

5.7.2 Dictionary allocation
---------------------------

Dictionary allocation is a stack-oriented allocation scheme, i.e., if
you want to deallocate X, you also deallocate everything allocated
after X.

   The allocations using the words below are contiguous and grow the
region towards increasing addresses.  Other words that allocate
dictionary memory of any kind (i.e., defining words including
`:noname') end the contiguous region and start a new one.

   In ANS Forth only `create'd words are guaranteed to produce an
address that is the start of the following contiguous region.  In
particular, the cell allocated by `variable' is not guaranteed to be
contiguous with following `allot'ed memory.

   You can deallocate memory by using `allot' with a negative argument
(with some restrictions, see `allot'). For larger deallocations use
`marker'.

`here'       - addr         core       "here"
   Return the address of the next free location in data space.

`unused'       - u         core-ext       "unused"
   Return the amount of free space remaining (in address units) in the
region addressed by `here'.

`allot'       n -         core       "allot"
   Reserve n address units of data space without initialization. n is a
signed number, passing a negative n releases memory.  In ANS Forth you
can only deallocate memory from the current contiguous region in this
way.  In Gforth you can deallocate anything in this way but named words.
The system does not check this restriction.

`c,'       c -         core       "c-comma"
   Reserve data space for one char and store c in the space.

`f,'       f -         gforth       "f,"
   Reserve data space for one floating-point number and store f in the
space.

`,'       w -         core       "comma"
   Reserve data space for one cell and store w in the space.

`2,'       w1 w2 -         gforth       "2,"
   Reserve data space for two cells and store the double w1 w2 there,
w2 first (lower address).

   Memory accesses have to be aligned (*note Address arithmetic::). So
of course you should allocate memory in an aligned way, too. I.e.,
before allocating allocating a cell, `here' must be cell-aligned, etc.
The words below align `here' if it is not already.  Basically it is
only already aligned for a type, if the last allocation was a multiple
of the size of this type and if `here' was aligned for this type before.

   After freshly `create'ing a word, `here' is `align'ed in ANS Forth
(`maxalign'ed in Gforth).

`align'       -         core       "align"
   If the data-space pointer is not aligned, reserve enough space to
align it.

`falign'       -         float       "f-align"
   If the data-space pointer is not float-aligned, reserve enough space
to align it.

`sfalign'       -         float-ext       "s-f-align"
   If the data-space pointer is not single-float-aligned, reserve
enough space to align it.

`dfalign'       -         float-ext       "d-f-align"
   If the data-space pointer is not double-float-aligned, reserve
enough space to align it.

`maxalign'       -         gforth       "maxalign"
   Align data-space pointer for all alignment requirements.

`cfalign'       -         gforth       "cfalign"
   Align data-space pointer for code field requirements (i.e., such
that the corresponding body is maxaligned).


File: gforth.info,  Node: Heap Allocation,  Next: Memory Access,  Prev: Dictionary allocation,  Up: Memory

5.7.3 Heap allocation
---------------------

Heap allocation supports deallocation of allocated memory in any order.
Dictionary allocation is not affected by it (i.e., it does not end a
contiguous region). In Gforth, these words are implemented using the
standard C library calls malloc(), free() and resize().

   The memory region produced by one invocation of `allocate' or
`resize' is internally contiguous.  There is no contiguity between such
a region and any other region (including others allocated from the
heap).

`allocate'       u - a-addr wior        memory       "allocate"
   Allocate u address units of contiguous data space. The initial
contents of the data space is undefined. If the allocation is
successful, a-addr is the start address of the allocated region and wior
is 0. If the allocation fails, a-addr is undefined and wior is a
non-zero I/O result code.

`free'       a-addr - wior        memory       "free"
   Return the region of data space starting at a-addr to the system.
The region must originally have been obtained using `allocate' or
`resize'. If the operational is successful, wior is 0.  If the
operation fails, wior is a non-zero I/O result code.

`resize'       a-addr1 u - a-addr2 wior        memory       "resize"
   Change the size of the allocated area at a-addr1 to u address units,
possibly moving the contents to a different area. a-addr2 is the
address of the resulting area.  If the operation is successful, wior is
0.  If the operation fails, wior is a non-zero I/O result code. If
a-addr1 is 0, Gforth's (but not the Standard) `resize' `allocate's u
address units.


File: gforth.info,  Node: Memory Access,  Next: Address arithmetic,  Prev: Heap Allocation,  Up: Memory

5.7.4 Memory Access
-------------------

`@'       a-addr - w        core       "fetch"
w is the cell stored at a_addr.

`!'       w a-addr -        core       "store"
   Store w into the cell at a-addr.

`+!'       n a-addr -        core       "plus-store"
   Add n to the cell at a-addr.

`c@'       c-addr - c        core       "c-fetch"
   c is the char stored at c_addr.

`c!'       c c-addr -        core       "c-store"
   Store c into the char at c-addr.

`2@'       a-addr - w1 w2        core       "two-fetch"
   w2 is the content of the cell stored at a-addr, w1 is the content of
the next cell.

`2!'       w1 w2 a-addr -        core       "two-store"
   Store w2 into the cell at c-addr and w1 into the next cell.

`f@'       f-addr - r        float       "f-fetch"
   r is the float at address f-addr.

`f!'       r f-addr -        float       "f-store"
   Store r into the float at address f-addr.

`sf@'       sf-addr - r        float-ext       "s-f-fetch"
   Fetch the single-precision IEEE floating-point value r from the
address sf-addr.

`sf!'       r sf-addr -        float-ext       "s-f-store"
   Store r as single-precision IEEE floating-point value to the address
sf-addr.

`df@'       df-addr - r        float-ext       "d-f-fetch"
   Fetch the double-precision IEEE floating-point value r from the
address df-addr.

`df!'       r df-addr -        float-ext       "d-f-store"
   Store r as double-precision IEEE floating-point value to the address
df-addr.

`sw@'       c-addr - n        gforth       "s-w-fetch"
   n is the sign-extended 16-bit value stored at c_addr.

`uw@'       c-addr - u        gforth       "u-w-fetch"
   u is the zero-extended 16-bit value stored at c_addr.

`w!'       w c-addr -        gforth       "w-store"
   Store the bottom 16 bits of w at c_addr.

`sl@'       c-addr - n        gforth       "s-l-fetch"
   n is the sign-extended 32-bit value stored at c_addr.

`ul@'       c-addr - u        gforth       "u-l-fetch"
   u is the zero-extended 32-bit value stored at c_addr.

`l!'       w c-addr -        gforth       "l-store"
   Store the bottom 32 bits of w at c_addr.


File: gforth.info,  Node: Address arithmetic,  Next: Memory Blocks,  Prev: Memory Access,  Up: Memory

5.7.5 Address arithmetic
------------------------

Address arithmetic is the foundation on which you can build data
structures like arrays, records (*note Structures::) and objects (*note
Object-oriented Forth::).

   ANS Forth does not specify the sizes of the data types. Instead, it
offers a number of words for computing sizes and doing address
arithmetic. Address arithmetic is performed in terms of address units
(aus); on most systems the address unit is one byte. Note that a
character may have more than one au, so `chars' is no noop (on
platforms where it is a noop, it compiles to nothing).

   The basic address arithmetic words are `+' and `-'.  E.g., if you
have the address of a cell, perform `1 cells +', and you will have the
address of the next cell.

   In ANS Forth you can perform address arithmetic only within a
contiguous region, i.e., if you have an address into one region, you
can only add and subtract such that the result is still within the
region; you can only subtract or compare addresses from within the same
contiguous region.  Reasons: several contiguous regions can be arranged
in memory in any way; on segmented systems addresses may have unusual
representations, such that address arithmetic only works within a
region.  Gforth provides a few more guarantees (linear address space,
dictionary grows upwards), but in general I have found it easy to stay
within contiguous regions (exception: computing and comparing to the
address just beyond the end of an array).

   ANS Forth also defines words for aligning addresses for specific
types. Many computers require that accesses to specific data types must
only occur at specific addresses; e.g., that cells may only be accessed
at addresses divisible by 4. Even if a machine allows unaligned
accesses, it can usually perform aligned accesses faster.

   For the performance-conscious: alignment operations are usually only
necessary during the definition of a data structure, not during the
(more frequent) accesses to it.

   ANS Forth defines no words for character-aligning addresses. This is
not an oversight, but reflects the fact that addresses that are not
char-aligned have no use in the standard and therefore will not be
created.

   ANS Forth guarantees that addresses returned by `CREATE'd words are
cell-aligned; in addition, Gforth guarantees that these addresses are
aligned for all purposes.

   Note that the ANS Forth word `char' has nothing to do with address
arithmetic.

`chars'       n1 - n2         core       "chars"
   n2 is the number of address units of n1 chars.""

`char+'       c-addr1 - c-addr2        core       "char-plus"
   `1 chars +'.

`cells'       n1 - n2        core       "cells"
    n2 is the number of address units of n1 cells.

`cell+'       a-addr1 - a-addr2        core       "cell-plus"
   `1 cells +'

`cell'       - u         gforth       "cell"
   `Constant' - `1 cells'

`aligned'       c-addr - a-addr        core       "aligned"
    a-addr is the first aligned address greater than or equal to c-addr.

`floats'       n1 - n2        float       "floats"
   n2 is the number of address units of n1 floats.

`float+'       f-addr1 - f-addr2        float       "float-plus"
   `1 floats +'.

`float'       - u         gforth       "float"
   `Constant' - the number of address units corresponding to a
floating-point number.

`faligned'       c-addr - f-addr        float       "f-aligned"
    f-addr is the first float-aligned address greater than or equal to
c-addr.

`sfloats'       n1 - n2        float-ext       "s-floats"
   n2 is the number of address units of n1 single-precision IEEE
floating-point numbers.

`sfloat+'       sf-addr1 - sf-addr2         float-ext       "s-float-plus"
   `1 sfloats +'.

`sfaligned'       c-addr - sf-addr        float-ext       "s-f-aligned"
   sf-addr is the first single-float-aligned address greater than or
equal to c-addr.

`dfloats'       n1 - n2        float-ext       "d-floats"
   n2 is the number of address units of n1 double-precision IEEE
floating-point numbers.

`dfloat+'       df-addr1 - df-addr2         float-ext       "d-float-plus"
   `1 dfloats +'.

`dfaligned'       c-addr - df-addr        float-ext       "d-f-aligned"
   df-addr is the first double-float-aligned address greater than or
equal to c-addr.

`maxaligned'       addr1 - addr2         gforth       "maxaligned"
   addr2 is the first address after addr1 that satisfies all alignment
restrictions.  maxaligned"

`cfaligned'       addr1 - addr2         gforth       "cfaligned"
   addr2 is the first address after addr1 that is aligned for a code
field (i.e., such that the corresponding body is maxaligned).

`ADDRESS-UNIT-BITS'       - n         environment       "ADDRESS-UNIT-BITS"
   Size of one address unit, in bits.

`/w'       - u         gforth       "slash-w"
   address units for a 16-bit value

`/l'       - u         gforth       "slash-l"
   address units for a 32-bit value


File: gforth.info,  Node: Memory Blocks,  Prev: Address arithmetic,  Up: Memory

5.7.6 Memory Blocks
-------------------

Memory blocks often represent character strings; For ways of storing
character strings in memory see *note String Formats::.  For other
string-processing words see *note Displaying characters and strings::.

   A few of these words work on address unit blocks.  In that case, you
usually have to insert `CHARS' before the word when working on
character strings.  Most words work on character blocks, and expect a
char-aligned address.

   When copying characters between overlapping memory regions, use
`chars move' or choose carefully between `cmove' and `cmove>'.

`move'       c-from c-to ucount -        core       "move"
   Copy the contents of ucount aus at c-from to c-to. `move' works
correctly even if the two areas overlap.

`erase'       addr u -         core-ext       "erase"
   Clear all bits in u aus starting at addr.

`cmove'       c-from c-to u -        string       "c-move"
   Copy the contents of ucount characters from data space at c-from to
c-to. The copy proceeds `char'-by-`char' from low address to high
address; i.e., for overlapping areas it is safe if c-to=<c-from.

`cmove>'       c-from c-to u -        string       "c-move-up"
   Copy the contents of ucount characters from data space at c-from to
c-to. The copy proceeds `char'-by-`char' from high address to low
address; i.e., for overlapping areas it is safe if c-to>=c-from.

`fill'       c-addr u c -        core       "fill"
   Store c in u chars starting at c-addr.

`blank'       c-addr u -         string       "blank"
   Store the space character into u chars starting at c-addr.

`compare'       c-addr1 u1 c-addr2 u2 - n        string       "compare"
   Compare two strings lexicographically. If they are equal, n is 0; if
the first string is smaller, n is -1; if the first string is larger, n
is 1. Currently this is based on the machine's character comparison. In
the future, this may change to consider the current locale and its
collation order.

`str='       c-addr1 u1 c-addr2 u2 - f         gforth       "str="

`str<'       c-addr1 u1 c-addr2 u2 - f         gforth       "str<"

`string-prefix?'       c-addr1 u1 c-addr2 u2 - f         gforth       "string-prefix?"
   Is C-ADDR2 U2 a prefix of C-ADDR1 U1?

`search'       c-addr1 u1 c-addr2 u2 - c-addr3 u3 flag         string       "search"
   Search the string specified by c-addr1, u1 for the string specified
by c-addr2, u2. If flag is true: match was found at c-addr3 with u3
characters remaining. If flag is false: no match was found; c-addr3, u3
are equal to c-addr1, u1.

`-trailing'       c_addr u1 - c_addr u2         string       "dash-trailing"
   Adjust the string specified by c-addr, u1 to remove all trailing
spaces. u2 is the length of the modified string.

`/string'       c-addr1 u1 n - c-addr2 u2        string       "slash-string"
   Adjust the string specified by c-addr1, u1 to remove n characters
from the start of the string.

`bounds'       addr u - addr+u addr         gforth       "bounds"
   Given a memory block represented by starting address addr and length
u in aus, produce the end address addr+u and the start address in the
right order for `u+do' or `?do'.

`pad'       - c-addr         core-ext       "pad"
   C-ADDR is the address of a transient region that can be used as
temporary data storage. At least 84 characters of space is available.


File: gforth.info,  Node: Control Structures,  Next: Defining Words,  Prev: Memory,  Up: Words

5.8 Control Structures
======================

Control structures in Forth cannot be used interpretively, only in a
colon definition(1). We do not like this limitation, but have not seen
a satisfying way around it yet, although many schemes have been
proposed.

* Menu:

* Selection::                   IF ... ELSE ... ENDIF
* Simple Loops::                BEGIN ...
* Counted Loops::               DO
* Arbitrary control structures::
* Calls and returns::
* Exception Handling::

   ---------- Footnotes ----------

   (1) To be precise, they have no interpretation semantics (*note
Interpretation and Compilation Semantics::).


File: gforth.info,  Node: Selection,  Next: Simple Loops,  Prev: Control Structures,  Up: Control Structures

5.8.1 Selection
---------------

     flag
     IF
       code
     ENDIF
If flag is non-zero (as far as `IF' etc. are concerned, a cell with any
bit set represents truth) code is executed.

     flag
     IF
       code1
     ELSE
       code2
     ENDIF

   If FLAG is true, code1 is executed, otherwise code2 is executed.

   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, whereas `THEN' in Pascal and many
other programming languages has the meaning 3d.]

   Gforth also provides the words `?DUP-IF' and `?DUP-0=-IF', so you
can avoid using `?dup'. Using these alternatives is also more efficient
than using `?dup'. Definitions in ANS Forth for `ENDIF', `?DUP-IF' and
`?DUP-0=-IF' are provided in `compat/control.fs'.

     n
     CASE
       n1 OF code1 ENDOF
       n2 OF code2 ENDOF
       ...
       ( n ) default-code ( n )
     ENDCASE ( )

   Executes the first codei, where the ni is equal to n.  If no ni
matches, the optional default-code is executed. The optional 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.  The
value n is consumed by this construction (either by a OF that matches,
or by the ENDCASE, if no OF matches).

   Programming style note: To keep the code understandable, you should
ensure that you change the stack in the same way (wrt. number and types
of stack items consumed and pushed) on all paths through a selection
construct.


File: gforth.info,  Node: Simple Loops,  Next: Counted Loops,  Prev: Selection,  Up: Control Structures

5.8.2 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.

   Programming style note: To keep the code understandable, a complete
iteration of the loop should not change the number and types of the
items on the stacks.

     BEGIN
       code
     AGAIN

   This is an endless loop.


File: gforth.info,  Node: Counted Loops,  Next: Arbitrary control structures,  Prev: Simple Loops,  Up: Control Structures

5.8.3 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, or index, can be accessed
with `i'. For example, 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'.

`i'       R:n - R:n n        core       "i"

`j'       R:w R:w1 R:w2 - w R:w R:w1 R:w2        core       "j"

`k'       R:w R:w1 R:w2 R:w3 R:w4 - w R:w R:w1 R:w2 R:w3 R:w4        gforth       "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. In
particuler, if you put values on the return stack outside the loop, you
cannot read them inside the loop(1). 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; execution
     continues after the associated `LOOP' or `NEXT'. For example:

          10 0 ?DO  i DUP . 3 = IF LEAVE THEN LOOP
     prints `0 1 2 3'

   * `UNLOOP' prepares 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. For example:

          : demo 10 0 ?DO i DUP . 3 = IF UNLOOP EXIT THEN LOOP ." Done" ;
     prints `0 1 2 3'

   * If start is greater than limit, a `?DO' loop is entered (and
     `LOOP' iterates until they become equal by wrap-around
     arithmetic). This behaviour is usually not what you want.
     Therefore, Gforth offers `+DO' and `U+DO' (as replacements for
     `?DO'), which do not enter the loop if start is greater than
     limit; `+DO' is for signed loop parameters, `U+DO' for unsigned
     loop parameters.

   * `?DO' can be replaced by `DO'. `DO' always enters the loop,
     independent of the loop parameters. Do not use `DO', even if you
     know that the loop is entered in any case. Such knowledge tends to
     become invalid during maintenance of a program, and then the `DO'
     will make trouble.

   * `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 `n +LOOP' with negative n. One
     alternative is `u -LOOP', which reduces the index by u each
     iteration. The loop is terminated when the border between limit+1
     and limit is crossed. Gforth also provides `-DO' and `U-DO' for
     down-counting loops. E.g.:

          -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.


   Unfortunately, `+DO', `U+DO', `-DO', `U-DO' and `-LOOP' are not
defined in ANS Forth. However, an implementation for these words that
uses only standard words is provided in `compat/loops.fs'.

   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. This loop structure is not
defined in ANS Forth. In Gforth, this loop iterates n+1 times; `i'
produces values starting with n and ending with 0. Other Forth systems
may behave differently, even if they support `FOR' loops. To avoid
problems, don't use `FOR' loops.

   ---------- Footnotes ----------

   (1) well, not in a way that is portable.


File: gforth.info,  Node: Arbitrary control structures,  Next: Calls and returns,  Prev: Counted Loops,  Up: Control Structures

5.8.4 Arbitrary control structures
----------------------------------

ANS Forth permits and supports using control structures in a non-nested
way. Information about incomplete control structures is stored on the
control-flow stack. This stack may be implemented on the Forth data
stack, and this is what we have done in Gforth.

   An orig entry represents an unresolved forward branch, a dest entry
represents a backward branch target. A few words are the basis for
building any control structure possible (except control structures that
need storage, like calls, coroutines, and backtracking).

`IF'       compilation - orig ; run-time f -         core       "IF"

`AHEAD'       compilation - orig ; run-time -         tools-ext       "AHEAD"

`THEN'       compilation orig - ; run-time -         core       "THEN"

`BEGIN'       compilation - dest ; run-time -         core       "BEGIN"

`UNTIL'       compilation dest - ; run-time f -         core       "UNTIL"

`AGAIN'       compilation dest - ; run-time -         core-ext       "AGAIN"

`CS-PICK'       ... u - ... destu         tools-ext       "c-s-pick"

`CS-ROLL'       destu/origu .. dest0/orig0 u - .. dest0/orig0 destu/origu         tools-ext       "c-s-roll"

   The Standard words `CS-PICK' and `CS-ROLL' allow you to manipulate
the control-flow stack in a portable way. Without them, you would need
to know how many stack items are occupied by a control-flow entry (many
systems use one cell. In Gforth they currently take three, but this may
change in the future).

   Some standard control structure words are built from these words:

`ELSE'       compilation orig1 - orig2 ; run-time -         core       "ELSE"

`WHILE'       compilation dest - orig dest ; run-time f -         core       "WHILE"

`REPEAT'       compilation orig dest - ; run-time -         core       "REPEAT"

Gforth adds some more control-structure words:

`ENDIF'       compilation orig - ; run-time -         gforth       "ENDIF"

`?DUP-IF'       compilation - orig ; run-time n - n|         gforth       "question-dupe-if"
   This is the preferred alternative to the idiom "`?DUP IF'", since it
can be better handled by tools like stack checkers. Besides, it's
faster.

`?DUP-0=-IF'       compilation - orig ; run-time n - n|         gforth       "question-dupe-zero-equals-if"

Counted loop words constitute a separate group of words:

`?DO'       compilation - do-sys ; run-time w1 w2 - | loop-sys         core-ext       "question-do"

`+DO'       compilation - do-sys ; run-time n1 n2 - | loop-sys         gforth       "plus-do"

`U+DO'       compilation - do-sys ; run-time u1 u2 - | loop-sys         gforth       "u-plus-do"

`-DO'       compilation - do-sys ; run-time n1 n2 - | loop-sys         gforth       "minus-do"

`U-DO'       compilation - do-sys ; run-time u1 u2 - | loop-sys         gforth       "u-minus-do"

`DO'       compilation - do-sys ; run-time w1 w2 - loop-sys         core       "DO"

`FOR'       compilation - do-sys ; run-time u - loop-sys         gforth       "FOR"

`LOOP'       compilation do-sys - ; run-time loop-sys1 - | loop-sys2         core       "LOOP"

`+LOOP'       compilation do-sys - ; run-time loop-sys1 n - | loop-sys2         core       "plus-loop"

`-LOOP'       compilation do-sys - ; run-time loop-sys1 u - | loop-sys2         gforth       "minus-loop"

`NEXT'       compilation do-sys - ; run-time loop-sys1 - | loop-sys2         gforth       "NEXT"

`LEAVE'       compilation - ; run-time loop-sys -         core       "LEAVE"

`?LEAVE'       compilation - ; run-time f | f loop-sys -         gforth       "question-leave"

`unloop'       R:w1 R:w2 -        core       "unloop"

`DONE'       compilation orig - ; run-time -         gforth       "DONE"

   The standard does not allow using `CS-PICK' and `CS-ROLL' on do-sys.
Gforth allows it, but it's your job to ensure that for every `?DO' etc.
there is exactly one `UNLOOP' on any path through the definition
(`LOOP' etc. compile an `UNLOOP' on the fall-through path). Also, you
have to ensure that all `LEAVE's are resolved (by using one of the
loop-ending words or `DONE').

Another group of control structure words are:

`case'       compilation  - case-sys ; run-time  -         core-ext       "case"

`endcase'       compilation case-sys - ; run-time x -         core-ext       "end-case"

`of'       compilation  - of-sys ; run-time x1 x2 - |x1         core-ext       "of"

`endof'       compilation case-sys1 of-sys - case-sys2 ; run-time  -         core-ext       "end-of"

   case-sys and of-sys cannot be processed using `CS-PICK' and
`CS-ROLL'.

5.8.4.1 Programming Style
.........................

In order to ensure readability we recommend that you do not create
arbitrary control structures directly, but define new control structure
words for the control structure you want and use these words in your
program. For example, instead of writing:

     BEGIN
       ...
     IF [ 1 CS-ROLL ]
       ...
     AGAIN THEN

we recommend defining control structure words, e.g.,

     : WHILE ( DEST -- ORIG DEST )
      POSTPONE IF
      1 CS-ROLL ; immediate

     : REPEAT ( orig dest -- )
      POSTPONE AGAIN
      POSTPONE THEN ; immediate

and then using these to create the control structure:

     BEGIN
       ...
     WHILE
       ...
     REPEAT

   That's much easier to read, isn't it? Of course, `REPEAT' and
`WHILE' are predefined, so in this example it would not be necessary to
define them.


File: gforth.info,  Node: Calls and returns,  Next: Exception Handling,  Prev: Arbitrary control structures,  Up: Control Structures

5.8.5 Calls and returns
-----------------------

A definition can be called simply be writing the name of the definition
to be called. Normally a definition is invisible during its own
definition. If you want to write a directly recursive definition, you
can use `recursive' to make the current definition visible, or
`recurse' to call the current definition directly.

`recursive'       compilation - ; run-time -         gforth       "recursive"
   Make the current definition visible, enabling it to call itself
recursively.

`recurse'       compilation - ; run-time ?? - ??         core       "recurse"
   Call the current definition.

     Programming style note: I prefer using `recursive' to `recurse',
     because calling the definition by name is more descriptive (if the
     name is well-chosen) than the somewhat cryptic `recurse'.  E.g.,
     in a quicksort implementation, it is much better to read (and
     think) "now sort the partitions" than to read "now do a recursive
     call".

   For mutual recursion, use `Defer'red words, like this:

     Defer foo

     : bar ( ... -- ... )
      ... foo ... ;

     :noname ( ... -- ... )
      ... bar ... ;
     IS foo

   Deferred words are discussed in more detail in *note Deferred
Words::.

   The current definition returns control to the calling definition when
the end of the definition is reached or `EXIT' is encountered.

`EXIT'       compilation - ; run-time nest-sys -         core       "EXIT"
   Return to the calling definition; usually used as a way of forcing
an early return from a definition. Before `EXIT'ing you must clean up
the return stack and `UNLOOP' any outstanding `?DO'...`LOOP's.

`;s'       R:w -        gforth       "semis"
   The primitive compiled by `EXIT'.


File: gforth.info,  Node: Exception Handling,  Prev: Calls and returns,  Up: Control Structures

5.8.6 Exception Handling
------------------------

If a word detects an error condition that it cannot handle, it can
`throw' an exception.  In the simplest case, this will terminate your
program, and report an appropriate error.

`throw'       y1 .. ym nerror - y1 .. ym / z1 .. zn error         exception       "throw"
   If nerror is 0, drop it and continue.  Otherwise, transfer control
to the next dynamically enclosing exception handler, reset the stacks
accordingly, and push nerror.

   `Throw' consumes a cell-sized error number on the stack. There are
some predefined error numbers in ANS Forth (see `errors.fs').  In
Gforth (and most other systems) you can use the iors produced by various
words as error numbers (e.g., a typical use of `allocate' is `allocate
throw').  Gforth also provides the word `exception' to define your own
error numbers (with decent error reporting); an ANS Forth version of
this word (but without the error messages) is available in
`compat/except.fs'.  And finally, you can use your own error numbers
(anything outside the range -4095..0), but won't get nice error
messages, only numbers.  For example, try:

     -10 throw                    \ ANS defined
     -267 throw                   \ system defined
     s" my error" exception throw \ user defined
     7 throw                      \ arbitrary number

`exception'       addr u - n         gforth       "exception"
   N is a previously unused `throw' value in the range (-4095...-256).
Consecutive calls to `exception' return consecutive decreasing numbers.
Gforth uses the string ADDR U as an error message.

   A common idiom to `THROW' a specific error if a flag is true is this:

     `( flag ) 0<> errno and throw'

   Your program can provide exception handlers to catch exceptions.  An
exception handler can be used to correct the problem, or to clean up
some data structures and just throw the exception to the next exception
handler.  Note that `throw' jumps to the dynamically innermost
exception handler.  The system's exception handler is outermost, and
just prints an error and restarts command-line interpretation (or, in
batch mode (i.e., while processing the shell command line), leaves
Gforth).

   The ANS Forth way to catch exceptions is `catch':

`catch'       ... xt - ... n         exception       "catch"

`nothrow'       -         gforth       "nothrow"
   Use this (or the standard sequence `['] false catch drop') after a
`catch' or `endtry' that does not rethrow; this ensures that the next
`throw' will record a backtrace.

   The most common use of exception handlers is to clean up the state
when an error happens.  E.g.,

     base  >r hex \ actually the hex should be inside foo, or we h
     ['] foo catch ( nerror|0 )
     r> base !
     ( nerror|0 ) throw \ pass it on

   A use of `catch' for handling the error `myerror' might look like
this:

     ['] foo catch
     CASE
       myerror OF ... ( do something about it ) nothrow ENDOF
       dup throw \ default: pass other errors on, do nothing on non-errors
     ENDCASE

   Having to wrap the code into a separate word is often cumbersome,
therefore Gforth provides an alternative syntax:

     TRY
       code1
       IFERROR
         code2
       THEN
       code3
     ENDTRY

   This performs code1.  If code1 completes normally, execution
continues with code3.  If code1 or there is an exception before
`endtry', the stacks are reset to the state during `try', the throw
value is pushed on the data stack, and execution constinues at code2,
and finally falls through the code3.

`try'       compilation  - orig ; run-time  - R:sys1         gforth       "try"
   Start an exception-catching region.

`endtry'       compilation  - ; run-time  R:sys1 -         gforth       "endtry"
   End an exception-catching region.

`iferror'       compilation  orig1 - orig2 ; run-time  -         gforth       "iferror"
   Starts the exception handling code (executed if there is an
exception between `try' and `endtry').  This part has to be finished
with `then'.

   If you don't need code2, you can write `restore' instead of `iferror
then':

     TRY
       code1
     RESTORE
       code3
     ENDTRY

   The cleanup example from above in this syntax:

     base @ { oldbase }
     TRY
       hex foo \ now the hex is placed correctly
       0       \ value for throw
     RESTORE
       oldbase base !
     ENDTRY
     throw

   An additional advantage of this variant is that an exception between
`restore' and `endtry' (e.g., from the user pressing `Ctrl-C') restarts
the execution of the code after `restore', so the base will be restored
under all circumstances.

   However, you have to ensure that this code does not cause an
exception itself, otherwise the `iferror'/`restore' code will loop.
Moreover, you should also make sure that the stack contents needed by
the `iferror'/`restore' code exist everywhere between `try' and
`endtry'; in our example this is achived by putting the data in a local
before the `try' (you cannot use the return stack because the exception
frame (sys1) is in the way there).

   This kind of usage corresponds to Lisp's `unwind-protect'.

   If you do not want this exception-restarting behaviour, you achieve
this as follows:

     TRY
       code1
     ENDTRY-IFERROR
       code2
     THEN

   If there is an exception in code1, then code2 is executed, otherwise
execution continues behind the `then' (or in a possible `else' branch).
This corresponds to the construct

     TRY
       code1
     RECOVER
       code2
     ENDTRY

   in Gforth before version 0.7.  So you can directly replace
`recover'-using code; however, we recommend that you check if it would
not be better to use one of the other `try' variants while you are at
it.

   To ease the transition, Gforth provides two compatibility files:
`endtry-iferror.fs' provides the `try ... endtry-iferror ... then'
syntax (but not `iferror' or `restore') for old systems;
`recover-endtry.fs' provides the `try ... recover ... endtry' syntax on
new systems, so you can use that file as a stopgap to run old programs.
Both files work on any system (they just do nothing if the system
already has the syntax it implements), so you can unconditionally
`require' one of these files, even if you use a mix old and new systems.

`restore'       compilation  orig1 - ; run-time  -         gforth       "restore"
   Starts restoring code, that is executed if there is an exception,
and if there is no exception.

`endtry-iferror'       compilation  orig1 - orig2 ; run-time  R:sys1 -         gforth       "endtry-iferror"
   End an exception-catching region while starting exception-handling
code outside that region (executed if there is an exception between
`try' and `endtry-iferror').  This part has to be finished with `then'
(or `else'...`then').

   Here's the error handling example:

     TRY
       foo
     ENDTRY-IFERROR
       CASE
         myerror OF ... ( do something about it ) nothrow ENDOF
         throw \ pass other errors on
       ENDCASE
     THEN

   Programming style note: As usual, you should ensure that the stack
depth is statically known at the end: either after the `throw' for
passing on errors, or after the `ENDTRY' (or, if you use `catch', after
the end of the selection construct for handling the error).

   There are two alternatives to `throw': `Abort"' is conditional and
you can provide an error message.  `Abort' just produces an "Aborted"
error.

   The problem with these words is that exception handlers cannot
differentiate between different `abort"'s; they just look like `-2
throw' to them (the error message cannot be accessed by standard
programs).  Similar `abort' looks like `-1 throw' to exception handlers.

`ABORT"'       compilation 'ccc"' - ; run-time f -         core,exception-ext       "abort-quote"
   If any bit of f is non-zero, perform the function of `-2 throw',
displaying the string ccc if there is no exception frame on the
exception stack.

`abort'       ?? - ??         core,exception-ext       "abort"
   `-1 throw'.


File: gforth.info,  Node: Defining Words,  Next: Interpretation and Compilation Semantics,  Prev: Control Structures,  Up: Words

5.9 Defining Words
==================

Defining words are used to extend Forth by creating new entries in the
dictionary.

* Menu:

* CREATE::
* Variables::                   Variables and user variables
* Constants::
* Values::                      Initialised variables
* Colon Definitions::
* Anonymous Definitions::       Definitions without names
* Supplying names::             Passing definition names as strings
* User-defined Defining Words::
* Deferred Words::              Allow forward references
* Aliases::


File: gforth.info,  Node: CREATE,  Next: Variables,  Prev: Defining Words,  Up: Defining Words

5.9.1 `CREATE'
--------------

Defining words are used to create new entries in the dictionary. The
simplest defining word is `CREATE'. `CREATE' is used like this:

     CREATE new-word1

   `CREATE' is a parsing word, i.e., it takes an argument from the
input stream (`new-word1' in our example).  It generates a dictionary
entry for `new-word1'. When `new-word1' is executed, all that it does
is leave an address on the stack. The address represents the value of
the data space pointer (`HERE') at the time that `new-word1' was
defined. Therefore, `CREATE' is a way of associating a name with the
address of a region of memory.

`Create'       "name" -         core       "Create"

   Note that in ANS Forth guarantees only for `create' that its body is
in dictionary data space (i.e., where `here', `allot' etc. work, *note
Dictionary allocation::).  Also, in ANS Forth only `create'd words can
be modified with `does>' (*note User-defined Defining Words::).  And in
ANS Forth `>body' can only be applied to `create'd words.

   By extending this example to reserve some memory in data space, we
end up with something like a variable. Here are two different ways to do
it:

     CREATE new-word2 1 cells allot  \ reserve 1 cell - initial value undefined
     CREATE new-word3 4 ,            \ reserve 1 cell and initialise it (to 4)

   The variable can be examined and modified using `@' ("fetch") and
`!' ("store") like this:

     new-word2 @ .      \ get address, fetch from it and display
     1234 new-word2 !   \ new value, get address, store to it

   A similar mechanism can be used to create arrays. For example, an
80-character text input buffer:

     CREATE text-buf 80 chars allot

     text-buf 0 chars + c@ \ the 1st character (offset 0)
     text-buf 3 chars + c@ \ the 4th character (offset 3)

   You can build arbitrarily complex data structures by allocating
appropriate areas of memory. For further discussions of this, and to
learn about some Gforth tools that make it easier, *Note Structures::.


File: gforth.info,  Node: Variables,  Next: Constants,  Prev: CREATE,  Up: Defining Words

5.9.2 Variables
---------------

The previous section showed how a sequence of commands could be used to
generate a variable.  As a final refinement, the whole code sequence can
be wrapped up in a defining word (pre-empting the subject of the next
section), making it easier to create new variables:

     : myvariableX ( "name" -- a-addr ) CREATE 1 cells allot ;
     : myvariable0 ( "name" -- a-addr ) CREATE 0 , ;

     myvariableX foo \ variable foo starts off with an unknown value
     myvariable0 joe \ whilst joe is initialised to 0

     45 3 * foo !   \ set foo to 135
     1234 joe !     \ set joe to 1234
     3 joe +!       \ increment joe by 3.. to 1237

   Not surprisingly, there is no need to define `myvariable', since
Forth already has a definition `Variable'. ANS Forth does not guarantee
that a `Variable' is initialised when it is created (i.e., it may
behave like `myvariableX'). In contrast, Gforth's `Variable'
initialises the variable to 0 (i.e., it behaves exactly like
`myvariable0'). Forth also provides `2Variable' and `fvariable' for
double and floating-point variables, respectively - they are
initialised to 0. and 0e in Gforth. If you use a `Variable' to store a
boolean, you can use `on' and `off' to toggle its state.

`Variable'       "name" -         core       "Variable"

`2Variable'       "name" -         double       "two-variable"

`fvariable'       "name" -         float       "f-variable"

   The defining word `User' behaves in the same way as `Variable'.  The
difference is that it reserves space in user (data) space rather than
normal data space. In a Forth system that has a multi-tasker, each task
has its own set of user variables.

`User'       "name" -         gforth       "User"


File: gforth.info,  Node: Constants,  Next: Values,  Prev: Variables,  Up: Defining Words

5.9.3 Constants
---------------

`Constant' allows you to declare a fixed value and refer to it by name.
For example:

     12 Constant INCHES-PER-FOOT
     3E+08 fconstant SPEED-O-LIGHT

   A `Variable' can be both read and written, so its run-time behaviour
is to supply an address through which its current value can be
manipulated. In contrast, the value of a `Constant' cannot be changed
once it has been declared(1) so it's not necessary to supply the
address - it is more efficient to return the value of the constant
directly. That's exactly what happens; the run-time effect of a
constant is to put its value on the top of the stack (You can find one
way of implementing `Constant' in *note User-defined Defining Words::).

   Forth also provides `2Constant' and `fconstant' for defining double
and floating-point constants, respectively.

`Constant'       w "name" -         core       "Constant"
   Define a constant name with value w.

   name execution: - w

`2Constant'       w1 w2 "name" -         double       "two-constant"

`fconstant'       r "name" -         float       "f-constant"

   Constants in Forth behave differently from their equivalents in other
programming languages. In other languages, a constant (such as an EQU in
assembler or a #define in C) only exists at compile-time; in the
executable program the constant has been translated into an absolute
number and, unless you are using a symbolic debugger, it's impossible to
know what abstract thing that number represents. In Forth a constant has
an entry in the header space and remains there after the code that uses
it has been defined. In fact, it must remain in the dictionary since it
has run-time duties to perform. For example:

     12 Constant INCHES-PER-FOOT
     : FEET-TO-INCHES ( n1 -- n2 ) INCHES-PER-FOOT * ;

   When `FEET-TO-INCHES' is executed, it will in turn execute the xt
associated with the constant `INCHES-PER-FOOT'. If you use `see' to
decompile the definition of `FEET-TO-INCHES', you can see that it makes
a call to `INCHES-PER-FOOT'. Some Forth compilers attempt to optimise
constants by in-lining them where they are used. You can force Gforth
to in-line a constant like this:

     : FEET-TO-INCHES ( n1 -- n2 ) [ INCHES-PER-FOOT ] LITERAL * ;

   If you use `see' to decompile this version of `FEET-TO-INCHES', you
can see that `INCHES-PER-FOOT' is no longer present. To understand how
this works, read *note Interpret/Compile states::, and *note Literals::.

   In-lining constants in this way might improve execution time
fractionally, and can ensure that a constant is now only referenced at
compile-time. However, the definition of the constant still remains in
the dictionary. Some Forth compilers provide a mechanism for controlling
a second dictionary for holding transient words such that this second
dictionary can be deleted later in order to recover memory space.
However, there is no standard way of doing this.

   ---------- Footnotes ----------

   (1) Well, often it can be - but not in a Standard, portable way.
It's safer to use a `Value' (read on).


File: gforth.info,  Node: Values,  Next: Colon Definitions,  Prev: Constants,  Up: Defining Words

5.9.4 Values
------------

A `Value' behaves like a `Constant', but it can be changed.  `TO' is a
parsing word that changes a `Values'.  In Gforth (not in ANS Forth) you
can access (and change) a `value' also with `>body'.

   Here are some examples:

     12 Value APPLES     \ Define APPLES with an initial value of 12
     34 TO APPLES        \ Change the value of APPLES. TO is a parsing word
     1 ' APPLES >body +! \ Increment APPLES.  Non-standard usage.
     APPLES              \ puts 35 on the top of the stack.

`Value'       w "name" -         core-ext       "Value"

`TO'       c|w|d|r "name" -         core-ext,local       "TO"


File: gforth.info,  Node: Colon Definitions,  Next: Anonymous Definitions,  Prev: Values,  Up: Defining Words

5.9.5 Colon Definitions
-----------------------

     : name ( ... -- ... )
         word1 word2 word3 ;

Creates a word called `name' that, upon execution, executes `word1
word2 word3'. `name' is a "(colon) definition".

   The explanation above is somewhat superficial. For simple examples of
colon definitions see *note Your first definition::.  For an in-depth
discussion of some of the issues involved, *Note Interpretation and
Compilation Semantics::.

`:'       "name" - colon-sys         core       "colon"

`;'       compilation colon-sys - ; run-time nest-sys         core       "semicolon"


File: gforth.info,  Node: Anonymous Definitions,  Next: Supplying names,  Prev: Colon Definitions,  Up: Defining Words

5.9.6 Anonymous Definitions
---------------------------

Sometimes you want to define an "anonymous word"; a word without a
name. You can do this with:

`:noname'       - xt colon-sys         core-ext       "colon-no-name"

   This leaves the execution token for the word on the stack after the
closing `;'. Here's an example in which a deferred word is initialised
with an `xt' from an anonymous colon definition:

     Defer deferred
     :noname ( ... -- ... )
       ... ;
     IS deferred

Gforth provides an alternative way of doing this, using two separate
words:

`noname'       -         gforth       "noname"
   The next defined word will be anonymous. The defining word will
leave the input stream alone. The xt of the defined word will be given
by `latestxt'.

`latestxt'       - xt         gforth       "latestxt"
   xt is the execution token of the last word defined.

The previous example can be rewritten using `noname' and `latestxt':

     Defer deferred
     noname : ( ... -- ... )
       ... ;
     latestxt IS deferred

`noname' works with any defining word, not just `:'.

   `latestxt' also works when the last word was not defined as
`noname'.  It does not work for combined words, though.  It also has
the useful property that is is valid as soon as the header for a
definition has been built. Thus:

     latestxt . : foo [ latestxt . ] ; ' foo .

prints 3 numbers; the last two are the same.


File: gforth.info,  Node: Supplying names,  Next: User-defined Defining Words,  Prev: Anonymous Definitions,  Up: Defining Words

5.9.7 Supplying the name of a defined word
------------------------------------------

By default, a defining word takes the name for the defined word from the
input stream. Sometimes you want to supply the name from a string. You
can do this with:

`nextname'       c-addr u -         gforth       "nextname"
   The next defined word will have the name C-ADDR U; the defining word
will leave the input stream alone.

   For example:

     s" foo" nextname create

is equivalent to:

     create foo

`nextname' works with any defining word.


File: gforth.info,  Node: User-defined Defining Words,  Next: Deferred Words,  Prev: Supplying names,  Up: Defining Words

5.9.8 User-defined Defining Words
---------------------------------

You can create a new defining word by wrapping defining-time code around
an existing defining word and putting the sequence in a colon
definition.

   For example, suppose that you have a word `stats' that gathers
statistics about colon definitions given the xt of the definition, and
you want every colon definition in your application to make a call to
`stats'. You can define and use a new version of `:' like this:

     : stats ( xt -- ) DUP ." (Gathering statistics for " . ." )"
       ... ;  \ other code

     : my: : latestxt postpone literal ['] stats compile, ;

     my: foo + - ;

   When `foo' is defined using `my:' these steps occur:

   * `my:' is executed.

   * The `:' within the definition (the one between `my:' and
     `latestxt') is executed, and does just what it always does; it
     parses the input stream for a name, builds a dictionary header for
     the name `foo' and switches `state' from interpret to compile.

   * The word `latestxt' is executed. It puts the xt for the word that
     is being defined - `foo' - onto the stack.

   * The code that was produced by `postpone literal' is executed; this
     causes the value on the stack to be compiled as a literal in the
     code area of `foo'.

   * The code `['] stats' compiles a literal into the definition of
     `my:'. When `compile,' is executed, that literal - the execution
     token for `stats' - is layed down in the code area of `foo' ,
     following the literal(1).

   * At this point, the execution of `my:' is complete, and control
     returns to the text interpreter. The text interpreter is in compile
     state, so subsequent text `+ -' is compiled into the definition of
     `foo' and the `;' terminates the definition as always.

   You can use `see' to decompile a word that was defined using `my:'
and see how it is different from a normal `:' definition. For example:

     : bar + - ;  \ like foo but using : rather than my:
     see bar
     : bar
       + - ;
     see foo
     : foo
       107645672 stats + - ;

     \ use ' foo . to show that 107645672 is the xt for foo

   You can use techniques like this to make new defining words in terms
of any existing defining word.

   If you want the words defined with your defining words to behave
differently from words defined with standard defining words, you can
write your defining word like this:

     : def-word ( "name" -- )
         CREATE code1
     DOES> ( ... -- ... )
         code2 ;

     def-word name

   This fragment defines a "defining word" `def-word' and then executes
it.  When `def-word' executes, it `CREATE's a new word, `name', and
executes the code code1. The code code2 is not executed at this time.
The word `name' is sometimes called a "child" of `def-word'.

   When you execute `name', the address of the body of `name' is put on
the data stack and code2 is executed (the address of the body of `name'
is the address `HERE' returns immediately after the `CREATE', i.e., the
address a `create'd word returns by default).

   You can use `def-word' to define a set of child words that behave
similarly; they all have a common run-time behaviour determined by
code2. Typically, the code1 sequence builds a data area in the body of
the child word. The structure of the data is common to all children of
`def-word', but the data values are specific - and private - to each
child word. When a child word is executed, the address of its private
data area is passed as a parameter on TOS to be used and manipulated(2)
by code2.

   The two fragments of code that make up the defining words act (are
executed) at two completely separate times:

   * At define time, the defining word executes code1 to generate a
     child word

   * At child execution time, when a child word is invoked, code2 is
     executed, using parameters (data) that are private and specific to
     the child word.

   Another way of understanding the behaviour of `def-word' and `name'
is to say that, if you make the following definitions:
     : def-word1 ( "name" -- )
         CREATE code1 ;

     : action1 ( ... -- ... )
         code2 ;

     def-word1 name1

Then using `name1 action1' is equivalent to using `name'.

   The classic example is that you can define `CONSTANT' in this way:

     : CONSTANT ( w "name" -- )
         CREATE ,
     DOES> ( -- w )
         @ ;

   When you create a constant with `5 CONSTANT five', a set of
define-time actions take place; first a new word `five' is created,
then the value 5 is laid down in the body of `five' with `,'. When
`five' is executed, the address of the body is put on the stack, and
`@' retrieves the value 5. The word `five' has no code of its own; it
simply contains a data field and a pointer to the code that follows
`DOES>' in its defining word. That makes words created in this way very
compact.

   The final example in this section is intended to remind you that
space reserved in `CREATE'd words is data space and therefore can be
both read and written by a Standard program(3):

     : foo ( "name" -- )
         CREATE -1 ,
     DOES> ( -- )
         @ . ;

     foo first-word
     foo second-word

     123 ' first-word >BODY !

   If `first-word' had been a `CREATE'd word, we could simply have
executed it to get the address of its data field. However, since it was
defined to have `DOES>' actions, its execution semantics are to perform
those `DOES>' actions. To get the address of its data field it's
necessary to use `'' to get its xt, then `>BODY' to translate the xt
into the address of the data field.  When you execute `first-word', it
will display `123'. When you execute `second-word' it will display `-1'.

   In the examples above the stack comment after the `DOES>' specifies
the stack effect of the defined words, not the stack effect of the
following code (the following code expects the address of the body on
the top of stack, which is not reflected in the stack comment). This is
the convention that I use and recommend (it clashes a bit with using
locals declarations for stack effect specification, though).

* Menu:

* CREATE..DOES> applications::
* CREATE..DOES> details::
* Advanced does> usage example::
* Const-does>::

   ---------- Footnotes ----------

   (1) Strictly speaking, the mechanism that `compile,' uses to convert
an xt into something in the code area is implementation-dependent. A
threaded implementation might spit out the execution token directly
whilst another implementation might spit out a native code sequence.

   (2) It is legitimate both to read and write to this data area.

   (3) Exercise: use this example as a starting point for your own
implementation of `Value' and `TO' - if you get stuck, investigate the
behaviour of `'' and `[']'.


File: gforth.info,  Node: CREATE..DOES> applications,  Next: CREATE..DOES> details,  Prev: User-defined Defining Words,  Up: User-defined Defining Words

5.9.8.1 Applications of `CREATE..DOES>'
.......................................

You may wonder how to use this feature. Here are some usage patterns:

   When you see a sequence of code occurring several times, and you can
identify a meaning, you will factor it out as a colon definition. When
you see similar colon definitions, you can factor them using
`CREATE..DOES>'. E.g., an assembler usually defines several words that
look very similar:
     : ori, ( reg-target reg-source n -- )
         0 asm-reg-reg-imm ;
     : andi, ( reg-target reg-source n -- )
         1 asm-reg-reg-imm ;

This could be factored with:
     : reg-reg-imm ( op-code -- )
         CREATE ,
     DOES> ( reg-target reg-source n -- )
         @ asm-reg-reg-imm ;

     0 reg-reg-imm ori,
     1 reg-reg-imm andi,

   Another view of `CREATE..DOES>' is to consider it as a crude way to
supply a part of the parameters for a word (known as "currying" in the
functional language community). E.g., `+' needs two parameters.
Creating versions of `+' with one parameter fixed can be done like this:

     : curry+ ( n1 "name" -- )
         CREATE ,
     DOES> ( n2 -- n1+n2 )
         @ + ;

      3 curry+ 3+
     -2 curry+ 2-


File: gforth.info,  Node: CREATE..DOES> details,  Next: Advanced does> usage example,  Prev: CREATE..DOES> applications,  Up: User-defined Defining Words

5.9.8.2 The gory details of `CREATE..DOES>'
...........................................

`DOES>'       compilation colon-sys1 - colon-sys2 ; run-time nest-sys -         core       "does"

   This means that you need not use `CREATE' and `DOES>' in the same
definition; you can put the `DOES>'-part in a separate definition. This
allows us to, e.g., select among different `DOES>'-parts:
     : does1
     DOES> ( ... -- ... )
         ... ;

     : does2
     DOES> ( ... -- ... )
         ... ;

     : def-word ( ... -- ... )
         create ...
         IF
            does1
         ELSE
            does2
         ENDIF ;

   In this example, the selection of whether to use `does1' or `does2'
is made at definition-time; at the time that the child word is
`CREATE'd.

   In a standard program you can apply a `DOES>'-part only if the last
word was defined with `CREATE'. In Gforth, the `DOES>'-part will
override the behaviour of the last word defined in any case. In a
standard program, you can use `DOES>' only in a colon definition. In
Gforth, you can also use it in interpretation state, in a kind of
one-shot mode; for example:
     CREATE name ( ... -- ... )
       initialization
     DOES>
       code ;

is equivalent to the standard:
     :noname
     DOES>
         code ;
     CREATE name EXECUTE ( ... -- ... )
         initialization

`>body'       xt - a_addr         core       "to-body"
   Get the address of the body of the word represented by xt (the
address of the word's data field).


File: gforth.info,  Node: Advanced does> usage example,  Next: Const-does>,  Prev: CREATE..DOES> details,  Up: User-defined Defining Words

5.9.8.3 Advanced does> usage example
....................................

The MIPS disassembler (`arch/mips/disasm.fs') contains many words for
disassembling instructions, that follow a very repetetive scheme:

     :noname DISASM-OPERANDS s" INST-NAME" type ;
     ENTRY-NUM cells TABLE + !

   Of course, this inspires the idea to factor out the commonalities to
allow a definition like

     DISASM-OPERANDS ENTRY-NUM TABLE define-inst INST-NAME

   The parameters DISASM-OPERANDS and TABLE are usually correlated.
Moreover, before I wrote the disassembler, there already existed code
that defines instructions like this:

     ENTRY-NUM INST-FORMAT INST-NAME

   This code comes from the assembler and resides in
`arch/mips/insts.fs'.

   So I had to define the INST-FORMAT words that performed the scheme
above when executed.  At first I chose to use run-time code-generation:

     : INST-FORMAT ( entry-num "name" -- ; compiled code: addr w -- )
       :noname Postpone DISASM-OPERANDS
       name Postpone sliteral Postpone type Postpone ;
       swap cells TABLE + ! ;

   Note that this supplies the other two parameters of the scheme above.

   An alternative would have been to write this using `create'/`does>':

     : INST-FORMAT ( entry-num "name" -- )
       here name string, ( entry-num c-addr ) \ parse and save "name"
       noname create , ( entry-num )
       latestxt swap cells TABLE + !
     does> ( addr w -- )
       \ disassemble instruction w at addr
       @ >r
       DISASM-OPERANDS
       r> count type ;

   Somehow the first solution is simpler, mainly because it's simpler to
shift a string from definition-time to use-time with `sliteral' than
with `string,' and friends.

   I wrote a lot of words following this scheme and soon thought about
factoring out the commonalities among them.  Note that this uses a
two-level defining word, i.e., a word that defines ordinary defining
words.

   This time a solution involving `postpone' and friends seemed more
difficult (try it as an exercise), so I decided to use a
`create'/`does>' word; since I was already at it, I also used
`create'/`does>' for the lower level (try using `postpone' etc. as an
exercise), resulting in the following definition:

     : define-format ( disasm-xt table-xt -- )
         \ define an instruction format that uses disasm-xt for
         \ disassembling and enters the defined instructions into table
         \ table-xt
         create 2,
     does> ( u "inst" -- )
         \ defines an anonymous word for disassembling instruction inst,
         \ and enters it as u-th entry into table-xt
         2@ swap here name string, ( u table-xt disasm-xt c-addr ) \ remember string
         noname create 2,      \ define anonymous word
         execute latestxt swap ! \ enter xt of defined word into table-xt
     does> ( addr w -- )
         \ disassemble instruction w at addr
         2@ >r ( addr w disasm-xt R: c-addr )
         execute ( R: c-addr ) \ disassemble operands
         r> count type ; \ print name

   Note that the tables here (in contrast to above) do the `cells +' by
themselves (that's why you have to pass an xt).  This word is used in
the following way:

     ' DISASM-OPERANDS ' TABLE define-format INST-FORMAT

   As shown above, the defined instruction format is then used like
this:

     ENTRY-NUM INST-FORMAT INST-NAME

   In terms of currying, this kind of two-level defining word provides
the parameters in three stages: first DISASM-OPERANDS and TABLE, then
ENTRY-NUM and INST-NAME, finally `addr w', i.e., the instruction to be
disassembled.

   Of course this did not quite fit all the instruction format names
used in `insts.fs', so I had to define a few wrappers that conditioned
the parameters into the right form.

   If you have trouble following this section, don't worry.  First,
this is involved and takes time (and probably some playing around) to
understand; second, this is the first two-level `create'/`does>' word I
have written in seventeen years of Forth; and if I did not have
`insts.fs' to start with, I may well have elected to use just a
one-level defining word (with some repeating of parameters when using
the defining word). So it is not necessary to understand this, but it
may improve your understanding of Forth.


File: gforth.info,  Node: Const-does>,  Prev: Advanced does> usage example,  Up: User-defined Defining Words

5.9.8.4 `Const-does>'
.....................

A frequent use of `create'...`does>' is for transferring some values
from definition-time to run-time.  Gforth supports this use with

`const-does>'       run-time: w*uw r*ur uw ur "name" -         gforth       "const-does>"
   Defines NAME and returns.

   NAME execution: pushes W*UW R*UR, then performs the code following
the `const-does>'.

   A typical use of this word is:

     : curry+ ( n1 "name" -- )
     1 0 CONST-DOES> ( n2 -- n1+n2 )
         + ;

     3 curry+ 3+

   Here the `1 0' means that 1 cell and 0 floats are transferred from
definition to run-time.

   The advantages of using `const-does>' are:

   * You don't have to deal with storing and retrieving the values,
     i.e., your program becomes more writable and readable.

   * When using `does>', you have to introduce a `@' that cannot be
     optimized away (because you could change the data using
     `>body'...`!'); `const-does>' avoids this problem.


   An ANS Forth implementation of `const-does>' is available in
`compat/const-does.fs'.


File: gforth.info,  Node: Deferred Words,  Next: Aliases,  Prev: User-defined Defining Words,  Up: Defining Words

5.9.9 Deferred Words
--------------------

The defining word `Defer' allows you to define a word by name without
defining its behaviour; the definition of its behaviour is deferred.
Here are two situation where this can be useful:

   * Where you want to allow the behaviour of a word to be altered
     later, and for all precompiled references to the word to change
     when its behaviour is changed.

   * For mutual recursion; *Note Calls and returns::.

   In the following example, `foo' always invokes the version of
`greet' that prints "`Good morning'" whilst `bar' always invokes the
version that prints "`Hello'". There is no way of getting `foo' to use
the later version without re-ordering the source code and recompiling
it.

     : greet ." Good morning" ;
     : foo ... greet ... ;
     : greet ." Hello" ;
     : bar ... greet ... ;

   This problem can be solved by defining `greet' as a `Defer'red word.
The behaviour of a `Defer'red word can be defined and redefined at any
time by using `IS' to associate the xt of a previously-defined word
with it. The previous example becomes:

     Defer greet ( -- )
     : foo ... greet ... ;
     : bar ... greet ... ;
     : greet1 ( -- ) ." Good morning" ;
     : greet2 ( -- ) ." Hello" ;
     ' greet2 IS greet  \ make greet behave like greet2

   Programming style note: You should write a stack comment for every
deferred word, and put only XTs into deferred words that conform to
this stack effect.  Otherwise it's too difficult to use the deferred
word.

   A deferred word can be used to improve the statistics-gathering
example from *note User-defined Defining Words::; rather than edit the
application's source code to change every `:' to a `my:', do this:

     : real: : ;     \ retain access to the original
     defer :         \ redefine as a deferred word
     ' my: IS :      \ use special version of :
     \
     \ load application here
     \
     ' real: IS :    \ go back to the original

   One thing to note is that `IS' has special compilation semantics,
such that it parses the name at compile time (like `TO'):

     : set-greet ( xt -- )
       IS greet ;

     ' greet1 set-greet

   In situations where `IS' does not fit, use `defer!' instead.

   A deferred word can only inherit execution semantics from the xt
(because that is all that an xt can represent - for more discussion of
this *note Tokens for Words::); by default it will have default
interpretation and compilation semantics deriving from this execution
semantics.  However, you can change the interpretation and compilation
semantics of the deferred word in the usual ways:

     : bar .... ; immediate
     Defer fred immediate
     Defer jim

     ' bar IS jim  \ jim has default semantics
     ' bar IS fred \ fred is immediate

`Defer'       "name" -         gforth       "Defer"
   Define a deferred word name; its execution semantics can be set with
`defer!' or `is' (and they have to, before first executing name.

`defer!'       xt xt-deferred -         gforth       "defer-store"
   Changes the `defer'red word XT-DEFERRED to execute XT.

`IS'       compilation/interpretation "name-deferred" - ; run-time xt -         gforth       "IS"
   Changes the `defer'red word NAME to execute XT.  Its compilation
semantics parses at compile time.

`defer@'       xt-deferred - xt         gforth       "defer-fetch"
   xt represents the word currently associated with the deferred word
xt-deferred.

`action-of'       interpretation "name" - xt; compilation "name" - ; run-time - xt         gforth       "action-of"
   Xt is the XT that is currently assigned to name.

`defers'       compilation "name" - ; run-time ... - ...         gforth       "defers"
   Compiles the present contents of the deferred word name into the
current definition.  I.e., this produces static binding as if name was
not deferred.

   Definitions of these words (except `defers') in ANS Forth are
provided in `compat/defer.fs'.


File: gforth.info,  Node: Aliases,  Prev: Deferred Words,  Up: Defining Words

5.9.10 Aliases
--------------

The defining word `Alias' allows you to define a word by name that has
the same behaviour as some other word. Here are two situation where
this can be useful:

   * When you want access to a word's definition from a different word
     list (for an example of this, see the definition of the `Root'
     word list in the Gforth source).

   * When you want to create a synonym; a definition that can be known
     by either of two names (for example, `THEN' and `ENDIF' are
     aliases).

   Like deferred words, an alias has default compilation and
interpretation semantics at the beginning (not the modifications of the
other word), but you can change them in the usual ways (`immediate',
`compile-only'). For example:

     : foo ... ; immediate

     ' foo Alias bar \ bar is not an immediate word
     ' foo Alias fooby immediate \ fooby is an immediate word

   Words that are aliases have the same xt, different headers in the
dictionary, and consequently different name tokens (*note Tokens for
Words::) and possibly different immediate flags.  An alias can only have
default or immediate compilation semantics; you can define aliases for
combined words with `interpret/compile:' - see *note Combined words::.

`Alias'       xt "name" -         gforth       "Alias"


File: gforth.info,  Node: Interpretation and Compilation Semantics,  Next: Tokens for Words,  Prev: Defining Words,  Up: Words

5.10 Interpretation and Compilation Semantics
=============================================

The "interpretation semantics" of a (named) word are what the text
interpreter does when it encounters the word in interpret state. It also
appears in some other contexts, e.g., the execution token returned by
`' word' identifies the interpretation semantics of word (in other
words, `' word execute' is equivalent to interpret-state text
interpretation of `word').

   The "compilation semantics" of a (named) word are what the text
interpreter does when it encounters the word in compile state. It also
appears in other contexts, e.g, `POSTPONE word' compiles(1) the
compilation semantics of word.

   The standard also talks about "execution semantics". They are used
only for defining the interpretation and compilation semantics of many
words. By default, the interpretation semantics of a word are to
`execute' its execution semantics, and the compilation semantics of a
word are to `compile,' its execution semantics.(2)

   Unnamed words (*note Anonymous Definitions::) cannot be encountered
by the text interpreter, ticked, or `postpone'd, so they have no
interpretation or compilation semantics.  Their behaviour is represented
by their XT (*note Tokens for Words::), and we call it execution
semantics, too.

   You can change the semantics of the most-recently defined word:

`immediate'       -         core       "immediate"
   Make the compilation semantics of a word be to `execute' the
execution semantics.

`compile-only'       -         gforth       "compile-only"
   Remove the interpretation semantics of a word.

`restrict'       -         gforth       "restrict"
   A synonym for `compile-only'

   By convention, words with non-default compilation semantics (e.g.,
immediate words) often have names surrounded with brackets (e.g.,
`[']', *note Execution token::).

   Note that ticking (`'') a compile-only word gives an error
("Interpreting a compile-only word").

* Menu:

* Combined words::

   ---------- Footnotes ----------

   (1) In standard terminology, "appends to the current definition".

   (2) In standard terminology: The default interpretation semantics
are its execution semantics; the default compilation semantics are to
append its execution semantics to the execution semantics of the current
definition.


File: gforth.info,  Node: Combined words,  Prev: Interpretation and Compilation Semantics,  Up: Interpretation and Compilation Semantics

5.10.1 Combined Words
---------------------

Gforth allows you to define "combined words" - words that have an
arbitrary combination of interpretation and compilation semantics.

`interpret/compile:'       interp-xt comp-xt "name" -         gforth       "interpret/compile:"

   This feature was introduced for implementing `TO' and `S"'. I
recommend that you do not define such words, as cute as they may be:
they make it hard to get at both parts of the word in some contexts.
E.g., assume you want to get an execution token for the compilation
part. Instead, define two words, one that embodies the interpretation
part, and one that embodies the compilation part.  Once you have done
that, you can define a combined word with `interpret/compile:' for the
convenience of your users.

   You might try to use this feature to provide an optimizing
implementation of the default compilation semantics of a word. For
example, by defining:
     :noname
        foo bar ;
     :noname
        POSTPONE foo POSTPONE bar ;
     interpret/compile: opti-foobar

as an optimizing version of:

     : foobar
         foo bar ;

   Unfortunately, this does not work correctly with `[compile]',
because `[compile]' assumes that the compilation semantics of all
`interpret/compile:' words are non-default. I.e., `[compile]
opti-foobar' would compile compilation semantics, whereas `[compile]
foobar' would compile interpretation semantics.

   Some people try to use "state-smart" words to emulate the feature
provided by `interpret/compile:' (words are state-smart if they check
`STATE' during execution). E.g., they would try to code `foobar' like
this:

     : foobar
       STATE @
       IF ( compilation state )
         POSTPONE foo POSTPONE bar
       ELSE
         foo bar
       ENDIF ; immediate

   Although this works if `foobar' is only processed by the text
interpreter, it does not work in other contexts (like `'' or
`POSTPONE'). E.g., `' foobar' will produce an execution token for a
state-smart word, not for the interpretation semantics of the original
`foobar'; when you execute this execution token (directly with
`EXECUTE' or indirectly through `COMPILE,') in compile state, the
result will not be what you expected (i.e., it will not perform `foo
bar'). State-smart words are a bad idea. Simply don't write them(1)!

   It is also possible to write defining words that define words with
arbitrary combinations of interpretation and compilation semantics. In
general, they look like this:

     : def-word
         create-interpret/compile
         code1
     interpretation>
         code2
     <interpretation
     compilation>
         code3
     <compilation ;

   For a word defined with `def-word', the interpretation semantics are
to push the address of the body of word and perform code2, and the
compilation semantics are to push the address of the body of word and
perform code3. E.g., `constant' can also be defined like this (except
that the defined constants don't behave correctly when `[compile]'d):

     : constant ( n "name" -- )
         create-interpret/compile
         ,
     interpretation> ( -- n )
         @
     <interpretation
     compilation> ( compilation. -- ; run-time. -- n )
         @ postpone literal
     <compilation ;

`create-interpret/compile'       "name" -         gforth       "create-interpret/compile"

`interpretation>'       compilation. - orig colon-sys         gforth       "interpretation>"

`<interpretation'       compilation. orig colon-sys -         gforth       "<interpretation"

`compilation>'       compilation. - orig colon-sys         gforth       "compilation>"

`<compilation'       compilation. orig colon-sys -         gforth       "<compilation"

   Words defined with `interpret/compile:' and
`create-interpret/compile' have an extended header structure that
differs from other words; however, unless you try to access them with
plain address arithmetic, you should not notice this. Words for
accessing the header structure usually know how to deal with this; e.g.,
`'' word `>body' also gives you the body of a word created with
`create-interpret/compile'.

   ---------- Footnotes ----------

   (1) For a more detailed discussion of this topic, see M. Anton Ertl,
``State'-smartness--Why it is Evil and How to Exorcise it
(http://www.complang.tuwien.ac.at/papers/ertl98.ps.gz)', EuroForth '98.


File: gforth.info,  Node: Tokens for Words,  Next: Compiling words,  Prev: Interpretation and Compilation Semantics,  Up: Words

5.11 Tokens for Words
=====================

This section describes the creation and use of tokens that represent
words.

* Menu:

* Execution token::             represents execution/interpretation semantics
* Compilation token::           represents compilation semantics
* Name token::                  represents named words


File: gforth.info,  Node: Execution token,  Next: Compilation token,  Prev: Tokens for Words,  Up: Tokens for Words

5.11.1 Execution token
----------------------

An "execution token" (XT) represents some behaviour of a word.  You can
use `execute' to invoke this behaviour.

   You can use `'' to get an execution token that represents the
interpretation semantics of a named word:

     5 ' .   ( n xt )
     execute ( )      \ execute the xt (i.e., ".")

`''       "name" - xt         core       "tick"
   xt represents name's interpretation semantics. Perform `-14 throw'
if the word has no interpretation semantics.

   `'' parses at run-time; there is also a word `[']' that parses when
it is compiled, and compiles the resulting XT:

     : foo ['] . execute ;
     5 foo
     : bar ' execute ; \ by contrast,
     5 bar .           \ ' parses "." when bar executes

`[']'       compilation. "name" - ; run-time. - xt         core       "bracket-tick"
   xt represents name's interpretation semantics. Perform `-14 throw'
if the word has no interpretation semantics.

   If you want the execution token of word, write `['] word' in
compiled code and `' word' in interpreted code.  Gforth's `'' and `[']'
behave somewhat unusually by complaining about compile-only words
(because these words have no interpretation semantics).  You might get
what you want by using `COMP' word DROP' or `[COMP'] word DROP' (for
details *note Compilation token::).

   Another way to get an XT is `:noname' or `latestxt' (*note Anonymous
Definitions::).  For anonymous words this gives an xt for the only
behaviour the word has (the execution semantics).  For named words,
`latestxt' produces an XT for the same behaviour it would produce if
the word was defined anonymously.

     :noname ." hello" ;
     execute

   An XT occupies one cell and can be manipulated like any other cell.

   In ANS Forth the XT is just an abstract data type (i.e., defined by
the operations that produce or consume it).  For old hands: In Gforth,
the XT is implemented as a code field address (CFA).

`execute'       xt -        core       "execute"
   Perform the semantics represented by the execution token, xt.

`perform'       a-addr -        gforth       "perform"
   `@ execute'.


File: gforth.info,  Node: Compilation token,  Next: Name token,  Prev: Execution token,  Up: Tokens for Words

5.11.2 Compilation token
------------------------

Gforth represents the compilation semantics of a named word by a
"compilation token" consisting of two cells: w xt. The top cell xt is
an execution token. The compilation semantics represented by the
compilation token can be performed with `execute', which consumes the
whole compilation token, with an additional stack effect determined by
the represented compilation semantics.

   At present, the w part of a compilation token is an execution token,
and the xt part represents either `execute' or `compile,'(1). However,
don't rely on that knowledge, unless necessary; future versions of
Gforth may introduce unusual compilation tokens (e.g., a compilation
token that represents the compilation semantics of a literal).

   You can perform the compilation semantics represented by the
compilation token with `execute'.  You can compile the compilation
semantics with `postpone,'. I.e., `COMP' word postpone,' is equivalent
to `postpone word'.

`[COMP']'       compilation "name" - ; run-time - w xt         gforth       "bracket-comp-tick"
   Compilation token w xt represents name's compilation semantics.

`COMP''       "name" - w xt         gforth       "comp-tick"
   Compilation token w xt represents name's compilation semantics.

`postpone,'       w xt -         gforth       "postpone-comma"
   Compile the compilation semantics represented by the compilation
token w xt.

   ---------- Footnotes ----------

   (1) Depending upon the compilation semantics of the word. If the
word has default compilation semantics, the xt will represent
`compile,'. Otherwise (e.g., for immediate words), the xt will
represent `execute'.


File: gforth.info,  Node: Name token,  Prev: Compilation token,  Up: Tokens for Words

5.11.3 Name token
-----------------

Gforth represents named words by the "name token", (nt).  Name token is
an abstract data type that occurs as argument or result of the words
below.

   The closest thing to the nt in older Forth systems is the name field
address (NFA), but there are significant differences: in older Forth
systems each word had a unique NFA, LFA, CFA and PFA (in this order, or
LFA, NFA, CFA, PFA) and there were words for getting from one to the
next.  In contrast, in Gforth 0...n nts correspond to one xt; there is
a link field in the structure identified by the name token, but
searching usually uses a hash table external to these structures; the
name in Gforth has a cell-wide count-and-flags field, and the nt is not
implemented as the address of that count field.

`find-name'       c-addr u - nt | 0         gforth       "find-name"
   Find the name c-addr u in the current search order. Return its nt,
if found, otherwise 0.

`latest'       - nt         gforth       "latest"
   NT is the name token of the last word defined; it is 0 if the last
word has no name.

`>name'       xt - nt|0         gforth       "to-name"
   tries to find the name token NT of the word represented by XT;
returns 0 if it fails.  This word is not absolutely reliable, it may
give false positives and produce wrong nts.

`name>int'       nt - xt         gforth       "name-to-int"
   xt represents the interpretation semantics of the word nt. If nt has
no interpretation semantics (i.e. is `compile-only'), xt is the
execution token for `ticking-compile-only-error', which performs `-2048
throw'.

`name?int'       nt - xt         gforth       "name-question-int"
   Like `name>int', but perform `-2048 throw' if nt has no
interpretation semantics.

`name>comp'       nt - w xt         gforth       "name-to-comp"
   w xt is the compilation token for the word nt.

`name>string'       nt - addr count         gforth       "name-to-string"
   addr count is the name of the word represented by nt.

`id.'       nt -         gforth       "i-d-dot"
   Print the name of the word represented by NT.

`.name'       nt -         gforth-obsolete       "dot-name"
   Gforth <=0.5.0 name for `id.'.

`.id'       nt -         F83       "dot-i-d"
   F83 name for `id.'.


File: gforth.info,  Node: Compiling words,  Next: The Text Interpreter,  Prev: Tokens for Words,  Up: Words

5.12 Compiling words
====================

In contrast to most other languages, Forth has no strict boundary
between compilation and run-time.  E.g., you can run arbitrary code
between defining words (or for computing data used by defining words
like `constant'). Moreover, `Immediate' (*note Interpretation and
Compilation Semantics:: and `['...`]' (see below) allow running
arbitrary code while compiling a colon definition (exception: you must
not allot dictionary space).

* Menu:

* Literals::                    Compiling data values
* Macros::                      Compiling words


File: gforth.info,  Node: Literals,  Next: Macros,  Prev: Compiling words,  Up: Compiling words

5.12.1 Literals
---------------

The simplest and most frequent example is to compute a literal during
compilation.  E.g., the following definition prints an array of strings,
one string per line:

     : .strings ( addr u -- ) \ gforth
         2* cells bounds U+DO
     	cr i 2@ type
         2 cells +LOOP ;

   With a simple-minded compiler like Gforth's, this computes `2 cells'
on every loop iteration.  You can compute this value once and for all
at compile time and compile it into the definition like this:

     : .strings ( addr u -- ) \ gforth
         2* cells bounds U+DO
     	cr i 2@ type
         [ 2 cells ] literal +LOOP ;

   `[' switches the text interpreter to interpret state (you will get
an `ok' prompt if you type this example interactively and insert a
newline between `[' and `]'), so it performs the interpretation
semantics of `2 cells'; this computes a number.  `]' switches the text
interpreter back into compile state.  It then performs `Literal''s
compilation semantics, which are to compile this number into the
current word.  You can decompile the word with `see .strings' to see
the effect on the compiled code.

   You can also optimize the `2* cells' into `[ 2 cells ] literal *' in
this way.

`['       -         core       "left-bracket"
   Enter interpretation state. Immediate word.

`]'       -         core       "right-bracket"
   Enter compilation state.

`Literal'       compilation n - ; run-time - n         core       "Literal"
   Compilation semantics: compile the run-time semantics.
Run-time Semantics: push n.
Interpretation semantics: undefined.

`]L'       compilation: n - ; run-time: - n         gforth       "]L"
   equivalent to `] literal'

   There are also words for compiling other data types than single
cells as literals:

`2Literal'       compilation w1 w2 - ; run-time  - w1 w2         double       "two-literal"
   Compile appropriate code such that, at run-time, w1 w2 are placed on
the stack. Interpretation semantics are undefined.

`FLiteral'       compilation r - ; run-time - r         float       "f-literal"
   Compile appropriate code such that, at run-time, r is placed on the
(floating-point) stack. Interpretation semantics are undefined.

`SLiteral'       Compilation c-addr1 u ; run-time - c-addr2 u         string       "SLiteral"
   Compilation: compile the string specified by c-addr1, u into the
current definition. Run-time: return c-addr2 u describing the address
and length of the string.

   You might be tempted to pass data from outside a colon definition to
the inside on the data stack.  This does not work, because `:' puhes a
colon-sys, making stuff below unaccessible.  E.g., this does not work:

     5 : foo literal ; \ error: "unstructured"

   Instead, you have to pass the value in some other way, e.g., through
a variable:

     variable temp
     5 temp !
     : foo [ temp @ ] literal ;


File: gforth.info,  Node: Macros,  Prev: Literals,  Up: Compiling words

5.12.2 Macros
-------------

`Literal' and friends compile data values into the current definition.
You can also write words that compile other words into the current
definition.  E.g.,

     : compile-+ ( -- ) \ compiled code: ( n1 n2 -- n )
       POSTPONE + ;

     : foo ( n1 n2 -- n )
       [ compile-+ ] ;
     1 2 foo .

   This is equivalent to `: foo + ;' (`see foo' to check this).  What
happens in this example?  `Postpone' compiles the compilation semantics
of `+' into `compile-+'; later the text interpreter executes
`compile-+' and thus the compilation semantics of +, which compile (the
execution semantics of) `+' into `foo'.(1)

`postpone'       "name" -         core       "postpone"
   Compiles the compilation semantics of name.

`[compile]'       compilation "name" - ; run-time ? - ?         core-ext       "bracket-compile"

   Compiling words like `compile-+' are usually immediate (or similar)
so you do not have to switch to interpret state to execute them;
mopifying the last example accordingly produces:

     : [compile-+] ( compilation: --; interpretation: -- )
       \ compiled code: ( n1 n2 -- n )
       POSTPONE + ; immediate

     : foo ( n1 n2 -- n )
       [compile-+] ;
     1 2 foo .

   Immediate compiling words are similar to macros in other languages
(in particular, Lisp).  The important differences to macros in, e.g., C
are:

   * You use the same language for defining and processing macros, not a
     separate preprocessing language and processor.

   * Consequently, the full power of Forth is available in macro
     definitions.  E.g., you can perform arbitrarily complex
     computations, or generate different code conditionally or in a
     loop (e.g., *note Advanced macros Tutorial::).  This power is very
     useful when writing a parser generators or other code-generating
     software.

   * Macros defined using `postpone' etc. deal with the language at a
     higher level than strings; name binding happens at macro definition
     time, so you can avoid the pitfalls of name collisions that can
     happen in C macros.  Of course, Forth is a liberal language and
     also allows to shoot yourself in the foot with text-interpreted
     macros like

          : [compile-+] s" +" evaluate ; immediate

     Apart from binding the name at macro use time, using `evaluate'
     also makes your definition `state'-smart (*note state-smartness::).

   You may want the macro to compile a number into a word.  The word to
do it is `literal', but you have to `postpone' it, so its compilation
semantics take effect when the macro is executed, not when it is
compiled:

     : [compile-5] ( -- ) \ compiled code: ( -- n )
       5 POSTPONE literal ; immediate

     : foo [compile-5] ;
     foo .

   You may want to pass parameters to a macro, that the macro should
compile into the current definition.  If the parameter is a number, then
you can use `postpone literal' (similar for other values).

   If you want to pass a word that is to be compiled, the usual way is
to pass an execution token and `compile,' it:

     : twice1 ( xt -- ) \ compiled code: ... -- ...
       dup compile, compile, ;

     : 2+ ( n1 -- n2 )
       [ ' 1+ twice1 ] ;

`compile,'       xt -         core-ext       "compile-comma"
    Compile the word represented by the execution token xt  into the
current definition.

   An alternative available in Gforth, that allows you to pass
compile-only words as parameters is to use the compilation token (*note
Compilation token::).  The same example in this technique:

     : twice ( ... ct -- ... ) \ compiled code: ... -- ...
       2dup 2>r execute 2r> execute ;

     : 2+ ( n1 -- n2 )
       [ comp' 1+ twice ] ;

   In the example above `2>r' and `2r>' ensure that `twice' works even
if the executed compilation semantics has an effect on the data stack.

   You can also define complete definitions with these words; this
provides an alternative to using `does>' (*note User-defined Defining
Words::).  E.g., instead of

     : curry+ ( n1 "name" -- )
         CREATE ,
     DOES> ( n2 -- n1+n2 )
         @ + ;

   you could define

     : curry+ ( n1 "name" -- )
       \ name execution: ( n2 -- n1+n2 )
       >r : r> POSTPONE literal POSTPONE + POSTPONE ; ;

     -3 curry+ 3-
     see 3-

   The sequence `>r : r>' is necessary, because `:' puts a colon-sys on
the data stack that makes everything below it unaccessible.

   This way of writing defining words is sometimes more, sometimes less
convenient than using `does>' (*note Advanced does> usage example::).
One advantage of this method is that it can be optimized better,
because the compiler knows that the value compiled with `literal' is
fixed, whereas the data associated with a `create'd word can be changed.

   ---------- Footnotes ----------

   (1) A recent RFI answer requires that compiling words should only be
executed in compile state, so this example is not guaranteed to work on
all standard systems, but on any decent system it will work.


File: gforth.info,  Node: The Text Interpreter,  Next: The Input Stream,  Prev: Compiling words,  Up: Words

5.13 The Text Interpreter
=========================

The text interpreter(1) is an endless loop that processes input from
the current input device. It is also called the outer interpreter, in
contrast to the inner interpreter (*note Engine::) which executes the
compiled Forth code on interpretive implementations.

   The text interpreter operates in one of two states: "interpret
state" and "compile state". The current state is defined by the
aptly-named variable `state'.

   This section starts by describing how the text interpreter behaves
when it is in interpret state, processing input from the user input
device - the keyboard. This is the mode that a Forth system is in after
it starts up.

   The text interpreter works from an area of memory called the "input
buffer"(2), which stores your keyboard input when you press the <RET>
key. Starting at the beginning of the input buffer, it skips leading
spaces (called "delimiters") then parses a string (a sequence of
non-space characters) until it reaches either a space character or the
end of the buffer. Having parsed a string, it makes two attempts to
process it:

   * It looks for the string in a "dictionary" of definitions. If the
     string is found, the string names a "definition" (also known as a
     "word") and the dictionary search returns information that allows
     the text interpreter to perform the word's "interpretation
     semantics". In most cases, this simply means that the word will be
     executed.

   * If the string is not found in the dictionary, the text interpreter
     attempts to treat it as a number, using the rules described in
     *note Number Conversion::. If the string represents a legal number
     in the current radix, the number is pushed onto a parameter stack
     (the data stack for integers, the floating-point stack for
     floating-point numbers).

   If both attempts fail, or if the word is found in the dictionary but
has no interpretation semantics(3) the text interpreter discards the
remainder of the input buffer, issues an error message and waits for
more input. If one of the attempts succeeds, the text interpreter
repeats the parsing process until the whole of the input buffer has been
processed, at which point it prints the status message "` ok'" and
waits for more input.

   The text interpreter keeps track of its position in the input buffer
by updating a variable called `>IN' (pronounced "to-in"). The value of
`>IN' starts out as 0, indicating an offset of 0 from the start of the
input buffer. The region from offset `>IN @' to the end of the input
buffer is called the "parse area"(4).  This example shows how `>IN'
changes as the text interpreter parses the input buffer:

     : remaining >IN @ SOURCE 2 PICK - -ROT + SWAP
       CR ." ->" TYPE ." <-" ; IMMEDIATE

     1 2 3 remaining + remaining .

     : foo 1 2 3 remaining SWAP remaining ;

The result is:

     ->+ remaining .<-
     ->.<-5  ok

     ->SWAP remaining ;-<
     ->;<-  ok

   The value of `>IN' can also be modified by a word in the input
buffer that is executed by the text interpreter.  This means that a word
can "trick" the text interpreter into either skipping a section of the
input buffer(5) or into parsing a section twice. For example:

     : lat ." <<foo>>" ;
     : flat ." <<bar>>" >IN DUP @ 3 - SWAP ! ;

When `flat' is executed, this output is produced(6):

     <<bar>><<foo>>

   This technique can be used to work around some of the
interoperability problems of parsing words.  Of course, it's better to
avoid parsing words where possible.

Two important notes about the behaviour of the text interpreter:

   * It processes each input string to completion before parsing
     additional characters from the input buffer.

   * It treats the input buffer as a read-only region (and so must your
     code).

When the text interpreter is in compile state, its behaviour changes in
these ways:

   * If a parsed string is found in the dictionary, the text
     interpreter will perform the word's "compilation semantics". In
     most cases, this simply means that the execution semantics of the
     word will be appended to the current definition.

   * When a number is encountered, it is compiled into the current
     definition (as a literal) rather than being pushed onto a
     parameter stack.

   * If an error occurs, `state' is modified to put the text interpreter
     back into interpret state.

   * Each time a line is entered from the keyboard, Gforth prints "`
     compiled'" rather than " `ok'".

   When the text interpreter is using an input device other than the
keyboard, its behaviour changes in these ways:

   * When the parse area is empty, the text interpreter attempts to
     refill the input buffer from the input source. When the input
     source is exhausted, the input source is set back to the previous
     input source.

   * It doesn't print out "` ok'" or "` compiled'" messages each time
     the parse area is emptied.

   * If an error occurs, the input source is set back to the user input
     device.

   You can read about this in more detail in *note Input Sources::.

`>in'       - addr         core       "to-in"
   `input-var' variable - a-addr is the address of a cell containing
the char offset from the start of the input buffer to the start of the
parse area.

`source'       - addr u         core       "source"
   Return address addr and length u of the current input buffer

`tib'       - addr         core-ext-obsolescent       "t-i-b"

`#tib'       - addr         core-ext-obsolescent       "number-t-i-b"
   `input-var' variable - a-addr is the address of a cell containing
the number of characters in the terminal input buffer. OBSOLESCENT:
`source' superceeds the function of this word.

* Menu:

* Input Sources::
* Number Conversion::
* Interpret/Compile states::
* Interpreter Directives::

   ---------- Footnotes ----------

   (1) This is an expanded version of the material in *note Introducing
the Text Interpreter::.

   (2) When the text interpreter is processing input from the keyboard,
this area of memory is called the "terminal input buffer" (TIB) and is
addressed by the (obsolescent) words `TIB' and `#TIB'.

   (3) This happens if the word was defined as `COMPILE-ONLY'.

   (4) In other words, the text interpreter processes the contents of
the input buffer by parsing strings from the parse area until the parse
area is empty.

   (5) This is how parsing words work.

   (6) Exercise for the reader: what would happen if the `3' were
replaced with `4'?


File: gforth.info,  Node: Input Sources,  Next: Number Conversion,  Prev: The Text Interpreter,  Up: The Text Interpreter

5.13.1 Input Sources
--------------------

By default, the text interpreter processes input from the user input
device (the keyboard) when Forth starts up. The text interpreter can
process input from any of these sources:

   * The user input device - the keyboard.

   * A file, using the words described in *note Forth source files::.

   * A block, using the words described in *note Blocks::.

   * A text string, using `evaluate'.

   A program can identify the current input device from the values of
`source-id' and `blk'.

`source-id'       - 0 | -1 | fileid         core-ext,file       "source-i-d"
   Return 0 (the input source is the user input device), -1 (the input
source is a string being processed by `evaluate') or a fileid (the
input source is the file specified by fileid).

`blk'       - addr         block       "b-l-k"
   `input-var' variable - This cell contains the current block number

`save-input'       - x1 .. xn n         core-ext       "save-input"
   The n entries xn - x1 describe the current state of the input source
specification, in some platform-dependent way that can be used by
`restore-input'.

`restore-input'       x1 .. xn n - flag         core-ext       "restore-input"
   Attempt to restore the input source specification to the state
described by the n entries xn - x1. flag is true if the restore fails.
In Gforth with the new input code, it fails only with a flag that can
be used to throw again; it is also possible to save and restore between
different active input streams. Note that closing the input streams
must happen in the reverse order as they have been opened, but in
between everything is allowed.

`evaluate'       ... addr u - ...         core,block       "evaluate"
   Save the current input source specification. Store `-1' in
`source-id' and `0' in `blk'. Set `>IN' to `0' and make the string
c-addr u the input source and input buffer. Interpret. When the parse
area is empty, restore the input source specification.

`query'       -         core-ext-obsolescent       "query"
   Make the user input device the input source. Receive input into the
Terminal Input Buffer. Set `>IN' to zero. OBSOLESCENT: superceeded by
`accept'.


File: gforth.info,  Node: Number Conversion,  Next: Interpret/Compile states,  Prev: Input Sources,  Up: The Text Interpreter

5.13.2 Number Conversion
------------------------

This section describes the rules that the text interpreter uses when it
tries to convert a string into a number.

   Let <digit> represent any character that is a legal digit in the
current number base(1).

   Let <decimal digit> represent any character in the range 0-9.

   Let {a b} represent the optional presence of any of the characters
in the braces (a or b or neither).

   Let * represent any number of instances of the previous character
(including none).

   Let any other character represent itself.

Now, the conversion rules are:

   * A string of the form <digit><digit>* is treated as a
     single-precision (cell-sized) positive integer. Examples are 0 123
     6784532 32343212343456 42

   * A string of the form -<digit><digit>* is treated as a
     single-precision (cell-sized) negative integer, and is represented
     using 2's-complement arithmetic. Examples are -45 -5681 -0

   * A string of the form <digit><digit>*.<digit>* is treated as a
     double-precision (double-cell-sized) positive integer. Examples
     are 3465. 3.465 34.65 (all three of these represent the same
     number).

   * A string of the form -<digit><digit>*.<digit>* is treated as a
     double-precision (double-cell-sized) negative integer, and is
     represented using 2's-complement arithmetic. Examples are -3465.
     -3.465 -34.65 (all three of these represent the same number).

   * A string of the form {+ -}<decimal digit>{.}<decimal digit>*{e
     E}{+ -}<decimal digit><decimal digit>* is treated as a
     floating-point number. Examples are 1e 1e0 1.e 1.e0 +1e+0 (which
     all represent the same number) +12.E-4

   By default, the number base used for integer number conversion is
given by the contents of the variable `base'.  Note that a lot of
confusion can result from unexpected values of `base'.  If you change
`base' anywhere, make sure to save the old value and restore it
afterwards; better yet, use `base-execute', which does this for you.
In general I recommend keeping `base' decimal, and using the prefixes
described below for the popular non-decimal bases.

`dpl'       - a-addr         gforth       "dpl"
   `User' variable - a-addr is the address of a cell that stores the
position of the decimal point in the most recent numeric conversion.
Initialised to -1. After the conversion of a number containing no
decimal point, `dpl' is -1. After the conversion of `2.' it holds 0.
After the conversion of 234123.9 it contains 1, and so forth.

`base-execute'       i*x xt u - j*x         gforth       "base-execute"
   execute xt with the content of `BASE' being u, and restoring the
original `BASE' afterwards.

`base'       - a-addr         core       "base"
   `User' variable - a-addr is the address of a cell that stores the
number base used by default for number conversion during input and
output.  Don't store to `base', use `base-execute' instead.

`hex'       -         core-ext       "hex"
   Set `base' to &16 (hexadecimal).  Don't use `hex', use
`base-execute' instead.

`decimal'       -         core       "decimal"
   Set `base' to &10 (decimal).  Don't use `hex', use `base-execute'
instead.

   Gforth allows you to override the value of `base' by using a
prefix(2) before the first digit of an (integer) number. The following
prefixes are supported:

   * `&' - decimal

   * `#' - decimal

   * `%' - binary

   * `$' - hexadecimal

   * `0x' - hexadecimal, if base<33.

   * `'' - numeric value (e.g., ASCII code) of next character; an
     optional `'' may be present after the character.

   Here are some examples, with the equivalent decimal number shown
after in braces:

   -$41 (-65), %1001101 (205), %1001.0001 (145 - a double-precision
number), 'A (65), -'a' (-97), &905 (905), $abc (2478), $ABC (2478).

Number conversion has a number of traps for the unwary:

   * You cannot determine the current number base using the code
     sequence `base @ .' - the number base is always 10 in the current
     number base. Instead, use something like `base @ dec.'

   * If the number base is set to a value greater than 14 (for example,
     hexadecimal), the number 123E4 is ambiguous; the conversion rules
     allow it to be intepreted as either a single-precision integer or a
     floating-point number (Gforth treats it as an integer). The
     ambiguity can be resolved by explicitly stating the sign of the
     mantissa and/or exponent: 123E+4 or +123E4 - if the number base is
     decimal, no ambiguity arises; either representation will be
     treated as a floating-point number.

   * There is a word `bin' but it does not set the number base!  It is
     used to specify file types.

   * ANS Forth requires the `.' of a double-precision number to be the
     final character in the string.  Gforth allows the `.' to be
     anywhere after the first digit.

   * The number conversion process does not check for overflow.

   * In an ANS Forth program `base' is required to be decimal when
     converting floating-point numbers.  In Gforth, number conversion to
     floating-point numbers always uses base &10, irrespective of the
     value of `base'.

   You can read numbers into your programs with the words described in
*note Line input and conversion::.

   ---------- Footnotes ----------

   (1) For example, 0-9 when the number base is decimal or 0-9, A-F
when the number base is hexadecimal.

   (2) Some Forth implementations provide a similar scheme by
implementing `$' etc. as parsing words that process the subsequent
number in the input stream and push it onto the stack. For example, see
`Number Conversion and Literals', by Wil Baden; Forth Dimensions 20(3)
pages 26-27. In such implementations, unlike in Gforth, a space is
required between the prefix and the number.


File: gforth.info,  Node: Interpret/Compile states,  Next: Interpreter Directives,  Prev: Number Conversion,  Up: The Text Interpreter

5.13.3 Interpret/Compile states
-------------------------------

A standard program is not permitted to change `state' explicitly.
However, it can change `state' implicitly, using the words `[' and `]'.
When `[' is executed it switches `state' to interpret state, and
therefore the text interpreter starts interpreting. When `]' is
executed it switches `state' to compile state and therefore the text
interpreter starts compiling. The most common usage for these words is
for switching into interpret state and back from within a colon
definition; this technique can be used to compile a literal (for an
example, *note Literals::) or for conditional compilation (for an
example, *note Interpreter Directives::).


File: gforth.info,  Node: Interpreter Directives,  Prev: Interpret/Compile states,  Up: The Text Interpreter

5.13.4 Interpreter Directives
-----------------------------

These words are usually used in interpret state; typically to control
which parts of a source file are processed by the text interpreter.
There are only a few ANS Forth Standard words, but Gforth supplements
these with a rich set of immediate control structure words to
compensate for the fact that the non-immediate versions can only be
used in compile state (*note Control Structures::). Typical usages:

     FALSE Constant HAVE-ASSEMBLER
     .
     .
     HAVE-ASSEMBLER [IF]
     : ASSEMBLER-FEATURE
       ...
     ;
     [ENDIF]
     .
     .
     : SEE
       ... \ general-purpose SEE code
       [ HAVE-ASSEMBLER [IF] ]
       ... \ assembler-specific SEE code
       [ [ENDIF] ]
     ;

`[IF]'       flag -         tools-ext       "bracket-if"
   If flag is `TRUE' do nothing (and therefore execute subsequent words
as normal). If flag is `FALSE', parse and discard words from the parse
area (refilling it if necessary using `REFILL') including nested
instances of `[IF]'..  `[ELSE]'.. `[THEN]' and `[IF]'.. `[THEN]' until
the balancing `[ELSE]' or `[THEN]' has been parsed and discarded.
Immediate word.

`[ELSE]'       -         tools-ext       "bracket-else"
   Parse and discard words from the parse area (refilling it if
necessary using `REFILL') including nested instances of `[IF]'..
`[ELSE]'.. `[THEN]' and `[IF]'.. `[THEN]' until the balancing `[THEN]'
has been parsed and discarded.  `[ELSE]' only gets executed if the
balancing `[IF]' was `TRUE'; if it was `FALSE', `[IF]' would have
parsed and discarded the `[ELSE]', leaving the subsequent words to be
executed as normal.  Immediate word.

`[THEN]'       -         tools-ext       "bracket-then"
   Do nothing; used as a marker for other words to parse and discard up
to. Immediate word.

`[ENDIF]'       -         gforth       "bracket-end-if"
   Do nothing; synonym for `[THEN]'

`[IFDEF]'       "<spaces>name" -         gforth       "bracket-if-def"
   If name is found in the current search-order, behave like `[IF]'
with a `TRUE' flag, otherwise behave like `[IF]' with a `FALSE' flag.
Immediate word.

`[IFUNDEF]'       "<spaces>name" -         gforth       "bracket-if-un-def"
   If name is not found in the current search-order, behave like `[IF]'
with a `TRUE' flag, otherwise behave like `[IF]' with a `FALSE' flag.
Immediate word.

`[?DO]'       n-limit n-index -         gforth       "bracket-question-do"

`[DO]'       n-limit n-index -         gforth       "bracket-do"

`[FOR]'       n -         gforth       "bracket-for"

`[LOOP]'       -         gforth       "bracket-loop"

`[+LOOP]'       n -         gforth       "bracket-question-plus-loop"

`[NEXT]'       n -         gforth       "bracket-next"

`[BEGIN]'       -         gforth       "bracket-begin"

`[UNTIL]'       flag -         gforth       "bracket-until"

`[AGAIN]'       -         gforth       "bracket-again"

`[WHILE]'       flag -         gforth       "bracket-while"

`[REPEAT]'       -         gforth       "bracket-repeat"


File: gforth.info,  Node: The Input Stream,  Next: Word Lists,  Prev: The Text Interpreter,  Up: Words

5.14 The Input Stream
=====================

The text interpreter reads from the input stream, which can come from
several sources (*note Input Sources::).  Some words, in particular
defining words, but also words like `'', read parameters from the input
stream instead of from the stack.

   Such words are called parsing words, because they parse the input
stream.  Parsing words are hard to use in other words, because it is
hard to pass program-generated parameters through the input stream.
They also usually have an unintuitive combination of interpretation and
compilation semantics when implemented naively, leading to various
approaches that try to produce a more intuitive behaviour (*note
Combined words::).

   It should be obvious by now that parsing words are a bad idea.  If
you want to implement a parsing word for convenience, also provide a
factor of the word that does not parse, but takes the parameters on the
stack.  To implement the parsing word on top if it, you can use the
following words:

`parse'       char "ccc<char>" - c-addr u         core-ext       "parse"
   Parse ccc, delimited by char, in the parse area. c-addr u specifies
the parsed string within the parse area. If the parse area was empty, u
is 0.

`parse-name'       "name" - c-addr u         gforth       "parse-name"
   Get the next word from the input buffer

`parse-word'       - c-addr u         gforth-obsolete       "parse-word"
   old name for `parse-name'

`name'       - c-addr u         gforth-obsolete       "name"
   old name for `parse-name'

`word'       char "<chars>ccc<char>- c-addr         core       "word"
   Skip leading delimiters. Parse ccc, delimited by char, in the parse
area. c-addr is the address of a transient region containing the parsed
string in counted-string format. If the parse area was empty or
contained no characters other than delimiters, the resulting string has
zero length. A program may replace characters within the counted
string. OBSOLESCENT: the counted string has a trailing space that is
not included in its length.

`refill'       - flag         core-ext,block-ext,file-ext       "refill"
   Attempt to fill the input buffer from the input source.  When the
input source is the user input device, attempt to receive input into
the terminal input device. If successful, make the result the input
buffer, set `>IN' to 0 and return true; otherwise return false. When
the input source is a block, add 1 to the value of `BLK' to make the
next block the input source and current input buffer, and set `>IN' to
0; return true if the new value of `BLK' is a valid block number, false
otherwise. When the input source is a text file, attempt to read the
next line from the file. If successful, make the result the current
input buffer, set `>IN' to 0 and return true; otherwise, return false.
A successful result includes receipt of a line containing 0 characters.

   Conversely, if you have the bad luck (or lack of foresight) to have
to deal with parsing words without having such factors, how do you pass
a string that is not in the input stream to it?

`execute-parsing'       ... addr u xt - ...         gforth       "execute-parsing"
   Make addr u the current input source, execute xt `( ... -- ... )',
then restore the previous input source.

   A definition of this word in ANS Forth is provided in
`compat/execute-parsing.fs'.

   If you want to run a parsing word on a file, the following word
should help:

`execute-parsing-file'       i*x fileid xt - j*x         gforth       "execute-parsing-file"
   Make fileid the current input source, execute xt `( i*x -- j*x )',
then restore the previous input source.


File: gforth.info,  Node: Word Lists,  Next: Environmental Queries,  Prev: The Input Stream,  Up: Words

5.15 Word Lists
===============

A wordlist is a list of named words; you can add new words and look up
words by name (and you can remove words in a restricted way with
markers).  Every named (and `reveal'ed) word is in one wordlist.

   The text interpreter searches the wordlists present in the search
order (a stack of wordlists), from the top to the bottom.  Within each
wordlist, the search starts conceptually at the newest word; i.e., if
two words in a wordlist have the same name, the newer word is found.

   New words are added to the "compilation wordlist" (aka current
wordlist).

   A word list is identified by a cell-sized word list identifier (wid)
in much the same way as a file is identified by a file handle. The
numerical value of the wid has no (portable) meaning, and might change
from session to session.

   The ANS Forth "Search order" word set is intended to provide a set of
low-level tools that allow various different schemes to be implemented.
Gforth also provides `vocabulary', a traditional Forth word.
`compat/vocabulary.fs' provides an implementation in ANS Forth.

`forth-wordlist'       - wid         search       "forth-wordlist"
   `Constant' - wid identifies the word list that includes all of the
standard words provided by Gforth. When Gforth is invoked, this word
list is the compilation word list and is at the top of the search order.

`definitions'       -         search       "definitions"
   Set the compilation word list to be the same as the word list that
is currently at the top of the search order.

`get-current'       - wid         search       "get-current"
   wid is the identifier of the current compilation word list.

`set-current'       wid -         search       "set-current"
   Set the compilation word list to the word list identified by wid.

`get-order'       - widn .. wid1 n         search       "get-order"
   Copy the search order to the data stack. The current search order
has n entries, of which wid1 represents the wordlist that is searched
first (the word list at the top of the search order) and widn
represents the wordlist that is searched last.

`set-order'       widn .. wid1 n -         search       "set-order"
   If N=0, empty the search order.  If N=-1, set the search order to
the implementation-defined minimum search order (for Gforth, this is
the word list `Root'). Otherwise, replace the existing search order
with the N wid entries such that WID1 represents the word list that
will be searched first and WIDN represents the word list that will be
searched last.

`wordlist'       - wid         search       "wordlist"
   Create a new, empty word list represented by wid.

`table'       - wid         gforth       "table"
   Create a case-sensitive wordlist.

`>order'       wid -         gforth       "to-order"
   Push WID on the search order.

`previous'       -         search-ext       "previous"
   Drop the wordlist at the top of the search order.

`also'       -         search-ext       "also"
   Like `DUP' for the search order. Usually used before a vocabulary
(e.g., `also Forth'); the combined effect is to push the wordlist
represented by the vocabulary on the search order.

`Forth'       -         search-ext       "Forth"
   Replace the wid at the top of the search order with the wid
associated with the word list `forth-wordlist'.

`Only'       -         search-ext       "Only"
   Set the search order to the implementation-defined minimum search
order (for Gforth, this is the word list `Root').

`order'       -         search-ext       "order"
   Print the search order and the compilation word list.  The word
lists are printed in the order in which they are searched (which is
reversed with respect to the conventional way of displaying stacks).
The compilation word list is displayed last.

`find'       c-addr - xt +-1 | c-addr 0         core,search       "find"
   Search all word lists in the current search order for the definition
named by the counted string at c-addr.  If the definition is not found,
return 0. If the definition is found return 1 (if the definition has
non-default compilation semantics) or -1 (if the definition has default
compilation semantics).  The xt returned in interpret state represents
the interpretation semantics.  The xt returned in compile state
represented either the compilation semantics (for non-default
compilation semantics) or the run-time semantics that the compilation
semantics would `compile,' (for default compilation semantics).  The
ANS Forth standard does not specify clearly what the returned xt
represents (and also talks about immediacy instead of non-default
compilation semantics), so this word is questionable in portable
programs.  If non-portability is ok, `find-name' and friends are better
(*note Name token::).

`search-wordlist'       c-addr count wid - 0 | xt +-1         search       "search-wordlist"
   Search the word list identified by wid for the definition named by
the string at c-addr count.  If the definition is not found, return 0.
If the definition is found return 1 (if the definition is immediate) or
-1 (if the definition is not immediate) together with the xt.  In
Gforth, the xt returned represents the interpretation semantics.  ANS
Forth does not specify clearly what xt represents.

`words'       -         tools       "words"
   Display a list of all of the definitions in the word list at the top
of the search order.

`vlist'       -         gforth       "vlist"
   Old (pre-Forth-83) name for `WORDS'.

`Root'       -         gforth       "Root"
   Add the root wordlist to the search order stack.  This vocabulary
makes up the minimum search order and contains only a search-order
words.

`Vocabulary'       "name" -         gforth       "Vocabulary"
   Create a definition "name" and associate a new word list with it.
The run-time effect of "name" is to replace the wid at the top of the
search order with the wid associated with the new word list.

`seal'       -         gforth       "seal"
   Remove all word lists from the search order stack other than the word
list that is currently on the top of the search order stack.

`vocs'       -         gforth       "vocs"
   List vocabularies and wordlists defined in the system.

`current'       - addr         gforth       "current"
   `Variable' - holds the wid of the compilation word list.

`context'       - addr         gforth       "context"
   `context' `@' is the wid of the word list at the top of the search
order.

* Menu:

* Vocabularies::
* Why use word lists?::
* Word list example::


File: gforth.info,  Node: Vocabularies,  Next: Why use word lists?,  Prev: Word Lists,  Up: Word Lists

5.15.1 Vocabularies
-------------------

Here is an example of creating and using a new wordlist using ANS Forth
words:

     wordlist constant my-new-words-wordlist
     : my-new-words get-order nip my-new-words-wordlist swap set-order ;

     \ add it to the search order
     also my-new-words

     \ alternatively, add it to the search order and make it
     \ the compilation word list
     also my-new-words definitions
     \ type "order" to see the problem

   The problem with this example is that `order' has no way to
associate the name `my-new-words' with the wid of the word list (in
Gforth, `order' and `vocs' will display `???'  for a wid that has no
associated name). There is no Standard way of associating a name with a
wid.

   In Gforth, this example can be re-coded using `vocabulary', which
associates a name with a wid:

     vocabulary my-new-words

     \ add it to the search order
     also my-new-words

     \ alternatively, add it to the search order and make it
     \ the compilation word list
     my-new-words definitions
     \ type "order" to see that the problem is solved


File: gforth.info,  Node: Why use word lists?,  Next: Word list example,  Prev: Vocabularies,  Up: Word Lists

5.15.2 Why use word lists?
--------------------------

Here are some reasons why people use wordlists:

   * To prevent a set of words from being used outside the context in
     which they are valid. Two classic examples of this are an
     integrated editor (all of the edit commands are defined in a
     separate word list; the search order is set to the editor word
     list when the editor is invoked; the old search order is restored
     when the editor is terminated) and an integrated assembler (the
     op-codes for the machine are defined in a separate word list which
     is used when a `CODE' word is defined).

   * To organize the words of an application or library into a
     user-visible set (in `forth-wordlist' or some other common
     wordlist) and a set of helper words used just for the
     implementation (hidden in a separate wordlist).  This keeps
     `words'' output smaller, separates implementation and interface,
     and reduces the chance of name conflicts within the common
     wordlist.

   * To prevent a name-space clash between multiple definitions with
     the same name. For example, when building a cross-compiler you
     might have a word `IF' that generates conditional code for your
     target system. By placing this definition in a different word list
     you can control whether the host system's `IF' or the target
     system's `IF' get used in any particular context by controlling
     the order of the word lists on the search order stack.


   The downsides of using wordlists are:

   * Debugging becomes more cumbersome.

   * Name conflicts worked around with wordlists are still there, and
     you have to arrange the search order carefully to get the desired
     results; if you forget to do that, you get hard-to-find errors (as
     in any case where you read the code differently from the compiler;
     `see' can help seeing which of several possible words the name
     resolves to in such cases).  `See' displays just the name of the
     words, not what wordlist they belong to, so it might be
     misleading.  Using unique names is a better approach to avoid name
     conflicts.

   * You have to explicitly undo any changes to the search order.  In
     many cases it would be more convenient if this happened
     implicitly.  Gforth currently does not provide such a feature, but
     it may do so in the future.


File: gforth.info,  Node: Word list example,  Prev: Why use word lists?,  Up: Word Lists

5.15.3 Word list example
------------------------

The following example is from the garbage collector
(http://www.complang.tuwien.ac.at/forth/garbage-collection.zip) and
uses wordlists to separate public words from helper words:

     get-current ( wid )
     vocabulary garbage-collector also garbage-collector definitions
     ... \ define helper words
     ( wid ) set-current \ restore original (i.e., public) compilation wordlist
     ... \ define the public (i.e., API) words
         \ they can refer to the helper words
     previous \ restore original search order (helper words become invisible)


File: gforth.info,  Node: Environmental Queries,  Next: Files,  Prev: Word Lists,  Up: Words

5.16 Environmental Queries
==========================

ANS Forth introduced the idea of "environmental queries" as a way for a
program running on a system to determine certain characteristics of the
system.  The Standard specifies a number of strings that might be
recognised by a system.

   The Standard requires that the header space used for environmental
queries be distinct from the header space used for definitions.

   Typically, environmental queries are supported by creating a set of
definitions in a word list that is only used during environmental
queries; that is what Gforth does. There is no Standard way of adding
definitions to the set of recognised environmental queries, but any
implementation that supports the loading of optional word sets must have
some mechanism for doing this (after loading the word set, the
associated environmental query string must return `true'). In Gforth,
the word list used to honour environmental queries can be manipulated
just like any other word list.

`environment?'       c-addr u - false / ... true         core       "environment-query"
   c-addr, u specify a counted string. If the string is not recognised,
return a `false' flag. Otherwise return a `true' flag and some
(string-specific) information about the queried string.

`environment-wordlist'       - wid         gforth       "environment-wordlist"
   wid identifies the word list that is searched by environmental
queries.

`gforth'       - c-addr u         gforth-environment       "gforth"
   Counted string representing a version string for this version of
Gforth (for versions>0.3.0).  The version strings of the various
versions are guaranteed to be ordered lexicographically.

`os-class'       - c-addr u         gforth-environment       "os-class"
   Counted string representing a description of the host operating
system.

   Note that, whilst the documentation for (e.g.) `gforth' shows it
returning two items on the stack, querying it using `environment?' will
return an additional item; the `true' flag that shows that the string
was recognised.

   Here are some examples of using environmental queries:

     s" address-unit-bits" environment? 0=
     [IF]
          cr .( environmental attribute address-units-bits unknown... ) cr
     [ELSE]
          drop \ ensure balanced stack effect
     [THEN]

     \ this might occur in the prelude of a standard program that uses THROW
     s" exception" environment? [IF]
        0= [IF]
           : throw abort" exception thrown" ;
        [THEN]
     [ELSE] \ we don't know, so make sure
        : throw abort" exception thrown" ;
     [THEN]

     s" gforth" environment? [IF] .( Gforth version ) TYPE
                             [ELSE] .( Not Gforth..) [THEN]

     \ a program using v*
     s" gforth" environment? [IF]
       s" 0.5.0" compare 0< [IF] \ v* is a primitive since 0.5.0
        : v* ( f_addr1 nstride1 f_addr2 nstride2 ucount -- r )
          >r swap 2swap swap 0e r> 0 ?DO
            dup f@ over + 2swap dup f@ f* f+ over + 2swap
          LOOP
          2drop 2drop ;
       [THEN]
     [ELSE] \
       : v* ( f_addr1 nstride1 f_addr2 nstride2 ucount -- r )
       ...
     [THEN]

   Here is an example of adding a definition to the environment word
list:

     get-current environment-wordlist set-current
     true constant block
     true constant block-ext
     set-current

   You can see what definitions are in the environment word list like
this:

     environment-wordlist >order words previous


File: gforth.info,  Node: Files,  Next: Blocks,  Prev: Environmental Queries,  Up: Words

5.17 Files
==========

Gforth provides facilities for accessing files that are stored in the
host operating system's file-system. Files that are processed by Gforth
can be divided into two categories:

   * Files that are processed by the Text Interpreter ("Forth source
     files").

   * Files that are processed by some other program ("general files").

* Menu:

* Forth source files::
* General files::
* Redirection::
* Search Paths::


File: gforth.info,  Node: Forth source files,  Next: General files,  Prev: Files,  Up: Files

5.17.1 Forth source files
-------------------------

The simplest way to interpret the contents of a file is to use one of
these two formats:

     include mysource.fs
     s" mysource.fs" included

   You usually want to include a file only if it is not included already
(by, say, another source file). In that case, you can use one of these
three formats:

     require mysource.fs
     needs mysource.fs
     s" mysource.fs" required

   It is good practice to write your source files such that
interpreting them does not change the stack. Source files designed in
this way can be used with `required' and friends without complications.
For example:

     1024 require foo.fs drop

   Here you want to pass the argument 1024 (e.g., a buffer size) to
`foo.fs'.  Interpreting `foo.fs' has the stack effect ( n - n ), which
allows its use with `require'.  Of course with such parameters to
required files, you have to ensure that the first `require' fits for
all uses (i.e., `require' it early in the master load file).

`include-file'       i*x wfileid - j*x         file       "include-file"
   Interpret (process using the text interpreter) the contents of the
file WFILEID.

`included'       i*x c-addr u - j*x         file       "included"
   `include-file' the file whose name is given by the string C-ADDR U.

`included?'       c-addr u - f         gforth       "included?"
   True only if the file C-ADDR U is in the list of earlier included
files. If the file has been loaded, it may have been specified as, say,
`foo.fs' and found somewhere on the Forth search path. To return `true'
from `included?', you must specify the exact path to the file, even if
that is `./foo.fs'

`include'       ... "file" - ...         gforth       "include"
   `include-file' the file FILE.

`required'       i*x addr u - i*x         gforth       "required"
   `include-file' the file with the name given by ADDR U, if it is not
`included' (or `required') already. Currently this works by comparing
the name of the file (with path) against the names of earlier included
files.

`require'       ... "file" - ...         gforth       "require"
   `include-file' FILE only if it is not included already.

`needs'       ... "name" - ...         gforth       "needs"
   An alias for `require'; exists on other systems (e.g., Win32Forth).

`sourcefilename'       - c-addr u         gforth       "sourcefilename"
   The name of the source file which is currently the input source.
The result is valid only while the file is being loaded.  If the
current input source is no (stream) file, the result is undefined.  In
Gforth, the result is valid during the whole seesion (but not across
`savesystem' etc.).

`sourceline#'       - u         gforth       "sourceline-number"
   The line number of the line that is currently being interpreted from
a (stream) file. The first line has the number 1. If the current input
source is not a (stream) file, the result is undefined.

   A definition in ANS Forth for `required' is provided in
`compat/required.fs'.


File: gforth.info,  Node: General files,  Next: Redirection,  Prev: Forth source files,  Up: Files

5.17.2 General files
--------------------

Files are opened/created by name and type. The following file access
methods (FAMs) are recognised:

`r/o'       - fam         file       "r-o"

`r/w'       - fam         file       "r-w"

`w/o'       - fam         file       "w-o"

`bin'       fam1 - fam2         file       "bin"

   When a file is opened/created, it returns a file identifier, wfileid
that is used for all other file commands. All file commands also return
a status value, wior, that is 0 for a successful operation and an
implementation-defined non-zero value in the case of an error.

`open-file'       c-addr u wfam - wfileid wior        file       "open-file"

`create-file'       c-addr u wfam - wfileid wior        file       "create-file"

`close-file'       wfileid - wior        file       "close-file"

`delete-file'       c-addr u - wior        file       "delete-file"

`rename-file'       c-addr1 u1 c-addr2 u2 - wior        file-ext       "rename-file"
   Rename file c_addr1 u1 to new name c_addr2 u2

`read-file'       c-addr u1 wfileid - u2 wior        file       "read-file"

`read-line'       c_addr u1 wfileid - u2 flag wior         file       "read-line"

`key-file'       wfileid - c        gforth       "paren-key-file"
   Read one character c from wfileid.  This word disables buffering for
wfileid.  If you want to read characters from a terminal in
non-canonical (raw) mode, you have to put the terminal in non-canonical
mode yourself (using the C interface); the exception is `stdin': Gforth
automatically puts it into non-canonical mode.

`key?-file'       wfileid - f        gforth       "key-q-file"
   f is true if at least one character can be read from wfileid without
blocking.  If you also want to use `read-file' or `read-line' on the
file, you have to call `key?-file' or `key-file' first (these two words
disable buffering).

`write-file'       c-addr u1 wfileid - wior        file       "write-file"

`write-line'       c-addr u fileid - ior         file       "write-line"

`emit-file'       c wfileid - wior        gforth       "emit-file"

`flush-file'       wfileid - wior        file-ext       "flush-file"

`file-status'       c-addr u - wfam wior        file-ext       "file-status"

`file-position'       wfileid - ud wior        file       "file-position"

`reposition-file'       ud wfileid - wior        file       "reposition-file"

`file-size'       wfileid - ud wior        file       "file-size"

`resize-file'       ud wfileid - wior        file       "resize-file"

`slurp-file'       c-addr1 u1 - c-addr2 u2         gforth       "slurp-file"
   C-ADDR1 U1 is the filename, C-ADDR2 U2 is the file's contents

`slurp-fid'       fid - addr u         gforth       "slurp-fid"
   ADDR U is the content of the file FID

`stdin'       - wfileid        gforth       "stdin"
   The standard input file of the Gforth process.

`stdout'       - wfileid        gforth       "stdout"
   The standard output file of the Gforth process.

`stderr'       - wfileid        gforth       "stderr"
   The standard error output file of the Gforth process.

