GOTO Loops

Home, Up: Loops

 

On this page:

GOTO Loops, Exiting Goto Loops, GOTO Loop Example: Next Prime Number, Timeout Emergency Exit.

 

GOTO Loops

When a GOTO command addresses a label line that comes before it in a script, it creates a loop.

GOTO loops are independent of Hypatia's DO and REPEAT loops, and can be used in scripts that are called directly, or in scripts that themselves run in a (DO or REPEAT) loop.

If you have some experience with programming languages, GOTO loops will look more familiar to you than Hypatia's idiosyncratic DO and REPEAT loop construct.

This documentation will only cover the basic principles of using GOTO loops, the rest is up to your programming skills.

 

Exiting Goto Loops

The most important thing about GOTO loops is how to exit them -- unlike Hypatia's DO and REPEAT loops, and unlike FOR ... NEXT loops in most programming languages, GOTO loops have no counter, and need to be explicitly exited by the script.

There are three ways to exit a GOTO loop when the script runs in a DO or REPEAT loop -- if it doesn't, then the first and second ones are the same.

1. You want to immediately end the script -- for this you use SKIP. If your script runs in a DO or REPEAT loop, that loop continues.

2. You want not only to immediately end the script, but also the DO or REPEAT loop in which it runs -- then you have to use ABORT.

When the script does not run in a DO or REPEAT loop, SKIP and ABORT do the same (though ABORT lets you display a comment).

In both of the above cases, the GOTO command at the bottom of the loop has to be the last line in the script, because any lines that follow it would never be reached.

 

3. You want to exit the GOTO loop but continue with the part of the script that comes after the GOTO command at the bottom of the loop.

This, again, can be done in two ways which were already mentioned on the page GOTO and Labels in chapter "Scripts".

One is to exit the loop with another GOTO command to a label line that immediately follows the GOTO command at the bottom of the loop.

The other one is to make the GOTO command that drives the loop depend on a condition, so that the loop ends when the condition is not met anymore.

 

GOTO Loop Example: Next Prime Number

As an example, let's create a script that prompts for a number and looks for the first prime number larger than this number. We can call this script prime.

 

PROMPT $p enter a positive integer number, 0 to abort

IF $p IS0 THEN ABORT

LABEL: next

$p = $p 1 +

IFNOT $p ISPRIME THEN GOTO next

#: the next prime number is:

SHOW $p

 

You can call this script directly:

? _prime

or in a loop:

_*prime

 

If you call the script in a loop, then when you do not enter a new number at the prompt for $p but only press ENTER, you get the next prime number -- only pressing ENTER means that the value of the variable remains unchanged, which in this case is the previously found prime number.

 

This script has one problem: if you enter a non-integer number then the GOTO loop will continue forever, because no matter how often you add 1, $p ISPRIME will never be true.

To avoid this, we can check whether the number that was entered is a positive integer:

 

PROMPT $p enter a positive integer number, 0 to abort

IF $p IS0 THEN ABORT

IFNOT $p ISPOSINT THEN SKIP

...

 

Note the difference between ABORT and SKIP, if this script runs in a DO or REPEAT loop: entering 0 aborts the loop, entering an invalid number skips the rest of the script and starts again at the first line, prompting for another number. If the script does not run in a loop, entering 0 or a non-integer number would do the same.

 

Now the GOTO loop works as we want it to, but there is still one possible improvement: since prime numbers can never be even (we disregard the prime number 2 here), we only need to look at every second number, if we start with an odd one.

The condition IF $p 2 MULIPLE is true when $p is even -- in this case we diminish $p by 1, before we add 2 to arrive at the next possible candidate for being prime.

 

PROMPT $p enter a positive integer number, 0 to abort

IF $p IS0 THEN ABORT

IFNOT $p ISPOSINT THEN SKIP

IF $p 2 MULTIPLE THEN $p = $p 1 -

LABEL: next

$p = $p 2 +

IFNOT $p ISPRIME THEN GOTO next

SHOW $p

 

Timeout Emergency Exit

Usually it will not be difficult to program a GOTO loop so that it will eventually end, but as a safeguard against GOTO loops going on forever you can use the TIME pseudo constant -- for instance, to end the loop after one minute, when it clearly shouldn't need that much time:

IF TIME 60 >> THEN ABORT timeout!

(This has to stand somewhere between the label line and the GOTO command, of course. Do not use IF TIME 60 == because TIME will probably never have that exact value.)

 

If needed, you can set the timer to zero with the command TIME0 -- for instance after the script had to wait for a user input:

 

PROMPT $p enter 0 to abort

IF $p IS0 THEN ABORT

TIME0

LABEL: next

IF TIME 60 >> THEN ABORT timeout!

...

...

IF ... THEN GOTO next

 

The TIME0 command not only prevents the script from immediately ending when the user had paused for more than 60 seconds before entering a value, it also makes it possible to call the script in a loop, with the time limit applying to each new pass of the loop.

 

Home, Up: Loops, Prev: REPEAT and REPEAT Loops, Next Chapter: Loop and Script Examples