SuperForth for the Tatung Einstein, showing a SuperForth 1.12 session defining a word
← Back to Courses
module
11

Names For Numbers

Introduction

The stack is a marvellous place to keep a number for the next two seconds. It is a poor place to keep a score for the length of a game. Anything that has to be remembered while other things happen needs a home of its own, and a name you can ask for it by.

SuperForth has two kinds of named number: one that never changes and one that does.

Constants

40 CONSTANT COLUMNS

From now on COLUMNS is a word that puts 40 on the stack. The number comes first, as always in Forth, because CONSTANT takes it from the stack.

COLUMNS 2 / . prints 20. A constant behaves exactly like the number it stands for; it is just easier to read, and if the number ever has to change there is one place to change it.

Variables

0 VARIABLE SCORE

makes a variable called SCORE that starts at 0. The starting value is not optional - VARIABLE takes it from the stack, like CONSTANT does.

Here is the thing that catches everybody. Typing SCORE does not give you the score. It gives you the address of the score: a number saying where in the machine's memory it lives. That number is no use to look at. It is what you hand to the three words that do the real work:

WordPictureDoes
@( addr -- n )fetch: replaces the address with what is stored there
!( n addr -- )store: puts n at that address
+!( n addr -- )adds n to what is stored there

@ is pronounced "fetch" and ! is "store". So:

SCORE @ .

is "score, fetch, print". And 10 SCORE ! is "ten, score, store".

Printing a variable is so common that there is a word for "fetch and print": ?. SCORE ? does what SCORE @ . does.

In MAME, @ is SHIFT and 0, and ! is SHIFT and 1.

The Code

40 CONSTANT COLUMNS
0 VARIABLE SCORE
: HIT 10 SCORE +! ;
: SHOW ." SCORE " SCORE ? ;
HIT HIT HIT SHOW
COLUMNS 2 / .

Starting from

A fresh boot, with SuperForth just started. FORTH or BIGFORTH will do.

What you should see

An ok after each of the first four lines, and then:

HIT HIT HIT SHOW
SCORE 30 ok
COLUMNS 2 / .
20 ok

A constant, a variable and two words that use it; three hits make a score of 30

HIT and SHOW are worth a second look. Neither takes anything from the stack or leaves anything on it. They get at the score through its name. That is what a variable is for: it lets words share a number without passing it from hand to hand.

Do Not Overdo It

Coming from BASIC, the temptation is to make a variable for everything. Try not to. A number that is used straight away belongs on the stack, where it costs nothing and needs no name. Keep variables for the things a whole program needs to agree on - the score, the lives left, where the player is.

Names That Are Taken

40 CONSTANT WIDTH
WIDTH Isn't Unique ok

SuperForth has a great many words of its own, and sooner or later you will pick a name it is already using. WIDTH is one. It is only a warning and your definition goes ahead, but you have just hidden one of SuperForth's own words behind yours, and anything you type later that expected the original will get yours instead. When you see Isn't Unique for a name you did not know you had used, FORGET it and choose another.

Change One Thing

  • Type SCORE . instead of SCORE ?. What is that number? Type HIT and try again. Did it change?
  • Make the constant 80 instead of 40. What does SuperForth say when you define COLUMNS a second time, and what does COLUMNS . print afterwards?
  • Change HIT so that it is worth 25, simply by defining it again. What does SuperForth say? Which HIT does HIT SCORE ? use now?
  • Type SCORE @ 1+ . and then SCORE ?. The first printed one more than the score. Did the score go up? Why not, and what would you add to make it?

Exercises

11.1 Make a variable LIVES that starts at 3, and a word LOSE that takes one away. Check it with LOSE LIVES ?.

11.2 Define NEW-GAME to set the score back to 0.

11.3 Define a constant DOZEN, and use it to print how many eggs are in three dozen.

11.4 Define BONUS to double the score, whatever it is.

Worked solutions are in Appendix II.

When It Goes Wrong

SymptomCause
A variable prints as a large number that means nothing to youYou printed its address. You want ?, or @ .
Isn't Unique for a name you have never usedSuperForth already has a word of that name. FORGET yours and pick another.
A burst of rubbish on the screen - it may clear, or turn to reverse colours - and then Empty Stack, when defining a variableThe starting value was missing, and SuperForth used whatever it found instead. It is 0 VARIABLE SCORE, number first. SuperForth carries on working afterwards, and the variable exists with rubbish in it; FORGET it and define it properly.
The variable never changes! and +! want the number first and the variable second: 10 SCORE !.

Summary

n CONSTANT name names a number that stays put. n VARIABLE name makes a store that starts at n; its name gives an address, and @ fetches from it, ! stores to it, +! adds to it and ? prints it. Use variables for what the whole program shares and the stack for everything else.

Next

S12, Doing It Again - making SuperForth repeat something a set number of times, and counting as it goes.

Get the Newsletter

New guides, disk images and community finds, roughly once a quarter. No spam, we promise, this isn't Tatung's marketing department.
Your subscription could not be saved. Please try again.
Your subscription has been successful.

Newsletter

Subscribe to our newsletter and stay updated.