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

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

   This file documents Gforth 0.5.0

   Copyright (C) 1995-2000 Free Software Foundation, Inc.

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

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

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


File: gforth.info,  Node: Literals,  Next: Macros,  Prev: Compiling words,  Up: Compiling words

Literals
--------

   The simplest and most frequent example is to compute a literal during
compilation.  E.g., the following definition prints an array of strings,
one string per line:

     : .strings ( addr u -- ) \ gforth
         2* cells bounds U+DO
     	cr i 2@ type
         2 cells +LOOP ;

   With a simple-minded compiler like Gforth's, this computes `2 cells'
on every loop iteration.  You can compute this value once and for all
at compile time and compile it into the definition like this:

     : .strings ( addr u -- ) \ gforth
         2* cells bounds U+DO
     	cr i 2@ type
         [ 2 cells ] literal +LOOP ;

   `[' switches the text interpreter to interpret state (you will get
an `ok' prompt if you type this example interactively and insert a
newline between `[' and `]'), so it performs the interpretation
semantics of `2 cells'; this computes a number.  `]' switches the text
interpreter back into compile state.  It then performs `Literal''s
compilation semantics, which are to compile this number into the
current word.  You can decompile the word with `see .strings' to see
the effect on the compiled code.

   You can also optimize the `2* cells' into `[ 2 cells ] literal *' in
this way.

`['       -         core       ``left-bracket''
   Enter interpretation state. Immediate word.

`]'       -         core       ``right-bracket''
   Enter compilation state.

`Literal'       compilation n - ; run-time - n         core       ``Literal''
   Compilation semantics: compile the run-time semantics.
Run-time Semantics: push n.
Interpretation semantics: undefined.

`]L'       compilation: n - ; run-time: - n         gforth       ``]L''
   equivalent to `] literal'

   There are also words for compiling other data types than single
cells as literals:

`2Literal'       compilation w1 w2 - ; run-time  - w1 w2         double       ``two-literal''
   Compile appropriate code such that, at run-time, cell pair w1, w2 are
placed on the stack. Interpretation semantics are undefined.

`FLiteral'       compilation r - ; run-time - r         float       ``f-literal''
   Compile appropriate code such that, at run-time, r is placed on the
(floating-point) stack. Interpretation semantics are undefined.

`SLiteral'       Compilation c-addr1 u ; run-time - c-addr2 u         string       ``SLiteral''
   Compilation: compile the string specified by c-addr1, u into the
current definition. Run-time: return c-addr2 u describing the address
and length of the string.

   You might be tempted to pass data from outside a colon definition to
the inside on the data stack.  This does not work, because `:' puhes a
colon-sys, making stuff below unaccessible.  E.g., this does not work:

     5 : foo literal ; \ error: "unstructured"

   Instead, you have to pass the value in some other way, e.g., through
a variable:

     variable temp
     5 temp !
     : foo [ temp @ ] literal ;


File: gforth.info,  Node: Macros,  Prev: Literals,  Up: Compiling words

Macros
------

   `Literal' and friends compile data values into the current
definition.  You can also write words that compile other words into the
current definition.  E.g.,

     : compile-+ ( -- ) \ compiled code: ( n1 n2 -- n )
       POSTPONE + ;
     
     : foo ( n1 n2 -- n )
       [ compile-+ ] ;
     1 2 foo .

   This is equivalent to `: foo + ;' (`see foo' to check this).  What
happens in this example?  `Postpone' compiles the compilation semantics
of `+' into `compile-+'; later the text interpreter executes
`compile-+' and thus the compilation semantics of +, which compile (the
execution semantics of) `+' into `foo'.(1)

`POSTPONE'       "name" -         core       ``POSTPONE''
   Compiles the compilation semantics of name.

`[compile]'       compilation "name" - ; run-time ? - ?         core-ext       ``bracket-compile''

   Compiling words like `compile-+' are usually immediate (or similar)
so you do not have to switch to interpret state to execute them;
mopifying the last example accordingly produces:

     : [compile-+] ( compilation: --; interpretation: -- )
       \ compiled code: ( n1 n2 -- n )
       POSTPONE + ; immediate
     
     : foo ( n1 n2 -- n )
       [compile-+] ;
     1 2 foo .

   Immediate compiling words are similar to macros in other languages
(in particular, Lisp).  The important differences to macros in, e.g., C
are:

   * You use the same language for defining and processing macros, not a
     separate preprocessing language and processor.

   * Consequently, the full power of Forth is available in macro
     definitions.  E.g., you can perform arbitrarily complex
     computations, or generate different code conditionally or in a
     loop (e.g., *note Advanced macros Tutorial::).  This power is very
     useful when writing a parser generators or other code-generating
     software.

   * Macros defined using `postpone' etc. deal with the language at a
     higher level than strings; name binding happens at macro definition
     time, so you can avoid the pitfalls of name collisions that can
     happen in C macros.  Of course, Forth is a liberal language and
     also allows to shoot yourself in the foot with text-interpreted
     macros like

          : [compile-+] s" +" evaluate ; immediate

     Apart from binding the name at macro use time, using `evaluate'
     also makes your definition `state'-smart (*note state-smartness::).

   You may want the macro to compile a number into a word.  The word to
do it is `literal', but you have to `postpone' it, so its compilation
semantics take effect when the macro is executed, not when it is
compiled:

     : [compile-5] ( -- ) \ compiled code: ( -- n )
       5 POSTPONE literal ; immediate
     
     : foo [compile-5] ;
     foo .

   You may want to pass parameters to a macro, that the macro should
compile into the current definition.  If the parameter is a number, then
you can use `postpone literal' (similar for other values).

   If you want to pass a word that is to be compiled, the usual way is
to pass an execution token and `compile,' it:

     : twice1 ( xt -- ) \ compiled code: ... -- ...
       dup compile, compile, ;
     
     : 2+ ( n1 -- n2 )
       [ ' 1+ twice1 ] ;

`compile,'       xt -         core-ext       ``compile-comma''
    Compile the word represented by the execution token xt  into the
current definition.

   An alternative available in Gforth, that allows you to pass
compile-only words as parameters is to use the compilation token (*note
Compilation token::).  The same example in this technique:

     : twice ( ... ct -- ... ) \ compiled code: ... -- ...
       2dup 2>r execute 2r> execute ;
     
     : 2+ ( n1 -- n2 )
       [ comp' 1+ twice ] ;

   In the example above `2>r' and `2r>' ensure that `twice' works even
if the executed compilation semantics has an effect on the data stack.

   You can also define complete definitions with these words; this
provides an alternative to using `does>' (*note User-defined Defining
Words::).  E.g., instead of

     : curry+ ( n1 "name" -- )
         CREATE ,
     DOES> ( n2 -- n1+n2 )
         @ + ;

   you could define

     : curry+ ( n1 "name" -- )
       \ name execution: ( n2 -- n1+n2 )
       >r : r> POSTPONE literal POSTPONE + POSTPONE ; ;
     
     -3 curry+ 3-
     see 3-

   The sequence `>r : r>' is necessary, because `:' puts a colon-sys on
the data stack that makes everything below it unaccessible.

   This way of writing defining words is sometimes more, sometimes less
convenient than using `does>' (*note Advanced does> usage example::).
One advantage of this method is that it can be optimized better,
because the compiler knows that the value compiled with `literal' is
fixed, whereas the data associated with a `create'd word can be changed.

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

   (1) A recent RFI answer requires that compiling words should only be
executed in compile state, so this example is not guaranteed to work on
all standard systems, but on any decent system it will work.


File: gforth.info,  Node: The Text Interpreter,  Next: Word Lists,  Prev: Compiling words,  Up: Words

The Text Interpreter
====================

   The text interpreter(1) is an endless loop that processes input from
the current input device. It is also called the outer interpreter, in
contrast to the inner interpreter (*note Engine::) which executes the
compiled Forth code on interpretive implementations.

   The text interpreter operates in one of two states: "interpret
state" and "compile state". The current state is defined by the
aptly-named variable `state'.

   This section starts by describing how the text interpreter behaves
when it is in interpret state, processing input from the user input
device - the keyboard. This is the mode that a Forth system is in after
it starts up.

   The text interpreter works from an area of memory called the "input
buffer"(2), which stores your keyboard input when you press the <RET>
key. Starting at the beginning of the input buffer, it skips leading
spaces (called "delimiters") then parses a string (a sequence of
non-space characters) until it reaches either a space character or the
end of the buffer. Having parsed a string, it makes two attempts to
process it:

   * It looks for the string in a "dictionary" of definitions. If the
     string is found, the string names a "definition" (also known as a
     "word") and the dictionary search returns information that allows
     the text interpreter to perform the word's "interpretation
     semantics". In most cases, this simply means that the word will be
     executed.

   * If the string is not found in the dictionary, the text interpreter
     attempts to treat it as a number, using the rules described in
     *Note Number Conversion::. If the string represents a legal number
     in the current radix, the number is pushed onto a parameter stack
     (the data stack for integers, the floating-point stack for
     floating-point numbers).

   If both attempts fail, or if the word is found in the dictionary but
has no interpretation semantics(3) the text interpreter discards the
remainder of the input buffer, issues an error message and waits for
more input. If one of the attempts succeeds, the text interpreter
repeats the parsing process until the whole of the input buffer has been
processed, at which point it prints the status message "` ok'" and
waits for more input.

   The text interpreter keeps track of its position in the input buffer
by updating a variable called `>IN' (pronounced "to-in"). The value of
`>IN' starts out as 0, indicating an offset of 0 from the start of the
input buffer. The region from offset `>IN @' to the end of the input
buffer is called the "parse area"(4).  This example shows how `>IN'
changes as the text interpreter parses the input buffer:

     : remaining >IN @ SOURCE 2 PICK - -ROT + SWAP
       CR ." ->" TYPE ." <-" ; IMMEDIATE
     
     1 2 3 remaining + remaining .
     
     : foo 1 2 3 remaining SWAP remaining ;

The result is:

     ->+ remaining .<-
     ->.<-5  ok
     
     ->SWAP remaining ;-<
     ->;<-  ok

   The value of `>IN' can also be modified by a word in the input
buffer that is executed by the text interpreter.  This means that a word
can "trick" the text interpreter into either skipping a section of the
input buffer(5) or into parsing a section twice. For example:

     : lat ." <<foo>>" ;
     : flat ." <<bar>>" >IN DUP @ 3 - SWAP ! ;

When `flat' is executed, this output is produced(6):

     <<bar>><<foo>>

   This technique can be used to work around some of the
interoperability problems of parsing words.  Of course, it's better to
avoid parsing words where possible.

Two important notes about the behaviour of the text interpreter:

   * It processes each input string to completion before parsing
     additional characters from the input buffer.

   * It treats the input buffer as a read-only region (and so must your
     code).

When the text interpreter is in compile state, its behaviour changes in
these ways:

   * If a parsed string is found in the dictionary, the text
     interpreter will perform the word's "compilation semantics". In
     most cases, this simply means that the execution semantics of the
     word will be appended to the current definition.

   * When a number is encountered, it is compiled into the current
     definition (as a literal) rather than being pushed onto a
     parameter stack.

   * If an error occurs, `state' is modified to put the text interpreter
     back into interpret state.

   * Each time a line is entered from the keyboard, Gforth prints "`
     compiled'" rather than " `ok'".

   When the text interpreter is using an input device other than the
keyboard, its behaviour changes in these ways:

   * When the parse area is empty, the text interpreter attempts to
     refill the input buffer from the input source. When the input
     source is exhausted, the input source is set back to the previous
     input source.

   * It doesn't print out "` ok'" or "` compiled'" messages each time
     the parse area is emptied.

   * If an error occurs, the input source is set back to the user input
     device.

   You can read about this in more detail in *Note Input Sources::.

`>in'       - a-addr         core       ``to-in''
   `User' variable - a-addr is the address of a cell containing the
char offset from the start of the input buffer to the start of the
parse area.

`source'       - c-addr u         core       ``source''
   c-addr is the address of the input buffer and u is the number of
characters in it.

`tib'       - c-addr         core-ext       ``t-i-b''
   c-addr is the address of the Terminal Input Buffer.  OBSOLESCENT:
`source' superceeds the function of this word.

`#tib'       - a-addr         core-ext       ``number-t-i-b''
   `User' variable - a-addr is the address of a cell containing the
number of characters in the terminal input buffer.  OBSOLESCENT:
`source' superceeds the function of this word.

* Menu:

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

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

   (1) This is an expanded version of the material in *Note Introducing
the Text Interpreter::.

   (2) When the text interpreter is processing input from the keyboard,
this area of memory is called the "terminal input buffer" (TIB) and is
addressed by the (obsolescent) words `TIB' and `#TIB'.

   (3) This happens if the word was defined as `COMPILE-ONLY'.

   (4) In other words, the text interpreter processes the contents of
the input buffer by parsing strings from the parse area until the parse
area is empty.

   (5) This is how parsing words work.

   (6) Exercise for the reader: what would happen if the `3' were
replaced with `4'?


File: gforth.info,  Node: Input Sources,  Next: Number Conversion,  Prev: The Text Interpreter,  Up: The Text Interpreter

Input Sources
-------------

   By default, the text interpreter processes input from the user input
device (the keyboard) when Forth starts up. The text interpreter can
process input from any of these sources:

   * The user input device - the keyboard.

   * A file, using the words described in *Note Forth source files::.

   * A block, using the words described in *Note Blocks::.

   * A text string, using `evaluate'.

   A program can identify the current input device from the values of
`source-id' and `blk'.

`source-id'       - 0 | -1 | fileid         core-ext,file       ``source-i-d''
   Return 0 (the input source is the user input device), -1 (the input
source is a string being processed by `evaluate') or a fileid (the
input source is the file specified by fileid).

`blk'       - a-addr         block       ``b-l-k''
   `User' variable - a-addr is the address of a cell containing zero
(in which case the input source is not a block and can be identified by
`source-id') or the number of the block currently being interpreted. A
Standard program should not alter `blk' directly.

`save-input'       - xn .. x1 n         core-ext       ``save-input''
   The n entries xn - x1 describe the current state of the input source
specification, in some platform-dependent way that can be used by
`restore-input'.

`restore-input'       xn .. x1 n - flag         core-ext       ``restore-input''
   Attempt to restore the input source specification to the state
described by the n entries xn - x1. flag is true if the restore fails.
In Gforth it fails pretty often (and sometimes with a `throw').

`evaluate'       c-addr u -         core,block       ``evaluate''
   Save the current input source specification. Store `-1' in
`source-id' and `0' in `blk'. Set `>IN' to `0' and make the string
c-addr u the input source and input buffer. Interpret. When the parse
area is empty, restore the input source specification.


File: gforth.info,  Node: Number Conversion,  Next: Interpret/Compile states,  Prev: Input Sources,  Up: The Text Interpreter

Number Conversion
-----------------

   This section describes the rules that the text interpreter uses when
it tries to convert a string into a number.

   Let <digit> represent any character that is a legal digit in the
current number base(1).

   Let <decimal digit> represent any character in the range 0-9.

   Let {a b} represent the optional presence of any of the characters
in the braces (a or b or neither).

   Let * represent any number of instances of the previous character
(including none).

   Let any other character represent itself.

Now, the conversion rules are:

   * A string of the form <digit><digit>* is treated as a
     single-precision (cell-sized) positive integer. Examples are 0 123
     6784532 32343212343456 42

   * A string of the form -<digit><digit>* is treated as a
     single-precision (cell-sized) negative integer, and is represented
     using 2's-complement arithmetic. Examples are -45 -5681 -0

   * A string of the form <digit><digit>*.<digit>* is treated as a
     double-precision (double-cell-sized) positive integer. Examples
     are 3465. 3.465 34.65 (all three of these represent the same
     number).

   * A string of the form -<digit><digit>*.<digit>* is treated as a
     double-precision (double-cell-sized) negative integer, and is
     represented using 2's-complement arithmetic. Examples are -3465.
     -3.465 -34.65 (all three of these represent the same number).

   * A string of the form {+ -}<decimal digit>{.}<decimal digit>*{e
     E}{+ -}<decimal digit><decimal digit>* is treated as a
     floating-point number. Examples are 1e 1e0 1.e 1.e0 +1e+0 (which
     all represent the same number) +12.E-4

   By default, the number base used for integer number conversion is
given by the contents of the variable `base'.  Note that a lot of
confusion can result from unexpected values of `base'.  If you change
`base' anywhere, make sure to save the old value and restore it
afterwards.  In general I recommend keeping `base' decimal, and using
the prefixes described below for the popular non-decimal bases.

`dpl'       - a-addr         gforth       ``dpl''
   `User' variable - a-addr is the address of a cell that stores the
position of the decimal point in the most recent numeric conversion.
Initialised to -1. After the conversion of a number containing no
decimal point, ` dpl' is -1. After the conversion of `2.' it holds 0.
After the conversion of 234123.9 it contains 1, and so forth.

`base'       - a-addr         core       ``base''
   `User' variable - a-addr is the address of a cell that stores the
number base used by default for number conversion during input and
output.

`hex'       -         core-ext       ``hex''
   Set `base' to &16 (hexadecimal).

`decimal'       -         core       ``decimal''
   Set `base' to &10 (decimal).

   Gforth allows you to override the value of `base' by using a
prefix(2) before the first digit of an (integer) number. Four prefixes
are supported:

   * `&' - decimal

   * `%' - binary

   * `$' - hexadecimal

   * `'' - base `max-char+1'

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

   -$41 (-65), %1001101 (205), %1001.0001 (145 - a double-precision
number), 'AB (16706; ascii A is 65, ascii B is 66, number is 65*256 +
66), 'ab (24930; ascii a is 97, ascii B is 98, number is 97*256 + 98),
&905 (905), $abc (2478), $ABC (2478).

Number conversion has a number of traps for the unwary:

   * You cannot determine the current number base using the code
     sequence `base @ .' - the number base is always 10 in the current
     number base. Instead, use something like `base @ dec.'

   * If the number base is set to a value greater than 14 (for example,
     hexadecimal), the number 123E4 is ambiguous; the conversion rules
     allow it to be intepreted as either a single-precision integer or a
     floating-point number (Gforth treats it as an integer). The
     ambiguity can be resolved by explicitly stating the sign of the
     mantissa and/or exponent: 123E+4 or +123E4 - if the number base is
     decimal, no ambiguity arises; either representation will be
     treated as a floating-point number.

   * There is a word `bin' but it does not set the number base!  It is
     used to specify file types.

   * ANS Forth requires the `.' of a double-precision number to be the
     final character in the string.  Gforth allows the `.' to be
     anywhere after the first digit.

   * The number conversion process does not check for overflow.

   * In an ANS Forth program `base' is required to be decimal when
     converting floating-point numbers.  In Gforth, number conversion to
     floating-point numbers always uses base &10, irrespective of the
     value of `base'.

   You can read numbers into your programs with the words described in
*Note Input::.

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

   (1) For example, 0-9 when the number base is decimal or 0-9, A-F
when the number base is hexadecimal.

   (2) Some Forth implementations provide a similar scheme by
implementing `$' etc. as parsing words that process the subsequent
number in the input stream and push it onto the stack. For example, see
`Number Conversion and Literals', by Wil Baden; Forth Dimensions 20(3)
pages 26-27. In such implementations, unlike in Gforth, a space is
required between the prefix and the number.


File: gforth.info,  Node: Interpret/Compile states,  Next: Interpreter Directives,  Prev: Number Conversion,  Up: The Text Interpreter

Interpret/Compile states
------------------------

   A standard program is not permitted to change `state' explicitly.
However, it can change `state' implicitly, using the words `[' and `]'.
When `[' is executed it switches `state' to interpret state, and
therefore the text interpreter starts interpreting. When `]' is
executed it switches `state' to compile state and therefore the text
interpreter starts compiling. The most common usage for these words is
for switching into interpret state and back from within a colon
definition; this technique can be used to compile a literal (for an
example, *note Literals::) or for conditional compilation (for an
example, *note Interpreter Directives::).

   `[' and `]' also give you the ability to switch into compile state
and back, but we cannot think of any useful Standard application for
this ability. Pre-ANS Forth textbooks have examples like this:

     : AA ." this is A" ;
     : BB ." this is B" ;
     : CC ." this is C" ;
     
     create table ] aa bb cc [
     
     : go ( n -- ) \ n is offset into table.. 0 for 1st entry
       cells table +  execute ;

   This example builds a jump table; `0 go' will display "`this is A'".
Using `[' and `]' in this example is equivalent to defining `table'
like this:

     create table ' aa COMPILE, ' bb COMPILE, ' cc COMPILE,

   The problem with this code is that the definition of `table' is not
portable - it compiles execution tokens into code space. Whilst it may
work on systems where code space and data space co-incide, the Standard
only allows data space to be assigned for a `CREATE'd word. In
addition, the Standard only allows `@' to access data space, whilst
this example is using it to access code space. The only portable,
Standard way to build this table is to build it in data space, like
this:

     create table ' aa , ' bb , ' cc ,

`state'       - a-addr         core,tools-ext       ``state''
   `User' variable - a-addr is the address of a cell containing the
compilation state flag. 0 => interpreting, -1 => compiling.  A program
shall not directly alter the value of `state'. The following Standard
words alter the value in `state': `:' (colon) `;' (semicolon) `abort'
`quit' `:noname' `[' (left-bracket) `]' (right-bracket) `;code'. Don't
use `state'! For an alternative see *Note Interpretation and
Compilation Semantics::.


File: gforth.info,  Node: Interpreter Directives,  Prev: Interpret/Compile states,  Up: The Text Interpreter

Interpreter Directives
----------------------

   These words are usually used in interpret state; typically to control
which parts of a source file are processed by the text interpreter.
There are only a few ANS Forth Standard words, but Gforth supplements
these with a rich set of immediate control structure words to
compensate for the fact that the non-immediate versions can only be
used in compile state (*note Control Structures::). Typical usages:

     FALSE Constant HAVE-ASSEMBLER
     .
     .
     HAVE-ASSEMBLER [IF]
     : ASSEMBLER-FEATURE
       ...
     ;
     [ENDIF]
     .
     .
     : SEE
       ... \ general-purpose SEE code
       [ HAVE-ASSEMBLER [IF] ]
       ... \ assembler-specific SEE code
       [ [ENDIF] ]
     ;

`[IF]'       flag | flag "<spaces>name ..." -         tools-ext       ``bracket-if''
   If flag is `TRUE' do nothing (and therefore execute subsequent words
as normal). If flag is `FALSE', parse and discard words from the parse
area (refilling it if necessary using `REFILL') including nested
instances of `[IF]'..  `[ELSE]'.. `[THEN]' and `[IF]'.. `[THEN]' until
the balancing `[ELSE]' or `[THEN]' has been parsed and discarded.
Immediate word.

`[ELSE]'       "<spaces>name ..." -         tools-ext       ``bracket-else''
   Parse and discard words from the parse area (refilling it if
necessary using `REFILL') including nested instances of `[IF]'..
`[ELSE]'.. `[THEN]' and `[IF]'.. `[THEN]' until the balancing `[THEN]'
has been parsed and discarded.  `[ELSE]' only gets executed if the
balancing `[IF]' was `TRUE'; if it was `FALSE', `[IF]' would have
parsed and discarded the `[ELSE]', leaving the subsequent words to be
executed as normal.  Immediate word.

`[THEN]'       -         tools-ext       ``bracket-then''
   Do nothing; used as a marker for other words to parse and discard up
to. Immediate word.

`[ENDIF]'       -         gforth       ``bracket-end-if''
   Do nothing; synonym for `[THEN]'

`[IFDEF]'       "<spaces>name" -         gforth       ``bracket-if-def''
   If name is found in the current search-order, behave like `[IF]'
with a `TRUE' flag, otherwise behave like `[IF]' with a `FALSE' flag.
Immediate word.

`[IFUNDEF]'       "<spaces>name" -         gforth       ``bracket-if-un-def''
   If name is not found in the current search-order, behave like `[IF]'
with a `TRUE' flag, otherwise behave like `[IF]' with a `FALSE' flag.
Immediate word.

`[?DO]'       n-limit n-index -         gforth       ``bracket-question-do''

`[DO]'       n-limit n-index -         gforth       ``bracket-do''

`[FOR]'       n -         gforth       ``bracket-for''

`[LOOP]'       -         gforth       ``bracket-loop''

`[+LOOP]'       n -         gforth       ``bracket-question-plus-loop''

`[NEXT]'       n -         gforth       ``bracket-next''

`[BEGIN]'       -         gforth       ``bracket-begin''

`[UNTIL]'       flag -         gforth       ``bracket-until''

`[AGAIN]'       -         gforth       ``bracket-again''

`[WHILE]'       flag -         gforth       ``bracket-while''

`[REPEAT]'       -         gforth       ``bracket-repeat''


File: gforth.info,  Node: Word Lists,  Next: Environmental Queries,  Prev: The Text Interpreter,  Up: Words

Word Lists
==========

   A wordlist is a list of named words; you can add new words and look
up words by name (and you can remove words in a restricted way with
markers).  Every named (and `reveal'ed) word is in one wordlist.

   The text interpreter searches the wordlists present in the search
order (a stack of wordlists), from the top to the bottom.  Within each
wordlist, the search starts conceptually at the newest word; i.e., if
two words in a wordlist have the same name, the newer word is found.

   New words are added to the "compilation wordlist" (aka current
wordlist).

   A word list is identified by a cell-sized word list identifier (wid)
in much the same way as a file is identified by a file handle. The
numerical value of the wid has no (portable) meaning, and might change
from session to session.

   The ANS Forth "Search order" word set is intended to provide a set of
low-level tools that allow various different schemes to be implemented.
Gforth also provides `vocabulary', a traditional Forth word.
`compat/vocabulary.fs' provides an implementation in ANS Forth.

`forth-wordlist'       - wid         search       ``forth-wordlist''
   `Constant' - wid identifies the word list that includes all of the
standard words provided by Gforth. When Gforth is invoked, this word
list is the compilation word list and is at the top of the search order.

`definitions'       -         search       ``definitions''
   Set the compilation word list to be the same as the word list that
is currently at the top of the search order.

`get-current'       - wid         search       ``get-current''
   wid is the identifier of the current compilation word list.

`set-current'       wid -         search       ``set-current''
   Set the compilation word list to the word list identified by wid.

`get-order'       - widn .. wid1 n         search       ``get-order''
   Copy the search order to the data stack. The current search order
has n entries, of which wid1 represents the wordlist that is searched
first (the word list at the top of the search order) and widn
represents the wordlist that is searched last.

`set-order'       widn .. wid1 n -         search       ``set-order''
   If N=0, empty the search order.  If N=-1, set the search order to
the implementation-defined minimum search order (for Gforth, this is
the word list `Root'). Otherwise, replace the existing search order
with the N wid entries such that WID1 represents the word list that
will be searched first and WIDN represents the word list that will be
searched last.

`wordlist'       - wid         search       ``wordlist''
   Create a new, empty word list represented by wid.

`table'       - wid         gforth       ``table''
   Create a case-sensitive wordlist.

`>order'       wid -         gforth       ``to-order''
   Push WID on the search order.

`previous'       -         search-ext       ``previous''
   Drop the wordlist at the top of the search order.

`also'       -         search-ext       ``also''
   Like `DUP' for the search order. Usually used before a vocabulary
(e.g., `also Forth'); the combined effect is to push the wordlist
represented by the vocabulary on the search order.

`Forth'       -         search-ext       ``Forth''
   Replace the wid at the top of the search order with the wid
associated with the word list `forth-wordlist'.

`Only'       -         search-ext       ``Only''
   Set the search order to the implementation-defined minimum search
order (for Gforth, this is the word list `Root').

`order'       -         search-ext       ``order''
   Print the search order and the compilation word list.  The word
lists are printed in the order in which they are searched (which is
reversed with respect to the conventional way of displaying stacks).
The compilation word list is displayed last.

`find'       c-addr - xt +-1 | c-addr 0         core,search       ``find''
   Search all word lists in the current search order for the definition
named by the counted string at c-addr.  If the definition is not found,
return 0. If the definition is found return 1 (if the definition has
non-default compilation semantics) or -1 (if the definition has default
compilation semantics).  The xt returned in interpret state represents
the interpretation semantics.  The xt returned in compile state
represented either the compilation semantics (for non-default
compilation semantics) or the run-time semantics that the compilation
semantics would `compile,' (for default compilation semantics).  The
ANS Forth standard does not specify clearly what the returned xt
represents (and also talks about immediacy instead of non-default
compilation semantics), so this word is questionable in portable
programs.  If non-portability is ok, `find-name' and friends are better
(*note Name token::).

`search-wordlist'       c-addr count wid - 0 | xt +-1         search       ``search-wordlist''
   Search the word list identified by wid for the definition named by
the string at c-addr count.  If the definition is not found, return 0.
If the definition is found return 1 (if the definition is immediate) or
-1 (if the definition is not immediate) together with the xt.  In
Gforth, the xt returned represents the interpretation semantics.  ANS
Forth does not specify clearly what xt represents.

`words'       -         tools       ``words''
   Display a list of all of the definitions in the word list at the top
of the search order.

`vlist'       -         gforth       ``vlist''
   Old (pre-Forth-83) name for `WORDS'.

`Root'       -         gforth       ``Root''
   Add the root wordlist to the search order stack.  This vocabulary
makes up the minimum search order and contains only a search-order
words.

`Vocabulary'       "name" -         gforth       ``Vocabulary''
   Create a definition "name" and associate a new word list with it.
The run-time effect of "name" is to replace the wid at the top of the
search order with the wid associated with the new word list.

`seal'       -         gforth       ``seal''
   Remove all word lists from the search order stack other than the word
list that is currently on the top of the search order stack.

`vocs'       -         gforth       ``vocs''
   List vocabularies and wordlists defined in the system.

`current'       - addr         gforth       ``current''
   `Variable' - holds the wid of the compilation word list.

`context'       - addr         gforth       ``context''
   `context' `@' is the wid of the word list at the top of the search
order.

* Menu:

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


File: gforth.info,  Node: Vocabularies,  Next: Why use word lists?,  Prev: Word Lists,  Up: Word Lists

Vocabularies
------------

   Here is an example of creating and using a new wordlist using ANS
Forth words:

     wordlist constant my-new-words-wordlist
     : my-new-words get-order nip my-new-words-wordlist swap set-order ;
     
     \ add it to the search order
     also my-new-words
     
     \ alternatively, add it to the search order and make it
     \ the compilation word list
     also my-new-words definitions
     \ type "order" to see the problem

   The problem with this example is that `order' has no way to
associate the name `my-new-words' with the wid of the word list (in
Gforth, `order' and `vocs' will display `???'  for a wid that has no
associated name). There is no Standard way of associating a name with a
wid.

   In Gforth, this example can be re-coded using `vocabulary', which
associates a name with a wid:

     vocabulary my-new-words
     
     \ add it to the search order
     also my-new-words
     
     \ alternatively, add it to the search order and make it
     \ the compilation word list
     my-new-words definitions
     \ type "order" to see that the problem is solved


File: gforth.info,  Node: Why use word lists?,  Next: Word list example,  Prev: Vocabularies,  Up: Word Lists

Why use word lists?
-------------------

   Here are some reasons why people use wordlists:

   * To prevent a set of words from being used outside the context in
     which they are valid. Two classic examples of this are an
     integrated editor (all of the edit commands are defined in a
     separate word list; the search order is set to the editor word
     list when the editor is invoked; the old search order is restored
     when the editor is terminated) and an integrated assembler (the
     op-codes for the machine are defined in a separate word list which
     is used when a `CODE' word is defined).

   * To organize the words of an application or library into a
     user-visible set (in `forth-wordlist' or some other common
     wordlist) and a set of helper words used just for the
     implementation (hidden in a separate wordlist).  This keeps
     `words'' output smaller, separates implementation and interface,
     and reduces the chance of name conflicts within the common
     wordlist.

   * To prevent a name-space clash between multiple definitions with
     the same name. For example, when building a cross-compiler you
     might have a word `IF' that generates conditional code for your
     target system. By placing this definition in a different word list
     you can control whether the host system's `IF' or the target
     system's `IF' get used in any particular context by controlling
     the order of the word lists on the search order stack.


   The downsides of using wordlists are:

   * Debugging becomes more cumbersome.

   * Name conflicts worked around with wordlists are still there, and
     you have to arrange the search order carefully to get the desired
     results; if you forget to do that, you get hard-to-find errors (as
     in any case where you read the code differently from the compiler;
     `see' can help seeing which of several possible words the name
     resolves to in such cases).  `See' displays just the name of the
     words, not what wordlist they belong to, so it might be
     misleading.  Using unique names is a better approach to avoid name
     conflicts.

   * You have to explicitly undo any changes to the search order.  In
     many cases it would be more convenient if this happened
     implicitly.  Gforth currently does not provide such a feature, but
     it may do so in the future.


File: gforth.info,  Node: Word list example,  Prev: Why use word lists?,  Up: Word Lists

Word list example
-----------------

   The following example is from the garbage collector
(http://www.complang.tuwien.ac.at/forth/garbage-collection.zip) and
uses wordlists to separate public words from helper words:

     get-current ( wid )
     vocabulary garbage-collector also garbage-collector definitions
     ... \ define helper words
     ( wid ) set-current \ restore original (i.e., public) compilation wordlist
     ... \ define the public (i.e., API) words
         \ they can refer to the helper words
     previous \ restore original search order (helper words become invisible)


File: gforth.info,  Node: Environmental Queries,  Next: Files,  Prev: Word Lists,  Up: Words

Environmental Queries
=====================

   ANS Forth introduced the idea of "environmental queries" as a way
for a program running on a system to determine certain characteristics
of the system.  The Standard specifies a number of strings that might
be recognised by a system.

   The Standard requires that the header space used for environmental
queries be distinct from the header space used for definitions.

   Typically, environmental queries are supported by creating a set of
definitions in a word list that is only used during environmental
queries; that is what Gforth does. There is no Standard way of adding
definitions to the set of recognised environmental queries, but any
implementation that supports the loading of optional word sets must have
some mechanism for doing this (after loading the word set, the
associated environmental query string must return `true'). In Gforth,
the word list used to honour environmental queries can be manipulated
just like any other word list.

`environment?'       c-addr u - false / ... true         core       ``environment-query''
   c-addr, u specify a counted string. If the string is not recognised,
return a `false' flag. Otherwise return a `true' flag and some
(string-specific) information about the queried string.

`environment-wordlist'       - wid         gforth       ``environment-wordlist''
   wid identifies the word list that is searched by environmental
queries.

`gforth'       - c-addr u         gforth-environment       ``gforth''
   Counted string representing a version string for this version of
Gforth (for versions>0.3.0).  The version strings of the various
versions are guaranteed to be ordered lexicographically.

`os-class'       - c-addr u         gforth-environment       ``os-class''
   Counted string representing a description of the host operating
system.

   Note that, whilst the documentation for (e.g.) `gforth' shows it
returning two items on the stack, querying it using `environment?' will
return an additional item; the `true' flag that shows that the string
was recognised.

   Here are some examples of using environmental queries:

     s" address-unit-bits" environment? 0=
     [IF]
          cr .( environmental attribute address-units-bits unknown... ) cr
     [ELSE]
          drop \ ensure balanced stack effect
     [THEN]
     
     \ this might occur in the prelude of a standard program that uses THROW
     s" exception" environment? [IF]
        0= [IF]
           : throw abort" exception thrown" ;
        [THEN]
     [ELSE] \ we don't know, so make sure
        : throw abort" exception thrown" ;
     [THEN]
     
     s" gforth" environment? [IF] .( Gforth version ) TYPE
                             [ELSE] .( Not Gforth..) [THEN]
     
     \ a program using v*
     s" gforth" environment? [IF]
       s" 0.5.0" compare 0< [IF] \ v* is a primitive since 0.5.0
        : v* ( f_addr1 nstride1 f_addr2 nstride2 ucount -- r )
          >r swap 2swap swap 0e r> 0 ?DO
            dup f over + 2swap dup f f* f+ over + 2swap
          LOOP
          2drop 2drop ;
       [THEN]
     [ELSE] \
       : v* ( f_addr1 nstride1 f_addr2 nstride2 ucount -- r )
       ...
     [THEN]

   Here is an example of adding a definition to the environment word
list:

     get-current environment-wordlist set-current
     true constant block
     true constant block-ext
     set-current

   You can see what definitions are in the environment word list like
this:

     environment-wordlist >order words previous


File: gforth.info,  Node: Files,  Next: Blocks,  Prev: Environmental Queries,  Up: Words

Files
=====

   Gforth provides facilities for accessing files that are stored in the
host operating system's file-system. Files that are processed by Gforth
can be divided into two categories:

   * Files that are processed by the Text Interpreter ("Forth source
     files").

   * Files that are processed by some other program ("general files").

* Menu:

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


File: gforth.info,  Node: Forth source files,  Next: General files,  Prev: Files,  Up: Files

Forth source files
------------------

   The simplest way to interpret the contents of a file is to use one of
these two formats:

     include mysource.fs
     s" mysource.fs" included

   You usually want to include a file only if it is not included already
(by, say, another source file). In that case, you can use one of these
three formats:

     require mysource.fs
     needs mysource.fs
     s" mysource.fs" required

   It is good practice to write your source files such that
interpreting them does not change the stack. Source files designed in
this way can be used with `required' and friends without complications.
For example:

     1024 require foo.fs drop

   Here you want to pass the argument 1024 (e.g., a buffer size) to
`foo.fs'.  Interpreting `foo.fs' has the stack effect ( n - n ), which
allows its use with `require'.  Of course with such parameters to
required files, you have to ensure that the first `require' fits for
all uses (i.e., `require' it early in the master load file).

`include-file'       i*x wfileid - j*x         file       ``include-file''

`included'       i*x c-addr u - j*x         file       ``included''
   `include-file' the file whose name is given by the string C-ADDR U.

`included?'       c-addr u - f         gforth       ``included?''
   True only if the file C-ADDR U is in the list of earlier included
files. If the file has been loaded, it may have been specified as, say,
`foo.fs' and found somewhere on the Forth search path. To return `true'
from `included?', you must specify the exact path to the file, even if
that is `./foo.fs'

`include'       ... "file" - ...         gforth       ``include''
   `include-file' the file FILE.

`required'       i*x addr u - j*x         gforth       ``required''
   `include-file' the file with the name given by ADDR U, if it is not
`included' (or `required') already. Currently this works by comparing
the name of the file (with path) against the names of earlier included
files.

`require'       ... "file" - ...         gforth       ``require''
   `include-file' FILE only if it is not included already.

`needs'       ... "name" - ...         gforth       ``needs''
   An alias for `require'; exists on other systems (e.g., Win32Forth).

`sourcefilename'       - c-addr u         gforth       ``sourcefilename''
   The name of the source file which is currently the input source.
The result is valid only while the file is being loaded.  If the
current input source is no (stream) file, the result is undefined.  In
Gforth, the result is valid during the whole seesion (but not across
`savesystem' etc.).

`sourceline#'       - u         gforth       ``sourceline-number''
   The line number of the line that is currently being interpreted from
a (stream) file. The first line has the number 1. If the current input
source is not a (stream) file, the result is undefined.

   A definition in ANS Forth for `required' is provided in
`compat/required.fs'.


File: gforth.info,  Node: General files,  Next: Search Paths,  Prev: Forth source files,  Up: Files

General files
-------------

   Files are opened/created by name and type. The following file access
methods (FAMs) are recognised:

`r/o'       - fam         file       ``r-o''

`r/w'       - fam         file       ``r-w''

`w/o'       - fam         file       ``w-o''

`bin'       fam1 - fam2         file       ``bin''

   When a file is opened/created, it returns a file identifier, wfileid
that is used for all other file commands. All file commands also return
a status value, wior, that is 0 for a successful operation and an
implementation-defined non-zero value in the case of an error.

`open-file'       c-addr u wfam - wfileid wior        file       ``open-file''

`create-file'       c-addr u wfam - wfileid wior        file       ``create-file''

`close-file'       wfileid - wior        file       ``close-file''

`delete-file'       c-addr u - wior        file       ``delete-file''

`rename-file'       c-addr1 u1 c-addr2 u2 - wior        file-ext       ``rename-file''
   Rename file c_addr1 u1 to new name c_addr2 u2

`read-file'       c-addr u1 wfileid - u2 wior        file       ``read-file''

`read-line'       c-addr u1 wfileid - u2 flag wior        file       ``read-line''
   this is only for backward compatibility

`write-file'       c-addr u1 wfileid - wior        file       ``write-file''

`write-line'       c-addr u fileid - ior         file       ``write-line''

`emit-file'       c wfileid - wior        gforth       ``emit-file''

`flush-file'       wfileid - wior        file-ext       ``flush-file''

`file-status'       c-addr u - wfam wior        file-ext       ``file-status''

`file-position'       wfileid - ud wior        file       ``file-position''

`reposition-file'       ud wfileid - wior        file       ``reposition-file''

`file-size'       wfileid - ud wior        file       ``file-size''

`resize-file'       ud wfileid - wior        file       ``resize-file''

