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

Lesson, slides, and applied problem sets.

View Slides

Lesson

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

Why v4 control flow matters

Before v4, you mostly lowered expressions. Now you lower execution shape:

  • repetitive structure
  • conditional jumps
  • non-local branch targets (break, continue)
  • short-circuit boolean edges

This is where control-flow correctness determines correctness of otherwise "valid" programs.


1) Canonical loop execution model

for (init; cond; post) { body } lowers with deterministic phases:

  1. optional init executes once
  2. jump to cond
  3. evaluate cond (or implicit true when omitted)
  4. if falsey -> exit loop
  5. execute body
  6. optional post
  7. jump to cond

A loop has two special edge types:

  • break: exit loop early
  • continue: go to continuation point

2) Loop scoping rules in v4

In this pack:

  • initializer may be declaration form (let i = 0)
  • initializer scope includes cond, body, and post
  • scope unwinds after loop end

That scope rule ensures:

  • for (let i = 0; ; ) { ... } has i visible in body/post
  • i does not leak outside loop

3) Compiler lowering skeleton

Lowering typically stores jump placeholders first:

ENTER_SCOPE
[init]
loop_start:
[cond]
JUMP_IF_FALSE loop_end
[body]
post_label:
[post]
JUMP loop_start
loop_end:
EXIT_SCOPE

For omitted parts:

  • no-init: skip init emission
  • no-cond: emit constant-true branch behavior
  • no-post: jump from post-label directly to loop_start

4) Patch lists for break/continue

You usually need a loop stack entry:

  • breakJumps []int to patch to loop_end
  • continueJumps []int to patch to post/next-iteration point

At loop exit, patch every recorded jump offset.

This avoids recursive backtracking and keeps nesting explicit.

Important:

  • continue in nested loops must target the innermost loop continuation
  • break targets current loop-end label

5) Short-circuit lowering (&& and ||)

For a && b:

  • evaluate a
  • if falsey: jump to false branch, push false, skip b
  • else evaluate b, result becomes final boolean

For a || b:

  • evaluate a
  • if truthy: jump to true branch, push true, skip b
  • else evaluate b

This module treats result as boolean in control-flow lowering, but runtime truthiness remains package policy (false or nil.


6) Precedence and parser support

Grammar in v4 parser is explicit:

  • or -> and ("||" and)*
  • and -> equality ("&&" equality)*

That gives left-associative behavior inside each precedence level.

Parsing contracts must preserve:

  • a || b && c as a || (b && c)
  • a && b || c as (a && b) || c

7) Correctness checks that catch 90% of bugs

Before finalizing v4 control flow:

  • every emitted jump offset is patched
  • each unresolved break/continue list should be empty after exit
  • no jump points to wrong loop level
  • boolean result left on stack exactly once for logical expressions

A small diff in one jump target can change program meaning without crashing.


8) Practice checkpoints (almost solved)

1) Loop state ordering + for (let i = 0; i < 2; i = i + 1) { } + Expected order: init once, repeated cond -> body -> post -> cond.

2) continue target in with-post loops + for (i = 0; i < 5; i = i + 1) { continue; f(i); } + Expected: f(i) is skipped; jump goes to post update.

3) break behavior + for (...) { break; } + Expected: exits to immediate loop end and does not execute post/body after break point.

4) Infinite loop rule + for (;;) { if (false) break; } + Expected: legal and semantically infinite unless control exits.

5) Short-circuit correctness + false && sideEffect() should not execute sideEffect(). true || sideEffect() should not execute sideEffect().

6) Nesting + Inner break/continue do not affect outer loop targets.

7) Omitted expression semantics + for (; ; i = i + 1) keeps loop running until explicit break/return from body.

This module is where deterministic jump graphs make your compiler production-real.


Module Items

  • Program Lexer v4

    Lex the v4 language with for/break/continue and logical operators.

    medium Sign in to access medium and hard problems
Join Discord