compile/while
Symbol: compile/while
Syntax: (while TEST BODY... [else: ELSEBODY...])
Use-case: Loop that runs body while TEST is truthy. Supports compile/break
and compile/continue inside the body. An optional [else: ELSEBODY...] clause
runs only when the loop exits because TEST is false (i.e. not via
compile/break); its value becomes the loop’s expression value. Without an
else clause the loop’s value is the value of its last iteration: the body’s
last form, or the value given to compile/continue; None when the body
never ran. (break VAL) makes VAL the loop’s value. In block syntax, the
same clause comes from an else: peer; see
layout/while.
Behaviour: Emits PUSH_LOOP (break target after POP_LOOP). The continue
target is the first instruction after PUSH_LOOP. Compiles TEST; on false,
jumps to the loop exit label. Compiles the body with helper_begin, then
CONTINUE 1 back to the test. On normal exit (test false), when an else body is
present, emits CLEAR_LOOP, compiles ELSEBODY, then POP_LOOP, which delivers
the else result from the region’s stack. The region is disabled while the
else body runs, so a compile/break or compile/continue written there
belongs to the enclosing loop. User compile/break from the body jumps to
the break target with its value and does not run the else clause.
Examples:
;; Simple loop
(while x
(append c x)
(setq x (- x 1)))
;; With break
(while True
(cond [done (break result)]
[else: (step)]))
;; Else runs when TEST becomes false
(while x
(setq x (- x 1))
[else: "done"])
Also: layout handler while.