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

This manual is for Gforth (version 0.7.9_20260415, April 15, 2026), a
fast and portable implementation of the Standard Forth language.  It
serves as reference manual, but it also contains an introduction to
Forth and a Forth tutorial.

   Authors: Bernd Paysan, Anton Ertl, Gerald Wodni, Neal Crook, David
Kuehling, Jens Wilke Copyright © 1995, 1996, 1997, 1998, 2000, 2003,
2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015,
2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024,2025 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.9_20260415, April 15, 2026), a
fast and portable implementation of the Standard Forth language.  It
serves as reference manual, but it also contains an introduction to
Forth and a Forth tutorial.

   Authors: Bernd Paysan, Anton Ertl, Gerald Wodni, Neal Crook, David
Kuehling, Jens Wilke Copyright © 1995, 1996, 1997, 1998, 2000, 2003,
2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015,
2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024,2025 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 Standard Forth
* Literals in source code::
* Words::                       Forth words available in Gforth
* Error messages::              How to interpret them
* Tools::                       Programming tools
* Standard 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
* MINOS2::                      The GUI library
* 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 --

Goals of Gforth

* Stability Goals::

Gforth Environment

* Invoking Gforth::             Getting in
* Leaving Gforth::              Getting out
* Help on Gforth::              Getting help
* Command-line editing::        Gforth's command-line editor
* Environment variables::       that affect how Gforth starts up
* Gforth Files::                What gets installed and where
* Gforth in pipes::             Piping into or out of Gforth
* Startup speed::               When 14ms 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 Standard 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::

Literals in source code

* Integer and character literals::
* Floating-point number and complex literals::
* String and environment variable literals::
* Literals for tokens and addresses::
* Disambiguating recognizers::

Forth Words

* Notation::
* Case insensitivity::
* Comments::
* Boolean Flags::
* Arithmetic::
* Floating-point comparisons::
* Stack Manipulation::
* Memory::
* Strings and Characters::
* Control Structures::
* Defining Words::
* Structures::
* User-defined Stacks::
* Interpretation and Compilation Semantics::
* Tokens for Words::
* Compiling words::
* The Text Interpreter::
* The Input Stream::
* Word Lists::
* Number conversion::
* Environmental Queries::
* Files::
* Blocks::
* Other I/O::
* OS command line arguments::
* Locals::
* Object-oriented Forth::
* Closures::
* Regular Expressions::
* Programming Tools::
* Multitasker::
* C Interface::
* Assembler and Code Words::
* Carnal words::
* Passing Commands to the OS::
* Keeping track of Time::
* Miscellaneous Words::

Arithmetic

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

Stack Manipulation

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

Memory

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

Heap allocation

* Memory blocks and heap allocation::
* Growable memory buffers::

Strings and Characters

* String representations::
* Xchars and Unicode::
* String and character literals::
* String words::
* $tring words::
* Internationalization and localization::
* Substitute::
* Counted string words::

Control Structures

* Selection::                   IF ... ELSE ... THEN
* General Loops::               BEGIN ...
* Counted Loops::               DO
* General loops with multiple exits::
* General control structures with CASE::
* Arbitrary control structures::
* Calls and returns::
* Exception Handling::

Defining Words

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

User-defined Defining Words

* User-defined defining words with colon definitions::
* User-defined defining words using CREATE::
* CREATE..DOES> applications::
* CREATE..DOES> details::
* Advanced does> usage example::
* Words with user-defined TO etc.::
* User-defined compile-comma::
* Creating from a prototype::
* Making a word current::
* Const-does>::

Structures

* Standard Structures::
* Value-Flavoured and Defer-Flavoured Fields::
* Structure Extension::
* Gforth structs::

Interpretation and Compilation Semantics

* Where are interpretation semantics used?::
* Where are compilation semantics used?::
* Which semantics do existing words have?::
* What semantics do normal definitions have?::
* How to define immediate words::
* How to define combined words::

Tokens for Words

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

Compiling words

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

The Text Interpreter

* Input Sources::
* Interpret/Compile states::
* Interpreter Directives::
* Recognizers::
* Text Interpreter Hooks::

Recognizers

* Default recognizers::
* Recognizer order::
* Defining recognizers::
* Defining translation tokens::
* Performing translation actions::

Word Lists

* Why use word lists?::
* Wordlist and vocabulary usage::

Number conversion

* Base and integer decimal point::
* String to number conversion::
* Integer to string conversion::
* Floating-point to string conversion::

Files

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

Search Paths

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

Other I/O

* Simple numeric output::       Predefined formats
* Floating-point output::
* Miscellaneous output::
* Displaying characters and strings::  Other stuff
* Terminal output::             Cursor positioning etc.
* Single-key input::
* String input from the terminal::
* Pipes::                       How to create your own pipes
* CSV reading and writing::

Terminal output

* Color output::
* Color themes::

Locals

* Gforth locals::
* Standard Forth locals::

Gforth locals

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

Object-oriented Forth

* Why object-oriented programming?::
* Object-Oriented Terminology::
* Objects::
* OOF::
* Mini-OOF::
* Mini-OOF2::
* 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::

The ‘mini-oof.fs’ model

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

Closures

* How do I read outer locals?::
* How do I write outer locals?::

Programming Tools

* Text interpreter status::
* Locating source code definitions::  and editing
* Locating uses of a word::     ‘where’.
* Locating exception source::   Examining backtraces.
* Examining compiled code::     ‘see’ and friends.
* Examining data::              Stacks and Memory.
* Forgetting words::            Usually before reloading.
* Debugging::                   By inserting ‘~~’ tracers.
* Assertions::                  Making your programs self-checking.
* Singlestep Debugger::         Executing your program word by word.
* Code Coverage::               Measure execution frequency.

Multitasker

* Pthreads::                    Native Unix multitasker
* Cilk::                        Implements Cilk-like spawn+sync

Pthreads

* Basic multi-tasking::
* Task-local data::
* Semaphores::
* Hardware operations for multi-tasking::
* Message queues::

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::
* Automated interface generation using SWIG::
* Migrating the C interface from earlier Gforth::

Assembler and Code Words

* Assembler Definitions::       Definitions in assembly language
* Common Assembler::            Assembler Syntax
* Common Disassembler::
* 386 Assembler::               Deviations and special cases
* AMD64 Assembler::
* 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

Carnal words

* Header fields::
* Header methods::
* Threading Words::

Tools

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

Standard 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::

MINOS2, a GUI library

* MINOS2 object framework::
* MINOS2 tutorial::

MINOS2 object framework

* actor methods::
* widget methods::

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
Standard Forth.  This can be split into several subgoals:

   • Gforth should conform to the 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 Forth-94 (ANS Forth) and Forth-2012 standards.

   We have changed some of the internal data structures (in particular,
the headers) over time, so Gforth does not provide the stability of
implementation details that we originally aimed for; they were too
constraining for a long-term project like Gforth.  However, we still aim
for a high level of stability.

   Gforth is quite popular and is treated by some like a de-facto
standard.

   It has some similarities to and some differences from previous
models.

   It has powerful features, and the version 1.0 indicates that it can
do everything (and more) that we originally envisioned.  That does not
mean that we will stop development.

   We certainly have achieved and exceeded our execution speed goals
(*note Performance::)(1).

   Gforth is free and available on many platforms.

* Menu:

* Stability Goals::

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

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


File: gforth.info,  Node: Stability Goals,  Prev: Goals,  Up: Goals

1.1 Stability Goals
===================

Programs that work on earlier versions of Gforth should also work on
newer versions.  However, there are some caveats:

   Internal data structures (including the representation of code) of
Gforth may change between versions, unless they are documented.

   Moreover, we only feel obliged to keep standard words (i.e., with
standard wordset names) and words documented as stable Gforth extensions
(with wordset name ‘gforth’ or ‘gforth-<version>’, *note Notation::).
Other words may be removed in newer releases.

   In particular, you may find a word by using ‘locate’ or otherwise
inspecting Gforth's source code.  You can see the wordset in a comment
right after the stack-effect comment.  E.g., in

     : execute-parsing ( ... addr u xt -- ... ) \ gforth

   the wordset is ‘gforth’.

   If there is no wordset for a word, it is an internal factor and may
be removed in a future version.  If the wordset is
‘gforth-experimental’, ‘gforth-internal’, or ‘gforth-obsolete’, the word
may also be removed in a future version.  In particular,
‘gforth-experimental’ indicates that this is a supported word that we do
not consider stable yet; ‘gforth-obsolete’ indicates an intent to remove
the word in the next version; and ‘gforth-internal’ (or no wordset)
indicates that we may remove the word as soon as we no longer use it in
Gforth.

   If you want to use a particular word that is not marked as stable,
please let us know, and we will consider to add the word as stable word
(or we may suggest an alternative to using this word).


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
* Help on Gforth::              Getting help
* Command-line editing::        Gforth's command-line editor
* Environment variables::       that affect how Gforth starts up
* Gforth Files::                What gets installed and where
* Gforth in pipes::             Piping into or out of Gforth
* Startup speed::               When 14ms 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 ...’.

‘--no-0rc’
     Do not load ‘~/.config/gforthrc0’ nor the file specified by
     ‘GFORTH_ENV’.

‘--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 and the working directory
     ‘.’ (e.g., ‘/usr/local/share/gforth/0.2.0:.’).  A path is given as
     a list of directories, separated by ‘:’ (previous versions had ‘;’
     for other OSes, but since Cygwin now only accepts
     ‘/cygdrive/<letter>’, and we dropped support for OS/2 and MS-DOS,
     it is ‘:’ everywhere).

‘--dictionary-size size’
‘-m size’
     Allocate size space for the Forth dictionary space instead of using
     the default specified in the image (default: 8M). The size
     specification for this and subsequent options consists of an
     integer and a unit (e.g., ‘1G’).  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 (default: 16K).

‘--return-stack-size size’
‘-r size’
     Allocate size space for the return stack instead of using the
     default specified in the image (default: 15K).

‘--fp-stack-size size’
‘-f size’
     Allocate size space for the floating point stack instead of using
     the default specified in the image (default: 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 (default: 14.5K).

‘--map_32bit’
     Allocate the dictionary and some other areas in the lower 2GB of
     the address space, if possible.  The purpose of this option is
     debugging convenience.

‘--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

‘--diag’
‘-D’
     Checks for and reports some performance problems.

‘--debug’
     Print some information useful for debugging on startup.

‘--debug-mcheck’
     Try to find and report erroneous usage of ‘allocate’, ‘free’, and
     the C functions ‘malloc()’, ‘free()’, etc.

‘--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 [number]’
     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.  The optional number set the
     number of signals to be handled; only the last one will cause
     Gforth to exit.

‘--ignore-async-signals’
     Ignore asynchronous signals (e.g., ‘SIGINT’ generated with
     ‘Ctrl-c’).

2.1.1 Code generation options
-----------------------------

‘--no-dynamic’
‘--dynamic’
     Disable or enable dynamic superinstructions with replication (*note
     Dynamic Superinstructions::).  Default enabled.

‘--no-dynamic-image’
     Disable dynamic native-code generation when loading the Gforth
     image, but generate dynamic native code afterwards.  This option is
     useful when debugging Gforth's code generator.

‘--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 primitive 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.

‘--opt-ip-updates=n’
     Set the level of IP-update optimization (default: 31 (7+3*8)).  n
     is computed as n1+8*n2.

     n1 indicates the use of IP-update optimization in straight-line
     code: 0 means no IP-update optimization, 1 combines IP-update
     optimizations of primitives without inline arguments, 2 also
     eliminates the dead IP updates of ‘;s’, ‘execute-;s’ and
     fast-throw, >2 eliminates the IP updates in front of several
     frequently-used primitives with inline arguments.

     n2 is the number of ip-updates that can replace a load in a
     backwards or unconditional branch; for conditional forward branches
     only n2/2 ip-updates replace a load (to avoid too many additional
     updates in the fall-through path).

‘--code-block-size=size’
     Size of native-code blocks (default: 2M). Gforth allocates as many
     blocks of this size as necessary.

‘--print-metrics’
     On exit from Gforth: Print 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.

‘--print-prims’
     When exiting GforthL: Print the primitives with static usage
     counts.  E.g., one line might look like:

          ?branch           1-1  0   21 1575   73 0x5573e4048c33 len= 4+ 25+ 3 send=0

     The columns are, from left to right: name of the primitive,
     stack-caching state transition (from a state with 1 stack item in a
     register to the same state in the example), IP offset for this
     version of the primitive (0 for most primitives, but, e.g., for
     ‘?branch’ there are also versions with 0-zero offset), index of the
     primitive, index of the corresponding branch-to-IP variant (in case
     of a branch), static number of occurrences of the primitive in the
     loaded/compiled code, address of the code of the primitive (or
     ‘(nil)’ if the primitive is not relocatable), length of the parts
     of this code: ip-update+main+dispatch, and whether the primitive
     ends a superblock (i.e., an unconditional branch or the like).

‘--print-nonreloc’
     When starting Gforth: Print the non-relocatable primitives.

‘--print-sequences’
     When loading the image: For each superblock in the image, print the
     sequence of primitives.

‘--tpa-noautomaton’
‘--tpa-noequiv’
     These options are about using an automaton for speeding up startup
     and compilation, in particular the shortest-path algorithm used for
     selecting static superinstructions and stack caching variants; tpa
     stands for for "tree-parsing automaton" (although we only have
     sequences, not trees).  In the ‘gforth’ engine the default is to
     use an automaton with state equivalence (state equivalence reduces
     the number of states compared to having one state for every
     sequence prefix), which is the fastest option and requires the
     least memory.

     With static superinstructions the automaton does not work
     correctly, so Gforth falls back to ‘--tpa-noautomaton’ in that case
     unless you ask for ‘--tpa-noequiv’ (‘gforth-fast’ uses static
     superinstructions and therefore ‘--tpa-noautomaton’ by default).

     ‘--tpa-noequiv’ turns off state equivalence, which costs memory and
     compiles a little slower than using an automaton.

     ‘--tpa-noautomaton’ turns off using the automaton.  This consumes
     quite a bit more compile time, and should in theory use less memory
     than using an automaton, but apparently there is a bug in Gforth,
     and it consumes more memory.

     The following shows the startup speed and memory consumption of
     Gforth 0.7.9_20240821 run with ‘gforth-fast -e bye’ (plus the
     options given in the table) on a Core-i5 6600K (Skylake):

           cycles    instructions KB(RSS) other options
          23_309_239  43_534_167   9228   --ss-number=0
          26_399_456  51_895_687  11316   --ss-number=0 --tpa-noequiv
          40_427_672  93_709_354  10988   --ss-number=0 --tpa-noautomaton
          27_599_969  53_126_621  11320
          27_732_944  53_128_381  11320   --tpa-noequiv
          42_960_520  95_466_840  11044   --tpa-noautomaton

‘--tpa-trace’
     This option produces data about the number of states generated
     during startup and compilation.

2.1.2 Image-specific options of ‘gforth.fi’
-------------------------------------------

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 there is an uncaught exception while
processing image options, Gforth will exit with a non-zero exit code.
This is how you run scripts in Gforth.

   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.

   On startup, before processing any of the image options, the user
initialization file is included, if it exists.  The user initialization
file is ‘~/.config/gforthrc0’, or, if the environment variable
‘GFORTH_ENV’ is set, it contains the name of the user initialization
file.  You can suppress loading this file with by setting ‘GFORTH_ENV’
to ‘off’, or with the option ‘--no-0rc’.

   After processing all the image options and just before printing the
boot message, the user initialization file ‘~/.config/gforthrc’ from
your home directory is included, unless the option ‘--no-rc’ is given.

   Warning levels can be set with

‘-W’
     Turn off warnings

‘-Won’
     Turn on warnings (level 1)

‘-Wall’
     Turn on beginner warnings (level 2)

‘-Wpedantic’
     Turn on pedantic warnings (level 3)

‘-Werror’
     Turn warnings into errors (level 4)


File: gforth.info,  Node: Leaving Gforth,  Next: Help on Gforth,  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
   Exit Gforth (with exit status 0).


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

2.3 Help on Gforth
==================

Gforth has a simple, text-based online help system.

‘help’ ( "rest-of-line" -  ) gforth-1.0
   If no name is given, show basic help.  If a documentation node name
is given followed by "::", show the start of the node.  If the name of a
word is given, show the documentation of the word if it exists, or its
source code if not.  If something else is given that is recognized,
shows help on the recognizer.  You can then use the same keys and
commands as after using ‘locate’ (*note Locating source code
definitions::).

‘authors’ ( -  ) gforth-1.0
   show the list of authors

‘license’ ( -  ) gforth-0.2
   print the license statement


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

2.4 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
     lines from the history buffer.
   • ‘Ctrl-n’ ("next") (or down-arrow) to recall successively newer
     lines from the history buffer.  If you moved to an older line
     earlier and gave it to Gforth for text-interpretation, asking for
     the next line as the first editing command gives you the next line
     after the one you selected last time.
   • ‘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
‘$HOME/.local/share/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.5 Environment variables
=========================

Gforth uses these environment variables:

   • ‘GFORTHHIST’ - (Unix systems only) specifies the path for the
     history file ‘.gforth-history’.  Default:
     ‘$HOME/.local/share/gforth/history’.

   • ‘GFORTHPATH’ - specifies the path used when searching for the
     gforth image file and for Forth source-code files (usually ‘.’, the
     current working directory).  Path separator is ‘:’, a typical path
     would be ‘/usr/local/share/gforth/1.0:.’.

   • ‘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 (*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.6 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.7 Gforth in pipes
===================

Gforth can be used in pipes created elsewhere (described in the
following).  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.8 Startup speed
=================

If Gforth is used for CGI scripts or in shell scripts, its startup speed
may become a problem.  On a 3GHz Core 2 Duo E8400 under 64-bit Linux
2.6.27.8 with libc-2.7, ‘gforth-fast -e bye’ takes 13.1ms user and 1.2ms
system time (‘gforth -e bye’ is faster on startup with about 3.4ms user
time and 1.2ms system time, because it subsumes some of the options
discussed below).

   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). Note that the first steps below
improve the startup time at the cost of run-time (including
compile-time), so whether they are profitable depends on the balance of
these times in your application.

   An easy step that influences Gforth startup speed is the use of a
number of options that increase run-time, but decrease image-loading
time.

   The first of these that you should try is ‘--ss-number=0
--ss-states=1’ because this option buys relatively little run-time
speedup and costs quite a bit of time at startup.  ‘gforth-fast
--ss-number=0 --ss-states=1 -e bye’ takes about 2.8ms user and 1.5ms
system time.

   The next option is ‘--no-dynamic’ which has a substantial impact on
run-time (about a factor of 2-4 on several platforms), but still makes
startup speed a little faster: ‘gforth-fast --ss-number=0 --ss-states=1
--no-dynamic -e bye’ consumes about 2.6ms user and 1.2ms system time.

   If the script you want to execute contains a significant amount of
code, it may be profitable to compile it into the image to avoid the
cost of compiling it at startup 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 Standard-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 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 out 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
================

Forth does not prevent you from shooting yourself in the foot.  Let's
try a few ways to crash Gforth:

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

   The last two examples are guaranteed to destroy important 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’).

   You will find out later what these lines do and then you will get an
idea why they produce crashes.

   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 contents 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 element of the stack 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 is 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; also, you need to include the
     exponent part in literal FP numbers, *note Floating Point
     Tutorial::).

   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 operation, 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 omit the comment part (‘-- b a’):

     : 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=’; indeed, it is more common to
use ‘0=’ instead of ‘invert’ for canonical flags).

     1 0= .
     1 0<> .

   While you can use ‘if’ without ‘0<>’ to test for zero/non-zero, you
sometimes need to use ‘0<>’ when combining zero/non-zero values with
‘and or xor’ because of their bitwise nature.  The simplest, least
error-prone, and probably clearest way is to use ‘0<>’ in all these
cases, but in some cases you can use fewer ‘0<>’s.  Here are some stack
effects, where fc represents a canonical flag, and fz represents
zero/non-zero (every fc also works as fz):

     or  ( fz1 fz2 -- fz3 )
     and ( fz1 fc  -- fz2 )
     and ( fc  fz1 -- fz2 )

   So, if you see code like this:

     ( n1 n2 ) 0<> and if

   This tests whether n1 and n2 are non-zero and if yes, performs the
code after ‘if’; it treats n1 as zero/non-zero and uses ‘0<>’ to convert
n2 into a canonical flag; the ‘and’ then produces an fz, which is
consumed by the ‘if’.

   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 a number of combinations/abbreviations, like ‘1+’.
However, ‘2/’ is not one of them; it shifts its argument right by one
bit (arithmetic shift right), and viewed as division that always rounds
towards negative infinity (floored division), like Gforth's ‘/’ (since
Gforth 0.7), but unlike ‘/’ in many other Forth systems.

     -5 2 / . \ -2 or -3
     -5 2/ .  \ -3

   ‘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 zero, execution continues at the
‘begin’, otherwise after the ‘until’.

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

   Reference: *note General 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 element 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
from the stack into this cell and ‘@’ (fetch) to load the value from
memory onto the stack:

     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 variable-like word ‘v2’ and reserves 20 uninitialized
cells; the address pushed by ‘v2’ points to the start of these 20 cells
(*note CREATE::).  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.

   The difference between ‘variable’ and ‘create’ is that ‘variable’
allots a cell, and that you cannot allot additional memory to a variable
in Standard Forth.

   You can also reserve memory without creating a new word:

     here 10 cells allot .
     here .

   The first ‘here’ pushes the start address of the memory area, the
second ‘here’ the address after the dictionary area.  You should store
the start address 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
(https://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
(https://docs.oracle.com/cd/E19957-01/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’, longer as ‘+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.  Examples:

     2e 2e f+ f.

   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 in conformance with
Forth-2012.  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
     (https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.111.4448&rep=rep1&type=pdf),
     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::.


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. Open an ASCII text file for input
  2. Open a file for output
  3. Read input file until string matches (or some other condition is
     met)
  4. Write some lines from input (modified or not) to output
  5. Close 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
       drop ;

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

   For some words, such as ‘if’, using their interpretation semantics is
usually a mistake, so we mark them as ‘compile-only’, and you get a
warning when you interpret them.

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

     : flop ( -- )
      flip ;
     flop

   In this example, first the interpretation semantics of ‘flip’ is used
(and you get a warning); the second use of ‘flip’ uses the compilation
semantics (and you get no warning).  You can also see in this example
that compile-only is a property that is evaluated at text interpretation
time, not at run-time.

   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
these 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 foo1

   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 foo1

   ‘'’ 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 (https://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 arrays, 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’ (which you can use instead of ‘THEN’) 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 row of one
matrix with every column of the other matrix.  You can generate the code
for one row 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 -- )’ which 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: Literals in source code,  Prev: Tutorial,  Up: Top

4 An Introduction to Standard 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 Standard 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 to
     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 numbers 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 (data and floating point stack) and removes any
entries that may have been left on them 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 constitutes 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 precedence 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 is to prevent 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.

   Certain kinds of words do not 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 its
     “execution token” (*note 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 by its “compilation token”
     (*note 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 always 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” means that the text interpreter
produces a warning when encountering this word in interpretation state;
ticking the word (with ‘'’ or ‘[']’ also produces a warning.

   It is never necessary to use ‘compile-only’ (and it is not even part
of Standard 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 warning.

   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’) is 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 is 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 depends 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 Standard 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 THEN ?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 exercises 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: Literals in source code,  Next: Words,  Prev: Introduction,  Up: Top

5 Literals in source code
*************************

* Menu:

* Integer and character literals::
* Floating-point number and complex literals::
* String and environment variable literals::
* Literals for tokens and addresses::
* Disambiguating recognizers::


File: gforth.info,  Node: Integer and character literals,  Next: Floating-point number and complex literals,  Prev: Literals in source code,  Up: Literals in source code

5.1 Integer and character literals
==================================

To push an integer number on the data stack, you write the number in
source code, e.g., ‘123’.  You can prefix the digits with ‘-’ to
indicate a negative number, e.g.  ‘-123’.  This works both inside colon
definitions and outside.  The number is interpreted according to the
value in ‘base’ (*note Base and integer decimal point::).  The digits
are ‘0’ to ‘9’ and ‘a’ (decimal 10) to ‘z’ (decimal 35), but only digits
smaller than ‘base @’ are recognized.  The conversion is
case-insensitive, so ‘A’ and ‘a’ are the same digit.

   You can make the base explicit for the number by using a prefix:

   • ‘#’ - decimal
   • ‘%’ - binary
   • ‘$’ - hexadecimal
   • ‘&’ - decimal (non-standard)
   • ‘0x’ - hexadecimal, if base<33 (non-standard).

   For combinations including base-prefix and sign, the standard order
is to have the base-prefix first (e.g., ‘#-123’); Gforth supports both
orders.

   You can put a decimal point ‘.’ at the end of a number (or,
non-standardly, anywhere else except before a prefix) to get a
double-cell integer (e.g., ‘#-123.’ or ‘#-.123’ (the same number)).

   By default (‘.-is-dcell?’ pushes true), prefixless numbers with a
decimal point (e.g., ‘-123.’) are also recognized as double-cell
integers.  This is confusing to users experienced in other programming
language.  To clear up the confusion early, Gforth warns of such usage;
to avoid the warnings, the best approach is to always write double
numbers with a base prefix (e.g., ‘#-123.’).  This also works in the
setting ‘0 to .-is-dcell?’.

   Here are some examples, with the equivalent decimal number shown
after in braces:

   ‘$-41’ (-65), ‘%1001101’ (205), ‘%1001.0001’ (145, a double-precision
number), ‘#905’ (905), ‘$abc’ (2478), ‘$ABC’ (2478).

   You can get the numeric value of a (character) code point by
surrounding the character with ‘'’ (e.g., ‘'a'’).  The trailing ‘'’ is
required by the standard, but you can leave it away in Gforth.  Note
that this also works for non-ASCII characters.  For many uses, it is
more useful to have the character as a string rather than as a cell; see
below for the string syntax.


File: gforth.info,  Node: Floating-point number and complex literals,  Next: String and environment variable literals,  Prev: Integer and character literals,  Up: Literals in source code

5.2 Floating-point number and complex literals
==============================================

For floating-point numbers in Forth, you recognize them due to their
exponent.  I.e., by default ‘1.’ is a double-cell integer, and ‘1e0’ is
a floating-point number; the latter can be (and usually is) shortened to
‘1e’.  Both the significand (the part before the ‘e’ or ‘E’) and the
exponent may have signs (including ‘+’); the significand must contain at
least one digit and may contain a decimal point, the exponent can be
empty.  Floating-point numbers always use decimal base for both
significand and exponent, and are only recognized when the base is
decimal.  Examples are: ‘1e 1e0 1.e 1.e0 +1e+0’ (which all represent the
same number) ‘+12.E-4’.

   With the setting ‘0 to .-is-dcell?’, Gforth (since 1.0) does not
recognize prefixless numbers with a decimal point as double-cell
integers, but recognizes them as FP numbers instead.  Note that standard
Forth systems (such as the default setting of Gforth) behave
differently, so we recommend always using ‘e’ to signify FP numbers.

   A Gforth extension (since 1.0) is to write a floating-point number in
scaled notation: It can optionally have a sign, then one or more digits,
then use one of the mostly SI-defined scaling symbols (aka metric
prefixes) or ‘%’, and then optionally more digits.  Here's the full list
of scaling symbols that Gforth accepts:

   • ‘Q’ ‘e30’ quetta
   • ‘R’ ‘e27’ ronna
   • ‘Y’ ‘e24’ yotta
   • ‘Z’ ‘e21’ zetta
   • ‘X’ ‘e18’ exa (not ‘E’)
   • ‘P’ ‘e15’ peta
   • ‘T’ ‘e12’ tera
   • ‘G’ ‘e9’ giga
   • ‘M’ ‘e6’ mega
   • ‘k’ ‘e3’ kilo
   • ‘h’ ‘e2’ hecto
   • ‘d’ ‘e-1’ deci
   • ‘%’ ‘e-2’ percent (not ‘c’)
   • ‘m’ ‘e-3’ milli
   • ‘u’ ‘e-6’ micro (not ‘μ’)
   • ‘n’ ‘e-9’ nano
   • ‘p’ ‘e-12’ pico
   • ‘f’ ‘e-15’ femto
   • ‘a’ ‘e-18’ atto
   • ‘z’ ‘e-21’ zepto
   • ‘y’ ‘e-24’ yocto
   • ‘r’ ‘e-27’ ronto
   • ‘q’ ‘e-30’ quecto

   Unlike most of the rest of Gforth, scaling symbols are treated
case-sensitively.  Using the scaled notation is equivalent to using a
decimal point instead of the scaling symbol and appending the
exponential notation at the end.  Examples of scaled notation: ‘6k5’
(6500e) ‘23%’ (0.23e).

   In Gforth (since 1.0) you can input a complex number with
‘real+imaginaryi’, where both ‘real’ and ‘imaginary’ are strings that
are recognized as floating-point numbers.  E.g., ‘1e+2ei’.  This pushes
the values ‘1e’ and ‘2e’ on the floating-point stack, so one might just
as well have written ‘1e 2e’, but ‘1e+2ei’ makes the intent obvious.


File: gforth.info,  Node: String and environment variable literals,  Next: Literals for tokens and addresses,  Prev: Floating-point number and complex literals,  Up: Literals in source code

5.3 String and environment variable literals
============================================

In Gforth (since 1.0) you can input a string by surrounding it with ‘"’
(e.g.  ‘"abc"’, ‘"a b"’).  The result is the starting address and byte
(=char) count of the string on the data stack.

   You have to escape any ‘"’ inside the string with ‘\’ (e.g.,
‘"double-quote->\"<-"’).  In addition, this string syntax supports all
the ways to write control characters that are supported by ‘s\"’ (*note
String and character literals::).  A disadvantage of this string syntax
is that it is non-standard; for standard programs, use ‘s\"’ instead.

   In Gforth (since 1.0) you can input an environment variable by
surrounding its name with ‘${’...‘}’, e.g., ‘${HOME}’; the result is a
string descriptor on the data stack in the format described above.  This
is equivalent to ‘"HOME" getenv’, i.e., the environment variable is
resolved at run-time.


File: gforth.info,  Node: Literals for tokens and addresses,  Next: Disambiguating recognizers,  Prev: String and environment variable literals,  Up: Literals in source code

5.4 Literals for tokens and addresses
=====================================

Gforth (since 1.0) also recognizes the following literals:

   You can input an execution token (xt) of a word by prefixing the name
of the word with the backquote ‘`’ (e.g., ‘`dup’).  An advantage over
using ‘'’ or ‘[']’ is you do not need to switch between them when
copying and pasting code from inside to outside a colon definition or
vice versa.  A disadvantage is that this syntax is non-standard.

   You can input a name token (nt) of a word by prefixing the name of
the word with ‘``’ (e.g., ‘``dup’).  This syntax is also non-standard.

   You can input a body address of a word by surrounding it with ‘<’ and
‘>’ (e.g., ‘<spaces>’).  You can also input an address that is at a
positive offset from the body address (typically an address in that
body), by putting ‘+’ and a number (see syntax above) between the word
name and the closing ‘>’ (e.g., ‘<spaces+$15>’, ‘<spaces+-3>’).  You
will get the body address plus the number.  This feature exists to allow
copying and pasting the output of ‘...’ (*note Examining data::).

   In addition, by default Gforth recognizes words with ‘rec-name’ and
‘rec-scope’, and stores in or adds to value-flavoured words with
‘rec-to’, but these do not recognize literals, so they are discussed
elsewhere (*note Default recognizers::).


File: gforth.info,  Node: Disambiguating recognizers,  Prev: Literals for tokens and addresses,  Up: Literals in source code

5.5 Disambiguating recognizers
==============================

In some cases where two recognizers match the same string, you can
specify in Gforth (since 1.0) which recognizer you want to use, with
‘recognizer?string’, where ‘recognizer’ is the name of the recognizer
without the ‘rec-’ prefix, and ‘string’ is the string you want to
recognize.  E.g., ‘float?1.’ uses ‘rec-float’ to recognize a string that
would otherwise be recognized as a double-cell integer number (because
‘rec-number’ is earlier in the recognizer sequence than ‘rec-float’).


File: gforth.info,  Node: Words,  Next: Error messages,  Prev: Literals in source code,  Up: Top

6 Forth Words
*************

* Menu:

* Notation::
* Case insensitivity::
* Comments::
* Boolean Flags::
* Arithmetic::
* Floating-point comparisons::
* Stack Manipulation::
* Memory::
* Strings and Characters::
* Control Structures::
* Defining Words::
* Structures::
* User-defined Stacks::
* Interpretation and Compilation Semantics::
* Tokens for Words::
* Compiling words::
* The Text Interpreter::
* The Input Stream::
* Word Lists::
* Number conversion::
* Environmental Queries::
* Files::
* Blocks::
* Other I/O::
* OS command line arguments::
* Locals::
* Object-oriented Forth::
* Closures::
* Regular Expressions::
* Programming Tools::
* Multitasker::
* C Interface::
* Assembler and Code Words::
* Carnal words::
* Passing Commands to the OS::
* Keeping track of Time::
* Miscellaneous Words::


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

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

     Gforth has several stacks, in particular, the data stack, return
     stack and floating-point stack.  However, it uses a unified stack
     effect notation, where one stack effect description describes all
     three stack effects, and the name of the item indicates which stack
     the item is on: floating-point stack items start with r.  Return
     stack items are prefixed with R:, but are otherwise the same as
     data stack items.  E.g., in the stack effect ‘( w1 w2 -- R:w1 R:w2
     )’ w1 is a cell on the data stack, and R:w1 is a cell on the return
     stack with the same value.  So a unified stack effect

          ( r1 n1 R:n2 -- R:n3 n4 r2 )

     is equivalent to the separated stack effect notation

          ( n1 -- n4 ) ( R: n2 -- n3 ) ( F: r1 -- r2 )

     The name of a stack item describes the type and/or the function of
     the item.  See below for a discussion of the types.

     Words generally have different stack effects in different contexts.
     If only one stack effect is shown, it's the stack effect for the
     execution/interpretation semantics.(1)  The stack effect of default
     compilation semantics is ‘( -- )’ and is not shown.

     The stack-effects of non-default compilation semantics are shown if
     they are other than ‘( -- )’.  Such words usually also have a
     run-time semantics, and their stack effects are then shown as in
     this example

          ; ( compilation colon-sys -- ; run-time nest-sys -- )

     Further stack effects, such as those of defined words, of passed
     xts, are shown in the description part of the glossary entry.

     Also note that in code templates or examples there can be comments
     in parentheses that display the stack picture at this point; there
     is no ‘--’ in these places, because there is no before-after
     situation.

PRONUNCIATION
     How the word is pronounced.

WORDSET
     The wordset specifies if a word has been standardized (indicated by
     a capitalized wordset name), it is an environmental query string
     (indicated by "environment"), or if it is a Gforth-specific word
     (lower case).

     The Forth standard is divided into several word sets.  In theory, a
     standard system need not support all of them, but in practice,
     serious systems on non-tiny machines support almost all
     standardized words (some systems require explicit loading of some
     word sets, however), so it does not increase portability in
     practice to be parsimonious in using word sets.

     For the Gforth-specific words, we have the following categories:

     ‘gforth’
     ‘gforth-<version>’
          We intend to permanently support this word in Gforth and it
          has been available since Gforth <version> (possibly not as
          stable word at that time).

          You see ‘gforth’ in the source code (e.g., when using
          ‘locate’), and ‘gforth-<version>’ in the documentation (e.g.,
          when using ‘help’).  So if you want to know since which Gforth
          version a word is available, use ‘help word’.

     ‘library’
          The word belongs to a library that is independent of Gforth,
          but is delivered with Gforth and documented in this manual.
          Gforth 1.0 includes libraries with the following wordset
          names: mini-oof mini-oof2 minos2 minos2-bidi objects oof
          regexp-cg regexp-pattern regexp-replace cilk

     ‘gforth-experimental’
          This word is available in the present version and may turn
          into a stable word or may be removed in a future release of
          Gforth.  Feedback welcome.

     ‘gforth-internal’
          This word is an internal factor, not a supported word, and it
          may be removed in a future release of Gforth.  If you see a
          word in the source code (e.g., with ‘locate’) without a
          wordset, that word is also an internal factor.

     ‘gforth-obsolete’
          This word will be removed in a future release of Gforth.

DESCRIPTION
     A description of the behaviour of the word.

   The type of a stack item is specified by the prefix of the name:

‘f’
     Boolean flags, i.e.  ‘false’ or ‘true’.
‘c’
     Char
‘w’
‘x’
     Cell, can contain an integer or an address
‘n’
     signed integer
‘u’
     unsigned integer
‘d’
     signed double-cell integer
‘ud’
     unsigned double-cell integer
‘r’
     Float (on the FP stack)
‘addr’
     Address without further information
‘a-’
     Cell-aligned address
‘c-’
     Char-aligned address, address used to point to a character or start
     of a string.
‘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
‘nt’
     Name 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.
‘"’
     String in the input stream (not on the stack), typically
     space-delimited.
‘'’
     String in the input stream, delimited by the last character before
     the closing ‘'’.  E.g., ‘'ccc"'’ indicates a string in the input
     stream that is terminated by ‘"’.

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

   (1) Gforth 1.0 does not make a difference between interpretation and
execution semantics.


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

6.2 Case insensitivity
======================

Gforth is case-insensitive for ASCII characters and case-sensitive for
non-ASCII characters.  I.e., you can invoke Standard words using upper,
lower or mixed case.

   For now, Standard Forth only requires implementations to recognise
Standard words when they are typed entirely in upper case.  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 ‘cs-wordlist’s
(case-sensitive wordlists, *note Word Lists::).


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

6.3 Comments
============

Forth supports two styles of comment; the in-line comment starting with
‘(’ and ending with ‘)’, and the comment to the end of the line line
starting with ‘\’.  Don't forget the space after the starting word.

‘(’ ( 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 until the end of line: parse and discard all remaining
characters in the parse area, except while ‘load’ing from a block: while
‘load’ing from a block, parse and discard all remaining characters in
the 64-byte line.

‘\G’ ( compilation 'ccc<newline>' - ; run-time -  ) gforth-0.2 "backslash-gee"
   Equivalent to ‘\’.  Used right below the start of a definition to
describe the behaviour of a word.  In Gforth's source code these
comments are those that are then inserted in the documentation.


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

6.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
   ‘Constant’ - f is a cell with all bits set.

‘false’ ( - f  ) core-ext
   ‘Constant’ - f is a cell with all bits clear.

‘on’ ( a-addr -  ) gforth-0.2
   Set the (value of the) variable at a-addr to ‘true’.

‘off’ ( a-addr -  ) gforth-0.2
   Set the (value of the) variable at a-addr to ‘false’.

‘select’ ( u1 u2 f - u ) gforth-1.0 "select"
   If f is false, u is u2, otherwise u1.


File: gforth.info,  Node: Arithmetic,  Next: Floating-point comparisons,  Prev: Boolean Flags,  Up: Words

6.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 -’.

* Menu:

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


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

6.5.1 Single precision
----------------------

By default, numbers in Forth are single-precision integers that are one
cell (a machine word, e.g., 64 bits on a 64-bit system) 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 Literals::.

   ‘+’, ‘1+’, ‘under+’, ‘-’, ‘1-’, ‘*’ are defined for signed operands,
but they also work for unsigned numbers.  For division words see *note
Integer division::.

‘+’ ( n1 n2 - n ) core "plus"

‘1+’ ( n1 - n2 ) core "one-plus"

‘under+’ ( n1 n2 n3 - n n2 ) gforth-0.3 "under-plus"
   add n3 to n1 (giving n)

‘-’ ( n1 n2 - n ) core "minus"

‘1-’ ( n1 - n2 ) core "one-minus"

‘*’ ( n1 n2 - n ) core "star"

‘negate’ ( n1 - n2 ) core "negate"

‘abs’ ( n - u ) core "abs"

‘min’ ( n1 n2 - n ) core "min"

‘max’ ( n1 n2 - n ) core "max"

‘umin’ ( u1 u2 - u ) gforth-0.5 "umin"

‘umax’ ( u1 u2 - u ) gforth-1.0 "umax"


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

6.5.2 Double precision
----------------------

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

   A double precision number is represented by a cell pair, with the
most significant cell at the top-of-stack (TOS). It is trivial to
convert an unsigned single to a double: simply push a ‘0’ onto the TOS.
Numbers are represented by Gforth using 2's complement arithmetic, so
converting a signed single to a (signed) double requires sign-extension
across the most significant cell.  This can be achieved using ‘s>d’.
You cannot convert a number from single-cell to double-cell without
knowing whether it represents an unsigned or a signed number.  By
contrast, in 2's complement arithmetic the conversion from double to
single just ‘drop’s the most significant cell, and ‘d>s’ just documents
the intent.

   ‘D+’ and ‘d-’ are defined for signed operands, but also work for
unsigned numbers.

‘s>d’ ( n - d  ) core "s-to-d"

‘d>s’ ( d - n  ) double "d-to-s"

‘d+’ ( ud1 ud2 - ud ) 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: Mixed precision,  Next: Integer division,  Prev: Double precision,  Up: Arithmetic

6.5.3 Mixed precision
---------------------

‘m+’ ( d1 n - d2 ) double "m-plus"

‘m*’ ( n1 n2 - d ) core "m-star"

‘um*’ ( u1 u2 - ud ) core "u-m-star"


File: gforth.info,  Node: Integer division,  Next: Two-stage integer division,  Prev: Mixed precision,  Up: Arithmetic

6.5.4 Integer division
----------------------

Below you find a considerable number of words for dealing with
divisions.  A major difference between them is in dealing with signed
division: Do the words support signed division?  Those with the ‘u’
prefix do not.

   Do signed division words round towards negative infinity (floored
division, suffix ‘F’), or towards 0 (symmetric division, suffix ‘S’).
The standard leaves the issue implementation-defined for most standard
words (‘/ mod /mod */ */mod m*/’).  Gforth implements these words as
floored (since Gforth 0.7), but there are systems that implement them as
symmetric.  There is only a difference between floored and symmetric
division if the dividend and the divisor have different signs, and the
dividend is not a multiple of the divisor.  The following table
illustrates the results:

                           floored          symmetric
     dividend divisor remainder quotient remainder quotient
         10      7           3   1              3   1
        -10      7           4  -2             -3  -1
         10     -7          -4  -2              3  -1
        -10     -7          -3   1             -3   1

   The common case where floored vs. symmetric makes a difference is
when dividends n1 with varying sign are divided by the same positive
divisor n2; in that case you usually want floored division, because then
the remainder is always positive and does not change sign depending on
the dividend; also, with floored division, the quotient always increases
by 1 when n1 increases by n2, while with symmetric division there is no
increase in the quotient for -n2<n1<n2 (the quotient is 0 in this
range).

   In any case, if you divide numbers where floored vs. symmetric makes
a difference, you should think about which variant is the right one for
you, and then use either the appropriately suffixed Gforth words, or the
standard words ‘fm/mod’ or ‘sm/rem’.

   In the following, "remainder" (symmetric) has the same sign as the
dividend or is 0, while "modulus" (floored) has the same sign as the
divisor or is 0.

   The following words perform single-by-single-cell division:

‘/’ ( n1 n2 - n  ) core "slash"
   n=n1/n2

‘/s’ ( n1 n2 - n ) gforth-1.0 "slash-s"

‘/f’ ( n1 n2 - n ) gforth-1.0 "slash-f"

‘u/’ ( u1 u2 - u ) gforth-1.0 "u-slash"

‘mod’ ( n1 n2 - n  ) core
   n is the modulus of n1/n2

‘mods’ ( n1 n2 - n ) gforth-1.0 "mod-s"

‘modf’ ( n1 n2 - n ) gforth-1.0 "modf"

‘umod’ ( u1 u2 - u ) gforth-1.0 "umod"

‘/mod’ ( n1 n2 - n3 n4  ) core "slash-mod"
   n1=n2*n4+n3; n3 is the modulus, n4 the quotient.

‘/mods’ ( n1 n2 - n3 n4 ) gforth-1.0 "slash-mod-s"
   n1=n2*n4+n3; n3 is the remainder, n4 the quotient

‘/modf’ ( n1 n2 - n3 n4 ) gforth-1.0 "slash-mod-f"
   n1=n2*n4+n3; n3 is the modulus, n4 the quotient

‘u/mod’ ( u1 u2 - u3 u4 ) gforth-1.0 "u-slash-mod"
   u1=u2*u4+u3; u3 is the modulus, u4 the quotient

   The following words perform double-by-single-cell division with
single-cell results; these words are roughly as fast as the words above
on some architectures (e.g., AMD64), but much slower on others (e.g., an
order of magnitude on various ARM A64 CPUs).

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

‘um/mod’ ( ud u1 - u2 u3 ) core "u-m-slash-mod"
   ud=u3*u1+u2, 0<=u2<u1

‘du/mod’ ( d u - n u1 ) gforth-1.0 "du-slash-mod"
   d=n*u+u1, 0<=u1<u; PolyForth style mixed division

‘*/’ ( ( n1 n2 n3 - n4  ) core "star-slash"
   n4=(n1*n2)/n3, with the intermediate result being double

‘*/s’ ( n1 n2 n3 - n4 ) gforth-1.0 "star-slash-s"
   n4=(n1*n2)/n3, with the intermediate result being double

‘*/f’ ( n1 n2 n3 - n4 ) gforth-1.0 "star-slash-f"
   n4=(n1*n2)/n3, with the intermediate result being double

‘u*/’ ( u1 u2 u3 - u4 ) gforth-1.0 "u-star-slash"
   u4=(u1*u2)/u3, 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; n4
is the modulus, n5 the quotient.

‘*/mods’ ( n1 n2 n3 - n4 n5 ) gforth-1.0 "star-slash-mod-s"
   n1*n2=n3*n5+n4, with the intermediate result (n1*n2) being double; n4
is the remainder, n5 the quotient

‘*/modf’ ( n1 n2 n3 - n4 n5 ) gforth-1.0 "star-slash-mod-f"
   n1*n2=n3*n5+n4, with the intermediate result (n1*n2) being double; n4
is the modulus, n5 the quotient

‘u*/mod’ ( u1 u2 u3 - u4 u5 ) gforth-1.0 "u-star-slash-mod"
   u1*u2=u3*u5+u4, with the intermediate result (u1*u2) being double.

   The following words perform division with double-cell results; these
words are much slower than the words above.

‘ud/mod’ ( ud1 u2 - urem udquot  ) gforth-0.2 "ud-slash-mod"
   divide unsigned double ud1 by u2, resulting in a unsigned double
quotient udquot and a single remainder urem.

‘m*/’ ( d1 n2 u3 - dquot  ) double "m-star-slash"
   dquot=(d1*n2)/u3, with the intermediate result being
triple-precision.  In Forth-2012 u3 is only allowed to be a positive
signed number.

   You can use the environmental query ‘floored’ (*note Environmental
Queries::) to learn whether ‘/ mod /mod */ */mod m*/’ use floored or
symmetric division on the system your program is being loaded on;
alternatively, ‘-1 3 /’ also produces -1 on floored and 0 on symmetric
systems.

   One other aspect of the integer division words is that most of them
can overflow, and division by zero is mathematically undefined.  What
happens if you hit one of these conditions depends on the engine, the
hardware, and the operating system: The engine ‘gforth’ tries hard to
throw the appropriate error -10 (Division by zero) or -11 (Result out of
range), but on some platforms throws -55 (Floating-point unidentified
fault).  The engine ‘gforth-fast’ may produce an inappropriate throw
code (and error message), or may produce no error, just produce a bogus
value.  I.e., you should not bet on such conditions being thrown, but
for quicker debugging ‘gforth’ catches more and produces more accurate
errors than ‘gforth-fast’.


File: gforth.info,  Node: Two-stage integer division,  Next: Bitwise operations,  Prev: Integer division,  Up: Arithmetic

6.5.5 Two-stage integer division
--------------------------------

On most hardware, multiplication is significantly faster than division.
So if you have to divide many numbers by the same divisor, it is usually
faster to determine the reciprocal of the divisor once and multiply the
numbers with the reciprocal.  If you divide by a constant, Gforth
performs this optimization automatically.

   However, for cases where the divisor is not known during compilation,
Gforth provides words that allow you to implement this optimization
without to much fuss.

   Let's start with an example: You want to divide all elements of an
array of cells by the same number n.  A straightforward way to implement
this is:

     : array/ ( addr u n -- )
       -rot cells bounds u+do
         i @ over / i !
       1 cells +loop
       drop ;

   A possibly more efficient version looks like this:

     : array/ ( addr u n -- )
       {: | reci[ staged/-size ] :}
       reci[ /f-stage1m
       cells bounds u+do
         i @ reci[ /f-stage2m i !
       1 cells +loop ;

   This example first creates a local buffer ‘reci[’ with size
‘staged/-size’ for storing the reciprocal data.  Then ‘/f-stage1m’
computes the reciprocal of n and stores it in ‘reci[’.  Finally, inside
the loop ‘/f-stage2m’ uses the data in ‘reci[’ to compute the quotient.

   There are some limitations: Only positive divisors are supported for
‘/f-stage1m’; for ‘u/-stage1m’ you can use a divisor of 2 or higher.
You get an error if you try to use an unsupported divisor.  You must
initialize the reciprocal buffer for the floored second-stage words with
‘/f-stage1m’ and for the unsigned second-stage words with ‘u/-stage1m’.
You must not modify the reciprocal buffer between the first stage and
the second stage; basically, don't treat it as a memory buffer, but as
something that is only mutable by the first stage; the point of this
rule is that future versions of Gforth will not consider aliasing of
this buffer.

   Measurements show that staged division is not always beneficial:

     break  100 elem
     even   speedup  core
       7      2.09   Skylake (Core i5-6600K)
       -      0.94   Rocket Lake (Xeon E-2388G)
      40      1.09   Golden Cove (Core i3-1315U P-core)
       -      0.85   Gracemont (Core i3-1315U E-core)
       6      1.68   Zen2 (Ryzen 9 3900X)
       -      0.56   Zen3 (Ryzen 7 5800X)

   The words are:

‘staged/-size’ ( - u  ) gforth-1.0 "staged-slash-size"
   Size of buffer for ‘u/-stage1m’ or ‘/f-stage1m’.

‘/f-stage1m’ ( n a-reci -  ) gforth-1.0 "slash-f-stage1m"
   Compute the reciprocal of n and store it in the buffer a-reci of size
‘staged/-size’.  Throws an error if n<1.

‘/f-stage2m’ ( n1 a-reci - nquotient ) gforth-1.0 "slash-f-stage2m"
   Nquotient is the result of dividing n1 by the divisor represented by
a-reci, which was computed by ‘/f-stage1m’.

‘modf-stage2m’ ( n1 a-reci - umodulus ) gforth-1.0 "mod-f-stage2m"
   Umodulus is the remainder of dividing n1 by the divisor represented
by a-reci, which was computed by ‘/f-stage1m’.

‘/modf-stage2m’ ( n1 a-reci - umodulus nquotient ) gforth-1.0 "slash-mod-f-stage2m"
   Nquotient is the quotient and umodulus is the remainder of dividing
n1 by the divisor represented by a-reci, which was computed by
‘/f-stage1m’.

‘u/-stage1m’ ( u a-reci -  ) gforth-1.0 "u-slash-stage1m"
   Compute the reciprocal of u and store it in the buffer a-reci of size
‘staged/-size’.  Throws an error if u<2.

‘u/-stage2m’ ( u1 a-reci - uquotient ) gforth-1.0 "u-slash-stage2m"
   Uquotient is the result of dividing u1 by the divisor represented by
a-reci, which was computed by ‘u/-stage1m’.

‘umod-stage2m’ ( u1 a-reci - umodulus ) gforth-1.0 "u-mod-stage2m"
   Umodulus is the remainder of dividing u1 by the divisor represented
by a-reci, which was computed by ‘u/-stage1m’.

‘u/mod-stage2m’ ( u1 a-reci - umodulus uquotient ) gforth-1.0 "u-slash-mod-stage2m"
   Uquotient is the quotient and umodulus is the remainder of dividing
u1 by the divisor represented by a-reci, which was computed by
‘u/-stage1m’.

   Gforth currently does not support staged symmetrical division.

   You can recover the divisor from (the address of) a reciprocal with
‘staged/-divisor @’:

‘staged/-divisor’ ( addr1 - addr2  ) gforth-1.0 "staged-slash-divisor"
   Addr1 is the address of a reciprocal, addr2 is the address containing
the divisor from which the reciprocal was computed.

   This can be useful when looking at the decompiler output of Gforth: a
division by a constant is often compiled to a literal containing the
address of a reciprocal followed by a second-stage word.

   The performance impact of using these words strongly depends on the
architecture (does it have hardware division?)  and the specific
implementation (how fast is hardware division?), but just to give you an
idea about the relative performance of these words, here are the cycles
per iteration of a microbenchmark (which performs the mentioned word
once per iteration) on two AMD64 implementations; the norm column shows
the normal division word (e.g., ‘u/’), while the stg2 column shows the
corresponding stage2 word (e.g., ‘u/-stage2m’):

      Skylake              Zen2
     norm stg2           norm stg2
     41.3 15.8 u/        35.2 21.4 u/
     39.8 19.7 umod      36.9 25.8 umod
     44.0 25.3 u/mod     43.0 33.9 u/mod
     48.7 16.9 /f        36.2 22.5 /f
     47.9 20.5 modf      37.9 27.1 modf
     53.0 24.6 /modf     45.8 35.4 /modf
         227.2 u/stage1      101.9 u/stage1
         159.8 /fstage1       97.7 /fstage1


File: gforth.info,  Node: Bitwise operations,  Next: Numeric comparison,  Prev: Two-stage integer division,  Up: Arithmetic

6.5.6 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"

‘mux’ ( u1 u2 u3 - u ) gforth-1.0 "mux"
   Multiplex: For every bit in u3: for a 1 bit, select the corresponding
bit from u1, otherwise the corresponding bit from u2.  E.g., ‘%0011
%1100 %1010 mux’ gives ‘%0110’

‘lshift’ ( u1 u - u2 ) core "l-shift"
   Shift u1 left by u bits.

‘rshift’ ( u1 u - u2 ) core "r-shift"
   Shift u1 (cell) right by u bits, filling the shifted-in bits with
zero (logical/unsigned shift).

‘arshift’ ( n1 u - n2 ) gforth-1.0 "ar-shift"
   Shift n1 (cell) right by u bits, filling the shifted-in bits from the
sign bit of n1 (arithmetic shift).

‘dlshift’ ( ud1 u - ud2 ) gforth-1.0 "dlshift"
   Shift ud1 (double-cell) left by u bits.

‘drshift’ ( ud1 u - ud2 ) gforth-1.0 "drshift"
   Shift ud1 (double-cell) right by u bits, filling the shifted-in bits
with zero (logical/unsigned shift).

‘darshift’ ( d1 u - d2 ) gforth-1.0 "darshift"
   Shift d1 (double-cell) right by u bits, filling the shifted-in bits
from the sign bit of d1 (arithmetic shift).

‘2*’ ( n1 - n2 ) core "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 ‘/’ is symmetric on some systems, but ‘2/’
always floors).

‘d2*’ ( d1 - d2 ) double "d-two-star"
   Shift double-cell left by 1; also works on unsigned numbers

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

‘>pow2’ ( u1 - u2 ) gforth-1.0 "to-pow2"
   u2 is the lowest power-of-2 number with u2>=u1.

‘log2’ ( u - n ) gforth-1.0 "log2"
   N is the rounded-down binary logarithm of u, i.e., the index of the
first set bit; if u=0, n=-1.

‘pow2?’ ( u - f  ) gforth-1.0 "pow-two-query"
   f is true if and only if u is a power of two, i.e., there is exactly
one bit set in u.

‘ctz’ ( x - u  ) gforth-1.0 "c-t-z"
   count trailing zeros in binary representation of x

   Unlike most other operations, rotation of narrower units cannot
easily be synthesized from rotation of wider units, so using cell-wide
and double-wide rotation operations means that the results depend on the
cell width.  For published algorithms or cell-width-independent results,
you usually need to use a fixed-width rotation operation.

‘wrol’ ( u1 u - u2 ) gforth-1.0 "wrol"
   Rotate the least significant 16 bits of u1 left by u bits, set the
other bits to 0.

‘wror’ ( u1 u - u2 ) gforth-1.0 "wror"
   Rotate the least significant 16 bits of u1 right by u bits, set the
other bits to 0.

‘lrol’ ( u1 u - u2 ) gforth-1.0 "lrol"
   Rotate the least significant 32 bits of u1 left by u bits, set the
other bits to 0.

‘lror’ ( u1 u - u2 ) gforth-1.0 "lror"
   Rotate the least significant 32 bits of u1 right by u bits, set the
other bits to 0.

‘rol’ ( u1 u - u2 ) gforth-1.0 "rol"
   Rotate all bits of u1 left by u bits.

‘ror’ ( u1 u - u2 ) gforth-1.0 "ror"
   Rotate all bits of u1 right by u bits.

‘drol’ ( ud1 u - ud2 ) gforth-1.0 "drol"
   Rotate all bits of ud1 (double-cell) left by u bits.

‘dror’ ( ud1 u - ud2 ) gforth-1.0 "dror"
   Rotate all bits of ud1 (double-cell) right by u bits.


File: gforth.info,  Node: Numeric comparison,  Next: Floating Point,  Prev: Bitwise operations,  Up: Arithmetic

6.5.7 Numeric comparison
------------------------

All these comparison words produce -1 (all bits set) if the condition is
true, otherwise 0.  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-0.2 "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-0.2 "greater-or-equal"

‘0<’ ( n - f ) core "zero-less-than"

‘0<=’ ( n - f ) gforth-0.2 "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-0.2 "zero-greater-or-equal"

‘u<’ ( u1 u2 - f ) core "u-less-than"

‘u<=’ ( u1 u2 - f ) gforth-0.2 "u-less-or-equal"

‘u>’ ( u1 u2 - f ) core-ext "u-greater-than"

‘u>=’ ( u1 u2 - f ) gforth-0.2 "u-greater-or-equal"

‘within’ ( u1 u2 u3 - f ) core-ext "within"
   u2<u3 and u1 in [u2,u3) or: u2>=u3 and u1 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-0.2 "d-less-or-equal"

‘d<>’ ( d1 d2 - f ) gforth-0.2 "d-not-equals"

‘d=’ ( d1 d2 - f ) double "d-equals"

‘d>’ ( d1 d2 - f ) gforth-0.2 "d-greater-than"

‘d>=’ ( d1 d2 - f ) gforth-0.2 "d-greater-or-equal"

‘d0<’ ( d - f ) double "d-zero-less-than"

‘d0<=’ ( d - f ) gforth-0.2 "d-zero-less-or-equal"

‘d0<>’ ( d - f ) gforth-0.2 "d-zero-not-equals"

‘d0=’ ( d - f ) double "d-zero-equals"

‘d0>’ ( d - f ) gforth-0.2 "d-zero-greater-than"

‘d0>=’ ( d - f ) gforth-0.2 "d-zero-greater-or-equal"

‘du<’ ( ud1 ud2 - f ) double-ext "d-u-less-than"

‘du<=’ ( ud1 ud2 - f ) gforth-0.2 "d-u-less-or-equal"

‘du>’ ( ud1 ud2 - f ) gforth-0.2 "d-u-greater-than"

‘du>=’ ( ud1 ud2 - f ) gforth-0.2 "d-u-greater-or-equal"


File: gforth.info,  Node: Floating Point,  Prev: Numeric comparison,  Up: Arithmetic

6.5.8 Floating Point
--------------------

For the rules used by the text interpreter for recognising
floating-point numbers see ‘rec-float’ (*note Default recognizers::).

   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 may be 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
(https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html), ACM
Computing Surveys 23(1):5−48, March 1991’.

   Conversion between integers and floating-point:

‘s>f’ ( n - r ) floating-ext "s-to-f"

‘d>f’ ( d - r ) floating "d-to-f"

‘f>s’ ( r - n ) floating-ext "f-to-s"

‘f>d’ ( r - d ) floating "f-to-d"

   Arithmetics:

‘f+’ ( r1 r2 - r3 ) floating "f-plus"

‘f-’ ( r1 r2 - r3 ) floating "f-minus"

‘f*’ ( r1 r2 - r3 ) floating "f-star"

‘f/’ ( r1 r2 - r3 ) floating "f-slash"

‘fnegate’ ( r1 - r2 ) floating "f-negate"

‘fabs’ ( r1 - r2 ) floating-ext "f-abs"

‘fcopysign’ ( r1 r2 - r3  ) gforth-1.0
   r3 takes its absolute value from r1 and its sign from r2

‘fmax’ ( r1 r2 - r3 ) floating "f-max"

‘fmin’ ( r1 r2 - r3 ) floating "f-min"

‘floor’ ( r1 - r2 ) floating "floor"
   Round towards the next smaller integral value, i.e., round toward
negative infinity.

‘fround’ ( r1 - r2 ) floating "f-round"
   Round to the nearest integral value.

‘ftrunc’ ( r1 - r2  ) floating-ext "f-trunc"
   round towards 0

‘f**’ ( r1 r2 - r3 ) floating-ext "f-star-star"
   r3 = r1^{r2}

‘fsqrt’ ( r1 - r2 ) floating-ext "f-square-root"

‘fexp’ ( r1 - r2 ) floating-ext "f-e-x-p"
   r2 = e^{r1}

‘fexpm1’ ( r1 - r2 ) floating-ext "f-e-x-p-m-one"
   r2=e^{r1}−1

‘fln’ ( r1 - r2 ) floating-ext "f-l-n"
   Natural logarithm: r1 = e^{r2}

‘flnp1’ ( r1 - r2 ) floating-ext "f-l-n-p-one"
   Inverse of ‘fexpm1’: r1+1 = e^{r2}

‘flog’ ( r1 - r2 ) floating-ext "f-log"
   The decimal logarithm: r1 = 10^{r2}

‘falog’ ( r1 - r2 ) floating-ext "f-a-log"
   r2=10^{r1}

‘f2*’ ( r1 - r2  ) gforth-0.2 "f-two-star"
   Multiply r1 by 2.0e0

‘f2/’ ( r1 - r2  ) gforth-0.2 "f-two-slash"
   Multiply r1 by 0.5e0

‘1/f’ ( r1 - r2  ) gforth-0.2 "one-slash-f"
   Divide 1.0e0 by r1.

   Vector arithmetics:

‘v*’ ( f-addr1 nstride1 f-addr2 nstride2 ucount - r ) gforth-0.5 "v-star"
   dot-product: r=v1*v2.  The first element of v1 is at f_addr1, the
next at f_addr1+nstride1 and so on (similar for v2).  Both vectors have
ucount elements.

‘faxpy’ ( ra f-x nstridex f-y nstridey ucount - ) gforth-0.5 "faxpy"
   vy=ra*vx+vy, where vy is the vector starting at f_y with stride
nstridey bytes, and vx is the vector starting at f_x with stride
nstridex, and both vectors contain ucount elements.

   Angles in floating point operations are given in radians (a full
circle has 2 pi radians).

‘fsin’ ( r1 - r2 ) floating-ext "f-sine"

‘fcos’ ( r1 - r2 ) floating-ext "f-cos"

‘fsincos’ ( r1 - r2 r3 ) floating-ext "f-sine-cos"
   r2=sin(r1), r3=cos(r1)

‘ftan’ ( r1 - r2 ) floating-ext "f-tan"

‘fasin’ ( r1 - r2 ) floating-ext "f-a-sine"

‘facos’ ( r1 - r2 ) floating-ext "f-a-cos"

‘fatan’ ( r1 - r2 ) floating-ext "f-a-tan"

‘fatan2’ ( r1 r2 - r3 ) floating-ext "f-a-tan-two"
   r1/r2=tan(r3).  Forth-2012 does not require, but probably intends
this to be the inverse of ‘fsincos’.  In Gforth it is.

‘fsinh’ ( r1 - r2 ) floating-ext "f-cinch"

‘fcosh’ ( r1 - r2 ) floating-ext "f-cosh"

‘ftanh’ ( r1 - r2 ) floating-ext "f-tan-h"

‘fasinh’ ( r1 - r2 ) floating-ext "f-a-cinch"

‘facosh’ ( r1 - r2 ) floating-ext "f-a-cosh"

‘fatanh’ ( r1 - r2 ) floating-ext "f-a-tan-h"

‘pi’ ( - r  ) gforth-0.2
   ‘Fconstant’ - r is the value pi; the ratio of a circle's area to its
diameter.

   Special values in IEEE754 can be derived by for example dividing by
zero.  The most common ones are defined as floating point constants for
easy usage.

‘infinity’ ( - r  ) gforth-1.0
   floating point infinity

‘inf’ ( - r  ) gforth-1.0
   Synonym of ‘infinity’ to allow copying and pasting from the output of
‘...’, *Note Examining data::.

‘-infinity’ ( - r  ) gforth-1.0
   floating point -infinity

‘-inf’ ( - r  ) gforth-1.0
   Synonym of ‘-infinity’ to allow copying and pasting from the output
of ‘...’, *Note Examining data::.

‘NaN’ ( - r  ) gforth-1.0
   floating point Not a Number

   ---------- 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: Floating-point comparisons,  Next: Stack Manipulation,  Prev: Arithmetic,  Up: Words

6.6 Floating-point comparisons
==============================

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-0.5 "f-tilde-rel"
   Approximate equality with relative error: |r1-r2|<r3*|r1+r2|.

‘f~abs’ ( r1 r2 r3 - flag  ) gforth-0.5 "f-tilde-abs"
   Approximate equality with absolute error: |r1-r2|<r3.

‘f~’ ( r1 r2 r3 - flag  ) floating-ext "f-proximate"
   Forth-2012 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-0.2 "f-equals"

‘f<>’ ( r1 r2 - f ) gforth-0.2 "f-not-equals"

‘f<’ ( r1 r2 - f ) floating "f-less-than"

‘f<=’ ( r1 r2 - f ) gforth-0.2 "f-less-or-equal"

‘f>’ ( r1 r2 - f ) gforth-0.2 "f-greater-than"

‘f>=’ ( r1 r2 - f ) gforth-0.2 "f-greater-or-equal"

‘f0<’ ( r - f ) floating "f-zero-less-than"

‘f0<=’ ( r - f ) gforth-0.2 "f-zero-less-or-equal"

‘f0<>’ ( r - f ) gforth-0.2 "f-zero-not-equals"

‘f0=’ ( r - f ) floating "f-zero-equals"

‘f0>’ ( r - f ) gforth-0.2 "f-zero-greater-than"

‘f0>=’ ( r - f ) gforth-0.2 "f-zero-greater-or-equal"


File: gforth.info,  Node: Stack Manipulation,  Next: Memory,  Prev: Floating-point comparisons,  Up: Words

6.7 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

6.7.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"

‘third’ ( w1 w2 w3 - w1 w2 w3 w1 ) gforth-1.0 "third"

‘fourth’ ( w1 w2 w3 w4 - w1 w2 w3 w4 w1 ) gforth-1.0 "fourth"

‘swap’ ( w1 w2 - w2 w1 ) core "swap"

‘rot’ ( w1 w2 w3 - w2 w3 w1 ) core "rote"

‘-rot’ ( w1 w2 w3 - w3 w1 w2 ) gforth-0.2 "not-rote"

‘tuck’ ( w1 w2 - w2 w1 w2 ) core-ext "tuck"

‘pick’ ( S:... u - S:... w ) core-ext "pick"
   Actually the stack effect is ‘ x0 ... xu u -- x0 ... xu x0 ’.

‘roll’ ( x0 x1 .. xn n - x1 .. xn x0  ) core-ext

‘?dup’ ( w - S:... w ) core "question-dupe"
   Actually the stack effect is: ‘( 0 -- 0 | x\0 -- x x )’.  It performs
a ‘dup’ if x is nonzero.

‘2drop’ ( w1 w2 - ) core "two-drop"

‘2nip’ ( w1 w2 w3 w4 - w3 w4 ) gforth-0.2 "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"

‘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"

‘2tuck’ ( w1 w2 w3 w4 - w3 w4 w1 w2 w3 w4 ) gforth-0.2 "two-tuck"


File: gforth.info,  Node: Floating point stack,  Next: Return stack,  Prev: Data stack,  Up: Stack Manipulation

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

‘fdrop’ ( r - ) floating "f-drop"

‘fnip’ ( r1 r2 - r2 ) gforth-0.2 "f-nip"

‘fdup’ ( r - r r ) floating "f-dupe"

‘fover’ ( r1 r2 - r1 r2 r1 ) floating "f-over"

‘fthird’ ( r1 r2 r3 - r1 r2 r3 r1 ) gforth-1.0 "fthird"

‘ffourth’ ( r1 r2 r3 r4 - r1 r2 r3 r4 r1 ) gforth-1.0 "ffourth"

‘fswap’ ( r1 r2 - r2 r1 ) floating "f-swap"

‘frot’ ( r1 r2 r3 - r2 r3 r1 ) floating "f-rote"

‘f-rot’ ( r1 r2 r3 - r3 r1 r2 ) gforth-1.0 "f-not-rote"

‘ftuck’ ( r1 r2 - r2 r1 r2 ) gforth-0.2 "f-tuck"

‘fpick’ ( f:... u - f:... r ) gforth-0.4 "fpick"
   Actually the stack effect is ‘ r0 ... ru u -- r0 ... ru r0 ’.


File: gforth.info,  Node: Return stack,  Next: Locals stack,  Prev: Floating point stack,  Up: Stack Manipulation

6.7.3 Return stack
------------------

The return stack primarily exists for storing system data, such as
return addresses and loop control parameters, but Forth also allows
programmers to make use of it, albeit with restrictions stemming from
the other uses.  The primary use is for temporary storage of data;
locals also provide this capability, and usually in a more convenient
way; some purists (or puritans) prefer to avoid locals, though.

   In Gforth 1.0 you can use the return stack during text interpretation
(and you cannot use locals for that).  The only limitation here is that
you cannot pass data on the return stack into or out of an included
file, block, or ‘evaluate’d string.  Example:

     1 >r
     : foo [ r> ] literal ;
     foo . \ prints 1

   This interpretive usage of return-stack words is non-standard, and
many other Forth systems do not have support this usage, or limit it to
within one line.

   In Gforth you can use the return stack for storing data while you
also keep and access data in locals.  However, the standard puts
restrictions on mixing return stack and locals usage, for easy locals
implementations, and there are systems that actually rely on these
restrictions.  So, if you want to produce a standard compliant program
and you are using local variables in a definition, 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@’ ( R:w - R:w w  ) core "r-fetch"

‘r'@’ ( r:w r:w2 - r:w r:w2 w ) gforth-1.0 "r-tick-fetch"
   The second item on the return stack

‘rpick’ ( R:wu ... R:w0 u - R:wu ... R:w0 wu  ) gforth-1.0
   wu is the uth element on the return stack; ‘0 rpick’ is equivalent to
‘r@’.

‘rdrop’ ( R:w - ) gforth-0.2 "rdrop"

‘2>r’ ( w1 w2 - R:w1 R:w2 ) core-ext "two-to-r"

‘2r>’ ( R:w1 R:w2 - w1 w2 ) core-ext "two-r-from"

‘2r@’ ( R:w1 R:w2 - R:w1 R:w2 w1 w2 ) core-ext "two-r-fetch"

‘2rdrop’ ( R:w1 R:w2 - ) gforth-0.2 "two-r-drop"

‘n>r’ ( x1 .. xn n - R:xn..R:x1 R:n  ) tools-ext "n-to-r"
   In Standard Forth, the order of items on the return stack is not
specified, and the only thing you can do with the items on the return
stack is to use ‘nr>’

‘nr>’ ( R:xn..R:x1 R:n - x1 .. xn n  ) tools-ext "n-r-from"
   In Standard Forth, the order of items on the return stack is not
specified, and the only thing you can do with the items on the return
stack is to use ‘nr>’

   On some platforms (particularly, 32-bit platforms) floating-point
numbers are not naturally aligned on the return stack and this can lead
to (usually, but not always) small performance disadvantages.

‘f>r’ ( r - ) gforth-experimental "f-to-r"
   Actual stack effect: ‘( r -- R:r )’

‘fr>’ ( - r ) gforth-experimental "f-r-from"
   Actual stack effect: ‘( R:r -- r )’

‘fr@’ ( - r ) gforth-experimental "f-r-fetch"
   Actual stack effect: ‘( R:r -- R:r r )’


File: gforth.info,  Node: Locals stack,  Next: Stack pointer manipulation,  Prev: Return stack,  Up: Stack Manipulation

6.7.4 Locals stack
------------------

Gforth uses a separate 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

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

In the stack effects of the following words, ignore the occurrences of
"..."  in the stack-pointer fetching words.

‘sp0’ ( - a-addr  ) gforth-0.4 "sp-zero"
   User variable - initial value of the data stack pointer.

‘sp@’ ( S:... - a-addr ) gforth-0.2 "sp-fetch"

‘sp!’ ( a-addr - S:... ) gforth-0.2 "sp-store"

‘fp0’ ( - a-addr  ) gforth-0.4 "fp-zero"
   User variable - initial value of the floating-point stack pointer.

‘fp@’ ( f:... - f-addr ) gforth-0.2 "fp-fetch"

‘fp!’ ( f-addr - f:... ) gforth-0.2 "fp-store"

‘rp0’ ( - a-addr  ) gforth-0.4 "rp-zero"
   User variable - initial value of the return stack pointer.

‘rp@’ ( - a-addr ) gforth-0.2 "rp-fetch"

‘rp!’ ( a-addr - ) gforth-0.2 "rp-store"

‘lp0’ ( - a-addr  ) gforth-0.4 "lp-zero"
   User variable - initial value of the locals stack pointer.

‘lp@’ ( - c-addr ) gforth-internal "lp-fetch"
   C_addr is the current value of the locals stack pointer.

‘lp!’ ( c-addr - ) gforth-internal "lp-store"
   Set the locals pointer to c-addr.


File: gforth.info,  Node: Memory,  Next: Strings and Characters,  Prev: Stack Manipulation,  Up: Words

6.8 Memory
==========

* Menu:

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

In addition to the Standard Forth memory allocation words, there is also
a garbage collector
(https://www.complang.tuwien.ac.at/forth/garbage-collection.zip).


File: gforth.info,  Node: Memory model,  Next: Dictionary allocation,  Prev: Memory,  Up: Memory

6.8.1 Memory model
------------------

Standard Forth considers a Forth system as consisting of several address
spaces, of which only “data space” is managed and accessible with the
memory words in standard programs.  Memory not necessarily in data space
includes the stacks, the code (called code space) and the headers
(called name space).  Gforth allows at least read access to all these
logical spaces, but does not guarantee that code accessing the stacks,
the threaded or native code, or the headers is portable or will work in
the next Gforth version; Gforth provides some accessor words for these
purposes, however.

   Another division of memory is between dictionary and heap memory.(1)
In heap memory you can free allocations in arbitrary order, but you
cannot grow allocations in-place (*note Heap Allocation::).  In
dictionary memory deallocation is impractical for the most part, but you
can grow allocations in place (*note Dictionary allocation::).  Gforth
(since 1.0) allows having several sections of dictionary memory in order
to allow more flexibility in this growing (*note Sections::).

   One relevant concept in this context is the contiguous region: It
means a piece of memory that is contiguous, without any system data
interleaved with it.  In heap memory each allocation forms one
contiguous region, and separate allocations are not contiguous with any
other allocations.  In dictionary memory all allocations in a section
are contiguous, unless something happens that ends the contiguous
region; a typical reason for ending a contiguous region is defining a
word in that section.

   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 regions
are those described by Standard Forth as contiguous; but you can be sure
that, within a section 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) The term “dictionary” is also used to refer to the search data
structure embodied in word lists and headers.  The search data (word
headers) reside in dictionary memory.


File: gforth.info,  Node: Dictionary allocation,  Next: Sections,  Prev: Memory model,  Up: Memory

6.8.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’)
in the same section end the contiguous region and start a new one, but
allocating memory in a different section does not end a contiguous
region.

   In Standard 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
   Return the address of the next free location in data space.

‘unused’ ( - u  ) core-ext
   Return the amount of free space remaining (in address units) in the
region addressed by ‘here’.

‘allot’ ( n -  ) core
   Reserve n address units of data space without initialization.  n is a
signed number, passing a negative n releases memory.  In Forth-2012 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.

‘->here’ ( addr -  ) gforth-1.0 "to-here"
   Change the value of ‘here’ to addr.

‘c,’ ( c -  ) core "c-comma"
   Reserve data space for one char and store c in the space.

‘f,’ ( f -  ) gforth-0.2 "f-comma"
   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-0.2 "two-comma"
   Reserve data space for two cells and store the double w1 w2 there, w2
first (lower address).

‘w,’ ( x -  ) gforth-1.0 "w-comma"
   Reserve 2 bytes of data space and store the least significant 16 bits
of x there.

‘l,’ ( l -  ) gforth-1.0 "l-comma"
   Reserve 4 bytes of data space and store the least significant 32 bits
of x there.

‘x,’ ( x -  ) gforth-1.0 "x-comma"
   Reserve 8 bytes of data space and store (the least significant 64
bits) of x there.  Reserve 8 bytes of data space and store w there.

‘xd,’ ( xd -  ) gforth-1.0 "x-d-comma"
   Reserve 8 bytes of data space and store the least significant 64 bits
of x there.

‘A,’ ( addr -  ) gforth-0.2 "a-comma"
   Reserve data space for one cell, and store addr there.  For our
cross-compiler this provides the type information necessary for a
relocatable image; normally, though, this is equivalent to ‘,’.

‘mem,’ ( addr u -  ) gforth-0.6 "mem-comma"
   Reserve u bytes of dictionary space and copy u bytes starting at addr
there.  If you want the memory to be aligned, precede ‘mem,’ with an
alignment word.

‘save-mem-dict’ ( addr1 u - addr2 u  ) gforth-0.7
   Copy the memory block addr1 u to a newly ‘allot’ed memory block of
size u; the target memory block starts at addr2.

   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 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 Standard
Forth (‘maxalign’ed in Gforth).

‘align’ ( -  ) core
   If the data-space pointer is not aligned, reserve enough space to
align it.

‘falign’ ( -  ) floating "f-align"
   If the data-space pointer is not float-aligned, reserve enough space
to align it.

‘sfalign’ ( -  ) floating-ext "s-f-align"
   If the data-space pointer is not single-float-aligned, reserve enough
space to align it.

‘dfalign’ ( -  ) floating-ext "d-f-align"
   If the data-space pointer is not double-float-aligned, reserve enough
space to align it.

‘maxalign’ ( -  ) gforth-0.2
   Align data-space pointer for all Forth alignment requirements.


File: gforth.info,  Node: Sections,  Next: Heap Allocation,  Prev: Dictionary allocation,  Up: Memory

6.8.3 Sections
--------------

If you want to do something that allocates memory from the dictionary or
compiles code in the middle of a contiguous region of another dictionary
allocation, or in the middle of a colon definition, that's not possible
with a single dictionary pointer, leading to complicated workarounds.

   Gforth provides dictionary sections to address this problem.  Each
section has its own dictionary pointer, and allocating or compiling
something in one section does not interrupt the contiguity of
allocations in other sections.  In this respect Gforth's sections are
similar to sections and segments in assembly languages.

   One difference is that the most common usage of sections is as a
stack of sections, which is useful for building nested definitions or
dictionary-allocated data structures: Use ‘next-section’ for the inner
definition or data structure, switch back with ‘previous-section’.

   Words like ‘latest’ (*note Name token::) and ‘latestxt’ (*note
Anonymous Definitions::) refer to the most recent definition in the
current section.  Quotations (*note Quotations::) and the implicit
quotation of ‘does>’ (*note User-defined defining words using CREATE::)
are in a different section than the containing definition, so after the
quotation ends (and the section is switched back), words like ‘latest’
report the outer definition rather than the quotation.

   An example of such a usage of the section stack is:

     create my2x2matrix
       next-section here 1 , 2 , previous-section ,
       next-section here 3 , 4 , previous-section ,

     \ now print my2x2matrix[0,1], i.e., "2":
     my2x2matrix 0 cells + @ 1 cells + @ .

   This works also for allocating section memory while compiling a
definition, or defining a definition during a contiguous region, e.g.:

     create mydispatchtable
       next-section :noname ." foo" ; previous-section ,
       next-section :noname ." bar" ; previous-section ,

     \ now dispatch mydispatchtable[1]
     mydispatchtable 1 cells + @ execute

   Note that the interpretation semantics of ‘[:’ (*note Quotations::)
switches to the next section internally, so you can write
‘mydispatchtable’ also as follows:

     create mydispatchtable
       [: ." foo" ;] ,
       [: ." bar" ;] ,

   The interpretation semantics of ‘does>’ uses a separate section, so
the ‘does>’ does not end the contiguous region, and you can define a
word ‘mydispatch’ that includes the dispatch code, as follows:

     create mydispatch
     does> ( u -- )
         ( u addr ) swap cells + @ execute ;
       [: ." foo" ;] ,
       [: ." bar" ;] ,

     1 mydispatch \ prints "bar"

‘next-section’ ( -  ) gforth-1.0
   Switch to the next section in the section stack.  If there is no such
section yet, create it (with the size being a quarter of the size of the
current section).

‘previous-section’ ( -  ) gforth-1.0
   Switch to the previous section in the section stack; the now-next
section continues to exist with everything that was put there.  Throw an
exception if there is no previous section.

   The bottom section in the section stack has the size given with the
‘--dictionary-size’ command-line parameter (*note Invoking Gforth::).

   In addition to the stack of anonymous sections you can also have
named sections that you define with:

‘extra-section’ ( usize "name" -  ) gforth-1.0
   Define a new word name and create a section s with at least usize
unused bytes.
Name execution ‘( ... xt -- ... )’: When calling name, the current
section is c.  Switch the current section to be s, execute xt, then
switch the current section back to c.

   As an example, here's a variant of the ‘my2x2matrix’ definition:

     4 cells extra-section myvec

     create my2x2matrix
       ' here myvec 1 ' , myvec 2 ' , myvec ,
       ' here myvec 3 ' , myvec 4 ' , myvec ,

   Currently a named section does not start a dictionary stack, and
using ‘next-section’ inside a named section throws an error.

   You can show the existing sections with:

‘.sections’ ( -  ) gforth-1.0 "dot-sections"
   Show all the sections and their status.

   At the time of this writing this outputs:

                 start      size      used name
         $7F9A5A516000     32768        96 noname
         $7F9A5A1A1000    131072       208 noname
         $7F9A5A1C2000    524288      2128 noname
         $7F9A4BDFD000   2097152     32680 noname
     >   $7F9A4BFFE040   8388608    659272 Forth
         $7F9A5A51F000     20480      1448 locals-headers

   The lines describe the different sections: First the section stack,
with sections called ‘noname’ and (the bottom) ‘Forth’, then the
extra-sections.  The columns are the start address of the section, the
gross size (including section management overhead), how much of the
section is already used, and the name.  The size and used columns are in
decimal base.

   In the section ‘Forth’, not all of the remaining size can be used for
‘allot’ting memory, because room must be left for ‘pad’ (*note Memory
Blocks::).  The current section is marked with ‘>’.  Also, if you use
‘word’ (*note The Input Stream::), you must leave room in the current
section for the parsed string and its length byte.


File: gforth.info,  Node: Heap Allocation,  Next: Memory Access,  Prev: Sections,  Up: Memory

6.8.4 Heap allocation
---------------------

Heap allocation supports deallocation of allocated memory in any order.
It does not affect dictionary allocation (i.e., heap allocation does not
end a contiguous region).  In Gforth, these words are implemented using
the standard C library calls malloc(), free() and realloc().

   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 u address units of contiguous data space.  This data space
is not initialized.  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 arbitrary and wior is a non-zero I/O result code.

‘free’ ( a_addr - wior  ) memory
   Return the region of data space starting at a-addr to the system.
The region must originally have been obtained using ‘allocate’ or
‘resize’, otherwise the result of ‘free’ is unpredictable.  If the
operation 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
   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.

* Menu:

* Memory blocks and heap allocation::
* Growable memory buffers::


File: gforth.info,  Node: Memory blocks and heap allocation,  Next: Growable memory buffers,  Prev: Heap Allocation,  Up: Heap Allocation

6.8.4.1 Memory blocks and heap allocation
.........................................

Additional words for dealing with memory blocks are described in *note
Memory Blocks::.  An alternative to the following words are among the
$tring words (*note $tring words::).

‘save-mem’ ( addr1 u - addr2 u  ) gforth-0.2
   Copy the memory block addr u to addr2, which is the start of a newly
heap allocated u-byte region.

‘extend-mem’ ( addr1 u1 u - addr addr2 u2  ) gforth-experimental
   Addr1 u1 is a memory block in heap memory.  Increase the size of this
memory block by u aus, possibly reallocating it.  C-addr2 u2 is the
resulting memory block (u2=u1+u), addr is the start of the u additional
aus (addr=addr2+u1).

‘free-mem-var’ ( addr -  ) gforth-experimental
   Addr is the address of a 2variable containing a memory block
descriptor c-addr u in heap memory; ‘free-mem-var’ frees the memory
block and stores 0 0 in the 2variable.

   Usage example:

     2variable myblock
     "foo" save-mem myblock 2!
     myblock 2@ "bar" tuck >r >r extend-mem myblock 2! r> swap r> move
     myblock 2@ type \ prints "foobar"
     myblock free-mem-var


File: gforth.info,  Node: Growable memory buffers,  Prev: Memory blocks and heap allocation,  Up: Heap Allocation

6.8.4.2 Growable memory buffers
...............................

The following words are useful for growable memory buffers.  One can
alternatively use $trings (*note $tring words::), and the differences
are: When the used memory in the buffer shrinks, $trings may resize the
buffer, while ‘adjust-buffer’ does not, which may be preferable for a
buffer that is reused all the time.  However, $strings have one cell
less memory overhead, and for longer-term storage the shrinking may be
worthwhile.

‘buffer%’ ( u1 u2 -  ) gforth-experimental "buffer-percent"
   u1 is the alignment and u2 is the size of a buffer descriptor.

‘init-buffer’ ( addr -  ) gforth-experimental

‘adjust-buffer’ ( u addr -  ) gforth-experimental
   Adjust buffer% at addr to length u.  This may grow the allocated
area, but never shrinks it.

   You can get the current address and length of such a buffer with
‘2@’.

   Typical usage:

     create mybuf  buffer% %allot  mybuf init-buffer
     s" frobnicate" mybuf adjust-buffer  mybuf 2@ move
     mybuf 2@ type
     s" foo"        mybuf adjust-buffer  mybuf 2@ move
     mybuf 2@ type


File: gforth.info,  Node: Memory Access,  Next: Special Memory Accesses,  Prev: Heap Allocation,  Up: Memory

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

‘!@’ ( w1 a-addr - w2 ) gforth-experimental "store-fetch"
   Fetch W2 from A_ADDR, then store W1 there.  There is also ‘atomic!@’
(*note Hardware operations for multi-tasking::).

‘+!@’ ( u1 a-addr - u2 ) gforth-experimental "plus-store-fetch"
   Fetch U2 from A_ADDR, then increment this location by U1.  There is
also ‘atomic+!@’ (*note Hardware operations for multi-tasking::).

‘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 ) floating "f-fetch"
   r is the float at address f-addr.

‘f!’ ( r f-addr - ) floating "f-store"
   Store r into the float at address f-addr.

‘sf@’ ( sf-addr - r ) floating-ext "s-f-fetch"
   Fetch the single-precision IEEE floating-point value r from the
address sf-addr.

‘sf!’ ( r sf-addr - ) floating-ext "s-f-store"
   Store r as single-precision IEEE floating-point value to the address
sf-addr.

‘df@’ ( df-addr - r ) floating-ext "d-f-fetch"
   Fetch the double-precision IEEE floating-point value r from the
address df-addr.

‘df!’ ( r df-addr - ) floating-ext "d-f-store"
   Store r as double-precision IEEE floating-point value to the address
df-addr.


File: gforth.info,  Node: Special Memory Accesses,  Next: Address arithmetic,  Prev: Memory Access,  Up: Memory

6.8.6 Special Memory Accesses
-----------------------------

This section is about memory accesses useful for communicating with
other software or other computers.  This means that the accesses are of
a certain bit width (independent of Gforth's cell width), are possibly
not naturally aligned and typically have a certain byte order that may
be different from the native byte order of the system that Gforth runs
on.

   We use the following prefixes:

‘c’
     8 bits (character)
‘w’
     16 bits
‘l’
     32 bits
‘x’
     64 bits represented as one cell
‘xd’
     64 bits represented as two cells

   The ‘x’-prefix words do not work properly on 32-bit systems, so for
code that is intended to be portable to 32-bit systems you should use
‘xd’-prefix words.  Note that ‘xd’-prefix words work on 64-bit systems:
there the upper cell is just 0 (for unsigned values) or a sign extension
of the lower cell.

   The memory-access words below all work with arbitrarily (un)aligned
addresses (unlike ‘@’, ‘!’, ‘f@’, ‘f!’, which require alignment on some
hardware), and use native byte order (like these words),

‘w@’ ( c-addr - u ) gforth-0.5 "w-fetch"
   u is the zero-extended 16-bit value stored at c_addr.

‘w!’ ( w c-addr - ) gforth-0.7 "w-store"
   Store the bottom 16 bits of w at c_addr.

‘l@’ ( c-addr - u ) gforth-0.7 "l-fetch"
   u is the zero-extended 32-bit value stored at c_addr.

‘l!’ ( w c-addr - ) gforth-0.7 "l-store"
   Store the bottom 32 bits of w at c_addr.

‘x@’ ( c-addr - u ) gforth-1.0 "x-fetch"
   u is the zero-extended 64-bit value stored at c_addr.

‘x!’ ( w c-addr - ) gforth-1.0 "x-store"
   Store the bottom 64 bits of w at c_addr.

‘xd@’ ( c-addr - ud ) gforth-1.0 "x-d-fetch"
   ud is the zero-extended 64-bit value stored at c_addr.

‘xd!’ ( ud c-addr - ) gforth-1.0 "x-d-store"
   Store the bottom 64 bits of ud at c_addr.

   For accesses with a specific byte order, you have to perform
byte-order adjustment immediately after a fetch (before the
sign-extension), or immediately before the store.  The results of these
byte-order adjustment words are always zero-extended.

‘wbe’ ( u1 - u2  ) gforth-1.0
   Convert 16-bit value in u1 from native byte order to big-endian or
from big-endian to native byte order (the same operation)

‘wle’ ( u1 - u2  ) gforth-1.0
   Convert 16-bit value in u1 from native byte order to little-endian or
from little-endian to native byte order (the same operation)

‘lbe’ ( u1 - u2  ) gforth-1.0
   Convert 32-bit value in u1 from native byte order to big-endian or
from big-endian to native byte order (the same operation)

‘lle’ ( u1 - u2  ) gforth-1.0
   Convert 32-bit value in u1 from native byte order to little-endian or
from little-endian to native byte order (the same operation)

‘xbe’ ( u1 - u2  ) gforth-1.0
   Convert 64-bit value in u1 from native byte order to big-endian or
from big-endian to native byte order (the same operation)

‘xle’ ( u1 - u2  ) gforth-1.0
   Convert 64-bit value in u1 from native byte order to little-endian or
from little-endian to native byte order (the same operation)

‘xdbe’ ( ud1 - ud2  ) gforth-1.0
   Convert 64-bit value in ud1 from native byte order to big-endian or
from big-endian to native byte order (the same operation)

‘xdle’ ( ud1 - ud2  ) gforth-1.0
   Convert 64-bit value in ud1 from native byte order to little-endian
or from little-endian to native byte order (the same operation)

   For signed fetches with a specific byte order, you have first have to
perform an unsigned fetch and a byte-order correction, and finally use a
sign-extension word:

‘c>s’ ( x - n ) gforth-1.0 "c-to-s"
   Sign-extend the 8-bit value in x to cell n.

‘w>s’ ( x - n ) gforth-1.0 "w-to-s"
   Sign-extend the 16-bit value in x to cell n.

‘l>s’ ( x - n ) gforth-1.0 "l-to-s"
   Sign-extend the 32-bit value in x to cell n.

‘x>s’ ( x - n  ) gforth-1.0 "x-to-s"
   Sign-extend the 64-bit value in x to cell n.

‘xd>s’ ( xd - d  ) gforth-1.0 "xd-to-s"
   Sign-extend the 64-bit value in XD to double-cell D.

   Overall, this leads to sequences like

     w@ wbe w>s   \ 16-bit unaligned signed big-endian fetch
     >r lle r> l! \ 32-bit unaligned little-endian store


File: gforth.info,  Node: Address arithmetic,  Next: Memory Blocks,  Prev: Special Memory Accesses,  Up: Memory

6.8.7 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::).

   Standard Forth does not specify the sizes of the data types.
Instead, it offers a number of words (e.g., ‘cells’) 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.  There is also
word-addressed(1) hardware in some embedded systems, and on these
systems the au is one cell.  Finally, Forth-2012 also supports systems
where a char needs more than one au.  However, the common practice is
that ‘1 chars’ produces 1, and this will be standardized in the next
release of the standard.

   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.

   Standard Forth also defines words for aligning addresses for specific
types.  Some hardware requires that accesses to specific data types must
only occur at specific addresses; e.g., that (4-byte) 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.

   Standard Forth defines no words for character-aligning addresses, but
given that ‘1 chars’=1 is common practice, that's not a big loss.

   Standard Forth guarantees that addresses returned by ‘CREATE’d words
are cell-aligned; in addition, Gforth guarantees that these addresses
are aligned for all Forth purposes.(2)

   Note that the Standard Forth word ‘char’ has nothing to do with
address arithmetic.

‘chars’ ( n1 - n2  ) core
   n2 is the number of address units of n1 chars.

‘char+’ ( c-addr1 - c-addr2 ) core "char-plus"
   ‘1 chars +’.

‘char-’ ( c-addr1 - c-addr2  ) gforth-0.7 "char-minus"
   ‘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-’ ( a-addr1 - a-addr2 ) core "cell-minus"
   ‘1 cells -’

‘cell/’ ( n1 - n2 ) gforth-1.0 "cell-divide"
   N2 is the number of cells that fit into n1 aus, rounded towards
negative infinity.

‘cell’ ( - u  ) gforth-0.2
   ‘Constant’ - ‘1 cells’

‘aligned’ ( c-addr - a-addr ) core "aligned"
   a-addr is the smallest aligned address greater than or equal to
c-addr.

‘floats’ ( n1 - n2 ) floating "floats"
   n2 is the number of address units of n1 floats.

‘float+’ ( f-addr1 - f-addr2 ) floating "float-plus"
   ‘1 floats +’.

‘float’ ( - u  ) gforth-0.3
   ‘Constant’ - the number of address units corresponding to a
floating-point number.

‘float/’ ( n1 - n2 ) gforth-1.0 "float-divide"
   N2 is the number of floats that fit into n1 aus, rounded towards
negative infinity.

‘faligned’ ( c-addr - f-addr ) floating "f-aligned"
   f-addr is the first float-aligned address greater than or equal to
c-addr.

‘sfloats’ ( n1 - n2 ) floating-ext "s-floats"
   n2 is the number of address units of n1 single-precision IEEE
floating-point numbers.

‘sfloat+’ ( sf-addr1 - sf-addr2  ) floating-ext "s-float-plus"
   ‘1 sfloats +’.

‘sfloat/’ ( n1 - n2 ) gforth-1.0 "s-float-divide"
   N2 is the number of sfloats that fit into n1 aus, rounded towards
negative infinity.

‘sfaligned’ ( c-addr - sf-addr ) floating-ext "s-f-aligned"
   sf-addr is the first single-float-aligned address greater than or
equal to c-addr.

‘dfloats’ ( n1 - n2 ) floating-ext "d-floats"
   n2 is the number of address units of n1 double-precision IEEE
floating-point numbers.

‘dfloat+’ ( df-addr1 - df-addr2  ) floating-ext "d-float-plus"
   ‘1 dfloats +’.

‘dfloat/’ ( n1 - n2 ) gforth-1.0 "d-float-divide"
   N2 is the number of dfloats that fit into n1 aus, rounded towards
negative infinity.

‘dfaligned’ ( c-addr - df-addr ) floating-ext "d-f-aligned"
   df-addr is the first double-float-aligned address greater than or
equal to c-addr.

‘maxaligned’ ( addr1 - addr2  ) gforth-0.2
   addr2 is the first address after addr1 that satisfies all alignment
restrictions.

‘*aligned’ ( addr1 n - addr2  ) gforth-1.0 "star-aligned"
   ADDR2 is the aligned version of ADDR1 with respect to the alignment
N; N must be a power of 2.

‘*align’ ( n -  ) gforth-1.0 "star-align"
   Align ‘here’ with respect to the alignment N.

‘waligned’ ( addr - addr'  ) gforth-1.0
   Addr' is the next even address >= addr.

‘walign’ ( -  ) gforth-1.0
   Align ‘here’ to even.

‘laligned’ ( addr - addr'  ) gforth-1.0
   Addr' is the next address >= addr divisible by 4.

‘lalign’ ( -  ) gforth-1.0
   Align ‘here’ to be divisible by 4.

‘xaligned’ ( addr - addr'  ) gforth-1.0
   Addr' is the next address >= addr divisible by 8.

‘xalign’ ( -  ) gforth-1.0
   Align ‘here’ to be divisible by 8.

   For cell-based addess calculations, there are three shortcuts, based
on

     : th ( a-addr0 n -- a-addr1 ) cells + ;

‘th’ ( a-addr1 n - a-addr2 ) gforth-0.7 "th"
   Array address calculator, ‘cells +’

‘th@’ ( a-addr n - u ) gforth-1.0 "th-fetch"
   Array fetch, ‘cells + @’

‘th!’ ( u a-addr n - ) gforth-1.0 "th-store"
   Array store, ‘cells + !’

   The environmental query ‘address-unit-bits’ (*note Environmental
Queries::) and the following words may be useful to those who want to
write software portable to non-byte-addressed machines.

‘/w’ ( - u  ) gforth-0.7 "slash-w"
   address units for a 16-bit value

‘/l’ ( - u  ) gforth-0.7 "slash-l"
   address units for a 32-bit value

‘/x’ ( - u  ) gforth-1.0 "slash-x"
   address units for a 64-bit value

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

   (1) In Forth terminology: cell-addressed.

   (2) Some SIMD extensions of some instruction sets impose more severe
alignment constraints that ‘create’ currently does not satisfy.


File: gforth.info,  Node: Memory Blocks,  Prev: Address arithmetic,  Up: Memory

6.8.8 Memory Blocks
-------------------

Memory blocks often represent character strings; For ways of storing
character strings in memory see *note String representations::.  For
other string-processing words see *note Displaying characters and
strings::.

   In case you want to write a program that is portable to systems with
‘1 chars’ > 1 (not recommended), you have to note the difference between
words that take a number of aus (e.g., ‘erase’) and words that take a
number of chars (e.g., ‘blank’), and insert ‘chars’ as appropriate.

   When copying characters between overlapping memory regions, use
‘move’.  ‘Cmove’ and ‘cmove>’ tend to be slower than a well-implemented
‘move’.

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

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

‘erase’ ( addr u -  ) core-ext
   Clear all bits in u aus starting at addr.

‘blank’ ( c-addr u -  ) string
   Store the space character into u chars starting at c-addr.

‘pad’ ( - c-addr  ) core-ext
   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: Strings and Characters,  Next: Control Structures,  Prev: Memory,  Up: Words

6.9 Strings and Characters
==========================

A Forth char is a byte.  Forth programs use chars to represent ASCII
characters or other data that fits into a byte.

   But the world has moved on since ASCII, and now the dominating
character set is Unicode, and it is supported by Forth in its UTF-8
encoding.  Forth has extended characters (xchars, *note Xchars and
Unicode::) which map to Unicode code points.  An xchar for an Unicode
code point is represented by 1-4 chars in memory, or one cell on the
data stack.

   So is an xchar a character (a “user-perceived character” in Unicode
terms)?  Unfortunately, the writing systems unified by Unicode are too
complex for that idea to work in general; e.g., characters can be
composed of base characters (one code point) modified by diacritical
marks (0 or more additional code points).  So in general a
user-perceived character cannot be represented by a single cell.  So the
way to go is to represent text (including a single user-perceived
characer) as string.

   Once you embrace the idea of working with strings instead of with
characters, you find out that you rarely need to deal with individual
code points, and therefore rarely need to use words from the xchar words
(*note Xchars and Unicode::).  Also, given that a string consists of
bytes aka chars, you can use the words that deal with chars to work on
strings containing Unicode characters.  In Unicode terms: the strings
are processed on the level of code units (bytes for UTF-8), not code
points.

   You can use the usual integer words on chars and Xchars on the stack.

   In UTF-8 each ASCII character is encoded as single byte with the same
value as in ASCII. The same holds true for all other character encodings
supported in Gforth.  So you can use the character words (e.g., ‘c@’) to
deal with ASCII characters.  Only ASCII characters are represented as
single bytes in UTF-8, so this benefit stops there.  In particular, the
Unicode code points 128-255 are represented by two-byte sequences in
UTF-8.

* Menu:

* String representations::
* Xchars and Unicode::
* String and character literals::
* String words::
* $tring words::
* Internationalization and localization::
* Substitute::
* Counted string words::


File: gforth.info,  Node: String representations,  Next: Xchars and Unicode,  Prev: Strings and Characters,  Up: Strings and Characters

6.9.1 String representations
----------------------------

Forth commonly represents strings as cell pair c-addr u on the stack; u
is the length of the string in bytes (aka chars), and c-addr is the
address of the first byte of the string.  Note that a code point may be
represented by a sequence of several chars in the string (and a
user-perceived character may consist of several code points).  *Note
String words::.

   Another string representation is used with the string library of
words containing ‘$’ (*note $tring words::).  It uses the address of a
cell-sized string handle to represent the string when its allocation
plays a role, e.g., when appending to the string; this corresponds to
owned strings in Rust.  When only the content of the string is of
interest, the c-addr u representation for the string is used with these
words, too; the validity of a c-addr u pair ends when the underlying
string is modified or freed; this corresponds to string slices in Rust.

   A legacy string representation are “counted strings”, represented on
the stack by c-addr.  The char addressed by c-addr contains a
character-count, n, of the string and the string occupies the subsequent
n char addresses in memory.  Counted strings are limited to 255 bytes in
length.  While counted strings may look attractive due to needing only
one stack item, due to their limitations we recommend avoiding them,
especially as input parameters of words.  *Note Counted string words::.


File: gforth.info,  Node: Xchars and Unicode,  Next: String and character literals,  Prev: String representations,  Up: Strings and Characters

6.9.2 Xchars and Unicode
------------------------

An xchar is represented as a single cell on the stack and as a sequence
of one or more chars (as string) in memory.(1)

   The actual supported xchars depend on the encoding, which is
determined automatically from the environment variable ‘LC_CTYPE’,
‘LC_ALL’, or ‘LANG’ (*note Environment variables::).  If any of them
contains "UTF-8" on Gforth startup, Gforth uses UTF-8 encoding (for
Unicode), otherwise it uses fixed-width 8-bit encoding.  The encoding
cannot be changed after Gforth startup, and if any non-ASCII characters
are stored in an image, the image must be invoked in a way that produces
the same encoding and charset setting.

   Any text I/O is expected to happen in the encoding and character set
specified in the environment variables, so if any encoding or character
set conversions are needed, perform them outside Gforth, with tools such
as ‘recode’ or ‘iconv’.

   The fixed-width 8-bit encoding is used for 8-bit encodings of legacy
character sets, such as ISO Latin-1, ISO Latin-2, or KOI8-R.

   Whatever the environment, an xchar corresponds to a code point of the
character set.  In some character sets, each code point represents a
character, but in Unicode a user-perceived character may consist of a
sequence of code points.  Gforth currently provides no facilities for
dealing with user-perceived characters, and dealing with code points
rarely provides any benefit, so the usual way to deal with text is as
strings of chars.

   The only thing that's in common between Unicode and all the charsets
for which Gforth supports a fixed-width encoding is ASCII: These
character sets all have the code points 0-127 which have the same
meaning, have the same on-stack representation (a number in the range
0-127), and have the same in-memory representation (a single byte (aka
char) that has a value in the range 0-127).

   When using UTF-8 encoding, all other codepoints take more than one
byte/char.  In most cases, you can just treat such characters as strings
in memory and don't need to use the following words, but if you want to
deal with individual codepoints, the following words are useful.

   When using the fixed-width encoding, all other code points take only
one byte, but you can still use the xchar words to access the code
points, and your code will also continue to work when you switch to
UTF-8 encoding.

   The xchar words add a few data types:

   • XC is an extended char (xchar) on the stack.  It occupies one cell,
     and is a subset of unsigned cell.

   • XC-ADDR is the address of an xchar in memory.  Alignment
     requirements are the same as C-ADDR.  The memory representation of
     an xchar differs from the stack representation, and depends on the
     encoding used.  An xchar may use a variable number of chars in
     memory.

   • XC-ADDR U is a string (or buffer) of xchars in memory, starting at
     XC-ADDR, U chars (i.e., bytes, not xchars) long.

‘xc-size’ ( xc - u  ) xchar "x-c-size"
   The xchar xc occupies u chars in memory.

‘x-size’ ( xc-addr u1 - u2  ) xchar
   The first xchar at xc-addr occupies u2 chars; if xc-addr u1 does not
contain a complete xchar, u2 is u1.

‘xc@’ ( xc-addr - xc  ) xchar-ext "x-c-fetch"
   xc is the xchar starting at XC-ADDR1.

‘xc@+’ ( xc-addr1 - xc-addr2 xc  ) xchar "x-c-fetch-plus"
   xc is the xchar starting at XC-ADDR1.  xc-addr2 points to the first
memory location after xc.

‘xc@+?’ ( xc-addr1 u1 - xc-addr2 u2 xc  ) gforth-experimental "x-c-fetch-plus-query"
   xc is the xchar starting at XC-ADDR1.  XC-ADDR2 U2 is the remaining
string behind XC.  If the start of xc-addr1 u1 contains no valid xchar,
xc is ‘invalid-char’, and xc-addr2 u2 is the remaining string after
skipping at least one byte.  If u1=0, the current behaviour does not
make much sense and may change in the future: xc-addr2=xc-addr1+1,
u2=MAX-U, and xc is either 0 or ‘invalid-char’.

‘xc!+?’ ( xc xc-addr1 u1 - xc-addr2 u2 f  ) xchar "x-c-store-plus-query"
   Stores the xchar XC into the buffer starting at address XC-ADDR1, U1
chars large.  XC-ADDR2 points to the first memory location after XC, U2
is the remaining size of the buffer.  If the xchar XC did fit into the
buffer, F is true, otherwise F is false, and XC-ADDR2 U2 equal XC-ADDR1
U1.  XC!+?  is safe against buffer overflows, and therefore preferred
over XC!+.

‘xc!+’ ( xc xc-addr1 - xc-addr2  ) xchar "x-c-store"
   Stores the xchar XC at XC-ADDR1.  XC-ADDR2 is the next unused address
in the buffer.  Note that this writes up to 4 bytes, so you need at
least 3 bytes of padding after the end of the buffer to avoid
overwriting useful data if you only check the address against the end of
the buffer.

‘xchar+’ ( xc-addr1 - xc-addr2  ) xchar "x-char-plus"
   xc-addr2 is the address of the next xchar behind the one pointed to
by xc-addr.

‘xchar-’ ( xc-addr1 - xc-addr2  ) xchar-ext "x-char-minus"
   xc-addr2 is the address of the previous xchar in front of the one
pointed to by xc-addr.

‘+x/string’ ( xc-addr1 u1 - xc-addr2 u2  ) xchar-ext "plus-x-slash-string"
   xc-addr1 u1 is a string of u1 chars.  XC-ADDR2 is the address of the
next xchar behind the one pointed to by xc-addr.  u2 is the size (in
chars) of the rest of the string.

‘x\string-’ ( xc-addr u1 - xc-addr u2  ) xchar-ext "x-backslash-string-minus"
   xc-addr1 u1 is a string of u1 chars.  u2 is the size of the string
without its last xchar.

‘-trailing-garbage’ ( xc-addr u1 - xc-addr u2  ) xchar-ext "minus-trailing-garbage"
   xc-addr1 u1 is a string of u1 chars.  u2 is the size of the string
after removing the chars from the end that do not constitute a complete,
valid xchar.
The idea here is that if you read a fixed number of chars, e.g., with
‘read-file’, there may be an incomplete xchar at the end; you eliminate
that with ‘-trainling-garbage’, leaving a valid xchar string for
processing (if the string starts with a complete xchar and only contains
valid xchars).  You prepend the eliminated chars to the next read block
of chars so you do not miss any parts.

‘x-width’ ( xc-addr u - n  ) xchar-ext
   n is the number of monospace ASCII chars that take the same space to
display as XC-ADDR U needs on a monospaced display.

‘xc-width’ ( xc - n  ) xchar-ext "x-c-width"
   XC has a width of N times the width of a normal fixed-width glyph.

‘xhold’ ( xc -  ) xchar-ext "x-hold"
   Used between ‘<<#’ and ‘#>’.  Prepend XC to the pictured numeric
output string.  We recommend that you use ‘holds’ instead.

‘xc,’ ( xc -  ) xchar "x-c-comma"
   Reserve data space for xc, and store xc in that space.

‘invalid-char’ ( - xc  ) gforth-experimental
   Unicode code point returned for cases where the string does not
contain a valid Unicode encoding.  Current value: the Unicode
replacement character U+FFFD.

‘toupper’ ( xc1 - xc2 ) gforth-0.2 "toupper"
   If xc1 is a lower-case ASCII character, xc2 is the equivalent
upper-case character, otherwise xc2 is xc1.

   See also ‘xemit’ (*note Displaying characters and strings::) and
‘xkey’ (*note Single-key input::).

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

   (1) Of course, you can also store the xchar cell in memory, but
Gforth has no words for dealing with sequences of such cells.


File: gforth.info,  Node: String and character literals,  Next: String words,  Prev: Xchars and Unicode,  Up: Strings and Characters

6.9.3 String and character literals
-----------------------------------

The nicest way to write a string literal is to write it as ‘"STRING"’.
For these kinds of string literals as well as for ‘s\"’ some sequences
are not put in the resulting string as is, but are replaced as shown
below.  The sequences are mostly the same as in C (exceptions noted):

‘\a’
     7 ‘#bell’ (alert)
‘\b’
     8 ‘#bs’ (backspace)
‘\e’
     27 ‘#esc’ (escape, not in C99)
‘\f’
     12 ‘#ff’ (form feed)
‘\l’
     10 ‘#lf’ (line feed, not in C)
‘\m’
     13 10 CR LF (not in C)
‘\n’
     sequence produced by ‘newline’ (in C this produces a LF)
‘\q’
     34 ‘"’ (double quote, not in C)
‘\r’
     13 ‘#cr’ (carriage return)
‘\t’
     9 ‘#tab’ (horizontal tab)
‘\uXXXX’
     Unicode code point XXXX (in hex); auto-merges surrogate pairs (not
     in Forth-2012 nor C)
‘\UXXXXXXXX’
     Unicode code point XXXXXXXX (in hex, not in Forth-2012 nor C)
‘\v’
     11 VT (vertical tab)
‘\xXX’
     raw byte (not code point) XX (in hex)
‘\z’
     0 NUL (not in C)
‘\\’
     ‘\’
‘\"’
     ‘"’ (the ‘\"’ does not terminate the string; not in Forth-2012)
‘\XXX’
     raw byte; XXX is 1-3 octal digits (not in Forth-2012).

   A ‘\’ before any other character is reserved.

   Note that ‘\x’XX produces raw bytes, while ‘\u’XXXX and ‘\U’XXXXXXXX
produce code points for the current encoding.  E.g., if we use UTF-8
encoding and want to encode ä (code point U+00E4), you can write the
letter ä itself, or write ‘\xc3\xa4’ (the UTF-8 bytes for this code
point), ‘\u00e4’, or ‘\U000000e4’.

   The ‘"STRING"’ syntax is non-standard, so for portability you may
want to use one of the following words:

‘s\"’ ( Interpretation 'ccc"' - c-addr u  ) core-ext,file-ext "s-backslash-quote"
   Interpretation: Parse the string ccc delimited by a ‘"’ (but not
‘\"’), and convert escaped characters as described above.  Store the
resulting string in newly allocated heap memory, and push its descriptor
c-addr u.
Compilation ‘( 'ccc"' -- )’: Parse the string ccc delimited by a ‘"’
(but not ‘\"’), and convert escaped characters as described above.
Append the run-time semantics below to the current definition.
Run-time ‘( -- c-addr u )’: Push a descriptor for the resulting string.

‘S"’ ( Interpretation 'ccc"' - c-addr u  ) core,file "s-quote"
   Interpretation: Parse the string ccc delimited by a ‘"’ (double
quote).  Store the resulting string in newly allocated heap memory, and
push its descriptor c-addr u.
Compilation ‘( 'ccc"' -- )’: Parse the string ccc delimited by a ‘"’
(double quote).  Append the run-time semantics below to the current
definition.
Run-time ‘( -- c-addr u )’: Push a descriptor for the parsed string.

   All these ways of interpreting strings consume heap memory; normally
you can just live with the string consuming memory until the end of the
Gforth session, but if that is a problem for some reason, you can ‘free’
the string when you no longer need it.  Forth-2012 only guarantees two
buffers of 80 characters each, so in standard programs you should assume
that the string lives only until the next-but-one ‘s"’.

   On the other hand, the compilation semantics of string literals of
any form allocates the string in the dictionary, and you cannot ‘free’
it, and it lives as long as the word it is compiled into (also in
Forth-2012).

   Likewise, You can get the code xc of a character C with ‘'C'’.  This
way has been standardized since Forth-2012.  An older way to get it is
to use one of the following words:

‘char’ ( '<spaces>ccc' - c  ) core,xchar-ext
   Skip leading spaces.  Parse the string ccc and return c, the display
code representing the first character of ccc.

‘[char]’ ( compilation '<spaces>ccc' - ; run-time - c  ) core,xchar-ext "bracket-char"
   Compilation: skip leading spaces.  Parse the string ccc.  Run-time:
return c, the display code representing the first character of ccc.
Interpretation semantics for this word are undefined.

   You usually use ‘char’ outside and ‘[char]’ inside colon definitions,
or you just use ‘'C'’.

   Note that, e.g.,

     "C" type

is (slightly) more efficient than

     'C' xemit

because the latter converts the code point into a sequence of bytes and
individually ‘emit’s them.  Similarly, dealing with general characters
is usually more efficient when representing them as strings rather than
code points.

   There are the following words for producing commonly-used characters
and strings that cannot be produced with ‘S"’ or ‘'C'’:

‘newline’ ( - c-addr u ) gforth-0.5 "newline"
   String containing the newline sequence of the host OS

‘bl’ ( - c-char  ) core "b-l"
   c-char is the character value for a space.

‘#tab’ ( - c  ) gforth-0.2 "number-tab"

‘#lf’ ( - c  ) gforth-0.2 "number-l-f"

‘#cr’ ( - c  ) gforth-0.2 "number-c-r"

‘#ff’ ( - c  ) gforth-0.2 "number-f-f"

‘#bs’ ( - c  ) gforth-0.2 "number-b-s"

‘#del’ ( - c  ) gforth-0.2 "number-del"

‘#bell’ ( - c  ) gforth-0.2 "number-bell"

‘#esc’ ( - c  ) gforth-0.5 "number-esc"

‘#eof’ ( - c  ) gforth-0.7 "number-e-o-f"
   actually EOT (ASCII code 4 aka ‘^D’)

   See also ‘invalid-char’ (*note Xchars and Unicode::).


File: gforth.info,  Node: String words,  Next: $tring words,  Prev: String and character literals,  Up: Strings and Characters

6.9.4 String words
------------------

Words that are used for memory blocks are also useful for strings, so
for words that move, copy, and fill strings, see *note Memory Blocks::.
For words that display characters and strings, see *note Displaying
characters and strings::.

   The following words work on previously existing strings:

‘compare’ ( c-addr1 u1 c-addr2 u2 - n ) string "compare"
   Compare two strings lexicographically, based on the values of the
bytes in the strings (i.e., case-sensitive and without locale-specific
collation order).  If they are equal, n is 0; if the string in c_addr1
u1 is smaller, n is -1; if it is larger, n is 1.

‘str=’ ( c-addr1 u1 c-addr2 u2 - f  ) gforth-0.6 "str-equals"
   Bytewise equality

‘str<’ ( c-addr1 u1 c-addr2 u2 - f  ) gforth-0.6 "str-less-than"
   Bytewise lexicographic comparison.

‘string-prefix?’ ( c-addr1 u1 c-addr2 u2 - f  ) gforth-0.6 "string-prefix-question"
   Is C-ADDR2 U2 a prefix of C-ADDR1 U1?

‘string-suffix?’ ( c-addr1 u1 c-addr2 u2 - f  ) gforth-1.0 "string-suffix-question"
   Is C-ADDR2 U2 a suffix of C-ADDR1 U1?

‘search’ ( c-addr1 u1 c-addr2 u2 - c-addr3 u3 flag  ) string
   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.

‘scan’ ( c-addr1 u1 c - c-addr2 u2 ) gforth-0.2 "scan"
   Skip all characters not equal to c.  The result starts with c or is
empty.  ‘Scan’ is limited to single-byte (ASCII) characters.  Use
‘search’ to search for multi-byte characters.

‘scan-back’ ( c-addr u1 c - c-addr u2  ) gforth-0.7
   The last occurrence of c in c-addr u1 is at c-addr+u2−1; if it does
not occur, u2=0.

‘skip’ ( c-addr1 u1 c - c-addr2 u2 ) gforth-0.2 "skip"
   Skip all characters equal to c.  The result starts with the first
non-c character, or it is empty.  ‘Scan’ is limited to single-byte
(ASCII) characters.

‘$split’ ( c-addr u char - c-addr u1 c-addr2 u2  ) gforth-0.7 "string-split"
   Divides a string c-addr u into two, with char as separator.  U1 is
the length of the string up to, but excluding the first occurrence of
the separator, c-addr2 u2 is the part of the input string behind the
separator.  If the separator does not occur in the string, u1=u, u2=0
and c-addr2=c-addr+u.

‘nosplit?’ ( addr1 u1 addr2 u2 -  addr1 u1 addr2 u2 flag  ) gforth-experimental "nosplit-question"
   Used on the result of ‘$split’, flag is true if and only if the
separator does not occur in the input string of ‘$split’.

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

‘safe/string’ ( c-addr1 u1 n - c-addr2 u2 ) gforth-1.0 "safe-slash-string"
   Adjust the string specified by c-addr1, u1 to remove n characters
from the start of the string.  Unlike ‘/string’, ‘safe/string’ removes
at least 0 and at most u1 characters.

‘insert’ ( c-addr1 u1 c-addr2 u2 -  ) gforth-0.7
   Move the contents of the buffer c-addr2 u2 towards higher addresses
by u1 chars, and copy the string c-addr1 u1 into the first u1 chars of
the buffer.

‘delete’ ( c-addr u u1 -  ) gforth-0.7
   In the memory block c-addr u, delete the first u1 chars by copying
the contents of the block starting at c-addr+u1 there; fill the u1
characters at the end of the block with blanks.

‘cstring>sstring’ ( c-addr - c-addr u  ) gforth-0.2 "cstring-to-sstring"
   C-addr is the start address of a zero-terminated string, u is its
length.

   The following words compare case-insensitively for ASCII characters,
but case-sensitively for non-ASCII characters (like in lookup in
wordlists).

‘capscompare’ ( c-addr1 u1 c-addr2 u2 - n ) gforth-0.7 "capscompare"
   Compare two strings lexicographically, based on the values of the
bytes in the strings, but comparing ASCII characters case-insensitively,
and non-ASCII characters case-sensitively and without locale-specific
collation order.  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.

‘capsstring-prefix?’ ( c-addr1 u1 c-addr2 u2 - f  ) gforth-1.0 "capsstring-prefix-question"
   Like ‘string-prefix?’, but case-insensitive for ASCII characters: Is
C-ADDR2 U2 a prefix of C-ADDR1 U1?

‘capssearch’ ( c-addr1 u1 c-addr2 u2 - c-addr3 u3 flag  ) gforth-1.0
   Like ‘search’, but case-insensitive for ASCII characters: Search for
c-addr2 u2 in c-addr1 u1; flag is true if found.

   The following words create or extend strings on the heap:

‘s+’ ( c-addr1 u1 c-addr2 u2 - c-addr u  ) gforth-0.7 "s-plus"
   c-addr u is a newly ‘allocate’d string that contains the
concatenation of c-addr1 u1 (first) and c-addr2 u2 (second).

‘append’ ( c-addr1 u1 c-addr2 u2 - c-addr u  ) gforth-0.7
   C-addr u is the concatenation of c-addr1 u1 (first) and c-addr2 u2
(second).  c-addr1 u1 is an ‘allocate’d string, and ‘append’ ‘resize’s
it (possibly moving it to a new address) to accomodate u characters.

‘>string-execute’ ( ... xt - ... c-addr u  ) gforth-1.0 "to-string-execute"
   Execute xt while the standard output (‘type’, ‘emit’, and everything
that uses them) is redirected to a string.  The resulting string is
c-addr u, which is in heap memory; it is the responsibility of the
caller of ‘>string-execute’ to ‘free’ this string.

‘$tmp’ ( xt - addr u  ) gforth-1.0 "string-t-m-p"
   Like ‘>string-execute’, but the result is deallocated when ‘$tmp’ is
invoked the next time, and you must not ‘free’ it yourself.

   One could define ‘s+’ using ‘>string-execute’, as follows:

     : s+ ( c-addr1 u1 c-addr2 u2 -- c-addr u )
       [: 2swap type type ;] >string-execute ;

   For concatenating just two strings ‘>string-execute’ is inefficient,
but for concatenating many strings ‘>string-execute’ can be more
efficient.


File: gforth.info,  Node: $tring words,  Next: Internationalization and localization,  Prev: String words,  Up: Strings and Characters

6.9.5 $tring words
------------------

The following string library stores strings in ordinary cell-size
variables (string handles).  These handles contain a pointer to a
cell-counted string allocated from the heap.  The string library
originates from bigFORTH.

   Because there is only one permanent reference to the contents (the
one in the handle), the string can be relocated or deleted without
worrying about dangling references; this requires that the programmer
uses references produced by, e.g., ‘$@’ only for temporary purposes,
i.e., these references are not passed out, e.g., as return values or
stored in global memory, and words that may change the handle are not
called while these references exist.

   This library is complemented by the cell-pair representation: You use
the $tring words for variable strings which are cumbersome with the
c-addr u representation.  You use the cell-pair representation for
processing (e.g., inspecting) strings while they do not change.

‘$!’ ( addr1 u $addr -  ) gforth-0.7 "string-store"
   stores a newly allocated string buffer at an address, frees the
previous buffer if necessary.

‘$@’ ( $addr - addr2 u  ) gforth-0.7 "string-fetch"
   returns the stored string.

‘$@len’ ( $addr - u  ) gforth-0.7 "string-fetch-len"
   returns the length of the stored string.

‘$!len’ ( u $addr -  ) gforth-0.7 "string-store-len"
   changes the length of the stored string.  Therefore we must change
the memory area and adjust address and count cell as well.

‘$+!len’ ( u $addr - addr  ) gforth-1.0 "string-plus-store-len"
   make room for u bytes at the end of the memory area referenced by
$addr; addr is the address of the first of these bytes.

‘$del’ ( $addr off u -  ) gforth-0.7 "string-del"
   Deletes U bytes at offset OFF bytes in the string $ADDR.

‘$ins’ ( addr1 u $addr off -  ) gforth-0.7 "string-ins"
   Inserts string ADDR1 U at offset OFF bytes in the string $ADDR.

‘$+!’ ( addr1 u $addr -  ) gforth-0.7 "string-plus-store"
   appends a string to another.

‘c$+!’ ( char $addr -  ) gforth-1.0 "c-string-plus-store"
   append a character to a string.

‘$free’ ( $addr -  ) gforth-1.0 "string-free"
   free the string pointed to by addr, and set addr to 0

‘$init’ ( $addr -  ) gforth-1.0 "string-init"
   store an empty string there, regardless of what was in before

‘$iter’ ( .. $addr char xt - ..  ) gforth-0.7 "string-iter"
   Splits the string in $addr using char as separator.  For each part,
its descriptor c-addr u is pushed and xt ‘( ... c-addr u -- ... )’ is
executed.

‘$over’ ( addr u $addr off -  ) gforth-1.0 "string-over"
   Overwrite U bytes at offset OFF bytes in the string $ADDR with the
string at ADDR U.

‘$exec’ ( xt $addr -  ) gforth-1.0 "string-exec"
   execute xt while the standard output (TYPE, EMIT, and everything that
uses them) is appended to the string in $ADDR.

‘$.’ ( $addr -  ) gforth-1.0 "string-dot"
   print a string, shortcut

‘$slurp’ ( fid $addr -  ) gforth-1.0 "string-slurp"
   Read the file fid until the end (without closing it) and put the read
data into the string at $addr.

‘$slurp-file’ ( c-addr u $addr -  ) gforth-1.0 "string-slurp-file"
   Put all the data in the file named c-addr u into the string at $addr.

‘$+slurp’ ( fid $addr -  ) gforth-1.0 "string-plus-slurp"
   Read the file fid until the end (without closing it) and append the
read data to the string at $addr.

‘$+slurp-file’ ( c-addr u $addr -  ) gforth-1.0 "string-plus+slurp-file"
   Append all the data in the file named c-addr u to the string at
$addr.

‘$[]’ ( u $[]addr - addr'  ) gforth-1.0 "string-array"
   Addr' is the address of the uth element of the string array $[]addr.
The array is resized if needed.

‘$[]!’ ( c-addr u n $[]addr -  ) gforth-1.0 "string-array-store"
   Store string c-addr y into the string array $[]addr at index n.  The
array is resized if needed.

‘$[]+!’ ( c-addr u n $[]addr -  ) gforth-1.0 "string-array-plus-store"
   Append the string c-addr u to the string at index n.  The array is
resized if needed.  Don't confuse this with ‘$+[]!’.

‘$+[]!’ ( c-addr u $[]addr -  ) gforth-1.0 "string-append-array"
   Store the string c-addr u as the new last element of string array
$[]addr.  The array is resized if needed.

‘$[]@’ ( n $[]addr - addr u  ) gforth-1.0 "string-array-fetch"
   fetch a string from array index n -- return the zero string if empty,
and don't accidentally grow the array.

‘$[]#’ ( $[]addr - len  ) gforth-1.0 "string-array-num"
   return the number of elements in an array

‘$[]map’ ( $[]addr xt -  ) gforth-1.0 "string-array-map"
   execute XT for all elements of the string array $[]ADDR.  xt is (
ADDR U - ), getting one string at a time

‘$[]slurp’ ( fid $[]addr -  ) gforth-1.0 "string-array-slurp"
   slurp a file FID line by line into a string array $[]ADDR

‘$[]slurp-file’ ( addr u $[]addr -  ) gforth-1.0 "string-array-slurp-file"
   slurp a named file ADDR U line by line into a string array $[]ADDR

‘$[].’ ( $[]addr -  ) gforth-1.0 "string-array-dot"
   print all array entries

‘$[]free’ ( $[]addr -  ) gforth-1.0 "string-array-free"
   $[]ADDR contains the address of a cell-counted string that contains
the addresses of a number of cell-counted strings; $[]free frees these
strings, frees the array, and sets addr to 0

‘$Variable’ ( "name" -  ) gforth-1.0 "string-variable"
   Defines a string variable whose content is preserved across
savesystem

‘$[]Variable’ ( "name" -  ) gforth-1.0 "string-array-variable"
   Defines a string array variable whose content is preserved across
savesystem


File: gforth.info,  Node: Internationalization and localization,  Next: Substitute,  Prev: $tring words,  Up: Strings and Characters

6.9.6 Internationalization and localization
-------------------------------------------

A program may need to communicate with its user in the user's language,
and it may have users with different languages.  We do not want to
produce one version of the program for each language, so we write one
internationalized program that can use localization features to
communicate in the user's language.

   Apart from the words mentioned here, you will probably want to use
Unicode to write the localized strings; you probably do not need to use
the xchar words (*note Xchars and Unicode::) in that context, but they
are there if you need them.

   Moreover, you may need to put placeholders (e.g., for amounts of
currency) in localized strings that you substitute for the real values
later.  The word ‘substitute’ and friends (*note Substitute::) have been
designed for that purpose.

   The basic idea in an internationalized program is that instead of,
e.g.,

     ." Please enter your name:"

   you write

     L" Please enter your name:" locale@ type

   In the following examples, we use the locales defined with

     locale: de    \ German (generic)
     locale: de_AT \ German (as used in Austria)
     locale: de_CH \ German (as used in Switzerland)
     locale: de_DE \ German (as used in Germany)

   In addition, there are the locales ‘program’ and ‘default’.

   You can activate a locale, i.e., make it the current locale, with,
e.g.,

     locales:de_AT

   Note that, unlike most Forth words, locales are case-sensitive, so
‘locales:de_at’ would not work.

   In the following examples, we use the following code to output
localized strings, after first setting the strings (shown later):

     L" Please enter your name:" locale@ cr type
     L" cauliflower" locale@ cr type
     L" street" locale@ cr type
     L" something else" locale@ cr type
     L" bank [geography]" locale@ cr type
     L" bank [finance]" locale@ cr type

   When the current locale is ‘de_AT’, the output is:

     Bitte geben Sie Ihren Namen ein:
     Karfiol
     Straße
     something else
     Ufer
     Bank

   When the current locale is ‘de_CH’, the output is:

     Bitte geben Sie Ihren Namen ein:
     Blumenkohl
     Strasse
     something else
     Ufer
     Bank

   In the localization data used for this example (see below), most of
these localizations are inherited from the locale ‘de’, with the only
‘de_AT’-specific localization being "Karfiol" and the only
‘de_CH’-specific localization being "Strasse".  There is no ‘de’ and no
‘default’ localization for "something else", so the text in the string
‘L" something else"’ is used (we always get that if we use the ‘program’
locale).

   So there is a sequence of fallbacks for looking up localizations: For
the general locale ‘X_Y’, the first fallback is to ‘X’, next to
‘default’, and finally to ‘program’.  If the current locale's name
contains no underscore, the fallback sequence starts at ‘default’.

   The locale ‘default’ is a fallback if there is no more specific
localization (typically, if the localization is missing), as for
"something else".  In many cases (as for "something else") there is no
‘default’ localization, and the fallback continues to the ‘L"’ string.
But in some cases (e.g., in ‘L" bank [geography]"’ and ‘L" bank
[finance]"’) these strings are too developer-oriented, and we put a
user-oriented string ("bank" for both) in the ‘default’ locale.

   So how do we provide the localized string for a given ‘program’
string?  A simple way is to use ‘locale!’, e.g.:

     locales:de_AT
     "Karfiol" L" cauliflower" locale!

   However, defining localizations for all ‘L"’ strings with ‘locale!’
is cumbersome and error-prone (you have to use the exact same spelling
for ‘L"’ strings with ‘locale!’ as before ‘locale@’ in the code).

   A better alternative is to use ‘locale-csv-out’ after loading the
program to save all its ‘L"’ strings and all the existing localizations
to a CSV (comma-separated values) file.  The first column of this file
contains the ‘L"’ strings, the others the various localizations for that
string.  E.g., the CSV file for the example in this section contains:

     "program","default","de","de_AT","de_CH","de_DE"
     "bank [finance]","bank","Bank","","",""
     "bank [geography]","bank","Ufer","","",""
     "Please enter your name:","","Bitte geben Sie Ihren Namen ein:","","",""
     "cauliflower","","Blumenkohl","Karfiol","",""
     "street","","Straße","","Strasse",""
     "something else","","","","",""

   The first line contains the names of the locales.  Many entries
contain empty strings; in that case, there is no localization for the
‘L"’ string for the locale of that column (and ‘locale@’ will use the
next fallback that is not empty.

   The way to add localizations is to edit the CSV file.  This is not
easy with a simple text editor if there are many columns.  One way to
work around this is to use a spreadsheet program or an editor that has
good CSV support.  Another way is to distribute the localizations across
several files (which is also better for letting several people work on
the localizations at the same time).  E.g., one file could contain the
localizations for ‘de’ and its variants, while another could contain the
localizations for ‘fr’ (French) and its variants.

   Once a localization has been edited into a CSV file, one can load the
CSV file with ‘locale-csv’.  All the locales mentioned in the CSV file
will be defined automatically; if you use ‘locale-csv’, do not use
‘locale:’ afterwards for the locales in the CSV file.

   The lines in the CSV file are ordered by the order in which the ‘L"’
strings are found by Gforth.  If the CSV file is generated just from the
‘L"’ strings in the program, this order may be helpful for producing the
localizations, because related ‘L"’ strings are grouped together.  If,
during maintenance, new ‘L"’ strings are added, and you first load the
CSV file, then the program, and then write out a CSV file, you will find
the new ‘L"’ strings (for localizing) at the end of the new CSV file.

   A “locale-string identifier” (“lsid”) is an opaque token that
occupies a cell, and it identifies the ‘L"’ string.

‘L"’ ( Interpretation "string<">" - lsid; Compilation "string<">" -  ) gforth-experimental "l-quote"
   At text interpretation time, parse string.  At run-time, push the
lsid associated with string.  Each string has a unique lsid.  If no lsid
for the string exists yet, a new one is created.  If an lsid for the
string exists already, that lsid is returned.  This means that one can
refer to and use the same lsid with ‘L"’ in different locations in the
source code, by uing the same string.  If you want two different lsids
(e.g., because you refer to two different concepts), but would use the
same user-centric text in ‘L"’, append " [specifier]" to the text, e.g.
‘L" bank [finance]"’ or ‘L" bank [geography]"’.  You may then want to
add a user-centric non-unique ‘default’ localization (e.g., "bank").

‘locales’ ( -  ) gforth-experimental
   This case-sensitive vocabulary contains the locales.  Typical use:
‘locales:locale’.

‘native@’ ( lsid - c-addr u  ) gforth-experimental "native-fetch"
   c-addr u is the ‘L"’ string for lsid (i.e., the text-interpretation
argument of ‘L"’).

‘locale@’ ( lsid - c-addr u  ) gforth-experimental "locale-fetch"
   c-addr u is the localized string for lsid in the current locale.  If
no localized string is found in the current locale with a name of the
form ‘X_Y’, lsid is looked up in locale ‘X’.  If no localized string is
found in the locale ‘X’, lsid is looked up in the locale ‘default’.  If
no localized string is found in the locale ‘default’, lsid is looked up
in the locale ‘program’ (i.e., c-addr u is the text-interpretation
argument of ‘L"’).

‘program’ ( -  ) gforth-experimental
   ‘locales:program’ becomes the current locale.  When this locale is
current, ‘locale@’ produces the string used for identifying the lsid
(i.e., the string parsed by ‘L"’).  This locale is useful for
development: One can see which lsid is used in which context.

‘default’ ( -  ) gforth-experimental
   ‘locales:default’ is the default locale if the user has not set one.
Most lsids don't have a specific default string, so fallback to the
‘program’ locale happens.  But if you have a developer-centric program
string that is inappropriate for end users (in particular, if the
program string contains an extra specifier), you will prefer to define a
user-centric string in the default locale.

‘locale-csv-out’ ( "name" -  ) gforth-experimental "locale-csv-out"
   Create file NAME and write the locale database to this in CSV format.

‘locale-csv’ ( "name" -  ) gforth-experimental "locale-csv"
   Import comma-separated value (CSV) table into locales.  The first
line contains the locale names (column headers).  The ‘program’ locale
must be leftmost.  Fallback locales like ‘de’ must precede more specific
locales like ‘de_AT’.  The other lines contain the ‘L"’ string (first
column) and the corresponding localizations.  Each column contains the
localizations for a specific locale.  Empty entries mean that this
locale does not define a localization for this ‘L"’ string, resulting in
using the localization from a fallback locale instead.

‘.locale-csv’ ( -  ) gforth-experimental "dot-locale-csv"
   Write the locale database in CSV format to the user output device.

‘locale!’ ( addr u lsid -  ) gforth-experimental "locale-store"
   After executing ‘locale!’, the localized string for lsid in the
current locale is c-addr u.

‘Locale:’ ( "name" -  ) gforth-experimental "Locale-colon"
   Defines a new locale l with name name in ‘locales’.
name execution: ( - ) l becomes the current locale.
For locales with names of the form ‘X_Y’, define ‘X’ first in order to
establish ‘X’ as a fallback for ‘X_Y’.


File: gforth.info,  Node: Substitute,  Next: Counted string words,  Prev: Internationalization and localization,  Up: Strings and Characters

6.9.7 Substitute
----------------

This is a simple text macro replacement facility; it is particularly
useful for working with localized strings (*note Internationalization
and localization::).  In other contexts, using ‘>string-execute’ (*note
String words::) is often easier.

   When using ‘substitute’, strings in the form ‘"text%macro%text"’
(with an arbitrary number of macros) are processed, and the macro
variables enclosed in ‘'%'’ are replaced by their associated strings.
Two consecutive ‘%’ are replaced by one ‘%’.  Macros are defined in a
specific wordlist, and return a string upon execution; the standard
defines only one way to declare macros, ‘replaces’, which creates a
macro that just returns a string.

‘macros-wordlist’ ( - wid  ) gforth-experimental
   wordlist for string replacement macros

‘replaces’ ( addr1 len1 addr2 len2 -  ) string-ext
   create a macro with name ADDR2 LEN2 and content ADDR1 LEN1.  If the
macro already exists, just change the content.

‘replacer:’ ( "name" -  ) gforth-experimental "replacer-colon"
   Start a colon definition name in ‘macros-wordlist’, i.e.  this colon
definition is a macro.  It must have the stack effect ( - ADDR U ).

‘.substitute’ ( addr1 len1 - n / ior  ) gforth-experimental "dot-substitute"
   substitute all macros in text ADDR1 LEN1 and print the result.  N is
the number of substitutions or, if negative, a throwable IOR.

‘$substitute’ ( addr1 len1 - addr2 len2 n/ior  ) gforth-experimental "string-substitute"
   substitute all macros in text ADDR1 LEN1.  N is the number of
substitutions, if negative, it's a throwable IOR, ADDR2 LEN2 the result.

‘substitute’ ( addr1 len1 addr2 len2 - addr2 len3 n/ior  ) string-ext
   substitute all macros in text ADDR1 LEN1, and copy the result to
ADDR2 LEN2.  N is the number of substitutions or, if negative, a
throwable IOR, ADDR2 LEN3 the result.

‘unescape’ ( addr1 u1 dest - dest u2  ) string-ext
   double all delimiters in ADDR1 U1, so that substitute will result in
the original text.  Note that the buffer DEST does not have a size, as
in worst case, it will need just twice as many characters as U1.  DEST
U2 is the resulting string.

‘$unescape’ ( addr1 u1 - addr2 u2  ) gforth-experimental "string-unescape"
   same as ‘unescape’, but creates a temporary destination string with
‘$tmp’.


File: gforth.info,  Node: Counted string words,  Prev: Substitute,  Up: Strings and Characters

6.9.8 Counted string words
--------------------------

Counted strings store the length as byte at the address pointed to,
followed by the bytes of the string.  Their possible length is severely
limited, and you cannot create a substring in-place without destroying
the input string.  Therefore we recommend against using counted strings.
Nevertheless, if you have to deal with counted strings, here are some
words for that:

‘count’ ( c-addr1 - c-addr2 u ) core "count"
   c-addr2 is the first character and u the length of the counted string
at c-addr1.

   The following word has no useful interpretation semantics (unlike
‘s"’) and no interpretive counterpart (unlike ‘[char]’), so you should
use it only inside colon definitions (if at all):

‘C"’ ( compilation "ccc<quote>" - ; run-time  - c-addr  ) core-ext "c-quote"
   Compilation: parse a string ccc delimited by a ‘"’ (double quote).
At run-time, return c-addr which specifies the counted string ccc.
Interpretation semantics are undefined.

‘place’ ( c-addr1 u c-addr2 -  ) gforth-experimental "place"
   Create a counted string of length U at C-ADDR2 and copy the string
C-ADDR1 U into that location.  Up to 256 bytes starting at C-ADDR2 will
be written, so make sure that the buffer at c-addr2 has that much space
(or check that u+1 does not exceed the buffer size before calling
‘place’)

‘string,’ ( c-addr u -  ) gforth-0.2 "string-comma"
   Reserve u+1 bytes of dictionary space and store the string c-addr u
there as counted string.


File: gforth.info,  Node: Control Structures,  Next: Defining Words,  Prev: Strings and Characters,  Up: Words

6.10 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 ... THEN
* General Loops::               BEGIN ...
* Counted Loops::               DO
* General loops with multiple exits::
* General control structures with CASE::
* Arbitrary control structures::
* Calls and returns::
* Exception Handling::

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

   (1) To be precise, in Standard Forth the control-flow words have no
interpretation semantics, and in Gforth the interpretation semantics of
the control-flow words are not useful for interpretive control flow
(*note Interpretation and Compilation Semantics::).


File: gforth.info,  Node: Selection,  Next: General Loops,  Prev: Control Structures,  Up: Control Structures

6.10.1 Selection
----------------

     flag IF
       code
     THEN

   If flag is non-zero (as far as ‘IF’ etc.  are concerned, a non-zero
cell represents truth), code is executed.

   You may wonder why ‘then’ ends an ‘if’ construct, which is at odds
with the usage of ‘then’ in some other programming languages, and with
the idiom "if ...  then ..."  in English.  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.  If you do not like this
usage of ‘then’, Gforth (but not Standard Forth) also has ‘endif’, which
can be used in its place.  Adding ‘ENDIF’ to a system that only supplies
‘THEN’ is simple:
     : ENDIF   POSTPONE then ; immediate

     flag IF
       code1
     ELSE
       code2
     THEN

   If FLAG is true, code1 is executed, otherwise code2 is executed.

   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 Standard Forth for ‘ENDIF’, ‘?DUP-IF’
and ‘?DUP-0=-IF’ are provided in ‘compat/control.fs’.

     x
     CASE
       x1 OF code1 ENDOF
       x2 OF code2 ENDOF
       ...
       ( x ) default-code ( x )
     ENDCASE ( )

   Executes the first codei, where the xi is equal to x.  If no xi
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 x, which is on top of the stack, but must not consume it.  The
value x is consumed by this construction (either by an ‘OF’ that
matches, or by the ‘ENDCASE’, if no OF matches).  Example:

     : num-name ( n -- c-addr u )
      case
        0 of s" zero " endof
        1 of s" one "  endof
        2 of s" two "  endof
        \ default case:
        s" other number"
        rot \ get n on top so ENDCASE can drop it
      endcase ;

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


File: gforth.info,  Node: General Loops,  Next: Counted Loops,  Prev: Selection,  Up: Control Structures

6.10.2 General 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.  You can leave it by leaving the enclosing
colon definition with ‘exit’ or ‘throw’, or with ‘while’ (*note General
loops with multiple exits::).


File: gforth.info,  Node: Counted Loops,  Next: General loops with multiple exits,  Prev: General Loops,  Up: Control Structures

6.10.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’.

   You can access the limit of the innermost loop with ‘i'’ and ‘i'’-‘i’
with ‘delta-i’.  E.g., running

     : foo 7 5 ?do cr i . i' . delta-i . loop ;

   prints

     5 7 2
     6 7 1

   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.

     We recommend not combining ‘?DO’ with ‘+LOOP’.  Gforth offers
     several alternatives:

     If you want ‘-1 +LOOP’'s behaviour of including an iteration where
     ‘I’=limit, start the loop with ‘-[DO’ or ‘U-[DO’ (where the ‘[’ is
     inspired by the mathematical notation for inclusive ranges, e.g.,
     [1,n]):

          -1 0 -[DO  i .  -1 +LOOP

     prints ‘0 -1’.

          0 0 -[DO  i .  -1 +LOOP

     prints ‘0’.

          0 -1 -[DO  i .  -1 +LOOP

     prints nothing.

     If you want to exclude the limit, you instead use ‘1 -LOOP’ (or
     generally ‘u -LOOP’) and start the loop with ‘?DO’, ‘-DO’ or
     ‘U-DO’.  ‘-LOOP’ terminates the loop when the border between
     limit+1 and limit is crossed.  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 Standard Forth.  However, an implementation for these
     words that uses only standard words is provided in
     ‘compat/loops.fs’.

   • A common task is to iterate over the elements of an array, forwards
     or backwards.  Iterating over the addresses of the elements has two
     benefits: It avoids the need to keep the start address of the array
     around, reducing the data stack load; and it avoids the need to
     perform address computations in every iteration.  The disadvantage
     is that, starting with the usual array representations addr uelems
     or addr ubytes, some processing is required to produce a start and
     limit address.  Gforth has ‘bounds’ for getting there from the addr
     ubytes representation, so you can write a forward loop through a
     cell array ‘v’ as:

          create v 1 , 3 , 7 ,
          : foo v 3 cells bounds U+DO i @ . cell +LOOP ;
          foo

     which prints ‘1 3 7’.  Preprocessing the inputs for walking
     backwards is more involved, so Gforth provide a loop construct of
     the form ‘MEM-DO’...‘LOOP’ that does it for you: It takes an array
     in addr ubytes representation and the element size, and iterates
     over the addresses of the elements in backwards order:

          create v 1 , 3 , 7 ,
          : foo1 v 3 cell array>mem MEM-DO i @ . LOOP ;
          foo1

     This prints ‘7 3 1’.  ‘ARRAY>MEM’ converts the addr uelems
     uelemsize representation into the addr ubytes uelemsize
     representation expected by ‘MEM-DO’.  This loop is finished with
     ‘LOOP’ which decrements by uelemsize when it finishes a ‘MEM-DO’.

     Gforth also adds ‘MEM+DO’ for completeness.  It takes the same
     parameters as ‘MEM-DO’, but walks forwards through the array:

          create v 1 , 3 , 7 ,
          : foo2 v 3 cell array>mem MEM+DO i @ . LOOP ;
          foo2

     prints ‘1 3 7’.

   • 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 Standard 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.

   The counted-loop words are:

‘?DO’ ( compilation - do-sys ; run-time w1 w2 - | loop-sys  ) core-ext "question-do"
   *Note Counted Loops::.

‘+DO’ ( compilation - do-sys ; run-time n1 n2 - | loop-sys  ) gforth-0.2 "plus-do"
   *Note Counted Loops::.

‘U+DO’ ( compilation - do-sys ; run-time u1 u2 - | loop-sys  ) gforth-0.2 "u-plus-do"
   *Note Counted Loops::.

‘bounds’ ( u1 u2 - u3 u1 ) gforth-0.2 "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’.

‘-[do’ ( compilation - do-sys ; run-time n1 n2 - | loop-sys  ) gforth-experimental "minus-bracket-do"
   Start of a counted loop with negative stride; Skips the loop if
n2<n1; such a counted loop ends with ‘+loop’ where the increment is
negative; it runs as long as ‘I’>=n1.

‘u-[do’ ( compilation - do-sys ; run-time u1 u2 - | loop-sys  ) gforth-experimental "u-minus-bracket-do"
   Start of a counted loop with negative stride; Skips the loop if
u2<u1; such a counted loop ends with ‘+loop’ where the increment is
negative; it runs as long as ‘I’>=u1.

‘-DO’ ( compilation - do-sys ; run-time n1 n2 - | loop-sys  ) gforth-0.2 "minus-do"
   *Note Counted Loops::.

‘U-DO’ ( compilation - do-sys ; run-time u1 u2 - | loop-sys  ) gforth-0.2 "u-minus-do"
   *Note Counted Loops::.

‘array>mem’ ( uelements uelemsize - ubytes uelemsize  ) gforth-experimental "array-to-mem"
   ubytes=uelements*uelemsize

‘mem+do’ ( compilation - w xt do-sys; run-time addr ubytes +nstride -  ) gforth-experimental "mem-plus-do"
   Starts a counted loop that starts with ‘I’ as addr and then steps
upwards through memory with nstride wide steps as long as
‘I’<addr+ubytes.  Must be finished with ‘loop’.

‘mem-do’ ( compilation - w xt do-sys; run-time addr ubytes +nstride -  ) gforth-experimental "mem-minus-do"
   Starts a counted loop that starts with ‘I’ as addr+ubytes-nstride and
then steps backwards through memory with -nstride wide steps as long as
‘I’>=addr.  Must be finished with ‘loop’.

‘DO’ ( compilation - do-sys ; run-time w1 w2 - loop-sys  ) core
   *Note Counted Loops::.

‘FOR’ ( compilation - do-sys ; run-time u - loop-sys  ) gforth-0.2
   *Note Counted Loops::.

‘LOOP’ ( compilation do-sys - ; run-time loop-sys1 - | loop-sys2  ) core
   Finish a counted loop.  If started with ‘mem+do’ or ‘mem-do’, the
stride (increment) and terminating condition is given by these words,
otherwise the stride is 1 and the loop ends when the limit is reached
(the last iteration has ‘i’=limit-1).

‘+LOOP’ ( compilation do-sys - ; run-time loop-sys1 n - | loop-sys2  ) core "plus-loop"
   *Note Counted Loops::.

‘-LOOP’ ( compilation do-sys - ; run-time loop-sys1 u - | loop-sys2  ) gforth-0.2 "minus-loop"
   *Note Counted Loops::.

‘NEXT’ ( compilation do-sys - ; run-time loop-sys1 - | loop-sys2  ) gforth-0.2
   *Note Counted Loops::.

‘i’ ( R:n - R:n n ) core "i"
   n is the index of the innermost counted loop.

‘j’ ( R:n R:w1 R:w2 - n R:n R:w1 R:w2 ) core "j"
   n is the index of the next-to-innermost counted loop.

‘k’ ( R:n R:w1 R:w2 R:w3 R:w4 - n R:n R:w1 R:w2 R:w3 R:w4 ) gforth-0.3 "k"
   n is the index of the third-innermost counted loop.

‘i'’ ( R:w R:w2 - R:w R:w2 w ) gforth-0.2 "i-tick"
   The limit of the innermost counted loop

‘delta-i’ ( r:ulimit r:u - r:ulimit r:u u2 ) gforth-1.0 "delta-i"
   u2=‘I'’-‘I’ (difference between limit and index).

‘LEAVE’ ( compilation - ; run-time loop-sys -  ) core
   *Note Counted Loops::.

‘?LEAVE’ ( compilation - ; run-time f | f loop-sys -  ) gforth-0.2 "question-leave"
   *Note Counted Loops::.

‘unloop’ ( R:w1 R:w2 - ) core "unloop"

‘DONE’ ( compilation do-sys - ; run-time -  ) gforth-0.2
   resolves all LEAVEs up to the do-sys

   The standard does not allow using ‘CS-PICK’ and ‘CS-ROLL’ on do-sys.
Gforth allows it, except for the do-sys produced by ‘MEM+DO’ and
‘MEM-DO’, 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’).

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

   (1) Not in a way that is portable.


File: gforth.info,  Node: General loops with multiple exits,  Next: General control structures with CASE,  Prev: Counted Loops,  Up: Control Structures

6.10.4 General loops with multiple exits
----------------------------------------

For counted loops, you can use ‘leave’ in several places.  For ‘begin’
loops, you have the following options:

   Use ‘exit’ (possibly several times) in the loop to leave not just the
loop, but the whole colon definition.  E.g.,:

     : foo
       begin
         condition1 while
           condition2 if
             exit-code2 exit then
           condition3 if
             exit-code3 exit then
         ...
       repeat
       exit-code1 ;

   The disadvantage of this approach is that, if you want to have some
common code afterwards, you either have to wrap ‘foo’ in another
definition that contains the common code, or you have to call the common
code several times, from each exit-code.

   Another approach is to use several ‘while’s in a ‘begin’ loop.  You
have to append a ‘then’ behind the loop for every additional ‘while’.
E.g.,;

     begin
       condition1 while
         condition2 while
           condition3 while
     again then then then

   Here I used ‘again’ at the end of the loop so that I would have a
‘then’ for each ‘while’; ‘repeat’ would result in one less ‘then’, but
otherwise the same behaviour.  For an explanation of why this works,
*Note Arbitrary control structures::.

   We can have common code afterwards, but, as presented above, we
cannot have different exit-codes for the different exits.  You can have
these different exit-codes, as follows:

     begin
       condition1 while
         condition2 while
           condition3 while
     again then exit-code3
     else exit-code2 then
     else exit-code1 then

   This is relatively hard to comprehend, because the exit-codes are
relatively far from the exit conditions (it does not help that we are
not used to such control structures, either).  The following extended
‘case’ does not have this problem.


File: gforth.info,  Node: General control structures with CASE,  Next: Arbitrary control structures,  Prev: General loops with multiple exits,  Up: Control Structures

6.10.5 General control structures with ‘case’
---------------------------------------------

Gforth provides an extended ‘case’ that solves the problems of the
multi-exit loops discussed above, and offers additional options.  You
can find a portable implementation of this extended ‘case’ in
‘compat/caseext.fs’.

   There are three additional words in the extension.  The first is
‘?of’ which allows general tests (rather than just testing for equality)
in a ‘case’; e.g.,

     : sgn ( n -- -1|0|1 )
       ( n ) case
         dup 0 < ?of drop -1 endof
         dup 0 > ?of drop 1  endof
         \ otherwise leave the 0 on the stack
       0 endcase ;

   Note that ‘endcase’ drops a value, which works fine much of the time
with ‘of’, but usually not with ‘?of’, so we leave a 0 on the stack for
‘endcase’ to drop.  The n that is passed into ‘sgn’ is also 0 if neither
‘?of’ triggers, and that is then passed out.

   The second additional word is ‘next-case’, which allows turning
‘case’ into a loop.  Our triple-exit loop becomes:

     case
       condition1 ?of exit-code1 endof
       condition2 ?of exit-code2 endof
       condition3 ?of exit-code3 endof
       ...
     next-case
     common code afterwards

   As you can see, this solves both problems of the variants discussed
above (*note General loops with multiple exits::).  Note that
‘next-case’ does not drop a value, unlike ‘endcase’.(1)

   The last additional word is ‘contof’, which is used instead of
‘endof’ and starts the next iteration instead of leaving the loop.  This
can be used in ways similar to Dijkstra's guarded command do, e.g.:

     : gcd ( n1 n2 -- n )
         case
             2dup > ?of tuck - contof
             2dup < ?of over - contof
         endcase ;

   Here the two ‘?of’s have different ways of continuing the loop; when
neither ‘?of’ triggers, the two numbers are equal and are the gcd.
‘Endcase’ drops one of them, leaving the other as n.

   You can also combine these words.  Here's an example that uses each
of the ‘case’ words once, except ‘endcase’:

     : collatz ( u -- )
         \ print the 3n+1 sequence starting at u until we reach 1
         case
             dup .
             1 of endof
             dup 1 and ?of 3 * 1+ contof
             2/
         next-case ;

   This example keeps the current value of the sequence on the stack.
If it is 1, the ‘of’ triggers, drops the value, and leaves the ‘case’
structure.  For odd numbers, the ‘?of’ triggers, computes 3n+1, and
starts the next iteration with ‘contof’.  Otherwise, if the number is
even, it is divided by 2, and the loop is restarted with ‘next-case’.

   The ‘case’ words are:

‘case’ ( compilation  - case-sys ; run-time  -  ) core-ext
   Start a ‘case’ structure.

‘endcase’ ( compilation case-sys - ; run-time x -  ) core-ext "end-case"
   Finish the ‘case’ structure; drop x, and continue behind the
‘endcase’.  Dropping x is useful in the original ‘case’ construct (with
only ‘of’s), but you may have to supply an x in other cases (especially
when using ‘?of’).

‘next-case’ ( compilation case-sys - ; run-time -  ) gforth-1.0
   Restart the ‘case’ loop by jumping to the matching ‘case’.  Note that
‘next-case’ does not drop a cell, unlike ‘endcase’.

‘of’ ( compilation  - of-sys ; run-time x1 x2 - |x1  ) core-ext
   If x1=x2, continue (dropping both); otherwise, leave x1 on the stack
and jump behind ‘endof’ or ‘contof’.

‘?of’ ( compilation  - of-sys ; run-time  f -  ) gforth-1.0 "question-of"
   If f is true, continue; otherwise, jump behind ‘endof’ or ‘contof’.

‘endof’ ( compilation case-sys1 of-sys - case-sys2 ; run-time  -  ) core-ext "end-of"
   Exit the enclosing ‘case’ structure by jumping behind
‘endcase’/‘next-case’.

‘contof’ ( compilation case-sys1 of-sys - case-sys2 ; run-time  -  ) gforth-1.0 "cont-of"
   Restart the ‘case’ loop by jumping to the enclosing ‘case’.

Internally, of-sys is an ‘orig’; and case-sys is a cell and some
stack-depth information, 0 or more ‘orig’s, and a ‘dest’.

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

   (1) The name ‘next-case’ has a ‘-’, unlike the other ‘case’ words,
because VFX Forth has a ‘next-case’ that works like Gforth's
‘next-case’, but also contains a ‘nextcase’ that drops a value; in VFX
you need to pair ‘next-case’ with ‘begincase’, however.

