Conditional branching
    Il "Quarto" fuso ] The 4th Time Zone ]   


 

Introduction
Input/Output operations
Mathematical Operators
Stack operators
Other operators
Colon definition
Control structures
Conditional branching
Constants and variables
Other Forth words
Using the editor
Error messages


                                   

[ Index ][ Back ][ Next ]

Conditional branching must again be used only within a colon definition and use the form:

IF  (True Part) … Forth-words … THEN

IF  (True Part) … Forth-words … ELSE (False Part) … Forth-words … THEN

These conditional statement rely on testing the top number on the stack and decide whether to execute the True Part or the False Part of the condition. If the top item on the stack is true (non-zero) then the True Part will be executed. If the top item is false (zero) then the true part will be skipped and execution of the False Part will take place. If the ELSE part is missing then execution skips to just after the THEN statement. ENDIF is a synonym of THEN.

There are several mathematical operations which will leave either a true (non-zero) flag or a false (zero) flag on the stack to be tested for by IF.

0<

This will leave a true flag on the stack if the number on the top of the stack is less than zero, otherwise it leaves a false flag.

e.g.      -4 0< <CR>

will leave a true flag (non zero). To see this type

. <CR>

to print the top number on the stack which is the flag. This will print

-1

to show the true flag

914 0< . <CR>

will print a 0 (false flag).

0=

This will leave a true flag if the number on the top of the stack is equal to zero, otherwise it leaves a false flag.

<

This will leave a true flag if the second number on the stack is less than the top number, otherwise it leaves a false flag.

e.g.      40 25 <  . <CR>

will print 0 (false flag).

If we look at the stack during this operation we will see  

Operation

TOS

40

40

25

40  25

<

0

.

empty

>

This will leave a true flag if the second number on the stack is greater than the top number, else a false flag will be left.

e.g.      40  25 > . <CR>

will print -1 (true flag).

=

This will leave a true flag if the top two numbers are equal, otherwise it will leave a false flag.

Now for some exampes using the conditional branching structure, type:

: TEST=  <CR>
= IF ." BOTH ARE EQUAL " THEN  <CR>
." FINISHED " ;  <CR>

Now key in two numbers followed by TEST= and carriage return.

e.g.      11 119  TEST= <CR>

this will print  FINISHED

119 119  TEST=  <CR>

will print BOTH ARE EQUAL FINISHED

Now key in

:  TEST1=  <CR>
= IF ." EQUAL " ELSE ." UNEQUAL " THEN  <CR>
CR ." FINISHED " ;  <CR>

Now key in:

249 249 TEST1=  <CR>

this will print

EQUAL
FINISHED

Try:      249 249  TEST1=  <CR>

this will print

UNEQUAL
FINISHED

Notice how the part after THEN was executed in both cases.

Two more loops structure will now be discussed

BEGIN  … Forth-words …  UNTIL

BEGIN  … Forth-words …  WHILE … Forth-words …  REPEAT

Going to BEGIN … UNTIL the value at the top of the stack is test upon searching UNTIL. If the flag is false (zero) then the loop starting from BEGIN is repeated. If the value is true (non zero) then an exit from the loop occours.

Try typing the following examples:

: COUNT-DOWN DECIMAL  100  <CR>
BEGIN 1 – DUP DUP . CR 0= UNTIL  <CR>
." DONE " ;  <CR>

Now key in

COUNT-DOWN  <CR>

This will print:

99
98
97
…
2
1
0
DONE

The BEGIN … WHILE … REPEAT structure uses the WHILE condition to abort a loop in the middle of that loop. WHILE will test the flag left on the top of the stack and if that flag is true, will continue with the execution of words up to REPEAT which then branches always (unconditionally) back to BEGIN. If the flag is false then WHILE will cause execution to skip the words up to REPEAT and thus exit from the loop.

We will now build a program to print out the cubes of numbers from 1 upwards, until the cube is greater than 3000. The colon definition could be as follows:

: CUBE DECIMAL 0  BEGIN 1+  <CR>  
DUP DUP DUP DUP * * DUP  <CR>  
3000 <  WHILE  ."  THE CUBE OF "  <CR>  
SWAP .  ." IS " . CR REPEAT <CR>  
DROP DROP DROP ." ALL DONE "  CR  ;  <CR>
 

You may get an error message MSG#4 appearing on the screen: this means that the word you have just created already exists. This is not a problem, since the new-word will be created and all actions referencing the word CUBE will be directed to the latest definition using that word.

Try run this by keying in:

CUBE <CR>

and watch the results.

Now to follow what is happening by writing down the values on the stack at each iteration, if you are having any difficulty in doing this, the stack values are:

STACK

 

Operation

Display

 

Emtpy

 

DECIMAL

 

 

0

 

0

 

 

0

 

BEGIN

 

 

1

 

1+

 

 

N  N

 

DUP

 

Let’s now refer to the

N  N  N

 

DUP

 

number of the stack as N

N  N  N  N

 

DUP

 

 

N  N  N  N  N

 

DUP

 

 

N  N  N  N2

 

*

 

 

N  N  N3

 

*

 

 

N  N  N3  N3

 

DUP

 

 

N  N  N3  N3  3000

 

3000

 

 

N  N  N3  N3  flag

 

<

 

 

IF TRUE:

 

 

 

 

N  N  N3

 

WHILE

 

 

N  N  N3

 

." THE CUBE OF "

THE CUBE OF

 

N  N3  N

 

SWAP

 

 

N  N3   

 

.

N

 

N  N3   

 

." IS "

IS

 

N

 

.

N3

 

N

 

CR

carriage return

 

N

 

REPEAT

 

 

IF FALSE:

 

 

 

 

N  N

 

DROP

 

 

N

 

DROP

 

 

empty

 

DROP

 

 

 

 

." ALL DONE "

ALL DONE

 

 

 

CR

 

 

 

 

;

 

 

In fact, it is a good idea to check the stack contents during the execution of any new Forth word to make sure that it is working correctly. (Note that DROP merely clears the top number from the stack)

Finally, one extra construct has been added to circunvent the problem of deeply nested IF … THEN … ELSE structure. This is CASE OF structure. It takes the general form: n1

CASE
n1  OF  forth-words  ENDOF
n2  OF  forth-words  ENDOF
…
nk
  OF  forth-words  ENDOF
forth-words
ENDCASE

For example type:

:  TEST4 CASE  <CR>
1  OF ." FIRST CASE "  ENDOF  <CR>
2  OF  ." SECOND CASE "  ENDOF  <CR>
3  OF  ." THIRD CASE "  ENDOF  <CR>
." OTHER CASE "  <CR>
ENDCASE ;  <CR>

Now type:

1 TEST4 CR  2 TEST4 CR 3 TEST4 CR  <CR>

[ Index ][ Back ][ Next ]


Ultimo aggiornamento: 10-12-2002. Copyright (c) 2000-2002 Matteo Vitturi. 
Per problemi o domande relativamente a questo sito contattare il webmaster
Last update: 12.10.2002. Copyright (c) 2000-2002 Matteo Vitturi.
For problems or questions related to this web please contact the webmaster.
1