Remember: Pairs are (ScriptNum, ScopeNum)
// Script 1
// Scope 1
var x = 1; // Declared(1) = [x];
function f() // Script 2
{ // Scope 2
if (x > 10) { //Scope 3 // Used[x] = [(2,2)];
var x = 12; // Declared(3) = [x];
function g() // Script 3
{ // Scope 4
return x; // Used[x] = [(2,2), (3,4)]
} // Leaving Script 3, Scope 4: No declared variables.
// Leaving Script 2, Scope 3: Declared(3) = [x];
// - Used[x][1] = (2,2) is not > (2,3)
// - Used[x][2] = (3,4) is > (2,3), so mark x as closed over.
// Update Used[x]: [] -- Makes sense, as at this point we have
// bound all the unbound x to a particlar
// declaration..
} else { // Scope 5
var x = 14; // Declared(5) = [x]
function g() // Script 4
{ // Scope 6
return y; // Used[y] = [(4,6)]
} // Leaving Script 4, Scope 6: No declarations.
} // Leaving Script 2, Scope 5: Declared(5) = [x]
// - Used[x] = [], so don't mark x as closed over.
var y = 12; // Declared(2) = [y]
} // Leaving Script 2, Scope 2: Declared(2) = [y]
// Used[y][1] = (4,6) is > (2,2), so mark y as closed over.
// Update Used[y]: [].