Using a stack for parameter passing between words makes Forth very powerful. It's because of the stack that the language is re-entrant and supports recursion. However, the dynamic nature of the stack makes it unsuitable for global data. Forth is not limited to using the stack, as the language provides for both named constants and variables.
Constants
A constant (a value that does not change) is declared by placing the value for the constant onto the stack, then the word constant, followed by the name for the constant.
For example, the following code declares a constant called kilobyte (representing the number of bytes in a K) to have a value of 1024:
For example, the following code declares a constant called kilobyte (representing the number of bytes in a K) to have a value of 1024:
1024 constant kilobyte
Using the constant in your code is trivial. Simply use the constant name to place the value onto the stack by typing:
kilobyte
As an example, to use the constant kilobyte to convert a Kbyte value into bytes and print out the result:
32 kilobyte * .
gives a result on the console of 3276.
Variables
Variables are declared in a similar way to constants, but the way they are used is quite different. Rather than placing a value onto the stack, the variable name will place a pointer (address) to the variable onto the stack. The pointer is used in conjunction with the words @ (pronounced fetch) and ! (pronounced store) to retrieve or modify the variable.
A variable is declared by the word variable, followed by the variable name:
A variable is declared by the word variable, followed by the variable name:
variable myVar
Let’s say we want to make myVar equal to 27. We do it by placing a value onto the stack, using the variable name to place the pointer to that variable onto the stack, and then use store to assign the value to the variable:
27 myVar !
Note that in FlashForth, the variable name is in the dictionary, stored in non-volatile flash memory, but the variable’s value is stored in RAM by default. The dictionary entry in flash points to the RAM location. Therefore, when power is lost and then restored, all RAM-based variables still exist as entities in the dictionary, but their values are lost. It’s important to initialize RAM-based variables as appropriate before use.
To recall the variable’s value, we use the variable name to place the pointer onto the stack, and then use fetch to retrieve the value and place it on the stack:
myVar @
For example, let’s say we want to add 5 to the current value of myVar:
myVar @
5 +
myVar !
This might seem a bit strange if you're used to other programming languages, but it is very close to what goes on behind the scenes when you say myVar = myVar + 5 in C. In C, the mechanics of the process is hidden from you. In Forth, the nuts and bolts are there for all to see (and play with).
Non-volatile Variables
All need not be lost when the power goes out. FlashForth supports storing variable values in non-volatile flash memory. In the following example, memory context is switched to flash, using the flash word, before the variable is created. Both the variable name (in the dictionary) and its value are stored in flash memory. The memory context is changed back to RAM with the word ram. The value (say for example, 42) is then stored to the variable, as we have seen previously. Using the variable is no different to using a RAM-based variable.
flash
variable myVar
ram
42 myVar !
If you kill and then restore power to your Udamonic computer, myVar will have retained its value.
Flash does not have the same endurance as RAM, limited to 20,000 write cycles in the case of the PIC24 processor in your Udamonic computer. Therefore, only use flash-based variables where absolutely necessary, and avoid unnecessary writes where possible.
VaLUES
A value is a variable that can be accessed by its name (rather than using the name in conjunction with fetch). Another way of thinking of a value is as a modifiable constant. It is created in a similar way to a constant, in that an initial value is placed on the stack, then the word value is called, followed by the name to be created:
100 value myValue
Then to recall that value, the name myValue is called, placing 100 onto the stack.
myValue
Changing a value is done with the to word:
120 to myValue
Typing myValue will now return 120 on the stack.
As with variables, values can be made non-volatile by declaring them in flash memory. This is useful for storing system settings.
As with variables, values can be made non-volatile by declaring them in flash memory. This is useful for storing system settings.