Creating Programs in Forth
A new word is created by using a colon definition. This simple example program squares the value on top of the stack:
: square
dup *
;
The colon (:) tells Forth that a definition is starting (switching Forth from interpreter to compiler mode). What immediately follows the colon is the name of the word to be created, in this case called square. (In FlashForth, word names are limited to 15 characters.) The definition is finished with a semicolon (;). (This is the equivalent of a function or subroutine return in C or assembler.) The semicolon also switches from compiler mode back to interpreter. Everything in between : and ; constitutes the new program.
Note that new lines and tabs are ignored by the compiler in a word definition. They are just there to improve readability. It’s perfectly valid to create a word all on one line. It works just the same:
Note that new lines and tabs are ignored by the compiler in a word definition. They are just there to improve readability. It’s perfectly valid to create a word all on one line. It works just the same:
: square dup * ;
To run our new word, at the prompt we simply type a number, then the word square we just created and a dot (to print the result), and press return:
3 square .
gives an output of 9.
Words are stored in a linked list known as the dictionary. You can see the dictionary by typing words at the prompt.
You may be surprised by how much is in the dictionary when you run words for the first time. Everything that Forth has and uses is in the dictionary. If you want to search the dictionary for a string, you can use words name to search for all words that contain name. For example, to search the dictionary for all words that contain the string char:
Words are stored in a linked list known as the dictionary. You can see the dictionary by typing words at the prompt.
You may be surprised by how much is in the dictionary when you run words for the first time. Everything that Forth has and uses is in the dictionary. If you want to search the dictionary for a string, you can use words name to search for all words that contain name. For example, to search the dictionary for all words that contain the string char:
words char
will find three words matching char.
[char] char chars char+
When the user types square on the console or uses square in a word definition, Forth looks through the dictionary for a match, and then simply uses the appropriate subroutine.
FlashForth remembers any word you created, even when powered off. There is no need to save the dictionary, it happens automatically. When you next use your Udamonic computer, your dictionary is as you left it.
The word latest will place onto the stack the address of the last word defined.
[char] char chars char+
When the user types square on the console or uses square in a word definition, Forth looks through the dictionary for a match, and then simply uses the appropriate subroutine.
FlashForth remembers any word you created, even when powered off. There is no need to save the dictionary, it happens automatically. When you next use your Udamonic computer, your dictionary is as you left it.
The word latest will place onto the stack the address of the last word defined.
|
In other Forth implementations, words may be redefined using the same name, the new word appearing in the dictionary list after the previous definition. When the input is parsed by the Forth interpreter, the dictionary is searched for a match, starting at the latest entry and working back. Thus, a redefined word will be matched before the parser reaches an earlier definition. Early words that used the prior definition reference that word by its address rather than its dictionary entry, and therefore still point to the original definition.
FlashForth does not allow a word to be redefined with the same name. This is a consequence of the dictionary being stored in the processor’s flash memory. Therefore, with FlashForth you will need to manually remove that word from the dictionary before redefining it. Experienced Forth programmers take note! |
|
Writing Good Forth
As with any other programming language, it’s possible to write good Forth, and just as easy to write bad Forth. Here are some Forth tips:
- Within a word, limit your stack usage to no more than three or four parameters. Any more than this and you will find it challenging to keep mental track of where you’re up to.
- Use several short word definitions rather than one long word definition. Break your problem up. Don’t ever create a Forth word that is hundreds of lines of code long. The beauty of Forth is its ability to build upon itself, allowing you to test as you go. To this end, keep your Forth words to three or four lines of code where possible. That might sound strange if you’re used to other languages, but once you get into the swing of Forth, you’ll understand that this is a logical approach to coding.
- Keep it simple and focus on what you’re trying to achieve. A simple Forth word that solves a specific, simple problem is better than a complicated do-all word that is difficult to write and hard to debug.
- Check for data that is out of range or erroneous, and generate useful error messages or diagnostics.
Removing Words
You can remove a word you have created from the dictionary using the forget word followed by the name of the word you wish to remove:
forget myword
Note if you have other words that use myword, then forget will also remove those. (This makes sense since any words that rely on myword will no longer work once myword is forgotten.)
|
You can only forget words that you have created. You can’t forget words that are part of the builtin FlashForth dictionary.
|
|
FlashForth has the ability to create sandboxes within the dictionary. If you’re just experimenting and want to create several words on a temporary basis (knowing you will ultimately delete or replace them), you can use the word marker to draw a line in the sand, so to speak. The word marker followed by a label creates a marker.
marker -myMarker
This creates a new marker word called -myMarker in the dictionary. The marker word, when run, will remove all words from the dictionary that were created after that marker. To erase all words back to the marker point, just type:
-myMarker
You can create as many markers at different points in the dictionary as you want. As -myMarker appears as a word in the dictionary, it’s useful (but not required) to prefix it with a minus sign. This acts a visual reminder that it’s a marker (and capable of removing words), so you don’t erase a bunch of words accidently.
The word empty will remove all words from the dictionary that were not part of the original Forth build. empty is the equivalent of a “factory reset” in FlashForth.
The word empty will remove all words from the dictionary that were not part of the original Forth build. empty is the equivalent of a “factory reset” in FlashForth.