version 1.47, 2000/03/17 21:35:32
|
version 1.48, 2000/05/14 20:23:05
|
Line 27
|
Line 27
|
@macro progstyle {} |
@macro progstyle {} |
Programming style note: |
Programming style note: |
@end macro |
@end macro |
|
|
|
@macro assignment {} |
|
@table @i |
|
@item Assignment: |
|
@end macro |
|
@macro endassignment {} |
|
@end table |
|
@end macro |
|
|
@comment %**end of header (This is for running Texinfo on a region.) |
@comment %**end of header (This is for running Texinfo on a region.) |
|
|
|
|
Line 132 personal machines. This manual correspon
|
Line 141 personal machines. This manual correspon
|
* License:: The GPL |
* License:: The GPL |
* Goals:: About the Gforth Project |
* Goals:: About the Gforth Project |
* Gforth Environment:: Starting (and exiting) Gforth |
* Gforth Environment:: Starting (and exiting) Gforth |
|
* Tutorial:: Hands-on Forth Tutorial |
* Introduction:: An introduction to ANS Forth |
* Introduction:: An introduction to ANS Forth |
* Words:: Forth words available in Gforth |
* Words:: Forth words available in Gforth |
* Error messages:: How to interpret them |
* Error messages:: How to interpret them |
Line 151 personal machines. This manual correspon
|
Line 161 personal machines. This manual correspon
|
* Name Index:: Forth words, only names listed |
* Name Index:: Forth words, only names listed |
* Concept Index:: A menu covering many topics |
* Concept Index:: A menu covering many topics |
|
|
@detailmenu |
@detailmenu --- The Detailed Node Listing --- |
--- The Detailed Node Listing --- |
|
|
|
Goals of Gforth |
Goals of Gforth |
|
|
Line 163 Gforth Environment
|
Line 172 Gforth Environment
|
* Invoking Gforth:: Getting in |
* Invoking Gforth:: Getting in |
* Leaving Gforth:: Getting out |
* Leaving Gforth:: Getting out |
* Command-line editing:: |
* Command-line editing:: |
* Upper and lower case:: |
* Upper and lower case:: |
* Environment variables:: ..that affect how Gforth starts up |
* Environment variables:: that affect how Gforth starts up |
* Gforth Files:: What gets installed and where |
* Gforth Files:: What gets installed and where |
|
* Startup speed:: When 35ms is not fast enough ... |
|
|
|
Forth Tutorial |
|
|
|
* Starting Gforth Tutorial:: |
|
* Syntax Tutorial:: |
|
* Crash Course Tutorial:: |
|
* Stack Tutorial:: |
|
* Arithmetics Tutorial:: |
|
* Stack Manipulation Tutorial:: |
|
* Using files for Forth code Tutorial:: |
|
* Comments Tutorial:: |
|
* Colon Definitions Tutorial:: |
|
* Decompilation Tutorial:: |
|
* Stack-Effect Comments Tutorial:: |
|
* Types Tutorial:: |
|
* Factoring Tutorial:: |
|
* Designing the stack effect Tutorial:: |
|
* Local Variables Tutorial:: |
|
* Conditional execution Tutorial:: |
|
* Flags and Comparisons Tutorial:: |
|
* General Loops Tutorial:: |
|
* Counted loops Tutorial:: |
|
* Recursion Tutorial:: |
|
* Leaving definitions or loops Tutorial:: |
|
* Return Stack Tutorial:: |
|
* Memory Tutorial:: |
|
* Characters and Strings Tutorial:: |
|
* Alignment Tutorial:: |
|
* Interpretation and Compilation Semantics and Immediacy Tutorial:: |
|
* Execution Tokens Tutorial:: |
|
* Exceptions Tutorial:: |
|
* Defining Words Tutorial:: |
|
* Arrays and Records Tutorial:: |
|
* POSTPONE Tutorial:: |
|
* Literal Tutorial:: |
|
* Advanced macros Tutorial:: |
|
* Compilation Tokens Tutorial:: |
|
* Wordlists and Search Order Tutorial:: |
|
|
An Introduction to ANS Forth |
An Introduction to ANS Forth |
|
|
Line 273 Word Lists
|
Line 321 Word Lists
|
|
|
Files |
Files |
|
|
* Forth source files:: |
* Forth source files:: |
* General files:: |
* General files:: |
* Search Paths:: |
* Search Paths:: |
* Forth Search Paths:: |
|
|
Search Paths |
|
|
|
* Forth Search Paths:: |
* General Search Paths:: |
* General Search Paths:: |
|
|
Other I/O |
Other I/O |
Line 315 Structures
|
Line 366 Structures
|
|
|
Object-oriented Forth |
Object-oriented Forth |
|
|
* Why object-oriented programming?:: |
* Why object-oriented programming?:: |
* Object-Oriented Terminology:: |
* Object-Oriented Terminology:: |
* Objects:: |
* Objects:: |
* OOF:: |
* OOF:: |
* Mini-OOF:: |
* Mini-OOF:: |
* Comparison with other object models:: |
* Comparison with other object models:: |
|
|
The @file{objects.fs} model |
The @file{objects.fs} model |
Line 347 The @file{oof.fs} model
|
Line 398 The @file{oof.fs} model
|
|
|
The @file{mini-oof.fs} model |
The @file{mini-oof.fs} model |
|
|
* Basic Mini-OOF Usage:: |
* Basic Mini-OOF Usage:: |
* Mini-OOF Example:: |
* Mini-OOF Example:: |
* Mini-OOF Implementation:: |
* Mini-OOF Implementation:: |
|
* Comparison with other object models:: |
|
|
Tools |
Tools |
|
|
Line 925 on many machines.
|
Line 977 on many machines.
|
* Gforth Extensions Sinful?:: |
* Gforth Extensions Sinful?:: |
@end menu |
@end menu |
|
|
@node Gforth Extensions Sinful?, , Goals, Goals |
@node Gforth Extensions Sinful?, , Goals, Goals |
@comment node-name, next, previous, up |
@comment node-name, next, previous, up |
@section Is it a Sin to use Gforth Extensions? |
@section Is it a Sin to use Gforth Extensions? |
@cindex Gforth extensions |
@cindex Gforth extensions |
Line 970 relies upon.
|
Line 1022 relies upon.
|
|
|
|
|
@c ****************************************************************** |
@c ****************************************************************** |
@node Gforth Environment, Introduction, Goals, Top |
@node Gforth Environment, Tutorial, Goals, Top |
@chapter Gforth Environment |
@chapter Gforth Environment |
@cindex Gforth environment |
@cindex Gforth environment |
|
|
Line 981 material in this chapter.
|
Line 1033 material in this chapter.
|
* Invoking Gforth:: Getting in |
* Invoking Gforth:: Getting in |
* Leaving Gforth:: Getting out |
* Leaving Gforth:: Getting out |
* Command-line editing:: |
* Command-line editing:: |
* Upper and lower case:: |
* Upper and lower case:: |
* Environment variables:: ..that affect how Gforth starts up |
* Environment variables:: that affect how Gforth starts up |
* Gforth Files:: What gets installed and where |
* Gforth Files:: What gets installed and where |
|
* Startup speed:: When 35ms is not fast enough ... |
@end menu |
@end menu |
|
|
@xref{Image Files} for related information about the creation of images. |
@xref{Image Files} for related information about the creation of images. |
|
|
@comment ---------------------------------------------- |
@comment ---------------------------------------------- |
@node Invoking Gforth, Leaving Gforth, ,Gforth Environment |
@node Invoking Gforth, Leaving Gforth, Gforth Environment, Gforth Environment |
@section Invoking Gforth |
@section Invoking Gforth |
@cindex invoking Gforth |
@cindex invoking Gforth |
@cindex running Gforth |
@cindex running Gforth |
Line 1091 the unit specifier @code{e} refers to fl
|
Line 1144 the unit specifier @code{e} refers to fl
|
Allocate @i{size} space for the locals stack instead of using the |
Allocate @i{size} space for the locals stack instead of using the |
default specified in the image (typically 14.5K). |
default specified in the image (typically 14.5K). |
|
|
@cindex -h, command-line option |
@cindex -h, command-line option |
@cindex --help, command-line option |
@cindex --help, command-line option |
@item --help |
@item --help |
@itemx -h |
@itemx -h |
Print a message about the command-line options |
Print a message about the command-line options |
|
|
|
@cindex -v, command-line option |
|
@cindex --version, command-line option |
|
@item --version |
|
@itemx -v |
|
Print version and exit |
|
|
|
@cindex --debug, command-line option |
|
@item --debug |
|
Print some information useful for debugging on startup. |
|
|
|
@cindex --offset-image, command-line option |
|
@item --offset-image |
|
Start the dictionary at a slightly different position than would be used |
|
otherwise (useful for creating data-relocatable images, |
|
@pxref{Data-Relocatable Image Files}). |
|
|
|
@cindex --no-offset-im, command-line option |
|
@item --no-offset-im |
|
Start the dictionary at the normal position. |
|
|
|
@cindex --clear-dictionary, command-line option |
|
@item --clear-dictionary |
|
Initialize all bytes in the dictionary to 0 before loading the image |
|
(@pxref{Data-Relocatable Image Files}). |
|
|
|
@cindex --die-on-signal, command-line-option |
|
@item --die-on-signal |
|
Normally Gforth handles most signals (e.g., the user interrupt SIGINT, |
|
or the segmentation violation SIGSEGV) by translating it into a Forth |
|
@code{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. |
|
@end table |
|
|
|
@cindex loading files at startup |
|
@cindex executing code on startup |
|
@cindex batch processing with Gforth |
|
As explained above, the image-specific command-line arguments for the |
|
default image @file{gforth.fi} consist of a sequence of filenames and |
|
@code{-e @var{forth-code}} options that are interpreted in the sequence |
|
in which they are given. The @code{-e @var{forth-code}} or |
|
@code{--evaluate @var{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 @code{-e} several times. To exit |
|
after processing the command line (instead of entering interactive mode) |
|
append @code{-e bye} to the command line. |
|
|
|
@cindex versions, invoking other versions of Gforth |
|
If you have several versions of Gforth installed, @code{gforth} will |
|
invoke the version that was installed last. @code{gforth-@i{version}} |
|
invokes a specific version. If your environment contains the variable |
|
@code{GFORTHPATH}, you may want to override it by using the |
|
@code{--path} option. |
|
|
|
Not yet implemented: |
|
On startup the system first executes the system initialization file |
|
(unless the option @code{--no-init-file} is given; note that the system |
|
resulting from using this option may not be ANS Forth conformant). Then |
|
the user initialization file @file{.gforth.fs} is executed, unless the |
|
option @code{--no-rc} is given; this file is first searched in @file{.}, |
|
then in @file{~}, then in the normal path (see above). |
|
|
|
|
|
|
|
@comment ---------------------------------------------- |
|
@node Leaving Gforth, Command-line editing, Invoking Gforth, Gforth Environment |
|
@section Leaving Gforth |
|
@cindex Gforth - leaving |
|
@cindex leaving Gforth |
|
|
|
You can leave Gforth by typing @code{bye} or @kbd{Ctrl-d} (at the start |
|
of a line) or (if you invoked Gforth with the @code{--die-on-signal} |
|
option) @kbd{Ctrl-c}. When you leave Gforth, all of your definitions and |
|
data are discarded. @xref{Image Files} for ways of saving the state of |
|
the system before leaving Gforth. |
|
|
|
doc-bye |
|
|
|
|
|
@comment ---------------------------------------------- |
|
@node Command-line editing, Upper and lower case, Leaving Gforth, Gforth Environment |
|
@section Command-line editing |
|
@cindex 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 @kbd{Ctrl-P} |
|
repeatedly you can recall successively older commands from this (or |
|
previous) session(s). The full list of command-line editing facilities is: |
|
|
|
@itemize @bullet |
|
@item |
|
@kbd{Ctrl-p} (``previous'') (or up-arrow) to recall successively older |
|
commands from the history buffer. |
|
@item |
|
@kbd{Ctrl-n} (``next'') (or down-arrow) to recall successively newer commands |
|
from the history buffer. |
|
@item |
|
@kbd{Ctrl-f} (or right-arrow) to move the cursor right, non-destructively. |
|
@item |
|
@kbd{Ctrl-b} (or left-arrow) to move the cursor left, non-destructively. |
|
@item |
|
@kbd{Ctrl-h} (backspace) to delete the character to the left of the cursor, |
|
closing up the line. |
|
@item |
|
@kbd{Ctrl-k} to delete (``kill'') from the cursor to the end of the line. |
|
@item |
|
@kbd{Ctrl-a} to move the cursor to the start of the line. |
|
@item |
|
@kbd{Ctrl-e} to move the cursor to the end of the line. |
|
@item |
|
@key{RET} (@kbd{Ctrl-m}) or @key{LFD} (@kbd{Ctrl-j}) to submit the current |
|
line. |
|
@item |
|
@key{TAB} to step through all possible full-word completions of the word |
|
currently being typed. |
|
@item |
|
@kbd{Ctrl-d} at the start of the line to terminate Gforth (gracefully, |
|
using @code{bye}). |
|
@end itemize |
|
|
|
When editing, displayable characters are inserted to the left of the |
|
cursor position; the line is always in ``insert'' (as opposed to |
|
``overstrike'') mode. |
|
|
|
@cindex history file |
|
@cindex @file{.gforth-history} |
|
On Unix systems, the history file is @file{~/.gforth-history} by |
|
default@footnote{i.e. it is stored in the user's home directory.}. You |
|
can find out the name and location of your history file using: |
|
|
|
@example |
|
history-file type \ Unix-class systems |
|
|
|
history-file type \ Other systems |
|
history-dir type |
|
@end example |
|
|
|
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. |
|
|
|
@comment this is all defined in history.fs |
|
@comment NAC TODO the ctrl-D behaviour can either do a bye or a beep.. how is that option |
|
@comment chosen? |
|
|
|
|
|
|
|
@comment ---------------------------------------------- |
|
@node Upper and lower case, Environment variables, Command-line editing, Gforth Environment |
|
@section Upper and lower case |
|
@cindex case-sensitivity |
|
@cindex upper and lower case |
|
|
|
Gforth is case-insensitive; you can enter definitions and invoke |
|
Standard words using upper, lower or mixed case (however, |
|
@pxref{core-idef, Implementation-defined options, Implementation-defined |
|
options}). |
|
|
|
ANS Forth only @i{requires} implementations to recognise Standard words |
|
when they are typed entirely in upper case. Therefore, a Standard |
|
program must use upper case for all Standard words. You can use whatever |
|
case you like for words that you define, but in a standard program you |
|
have to use the words in the same case that you defined them. |
|
|
|
Gforth supports case sensitivity through @code{table}s (case-sensitive |
|
wordlists, @pxref{Word Lists}). |
|
|
|
Two people have asked how to convert Gforth to case sensitivity; while |
|
we think this is a bad idea, you can change all wordlists into tables |
|
like this: |
|
|
|
@example |
|
' table-find forth-wordlist wordlist-map @ ! |
|
@end example |
|
|
|
Note that you now have to type the predefined words in the same case |
|
that we defined them, which are varying. You may want to convert them |
|
to your favourite case before doing this operation (I won't explain how, |
|
because if you are even contemplating to do this, you'd better have |
|
enough knowledge of Forth systems to know this already). |
|
|
|
@comment ---------------------------------------------- |
|
@node Environment variables, Gforth Files, Upper and lower case, Gforth Environment |
|
@section Environment variables |
|
@cindex environment variables |
|
|
|
Gforth uses these environment variables: |
|
|
|
@itemize @bullet |
|
@item |
|
@cindex @code{GFORTHHIST} -- environment variable |
|
@code{GFORTHHIST} -- (Unix systems only) specifies the directory in which to |
|
open/create the history file, @file{.gforth-history}. Default: |
|
@code{$HOME}. |
|
|
|
@item |
|
@cindex @code{GFORTHPATH} -- environment variable |
|
@code{GFORTHPATH} -- specifies the path used when searching for the gforth image file and |
|
for Forth source-code files. |
|
|
|
@item |
|
@cindex @code{GFORTH} -- environment variable |
|
@code{GFORTH} -- used by @file{gforthmi} @xref{gforthmi}. |
|
|
|
@item |
|
@cindex @code{GFORTHD} -- environment variable |
|
@code{GFORTHD} -- used by @file{gforthmi} @xref{gforthmi}. |
|
|
|
@item |
|
@cindex @code{TMP}, @code{TEMP} - environment variable |
|
@code{TMP}, @code{TEMP} - (non-Unix systems only) used as a potential |
|
location for the history file. |
|
@end itemize |
|
|
|
@comment also POSIXELY_CORRECT LINES COLUMNS HOME but no interest in |
|
@comment mentioning these. |
|
|
|
All the Gforth environment variables default to sensible values if they |
|
are not set. |
|
|
|
|
|
@comment ---------------------------------------------- |
|
@node Gforth Files, Startup speed, Environment variables, Gforth Environment |
|
@section Gforth files |
|
@cindex Gforth files |
|
|
|
When you install Gforth on a Unix system, it installs files in these |
|
locations by default: |
|
|
|
@itemize @bullet |
|
@item |
|
@file{/usr/local/bin/gforth} |
|
@item |
|
@file{/usr/local/bin/gforthmi} |
|
@item |
|
@file{/usr/local/man/man1/gforth.1} - man page. |
|
@item |
|
@file{/usr/local/info} - the Info version of this manual. |
|
@item |
|
@file{/usr/local/lib/gforth/<version>/...} - Gforth @file{.fi} files. |
|
@item |
|
@file{/usr/local/share/gforth/<version>/TAGS} - Emacs TAGS file. |
|
@item |
|
@file{/usr/local/share/gforth/<version>/...} - Gforth source files. |
|
@item |
|
@file{.../emacs/site-lisp/gforth.el} - Emacs gforth mode. |
|
@end itemize |
|
|
|
You can select different places for installation by using |
|
@code{configure} options (listed with @code{configure --help}). |
|
|
|
@comment ---------------------------------------------- |
|
@node Startup speed, , Gforth Files, Gforth Environment |
|
@section Startup speed |
|
@cindex Startup speed |
|
@cindex speed, startup |
|
|
|
If Gforth is used for CGI scripts or in shell scripts, its startup |
|
speed may become a problem. On a 300MHz 21064a under Linux-2.2.13 with |
|
glibc-2.0.7, @code{gforth -e bye} takes about 24.6ms user and 11.3ms |
|
system time. |
|
|
|
If startup speed is a problem, you may consider the following ways to |
|
improve it; or you may consider ways to reduce the number of startups |
|
(e.g., Fast-CGI). |
|
|
|
The first step to improve startup speed is to statically link Gforth, by |
|
building it with @code{XLDFLAGS=-static}. This requires more memory for |
|
the code and will therefore slow down the first invocation, but |
|
subsequent invocations avoid the dynamic linking overhead. Another |
|
disadvantage is that Gforth won't profit from library upgrades. As a |
|
result, @code{gforth-static -e bye} takes about 17.1ms user and |
|
8.2ms system time. |
|
|
|
The next step to improve startup speed is to use a non-relocatable image |
|
@ref{Non-Relocatable Image Files}. You can create this image with |
|
@code{gforth -e "savesystem gforthnr.fi bye"} and later use it with |
|
@code{gforth -i gforthnr.fi ...}. This avoids the relocation overhead |
|
and a part of the copy-on-write overhead. The disadvantage is that the |
|
nonrelocatable image does not work if the OS gives Gforth a different |
|
address for the dictionary, for whatever reason; so you better provide a |
|
fallback on a relocatable image. @code{gforth-static -i gforthnr.fi -e |
|
bye} takes about 15.3ms user and 7.5ms system time. |
|
|
|
The final step is to disable dictionary hashing in Gforth. Gforth |
|
builds the hash table on startup, which takes much of the startup |
|
overhead. You can do this by commenting out the @code{include hash.fs} |
|
in @file{startup.fs} and everything that requires @file{hash.fs} (at the |
|
moment @file{table.fs} and @file{ekey.fs}) and then doing @code{make}. |
|
The disadvantages are that functionality like @code{table} and |
|
@code{ekey} is missing and that text interpretation (e.g., compiling) |
|
now takes much longer. So, you should only use this method if there is |
|
no significant text interpretation to perform (the script should be |
|
compiled into the image, among other things). @code{gforth-static -i |
|
gforthnrnh.fi -e bye} takes about 2.1ms user and 6.1ms system time. |
|
|
|
@c ****************************************************************** |
|
@node Tutorial, Introduction, Gforth Environment, Top |
|
@chapter Forth Tutorial |
|
@cindex Tutorial |
|
@cindex Forth Tutorial |
|
|
|
This tutorial can be used with any ANS-compliant Forth; any places that |
|
mention features specific to Gforth are marked as such and you can skip |
|
them, if you work with another Forth. This tutorial does not explain |
|
all features of Forth, just enough to get you started and give you some |
|
ideas about the facilities available in Forth. Read the rest of the |
|
manual and the standard when you are through this. |
|
|
|
The intended way to use this tutorial is that you work through it while |
|
sitting in front of the console, take a look at the examples and predict |
|
what they will do, then try them out; if the outcome is not as expected, |
|
find out why (e.g., by trying out variations of the example), so you |
|
understand what's going on. There are also some assignments that you |
|
should solve. |
|
|
|
This tutorial assumes that you have programmed before and know what, |
|
e.g., a loop is. |
|
|
|
@c !! explain compat library |
|
|
|
@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:: |
|
* 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:: |
|
@end menu |
|
|
|
@node Starting Gforth Tutorial, Syntax Tutorial, Tutorial, Tutorial |
|
@section Starting Gforth |
|
|
|
You can start Gforth by typing its name: |
|
|
|
@example |
|
gforth |
|
@end example |
|
|
|
That puts you into interactive mode; you can leave Gforth by typing |
|
@code{bye}. While in Gforth, you can edit the command line and access |
|
the command line history with cursor keys, similar to bash. |
|
|
|
|
|
@node Syntax Tutorial, Crash Course Tutorial, Starting Gforth Tutorial, Tutorial |
|
@section Syntax |
|
|
|
A @dfn{word} is a sequence of arbitrary characters (expcept white |
|
space). Words are separated by white space. E.g., each of the |
|
following lines contains exactly one word: |
|
|
|
@example |
|
word |
|
!@@#$%^&*() |
|
1234567890 |
|
5!a |
|
@end example |
|
|
|
A frequent beginner's error is to leave away necessary white space, |
|
resulting in an error like @samp{Undefined word}; so if you see such an |
|
error, check if you have put spaces wherever necessary. |
|
|
|
@example |
|
." hello, world" \ correct |
|
."hello, world" \ gives an "Undefined word" error |
|
@end example |
|
|
|
Gforth and most other Forth systems ignores differences in case (it is |
|
case-insensitive), i.e., @samp{word} is the same as @samp{Word}. If |
|
your system is case-sensitive, you may have to type all the examples |
|
given here in upper case. |
|
|
|
|
|
@node Crash Course Tutorial, Stack Tutorial, Syntax Tutorial, Tutorial |
|
@section Crash Course |
|
|
|
Type |
|
|
|
@example |
|
0 0 ! |
|
here execute |
|
' catch >body 20 erase abort |
|
' (quit) >body 20 erase |
|
@end example |
|
|
|
The last two examples are guaranteed to destroy parts of Gforth (and |
|
most other systems), so you better leave Gforth afterwards (if it has |
|
not finished by itself). On some systems you may have to kill gforth |
|
from outside (e.g., in Unix with @code{kill}). |
|
|
|
Now that you know how to produce crashes (and that there's not much to |
|
them), let's learn how to produce meaningful programs. |
|
|
|
|
|
@node Stack Tutorial, Arithmetics Tutorial, Crash Course Tutorial, Tutorial |
|
@section Stack |
|
|
|
The most obvious feature of Forth is the stack. When you type in a |
|
number, it is pushed on the stack. You can display the content of the |
|
stack with @code{.s}. |
|
|
|
@example |
|
1 2 .s |
|
3 .s |
|
@end example |
|
|
|
@code{.s} displays the top-of-stack to the right, i.e., the numbers |
|
appear in @code{.s} output as they appeared in the input. |
|
|
|
You can print the top of stack element with @code{.}. |
|
|
|
@example |
|
1 2 3 . . . |
|
@end example |
|
|
|
In general, words consume their stack arguments (@code{.s} is an |
|
exception). |
|
|
|
@assignment |
|
What does the stack contain after @code{5 6 7 .}? |
|
@endassignment |
|
|
|
|
|
@node Arithmetics Tutorial, Stack Manipulation Tutorial, Stack Tutorial, Tutorial |
|
@section Arithmetics |
|
|
|
The words @code{+}, @code{-}, @code{*}, @code{/}, and @code{mod} always |
|
operate on the top two stack items: |
|
|
|
@example |
|
2 2 + . |
|
2 1 - . |
|
7 3 mod . |
|
@end example |
|
|
|
The operands of @code{-}, @code{/}, and @code{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: |
|
|
|
@example |
|
3 4 + 5 * . |
|
3 4 5 * + . |
|
@end example |
|
|
|
@assignment |
|
What are the infix expressions corresponding to the Forth code above? |
|
Write @code{6-7*8+9} in Forth notation@footnote{This notation is also |
|
known as Postfix or RPN (Reverse Polish Notation).}. |
|
@endassignment |
|
|
|
To change the sign, use @code{negate}: |
|
|
|
@example |
|
2 negate . |
|
@end example |
|
|
|
@assignment |
|
Convert -(-3)*4-5 to Forth. |
|
@endassignment |
|
|
|
@code{/mod} performs both @code{/} and @code{mod}. |
|
|
|
@example |
|
7 3 /mod . . |
|
@end example |
|
|
|
@node Stack Manipulation Tutorial, Using files for Forth code Tutorial, Arithmetics Tutorial, Tutorial |
|
@section Stack Manipulation |
|
|
|
Stack manipulation words rearrange the data on the stack. |
|
|
|
@example |
|
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 |
|
@end example |
|
|
|
These are the most important stack manipulation words. There are also |
|
variants that manipulate twice as many stack items: |
|
|
|
@example |
|
1 2 3 4 .s 2swap .s 2drop 2drop |
|
@end example |
|
|
|
Two more stack manipulation words are: |
|
|
|
@example |
|
1 2 .s nip .s drop |
|
1 2 .s tuck .s 2drop drop |
|
@end example |
|
|
|
@assignment |
|
Replace @code{nip} and @code{tuck} with combinations of other stack |
|
manipulation words. |
|
|
|
@example |
|
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 |
|
@end example |
|
@endassignment |
|
|
|
@example |
|
5 dup * . |
|
@end example |
|
|
|
@assignment |
|
Write 17^3 and 17^4 in Forth, without writing @code{17} more than once. |
|
Write a piece of Forth code that expects two numbers on the stack |
|
(@var{a} and @var{b}, with @var{b} on top) and computes |
|
@code{(a-b)(a+1)}. |
|
@endassignment |
|
|
|
@node Using files for Forth code Tutorial, Comments Tutorial, Stack Manipulation Tutorial, Tutorial |
|
@section 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, @pxref{Emacs and |
|
Gforth}) to create @var{file} and use |
|
|
|
@example |
|
s" @var{file}" included |
|
@end example |
|
|
|
to load it into your Forth system. The file name extension I use for |
|
Forth files is @samp{.fs}. |
|
|
|
You can easily start Gforth with some files loaded like this: |
|
|
|
@example |
|
gforth @var{file1} @var{file2} |
|
@end example |
|
|
|
If an error occurs during loading these files, Gforth terminates, |
|
whereas an error during @code{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 |
|
|
|
@example |
|
gforth @var{code} @var{tests} -e bye |
|
@end example |
|
|
|
(often by performing this command with @kbd{C-x C-e} in Emacs). The |
|
@code{-e bye} ensures that Gforth terminates afterwards so that I can |
|
restart this command without ado. |
|
|
|
The advantage of this approach is that the tests can be repeated easily |
|
every time the program ist changed, making it easy to catch bugs |
|
introduced by the change. |
|
|
|
|
|
@node Comments Tutorial, Colon Definitions Tutorial, Using files for Forth code Tutorial, Tutorial |
|
@section Comments |
|
|
|
@example |
|
\ That's a comment; it ends at the end of the line |
|
( Another comment; it ends here: ) .s |
|
@end example |
|
|
|
@code{\} and @code{(} are ordinary Forth words and therefore have to be |
|
separated with white space from the following text. |
|
|
|
@example |
|
\This gives an "Undefined word" error |
|
@end example |
|
|
|
The first @code{)} ends a comment started with @code{(}, so you cannot |
|
nest @code{(}-comments; and you cannot comment out text containing a |
|
@code{)} with @code{( ... )}@footnote{therefore it's a good idea to |
|
avoid @code{)} in word names.}. |
|
|
|
I use @code{\}-comments for descriptive text and for commenting out code |
|
of one or more line; I use @code{(}-comments for describing the stack |
|
effect, the stack contents, or for commenting out sub-line pieces of |
|
code. |
|
|
|
The Emacs mode @file{gforth.el} (@pxref{Emacs and Gforth}) supports |
|
these uses by commenting out a region with @kbd{C-x \}, uncommenting a |
|
region with @kbd{C-u C-x \}, and filling a @code{\}-commented region |
|
with @kbd{M-q}. |
|
|
|
|
|
@node Colon Definitions Tutorial, Decompilation Tutorial, Comments Tutorial, Tutorial |
|
@section Colon Definitions |
|
|
|
are similar to procedures and functions in other programming languages. |
|
|
|
@example |
|
: squared ( n -- n^2 ) |
|
dup * ; |
|
5 squared . |
|
7 squared . |
|
@end example |
|
|
|
@code{:} starts the colon definition; its name is @code{squared}. The |
|
following comment describes its stack effect. The words @code{dup *} |
|
are not executed, but compiled into the definition. @code{;} ends the |
|
colon definition. |
|
|
|
The newly-defined word can be used like any other word, including using |
|
it in other definitions: |
|
|
|
@example |
|
: cubed ( n -- n^3 ) |
|
dup squared * ; |
|
-5 cubed . |
|
: fourth-power ( n -- n^4 ) |
|
squared squared ; |
|
3 fourth-power . |
|
@end example |
|
|
|
@assignment |
|
Write colon definitions for @code{nip}, @code{tuck}, @code{negate}, and |
|
@code{/mod} in terms of other Forth words, and check if they work (hint: |
|
test your tests on the originals first). Don't let the |
|
@samp{redefined}-Messages spook you, they are just warnings. |
|
@endassignment |
|
|
|
|
|
@node Decompilation Tutorial, Stack-Effect Comments Tutorial, Colon Definitions Tutorial, Tutorial |
|
@section Decompilation |
|
|
|
You can decompile colon definitions with @code{see}: |
|
|
|
@example |
|
see squared |
|
see cubed |
|
@end example |
|
|
|
In Gforth @code{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). |
|
|
|
@node Stack-Effect Comments Tutorial, Types Tutorial, Decompilation Tutorial, Tutorial |
|
@section Stack-Effect Comments |
|
|
|
By convention the comment after the name of a definition describes the |
|
stack effect: The part in from of the @samp{--} 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 @samp{--} |
|
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 @code{( -- )}. You should also add some descriptive comment to |
|
more complicated words (I usually do this in the lines following |
|
@code{:}). If you don't do this, your code becomes unreadable (because |
|
you have to work through every definition before you can undertsand |
|
any). |
|
|
|
@assignment |
|
The stack effect of @code{swap} can be written like this: @code{x1 x2 -- |
|
x2 x1}. Describe the stack effect of @code{-}, @code{drop}, @code{dup}, |
|
@code{over}, @code{rot}, @code{nip}, and @code{tuck}. Hint: When you |
|
are done, you can compare your stack effects to this in this manual |
|
(@pxref{Word Index}). |
|
@endassignment |
|
|
|
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., |
|
|
|
@example |
|
: cubed ( n -- n^3 ) |
|
dup squared ( n n^2 ) * ; |
|
@end example |
|
|
|
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 (@pxref{Factoring Tutorial,, |
|
Factoring}), which typically eliminates the need for the stack effect; |
|
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: |
|
|
|
@table @code |
|
@item n |
|
signed integer |
|
@item u |
|
unsigned integer |
|
@item c |
|
character |
|
@item f |
|
Boolean flags, i.e. @code{false} or @code{true}. |
|
@item a-addr,a- |
|
Cell-aligned address |
|
@item c-addr,c- |
|
Char-aligned address (note that a Char may have two bytes in Windows NT) |
|
@item xt |
|
Execution token, same size as Cell |
|
@item 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 @emph{word} already means |
|
something different in Forth. |
|
@item d |
|
signed double-cell integer |
|
@item ud |
|
unsigned double-cell integer |
|
@item r |
|
Float (on the FP stack) |
|
@end table |
|
|
|
You can find a more complete list in @ref{Notation}. |
|
|
|
@assignment |
|
Write stack-effect comments for all definitions you have written up to |
|
now. |
|
@endassignment |
|
|
|
|
|
@node Types Tutorial, Factoring Tutorial, Stack-Effect Comments Tutorial, Tutorial |
|
@section Types |
|
|
|
In Forth the names of the operations are not overloaded; so similar |
|
operations on different types need different names; e.g., @code{+} adds |
|
integers, and you have to use @code{f+} to add floating-point numbers. |
|
The following prefixes are often used for related operations on |
|
different types: |
|
|
|
@table @code |
|
@item (none) |
|
signed integer |
|
@item u |
|
unsigned integer |
|
@item c |
|
character |
|
@item d |
|
signed double-cell integer |
|
@item ud, du |
|
unsigned double-cell integer |
|
@item 2 |
|
two cells (not-necessarily double-cell numbers) |
|
@item m, um |
|
mixed single-cell and double-cell operations |
|
@item f |
|
floating-point (note that in stack comments @samp{f} represents flags, |
|
and @samp{r} represents FP number). |
|
@end table |
|
|
|
If there are no differences between the signed and the unsigned variant |
|
(e.g., for @code{+}), there is only the prefix-less variant. |
|
|
|
Forth does not perform type checking, neither at compile time, nor at |
|
run time. If you use the wrong oeration, the data are interpreted |
|
incorrectly: |
|
|
|
@example |
|
-1 u. |
|
@end example |
|
|
|
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). |
|
|
|
|
|
@node Factoring Tutorial, Designing the stack effect Tutorial, Types Tutorial, Tutorial |
|
@section 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 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. |
|
|
|
@c example !! |
|
|
|
|
|
@node Designing the stack effect Tutorial, Local Variables Tutorial, Factoring Tutorial, Tutorial |
|
@section Designing the stack effect |
|
|
|
In other languages you can use an arbitrary order of parameters for a |
|
function; and since ther 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: |
|
|
|
@itemize @bullet |
|
|
|
@item |
|
Words consume all of their parameters (e.g., @code{.}). |
|
|
|
@item |
|
If there is a convention on the order of parameters (e.g., from |
|
mathematics or another programming language), stick with it (e.g., |
|
@code{-}). |
|
|
|
@item |
|
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 reader does not need to keep track of the bottom item |
|
through a long sequence of code (or, alternatively, through stack |
|
manipulations). E.g., @code{!} (store, see @pxref{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). |
|
|
|
@item |
|
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 @code{open-file} return the error code on the top of stack, because |
|
it is usually consumed quickly by @code{throw}; moreover, the error code |
|
has to be checked before doing anything with the other results. |
|
|
|
@end itemize |
|
|
|
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). |
|
|
|
@c example !! structure package |
|
|
|
@node Local Variables Tutorial, Conditional execution Tutorial, Designing the stack effect Tutorial, Tutorial |
|
@section Local Variables |
|
|
|
You can define local variables (@emph{locals}) in a colon definition: |
|
|
|
@example |
|
: swap @{ a b -- b a @} |
|
b a ; |
|
1 2 swap .s 2drop |
|
@end example |
|
|
|
(If your Forth system does not support this syntax, include |
|
@file{compat/anslocals.fs} first). |
|
|
|
In this example @code{@{ a b -- b a @}} is the locals definition; it |
|
takes two cells from the stack, puts the top of stack in @code{b} and |
|
the next stack element in @code{a}. @code{--} starts a comment ending |
|
with @code{@}}. After the locals definition, using the name of the |
|
local will push its value on the stack. You can leave the comment |
|
part (@code{-- b a}) away: |
|
|
|
@example |
|
: swap ( x1 x2 -- x2 x1 ) |
|
@{ a b @} b a ; |
|
@end example |
|
|
|
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 controll 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 |
|
@endassignment |
|
|
|
|
|
@node Conditional execution Tutorial, Flags and Comparisons Tutorial, Local Variables Tutorial, Tutorial |
|
@section Conditional execution |
|
|
|
In Forth you can use control structures only inside colon definitions. |
|
An @code{if}-structure looks like this: |
|
|
|
@example |
|
: abs ( n1 -- +n2 ) |
|
dup 0 < if |
|
negate |
|
endif ; |
|
5 abs . |
|
-5 abs . |
|
@end example |
|
|
|
@code{if} takes a flag from the stack. If the flag is non-zero (true), |
|
the following code is performed, otherwise execution continues after the |
|
@code{endif} (or @code{else}). @code{<} combares the top two stack |
|
elements and prioduces a flag: |
|
|
|
@example |
|
1 2 < . |
|
2 1 < . |
|
1 1 < . |
|
@end example |
|
|
|
Actually the standard name for @code{endif} is @code{then}. This |
|
tutorial presents the examples using @code{endif}, because this is often |
|
less confusing for people familiar with other programming languages |
|
where @code{then} has a different meaning. If your system does not have |
|
@code{endif}, define it with |
|
|
|
@example |
|
: endif postpone then ; immediate |
|
@end example |
|
|
|
You can optionally use an @code{else}-part: |
|
|
|
@example |
|
: min ( n1 n2 -- n ) |
|
2dup < if |
|
drop |
|
else |
|
nip |
|
endif ; |
|
2 3 min . |
|
3 2 min . |
|
@end example |
|
|
|
@assignment |
|
Write @code{min} without @code{else}-part (hint: what's the definition |
|
of @code{nip}?). |
|
@endassignment |
|
|
|
|
|
@node Flags and Comparisons Tutorial, General Loops Tutorial, Conditional execution Tutorial, Tutorial |
|
@section 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., @code{if}) any non-zero value is |
|
treated as true flag. |
|
|
|
@example |
|
false . |
|
true . |
|
true hex u. decimal |
|
@end example |
|
|
|
Comparison words produce canonical flags: |
|
|
|
@example |
|
1 1 = . |
|
1 0= . |
|
0 1 < . |
|
0 0 < . |
|
-1 1 u< . \ type error, u< interprets -1 as large unsigned number |
|
-1 1 < . |
|
@end example |
|
|
|
Gforth supports all combinations of the prefixes @code{0 u d d0 du} (or |
|
none) and the comparisons @code{= <> < > <= >=}. Only a part of these |
|
combinations are standard (see the standard or !! the glossary for |
|
details). |
|
|
|
You can use @code{and or xor invert} can be used as operations on |
|
canonical flags. Actually they are bitwise operations: |
|
|
|
@example |
|
1 2 and . |
|
1 2 or . |
|
1 3 xor . |
|
1 invert . |
|
@end example |
|
|
|
You can convert a zero/non-zero flag into a canonical flag with |
|
@code{0<>} (and complement it on the way with @code{0=}). |
|
|
|
@example |
|
1 0= . |
|
1 0<> . |
|
@end example |
|
|
|
You can use the all-bits-set feature of canonicasl flags and the bitwise |
|
operation of the Boolean operations to avoid @code{if}s: |
|
|
|
@example |
|
: foo ( n1 -- n2 ) |
|
0= if |
|
14 |
|
else |
|
0 |
|
endif ; |
|
0 foo . |
|
1 foo . |
|
|
|
: foo ( n1 -- n2 ) |
|
0= 14 and ; |
|
0 foo . |
|
1 foo . |
|
@end example |
|
|
|
@assignment |
|
Write @code{min} without @code{if}. |
|
@endassignment |
|
|
|
|
|
@node General Loops Tutorial, Counted loops Tutorial, Flags and Comparisons Tutorial, Tutorial |
|
@section General Loops |
|
|
|
The endless loop is the most simple one: |
|
|
|
@example |
|
: endless ( -- ) |
|
0 begin |
|
dup . 1+ |
|
again ; |
|
endless |
|
@end example |
|
|
|
Terminate this loop by pressing @kbd{Ctrl-C} (in Gforth). @code{begin} |
|
does nothing at run-time, @code{again} jumps back to @code{begin}. |
|
|
|
A loop with one exit at any place looks like this: |
|
|
|
@example |
|
: 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 . |
|
@end example |
|
|
|
At run-time @code{while} consumes a flag; if it is 0, execution |
|
continues behind the @code{repeat}; if the falg is non-zero, execution |
|
continues behind the @code{while}. @code{Repeat} jumps back to |
|
@code{begin}, just like @code{again}. |
|
|
|
In Forth there are many combinations/abbreviations, like @code{1+}. |
|
However, @code{2/} is not one of them; it shifts it's argument right by |
|
one bit (arithmetic shift right): |
|
|
|
@example |
|
-5 2 / . |
|
-5 2/ . |
|
@end example |
|
|
|
@code{assert(} is no standard word, but you can get it on systems other |
|
then Gforth by including @file{compat/assert.fs}. You can see what it |
|
does by trying |
|
|
|
@example |
|
0 log2 . |
|
@end example |
|
|
|
Here's a loop with an exit at the end: |
|
|
|
@example |
|
: 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 ; |
|
@end example |
|
|
|
@code{Until} consumes a flag; if it is non-zero, execution continues at |
|
the @code{begin}, otherwise after the @code{until}. |
|
|
|
@assignment |
|
Write a definition for computing the greatest common divisor. |
|
@endassignment |
|
|
|
|
|
@node Counted loops Tutorial, Recursion Tutorial, General Loops Tutorial, Tutorial |
|
@section Counted loops |
|
|
|
@example |
|
: ^ ( n1 u -- n ) |
|
\ n = the uth power of u1 |
|
1 swap 0 u+do |
|
over * |
|
loop |
|
nip ; |
|
3 2 ^ . |
|
4 3 ^ . |
|
@end example |
|
|
|
@code{U+do} (from @file{compat/loops.fs}, if your Forth system doesn't |
|
have it) takes two numbers of the stack @code{( u3 u4 -- )}, and then |
|
performs the code between @code{u+do} and @code{loop} for @code{u3-u4} |
|
times (or not at all, if @code{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 @code{i}: |
|
|
|
@example |
|
: fac ( u -- u! ) |
|
1 swap 1+ 1 u+do |
|
i * |
|
loop ; |
|
5 fac . |
|
7 fac . |
|
@end example |
|
|
|
There is also @code{+do}, which expects signed numbers (important for |
|
deciding whether to enter the loop). |
|
|
|
@assignment |
|
Write a definition for computing the nth Fibonacci number. |
|
@endassignment |
|
|
|
!! +DO...+LOOP |
|
!! -DO...-LOOP |
|
|
|
|
|
@node Recursion Tutorial, Leaving definitions or loops Tutorial, Counted loops Tutorial, Tutorial |
|
@section Recursion |
|
|
|
Usually the name of a definition is not visible in the definition; but |
|
earlier definitions are usually visible: |
|
|
|
@example |
|
1 0 / . \ "Floating-point unidentified fault" in Gforth on most platforms |
|
: / ( n1 n2 -- n ) |
|
dup 0= if |
|
-10 throw \ report division by zero |
|
endif |
|
/ \ old version |
|
; |
|
1 0 / |
|
@end example |
|
|
|
For recursive definitions you can use @code{recursive} (non-standard) or |
|
@code{recurse}: |
|
|
|
@example |
|
: 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 . |
|
@end example |
|
|
|
@assignment |
|
Write a recursive definition for computing the nth Fibonacci number. |
|
@endassignment |
|
|
|
|
|
@node Leaving definitions or loops Tutorial, Return Stack Tutorial, Recursion Tutorial, Tutorial |
|
@section Leaving definitions or loops |
|
|
|
@code{EXIT} exits the current definition right away. For every counted |
|
loop that is left in this way, an @code{UNLOOP} has to be performed |
|
before the @code{EXIT}: |
|
|
|
@c !! real examples |
|
@example |
|
: ... |
|
... u+do |
|
... if |
|
... unloop exit |
|
endif |
|
... |
|
loop |
|
... ; |
|
@end example |
|
|
|
@code{LEAVE} leaves the innermost counted loop right away: |
|
|
|
@example |
|
: ... |
|
... u+do |
|
... if |
|
... leave |
|
endif |
|
... |
|
loop |
|
... ; |
|
@end example |
|
|
|
|
|
@node Return Stack Tutorial, Memory Tutorial, Leaving definitions or loops Tutorial, Tutorial |
|
@section 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: |
|
|
|
@example |
|
: foo ( n1 n2 -- ) |
|
.s |
|
>r .s |
|
r@ . |
|
>r .s |
|
r@ . |
|
r> . |
|
r@ . |
|
r> . ; |
|
1 2 foo |
|
@end example |
|
|
|
@code{>r} takes an element from the data stack and pushes it onto the |
|
return stack; conversely, @code{r>} moves an elementm from the return to |
|
the data stack; @code{r@@} pushes a copy of the top of the return stack |
|
on the return 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: |
|
|
|
@example |
|
: 2swap ( x1 x2 x3 x4 -- x3 x4 x1 x2 ) |
|
rot >r rot r> ; |
|
@end example |
|
|
|
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: |
|
|
|
@example |
|
: crash ( n -- ) |
|
>r ; |
|
5 crash |
|
@end example |
|
|
|
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? |
|
@endassignment |
|
|
|
|
|
@node Memory Tutorial, Characters and Strings Tutorial, Return Stack Tutorial, Tutorial |
|
@section Memory |
|
|
|
You can create a global variable @code{v} with |
|
|
|
@example |
|
variable v ( -- addr ) |
|
@end example |
|
|
|
@code{v} pushes the address of a cell in memory on the stack. This cell |
|
was reserved by @code{variable}. You can use @code{!} (store) to store |
|
values into this cell and @code{@@} (fetch) to load the value from the |
|
stack into memory: |
|
|
|
@example |
|
v . |
|
5 v ! .s |
|
v @ . |
|
@end example |
|
|
|
You can also reserve more memory: |
|
|
|
@example |
|
create v2 20 cells allot |
|
@end example |
|
|
|
creates a word @code{v2} and reserves 20 cells; the address pushed by |
|
@code{v2} points to the start of these 20 cells. You can use address |
|
arithmetic to access these cells: |
|
|
|
@example |
|
3 v2 5 cells + ! |
|
@end example |
|
|
|
You can reserve and initialize memory with @code{,}: |
|
|
|
@example |
|
create v3 |
|
5 , 4 , 3 , 2 , 1 , |
|
v3 @ . |
|
v3 cell+ @ . |
|
v3 2 cells + @ . |
|
@end example |
|
|
|
@assignment |
|
Write a definition @code{vsum ( addr u -- n )} that computes the sum of |
|
@code{u} cells, with the first of these cells at @code{addr}, the next |
|
one at @code{addr cell+} etc. |
|
@endassignment |
|
|
|
You can also reserve memory without creating a new word: |
|
|
|
@example |
|
here 10 cells allot |
|
.s |
|
@end example |
|
|
|
@code{Here} pushes the start address of the memory area. You should |
|
store it somewhere, or you will have a hard time finding the memory area |
|
again. |
|
|
|
@code{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 @code{allot}ed with |
|
|
|
@example |
|
-10 cells allot |
|
@end example |
|
|
|
Note that you cannot do this if you have created a new word in the |
|
meantime (because then your @code{allot}ed memory is no longer on the |
|
top of the dictionary ``stack''). |
|
|
|
Alternatively, you can use @code{allocate} and @code{free} which allow |
|
freeing memory in any order: |
|
|
|
@example |
|
10 cells allocate throw .s |
|
20 cells allocate throw .s |
|
swap |
|
free throw |
|
free throw |
|
@end example |
|
|
|
The @code{throw}s deal with errors (e.g., out of memory). |
|
|
|
And there is also a garbage collector @url{!!}, which eliminates the |
|
need to @code{free} memory explicitly. |
|
|
|
|
|
@node Characters and Strings Tutorial, Alignment Tutorial, Memory Tutorial, Tutorial |
|
@section 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: |
|
|
|
@example |
|
create v4 |
|
104 c, 97 c, 108 c, 108 c, 111 c, |
|
v4 4 chars + c@ . |
|
@end example |
|
|
|
The preferred representation of strings on the stack is @code{addr |
|
u-count}, where @code{addr} is the address of the first character and |
|
@code{u-count} is the number of characters in the string. |
|
|
|
@example |
|
v4 5 type |
|
@end example |
|
|
|
You get a string constant with |
|
|
|
@example |
|
s" hello, world" .s |
|
type |
|
@end example |
|
|
|
Make sure you have a space between @code{s"} and the string; @code{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 @code{s"} is quite restricted: the |
|
string exists only until the next call of @code{s"} (some Forth systems |
|
keep more than one of these strings, but usually they still have a |
|
limited lifetime. |
|
|
|
@example |
|
s" hello," s" world" .s |
|
type |
|
type |
|
@end example |
|
|
|
However, you can also use @code{s"} in a definition, and the resulting |
|
strings then live forever (well, as long as the definition): |
|
|
|
@example |
|
: foo s" hello," s" world" ; |
|
foo .s |
|
type |
|
type |
|
@end example |
|
|
|
@assignment |
|
@code{Emit ( c -- )} types @code{c} as character (not a number). |
|
Implement @code{type ( addr u -- )}. |
|
@endassignment |
|
|
|
@node Alignment Tutorial, Interpretation and Compilation Semantics and Immediacy Tutorial, Characters and Strings Tutorial, Tutorial |
|
@section Alignment |
|
|
|
On many processors cells have to be aligned in memory, if you want to |
|
access them with @code{@@} and @code{!} (and even if the processor does |
|
not require alignment, access to aligned cells are faster). |
|
|
|
@code{Create} aligns @code{here} (i.e., the place where the next |
|
allocation will occur, and that the @code{create}d word points to). |
|
Likewise, the memory produced by @code{allocate} starts at an aligned |
|
address. Adding a number of @code{cells} to an aligned address produces |
|
another aligned address. |
|
|
|
However, address arithmetic involving @code{char+} and @code{chars} can |
|
create an address that is not cell-aligned. @code{Aligned ( addr -- |
|
a-addr )} produces the next aligned address: |
|
|
|
@example |
|
v3 char+ aligned .s @ . |
|
v3 char+ .s @ . |
|
@end example |
|
|
|
Similarly, @code{align} advances @code{here} to the next aligned |
|
address: |
|
|
|
@example |
|
create v5 97 c, |
|
here . |
|
align here . |
|
1000 , |
|
@end example |
|
|
|
Note that you should use aligned addresses even if your processor does |
|
not require them, if you want your program to be portable. |
|
|
|
|
|
@node Interpretation and Compilation Semantics and Immediacy Tutorial, Execution Tokens Tutorial, Alignment Tutorial, Tutorial |
|
@section Interpretation and Compilation Semantics and Immediacy |
|
|
|
When a word is compiled, it behaves differently from being interpreted. |
|
E.g., consider @code{+}: |
|
|
|
@example |
|
1 2 + . |
|
: foo + ; |
|
@end example |
|
|
|
These two behaviours are known as compilation and interpretation |
|
semantics. For normal words (e.g., @code{+}), the compilation semantics |
|
is to append the interpretation semantics to the currently defined word |
|
(@code{foo} in the example above). I.e., when @code{foo} is executed |
|
later, the interpretation semantics of @code{+} (i.e., adding two |
|
numbers) will be performed. |
|
|
|
However, there are words with non-default compilation semantics, e.g., |
|
the control-flow words like @code{if}. You can use @code{immediate} to |
|
change the compilation semantics of the last defined word to be equal to |
|
the interpretation semantics: |
|
|
|
@example |
|
: [FOO] ( -- ) |
|
5 . ; immediate |
|
|
|
[FOO] |
|
: bar ( -- ) |
|
[FOO] ; |
|
bar |
|
see bar |
|
@end example |
|
|
|
Two conventions to mark words with non-default compilation semnatics are |
|
names with brackets (more frequently used) and to write them all in |
|
upper case (less frequently used). |
|
|
|
In Gforth (and many other systems) you can also remove the |
|
interpretation semantics with @code{compile-only} (the compilation |
|
semantics is derived from the original interpretation semantics): |
|
|
|
@example |
|
: flip ( -- ) |
|
6 . ; compile-only \ but not immediate |
|
flip |
|
|
|
: flop ( -- ) |
|
flip ; |
|
flop |
|
@end example |
|
|
|
In this example the interpretation semantics of @code{flop} is equal to |
|
the original interpretation semantics of @code{flip}. |
|
|
|
The text interpreter has two states: in interpret state, it performs the |
|
interpretation semantics of words it encounters; in compile state, it |
|
performs the compilation semantics of these words. |
|
|
|
Among other things, @code{:} switches into compile state, and @code{;} |
|
switches back to interpret state. They contain the factors @code{]} |
|
(switch to compile state) and @code{[} (switch to interpret state), that |
|
do nothing but switch the state. |
|
|
|
@example |
|
: xxx ( -- ) |
|
[ 5 . ] |
|
; |
|
|
|
xxx |
|
see xxx |
|
@end example |
|
|
|
These brackets are also the source of the naming convention mentioned |
|
above. |
|
|
|
|
|
@node Execution Tokens Tutorial, Exceptions Tutorial, Interpretation and Compilation Semantics and Immediacy Tutorial, Tutorial |
|
@section Execution Tokens |
|
|
|
@code{' word} gives you the execution token (XT) of a word. The XT is a |
|
cell representing the interpretation semantics of a word. You can |
|
execute this semantics with @code{execute}: |
|
|
|
@example |
|
' + .s |
|
1 2 rot execute . |
|
@end example |
|
|
|
The XT is similar to a function pointer in C. However, parameter |
|
passing through the stack makes it a little more flexible: |
|
|
|
@example |
|
: map-array ( ... addr u xt -- ... ) |
|
\ führt xt ( ... x -- ... ) für jedes Element des Arrays aus, |
|
\ das bei addr beginnt und u Elemente enthält |
|
@{ 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 . |
|
@end example |
|
|
|
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 arrays 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 @code{compile,}: |
|
|
|
@example |
|
: foo1 ( n1 n2 -- n ) |
|
[ ' + compile, ] ; |
|
see foo |
|
@end example |
|
|
|
This is non-standard, because @code{compile,} has no compilation |
|
semantics in the standard, but it works in good Forth systems. For the |
|
broken ones, use |
|
|
|
@example |
|
: [compile,] compile, ; immediate |
|
|
|
: foo1 ( n1 n2 -- n ) |
|
[ ' + ] [compile,] ; |
|
see foo |
|
@end example |
|
|
|
@code{'} is a word with default compilation semantics; it parses the |
|
next word when its interpretation semantics are executed, not during |
|
compilation: |
|
|
|
@example |
|
: foo ( -- xt ) |
|
' ; |
|
see foo |
|
: bar ( ... "word" -- ... ) |
|
' execute ; |
|
see bar |
|
1 2 bar + |
|
@end example |
|
|
|
You often want to parse a word during compilation and compile its XT so |
|
it will be pushed on the stack at run-time. @code{[']} does this: |
|
|
|
@example |
|
: xt-+ ( -- xt ) |
|
['] + ; |
|
see xt-+ |
|
1 2 xt-+ execute . |
|
@end example |
|
|
|
Many programmers tend to see @code{'} and the word it parses as one |
|
unit, and expect it to behave like @code{[']} when compiled, and are |
|
confused by the actual behaviour. If you are, just remember that the |
|
Forth system just takes @code{'} 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 |
|
@uref{http://www.complang.tuwien.ac.at/papers/ertl98.ps.gz}). |
|
|
|
Note that the state of the interpreter does not come into play when |
|
creating and executing xts. I.e., even when you execute @code{'} in |
|
compile state, it still gives you the interpretation semantics. And |
|
whatever that state is, @code{execute} performs the semantics |
|
represented by the xt (i.e., the interpretation semantics). |
|
|
|
|
|
@node Exceptions Tutorial, Defining Words Tutorial, Execution Tokens Tutorial, Tutorial |
|
@section Exceptions |
|
|
|
@code{throw ( n -- )} causes an exception unless n is zero. |
|
|
|
@example |
|
100 throw .s |
|
0 throw .s |
|
@end example |
|
|
|
@code{catch ( ... xt -- ... n )} behaves similar to @code{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 @code{catch}: |
|
|
|
@example |
|
.s |
|
3 0 ' / catch .s |
|
3 2 ' / catch .s |
|
@end example |
|
|
|
@assignment |
|
Try the same with @code{execute} instead of @code{catch}. |
|
@endassignment |
|
|
|
@code{Throw} always jumps to the dynamically next enclosing |
|
@code{catch}, even if it has to leave several call levels to achieve |
|
this: |
|
|
|
@example |
|
: foo 100 throw ; |
|
: foo1 foo ." after foo" ; |
|
: bar ' foo1 catch ; |
|
bar |
|
@end example |
|
|
|
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: |
|
|
|
@example |
|
: ... |
|
save-x |
|
' word-changing-x catch ( ... n ) |
|
restore-x |
|
( ... n ) throw ; |
|
@end example |
|
|
|
Gforth provides an alternative syntax in addition to @code{cacth}: |
|
@code{try ... recover ... endtry}. If the code between @code{try} and |
|
@code{recover} has an exception, the stack depths are restored, the |
|
exception number is pushed on the stack, and the code between |
|
@code{recover} and @code{endtry} is performed. E.g., the definition for |
|
@code{catch} is |
|
|
|
@example |
|
: catch ( x1 .. xn xt -- y1 .. ym 0 / z1 .. zn error ) \ exception |
|
try |
|
execute 0 |
|
recover |
|
nip |
|
endtry ; |
|
@end example |
|
|
|
The equivalent to the restoration code above is |
|
|
|
@example |
|
: ... |
|
save-x |
|
try |
|
word-changing-x |
|
end-try |
|
restore-x |
|
throw ; |
|
@end example |
|
|
|
As you can see, the @code{recover} part is optional. |
|
|
|
|
|
@node Defining Words Tutorial, Arrays and Records Tutorial, Exceptions Tutorial, Tutorial |
|
@section Defining Words |
|
|
|
@code{:}, @code{create}, and @code{variable} are definition words: They |
|
define other words. @code{Constant} is another definition word: |
|
|
|
@example |
|
5 constant foo |
|
foo . |
|
@end example |
|
|
|
You can also use the prefixes @code{2} (double-cell) and @code{f} |
|
(floating point) with @code{variable} and @code{constant}. |
|
|
|
You can also define your own defining words. E.g.: |
|
|
|
@example |
|
: variable ( "name" -- ) |
|
create 0 , ; |
|
@end example |
|
|
|
You can also define defining words that create words that do something |
|
other than just producing their address: |
|
|
|
@example |
|
: constant ( n "name" -- ) |
|
create , |
|
does> ( -- n ) |
|
( addr ) @ ; |
|
|
|
5 constant foo |
|
foo . |
|
@end example |
|
|
|
The definition of @code{constant} above ends at the @code{does>}; i.e., |
|
@code{does>} replaces @code{;}, 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 @code{does>} |
|
whenever it is called. |
|
|
|
In the example above, @code{constant} uses @code{,} to store 5 into the |
|
body of @code{foo}. When @code{foo} executes, it pushes the address of |
|
the body onto the stack, then (in the code after the @code{does>}) |
|
fetches the 5 from there. |
|
|
|
The stack comment near the @code{does>} reflects the stack effect of the |
|
defined word, not the stack effect of the code after the @code{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 |
|
|
|
@example |
|
2 cells constant offset-field1 |
|
@end example |
|
|
|
and using this like |
|
|
|
@example |
|
( addr ) offset-field1 + |
|
@end example |
|
|
|
you can define a definition word |
|
|
@cindex -v, command-line option |
@example |
@cindex --version, command-line option |
: simple-field ( n "name" -- ) |
@item --version |
create , |
@itemx -v |
does> ( n1 -- n1+n ) |
Print version and exit |
( addr ) @ + ; |
|
@end example |
|
|
@cindex --debug, command-line option |
Definition and use of field offsets now look like this: |
@item --debug |
|
Print some information useful for debugging on startup. |
|
|
|
@cindex --offset-image, command-line option |
@example |
@item --offset-image |
2 cells simple-field field1 |
Start the dictionary at a slightly different position than would be used |
( addr ) field1 |
otherwise (useful for creating data-relocatable images, |
@end example |
@pxref{Data-Relocatable Image Files}). |
|
|
|
@cindex --no-offset-im, command-line option |
If you want to do something with the word without performing the code |
@item --no-offset-im |
after the @code{does>}, you can access the body of a @code{create}d word |
Start the dictionary at the normal position. |
with @code{>body ( xt -- addr )}: |
|
|
@cindex --clear-dictionary, command-line option |
@example |
@item --clear-dictionary |
: value ( n "name" -- ) |
Initialize all bytes in the dictionary to 0 before loading the image |
create , |
(@pxref{Data-Relocatable Image Files}). |
does> ( -- n1 ) |
|
@ ; |
|
: to ( n "name" -- ) |
|
' >body ! ; |
|
|
@cindex --die-on-signal, command-line-option |
5 value foo |
@item --die-on-signal |
foo . |
Normally Gforth handles most signals (e.g., the user interrupt SIGINT, |
7 to foo |
or the segmentation violation SIGSEGV) by translating it into a Forth |
foo . |
@code{THROW}. With this option, Gforth exits if it receives such a |
@end example |
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. |
|
@end table |
|
|
|
@cindex loading files at startup |
@assignment |
@cindex executing code on startup |
Define @code{defer ( "name" -- )}, which creates a word that stores an |
@cindex batch processing with Gforth |
XT (at the start the XT of @code{abort}), and upon execution |
As explained above, the image-specific command-line arguments for the |
@code{execute}s the XT. Define @code{is ( xt "name" -- )} that stores |
default image @file{gforth.fi} consist of a sequence of filenames and |
@code{xt} into @code{name}, a word defined with @code{defer}. Indirect |
@code{-e @var{forth-code}} options that are interpreted in the sequence |
recursion is one application of @code{defer}. |
in which they are given. The @code{-e @var{forth-code}} or |
@endassignment |
@code{--evaluate @var{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 @code{-e} several times. To exit |
|
after processing the command line (instead of entering interactive mode) |
|
append @code{-e bye} to the command line. |
|
|
|
@cindex versions, invoking other versions of Gforth |
@node Arrays and Records Tutorial, POSTPONE Tutorial, Defining Words Tutorial, Tutorial |
If you have several versions of Gforth installed, @code{gforth} will |
@section Arrays and Records |
invoke the version that was installed last. @code{gforth-@i{version}} |
|
invokes a specific version. If your environment contains the variable |
|
@code{GFORTHPATH}, you may want to override it by using the |
|
@code{--path} option. |
|
|
|
Not yet implemented: |
Forth has no standard words for defining data structures such as arrays |
On startup the system first executes the system initialization file |
and records (structs in C terminology), but you can build them yourself |
(unless the option @code{--no-init-file} is given; note that the system |
based on address arithmetic. You can also define words for defining |
resulting from using this option may not be ANS Forth conformant). Then |
arrays and records (@pxref{Defining Words Tutorial,, Defining Words}). |
the user initialization file @file{.gforth.fs} is executed, unless the |
|
option @code{--no-rc} is given; this file is first searched in @file{.}, |
|
then in @file{~}, then in the normal path (see above). |
|
|
|
|
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 yet 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). |
|
|
|
On the other hand, there is a useful set of record words, and it has |
|
been defined in @file{compat/struct.fs}; these words are predefined in |
|
Gforth. They are explained in depth elsewhere in this manual (see |
|
@pxref{Structures}). The @code{simple-field} example above is |
|
simplified variant of fields in this package. |
|
|
@comment ---------------------------------------------- |
|
@node Leaving Gforth, Command-line editing, Invoking Gforth, Gforth Environment |
|
@section Leaving Gforth |
|
@cindex Gforth - leaving |
|
@cindex leaving Gforth |
|
|
|
You can leave Gforth by typing @code{bye} or @kbd{Ctrl-d} (at the start |
@node POSTPONE Tutorial, Literal Tutorial, Arrays and Records Tutorial, Tutorial |
of a line) or (if you invoked Gforth with the @code{--die-on-signal} |
@section @code{POSTPONE} |
option) @kbd{Ctrl-c}. When you leave Gforth, all of your definitions and |
|
data are discarded. @xref{Image Files} for ways of saving the state of |
|
the system before leaving Gforth. |
|
|
|
doc-bye |
You can compile the compilation semantics (instead of compiling the |
|
interpretation semantics) of a word with @code{POSTPONE}: |
|
|
|
@example |
|
: MY-+ ( Compilation: -- ; Run-time of compiled code: n1 n2 -- n ) |
|
POSTPONE + ; immediate compile-only |
|
: foo ( n1 n2 -- n ) |
|
MY-+ ; |
|
1 2 foo . |
|
see foo |
|
@end example |
|
|
@comment ---------------------------------------------- |
During the definition of @code{foo} the text interpreter performs the |
@node Command-line editing, Upper and lower case,Leaving Gforth,Gforth Environment |
compilation semantics of @code{MY-+}, which performs the compilation |
@section Command-line editing |
semantics of @code{+}, i.e., it compiles @code{+} into @code{foo}. |
@cindex command-line editing |
|
|
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 |
|
@code{( -- )} 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.: |
|
|
|
@example |
|
: foo2 ( n1 n2 -- n ) |
|
[ MY-+ ] ; |
|
1 2 foo . |
|
see foo |
|
@end example |
|
|
Gforth maintains a history file that records every line that you type to |
However, there are some broken Forth systems where this does not always |
the text interpreter. This file is preserved between sessions, and is |
work, and therefore this practice has been declared non-standard in |
used to provide a command-line recall facility; if you type @kbd{Ctrl-P} |
1999. |
repeatedly you can recall successively older commands from this (or |
@c !! repair.fs |
previous) session(s). The full list of command-line editing facilities is: |
|
|
Here is another example for using @code{POSTPONE}: |
|
|
@itemize @bullet |
@example |
@item |
: MY-- ( Compilation: -- ; Run-time of compiled code: n1 n2 -- n ) |
@kbd{Ctrl-p} (``previous'') (or up-arrow) to recall successively older |
POSTPONE negate POSTPONE + ; immediate compile-only |
commands from the history buffer. |
: bar ( n1 n2 -- n ) |
@item |
MY-- ; |
@kbd{Ctrl-n} (``next'') (or down-arrow) to recall successively newer commands |
2 1 bar . |
from the history buffer. |
see bar |
@item |
@end example |
@kbd{Ctrl-f} (or right-arrow) to move the cursor right, non-destructively. |
|
@item |
|
@kbd{Ctrl-b} (or left-arrow) to move the cursor left, non-destructively. |
|
@item |
|
@kbd{Ctrl-h} (backspace) to delete the character to the left of the cursor, |
|
closing up the line. |
|
@item |
|
@kbd{Ctrl-k} to delete (``kill'') from the cursor to the end of the line. |
|
@item |
|
@kbd{Ctrl-a} to move the cursor to the start of the line. |
|
@item |
|
@kbd{Ctrl-e} to move the cursor to the end of the line. |
|
@item |
|
@key{RET} (@kbd{Ctrl-m}) or @key{LFD} (@kbd{Ctrl-j}) to submit the current |
|
line. |
|
@item |
|
@key{TAB} to step through all possible full-word completions of the word |
|
currently being typed. |
|
@item |
|
@kbd{Ctrl-d} at the start of the line to terminate Gforth (gracefully, |
|
using @code{bye}). |
|
@end itemize |
|
|
|
When editing, displayable characters are inserted to the left of the |
You can define @code{ENDIF} in this way: |
cursor position; the line is always in ``insert'' (as opposed to |
|
``overstrike'') mode. |
|
|
|
@cindex history file |
@example |
@cindex @file{.gforth-history} |
: ENDIF ( Compilation: orig -- ) |
On Unix systems, the history file is @file{~/.gforth-history} by |
POSTPONE then ; immediate |
default@footnote{i.e. it is stored in the user's home directory.}. You |
@end example |
can find out the name and location of your history file using: |
|
|
|
@example |
@assignment |
history-file type \ Unix-class systems |
Write @code{MY-2DUP} that has compilation semantics equivalent to |
|
@code{2dup}, but compiles @code{over over}. |
|
@endassignment |
|
|
history-file type \ Other systems |
@node Literal Tutorial, Advanced macros Tutorial, POSTPONE Tutorial, Tutorial |
history-dir type |
@section @code{Literal} |
|
|
|
You cannot @code{POSTPONE} numbers: |
|
|
|
@example |
|
: [FOO] POSTPONE 500 ; immediate |
@end example |
@end example |
|
|
If you enter long definitions by hand, you can use a text editor to |
Instead, you can use @code{LITERAL (compilation: n --; run-time: -- n )}: |
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 |
@example |
periodically, if necessary. |
: [FOO] ( compilation: --; run-time: -- n ) |
|
500 POSTPONE literal ; immediate |
|
|
@comment this is all defined in history.fs |
: flip foo ; |
@comment NAC TODO the ctrl-D behaviour can either do a bye or a beep.. how is that option |
flip . |
@comment chosen? |
see flip |
|
@end example |
|
|
|
@code{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 @code{LITERAL} is to compile a |
|
number computed at compile time into the current word: |
|
|
|
@example |
|
: bar ( -- n ) |
|
[ 2 2 + ] literal ; |
|
see bar |
|
@end example |
|
|
@comment ---------------------------------------------- |
@assignment |
@node Upper and lower case, Environment variables,Command-line editing,Gforth Environment |
Write @code{]L} which allows writing the example above as @code{: bar ( |
@section Upper and lower case |
-- n ) [ 2 2 + ]L ;} |
@cindex case-sensitivity |
@endassignment |
@cindex upper and lower case |
|
|
|
|
@node Advanced macros Tutorial, Compilation Tokens Tutorial, Literal Tutorial, Tutorial |
|
@section Advanced macros |
|
|
|
Reconsider @code{map-array} from @ref{Execution Tokens |
|
Tutorial,, Execution Tokens}. It frequently performs @code{execute}, a |
|
relatively expensive operation in some implementations. You can use |
|
@code{compile,} and @code{POSTPONE} to eliminate these @code{execute}s |
|
and produce a word that contains the word to be performed directly: |
|
|
|
@c use ]] ... [[ |
|
@example |
|
: 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 . |
|
@end example |
|
|
|
You can use the full power of Forth for generating the code; here's an |
|
example where the code is generated in a loop: |
|
|
|
@example |
|
: 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 (inneres Produkt), wobei die v_i als addr_i u repräsentiert sind |
|
0 postpone literal postpone swap |
|
[ ' compile-vmul-step compile-map-array ] |
|
postpone drop ; |
|
see compile-vmul |
|
|
|
: a-vmul ( addr -- n ) |
|
\ n=a*v, wobei v ein Vektor ist, der so lang ist wie a und bei addr anfängt |
|
[ a 5 compile-vmul ] ; |
|
see a-vmul |
|
a a-vmul . |
|
@end example |
|
|
|
This example uses @code{compile-map-array} to show off, but you could |
|
also use @code{map-array} instead (try it now). |
|
|
|
You can use this technique for efficient multiplication of large |
|
matrices. In matrix multiplication, you multiply every line of one |
|
matrix with every column of the other matrix. You can generate the code |
|
for one line once, and use it for every column. The only downside of |
|
this technique is that it is cumbersome to recover the memory consumed |
|
by the generated code when you are done (and in more complicated cases |
|
it is not possible portably). |
|
|
|
@node Compilation Tokens Tutorial, Wordlists and Search Order Tutorial, Advanced macros Tutorial, Tutorial |
|
@section Compilation Tokens |
|
|
|
This section is Gforth-specific. You can skip it. |
|
|
|
@code{' 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 @code{if} that have no interpretation |
|
semantics), Gforth has the concept of a compilation token (CT, |
|
consisting of two cells), and words @code{comp'} and @code{[comp']}. |
|
You can perform the compilation semantics represented by a CT with |
|
@code{execute}: |
|
|
Gforth is case-insensitive; you can enter definitions and invoke |
@example |
Standard words using upper, lower or mixed case (however, |
: foo2 ( n1 n2 -- n ) |
@pxref{core-idef, Implementation-defined options, Implementation-defined |
[ comp' + execute ] ; |
options}). |
see foo |
|
@end example |
|
|
ANS Forth only @i{requires} implementations to recognise Standard words |
You can compile the compilation semantics represented by a CT with |
when they are typed entirely in upper case. Therefore, a Standard |
@code{postpone,}: |
program must use upper case for all Standard words. You can use whatever |
|
case you like for words that you define, but in a standard program you |
|
have to use the words in the same case that you defined them. |
|
|
|
Gforth supports case sensitivity through @code{table}s (case-sensitive |
@example |
wordlists, @pxref{Word Lists}). |
: foo3 ( -- ) |
|
[ comp' + postpone, ] ; |
|
see foo3 |
|
@end example |
|
|
Two people have asked how to convert Gforth to case sensitivity; while |
@code{[ comp' wort postpone, ]} is equivalent to @code{POSTPONE word}. |
we think this is a bad idea, you can change all wordlists into tables |
@code{comp'} is particularly useful for words that have no |
like this: |
interpretation semantics: |
|
|
@example |
@example |
' table-find forth-wordlist wordlist-map @ ! |
' if |
|
comp' if .s |
@end example |
@end example |
|
|
Note that you now have to type the predefined words in the same case |
|
that we defined them, which are varying. You may want to convert them |
|
to your favourite case before doing this operation (I won't explain how, |
|
because if you are even contemplating to do this, you'd better have |
|
enough knowledge of Forth systems to know this already). |
|
|
|
@comment ---------------------------------------------- |
@node Wordlists and Search Order Tutorial, , Compilation Tokens Tutorial, Tutorial |
@node Environment variables, Gforth Files, Upper and lower case,Gforth Environment |
@section Wordlists and Search Order |
@section Environment variables |
|
@cindex environment variables |
|
|
|
Gforth uses these environment variables: |
The dictionary is not just a memory area that allows you to allocate |
|
memory with @code{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. |
|
|
@itemize @bullet |
Which wordlists are searched in which order is determined by the search |
@item |
order. You can display the search order with @code{order}. It displays |
@cindex @code{GFORTHHIST} -- environment variable |
first the search order, starting with the wordlist searched first, then |
@code{GFORTHHIST} -- (Unix systems only) specifies the directory in which to |
it displays the wordlist that will contain newly defined words. |
open/create the history file, @file{.gforth-history}. Default: |
|
@code{$HOME}. |
|
|
|
@item |
You can create a new, empty wordlist with @code{wordlist ( -- wid )}: |
@cindex @code{GFORTHPATH} -- environment variable |
|
@code{GFORTHPATH} -- specifies the path used when searching for the gforth image file and |
|
for Forth source-code files. |
|
|
|
@item |
@example |
@cindex @code{GFORTH} -- environment variable |
wordlist constant mywords |
@code{GFORTH} -- used by @file{gforthmi} @xref{gforthmi}. |
@end example |
|
|
@item |
@code{Set-current ( wid -- )} sets the wordlist that will contain newly |
@cindex @code{GFORTHD} -- environment variable |
defined words (the @emph{current} wordlist): |
@code{GFORTHD} -- used by @file{gforthmi} @xref{gforthmi}. |
|
|
|
@item |
@example |
@cindex @code{TMP}, @code{TEMP} - environment variable |
mywords set-current |
@code{TMP}, @code{TEMP} - (non-Unix systems only) used as a potential |
order |
location for the history file. |
@end example |
@end itemize |
|
|
|
@comment also POSIXELY_CORRECT LINES COLUMNS HOME but no interest in |
Gforth does not display a name for the wordlist in @code{mywords} |
@comment mentioning these. |
because this wordlist was created anonymously with @code{wordlist}. |
|
|
All the Gforth environment variables default to sensible values if they |
You can get the current wordlist with @code{get-current ( -- wid)}. If |
are not set. |
you want to put something into a specific wordlist without overall |
|
effect on the current wordlist, this typically looks like this: |
|
|
|
@example |
|
get-current mywords set-current ( wid ) |
|
create someword |
|
( wid ) set-current |
|
@end example |
|
|
@comment ---------------------------------------------- |
You can write the search order with @code{set-order ( wid1 .. widn n -- |
@node Gforth Files, ,Environment variables,Gforth Environment |
)} and read it with @code{get-order ( -- wid1 .. widn n )}. The first |
@section Gforth files |
searched wordlist is topmost. |
@cindex Gforth files |
|
|
|
When you install Gforth on a Unix system, it installs files in these |
@example |
locations by default: |
get-order mywords swap 1+ set-order |
|
order |
|
@end example |
|
|
@itemize @bullet |
Yes, the order of wordlists in the output of @code{order} is reversed |
@item |
from stack comments and the output of @code{.s} and thus unintuitive. |
@file{/usr/local/bin/gforth} |
|
@item |
@assignment |
@file{/usr/local/bin/gforthmi} |
Define @code{>order ( wid -- )} with adds @code{wid} as first searched |
@item |
wordlist to the search order. Define @code{previous ( -- )}, which |
@file{/usr/local/man/man1/gforth.1} - man page. |
removes the first searched wordlist from the search order. Experiment |
@item |
with boundary conditions (you will see some crashes or situations that |
@file{/usr/local/info} - the Info version of this manual. |
are hard or impossible to leave). |
@item |
@endassignment |
@file{/usr/local/lib/gforth/<version>/...} - Gforth @file{.fi} files. |
|
@item |
The search order is a powerful foundation for providing features similar |
@file{/usr/local/share/gforth/<version>/TAGS} - Emacs TAGS file. |
to Modula-2 modules and C++ namespaces. However, trying to modularize |
@item |
programs in this way has disadvantages for debugging and reuse/factoring |
@file{/usr/local/share/gforth/<version>/...} - Gforth source files. |
that overcome the advantages in my experience (I don't do huge projects, |
@item |
though). These disadvanategs are not so clear in other |
@file{.../emacs/site-lisp/gforth.el} - Emacs gforth mode. |
languages/programming environments, because these langauges are not so |
@end itemize |
strong in debugging and reuse. |
|
|
You can select different places for installation by using |
|
@code{configure} options (listed with @code{configure --help}). |
|
|
|
@c ****************************************************************** |
@c ****************************************************************** |
@node Introduction, Words, Gforth Environment, Top |
@node Introduction, Words, Tutorial, Top |
@comment node-name, next, previous, up |
@comment node-name, next, previous, up |
@chapter An Introduction to ANS Forth |
@chapter An Introduction to ANS Forth |
@cindex Forth - an introduction |
@cindex Forth - an introduction |
Line 2167 Many Forth systems are implemented mainl
|
Line 4133 Many Forth systems are implemented mainl
|
|
|
|
|
@comment ---------------------------------------------- |
@comment ---------------------------------------------- |
@node Where to go next,Exercises,Review - elements of a Forth system, Introduction |
@node Where to go next, Exercises, Review - elements of a Forth system, Introduction |
@section Where To Go Next |
@section Where To Go Next |
@cindex where to go next |
@cindex where to go next |
|
|
Line 2220 When you have mastered these, there's no
|
Line 4186 When you have mastered these, there's no
|
the whole of this manual and find out what you've missed. |
the whole of this manual and find out what you've missed. |
|
|
@comment ---------------------------------------------- |
@comment ---------------------------------------------- |
@node Exercises, ,Where to go next, Introduction |
@node Exercises, , Where to go next, Introduction |
@section Exercises |
@section Exercises |
@cindex exercises |
@cindex exercises |
|
|
Line 4615 Note that ticking (@code{'}) a compile-o
|
Line 6581 Note that ticking (@code{'}) a compile-o
|
* Combined words:: |
* Combined words:: |
@end menu |
@end menu |
|
|
@node Combined words, ,Interpretation and Compilation Semantics, Interpretation and Compilation Semantics |
@node Combined words, , Interpretation and Compilation Semantics, Interpretation and Compilation Semantics |
@subsection Combined Words |
@subsection Combined Words |
@cindex combined words |
@cindex combined words |
|
|
Line 5348 doc-2literal
|
Line 7314 doc-2literal
|
doc-fliteral |
doc-fliteral |
|
|
|
|
@node Interpreter Directives, , Literals, The Text Interpreter |
@node Interpreter Directives, , Literals, The Text Interpreter |
@subsection Interpreter Directives |
@subsection Interpreter Directives |
@cindex interpreter directives |
@cindex interpreter directives |
|
|
Line 5513 any particular context by controlling th
|
Line 7479 any particular context by controlling th
|
search order stack. |
search order stack. |
@end itemize |
@end itemize |
|
|
@node Word list examples, ,Why use word lists?, Word Lists |
@node Word list examples, , Why use word lists?, Word Lists |
@subsection Word list examples |
@subsection Word list examples |
@cindex word lists - examples |
@cindex word lists - examples |
|
|
Line 5646 doc-sourcefilename
|
Line 7612 doc-sourcefilename
|
doc-sourceline# |
doc-sourceline# |
|
|
@menu |
@menu |
* Forth source files:: |
* Forth source files:: |
* General files:: |
* General files:: |
* Search Paths:: |
* Search Paths:: |
* Forth Search Paths:: |
|
* General Search Paths:: |
|
@end menu |
@end menu |
|
|
|
|
Line 5746 doc-resize-file
|
Line 7710 doc-resize-file
|
|
|
|
|
@c --------------------------------------------------------- |
@c --------------------------------------------------------- |
@node Search Paths, Forth Search Paths, General files, Files |
@node Search Paths, , General files, Files |
@subsection Search Paths |
@subsection Search Paths |
@cindex path for @code{included} |
@cindex path for @code{included} |
@cindex file search path |
@cindex file search path |
Line 5782 If the filename starts with @file{./}, t
|
Line 7746 If the filename starts with @file{./}, t
|
(just as with absolute filenames), and the @file{.} has the same meaning |
(just as with absolute filenames), and the @file{.} has the same meaning |
as described above. |
as described above. |
|
|
|
@menu |
|
* Forth Search Paths:: |
|
* General Search Paths:: |
|
@end menu |
|
|
@c --------------------------------------------------------- |
@c --------------------------------------------------------- |
@node Forth Search Paths, General Search Paths, Search Paths, Files |
@node Forth Search Paths, General Search Paths, Search Paths, Search Paths |
@subsubsection Forth Search Paths |
@subsubsection Forth Search Paths |
@cindex search path control - Forth |
@cindex search path control - Forth |
|
|
Line 5806 require timer.fs
|
Line 7775 require timer.fs
|
@end example |
@end example |
|
|
@c --------------------------------------------------------- |
@c --------------------------------------------------------- |
@node General Search Paths, , Forth Search Paths, Files |
@node General Search Paths, , Forth Search Paths, Search Paths |
@subsubsection General Search Paths |
@subsubsection General Search Paths |
@cindex search path control - for user applications |
@cindex search path control - for user applications |
|
|
Line 5910 and its state changes to @i{assigned-cle
|
Line 7879 and its state changes to @i{assigned-cle
|
manipulated (read or written) within the current block buffer. |
manipulated (read or written) within the current block buffer. |
|
|
When the contents of the current block buffer has been modified it is |
When the contents of the current block buffer has been modified it is |
necessary, @i{before calling} @code{block} @i{or} @code{buffer} |
necessary, @emph{before calling @code{block} or @code{buffer} again}, to |
@i{again}, to either abandon the changes (by doing nothing) or commit |
either abandon the changes (by doing nothing) or commit the changes, |
the changes, using @code{update}. Using @code{update} does not change |
using @code{update}. Using @code{update} does not change the blocks |
the blocks file; it simply changes a block buffer's state to |
file; it simply changes a block buffer's state to @i{assigned-dirty}. |
@i{assigned-dirty}. |
|
|
|
The word @code{flush} causes all @i{assigned-dirty} blocks to be |
The word @code{flush} causes all @i{assigned-dirty} blocks to be |
written back to the blocks file on disk. Leaving Gforth using @code{bye} |
written back to the blocks file on disk. Leaving Gforth using @code{bye} |
Line 6298 definition of @code{my-char}.
|
Line 8266 definition of @code{my-char}.
|
|
|
|
|
|
|
@node Input, , Displaying characters and strings, Other I/O |
@node Input, , Displaying characters and strings, Other I/O |
@subsection Input |
@subsection Input |
@cindex input |
@cindex input |
@cindex I/O - see input |
@cindex I/O - see input |
Line 6487 Definitions in ANS Forth for these asser
|
Line 8455 Definitions in ANS Forth for these asser
|
in @file{compat/assert.fs}. |
in @file{compat/assert.fs}. |
|
|
|
|
@node Singlestep Debugger, , Assertions, Programming Tools |
@node Singlestep Debugger, , Assertions, Programming Tools |
@subsection Singlestep Debugger |
@subsection Singlestep Debugger |
@cindex singlestep Debugger |
@cindex singlestep Debugger |
@cindex debugging Singlestep |
@cindex debugging Singlestep |
Line 7533 and @code{DOES>}. The body of the field
|
Line 9501 and @code{DOES>}. The body of the field
|
of the field, and the normal @code{DOES>} action is simply: |
of the field, and the normal @code{DOES>} action is simply: |
|
|
@example |
@example |
@ + |
@@ + |
@end example |
@end example |
|
|
@noindent |
@noindent |
Line 7585 in @ref{Comparison with other object mod
|
Line 9553 in @ref{Comparison with other object mod
|
in ANS Forth and can be used with any other ANS Forth. |
in ANS Forth and can be used with any other ANS Forth. |
|
|
@menu |
@menu |
* Why object-oriented programming?:: |
* Why object-oriented programming?:: |
* Object-Oriented Terminology:: |
* Object-Oriented Terminology:: |
* Objects:: |
* Objects:: |
* OOF:: |
* OOF:: |
* Mini-OOF:: |
* Mini-OOF:: |
* Comparison with other object models:: |
* Comparison with other object models:: |
@end menu |
@end menu |
|
|
|
@c ---------------------------------------------------------------- |
@node Why object-oriented programming?, Object-Oriented Terminology, , Object-oriented Forth |
@node Why object-oriented programming?, Object-Oriented Terminology, Object-oriented Forth, Object-oriented Forth |
@subsubsection Why object-oriented programming? |
@subsection Why object-oriented programming? |
@cindex object-oriented programming motivation |
@cindex object-oriented programming motivation |
@cindex motivation for object-oriented programming |
@cindex motivation for object-oriented programming |
|
|
Line 7624 themselves object-oriented; the object-o
|
Line 9592 themselves object-oriented; the object-o
|
solve this problem (and not much else). |
solve this problem (and not much else). |
@comment TODO ?list properties of oo systems.. oo vs o-based? |
@comment TODO ?list properties of oo systems.. oo vs o-based? |
|
|
|
@c ------------------------------------------------------------------------ |
@node Object-Oriented Terminology, Objects, Why object-oriented programming?, Object-oriented Forth |
@node Object-Oriented Terminology, Objects, Why object-oriented programming?, Object-oriented Forth |
@subsubsection Object-Oriented Terminology |
@subsection Object-Oriented Terminology |
@cindex object-oriented terminology |
@cindex object-oriented terminology |
@cindex terminology for object-oriented programming |
@cindex terminology for object-oriented programming |
|
|
Line 7694 terminology: The derived class inherits
|
Line 9663 terminology: The derived class inherits
|
@c they can do most things through simple (indirect) calls. They kept the |
@c they can do most things through simple (indirect) calls. They kept the |
@c terminology. |
@c terminology. |
|
|
|
@c -------------------------------------------------------------- |
@node Objects, OOF, Object-Oriented Terminology, Object-oriented Forth |
@node Objects, OOF, Object-Oriented Terminology, Object-oriented Forth |
@subsection The @file{objects.fs} model |
@subsection The @file{objects.fs} model |
@cindex objects |
@cindex objects |
Line 8711 and reduces to the bare minimum of featu
|
Line 10680 and reduces to the bare minimum of featu
|
of Bernd Paysan in comp.arch. |
of Bernd Paysan in comp.arch. |
|
|
@menu |
@menu |
* Basic Mini-OOF Usage:: |
* Basic Mini-OOF Usage:: |
* Mini-OOF Example:: |
* Mini-OOF Example:: |
* Mini-OOF Implementation:: |
* Mini-OOF Implementation:: |
|
* Comparison with other object models:: |
@end menu |
@end menu |
|
|
@c ------------------------------------------------------------- |
@c ------------------------------------------------------------- |
@node Basic Mini-OOF Usage, Mini-OOF Example, , Mini-OOF |
@node Basic Mini-OOF Usage, Mini-OOF Example, Mini-OOF, Mini-OOF |
@subsubsection Basic @file{mini-oof.fs} Usage |
@subsubsection Basic @file{mini-oof.fs} Usage |
@cindex mini-oof usage |
@cindex mini-oof usage |
|
|
Line 8804 We can draw this new circle at (100,100)
|
Line 10774 We can draw this new circle at (100,100)
|
100 100 my-circle draw |
100 100 my-circle draw |
@end example |
@end example |
|
|
@node Mini-OOF Implementation, , Mini-OOF Example, Mini-OOF |
@node Mini-OOF Implementation, , Mini-OOF Example, Mini-OOF |
@subsubsection @file{mini-oof.fs} Implementation |
@subsubsection @file{mini-oof.fs} Implementation |
|
|
Object-oriented systems with late binding typically use a |
Object-oriented systems with late binding typically use a |
Line 8947 bar draw
|
Line 10917 bar draw
|
@end example |
@end example |
|
|
|
|
@node Comparison with other object models, , Mini-OOF, Object-oriented Forth |
@node Comparison with other object models, , Mini-OOF, Object-oriented Forth |
@subsubsection Comparison with other object models |
@subsection Comparison with other object models |
@cindex comparison of object models |
@cindex comparison of object models |
@cindex object models, comparison |
@cindex object models, comparison |
|
|
Line 8968 Dimensions, May 1997) by Anton Ertl.}:
|
Line 10938 Dimensions, May 1997) by Anton Ertl.}:
|
|
|
@itemize @bullet |
@itemize @bullet |
@item |
@item |
It uses a @code{@emph{selector |
It uses a @code{@emph{selector object}} syntax, which makes it unnatural |
object}} syntax, which makes it unnatural to pass objects on the |
to pass objects on the stack. |
stack. |
|
|
|
@item |
@item |
It requires that the selector parses the input stream (at |
It requires that the selector parses the input stream (at |
Line 8991 binding. Instead, it focuses on features
|
Line 10960 binding. Instead, it focuses on features
|
overloading that are characteristic of modular languages like Ada (83). |
overloading that are characteristic of modular languages like Ada (83). |
|
|
@cindex Zsoter's object-oriented model |
@cindex Zsoter's object-oriented model |
In @cite{Does late binding have to be slow?} (Forth Dimensions 18(1) 1996, pages 31-35) |
In @cite{Does late binding have to be slow?} (Forth Dimensions 18(1) |
Andras Zsoter describes a model that makes heavy use of an active object |
1996, pages 31-35) Andras Zsoter describes a model that makes heavy use |
(like @code{this} in @file{objects.fs}): The active object is not only |
of an active object (like @code{this} in @file{objects.fs}): The active |
used for accessing all fields, but also specifies the receiving object |
object is not only used for accessing all fields, but also specifies the |
of every selector invocation; you have to change the active object |
receiving object of every selector invocation; you have to change the |
explicitly with @code{@{ ... @}}, whereas in @file{objects.fs} it |
active object explicitly with @code{@{ ... @}}, whereas in |
changes more or less implicitly at @code{m: ... ;m}. Such a change at |
@file{objects.fs} it changes more or less implicitly at @code{m: |
the method entry point is unnecessary with the Zsoter's model, because |
... ;m}. Such a change at the method entry point is unnecessary with the |
the receiving object is the active object already. On the other hand, the explicit |
Zsoter's model, because the receiving object is the active object |
change is absolutely necessary in that model, because otherwise no one |
already. On the other hand, the explicit change is absolutely necessary |
could ever change the active object. An ANS Forth implementation of this |
in that model, because otherwise no one could ever change the active |
model is available at @uref{http://www.forth.org/fig/oopf.html}. |
object. An ANS Forth implementation of this model is available at |
|
@uref{http://www.forth.org/fig/oopf.html}. |
|
|
@cindex @file{oof.fs}, differences to other models |
@cindex @file{oof.fs}, differences to other models |
The @file{oof.fs} model combines information hiding and overloading |
The @file{oof.fs} model combines information hiding and overloading |
Line 9021 essentially, you are only safe if you ne
|
Line 10991 essentially, you are only safe if you ne
|
object or class (Bernd disagrees, but I (Anton) am not convinced). |
object or class (Bernd disagrees, but I (Anton) am not convinced). |
|
|
@cindex @file{mini-oof.fs}, differences to other models |
@cindex @file{mini-oof.fs}, differences to other models |
The @file{mini-oof.fs} model is quite similar to a very stripped-down version of |
The @file{mini-oof.fs} model is quite similar to a very stripped-down |
the @file{objects.fs} model, but syntactically it is a mixture of the @file{objects.fs} and |
version of the @file{objects.fs} model, but syntactically it is a |
@file{oof.fs} models. |
mixture of the @file{objects.fs} and @file{oof.fs} models. |
|
|
@c ------------------------------------------------------------- |
@c ------------------------------------------------------------- |
@node Passing Commands to the OS, Keeping track of Time, Object-oriented Forth, Words |
@node Passing Commands to the OS, Keeping track of Time, Object-oriented Forth, Words |
Line 11745 cell 2 = [IF] &32 [ELSE] &256 [THEN] KB
|
Line 13715 cell 2 = [IF] &32 [ELSE] &256 [THEN] KB
|
&14 KB &512 + DefaultValue lstack-size |
&14 KB &512 + DefaultValue lstack-size |
@end example |
@end example |
|
|
@node How the Cross Compiler Works, , Using the Cross Compiler, Cross Compiler |
@node How the Cross Compiler Works, , Using the Cross Compiler, Cross Compiler |
@section How the Cross Compiler Works |
@section How the Cross Compiler Works |
|
|
@node Bugs, Origin, Cross Compiler, Top |
@node Bugs, Origin, Cross Compiler, Top |
Line 11932 contact the FIG through their office ema
|
Line 13902 contact the FIG through their office ema
|
chapters in other countries and American cities |
chapters in other countries and American cities |
(@uref{http://www.forth.org/chapters.html}). |
(@uref{http://www.forth.org/chapters.html}). |
|
|
@node Conferences, , The Forth Interest Group, Forth-related information |
@node Conferences, , The Forth Interest Group, Forth-related information |
@section Conferences |
@section Conferences |
@cindex Conferences |
@cindex Conferences |
|
|