Introduction to Forth - Embedded.com

Introduction to Forth

Forth is a niche programming language originally designed for real-time control of telescopes. Over the years, it evolved into an ANSI-standard language. While not widely used anymore, it's still worth a look.

Forth is a niche programming language originally designed for real-time control of telescopes. As programmers from other fields discovered Forth, a grassroots effort emerged to mold it into an ANSI-standard language.

Programmers who've used Forth describe the language as being like a room without walls. Some thrive on such freedom, while others are uncomfortable with it. Since Forth is a type-less language, the compiler can do little checking for you before you run your program. As a result, the most common failure scenario is a system crash.

Forth is used mostly to test and debug hardware and bring up systems. Only about one in 50 embedded developers report using Forth regularly. Interestingly, some UNIX workstations boot a small Forth interpreter before the rest of the operating system. This environment provides some basic programming capabilities right out of ROM, and a small Forth bootloader stored there enables the operating system to be manually or automatically loaded from a disk drive or over a network and then run.

The Forth estate

Forth is a language with a simple syntax and many keywords. This is in contrast to Algol-style languages (such as Pascal and C/C++), which have a complex syntax and few keywords. If you're completely new to Forth, try to forget everything you know about programming languages as you read on.

Forth programs are made of many small procedures. Forth is compiled, yet has no compiler in the traditional sense. Essentially, it's a population of subroutines and an interpreter. The subroutines are called words. (In this article, words will appear in UPPER-CASE.) The dictionary is a data structure that associates the compiled words with their string names. The interpreter can invoke words that perform compilation actions, thereby extending the dictionary in the middle of a program. Figure 1 shows a flow chart of a Forth interpreter. The interpreter evaluates white space-delimited strings taken from an input stream, such as a console or file, usually in one pass.


Figure 1: A Forth interpreter's flow chart

Word games

You write a Forth program by defining new words, and run it by executing the top-level word. Forth manipulates data on a parameter stack that is separate from the call stack. (There are no registers.) Although static variables can be defined, words generally pop their parameters from the parameter stack, and push their results onto it. For example, the built-in word + pops the top two values, adds them, and pushes the sum back onto the stack. Bitwise AND operates similarly. The word < pops="" two="" values,="" compares="" them,="" and="" pushes="" the="" result="" (0="" or="" -1).="" so="" a="" forth="" programmer="" would="" code="" (2+3)*(4+5)="" as="" 2="" 3="" +="" 4="" 5="" +="" *,="" in="" reverse="" polish="" notation="" (rpn).="">

The Forth standard specifies a boolean result as all 0's or all 1's, which is 0 or -1 in twos complement arithmetic. This allows you to mix arithmetic and boolean operations, for example < 7="" and.="" the="" compiler="" allows="" any="" kind="" of="" type="" mixing,="" as="" forth="" is="" typeless.="">

With most data kept on the parameter stack, there's little need to track variable names or addresses, and temporary storage is automatic. Several built-in words manipulate the stack by rotating, removing, copying, or displaying items from various stack positions: SWAP swaps the top two items, DROP removes the top stack item, and OVER copies the second stack item to the top of the stack, thereby increasing the stack size by one.

Words that manipulate character strings generally require a pointer as the second item on the stack and the string length on the top. Branching and looping words also use the stack. IF pops and tests the value on top of the stack. If the value is non-zero, the next word executes. Otherwise, control passes to the word following the ELSE, if present. BEGIN starts an indefinite loop and the corresponding END pops and tests the top stack value, looping back to BEGIN if it's zero. DO/LOOP pairs repeat until an index (passed on the stack) increments to or beyond a limit (also passed on the stack). An important difference is that the index and limit are copied to the call stack-to avoid cluttering the parameter stack.

Listing 1: A Forth program and its stack

: BIGGEST OVER OVER < if="" swap="" then="" drop="" ;="" 5="" 9="" biggest="" .="">

Listing 1 shows the definition and testing of a new word, BIGGEST. The word : switches to compiler mode and begins the definition of the new word. OVER OVER duplicates the values to be compared while maintaining their order. The word < compares="" them,="" popping="" the="" two="" values="" copied="" by="" over="" over="" and="" pushing="" the="" result="" of="" the="" comparison,="" which="" is="" subsequently="" popped="" and="" tested="" by="" if.="" if="" the="" comparison="" results="" in="" a="" -1,="" control="" passes="" to="" swap,="" which="" swaps="" the="" two="" values.="" either="" way,="" the="" smaller="" value="" is="" now="" on="" top,="" ready="" to="" be="" removed="" by="" drop.="" the="" word="" ;="" terminates="" the="" definition="" and="" takes="" the="" interpreter="" out="" of="" compile="" mode.="">

Once defined, we can use a new word immediately. 5 9 BIGGEST pushes 5, then 9, then removes the smaller value. The word . prints the value on top of the stack (in this case 9), and the stack is again empty. The state of the stack as the program executes is shown below the code.

Go Forth and prosper

Forth has earned a reputation for being a write-only language. A typical Forth program defines and uses thousands of new words. In the absence of good naming conventions and comments, this can be a big maintenance headache. On the other hand, there's no reason Forth programs can't be useful and well documented. esp

Brad Eckert holds a BS in physics from Shippensburg University. He has been a designer of both hardware and software for embedded systems for about 15 years. Brad wrote and maintains a free Forth-based framework for extensible firmware. His e-mail address is .

Don Rowe is a consultant specializing in embedded controllers. He has over 25 years of experience with digital and analog design, software testing, and reverse engineering. Contact him at .

Further Reading

www.forth.org
Conklin, Edward and Elizabeth Rather. Forth Programmer's Handbook. Hawthorne, CA: Forth Inc., 1998.

Return to the September 2002 Table of Contents

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.