<< Home | About Forth | About TurboForth | Download | Language Reference | Resources | Tutorials | YouTube >>


3 Decision Making

Of course, computer languages aren't much use if they can't make decisions based upon some datum. Forth is similar to many other languages with its use of IF...THEN and CASE. However, because Forth uses a stack, its syntax is different. If you are coming to Forth with experience of other languages, such as BASIC or C then it will definitely look weird. Don't worry. It's just the stack-centric nature of Forth. It'll make sense, don't worry!

3.1 IF...ELSE...THEN

In languages such as BASIC (Visual Basic, VB Script etc) we're used to seeing IF expressions written like this:

    IF condition THEN THIS ELSE THAT ENDIF

Or, if you prefer it written in the horizontal, indented style:

    IF condition THEN
THIS
ELSE
THAT
ENDIF

In Forth, the format is different:

    condition IF THIS ELSE THAT THEN 

Firstly, don't worry about THEN coming at the end. We'll get to that (it's very simple, as is everything in Forth).

Notice how the condition comes before the IF? Well, as we know, Forth is a stack based language. All data is transferred via the stack. So, IF expects something on the stack. IF is a word just like any other word in Forth. It simply tests the value on the top of the stack (removing it as it does so) and if it determines that the value is true (i.e. anything other than zero) then the words immediately after the IF will be executed. If IF determines that the value being tested is false (0) then the words after the optional ELSE part are executed. Then the program continues with the words after the THEN word.

Let's have a look in a little bit more detail. Let's look at some C code, then we will write the equivalent Forth code.

In C we could write:

    a=4;
if((a & 1)==0)
printf("%s","Number is even");
else
printf("%s","Number is odd");

The above program tests the least significant bit of an integer, and if the bit is 0, then we indicate that the number is even, otherwise we declare that the number is odd.

How is this done in Forth? Read on:

    4 1 AND IF ." Number is odd" ELSE ." Number is even" THEN

Here, the 4 represents the variable A in the C program. We then put a 1 on the stack, and call AND which ANDs 4 with 1 (producing a result on the stack of 0 - the 4 and the 1 are removed from the stack by AND). The 0 returned by AND is fed into IF. Remember, the code after the IF executes if the value that IF tested is true (i.e. not 0). If the test is false, then the part after ELSE executes. Then the code continues with any code after the THEN (if it helps, think of THEN as ENDIF. In fact, some Forth systems use ENDIF rather than THEN).

Let's try it. Type the following into TurboForth:

    : ODD? 1 AND IF ." Number is odd" ELSE ." Number is even" THEN CR ;

We can try it by supply a number on the stack, then calling ODD? like this:

   5 ODD?

or

   6 ODD?

etc.

Let's examine which parts of the code execute when an odd number is supplied on the stack. Words in green are executed. Words in red are not executed:

    1 AND IF ." Number is odd" ELSE ." Number is even" THEN CR

As we can see, the 'odd' section of the code was executed, followed by the CR. Note that the CR is not part of the IF statement; it follows THEN (i.e. ENDIF) so it is just normal code to be executed in all circumstances, just like code before IF.

Let's examine which parts of the code execute when an even number is supplied on the stack. Again, words in green are executed. Words in red are not executed:

    1 AND IF ." Number is odd" ELSE ." Number is even" THEN CR 

AND and other such words are members of a family of 'comparison words', such as > (greater than), >= (greater than or equal) < (less than) etc. These words normally precede IF in Forth.

Note: Strictly speaking, the ELSE and the THEN aren't executed at all. They serve as place-markers to the compiler, but we don't need to worry about that. That's the compilers' job!

3.2 CASE

Case is used to make code clearer and easy to understand. You use it when you want to test a single value against a number of different possible values. As an example, we will compare a key press to a number of keys on the keyboard.

Here's how you might do it in BASIC, and C, with a SELECT CASE (BASIC) or Switch statement (C):

BASIC C
Select Key
CASE "Q": do_q CASE "A": do_a
CASE "O": do_o
CASE "P": do_p
CASE ELSE PRINT "Unrecognised key"
END SELECT
switch(key)
{
case 'Q': do_q(); break;
case 'A': do_a(); break;
case 'O': do_o(); break;
case 'P': do_p(); break;
printf("%s","unknown key");
}

The format is very similar in Forth, and would be instantly recognisable to most people familiar with BASIC or C. In forth, the words CASE, ENDCASE, OF and ENDOF are used in case processing, as shown in the example below (words in blue indicate the words associated with case processing):

Example

    key CASE
ASCII Q OF do_q ENDOF
ASCII A OF do_a ENDOF
ASCII O OF do_o ENDOF
ASCII P OF do_p ENDOF
." Unknown key"
ENDCASE

The above can be tested by entering the following code:

To test it, simply type TEST and press enter.

Notice the 'default case' - this code is executed if none of the case criteria match. It cannot be surrounded by OF and ENDOF (otherwise it just becomes another criteria) but must be placed before the ENDCASE code.

<-- Back to Tutorials


<< Home | About Forth | About TurboForth | Download | Language Reference | Resources | Tutorials | YouTube >>