To recalculate in the right order, the engine must know which cells each formula reads - its precedents. Today you walk a formula's tree and collect the exact set of cells it depends on.
Collect the set of cells a formula reads, expanding any ranges to their cells.
The whole of recalculation rests on one question: which cells does a formula
read? Those cells are its precedents. Finding them is a recursive walk of
the AST that collects every CellNode’s address and expands every RangeNode to
its cells, gathering them into a set so a cell mentioned twice counts once. So
A1+B1*2 depends on A1 and B1, and SUM(A1:A3) depends on all three cells the
range covers.
Return the precedents in a stable reading order (row by row, left to right) so that every result built on top of them - the graph’s edges, the recalculation order
C1’s precedents include B1, then there is an edge saying
“C1 depends on B1”, and therefore B1 must be computed before C1. The next
lesson turns these per-formula precedent sets into that graph.// walk the AST; collect CellNode refs, expand RangeNode to its cellsfunc precedents(e Expr) []Ref {set := map[Ref]bool{}var walk func(Expr)walk = func(e Expr) {switch n := e.(type) {case CellNode: set[n.Ref] = truecase RangeNode: for _, r := range expand(n.A, n.B) { set[r] = true }case BinaryNode: walk(n.L); walk(n.R)case CallNode: for _, a := range n.Args { walk(a) }}}walk(e)return sortedReadingOrder(set)}