v4 Control Flow: for, break/continue, && / ||

Work through examples, try the reasoning yourself, then put it into practice.

View Slides

Before you start

  • Complete the v3 integration gate and lexical environment tracing.

What you will practice

  • Predict for-loop, break, and continue execution order.
  • Separate runtime short-circuiting from static traversal.
  • Extend maximal-munch lexing with logical operators and loop keywords.
In this lesson

Lesson

3 min read

v4 Control Flow: for, break/continue, && / ||

v4 adds for loops, break, continue, &&, and ||. The coding exercise here extends the lexer with the corresponding keywords and operator tokens; later modules implement the parser, analyzer, and compiler. v3 already had while loops and branches, so this milestone expands control transfer rather than inventing it.

Worked reconstruction

let total=0;
for (let i=0; i<4; i=i+1) {
  if (i==1) { continue; }
  if (i==3) { break; }
  total=total+i;
}
i entering body Body path Post-step runs? total
0 add 0 yes 0
1 continue yes 0
2 add 2 yes 2
3 break no 2

Initialization runs once. The condition precedes every body entry. Continue jumps to post (or the condition if post is absent); break skips post and exits. The initializer's i is scoped to the loop and is unavailable afterward. The body is a nested block, so its local declarations do not become post-step locals.

Lazy execution, complete syntax

false && (1/0) skips the division at runtime. Both operands still parse and are analyzed; false && missing() fails static name lookup. Compilation emits RHS code behind a branch instead of running it eagerly. Results are booleans, not operand values: nil || 7 gives true, and 7 && nil gives false. Only false and nil are falsey in v4; zero is truthy.

Lexing uses maximal munch for && and ||; a single & or | is unsupported. continueCount remains an identifier, so recognize keywords only after scanning a whole word. The syntax tree later gives && higher precedence than ||. No lexer decision should evaluate truthiness or decide whether a break has a legal enclosing loop.

Debugging lab

A loop with continue at i=1 never terminates after a refactor. Another lexer accepts a single & as AND. Identify the execution-edge defect and lexical contract defect.

Compare your diagnosis after attempting the lab

Continue must still reach the for post-step; jumping directly to the condition can leave i unchanged. AND requires the two-character && spelling, while a single & is an unsupported character in this language.

Transfer task

Modify the worked loop so post is absent and the body increments i explicitly. Identify where continue must go and how to keep the loop terminating. Tokenize continueFlag || false && true without deciding its runtime path.

Carry forward

Carry the event trace and new tokens into v4 parsing. Save separate tests for token boundaries, AST precedence, static loop legality, and runtime skip behavior.

Build program-lexer-v4. Keep a before/after trace of one failing test. Use the checkpoint to diagnose specific skills; passing it does not replace implementing and testing the artifact.


Practice sequence

Use the order below for a guided path, or choose an item to revisit. A pass records a successful attempt; try a fresh example later to check what you can reconstruct.

Join Discord