Welcome to RetroForth

Forth does not rely as heavily on the use of variables as other compiled languages. This is because values normally reside on the stack. There are situations, of course, where variables are required. To create a variable, use the word variable as follows:

variable MY-VAR

This created a variable named MY-VAR. A space in memory is now reserved to hold its 32-bit value. The word variable is what's known as a defining word since it creates new words in the dictionary. Now enter:

MY-VAR .

The number you see is the address, or location, of the memory that was reserved for MY-VAR. To store data into memory you use the word !, pronounced store. It looks like an exclamation point, but to a Forth programmer it is the way to write 32-bit data to memory. To read the value contained in memory at a given address, use the Forth word @, pronounced fetch. Try entering the following:

513 MY-VAR !
MY-VAR @ .

This sets the variable MY-VAR to 513, then reads the value back and prints it. You can also create a variable and set its value at the same time:

513 variable: MY-VAR2
MY-VAR2 @ .

The stack diagrams for these words follows:

@ ( addr -- val )
! ( val addr -- )
variable ( [name] -- )
variable: ( val [name] -- )

Imagine you are writing a game and you want to keep track of the highest score. You could keep the highest score in a variable. When you reported a new score, you could check it against the highest score. Try entering this code:

variable HIGH-SCORE

: max ( a b -- c ) 2dup <if nip ;; then drop ;

: REPORT.SCORE ( score -- )
dup cr ." Your Score = " . cr
HIGH-SCORE @ max ( calculate new high )
dup ." Highest Score = " . cr
HIGH-SCORE ! ( update variable )
;

Save the file to disk, then load this code using the include word. Test your word as follows:

123 REPORT.SCORE
9845 REPORT.SCORE
534 REPORT.SCORE

The Forth words @ and ! work on 32-bit quantities. Some Forths are "16-bit" Forths. They fetch and store 16-bit quantities. Forth has some words that will work on 8 and 16-bit values. c@ and c! work on characters which are usually for 8-bit bytes. The c stands for character since ASCII characters are 8-bit numbers.

A word of warning about fetching and storing to memory: You have now learned enough about Forth to be dangerous. The operation of a computer is based on having the right numbers in the right place in memory. You now know how to write new numbers to any place in memory. Since an address is just a number, you could, but shouldn't, enter:

73 253000 ! ( Do NOT do this. )

The 253000 would be treated as an address and you would set that memory location to 73. I have no idea what will happen after that, maybe nothing. This would be like firing a rifle through the walls of your apartment building. You don't know who or what you are going to hit. Since you share memory with other programs including the operating system, you could easily cause the computer to behave strangely, even crash. Don't let this bother you too much, however. Crashing a computer, unlike crashing a car, does not hurt the computer. You just have to reboot. The worst that could happen is that if you crash while the computer is writing to a disk, you could lose a file. That's why we make backups. This same potential problem exists in any powerful language, not just Forth. This might be less likely in BASIC, however, because BASIC protects you from a lot of things, including the danger of writing powerful programs.

Constants

If you have a number that is appearing often in your program, it's recommended you define it as a constant. We do this just like defining a word. Enter:

: MAX_CHARS 128 ;
MAX_CHARS .

We just defined a word called MAX_CHARS that returns a specific value. It cannot be directly changed unless you edit the program and recompile. Using constants can improve the readability of your programs and reduce some bugs. Imagine if you refer to the number 128 very often in your program, say 8 times. Then you decide to change this number to 256. If you globally change 128 to 256 you might change something you didn't intend. If you change it by hand you might miss one, especially if your program occupies more than one file. Using constant will make it easy to change. The code that results is equally as fast and small as putting the numbers in directly. I recommend defining a constant for almost any number used more than two or three times.