Commodore‎ > ‎BASIC‎ > ‎Keywords‎ > ‎


Keyword Abbreviation Token (hex) Version(s) Classification
DO none EB 3.5, 7.0 Command and Statement

DO [ { UNTIL | WHILE startTest ] [ : statement ] ...
[ statement : ] ... [ EXIT ] [ : statement ] ...
[ statement : ] ... LOOP [ { UNTIL | WHILE } endTest ] [ : otherCode ] ...
Parameters Type Legal Value(s) Default Value Note(s)
startTest Float    all   Zero is false, any other number is true
endTest Float all Zero is false, any other number is true
Command or
all Inside (during) the loop
Command or
all   Outside (after) the loop
Program flow control.  Execute statement(s) zero or more times.

The entire DO...LOOP construct may be on a single line, or span any number of lines (not only 3 lines like Syntax shows).  The statement(s) will be executed an arbitrary number of times; depending on the results of startTest and/or endTest (if either).  The loop will run forever (or until an EXIT is executed) if both startTest and endTest are omitted.
DO/LOOP is far more versatile than FOR/NEXT, however it generally runs slower.  This is true if the startTest or endTest check a variable that is changed during the statement(s).  The reason is BASIC will need to evaluate the statment(s) that do the updating on each pass, while FOR/NEXT is hard-coded to add a value that is calculated once at its beginning.  On the other hand, DO/LOOP uses only 5 bytes of stack space while FOR/NEXT uses 13 bytes.  Also it is rather easy to escape from DO/LOOP by using EXIT.  (This is possible with FOR/NEXT but requires some tricks to keep the stack clean.)
The WHILE clause will check if a condition is true, and if not (it "fails") the otherCode following the loop (if any) will be executed.  The UNTIL clause is the opposite; it will check if a condition is false, and if not (it "fails") it prevents another pass.
Unlike Visual BASIC or C, a test can be made at both the start and end of DO/LOOP in CBM BASIC.
Unlike the similar FOR/NEXT construct, DO/LOOP may execute zero times (i.e., if startTest "fails" when DO is first encountered.)
One problem remains, and is similar to that of FOR/NEXT.  The problem is that using LOOP in a conditional statement (IF/THEN/ELSE) may foul things up.  This happens when EXIT occurs before the conditional LOOP or the startTest "fails".  In my opinion, EXIT should ignore any LOOP that occurs in a conditional block of code.  Anyway the solution is similar to that of a conditional NEXT, which is to follow the conditional LOOP with GOTO to get to the real/unconditional end of the loop.
DO/LOOP is often used when the number of passes is not known (or easily calculated).  The EXIT statment also makes it easier to use if a pass needs to be aborted.  It also common to see it where the number of passes may need to be zero (although simply preceding FOR/NEXT with an IF/THEN clause may give faster results).  In any case, it is usually preferable to IF/THEN/GOTO "manual" looping constructs.
DO/LOOP may be nested.  Each LOOP matches the most recent DO.  If the startTest "fails" and a matching LOOP is not found then a LOOP NOT FOUND ERROR is generated.
Each DO should (generally) have a matching LOOP to avoid "memory leaks" (i.e., the BASIC stack getting filled with DO entries that are never removed by a matching LOOP).  It is possible to do this without creating memory leaks, it just requires some other kind of entry (such as FOR or GOSUB) to be on the BASIC stack prior to DO being executed.  Then when NEXT / RETURN is executed, it will clear the DO entry.
An OUT OF MEMORY ERROR occurs if there isn't room for 5 bytes on the BASIC stack when DO is first encountered.  Although startTest is optional, if present a SYNTAX ERROR occurs if it is not a valid expression or TYPE MISMATCH ERROR if it is a string expression.
TI$="000000" : DO WHILE TI<10 : PRINT TI : LOOP
 0           values may differ slightly on different machines


10 X = 0: DO: PRINT X;
20 : Y = 0: DO: PRINT Y
30 : Y = Y+1 : LOOP UNTIL Y>1
30 X = X+1 : LOOP WHILE X<3
 0  0
 0  1
 1  0
 1  1
 2  0
 2  1

  Compare With  
  See Also  

© H2Obsession, 2014