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

Making A Choice

Introduction

S13 gave you questions. This section gives you something to do with the answers.

IF, ELSE, THEN

: SIZE 100 > IF ." BIG"
ELSE ." SMALL" THEN ;

IF takes a flag from the stack. If the flag is true, the words between IF and ELSE run. If it is false, the words between ELSE and THEN run instead. Either way, things carry on after THEN.

The order takes getting used to, because it is Forth's order: the question comes first, already answered and sitting on the stack, and IF only acts on it. Read THEN as "and then carry on". It marks the end of the choice, not the start of a consequence.

If THEN jars too much, SuperForth lets you write ENDIF instead. It does the same job.

Like loops, IF only works inside a definition.

The Code

: SIZE 100 > IF ." BIG"
ELSE ." SMALL" THEN ;
500 SIZE
7 SIZE

Starting from

A fresh boot, with SuperForth just started.

What you should see

500 SIZE
BIGok
7 SIZE
SMALLok

SIZE defined over two lines, then tried on 500 and on 7

Without ELSE

Often there is nothing to do when the answer is no. Leave the ELSE out:

: MYABS DUP 0< IF MINUS THEN ;

If the number is negative, change its sign; otherwise leave it alone. The DUP is essential, and it is the mistake everyone makes once: 0< uses up the number it tests, and IF uses up the flag. Without the DUP there would be nothing left to take the sign of.

Any Number Will Do

IF does not insist on a 1. Anything that is not zero counts as true. That is what -DUP from S6 is for. It copies the top number only when it is not zero, so

: SHOW -DUP IF . THEN ;

prints a number unless it is zero, and leaves the stack clean in both cases: with a non-zero number there is a copy for IF to use up and the original for .; with zero there is only the zero, and IF uses that up.

Choices Inside Choices

: GRADE DUP 70 > IF ." MERIT" ELSE
DUP 50 > IF ." PASS" ELSE ." FAIL"
THEN THEN DROP ;

Each IF needs its own THEN, which is why there are two at the end. It works, and you can see it is already getting hard to read. Two deep is about the limit; S16 has a better tool for choosing among several things.

Guarding A Loop

S12 left a problem: a loop always runs once, so 0 STARS prints a star. Now you can stop it:

: STARS -DUP IF 0 DO 42 EMIT
LOOP THEN ;

It is split over two lines because on one it would be exactly 40 characters long, and S7 explained what becomes of those. With 0 on the stack, -DUP leaves just the 0, IF takes it as false, and the loop is skipped.

Change One Thing

  • Change SIZE so that exactly 100 counts as big. There is more than one way.
  • Take the ELSE ." SMALL" out of SIZE. What does 7 SIZE print now?
  • Remove the DUP from MYABS and try -9 MYABS . What went wrong, and where did the 9 go?
  • Define the guarded STARS and try 0 STARS, 1 STARS and 5 STARS.

Exercises

14.1 Define EVEN-ODD to print EVEN or ODD for the number on the stack.

14.2 Define BIGGER ( n1 n2 -- n ) to leave the larger of two numbers, without using MAX.

14.3 Define COUNT-UP ( n -- ) to print the numbers from 1 to n, and to print nothing at all if n is 0.

Worked solutions are in Appendix II.

When It Goes Wrong

SymptomCause
IF? Compilation only, Use in DefinitionIF typed at the keyboard. It has to be inside a word.
Empty Stack, or a wrong answer, after an IFThe test used up the number you wanted afterwards. DUP before testing.
A number left on the stack that should not beOne branch used the number and the other did not. Both branches must leave the stack the same.
;? Definition not FinishedAn IF without its THEN. Count them.
Isn't Unique for a name you thought was newSuperForth already has it. SIGN and END are both taken.

Summary

flag IF ... ELSE ... THEN runs one set of words or the other; ELSE is optional and ENDIF is another name for THEN. IF uses up the flag, any non-zero number counts as true, and the test usually needs a DUP in front of it. Both branches should leave the stack the same way.

Next

S15, Until It's Done - loops that go round not a set number of times but until something happens.

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.