3.2 Overview: MUF (cont'd)
A loop is a section of code that executes repeatedly, until a certain
condition is met. The programmer defines the condition. If no condition
is defined (or if the condition is one that will never be met), the loop
will continue to execute indefinitely. This is called an `infinite
loop'. The code for a loop begins with the primitive
and ends with either
A common way to define the exit condition of a loop is to use a
variable to store the number of times the loop is to execute. With each
repetition (or `iteration') of the loop, the variable is increased
(`incremented') or decreased (`decremented') by one. When the value
stored in the variable matches a predefined limit (often
0), the loop exits. The following version of tinker.muf
uses a loop controlled in this manner to do the `random number test'
from the previous version three times.
me @ "Yes, the number is greater than one million." notify
me @ "No, the number is less than one million." notify
3 ourCounter !
ourCounter @ 0 = if
random ourNumber !
ourNumber @ 1000000 > if
me @ ourNumber @ intostr notify
ourCounter @ 1 - ourCounter !
me @ "OK, we're done with the loop." notify
At the very top of the program, we declared the local variable
In the first iteration of the loop, the
ourCounter. In the first line in main, we stored the integer 3
in our variable
ourCounter. The next line is
BEGIN, which starts the loop. The first thing
MUF does with each pass through the loop is check to see if
the value stored in
ourCounter is 0. If it is, execution
BREAKs out of the loop, and does whatever comes next (which
in this case is to tell us "OK, we're done.")
IF test will be false,
because we just put a
ourCounter, not a
0. So the loop will continue, executing our random number test.
Then, at the bottom of the loop, we fetch the number out of
1 from it, and then store the
new number back in
ourCounter. Then the loop
REPEATs, jumping back to the top of the loop. This time, the
2... still not
0, so the loop exectutes again. The next time the loop repeats,
the value is
1: the random number test has executed three times.
Then execution will jump back to the top of the loop and begin for a
fourth iteration. This time, however, the value stored in
ourCounter has reached
will be true, so the
BREAK will be executed. The program jumps
out of the loop and does whatever comes after the
us we're done).
Here we are using
IF to see if it is time to break out of
MUF provides another conditional statement that
does the same thing in shortened form.
WHILE tests the top
value on the stack for truth, just like
IF does. When an
IF test is true, code between the
IF and its
THEN is executed; otherwise, it skips to whatever
THEN. When a
WHILE test is true,
code between the
WHILE and the next
UNTIL is executed; otherwise, it skips to whatever follows
UNTIL. In other words, the loop
continues to execute
WHILE the condition is true.
In the above version of tinker.muf, we used...
ourCounter @ 0 = if
to exit the loop. We could accomplish the same thing with...
ourCounter @ while
As long as
ourCounter is not
0, it will be
true, and the rest of the loop will execute. When it gets to
0, it becomes false, and the
WHILE will cause
execution to break out of the loop.
UNTIL also provides a way to exit from a loop. The
UNTIL marks the `bottom' of the loop, like a
REPEAT, but also serves as an exit-condition check like
WHILE. If the value on top of the stack is true when the
program gets to
UNTIL, execution `falls through' the bottom
of the loop and continues from there. For example, the following loop
RANDOM generates an integer greater than 1.5
dup intostr me @ swap notify
With each iteration, the loop generates a random number, converts it
into a string and notifies the user, then tests to see if it's greater
than 1.5 billion. If so, the top value on the stack at
UNTIL will be true, and the program will exit the loop.
Otherwise, execution jumps back to
BEGIN, and the loop