DO / LOOP

Syntax

Syntax: DO [WHILE|UNTIL cond] : ... : LOOP [WHILE|UNTIL cond]
Source: pb_cg_emit_do (pb_codegen.c:5639)

Description

Creates a loop with flexible condition placement. Conditions can be tested at the top (DO WHILE / DO UNTIL) or at the bottom (LOOP WHILE / LOOP UNTIL). A bare DO...LOOP with no condition creates an infinite loop (use EXIT DO to break). WHILE continues while the condition is true; UNTIL exits once the condition becomes true. ITERATE DO jumps to the condition check at the bottom of the loop.

Parameters

ParameterDescription
WHILE conditionLoop continues while the condition is TRUE (non-zero). Can appear at DO (pre-test) or LOOP (post-test).
UNTIL conditionLoop exits when the condition becomes TRUE. Can appear at DO (pre-test) or LOOP (post-test).
(no condition)A bare DO...LOOP loops forever. Must use EXIT DO to break out.

Example

FUNCTION PBMAIN() AS LONG
    LOCAL x AS LONG
    LOCAL input AS STRING
    
    ' Pre-test: DO WHILE x > 0
    x = 5
    DO WHILE x > 0
        PRINT "Countdown: "; x
        x = x - 1
    LOOP
    PRINT "Done!"
    
    ' Post-test: loop at least once
    x = 0
    DO
        PRINT "x = "; x
        x = x + 1
    LOOP UNTIL x > 3
    
    ' Infinite loop with EXIT
    x = 0
    DO
        x = x + 1
        IF x > 10 THEN EXIT DO
        ' Skip even numbers
        IF (x AND 1) = 0 THEN ITERATE DO
        PRINT "Odd: "; x
    LOOP
    
    FUNCTION = 0
END FUNCTION

Generated Assembly

DO WHILE (pre-test)

__pb_do_N:                            ; LOOP TOP
; Evaluate condition
; Condition-false-jump -> __pb_do_end_N
; ... body ...
jmp    __pb_do_N                       ; loop back
__pb_do_end_N:

DO UNTIL (pre-test, exits when true)

__pb_do_N:
; Evaluate condition
; Condition-true-jump -> __pb_do_end_N (inverted from WHILE)
; ... body ...
jmp    __pb_do_N
__pb_do_end_N:

LOOP WHILE (post-test)

__pb_do_N:
__pb_do_iterate_N:                    ; ITERATE target
; ... body ...
; LOOP WHILE condition:
; Evaluate condition -> RAX
test   rax, rax
jne    __pb_do_N                       ; loop if true
__pb_do_end_N:

LOOP UNTIL (post-test)

__pb_do_N:
__pb_do_iterate_N:
; ... body ...
; LOOP UNTIL condition:
test   rax, rax
je     __pb_do_N                       ; loop if false
__pb_do_end_N:

Infinite DO...LOOP

__pb_do_N:
; ... body ...
jmp    __pb_do_N                       ; unconditional loop
; (no __pb_do_end_N generated)

EXIT DO

jmp    __pb_do_end_N                   ; exits the loop

ITERATE DO

jmp    __pb_do_iterate_N               ; skips to condition check