with the outside.</p></td><tdclass="code"><divclass="highlight"><pre></pre></div></td></tr><trid="section-2"><tdclass="docs"><divclass="pilwrap"><aclass="pilcrow"href="#section-2">¶</a></div><p>Import the helpers we plan to use.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="p">{</span><spanclass="nx">extend</span><spanclass="p">,</span><spanclass="nx">last</span><spanclass="p">}</span><spanclass="o">=</span><spanclass="nx">require</span><spanclass="s1">'./helpers'</span>
<spanclass="nv">exports.Scope = </span><spanclass="nx">class</span><spanclass="nx">Scope</span></pre></div></td></tr><trid="section-3"><tdclass="docs"><divclass="pilwrap"><aclass="pilcrow"href="#section-3">¶</a></div><p>The top-level <strong>Scope</strong> object.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nx">@root</span><spanclass="o">:</span><spanclass="kc">null</span></pre></div></td></tr><trid="section-4"><tdclass="docs"><divclass="pilwrap"><aclass="pilcrow"href="#section-4">¶</a></div><p>Initialize a scope with its parent, for lookups up the chain,
it wraps.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nx">constructor</span><spanclass="o">:</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="nv">Scope.root = </span><spanclass="k">this</span><spanclass="nx">unless</span><spanclass="nx">@parent</span></pre></div></td></tr><trid="section-5"><tdclass="docs"><divclass="pilwrap"><aclass="pilcrow"href="#section-5">¶</a></div><p>Adds a new variable or overrides an existing one.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nx">add</span><spanclass="o">:</span><spanclass="p">(</span><spanclass="nx">name</span><spanclass="p">,</span><spanclass="nx">type</span><spanclass="p">,</span><spanclass="nx">immediate</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="nx">@positions</span><spanclass="p">[</span><spanclass="nx">name</span><spanclass="p">]</span><spanclass="o">=</span><spanclass="nx">@variables</span><spanclass="p">.</span><spanclass="nx">push</span><spanclass="p">({</span><spanclass="nx">name</span><spanclass="p">,</span><spanclass="nx">type</span><spanclass="p">})</span><spanclass="o">-</span><spanclass="mi">1</span></pre></div></td></tr><trid="section-6"><tdclass="docs"><divclass="pilwrap"><aclass="pilcrow"href="#section-6">¶</a></div><p>Look up a variable name in lexical scope, and declare it if it does not
<spanclass="kc">no</span></pre></div></td></tr><trid="section-7"><tdclass="docs"><divclass="pilwrap"><aclass="pilcrow"href="#section-7">¶</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="nx">parameter</span><spanclass="o">:</span><spanclass="p">(</span><spanclass="nx">name</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="nx">@add</span><spanclass="nx">name</span><spanclass="p">,</span><spanclass="s1">'param'</span></pre></div></td></tr><trid="section-8"><tdclass="docs"><divclass="pilwrap"><aclass="pilcrow"href="#section-8">¶</a></div><p>Just check to see if a variable has already been declared, without reserving,
walks up to the root scope.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nx">check</span><spanclass="o">:</span><spanclass="p">(</span><spanclass="nx">name</span><spanclass="p">,</span><spanclass="nx">immediate</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="o">!!</span><spanclass="nx">@parent</span><spanclass="o">?</span><spanclass="p">.</span><spanclass="nx">check</span><spanclass="nx">name</span></pre></div></td></tr><trid="section-9"><tdclass="docs"><divclass="pilwrap"><aclass="pilcrow"href="#section-9">¶</a></div><p>Generate a temporary variable name at the given index.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nx">temporary</span><spanclass="o">:</span><spanclass="p">(</span><spanclass="nx">name</span><spanclass="p">,</span><spanclass="nx">index</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="s1">'_'</span><spanclass="o">+</span><spanclass="p">(</span><spanclass="nx">index</span><spanclass="o">+</span><spanclass="nb">parseInt</span><spanclass="nx">name</span><spanclass="p">,</span><spanclass="mi">36</span><spanclass="p">).</span><spanclass="nx">toString</span><spanclass="p">(</span><spanclass="mi">36</span><spanclass="p">).</span><spanclass="nx">replace</span><spanclass="sr">/\d/g</span><spanclass="p">,</span><spanclass="s1">'a'</span></pre></div></td></tr><trid="section-10"><tdclass="docs"><divclass="pilwrap"><aclass="pilcrow"href="#section-10">¶</a></div><p>Gets the type of a variable.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nx">type</span><spanclass="o">:</span><spanclass="p">(</span><spanclass="nx">name</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="kc">null</span></pre></div></td></tr><trid="section-11"><tdclass="docs"><divclass="pilwrap"><aclass="pilcrow"href="#section-11">¶</a></div><p>If we need to store an intermediate result, find an available name for a
compiler-generated variable. <code>_var</code>, <code>_var2</code>, and so on...</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nx">freeVariable</span><spanclass="o">:</span><spanclass="p">(</span><spanclass="nx">type</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="nx">temp</span></pre></div></td></tr><trid="section-12"><tdclass="docs"><divclass="pilwrap"><aclass="pilcrow"href="#section-12">¶</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="nx">assign</span><spanclass="o">:</span><spanclass="p">(</span><spanclass="nx">name</span><spanclass="p">,</span><spanclass="nx">value</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="vi">@hasAssignments = </span><spanclass="kc">yes</span></pre></div></td></tr><trid="section-13"><tdclass="docs"><divclass="pilwrap"><aclass="pilcrow"href="#section-13">¶</a></div><p>Does this scope have any declared variables?</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nx">hasDeclarations</span><spanclass="o">:</span><spanclass="o">-></span>
<spanclass="o">!!</span><spanclass="nx">@declaredVariables</span><spanclass="p">().</span><spanclass="nx">length</span></pre></div></td></tr><trid="section-14"><tdclass="docs"><divclass="pilwrap"><aclass="pilcrow"href="#section-14">¶</a></div><p>Return the list of variables first declared in this scope.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nx">declaredVariables</span><spanclass="o">:</span><spanclass="o">-></span>
<spanclass="nx">realVars</span><spanclass="p">.</span><spanclass="nx">sort</span><spanclass="p">().</span><spanclass="nx">concat</span><spanclass="nx">tempVars</span><spanclass="p">.</span><spanclass="nx">sort</span><spanclass="p">()</span></pre></div></td></tr><trid="section-15"><tdclass="docs"><divclass="pilwrap"><aclass="pilcrow"href="#section-15">¶</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="nx">assignedVariables</span><spanclass="o">:</span><spanclass="o">-></span>