2. Optimization Passes

Fix the Bug: Constant Folding

midcompiler-internalsdebugging

This fold(node) is supposed to fold every constant subexpression in an AST -- (2 * 3) + 4 should become ("num", 10), not stay as a tree with an unfolded 2 * 3 inside it. It works fine on the simple, one-level cases. It's silently wrong the moment a foldable subexpression is nested inside a larger one.

Your task: find the bug and fix it. Don't rewrite fold from scratch -- the overall approach is right, one specific thing about it is wrong.

fold(node) operates on the same two AST node shapes as the Parser exercise -- ("num", value) and ("binop", op, left, right) -- plus possibly other leaf shapes (e.g. ("var", name)) that aren't foldable and should come back unchanged.

Example that currently fails

fold(("binop", "+", ("binop", "*", ("num", 2), ("num", 3)), ("num", 4)))
# should be: ("num", 10)
# currently: ("binop", "+", ("binop", "*", ("num", 2), ("num", 3)), ("num", 4))
#            -- completely unchanged! the inner (2*3) never got a chance to fold.

Real-world grounding

Real compilers fold constants at every stage of optimization, not just once -- an earlier pass might turn a non-constant expression into a constant one, so folding often runs repeatedly until nothing changes. This exercise is the single core operation that machinery is built on.

hints
constant_fold.pysign in to run
Loading...
test result

This is a preview. Sign in to run this exercise against the real tests.