Tracing a program
Step through a TypeScript program that combines a conditional and a loop. Follow the program counter and variable state on each iteration to see exactly how if and while behave together at the instruction level.
You now know that an if is a conditional jump and a while is a backward jump. But
reading about them separately is different from watching them work together in a real
program, step by step, with the variable state changing in front of you.
This lesson does exactly that. You will read a short TypeScript function that loops over a small array and adds up only the positive numbers. Then you will trace it frame by frame — following the program counter and the value of every variable on each line — until the function returns its result.
After this trace you will not just know what the code says; you will know what the CPU does, one instruction at a time.
After this lesson you can read a program that combines a loop and a conditional, predict each step of execution by tracking the program counter and variable values, explain how the loop condition and the if-condition interact, and identify the exact frame at which the loop exits.
The program to trace is a sum-of-positives function over a fixed array. It has three control-flow moments:
- While test — evaluate
i < nums.lengthat the start of each iteration. The program counter either falls through into the loop body (condition true) or jumps forward past the loop (condition false, exits). - If test — evaluate
nums[i] > 0inside the body. The program counter either executessum += nums[i](condition true, fall-through) or skips it (condition false, jump forward). - Increment and backward jump —
i++runs every iteration (positive or not), then the unconditional backward jump returns to the while test.
The array is [3, -1, 4]. Initial state: sum = 0, i = 0. Expected result: 3 + 4 = 7
(the value -1 is skipped by the inner if).
Each frame in the trace below shows:
- The line of code about to execute.
- The current values of
i,sum, andnums[i].
Together, these three control-flow moments mean every element is visited exactly once and the accumulator reflects only those that pass the inner test; if you moved i++ inside the if block, negative numbers would stall the loop forever.
Tracing this by hand before looking at the frames is highly recommended — it cements the mental model of the program counter moving through code.
function sumPositives(nums: number[]): number { let sum = 0; // accumulator starts at zero let i = 0; // loop counter starts at zero while (i < nums.length) { // backward-jump loop if (nums[i] > 0) { // conditional: skip negatives sum += nums[i]; } i++; // always increment, positive or not } return sum; } - L2 sum: accumulator — collects the running total
- L3 i: index into nums — advances every iteration
- L5 while test: CMP i, nums.length → conditional jump exits when i >= length
- L6 if test: CMP nums[i], 0 → conditional jump skips sum+= when nums[i] <= 0
- L7 sum += nums[i]: adds current element only when the if condition is true
- L9 i++: unconditional; runs even when the if was skipped
- L10 closing brace: unconditional backward jump back to the while test on line 5
Step through sumPositives([3, -1, 4]) frame by frame. Each cell shows the current value
of one variable. The active line is highlighted in the code panel above.
function sumPositives(nums: number[]): number { let sum = 0; let i = 0; while (i < nums.length) { if (nums[i] > 0) { sum += nums[i]; } i++; } return sum; } ▸Edge cases
What if the array is empty? If nums = [], then nums.length = 0 and the while test
on the very first check evaluates i=0 < 0 → false. The loop body never runs. The
function immediately returns sum = 0. This is the correct result for an empty input and
is a natural consequence of testing the condition before the body — the same hardware
mechanism that makes a while test at the top.
After the first iteration of sumPositives([3,-1,4]), i has been incremented from 0. What value does i hold at the start of the second while test?
During iteration 2 (nums[1] = -1), the if condition nums[1] > 0 is false. What value does sum hold after i++ runs at the end of that iteration?
How many times does the line 'sum += nums[i]' execute when called with [3,-1,4]?
At what value of i does the while loop exit (i.e., when the while condition becomes false)?
sumPositives([2, -5, -3, 6]) returns what value?
In sumPositives, what happens when nums[i] is negative or zero?
Tracing a program step by step reveals the concrete machinery behind high-level syntax.
In sumPositives, the while loop is a test-first backward-jump structure: on each
iteration the condition i < nums.length is evaluated (a compare updates the Z or N
flag), a conditional jump either exits the loop or falls through into the body, and an
unconditional backward jump at the bottom resets the program counter to the test. The
inner if is a second CMP + conditional jump: when nums[i] > 0 is false, the body
sum += nums[i] is skipped by a forward conditional jump; when true, it falls through.
The i++ increment is unconditional — it sits outside the if block and runs regardless.
The loop exits when i reaches nums.length, at which point the while condition is
false, the conditional jump at the top fires (a forward jump past the loop), and the
program counter moves to return sum. The final value of sum is the total of all
positive elements encountered during the iteration. Now when you trace any unfamiliar loop-with-condition by hand, follow this same frame-by-frame discipline: track each variable, note which jump fired and why, and the bug — whether a wrong result or an infinite loop — will surface at the exact frame where state diverges from expectation.
Practice
Start at the top. Tasks go easiest → hardest: recall a fact, apply it to a case, then a senior-level stretch. Open one, attempt it, then reveal.
Something unclear?
Ask a question about this lesson. Questions are anonymous and go straight to the author to make the lesson better.