Programming Forth Stephen Pelc pdf download
Programming Forth Stephen Pelc pdf download
https://ebookbell.com/product/programming-forth-stephen-
pelc-50790758
https://ebookbell.com/product/classical-fortran-programming-for-
engineering-and-scientific-applications-2nd-edition-
kupferschmid-5066472
https://ebookbell.com/product/computer-programming-in-
fortran-90-and-95-1st-edition-v-rajaram-5441124
https://ebookbell.com/product/introduction-to-programming-with-
fortran-4th-edn-ian-chivers-jane-sleightholme-49848242
https://ebookbell.com/product/introduction-to-programming-with-
fortran-with-coverage-of-fortran-90-95-2003-2008-and-77-2nd-edition-
ian-chivers-2521034
Introduction To Programming With Fortran Ian D Chivers Bsc Pgced
https://ebookbell.com/product/introduction-to-programming-with-
fortran-ian-d-chivers-bsc-pgced-4239444
https://ebookbell.com/product/introduction-to-programming-with-
fortran-with-coverage-of-fortran-90-95-2003-2008-and-77-3rd-edition-
ian-chivers-5234568
https://ebookbell.com/product/objectoriented-programming-via-
fortran-9095-ed-akin-6812044
https://ebookbell.com/product/introduction-to-programming-with-
fortran-4th-ian-chivers-jane-sleightholme-7164316
https://ebookbell.com/product/introduction-to-programming-using-
fortran-9520032008-version-3051-ed-jorgensen-10466018
Programming Forth
Copyright
ALIGNCopyright (c) 2005, 2006, 2007, 2011, 2016
MicroProcessor Engineering Limited
For further information
MicroProcessor Engineering Limited
133 Hill Lane, Southampton
SO15 5AF, UK
Tel: +44 (0)23 8063
1441 Fax: +44 (0)23
8033 9691
e-mail:
mpe@mpeforth.com
tech-support@mpeforth.com
web:
http://www.mpeforth.com
version 8k 2016_07_24
Acknowledgements
I would like to thank the following people in particular for their involvement in the
content of this book:
Peter Knaggs,
Chris E. Bailey,
Bill Stoddart,
Bob Marchbanks,
Hans Bezemer
These people have influenced “Programming Forth” and contributed to it, and their
input is valued. All faults are my own.
Much criticism and proof-reading was provided by the readers of the comp.lang.forth
newsgroup, especially:
Stefan Schmiedl,
William Cook,
Anton Ertl
Other people have influenced my programming style and general attitude to life:
Fokko van Duin,
Willem Botha,
Chuck Moore
Programming Forth
Copyright © 2005, 2006, 2007, 2011, 2016 MicroProcessor Engineering Limited
ISBN 978-0-9525310-5-0
intentionally left blank
Table of Contents
( page numbers of the A5 print left intentionally )
12 List of Tables
12 List of Figures
13 1 Introduction
13 About this book
14 What Forth is
15 Key concepts
16 Interactivity, Development and Testing
17 How to Debug
18 Writing programs in Forth
20 Editors
21 Forth Implementation
21 MPEisms
22 2 Architecture of Forth
22 Forth Virtual Machine
24 Stacks and postfix notation
25 Data types
26 Words and Numbers
26 Interpreting and compiling
27 Defining Words and Immediate words
27 Factoring
35 5 Components of Forth
35 Data stack operations
36 Return Stack operations
37 Maths operations
38 Comparisons
39 Widely available
40 Bitwise logic
40 Memory operations
41 Widely available
41 Constants and variables
42 CONSTANTs
42 VARIABLEs
43 VALUEs
43 Control structures
44 IF … THEN
44 IF…ELSE…THEN
45 EXIT
45 DO … LOOP and DO … n +LOOP
47 ?DO … LOOP and ?DO … n +LOOP
48 BEGIN … AGAIN
48 BEGIN … UNTIL
49 BEGIN … WHILE … REPEAT
49 CASE … OF … ENDOF … ENDCASE
51 MPEisms: CASE extensions
52 Restarts and errors
52 Text and strings
53 Counted strings
53 Character Strings
54 Character Literals
54 Text and String input
55 Print Formatting
57 Vocabularies
59 Wordlists
114 13 Files
114 ANS File Access Wordset
117 Simple file tools
200 19 Exercises
200 Stack operations
200 Arithmetic
208 Input, output and loops
210 Memory
213 Defining words
215 Miscellaneous
I appreciate all your comments and contributions - Stephen Pelc July 2016
What Forth is
Forth is a member of the class of extensible interactive languages, which includes
classical implementations of Smalltalk. Extensible means that there is no distinction
between the keywords (core words) and the routines that you write. Once a new definition
has been compiled, even from the keyboard, it is immediately available to you.
Interactive means that you can talk to it from your keyboard.
Forth is a different sort of computer language. Forth code is easy to debug because Forth
is interactive, fast because Forth is compiled and powerful because it is extensible. Forth
is a language with a definite style.
Forth was developed by Charles (Chuck) Moore in the early 1960s. Moore’s work with
computers at MIT and the Stanford Linear Accelerator Centre left him dissatisfied. The
turn-round time for editing, compiling and running a program using the then current
generation of ALGOL and FORTRAN compilers was too slow. His solution to this was to
write a simple text interpreter in ALGOL which read in words (any printable characters
except space) and performed actions associated with them. Words were either primaries
(i.e. “understood” by the interpreter) or secondaries (i.e. defined in terms of other words).
After his initial success with an ALGOL based interpreter at MIT and Stanford, Moore
moved on to work with Burroughs equipment. This hardware was strongly oriented
around a stack. This influenced the further development of Forth. Implementations were
written in BALGOL, COBOL and SBOL (the Burroughs Systems Programming
Language). These provided manipulation words for the stack: DROP , DUP , SWAP ,
etc. which are still found in modern Forth systems. The first true Forth system which
resembled what we now perceive as Forth was then created by Moore on an IBM 1130.
The word size of this machine limited the users to having names of not more than five
characters. Had it not been for this IBM limitation the name `Forth’ would have been
`Fourth’ - standing for Fourth Generation Language.
The first Forth application was a Radio Telescope Data Acquisition Program written for a
Honeywell H316 at the National Radio Astronomy Observatory. This implementation of
Forth used a dictionary to store words defined by the user.
Key concepts
This text is derived from a posting on comp.lang.forth by Dwight Elvey. “Like many
programming languages, Forth has an execution model or virtual machine. Unlike many
languages, Forth exposes this to the programmer.
The Forth virtual machine is discussed in more detail in the next chapter.
All source code elements are either numbers or words. Words are what are called
functions, procedures or subroutines in other languages. Words can be either user defined
or part of the Forth core and are entered as a dictionary. Words are composed of other
Forth elements and/or true machine code.
All elements are executed in sequential order, left to right, top to bottom. Sequential order
is only broken by flow structure words.
Normal input and output of words is by the data stack, return stack, variables (values),
or arrays.
Nesting is maintained by a return stack. Execution of words implies nesting, except at the
lowest levels of true machine code.
The programmer is responsible to maintain stacks.
Forth can be either compiled or interpreted. These can be selected at will by the
programmer but is usually done in an orderly fashion.
All the rest comes from the above.”
One of the key portions of Forth is its interactivity – you sit in front of the keyboard and
play (explore) with your application. Daniel Ciesinger wrote:
“Further, I use Forth to test C libraries. Experience is that this finds errors which are not
found by C test procedures. I even prefer it to Rational Test Real-time which is too
indirect for my taste. Takes eternities to write test cases. In Forth, you just test
interactively and cut and paste your test cases into your favourite editor afterwards, so
you can run the same test again.”
The language does not provide forward references. It is completely bottom-up, in that you
can only reference words that already exist. Mark Wills had this to say:
“Of all the concepts that I have had to mentally adjust to during my Forth journey,
bottom up was the least problematic for me. Bottom-up is actually a jewel-in-the-crown of
Forth. It means that your lower level code is already written and tested by the time you
begin to hook it up into higher-level abstracts.”
“I think that most new-comers to the language (including me) are guilty of bringing their
previous programming language experience with them. This is natural, I guess. It’s
natural to look for frames of reference. The thing is, Forth is very different. One’s
previous programming experience is ‘baggage’, and it just weighs one down.”
Interactivity, Development and Testing
Elizabeth Rather wrote this posting about working with Chuck Moore (the originator of
Forth) on comp.lang.forth:
“Any given problem has a certain intrinsic level of complexity. In the solution of the
problem, this complexity will be conserved: if you dive in with too little advance thought,
your solution may become very complex by the time it’s done. On the other hand, if you
invest more in thought, design, and preparation, you may be able to achieve a very simple
solution (the complexity hasn’t gone away, it’s become embodied in the sophistication of
the design).
In connection with our recent discussion, that investment certainly can take the form of
prototyping. When I was working with Chuck, he’d typically go through the following
process:
1. Read the spec. Assert confidently that it really isn’t as complicated as that, and
write a very clever program that solves the essence of the problem.
2. Enter a phase in which the customer repeatedly points out aspects of the spec that
have been ignored or omitted; in fixing these, the code gets more and more complicated.
3. At some point, a full understanding of the problem emerges. All the previous code
is thrown out and a new program emerges which represents a simple, elegant solution
to the whole problem.
Elizabeth’s notes illustrate that coding is not the major part of delivering software. I am
very rarely given a formal specification for a new piece of software, despite the effort,
time and cost-savings that a good specification provide. Writing a piece of software is
mostly an iterative process involving exploration, design, coding and debugging. These
realities of the software engineer’s life lead to techniques whose buzzwords include
“rapid prototyping” and “extreme programming”. In such an environment, debugging is
far more expensive than coding in both time and cost.
How to Debug
Interactive testing and debugging is a key feature of Forth. Rapid debugging can be
achieved by the application of formal scientific method. The slide below is taken from
one of our course presentations.
Figure 1: Debugging
The diagram above shows that debugging consists of two nested loops. How fast you can
go around the inner loop determines how fast you can debug a system. Interactive
debugging is the fastest route I have found. The stages of debugging are:
1 Make the problem repeatable. This usually involves finding out which inputs
cause the problem.
2 Gather data about the problem. This observation is crucial, so take this stage
slowly and carefully. I have seen people immediately dismiss exception displays and
crash dumps which contain vital clues.
3 From the data, form a hypothesis as to what caused the problem.
4 Design an experiment which tests the hypothesis. The important part in
designing the experiment is to ensure that it gives a yes/no answer.
5 Run the experiment. If the hypothesis is incorrect, go back to stage 2.
6 Fix the problem.
7 If you have more bugs to fix, go back to stage 1 for the next problem.
Forth is a wonderful tool for debugging systems and their software. Effective debugging
in any programming language requires us to understand the techniques required for
efficient debugging and how to acquire the required information.
Writing programs in Forth
Forth often takes a little longer to learn than other languages. Just like spoken languages,
there are many words to learn in Forth before you can use it well. In Forth parlance, what
are called functions, procedures or subroutines in other languages are called words. Forth
is a language in which very little is hidden from you. Nearly every word that we used
along the way to some other function has a name, and is documented in a glossary.
As a result of this openness there are many words in the dictionary (type WORDS to see
them). Functions in Forth are called words in Forth jargon. These words are stored as a
dictionary, and the group of words forming your area of interest - the context in which
you work - is known as a vocabulary. For example, words used to define the assembler
are often kept in a vocabulary called ASSEMBLER . As in all computer languages, there
is a jargon to Forth. In this instance the jargon is a technical language, and serves as a set
of communication tools so that we can explain our ideas to each other without being
bogged down in the minutiae. Persevere, Forth is not only well worth the effort, but is a
tool of spectacular productivity in the right hands.
The Forth run-time package is actually a compact combination of interpreter, compiler,
and tools. A command or sequence of commands (words) may be executed directly from
the keyboard, or loaded from mass storage as if from the keyboard. In hosted versions of
Forth (and some embedded systems), you can also take input from a normal operating
system text file, created by a normal (non-Forth editor). Programs in Forth are compiled
from combinations of existing words (already in the dictionary), new words as defined by
the user, and control structures such as IF … ELSE … THEN or DO … LOOP . Often,
new words are developed interactively at the terminal before the final (and tested) version
is then entered using the editor and saved on disc, where it can be invoked from the
keyboard or used by another program. If you are teaching yourself Forth, get all your
books ready in front of the terminal, and try things out as you go along.
The beauty and power of Forth lies in interactivity, extensibility and flexibility. New
words can be added either at high or low (assembler) level. Forth is one of the very few
languages which can define a data structure and how it is used inside a single definition.
This ability to create new words known as defining words, which can add new classes of
operators to the language, is one of the keys to the extraordinary power of Forth in the
hands of an experienced programmer. A bad Forth programmer is just as much a disaster
as in any other language.
If your experience of programming has been in traditionally organised languages such as
C or BASIC, you will find reading and writing programs in Forth somewhat bizarre at
first. Patience brings rich rewards. Forth becomes much easier to understand once you
have mastered a few ideas and played with the language. Among the most important aids
in using Forth is the choice of word names.
Think about the name of a word in advance. Poets make good Forth programmers. Verbs,
nouns, and adjectives all have their place in good Forth programming style. Good choice
of word names leads to very readable code, as does the use of white space in source code.
You can use any character within a word name - the use of printable ones is sensible.
Word names can be up to 31 characters long (more in some implementations), and all the
characters are significant.
Forth programs keep most of their working variables on the stack, rather than in named
variables, so reading some sections of code can be a little mind-boggling - even for the
experienced. The secret is to keep definitions short and simple. Lazy programmers often
make good programmers because they make life easy for themselves - and part of making
life easy is making sure that you can work out what the code is doing a year from now.
The language lends itself well to bottom-up coding. Like the choice of word names, this
can be a double-edged sword. There is no substitute for good overall program design,
which can only be done properly from the top down. Bottom-up design and coding is
excellent, however, for exploring the nuts and bolts of techniques, algorithms, and low-
level interfaces. The ability to interactively create, test, and produce working code early
in the development cycle is invaluable. Early working code also helps to keep your boss
off your back, and it enables customers to make sensible reactions and discover
specification errors before it is too late. Carefully used this feature can save you a great
deal of time.
Bottom-up coding has an additional advantage in that it is easy to test with the Forth
interpreter. Since you cannot use a word until all its components have been defined, you
simply test an application in the order of the source code. Each component that you test is
then based on previously tested code. This is a much more reliable strategy than testing
by running the completed application.
You may well find it profitable to study the source code of the programs supplied in the
files with your Forth as a guide to style. The style is the one we use, and has evolved over
a number of years, rather than through any theoretical arguments. We find it usable by
both the authors and those who have to read other people’s code. Read the glossary
documentation, and spend a while trying out the functions, and observing their action on
the stack.
Editors
Forth source code is usually held in regular text files. You can use your programming
editor of choice. Forth syntax colouring files are available for many of them. The MPE
Forth layout standard discusses MPE practice for laying out source code.
The earlier ‘screen’ or ‘block’ layout of Forth source code is now obsolete except for
special use, mostly on embedded systems or for legacy reasons. Block editors are
discussed in the chapter on legacy issues.
Forth Implementation
As with all computer languages, Forth has evolved over time. This book assumes the use
of an ANS Forth which conforms to the ANS Forth standard published in 1994. At the
time of writing in 2005, the ANS Forth standard is the most widely used.
Modern Forth implementations usually generate optimised native code, and the good ones
produce code of the same quality as the good C compilers. For those CPUs in the
embedded world where code density is more important than performance, threaded code
(interpreted code) implementations are still used, often with limited peephole
optimisation.
The different implementation strategies are discussed in the Forth internals chapter.
MPEisms
Because this book was written at MPE using MPE’s VFX Forth for Windows for testing
the code, it inevitably suffers from the use of a few idioms which are specific to MPE’s
implementations. I have tried to avoid these and where appropriate they are marked. For
example,
MPEism: MPE implementations of Forth do not care about the case of characters in
Forth word names. CAT is the same as cat is the same as Cat. Embedded comments may
be as long as you wish without a space or speed penalty in the compiled code.
2 Architecture of Forth
Most programming languages, including C, have an underlying architecture or model of
the computer. This is often called the language’s virtual machine (VM), regardless of
how the final binary code is produced.
This chapter includes some details which you do not need to appreciate fully to use Forth,
but are described here because they are a consequence of the architecture of Forth. You
can always come back to these later.
Forth Virtual Machine
Classical or canonical Forth views the world as a CPU connected to main memoryy and
two stacks. The stacks are not addressable, and are quite separate from main memory. C
views the world as a CPU connected to memory, which includes a list of frames (usually a
stack of frames) which must be in addressable memory.
Notice that the use of brackets becomes unnecessary. This is because of the use of the
stack to hold intermediate results. Although the use of a stack is intimidating at first, after
a while it becomes natural, and eventually it is only noticeable on rare occasions.
Remembering that the word . is used to print what is on the top of the stack you can try a
few bits of arithmetic.
12+.
45*.
93/.
12+3*.
123+*.
123*+.
Nearly all Forth words remove their data from the top of the stack, and leave the result
behind. Words like + and * remove two items, and leave one behind. There is a Forth
word .S which prints out the contents of the stack without destroying the contents. Use it
whenever you want to see what is on the stack. So far, we have executed words by typing
their names at the keyboard.
Data types
Forths are often characterised by the size of an item on the data stack, which is usually 32
bits or 16 bits. Several 64 and 8 bit Forths also exist, as well as 4, 20 and 24 bit systems.
Forth is an untyped language, so there is nothing to stop you adding a character to a
number. No casts are necessary. The amount of memory needed to store a stack item is
called a cell.
Words that operate on stack items will just assume that the data is appropriate. Most Forth
compilers do not check the data types at all.
An integer occupies a single cell on the stack, as does an address. If you need larger
integers, use a double integer which occupies two cells on the data stack, most significant
half topmost.
A character is smaller than (or the same size as) an integer, and is zero extended to fill a
cell.
Two different floating point implementations are described by the ANS standard. In one,
known as a separated float stack, floating point numbers are held on a separate stack
reserved for floating point numbers. Floating point operations that require integer
parameters take them from the data stack. The second form uses a combined stack, in
which floating point numbers share the data stack.
Words and Numbers
All text entered to Forth is treated either as a number (literal, e.g. 1234) or a word
(function). A unit of text is separated by spaces or line breaks. These units are either
interpreted or compiled. That’s all. Although this is a very simple process, it is a key to
the use of Forth.
Interpreting and compiling
Forth contains both an interpreter and a compiler. Interpreting means taking the text fed
in, converting it into a form the machine can execute, executing that form, and then
discarding the executable form.
Compiling means taking the input text, completely converting it into a machine
executable form, keeping the executable form, and discarding the text. This can produce a
program that runs very fast, but you cannot change anything without first editing the
source text, then compiling it (using a separate program called a compiler), and then
loading the executable code when you want to run it.
Any text fed to Forth, either from the keyboard or from mass storage, is executed or
compiled. Remember, all commands to Forth are pre-defined ‘words’ in its
‘vocabularies’, consequently Forth can look up the address of a given word for later
execution. Some words in Forth change the way the compiler section deals with text.
For instance, we could define a word that squares the value given to it.
: squared ( n1 — n1^2 )
dup * ;
The address of the word : is found and : is executed; the action of : is to tell the compiler
section to start defining a new word whose name comes next, squared, and then compile
into the new word the actions of the words that follow. This would carry on for ever
unless we had a way of stopping it, and this is provided by ‘immediate’ words such as ;
which are always executed, regardless of what the compiler would otherwise be doing.
The action of ; is to stop the compiler compiling word addresses, and return it to the
mode of executing the addresses instead. There are other words (defining words) which
are used to create words such as : - these are one of the keys to advanced use of Forth. At
all times remember, however, that the basis of Forth is always very simple. Forth is a
language built from a number of very simple ideas, rather than one founded on a few
complex systems.
anywhere in your source code. A comment to the end of the line is started by a backslash
used as a word:
<code> \ <comment>
You can use the word .( which behaves like the ( comment but displays the text.
.( This is displayed during compilation )
Stack comments
Words in this book are documented in a style popular with many Forth programmers. It
shows what is on the stack before the word executes (the input), and what is on the stack
after the word has executed (the output). The top of the stack is right of the group, and the
execution point is marked by two dashes.
The multiply operator * takes two parameters on input, and leaves one on output. It is
thus shown:
( n1 n2 — n3 )
or
\ n1 n2 — n3
The round brackets are Forth’s way of marking a comment, and n2 is the top of the stack
before execution. In the manual Forth words are written in capital letters to distinguish
them from the lower case letters of the rest of the text. It does not matter which you use in
your programs. Personally, I prefer the look of programs written in lower case. All
children are taught to read using lower case letters. All keyboards are marked in upper
case, even those for use by children!
Notation
Data items are described using the following notation
OPERAND DESCRIPTION
n1,n2 signed numbers (integers)
d1,d2 double precision signed numbers
u1,u2 unsigned numbers (integers)
ud1,ud2 double precision unsigned numbers
addr1 address
b1,b2 bytes
c1,c2 ASCII characters
char1,char22 ASCII characters
t/f,t,f boolean flag, true, false
0=false, nz=true,
Flag 0=false, -1 =true
Note that the ANS standard uses f for a flag, whereas many programmers still use t and f
to indicate true and false
4 First words in Forth
The only sure way to learn Forth is to use it. Forth programmers spend more time at the
terminal, because the interactive nature of the language means that words can be tested as
soon as they are entered. A result of this feature is that succeeding words, which use
previous ones, use tested code. Adherence to the procedure of `top down design’,
followed by `bottom up’ coding and interactive testing, leads to very rapid debugging,
and successful program generation. Audits of large software projects reveal that over half
the time may be spent on debugging. As this is the largest single activity, it is the one to
reduce. If you are at all interested in software management, do read Fred Brook’s book,
‘The Mythical Man-Month’.
To write new words you can either just type them in at the keyboard, or you can use the
editor to put source code in a file.
If you decide just to enter the examples directly, you do not need to enter the comments
or use the same layout. In fact, Forth is completely free-form. This means that the
position of the words is unimportant, only their order.
MPEism: MPE Forths do not care whether a word is in UPPER CASE or in lower case
or in MiXeD case.
Forth word names can contain any characters except spaces or nulls (ASCII character 0).
It is sensible to use printable characters, but Forth does not actually check the characters.
New Forth words are defined by the word :whose first action is to pick up the name that
follows and use it to make a new entry in the dictionary. Then, everything that follows up
to the next ; defines the action of the word.
By comparison with extended BASICs :is equivalent to DEFine PROCedure or DEFine
FuNction and ;is equivalent to END PROCedure or END DEFine . For example:
: NEW-NAME \ —
CR .” This is a new word” CR ;
NEW-NAME
The example word above is called NEW-NAME - when you type NEW-NAME it will
print a new line, and the print the text `This is a new word’, and then print another new
line. The word .” prints out all the characters except the space after .” up to but not
including the next double quotation mark ( ” ). The word CR is a predefined word that
generates a new line - CR stands for Carriage-Return.
A new Forth word can contain any words that exist in the dictionary. The new Forth word
can be executed by typing its name, or included in the definition of another word.
: TIMES \ n1 n2 —
*. ;
2 4 TIMES
This example will multiply two numbers together and print the result. The word * is
Forth’s multiply word, and . is the word to print a number. TIMES can be used as part of
a word that presents information more prettily to the user. First we print a new line
using CR then we duplicate the two numbers using 2DUP and print them out together
with the result. Why is the word SWAP used? Try it without SWAP .
: MULTIPLY ( n1 n2 — )
CR 2DUP SWAP . .” multiplied by ” .
.” equals ” TIMES CR ;
4 3 MULTIPLY
We have shown the definition entered on two lines. When you type it in there will be no
‘ok’ prompt after the first line. This is because you have not finished the definition. The
Forth system has converted the list of word names into a dictionary entry
called MULTIPLY and its associated code. This process is called compilation, and
during compilation source text entered from the keyboard is discarded.
If you want to keep source code available for re-use, use your standard text editor, save
the file, conventionally with a .FTH extension, and use the word INCLUDE to load it,
e.g.
INCLUDE MULTIPLY.FTH
which will compile it just as if you had entered the text at the keyboard. INCLUDE s can
be nested inside other files. Many Forth programmers compile big applications by
compiling a control file which just includes other files. On many systems you can find the
source code of a word by typing:
LOCATE <name>
You can also often see what was compiled using one of the following:
DIS <name>
SEE <name>
VIEW <name>
Suppose we had a section of a program that had to greet people. First, we could define a
word to say ‘hello’. We use a dot at the beginning of the name because it is a Forth
convention that words which print start with a dot. We use :to start a definition (followed
by its name) and ; to end it.
: .HELLO \ — ; has no effect on the stack
.” Hello “ ;
If you now type . HELLO <ENTER>, Forth will respond, followed by `ok’ to show that
there were no errors in the last entry. We now need some words to print out the names of
the people we want to greet.
(—)
: .FRED
.” Fred “ ;
: .MARY
.” Mary “ ;
: .NEIL
.” Neil “ ;
: .LINDA
.” Linda “ ;
We can now define a word to greet all these people. Forth words can occupy as many
lines as are needed. You can use line breaks and additional spaces to emphasize the
phrasing of the word.
: .GREET \ —
.HELLO .MARY .AND .FRED
.AND .LINDA .AND .NEIL CR ;
At some stage you will want to see what words are in the dictionary, to do this enter:
WORDS
You will see a long list of words roll past. You can stop the listing by pressing the space
bar. Press it again and the listing will continue. Press any other key, and the listing will
finish. All the names you see are the names of predefined words in Forth, plus any that
you have created. All these words are available for you to use, and the predefined ones
are documented later in this manual. The words that you write will use these words as
their basis.
The secret of writing programs in Forth is to keep everything simple. Remember the
KISS method (Keep It Simple, Stupid). Simple things work, and complicated things can
be built out of simple things. A programmer’s job is to decide what those simple things
should be, and then to design and code them. If the names of the words reflect what they
are to do, then the code will be readable and easy to follow. The next sections give an
introduction to the components of Forth, and a description of the program control
structures available.
5 Components of Forth
Only the words needed for this book are documented here. Most Forths have many more.
An HTML version of the last publicly available ANS Forth document, which is very
close to the final standard, is provided on the CD supplied with this book. Start with
DPANS.HTM.
Data stack operations
Learning any new language involves some grunt work. In Forth, much of this grunt work
involves learning how to manipulate items on the data stack. To quote Elizabeth Rather:
“Development of good stack management skills is a core component of Forth practice,
and a key to enjoying its benefits. If you regard the stack as a nuisance or an impediment,
you’re missing the whole point.”
By convention the top item of the data stack is called TOS and second item is called
NOS. You may also see the terms 3OS and 4OS in some code.
DUP \x—xx
DUPlicate the top stack item.
?DUP \x— 0|xx
DUP licate the top stack item only if it is non-zero. Nearly always used before a
conditional branch.
DROP \ x --
Discard the top data stack item and promote NOS to TOS.
SWAP \ x1 x2 — x2 x1
Exchange the top two data stack items.
OVER \ x1 x2 — x1 x2 x1
Copy the top item of the return stack and place on the data stack.
R> \ —x ; R: x --
Pop the top item off the return stack and place on the data stack.
2>R \ x1 x2 — ; R: — x1 x2
Push the current top cell pair from the data stack onto the return stack.
2R@ \ — x1 x2 ; R: x1 x2 — x1 x2
Copy the top cell pair of the return stack and place on the data stack.
2R> \ — x1 x2 ; R: x1 x2 --
Pop the top cell pair from the return stack and place on the data stack.
Maths operations
+ \ n1|u1 n2|u2 — n3|u3
Add two single precision integer numbers: n3=n1+n2. The stack comment indicates that
the operation works for both signed and unsigned numbers.
- \ n1|u1 n2|u2 — n3|u3
Subtract two single precision integer numbers: n3=n1-n2.
* \ n1 n2 — n3
Standard signed multiply: n3 = n1 * n2.
/ \ n1 n2 — n3
Standard signed division operator: n3 = n1/n2.
MOD \ n1 n2 — n3
Standard signed division operator returning the remainder: n3 = n1 mod n2.
UM* \ u1 u2 — ud3
An unsigned multiply that produces an unsigned double result.
*/ \ n1 n2 n3 — n4
Multiply n1 by n2 to give a double precision result, and then divide it by n3 returning the
quotient. The point of this operation is to avoid loss of precision. The ANS standard
permits systems to restrict n3 to positive numbers. This word is ideal for scaling
operations, e.g. after reading an analogue to digital converter or converting radians to
degrees.
: PI \ n — n*pi
355 113 */
;
Return TRUE if n2|u2 <= n1|u1 < n3|u3. Note the conditions. This word uses unsigned
arithmetic, so that signed compares are treated as existing on a number circle.
Widely available
<= \ n1 n2 — flag
Returns true if n1<=n2
>= \ n1 n2 — flag
Returns true if n1>=n2
Bitwise logic
AND \ n1 n2 — n3
Returns n3 = n1 AND n2
OR \ n1 n2 — n3
Returns n3 = n1 OR n2
XOR \ n1 n2 — n3
Returns n3 = n1 XOR n2
INVERT \ n1 — n2
Returns bitwise inverse of n1.
LSHIFT \ x1 u — x2
Logically shift x1 by u bits left.
RSHIFT \ x1 u — x2
Logically shift x1 by u bits right.
Memory operations
In Forth terminology items in memory that are the same size as items on the data stack
are called cells. The width of the stack is usually determined by the underlying CPU
architecture, being 16 bits on 16 bit CPUs, 32 bits on 32 bit CPUs and so on. For byte-
addressed CPUs (the majority), a character is a byte and bytes in an array are stored at
consecutive addresses.
@ \ addr — n
Fetch and return the cell at memory address addr.
! \ n addr --
Store the cell quantity n at memory address addr.
+! \ n addr --
Add n to the cell at memory address addr.
c@ \ addr — char
Fetch and zero extend the character at memory address addr.
c! \ char addr --
Store the character char at memory address addr.
CELLS \ n1 — n2
Returns n2, the memory size required to hold n1 cells. CELLS improves portability and
readability.
CHARS \ n1 — n2
Returns n2, the memory size required to hold n1 characters. CHARS improves
portability and readability.
Widely available
w@ \ addr — val
Fetch and zero extend the 16 bit item at memory address addr. Usually only found on 32
and 64 bit systems.
w! \ val addr --
Store the 16 bit item val at memory address addr. Usually only found on 32 and 64 bit
systems.
Constants and variables
Many times in a program we need to use a value to represent something, a type of flower,
or a bus route number. On other occasions the value corresponds to an actual value rather
than an association, the price of roses today, the ASCII code for a special key. Some of
this data never changes; it is constant. Other data changes from day to day or minute to
minute. The two types of data are created by CONSTANT, VARIABLE and VALUE .
Naming data makes programs easier to write and read, as people remember names more
easily than numbers.
CONSTANTs
Constants are used when the data will not change, or will only be changed when the
programmer edits the program (for instance, to change a control key). Constants return
their value to the stack.
DECIMAL \ all numbers are in decimal
(—n)
13 CONSTANT ENTER-KEY
1 CONSTANT DAFFODIL
2 CONSTANT TULIP
3 CONSTANT ROSE
4 CONSTANT SNOWDROP
VARIABLEs
In Forth a variable is named and set up by the word VARIABLE .
( — addr )
VARIABLE FLOWER
At this stage a variablecalled FLOWER has been declared with an initial value of 0 on
most systems. The ANS standard does not mandate a specific initial value. When you
use FLOWER the address of the data is given. Forth uses @ (‘fetch’) to fetch the data
from the address, and ! (‘store’) to store data into an address. If a specific initial value is
needed we can change it.
DAFFODIL FLOWER !
Later on in a program we can use the value of FLOWER to change the way the program
acts. Part of the program might be about to draw the flower, and we need to set the colour
properly.
: DAFF \ —
FLOWER @ DAFFODIL =
IF
YELLOW INK
THEN ;
To make a program wait until the ENTER key is pressed, you can try the code below.
: WAIT-ENTER \ — ; wait for <CR>
BEGIN
KEY ENTER-KEY =
UNTIL ;
In most words data is passed from word to word using the stack. If you find the stack
usage getting too complex, try splitting the word into other words which only use one or
two items on the stack. On other occasions you will find that all the words need to refer to
the same value which controls what happens on this run of the program (say, the type of
flower). In these cases the use of a variable is appropriate. As your Forth skills improve,
you will find that you use fewer variables.
VALUEs
The word VALUE creates a variable that returns its contents (value) when referenced,
and is widely used for variables that are mostly read and rarely changed. A VALUE is
defined with an initial value.
55 VALUE FOO
In embedded systems, you can rely on a VALUE being initialised at power up, whereas
the ANS specification does not require VARIABLEsto be initialised. You get the
contents of a VALUE by referring to it, but you set it by prefixing it with the word TO .
: test \n—
cr .” The value of FOO was “ foo .
to foo
.” and is now “ foo . ;
Control structures
A control structure is one that allows you to control the way a program behaves,
depending on the value of some piece of data you have previously calculated. This gives
a program the power of choosing to do this if one thing happens, or that if another thing
happens. Control structures in Forth allow execution and looping determined by values
on the stack. Although the user is not necessarily aware of it, control structures are
usually implemented by means of words that execute at compile time (immediate words),
and compile other words that actually execute at run time. Techniques like these allow
error checking to be implemented as well. Control structures must be used inside a colon
definition; they cannot be directly executed from the keyboard. Any one structure must be
written entirely within one definition; you cannot put the IF in one word and the THEN
in another. Control structures can be nested inside one another, but they must not overlap.
Although it is possible to write loops and control structures that return a variable number
of items on the stack, this practice leads to errors and is not recommended.
IF … THEN
flag IF <true words> THEN
The flag on the top of the stack controls execution. If the flag is non-zero (true), the
words between IF and THEN are executed, otherwise they are not.
Like most Forth words IF consumes the flag used as input to it. If the value of the flag
must be used again it can be duplicated by DUP . In the case of IF …. THEN , where
the value may only be needed between IF and THEN , the use of ?DUP , which only
duplicates a number if it is non-zero, may be more appropriate.
: TEST \ flag —
IF .” top of stack is non-zero ”
THEN
;
1 TEST top of stack is non-zero ok
0 TEST ok
IF…ELSE…THEN
flag IF <true words> ELSE <false words> THEN
This structure behaves just like IF ... THEN above except that an alternate set of words
will execute when the flag is false (zero).
: TEST \ flag
IF .” top of stack is non-zero “
ELSE .” top of stack is zero ”
THEN
;
EXIT
EXIT causes a return from the current definition. Before using EXIT you must ensure
that the data stack is correct and that anything you put on the return stack with >R has
been removed. EXIT is often used when an error check fails.
: FOO \ a b c – result
TEST1
IF DROP 2DROP <errcode1> EXIT
THEN TEST2
IF DROP 2DROP <errcode2> EXIT
THEN …
0 \ for success
;
This structure is very roughly the same as BASIC’s FOR X=1 TO 10….NEXT.
To use this structure, place the limit value and the starting value of the loop index on the
stack. DO will consume this data and transfer it to the return stack for use during
execution of the loop. LOOP will add one to the index and compare it to the limit. If the
index is still less than the limit the loop will be executed again. As a result of this the
limit value is never used. +LOOP behaves in the same way except that the increment on
the stack is added to the index.
You can get out of the loop early with the words LEAVE or ?LEAVE .
LEAVE ( — ) cleans up the return stack, and execution then resumes after
the LOOP or +LOOP . Note that words between LEAVE and LOOP or +LOOP are
not executed.
?LEAVE behaves like LEAVE except that the loop is left only if the top of the stack is
non-zero. This is a useful word when checking for errors. This word is non-ANS but is
widely available. It is equivalent to IF LEAVE THEN .
DO … LOOP structures may be nested to any level up to the capacity of the return stack.
The index of the current loop is inspected using I ( — n ) . The index of the next outer
loop is inspected using J ( — n ) .
If you need to terminate the loop early and get out of the current word by
using EXIT (see above) the code will not pass through LOOP or +LOOP . In this case
you must remove the loop control information using UNLOOP ( — ) . The following
word polls the keyboard every 100 milliseconds for one second. It returns a key code
immediately if a key is pressed, or returns a zero after one second if no key has been
pressed.
: TESTKEY \ — char|0
10 0 DO \ ten times
KEY? IF \ true if char
Random documents with unrelated
content Scribd suggests to you:
The Project Gutenberg eBook of Natchez,
Symbol of the Old South
This ebook is for the use of anyone anywhere in the United
States and most other parts of the world at no cost and with
almost no restrictions whatsoever. You may copy it, give it away
or re-use it under the terms of the Project Gutenberg License
included with this ebook or online at www.gutenberg.org. If you
are not located in the United States, you will have to check the
laws of the country where you are located before using this
eBook.
Language: English
Natchez
SYMBOL OF THE OLD SOUTH
2
MONTEIGNE—Stairhall
This book is dedicated to Louise and Mary.
3
Foreword
5
The Natchez Tribe
Natchez Trace
Opportunity for easy travel, over trails that were once Indian foot
paths, is offered now to motorists on perfect concrete highways.
Modern roads, which slowly evolved from dirt roads to paved
highways, stretch from Nashville, Tennessee, in a continuous smooth
concrete ribbon to Natchez, on the great Mississippi River.
Days when the beauty of the Southland could be viewed only
from a steamboat deck; days when transportation of passenger and
freight could be handled only by oxcart or slow stage coach or horse
and buggy (a three-weeks journey from Nashville to Natchez) are
gone forever, and soon the Deep South will be directly connected by
a day’s pleasant journey with all the cities and towns along the
Natchez Trace.
By treaty with Choctaw and Chickasaw Indian tribes the United
States Government in 1801 secured a permit to open the Natchez
Trace as a wagon road over which the mails could travel.
That same trail or “trace” from Nashville to Natchez is 500 miles
of consecutive beauty spots along continuous acres of parkways and
historic highways.
Mrs. Roan Fleming Byrnes, serving as President of the Natchez
Trace Highway Committee, in a recent publication says:
ebookbell.com