generate code, you create a tree of scopes in the same shape as the nested
function bodies. Each scope knows about the variables declared within it,
and has a reference to its parent enclosing scope. In this way, we know which
variables are new and need to be declared with <code>var</code>, and which are shared
with the outside.</p></td><tdclass="code"><divclass="highlight"><pre></pre></div></td></tr><trid="section-2"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-2">#</a></div><p>Set up exported variables for both <strong>Node.js</strong> and the browser.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="k">this</span><spanclass="p">.</span><spanclass="nv">exports: </span><spanclass="k">this</span><spanclass="nx">unless</span><spanclass="nx">process</span><spanclass="o">?</span>
<spanclass="nv">exports.Scope: </span><spanclass="nx">class</span><spanclass="nx">Scope</span></pre></div></td></tr><trid="section-3"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-3">#</a></div><p>Initialize a scope with its parent, for lookups up the chain,
as well as a reference to the <strong>Expressions</strong> node is belongs to, which is
where it should declare its variables, and a reference to the function that
it wraps.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">constructor: </span><spanclass="p">(</span><spanclass="nx">parent</span><spanclass="p">,</span><spanclass="nx">expressions</span><spanclass="p">,</span><spanclass="nx">method</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="err">@</span><spanclass="nv">temp_var: </span><spanclass="k">if</span><spanclass="err">@</span><spanclass="nx">parent</span><spanclass="k">then</span><spanclass="err">@</span><spanclass="nx">parent</span><spanclass="p">.</span><spanclass="nx">temp_var</span><spanclass="k">else</span><spanclass="s1">'_a'</span></pre></div></td></tr><trid="section-4"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-4">#</a></div><p>Look up a variable name in lexical scope, and declare it if it does not
<spanclass="kc">false</span></pre></div></td></tr><trid="section-5"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-5">#</a></div><p>Reserve a variable name as originating from a function parameter for this
scope. No <code>var</code> required for internal references.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">parameter: </span><spanclass="p">(</span><spanclass="nx">name</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="err">@</span><spanclass="nx">variables</span><spanclass="p">[</span><spanclass="nx">name</span><spanclass="p">]</span><spanclass="o">:</span><spanclass="s1">'param'</span></pre></div></td></tr><trid="section-6"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-6">#</a></div><p>Just check to see if a variable has already been declared, without reserving.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">check: </span><spanclass="p">(</span><spanclass="nx">name</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="o">!!</span><spanclass="p">(</span><spanclass="err">@</span><spanclass="nx">parent</span><spanclass="o">and</span><spanclass="err">@</span><spanclass="nx">parent</span><spanclass="p">.</span><spanclass="nx">check</span><spanclass="p">(</span><spanclass="nx">name</span><spanclass="p">))</span></pre></div></td></tr><trid="section-7"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-7">#</a></div><p>If we need to store an intermediate result, find an available name for a
compiler-generated variable. <code>_a</code>, <code>_b</code>, and so on...</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">free_variable: </span><spanclass="o">-></span>
<spanclass="err">@</span><spanclass="nx">temp_var</span></pre></div></td></tr><trid="section-8"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-8">#</a></div><p>Ensure that an assignment is made at the top of this scope
(or at the top-level scope, if requested).</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">assign: </span><spanclass="p">(</span><spanclass="nx">name</span><spanclass="p">,</span><spanclass="nx">value</span><spanclass="p">,</span><spanclass="nx">top_level</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="err">@</span><spanclass="nx">variables</span><spanclass="p">[</span><spanclass="nx">name</span><spanclass="p">]</span><spanclass="o">:</span><spanclass="p">{</span><spanclass="nv">value: </span><spanclass="nx">value</span><spanclass="p">,</span><spanclass="nv">assigned: </span><spanclass="kc">true</span><spanclass="p">}</span></pre></div></td></tr><trid="section-9"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-9">#</a></div><p>Does this scope reference any variables that need to be declared in the
given function body?</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">has_declarations: </span><spanclass="p">(</span><spanclass="nx">body</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="nx">body</span><spanclass="o">is</span><spanclass="err">@</span><spanclass="nx">expressions</span><spanclass="o">and</span><spanclass="err">@</span><spanclass="nx">declared_variables</span><spanclass="p">().</span><spanclass="nx">length</span></pre></div></td></tr><trid="section-10"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-10">#</a></div><p>Does this scope reference any assignments that need to be declared at the
top of the given function body?</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">has_assignments: </span><spanclass="p">(</span><spanclass="nx">body</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="nx">body</span><spanclass="o">is</span><spanclass="err">@</span><spanclass="nx">expressions</span><spanclass="o">and</span><spanclass="err">@</span><spanclass="nx">assigned_variables</span><spanclass="p">().</span><spanclass="nx">length</span></pre></div></td></tr><trid="section-11"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-11">#</a></div><p>Return the list of variables first declared in this scope.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">declared_variables: </span><spanclass="o">-></span>
<spanclass="p">(</span><spanclass="nx">key</span><spanclass="k">for</span><spanclass="nx">key</span><spanclass="p">,</span><spanclass="nx">val</span><spanclass="k">of</span><spanclass="err">@</span><spanclass="nx">variables</span><spanclass="k">when</span><spanclass="nx">val</span><spanclass="o">is</span><spanclass="s1">'var'</span><spanclass="p">).</span><spanclass="nx">sort</span><spanclass="p">()</span></pre></div></td></tr><trid="section-12"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-12">#</a></div><p>Return the list of assignments that are supposed to be made at the top
of this scope.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">assigned_variables: </span><spanclass="o">-></span>
<spanclass="s2">"$key = ${val.value}"</span><spanclass="k">for</span><spanclass="nx">key</span><spanclass="p">,</span><spanclass="nx">val</span><spanclass="k">of</span><spanclass="err">@</span><spanclass="nx">variables</span><spanclass="k">when</span><spanclass="nx">val</span><spanclass="p">.</span><spanclass="nx">assigned</span></pre></div></td></tr><trid="section-13"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-13">#</a></div><p>Compile the JavaScript for all of the variable declarations in this scope.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">compiled_declarations: </span><spanclass="o">-></span>
<spanclass="err">@</span><spanclass="nx">declared_variables</span><spanclass="p">().</span><spanclass="nx">join</span><spanclass="s1">', '</span></pre></div></td></tr><trid="section-14"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-14">#</a></div><p>Compile the JavaScript for all of the variable assignments in this scope.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">compiled_assignments: </span><spanclass="o">-></span>