Base CS from zero
Control flow: build a jump machine
Reading that an if is a conditional jump and a loop is a backward jump is one thing. Building a machine that runs nothing but jumps — and watching your if/else and your while loop emerge from it — is what turns the idea into a model you own. You will write a tiny interpreter whose only control-flow primitive is “set the program counter,” then make real branches and loops run on it.
Turn the unit’s mental model into working code: represent a program as a list of instructions, drive it with an explicit program counter, implement only sequential advance plus conditional and unconditional jumps, and demonstrate that every if/else and every loop you build reduces to those jumps — including the off-by-one and infinite-loop failure modes.
Build a small instruction interpreter (a 'jump machine') in any language whose only way to change control flow is writing the program counter. Then run several hand-written programs on it — straight-line, if/else, a counting loop, and a buggy loop — and produce an execution trace for each that follows the PC and the variables step by step.
- Running program A shows the PC advancing by exactly one each step and every instruction executing once, with no jumps taken.
- Program B produces two distinct PC paths for the true and false cases, the else block runs only on the false case, and the unconditional skip-jump is visibly what prevents the true path from running the else block.
- Program C's trace shows the backward jump firing exactly N times and the conditional exit jump firing once, with the loop variable matching the unit's countdown example.
- Program D demonstrates the failure: the off-by-one trace clearly reads or counts one item past the boundary, OR the infinite-loop trace shows the same flag value every pass until the step guard trips — and a one-paragraph note explains which condition never became false.
- A short write-up (a few sentences) stating, in your own words, why every branch and loop in the four programs reduced to nothing but rewriting the program counter.
- Add a do-while by moving the CMP + conditional jump to the bottom of the loop, and show in a trace that the body now runs at least once even when the condition is false at entry.
- Add support for an else-if chain (multiple CMP + conditional-jump pairs) and trace which arm wins for a few inputs.
- Implement short-circuit && and || in a guest program as chained conditional jumps, and trace an input that proves the right-hand operand is never evaluated.
- Add a tiny visualiser: print the instruction list with an arrow marking the current PC each step, so the trace reads like the MachineFigure cells from the lessons.
This is the unit made executable. By building a machine whose only control-flow primitive is “write the program counter,” you prove to yourself that sequential execution, if/else, and loops are not separate features — they are three uses of one mechanism. The straight-line program never touches the PC; the if/else steers it to two destinations with a skip-jump on the boundary; the loop rewinds it with a backward jump under a top-of-loop test; and the broken loop shows exactly how off-by-one and infinite loops arise from getting the test or the boundary wrong. Once you have watched branches and loops emerge from nothing but jumps, you read any program at the level the machine does.