The interpreter

FlashForth is an interactive programming language consisting of words. Forth words are the equivalent of subroutines or functions in other languages and are executed by naming them. Although FlashForth is interactive at its core, the user doesn't need to interact with an embedded application if its top-level word is set to automatically execute at power-up.


Here is an example of executing a FlashForth word:


decimal \fbox{$\hookleftarrow$} ok<#,ram>


This executes the word that sets the base for representing numbers to 10, a format that you are likely to be more familiar with unless you are a student of mechatronics or computing.


Now, let's try something a bit more interesting by entering:


2 17 + . \fbox{$\hookleftarrow$} 19 <#,ram>


This time FlashForth more clearly shows its interpretive nature. A small program called the outer interpreter continually loops, waiting for input from the serial port. The input is a sequence of text strings (words or numbers) separated from each other by the standard Forth delimiter, one or more ASCII blank characters.


The text strings are interpreted in only three ways: words (subroutine or function names), numbers, or not defined. The outer interpreter tries first to look for the incoming word in the dictionary that contains the already defined words. If it finds the word, it executes the corresponding code.


If no dictionary entry exists, the interpreter tries to read the input as a number. If the string satisfies the rules for defining a number, it is converted to a number in the microcontroller's internal representation, and stored in a special memory location, called the top of stack (TOS).


In the example above, FlashForth interpreted 2 and 17 as numbers, and pushed them onto the stack. ``+'' is a predefined word, as is ``.'', so they are looked up and executed. The ``+'' (plus) word removed 2 and 17 from the stack, added them together, and left the result 19 on the stack. The word ``.'' (dot) removed 19 from the stack and sent it on the standard output device, the serial port for FlashForth. Here is a picture of the stack through the process.

word executed   2 17 + .  
             
stack result TOS
NOS
 2
17
 2
19
   


We might also work in hexadecimal, which was the default at power on:


hex 0a 14 * . \fbox{$\hookleftarrow$} c8 <$,ram>


This default is probably convenient for most embedded systems work, where setting and monitoring bit patterns forms a large part of the code. If you want to explicitly indicate the base of a number, you can prepend a sigil to the digits of the number. For example, $10, #16 and %10000 all represent the decimal value sixteen.


If the incoming text cannot be located in the dictionary nor interpreted as a number, FlashForth issues an error message.


0A \fbox{$\hookleftarrow$} 0A ?


thing \fbox{$\hookleftarrow$} thing ?


Note that the apparent hexadecimal number 0A was not interpreted as such because of the case sensitivity of FlashForth. Other error messages that you might see include SP ?, for a stack pointer error, and CO ?, for a context error. If the word * was to be executed without there being at least two numbers sitting on the stack, the interpreter would abort, issuing the SP error message, and then wait for new input.


Finally, here is the classic Hello World! program.


: hi ." Hello, World!" ; \fbox{$\hookleftarrow$} ok<$,ram>


Forth lets you output text using the word ." while the words : and ; begin and end the definition of your own word hi. Note that blank characters are used to delimit each of these words. Now, type in hi and see what happens.


hi \fbox{$\hookleftarrow$} Hello, World! ok<$,ram>


Peter Jacobs 2013-06-12