There are no if, then, while, for, etc. loops or even a goto statement in
Q-BAL. Program control is handled by explicitly manipulating the program
counter, a predefined queue represented by a semicolon (;
). The
program counter normally has one element in it, representing a line number
(after all .I inclusions: see below), starting from 1 at the first line.
Blank lines and comments are not counted. So the following line:
0 -> ;
Will reset program execution to the beginning of the program. But in reality, it is never necessary to know the exact line number of any given line. Labels and relative branching are usually sufficient, as we will discover later.
You may have been wondering why the code snippet in the previous section
was 0 -> ;
and not 1 -> ;
. Normally, program
execution follows this pattern: The compiler/interpreter compiles/interprets
the command at the line number at the top of the program counter, then
executes the statement ;+1 -> ;
and repeats. If not
disturbed, therefore, execution will begin at line one (since ; =
{1}
at the start) and continue through the program one line at a time.
Therefore you must always set the program counter to the number one less than
the line number you want to branch to.
To imitate if, while, for, etc. statements, we only need to be able to say "go back x lines if such-and-such is true." This is done by multiplying x by the result of a logic operation, which is 0 if false and 1 if true. The code snippet
Q x in -> x ; - 2 \ (x != 0) -> ;
illustrates this concept, and will get input repeatedly until the number 0
is entered. Remember that after the line the statement ;+1 ->
;
is executed, so you must set ; to the line number one before the
line number of the line you want execution to jump to.
Very rarely, you may want to put two numbers into the program counter. This will cause execution to jump back and forth between two areas of the program, executing one statement, then another at a completely different address, then the statement after the first, then the one after the second, and so on.
Program execution can be stopped by the statement ; ->
if
there is only one number in the ; queue or ; =
if there are more
(except from inside a function as noted below. From inside a function these
statements return from the function, and :; ->
is required to
end execution.). The compiler/interpreter will assume the program is over if
there is no more code, so this statement is not really necessary. (A function
will also return without it at the end of the code.)
As anyone who has programmed in primitive BASIC will know, it can be extremely cumbersome to have to know line numbers in order to control program flow. Fortunately, it is possible to "label" a line in Q-BAL, although (like so many other things in Q-BAL) it is not designed directly into the language. Consider this code:
Q LABEL ... LABEL = ; ... ; = LABEL
The first statement functions as the "label," storing the program counter value (i.e. line number) at that point. It does not modify the program counter. The second statement reassigns that line number to the program counter, causing execution to jump to the line just after the label. Voila! And all without knowing what that line number is. Note that the second statement does not modify the queue LABEL, allowing it to be used again and again.