Sophie

Sophie

distrib > Mageia > 7 > i586 > by-pkgid > 90f42621c55a32b656e489cf8cdef274 > files > 107

coffee-script-doc-1.10.0-8.mga7.noarch.rpm

<!DOCTYPE html>

<html>
<head>
  <title>nodes.coffee</title>
  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  <meta name="viewport" content="width=device-width, target-densitydpi=160dpi, initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">
  <link rel="stylesheet" media="all" href="docco.css" />
</head>
<body>
  <div id="container">
    <div id="background"></div>
    
      <ul id="jump_to">
        <li>
          <a class="large" href="javascript:void(0);">Jump To &hellip;</a>
          <a class="small" href="javascript:void(0);">+</a>
          <div id="jump_wrapper">
          <div id="jump_page_wrapper">
            <div id="jump_page">
              
                
                <a class="source" href="browser.html">
                  browser.coffee
                </a>
              
                
                <a class="source" href="cake.html">
                  cake.coffee
                </a>
              
                
                <a class="source" href="coffee-script.html">
                  coffee-script.coffee
                </a>
              
                
                <a class="source" href="command.html">
                  command.coffee
                </a>
              
                
                <a class="source" href="grammar.html">
                  grammar.coffee
                </a>
              
                
                <a class="source" href="helpers.html">
                  helpers.coffee
                </a>
              
                
                <a class="source" href="index.html">
                  index.coffee
                </a>
              
                
                <a class="source" href="lexer.html">
                  lexer.coffee
                </a>
              
                
                <a class="source" href="nodes.html">
                  nodes.coffee
                </a>
              
                
                <a class="source" href="optparse.html">
                  optparse.coffee
                </a>
              
                
                <a class="source" href="register.html">
                  register.coffee
                </a>
              
                
                <a class="source" href="repl.html">
                  repl.coffee
                </a>
              
                
                <a class="source" href="rewriter.html">
                  rewriter.coffee
                </a>
              
                
                <a class="source" href="scope.html">
                  scope.litcoffee
                </a>
              
                
                <a class="source" href="sourcemap.html">
                  sourcemap.litcoffee
                </a>
              
            </div>
          </div>
        </li>
      </ul>
    
    <ul class="sections">
        
          <li id="title">
              <div class="annotation">
                  <h1>nodes.coffee</h1>
              </div>
          </li>
        
        
        
        <li id="section-1">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-1">&#182;</a>
              </div>
              <p><code>nodes.coffee</code> contains all of the node classes for the syntax tree. Most
nodes are created as the result of actions in the <a href="grammar.html">grammar</a>,
but some are created by other nodes as a method of code generation. To convert
the syntax tree into a string of JavaScript code, call <code>compile()</code> on the root.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>
Error.stackTraceLimit = Infinity

{Scope} = <span class="hljs-built_in">require</span> <span class="hljs-string">'./scope'</span>
{RESERVED, STRICT_PROSCRIBED} = <span class="hljs-built_in">require</span> <span class="hljs-string">'./lexer'</span></pre></div></div>
            
        </li>
        
        
        <li id="section-2">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-2">&#182;</a>
              </div>
              <p>Import the helpers we plan to use.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>{compact, flatten, extend, merge, del, starts, ends, some,
addLocationDataFn, locationDataToString, throwSyntaxError} = <span class="hljs-built_in">require</span> <span class="hljs-string">'./helpers'</span></pre></div></div>
            
        </li>
        
        
        <li id="section-3">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-3">&#182;</a>
              </div>
              <p>Functions required by parser</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.extend = extend
<span class="hljs-built_in">exports</span>.addLocationDataFn = addLocationDataFn</pre></div></div>
            
        </li>
        
        
        <li id="section-4">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-4">&#182;</a>
              </div>
              <p>Constant functions for nodes that don’t need customization.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">YES</span>     = -&gt;</span> <span class="hljs-literal">yes</span>
<span class="hljs-function"><span class="hljs-title">NO</span>      = -&gt;</span> <span class="hljs-literal">no</span>
<span class="hljs-function"><span class="hljs-title">THIS</span>    = -&gt;</span> <span class="hljs-keyword">this</span>
<span class="hljs-function"><span class="hljs-title">NEGATE</span>  = -&gt;</span> <span class="hljs-property">@negated</span> = <span class="hljs-keyword">not</span> <span class="hljs-property">@negated</span>; <span class="hljs-keyword">this</span></pre></div></div>
            
        </li>
        
        
        <li id="section-5">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-5">&#182;</a>
              </div>
              <h3 id="codefragment">CodeFragment</h3>

            </div>
            
        </li>
        
        
        <li id="section-6">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-6">&#182;</a>
              </div>
              <p>The various nodes defined below all compile to a collection of <strong>CodeFragment</strong> objects.
A CodeFragments is a block of generated code, and the location in the source file where the code
came from. CodeFragments can be assembled together into working code just by catting together
all the CodeFragments’ <code>code</code> snippets, in order.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.CodeFragment = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">CodeFragment</span></span>
  <span class="hljs-attribute">constructor</span>: <span class="hljs-function"><span class="hljs-params">(parent, code)</span> -&gt;</span>
    <span class="hljs-property">@code</span> = <span class="hljs-string">"<span class="hljs-subst">#{code}</span>"</span>
    <span class="hljs-property">@locationData</span> = parent?.locationData
    <span class="hljs-property">@type</span> = parent?.constructor?.name <span class="hljs-keyword">or</span> <span class="hljs-string">'unknown'</span>

  <span class="hljs-attribute">toString</span>:<span class="hljs-function">   -&gt;</span>
    <span class="hljs-string">"<span class="hljs-subst">#{<span class="hljs-property">@code</span>}</span><span class="hljs-subst">#{<span class="hljs-keyword">if</span> <span class="hljs-property">@locationData</span> <span class="hljs-keyword">then</span> <span class="hljs-string">": "</span> + locationDataToString(<span class="hljs-property">@locationData</span>) <span class="hljs-keyword">else</span> <span class="hljs-string">''</span>}</span>"</span></pre></div></div>
            
        </li>
        
        
        <li id="section-7">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-7">&#182;</a>
              </div>
              <p>Convert an array of CodeFragments into a string.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">fragmentsToText</span> = <span class="hljs-params">(fragments)</span> -&gt;</span>
  (fragment.code <span class="hljs-keyword">for</span> fragment <span class="hljs-keyword">in</span> fragments).join(<span class="hljs-string">''</span>)</pre></div></div>
            
        </li>
        
        
        <li id="section-8">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-8">&#182;</a>
              </div>
              <h3 id="base">Base</h3>

            </div>
            
        </li>
        
        
        <li id="section-9">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-9">&#182;</a>
              </div>
              <p>The <strong>Base</strong> is the abstract base class for all nodes in the syntax tree.
Each subclass implements the <code>compileNode</code> method, which performs the
code generation for that node. To compile a node to JavaScript,
call <code>compile</code> on it, which wraps <code>compileNode</code> in some generic extra smarts,
to know when the generated code needs to be wrapped up in a closure.
An options hash is passed and cloned throughout, containing information about
the environment from higher in the tree (such as if a returned value is
being requested by the surrounding function), information about the current
scope, and indentation level.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.Base = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Base</span></span>

  <span class="hljs-attribute">compile</span>: <span class="hljs-function"><span class="hljs-params">(o, lvl)</span> -&gt;</span>
    fragmentsToText <span class="hljs-property">@compileToFragments</span> o, lvl</pre></div></div>
            
        </li>
        
        
        <li id="section-10">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-10">&#182;</a>
              </div>
              <p>Common logic for determining whether to wrap this node in a closure before
compiling it, or to compile directly. We need to wrap if this node is a
<em>statement</em>, and it’s not a <em>pureStatement</em>, and we’re not at
the top level of a block (which would be unnecessary), and we haven’t
already been asked to return the result (because statements know how to
return results).</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">compileToFragments</span>: <span class="hljs-function"><span class="hljs-params">(o, lvl)</span> -&gt;</span>
    o        = extend {}, o
    o.level  = lvl <span class="hljs-keyword">if</span> lvl
    node     = <span class="hljs-property">@unfoldSoak</span>(o) <span class="hljs-keyword">or</span> <span class="hljs-keyword">this</span>
    node.tab = o.indent
    <span class="hljs-keyword">if</span> o.level <span class="hljs-keyword">is</span> LEVEL_TOP <span class="hljs-keyword">or</span> <span class="hljs-keyword">not</span> node.isStatement(o)
      node.compileNode o
    <span class="hljs-keyword">else</span>
      node.compileClosure o</pre></div></div>
            
        </li>
        
        
        <li id="section-11">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-11">&#182;</a>
              </div>
              <p>Statements converted into expressions via closure-wrapping share a scope
object with their parent closure, to preserve the expected lexical scope.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">compileClosure</span>: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-keyword">if</span> jumpNode = <span class="hljs-property">@jumps</span>()
      jumpNode.error <span class="hljs-string">'cannot use a pure statement in an expression'</span>
    o.sharedScope = <span class="hljs-literal">yes</span>
    func = <span class="hljs-keyword">new</span> Code [], Block.wrap [<span class="hljs-keyword">this</span>]
    args = []
    <span class="hljs-keyword">if</span> (argumentsNode = <span class="hljs-property">@contains</span> isLiteralArguments) <span class="hljs-keyword">or</span> <span class="hljs-property">@contains</span> isLiteralThis
      args = [<span class="hljs-keyword">new</span> Literal <span class="hljs-string">'this'</span>]
      <span class="hljs-keyword">if</span> argumentsNode
        meth = <span class="hljs-string">'apply'</span>
        args.push <span class="hljs-keyword">new</span> Literal <span class="hljs-string">'arguments'</span>
      <span class="hljs-keyword">else</span>
        meth = <span class="hljs-string">'call'</span>
      func = <span class="hljs-keyword">new</span> Value func, [<span class="hljs-keyword">new</span> Access <span class="hljs-keyword">new</span> Literal meth]
    parts = (<span class="hljs-keyword">new</span> Call func, args).compileNode o
    <span class="hljs-keyword">if</span> func.isGenerator <span class="hljs-keyword">or</span> func.base?.isGenerator
      parts.unshift <span class="hljs-property">@makeCode</span> <span class="hljs-string">"(yield* "</span>
      parts.push    <span class="hljs-property">@makeCode</span> <span class="hljs-string">")"</span>
    parts</pre></div></div>
            
        </li>
        
        
        <li id="section-12">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-12">&#182;</a>
              </div>
              <p>If the code generation wishes to use the result of a complex expression
in multiple places, ensure that the expression is only ever evaluated once,
by assigning it to a temporary variable. Pass a level to precompile.</p>
<p>If <code>level</code> is passed, then returns <code>[val, ref]</code>, where <code>val</code> is the compiled value, and <code>ref</code>
is the compiled reference. If <code>level</code> is not passed, this returns <code>[val, ref]</code> where
the two values are raw nodes which have not been compiled.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">cache</span>: <span class="hljs-function"><span class="hljs-params">(o, level, isComplex)</span> -&gt;</span>
    complex = <span class="hljs-keyword">if</span> isComplex? <span class="hljs-keyword">then</span> isComplex <span class="hljs-keyword">this</span> <span class="hljs-keyword">else</span> <span class="hljs-property">@isComplex</span>()
    <span class="hljs-keyword">if</span> complex
      ref = <span class="hljs-keyword">new</span> Literal o.scope.freeVariable <span class="hljs-string">'ref'</span>
      sub = <span class="hljs-keyword">new</span> Assign ref, <span class="hljs-keyword">this</span>
      <span class="hljs-keyword">if</span> level <span class="hljs-keyword">then</span> [sub.compileToFragments(o, level), [<span class="hljs-property">@makeCode</span>(ref.value)]] <span class="hljs-keyword">else</span> [sub, ref]
    <span class="hljs-keyword">else</span>
      ref = <span class="hljs-keyword">if</span> level <span class="hljs-keyword">then</span> <span class="hljs-property">@compileToFragments</span> o, level <span class="hljs-keyword">else</span> <span class="hljs-keyword">this</span>
      [ref, ref]

  <span class="hljs-attribute">cacheToCodeFragments</span>: <span class="hljs-function"><span class="hljs-params">(cacheValues)</span> -&gt;</span>
    [fragmentsToText(cacheValues[<span class="hljs-number">0</span>]), fragmentsToText(cacheValues[<span class="hljs-number">1</span>])]</pre></div></div>
            
        </li>
        
        
        <li id="section-13">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-13">&#182;</a>
              </div>
              <p>Construct a node that returns the current node’s result.
Note that this is overridden for smarter behavior for
many statement nodes (e.g. If, For)…</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">makeReturn</span>: <span class="hljs-function"><span class="hljs-params">(res)</span> -&gt;</span>
    me = <span class="hljs-property">@unwrapAll</span>()
    <span class="hljs-keyword">if</span> res
      <span class="hljs-keyword">new</span> Call <span class="hljs-keyword">new</span> Literal(<span class="hljs-string">"<span class="hljs-subst">#{res}</span>.push"</span>), [me]
    <span class="hljs-keyword">else</span>
      <span class="hljs-keyword">new</span> Return me</pre></div></div>
            
        </li>
        
        
        <li id="section-14">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-14">&#182;</a>
              </div>
              <p>Does this node, or any of its children, contain a node of a certain kind?
Recursively traverses down the <em>children</em> nodes and returns the first one
that verifies <code>pred</code>. Otherwise return undefined. <code>contains</code> does not cross
scope boundaries.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">contains</span>: <span class="hljs-function"><span class="hljs-params">(pred)</span> -&gt;</span>
    node = <span class="hljs-literal">undefined</span>
    <span class="hljs-property">@traverseChildren</span> <span class="hljs-literal">no</span>, <span class="hljs-function"><span class="hljs-params">(n)</span> -&gt;</span>
      <span class="hljs-keyword">if</span> pred n
        node = n
        <span class="hljs-keyword">return</span> <span class="hljs-literal">no</span>
    node</pre></div></div>
            
        </li>
        
        
        <li id="section-15">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-15">&#182;</a>
              </div>
              <p>Pull out the last non-comment node of a node list.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">lastNonComment</span>: <span class="hljs-function"><span class="hljs-params">(list)</span> -&gt;</span>
    i = list.length
    <span class="hljs-keyword">return</span> list[i] <span class="hljs-keyword">while</span> i-- <span class="hljs-keyword">when</span> list[i] <span class="hljs-keyword">not</span> <span class="hljs-keyword">instanceof</span> Comment
    <span class="hljs-literal">null</span></pre></div></div>
            
        </li>
        
        
        <li id="section-16">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-16">&#182;</a>
              </div>
              <p><code>toString</code> representation of the node, for inspecting the parse tree.
This is what <code>coffee --nodes</code> prints out.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">toString</span>: <span class="hljs-function"><span class="hljs-params">(idt = <span class="hljs-string">''</span>, name = <span class="hljs-property">@constructor</span>.name)</span> -&gt;</span>
    tree = <span class="hljs-string">'\n'</span> + idt + name
    tree += <span class="hljs-string">'?'</span> <span class="hljs-keyword">if</span> <span class="hljs-property">@soak</span>
    <span class="hljs-property">@eachChild</span> <span class="hljs-function"><span class="hljs-params">(node)</span> -&gt;</span> tree += node.toString idt + TAB
    tree</pre></div></div>
            
        </li>
        
        
        <li id="section-17">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-17">&#182;</a>
              </div>
              <p>Passes each child to a function, breaking when the function returns <code>false</code>.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">eachChild</span>: <span class="hljs-function"><span class="hljs-params">(func)</span> -&gt;</span>
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span> <span class="hljs-keyword">unless</span> <span class="hljs-property">@children</span>
    <span class="hljs-keyword">for</span> attr <span class="hljs-keyword">in</span> <span class="hljs-property">@children</span> <span class="hljs-keyword">when</span> @[attr]
      <span class="hljs-keyword">for</span> child <span class="hljs-keyword">in</span> flatten [@[attr]]
        <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span> <span class="hljs-keyword">if</span> func(child) <span class="hljs-keyword">is</span> <span class="hljs-literal">false</span>
    <span class="hljs-keyword">this</span>

  <span class="hljs-attribute">traverseChildren</span>: <span class="hljs-function"><span class="hljs-params">(crossScope, func)</span> -&gt;</span>
    <span class="hljs-property">@eachChild</span> <span class="hljs-function"><span class="hljs-params">(child)</span> -&gt;</span>
      recur = func(child)
      child.traverseChildren(crossScope, func) <span class="hljs-keyword">unless</span> recur <span class="hljs-keyword">is</span> <span class="hljs-literal">no</span>

  <span class="hljs-attribute">invert</span>:<span class="hljs-function"> -&gt;</span>
    <span class="hljs-keyword">new</span> Op <span class="hljs-string">'!'</span>, <span class="hljs-keyword">this</span>

  <span class="hljs-attribute">unwrapAll</span>:<span class="hljs-function"> -&gt;</span>
    node = <span class="hljs-keyword">this</span>
    <span class="hljs-keyword">continue</span> <span class="hljs-keyword">until</span> node <span class="hljs-keyword">is</span> node = node.unwrap()
    node</pre></div></div>
            
        </li>
        
        
        <li id="section-18">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-18">&#182;</a>
              </div>
              <p>Default implementations of the common node properties and methods. Nodes
will override these with custom logic, if needed.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">children</span>: []

  isStatement     : NO
  jumps           : NO
  isComplex       : YES
  isChainable     : NO
  isAssignable    : NO

  unwrap     : THIS
  unfoldSoak : NO</pre></div></div>
            
        </li>
        
        
        <li id="section-19">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-19">&#182;</a>
              </div>
              <p>Is this node used to assign a certain variable?</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">assigns</span>: NO</pre></div></div>
            
        </li>
        
        
        <li id="section-20">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-20">&#182;</a>
              </div>
              <p>For this node and all descendents, set the location data to <code>locationData</code>
if the location data is not already set.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">updateLocationDataIfMissing</span>: <span class="hljs-function"><span class="hljs-params">(locationData)</span> -&gt;</span>
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span> <span class="hljs-keyword">if</span> <span class="hljs-property">@locationData</span>
    <span class="hljs-property">@locationData</span> = locationData

    <span class="hljs-property">@eachChild</span> <span class="hljs-function"><span class="hljs-params">(child)</span> -&gt;</span>
      child.updateLocationDataIfMissing locationData</pre></div></div>
            
        </li>
        
        
        <li id="section-21">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-21">&#182;</a>
              </div>
              <p>Throw a SyntaxError associated with this node’s location.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">error</span>: <span class="hljs-function"><span class="hljs-params">(message)</span> -&gt;</span>
    throwSyntaxError message, <span class="hljs-property">@locationData</span>

  <span class="hljs-attribute">makeCode</span>: <span class="hljs-function"><span class="hljs-params">(code)</span> -&gt;</span>
    <span class="hljs-keyword">new</span> CodeFragment <span class="hljs-keyword">this</span>, code

  <span class="hljs-attribute">wrapInBraces</span>: <span class="hljs-function"><span class="hljs-params">(fragments)</span> -&gt;</span>
    [].concat <span class="hljs-property">@makeCode</span>(<span class="hljs-string">'('</span>), fragments, <span class="hljs-property">@makeCode</span>(<span class="hljs-string">')'</span>)</pre></div></div>
            
        </li>
        
        
        <li id="section-22">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-22">&#182;</a>
              </div>
              <p><code>fragmentsList</code> is an array of arrays of fragments. Each array in fragmentsList will be
concatonated together, with <code>joinStr</code> added in between each, to produce a final flat array
of fragments.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">joinFragmentArrays</span>: <span class="hljs-function"><span class="hljs-params">(fragmentsList, joinStr)</span> -&gt;</span>
    answer = []
    <span class="hljs-keyword">for</span> fragments,i <span class="hljs-keyword">in</span> fragmentsList
      <span class="hljs-keyword">if</span> i <span class="hljs-keyword">then</span> answer.push <span class="hljs-property">@makeCode</span> joinStr
      answer = answer.concat fragments
    answer</pre></div></div>
            
        </li>
        
        
        <li id="section-23">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-23">&#182;</a>
              </div>
              <h3 id="block">Block</h3>

            </div>
            
        </li>
        
        
        <li id="section-24">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-24">&#182;</a>
              </div>
              <p>The block is the list of expressions that forms the body of an
indented block of code — the implementation of a function, a clause in an
<code>if</code>, <code>switch</code>, or <code>try</code>, and so on…</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.Block = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Block</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  <span class="hljs-attribute">constructor</span>: <span class="hljs-function"><span class="hljs-params">(nodes)</span> -&gt;</span>
    <span class="hljs-property">@expressions</span> = compact flatten nodes <span class="hljs-keyword">or</span> []

  <span class="hljs-attribute">children</span>: [<span class="hljs-string">'expressions'</span>]</pre></div></div>
            
        </li>
        
        
        <li id="section-25">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-25">&#182;</a>
              </div>
              <p>Tack an expression on to the end of this expression list.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">push</span>: <span class="hljs-function"><span class="hljs-params">(node)</span> -&gt;</span>
    <span class="hljs-property">@expressions</span>.push node
    <span class="hljs-keyword">this</span></pre></div></div>
            
        </li>
        
        
        <li id="section-26">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-26">&#182;</a>
              </div>
              <p>Remove and return the last expression of this expression list.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">pop</span>:<span class="hljs-function"> -&gt;</span>
    <span class="hljs-property">@expressions</span>.pop()</pre></div></div>
            
        </li>
        
        
        <li id="section-27">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-27">&#182;</a>
              </div>
              <p>Add an expression at the beginning of this expression list.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">unshift</span>: <span class="hljs-function"><span class="hljs-params">(node)</span> -&gt;</span>
    <span class="hljs-property">@expressions</span>.unshift node
    <span class="hljs-keyword">this</span></pre></div></div>
            
        </li>
        
        
        <li id="section-28">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-28">&#182;</a>
              </div>
              <p>If this Block consists of just a single node, unwrap it by pulling
it back out.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">unwrap</span>:<span class="hljs-function"> -&gt;</span>
    <span class="hljs-keyword">if</span> <span class="hljs-property">@expressions</span>.length <span class="hljs-keyword">is</span> <span class="hljs-number">1</span> <span class="hljs-keyword">then</span> <span class="hljs-property">@expressions</span>[<span class="hljs-number">0</span>] <span class="hljs-keyword">else</span> <span class="hljs-keyword">this</span></pre></div></div>
            
        </li>
        
        
        <li id="section-29">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-29">&#182;</a>
              </div>
              <p>Is this an empty block of code?</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">isEmpty</span>:<span class="hljs-function"> -&gt;</span>
    <span class="hljs-keyword">not</span> <span class="hljs-property">@expressions</span>.length

  <span class="hljs-attribute">isStatement</span>: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-keyword">for</span> exp <span class="hljs-keyword">in</span> <span class="hljs-property">@expressions</span> <span class="hljs-keyword">when</span> exp.isStatement o
      <span class="hljs-keyword">return</span> <span class="hljs-literal">yes</span>
    <span class="hljs-literal">no</span>

  <span class="hljs-attribute">jumps</span>: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-keyword">for</span> exp <span class="hljs-keyword">in</span> <span class="hljs-property">@expressions</span>
      <span class="hljs-keyword">return</span> jumpNode <span class="hljs-keyword">if</span> jumpNode = exp.jumps o</pre></div></div>
            
        </li>
        
        
        <li id="section-30">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-30">&#182;</a>
              </div>
              <p>A Block node does not return its entire body, rather it
ensures that the final expression is returned.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">makeReturn</span>: <span class="hljs-function"><span class="hljs-params">(res)</span> -&gt;</span>
    len = <span class="hljs-property">@expressions</span>.length
    <span class="hljs-keyword">while</span> len--
      expr = <span class="hljs-property">@expressions</span>[len]
      <span class="hljs-keyword">if</span> expr <span class="hljs-keyword">not</span> <span class="hljs-keyword">instanceof</span> Comment
        <span class="hljs-property">@expressions</span>[len] = expr.makeReturn res
        <span class="hljs-property">@expressions</span>.splice(len, <span class="hljs-number">1</span>) <span class="hljs-keyword">if</span> expr <span class="hljs-keyword">instanceof</span> Return <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> expr.expression
        <span class="hljs-keyword">break</span>
    <span class="hljs-keyword">this</span></pre></div></div>
            
        </li>
        
        
        <li id="section-31">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-31">&#182;</a>
              </div>
              <p>A <strong>Block</strong> is the only node that can serve as the root.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">compileToFragments</span>: <span class="hljs-function"><span class="hljs-params">(o = {}, level)</span> -&gt;</span>
    <span class="hljs-keyword">if</span> o.scope <span class="hljs-keyword">then</span> <span class="hljs-keyword">super</span> o, level <span class="hljs-keyword">else</span> <span class="hljs-property">@compileRoot</span> o</pre></div></div>
            
        </li>
        
        
        <li id="section-32">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-32">&#182;</a>
              </div>
              <p>Compile all expressions within the <strong>Block</strong> body. If we need to
return the result, and it’s an expression, simply return it. If it’s a
statement, ask the statement to do so.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">compileNode</span>: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-property">@tab</span>  = o.indent
    top   = o.level <span class="hljs-keyword">is</span> LEVEL_TOP
    compiledNodes = []

    <span class="hljs-keyword">for</span> node, index <span class="hljs-keyword">in</span> <span class="hljs-property">@expressions</span>

      node = node.unwrapAll()
      node = (node.unfoldSoak(o) <span class="hljs-keyword">or</span> node)
      <span class="hljs-keyword">if</span> node <span class="hljs-keyword">instanceof</span> Block</pre></div></div>
            
        </li>
        
        
        <li id="section-33">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-33">&#182;</a>
              </div>
              <p>This is a nested block. We don’t do anything special here like enclose
it in a new scope; we just compile the statements in this block along with
our own</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>        compiledNodes.push node.compileNode o
      <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> top
        node.front = <span class="hljs-literal">true</span>
        fragments = node.compileToFragments o
        <span class="hljs-keyword">unless</span> node.isStatement o
          fragments.unshift <span class="hljs-property">@makeCode</span> <span class="hljs-string">"<span class="hljs-subst">#{<span class="hljs-property">@tab</span>}</span>"</span>
          fragments.push <span class="hljs-property">@makeCode</span> <span class="hljs-string">";"</span>
        compiledNodes.push fragments
      <span class="hljs-keyword">else</span>
        compiledNodes.push node.compileToFragments o, LEVEL_LIST
    <span class="hljs-keyword">if</span> top
      <span class="hljs-keyword">if</span> <span class="hljs-property">@spaced</span>
        <span class="hljs-keyword">return</span> [].concat <span class="hljs-property">@joinFragmentArrays</span>(compiledNodes, <span class="hljs-string">'\n\n'</span>), <span class="hljs-property">@makeCode</span>(<span class="hljs-string">"\n"</span>)
      <span class="hljs-keyword">else</span>
        <span class="hljs-keyword">return</span> <span class="hljs-property">@joinFragmentArrays</span>(compiledNodes, <span class="hljs-string">'\n'</span>)
    <span class="hljs-keyword">if</span> compiledNodes.length
      answer = <span class="hljs-property">@joinFragmentArrays</span>(compiledNodes, <span class="hljs-string">', '</span>)
    <span class="hljs-keyword">else</span>
      answer = [<span class="hljs-property">@makeCode</span> <span class="hljs-string">"void 0"</span>]
    <span class="hljs-keyword">if</span> compiledNodes.length &gt; <span class="hljs-number">1</span> <span class="hljs-keyword">and</span> o.level &gt;= LEVEL_LIST <span class="hljs-keyword">then</span> <span class="hljs-property">@wrapInBraces</span> answer <span class="hljs-keyword">else</span> answer</pre></div></div>
            
        </li>
        
        
        <li id="section-34">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-34">&#182;</a>
              </div>
              <p>If we happen to be the top-level <strong>Block</strong>, wrap everything in
a safety closure, unless requested not to.
It would be better not to generate them in the first place, but for now,
clean up obvious double-parentheses.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">compileRoot</span>: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    o.indent  = <span class="hljs-keyword">if</span> o.bare <span class="hljs-keyword">then</span> <span class="hljs-string">''</span> <span class="hljs-keyword">else</span> TAB
    o.level   = LEVEL_TOP
    <span class="hljs-property">@spaced</span>   = <span class="hljs-literal">yes</span>
    o.scope   = <span class="hljs-keyword">new</span> Scope <span class="hljs-literal">null</span>, <span class="hljs-keyword">this</span>, <span class="hljs-literal">null</span>, o.referencedVars ? []</pre></div></div>
            
        </li>
        
        
        <li id="section-35">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-35">&#182;</a>
              </div>
              <p>Mark given local variables in the root scope as parameters so they don’t
end up being declared on this block.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    o.scope.parameter name <span class="hljs-keyword">for</span> name <span class="hljs-keyword">in</span> o.locals <span class="hljs-keyword">or</span> []
    prelude   = []
    <span class="hljs-keyword">unless</span> o.bare
      preludeExps = <span class="hljs-keyword">for</span> exp, i <span class="hljs-keyword">in</span> <span class="hljs-property">@expressions</span>
        <span class="hljs-keyword">break</span> <span class="hljs-keyword">unless</span> exp.unwrap() <span class="hljs-keyword">instanceof</span> Comment
        exp
      rest = <span class="hljs-property">@expressions</span>[preludeExps.length...]
      <span class="hljs-property">@expressions</span> = preludeExps
      <span class="hljs-keyword">if</span> preludeExps.length
        prelude = <span class="hljs-property">@compileNode</span> merge(o, <span class="hljs-attribute">indent</span>: <span class="hljs-string">''</span>)
        prelude.push <span class="hljs-property">@makeCode</span> <span class="hljs-string">"\n"</span>
      <span class="hljs-property">@expressions</span> = rest
    fragments = <span class="hljs-property">@compileWithDeclarations</span> o
    <span class="hljs-keyword">return</span> fragments <span class="hljs-keyword">if</span> o.bare
    [].concat prelude, <span class="hljs-property">@makeCode</span>(<span class="hljs-string">"(function() {\n"</span>), fragments, <span class="hljs-property">@makeCode</span>(<span class="hljs-string">"\n}).call(this);\n"</span>)</pre></div></div>
            
        </li>
        
        
        <li id="section-36">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-36">&#182;</a>
              </div>
              <p>Compile the expressions body for the contents of a function, with
declarations of all inner variables pushed up to the top.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">compileWithDeclarations</span>: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    fragments = []
    post = []
    <span class="hljs-keyword">for</span> exp, i <span class="hljs-keyword">in</span> <span class="hljs-property">@expressions</span>
      exp = exp.unwrap()
      <span class="hljs-keyword">break</span> <span class="hljs-keyword">unless</span> exp <span class="hljs-keyword">instanceof</span> Comment <span class="hljs-keyword">or</span> exp <span class="hljs-keyword">instanceof</span> Literal
    o = merge(o, <span class="hljs-attribute">level</span>: LEVEL_TOP)
    <span class="hljs-keyword">if</span> i
      rest = <span class="hljs-property">@expressions</span>.splice i, <span class="hljs-number">9e9</span>
      [spaced,    <span class="hljs-property">@spaced</span>] = [<span class="hljs-property">@spaced</span>, <span class="hljs-literal">no</span>]
      [fragments, <span class="hljs-property">@spaced</span>] = [<span class="hljs-property">@compileNode</span>(o), spaced]
      <span class="hljs-property">@expressions</span> = rest
    post = <span class="hljs-property">@compileNode</span> o
    {scope} = o
    <span class="hljs-keyword">if</span> scope.expressions <span class="hljs-keyword">is</span> <span class="hljs-keyword">this</span>
      declars = o.scope.hasDeclarations()
      assigns = scope.hasAssignments
      <span class="hljs-keyword">if</span> declars <span class="hljs-keyword">or</span> assigns
        fragments.push <span class="hljs-property">@makeCode</span> <span class="hljs-string">'\n'</span> <span class="hljs-keyword">if</span> i
        fragments.push <span class="hljs-property">@makeCode</span> <span class="hljs-string">"<span class="hljs-subst">#{<span class="hljs-property">@tab</span>}</span>var "</span>
        <span class="hljs-keyword">if</span> declars
          fragments.push <span class="hljs-property">@makeCode</span> scope.declaredVariables().join(<span class="hljs-string">', '</span>)
        <span class="hljs-keyword">if</span> assigns
          fragments.push <span class="hljs-property">@makeCode</span> <span class="hljs-string">",\n<span class="hljs-subst">#{<span class="hljs-property">@tab</span> + TAB}</span>"</span> <span class="hljs-keyword">if</span> declars
          fragments.push <span class="hljs-property">@makeCode</span> scope.assignedVariables().join(<span class="hljs-string">",\n<span class="hljs-subst">#{<span class="hljs-property">@tab</span> + TAB}</span>"</span>)
        fragments.push <span class="hljs-property">@makeCode</span> <span class="hljs-string">";\n<span class="hljs-subst">#{<span class="hljs-keyword">if</span> <span class="hljs-property">@spaced</span> <span class="hljs-keyword">then</span> <span class="hljs-string">'\n'</span> <span class="hljs-keyword">else</span> <span class="hljs-string">''</span>}</span>"</span>
      <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> fragments.length <span class="hljs-keyword">and</span> post.length
        fragments.push <span class="hljs-property">@makeCode</span> <span class="hljs-string">"\n"</span>
    fragments.concat post</pre></div></div>
            
        </li>
        
        
        <li id="section-37">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-37">&#182;</a>
              </div>
              <p>Wrap up the given nodes as a <strong>Block</strong>, unless it already happens
to be one.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  <span class="hljs-property">@wrap</span>: <span class="hljs-function"><span class="hljs-params">(nodes)</span> -&gt;</span>
    <span class="hljs-keyword">return</span> nodes[<span class="hljs-number">0</span>] <span class="hljs-keyword">if</span> nodes.length <span class="hljs-keyword">is</span> <span class="hljs-number">1</span> <span class="hljs-keyword">and</span> nodes[<span class="hljs-number">0</span>] <span class="hljs-keyword">instanceof</span> Block
    <span class="hljs-keyword">new</span> Block nodes</pre></div></div>
            
        </li>
        
        
        <li id="section-38">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-38">&#182;</a>
              </div>
              <h3 id="literal">Literal</h3>

            </div>
            
        </li>
        
        
        <li id="section-39">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-39">&#182;</a>
              </div>
              <p>Literals are static values that can be passed through directly into
JavaScript without translation, such as: strings, numbers,
<code>true</code>, <code>false</code>, <code>null</code>…</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.Literal = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Literal</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  <span class="hljs-attribute">constructor</span>: <span class="hljs-function"><span class="hljs-params">(<span class="hljs-property">@value</span>)</span> -&gt;</span>

  <span class="hljs-attribute">makeReturn</span>:<span class="hljs-function"> -&gt;</span>
    <span class="hljs-keyword">if</span> <span class="hljs-property">@isStatement</span>() <span class="hljs-keyword">then</span> <span class="hljs-keyword">this</span> <span class="hljs-keyword">else</span> <span class="hljs-keyword">super</span>

  <span class="hljs-attribute">isAssignable</span>:<span class="hljs-function"> -&gt;</span>
    IDENTIFIER.test <span class="hljs-property">@value</span>

  <span class="hljs-attribute">isStatement</span>:<span class="hljs-function"> -&gt;</span>
    <span class="hljs-property">@value</span> <span class="hljs-keyword">in</span> [<span class="hljs-string">'break'</span>, <span class="hljs-string">'continue'</span>, <span class="hljs-string">'debugger'</span>]

  <span class="hljs-attribute">isComplex</span>: NO

  <span class="hljs-attribute">assigns</span>: <span class="hljs-function"><span class="hljs-params">(name)</span> -&gt;</span>
    name <span class="hljs-keyword">is</span> <span class="hljs-property">@value</span>

  <span class="hljs-attribute">jumps</span>: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span> <span class="hljs-keyword">if</span> <span class="hljs-property">@value</span> <span class="hljs-keyword">is</span> <span class="hljs-string">'break'</span> <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> (o?.<span class="hljs-keyword">loop</span> <span class="hljs-keyword">or</span> o?.block)
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span> <span class="hljs-keyword">if</span> <span class="hljs-property">@value</span> <span class="hljs-keyword">is</span> <span class="hljs-string">'continue'</span> <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> o?.<span class="hljs-keyword">loop</span>

  <span class="hljs-attribute">compileNode</span>: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    code = <span class="hljs-keyword">if</span> <span class="hljs-property">@value</span> <span class="hljs-keyword">is</span> <span class="hljs-string">'this'</span>
      <span class="hljs-keyword">if</span> o.scope.method?.bound <span class="hljs-keyword">then</span> o.scope.method.context <span class="hljs-keyword">else</span> <span class="hljs-property">@value</span>
    <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> <span class="hljs-property">@value</span>.reserved
      <span class="hljs-string">"\"<span class="hljs-subst">#{<span class="hljs-property">@value</span>}</span>\""</span>
    <span class="hljs-keyword">else</span>
      <span class="hljs-property">@value</span>
    answer = <span class="hljs-keyword">if</span> <span class="hljs-property">@isStatement</span>() <span class="hljs-keyword">then</span> <span class="hljs-string">"<span class="hljs-subst">#{<span class="hljs-property">@tab</span>}</span><span class="hljs-subst">#{code}</span>;"</span> <span class="hljs-keyword">else</span> code
    [<span class="hljs-property">@makeCode</span> answer]

  <span class="hljs-attribute">toString</span>:<span class="hljs-function"> -&gt;</span>
    <span class="hljs-string">' "'</span> + <span class="hljs-property">@value</span> + <span class="hljs-string">'"'</span>

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">exports</span>.<span class="hljs-title">Undefined</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  <span class="hljs-attribute">isAssignable</span>: NO
  <span class="hljs-attribute">isComplex</span>: NO
  <span class="hljs-attribute">compileNode</span>: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    [<span class="hljs-property">@makeCode</span> <span class="hljs-keyword">if</span> o.level &gt;= LEVEL_ACCESS <span class="hljs-keyword">then</span> <span class="hljs-string">'(void 0)'</span> <span class="hljs-keyword">else</span> <span class="hljs-string">'void 0'</span>]

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">exports</span>.<span class="hljs-title">Null</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  <span class="hljs-attribute">isAssignable</span>: NO
  <span class="hljs-attribute">isComplex</span>: NO
  <span class="hljs-attribute">compileNode</span>:<span class="hljs-function"> -&gt;</span> [<span class="hljs-property">@makeCode</span> <span class="hljs-string">"null"</span>]

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">exports</span>.<span class="hljs-title">Bool</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  <span class="hljs-attribute">isAssignable</span>: NO
  <span class="hljs-attribute">isComplex</span>: NO
  <span class="hljs-attribute">compileNode</span>:<span class="hljs-function"> -&gt;</span> [<span class="hljs-property">@makeCode</span> <span class="hljs-property">@val</span>]
  <span class="hljs-attribute">constructor</span>: <span class="hljs-function"><span class="hljs-params">(<span class="hljs-property">@val</span>)</span> -&gt;</span></pre></div></div>
            
        </li>
        
        
        <li id="section-40">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-40">&#182;</a>
              </div>
              <h3 id="return">Return</h3>

            </div>
            
        </li>
        
        
        <li id="section-41">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-41">&#182;</a>
              </div>
              <p>A <code>return</code> is a <em>pureStatement</em> — wrapping it in a closure wouldn’t
make sense.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.Return = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Return</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  <span class="hljs-attribute">constructor</span>: <span class="hljs-function"><span class="hljs-params">(<span class="hljs-property">@expression</span>)</span> -&gt;</span>

  <span class="hljs-attribute">children</span>: [<span class="hljs-string">'expression'</span>]

  <span class="hljs-attribute">isStatement</span>:     YES
  <span class="hljs-attribute">makeReturn</span>:      THIS
  <span class="hljs-attribute">jumps</span>:           THIS

  <span class="hljs-attribute">compileToFragments</span>: <span class="hljs-function"><span class="hljs-params">(o, level)</span> -&gt;</span>
    expr = <span class="hljs-property">@expression</span>?.makeReturn()
    <span class="hljs-keyword">if</span> expr <span class="hljs-keyword">and</span> expr <span class="hljs-keyword">not</span> <span class="hljs-keyword">instanceof</span> Return <span class="hljs-keyword">then</span> expr.compileToFragments o, level <span class="hljs-keyword">else</span> <span class="hljs-keyword">super</span> o, level

  <span class="hljs-attribute">compileNode</span>: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    answer = []
    exprIsYieldReturn = <span class="hljs-property">@expression</span>?.isYieldReturn?()</pre></div></div>
            
        </li>
        
        
        <li id="section-42">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-42">&#182;</a>
              </div>
              <p>TODO: If we call expression.compile() here twice, we’ll sometimes get back different results!</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    <span class="hljs-keyword">unless</span> exprIsYieldReturn
      answer.push <span class="hljs-property">@makeCode</span> <span class="hljs-property">@tab</span> + <span class="hljs-string">"return<span class="hljs-subst">#{<span class="hljs-keyword">if</span> <span class="hljs-property">@expression</span> <span class="hljs-keyword">then</span> <span class="hljs-string">" "</span> <span class="hljs-keyword">else</span> <span class="hljs-string">""</span>}</span>"</span>
    <span class="hljs-keyword">if</span> <span class="hljs-property">@expression</span>
      answer = answer.concat <span class="hljs-property">@expression</span>.compileToFragments o, LEVEL_PAREN
    answer.push <span class="hljs-property">@makeCode</span> <span class="hljs-string">";"</span> <span class="hljs-keyword">unless</span> exprIsYieldReturn
    <span class="hljs-keyword">return</span> answer</pre></div></div>
            
        </li>
        
        
        <li id="section-43">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-43">&#182;</a>
              </div>
              <h3 id="value">Value</h3>

            </div>
            
        </li>
        
        
        <li id="section-44">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-44">&#182;</a>
              </div>
              <p>A value, variable or literal or parenthesized, indexed or dotted into,
or vanilla.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.Value = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Value</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  <span class="hljs-attribute">constructor</span>: <span class="hljs-function"><span class="hljs-params">(base, props, tag)</span> -&gt;</span>
    <span class="hljs-keyword">return</span> base <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> props <span class="hljs-keyword">and</span> base <span class="hljs-keyword">instanceof</span> Value
    <span class="hljs-property">@base</span>       = base
    <span class="hljs-property">@properties</span> = props <span class="hljs-keyword">or</span> []
    @[tag]      = <span class="hljs-literal">true</span> <span class="hljs-keyword">if</span> tag
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>

  <span class="hljs-attribute">children</span>: [<span class="hljs-string">'base'</span>, <span class="hljs-string">'properties'</span>]</pre></div></div>
            
        </li>
        
        
        <li id="section-45">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-45">&#182;</a>
              </div>
              <p>Add a property (or <em>properties</em> ) <code>Access</code> to the list.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">add</span>: <span class="hljs-function"><span class="hljs-params">(props)</span> -&gt;</span>
    <span class="hljs-property">@properties</span> = <span class="hljs-property">@properties</span>.concat props
    <span class="hljs-keyword">this</span>

  <span class="hljs-attribute">hasProperties</span>:<span class="hljs-function"> -&gt;</span>
    !!<span class="hljs-property">@properties</span>.length

  <span class="hljs-attribute">bareLiteral</span>: <span class="hljs-function"><span class="hljs-params">(type)</span> -&gt;</span>
    <span class="hljs-keyword">not</span> <span class="hljs-property">@properties</span>.length <span class="hljs-keyword">and</span> <span class="hljs-property">@base</span> <span class="hljs-keyword">instanceof</span> type</pre></div></div>
            
        </li>
        
        
        <li id="section-46">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-46">&#182;</a>
              </div>
              <p>Some boolean checks for the benefit of other nodes.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  isArray        :<span class="hljs-function"> -&gt;</span> <span class="hljs-property">@bareLiteral</span>(Arr)
  isRange        :<span class="hljs-function"> -&gt;</span> <span class="hljs-property">@bareLiteral</span>(Range)
  isComplex      :<span class="hljs-function"> -&gt;</span> <span class="hljs-property">@hasProperties</span>() <span class="hljs-keyword">or</span> <span class="hljs-property">@base</span>.isComplex()
  isAssignable   :<span class="hljs-function"> -&gt;</span> <span class="hljs-property">@hasProperties</span>() <span class="hljs-keyword">or</span> <span class="hljs-property">@base</span>.isAssignable()
  isSimpleNumber :<span class="hljs-function"> -&gt;</span> <span class="hljs-property">@bareLiteral</span>(Literal) <span class="hljs-keyword">and</span> SIMPLENUM.test <span class="hljs-property">@base</span>.value
  isString       :<span class="hljs-function"> -&gt;</span> <span class="hljs-property">@bareLiteral</span>(Literal) <span class="hljs-keyword">and</span> IS_STRING.test <span class="hljs-property">@base</span>.value
  isRegex        :<span class="hljs-function"> -&gt;</span> <span class="hljs-property">@bareLiteral</span>(Literal) <span class="hljs-keyword">and</span> IS_REGEX.test <span class="hljs-property">@base</span>.value
  isAtomic       :<span class="hljs-function"> -&gt;</span>
    <span class="hljs-keyword">for</span> node <span class="hljs-keyword">in</span> <span class="hljs-property">@properties</span>.concat <span class="hljs-property">@base</span>
      <span class="hljs-keyword">return</span> <span class="hljs-literal">no</span> <span class="hljs-keyword">if</span> node.soak <span class="hljs-keyword">or</span> node <span class="hljs-keyword">instanceof</span> Call
    <span class="hljs-literal">yes</span>

  isNotCallable  :<span class="hljs-function"> -&gt;</span> <span class="hljs-property">@isSimpleNumber</span>() <span class="hljs-keyword">or</span> <span class="hljs-property">@isString</span>() <span class="hljs-keyword">or</span> <span class="hljs-property">@isRegex</span>() <span class="hljs-keyword">or</span>
                      <span class="hljs-property">@isArray</span>() <span class="hljs-keyword">or</span> <span class="hljs-property">@isRange</span>() <span class="hljs-keyword">or</span> <span class="hljs-property">@isSplice</span>() <span class="hljs-keyword">or</span> <span class="hljs-property">@isObject</span>()

  isStatement : <span class="hljs-function"><span class="hljs-params">(o)</span>    -&gt;</span> <span class="hljs-keyword">not</span> <span class="hljs-property">@properties</span>.length <span class="hljs-keyword">and</span> <span class="hljs-property">@base</span>.isStatement o
  assigns     : <span class="hljs-function"><span class="hljs-params">(name)</span> -&gt;</span> <span class="hljs-keyword">not</span> <span class="hljs-property">@properties</span>.length <span class="hljs-keyword">and</span> <span class="hljs-property">@base</span>.assigns name
  jumps       : <span class="hljs-function"><span class="hljs-params">(o)</span>    -&gt;</span> <span class="hljs-keyword">not</span> <span class="hljs-property">@properties</span>.length <span class="hljs-keyword">and</span> <span class="hljs-property">@base</span>.jumps o

  <span class="hljs-attribute">isObject</span>: <span class="hljs-function"><span class="hljs-params">(onlyGenerated)</span> -&gt;</span>
    <span class="hljs-keyword">return</span> <span class="hljs-literal">no</span> <span class="hljs-keyword">if</span> <span class="hljs-property">@properties</span>.length
    (<span class="hljs-property">@base</span> <span class="hljs-keyword">instanceof</span> Obj) <span class="hljs-keyword">and</span> (<span class="hljs-keyword">not</span> onlyGenerated <span class="hljs-keyword">or</span> <span class="hljs-property">@base</span>.generated)

  <span class="hljs-attribute">isSplice</span>:<span class="hljs-function"> -&gt;</span>
    [..., lastProp] = <span class="hljs-property">@properties</span>
    lastProp <span class="hljs-keyword">instanceof</span> Slice

  <span class="hljs-attribute">looksStatic</span>: <span class="hljs-function"><span class="hljs-params">(className)</span> -&gt;</span>
    <span class="hljs-property">@base</span>.value <span class="hljs-keyword">is</span> className <span class="hljs-keyword">and</span> <span class="hljs-property">@properties</span>.length <span class="hljs-keyword">is</span> <span class="hljs-number">1</span> <span class="hljs-keyword">and</span>
      <span class="hljs-property">@properties</span>[<span class="hljs-number">0</span>].name?.value <span class="hljs-keyword">isnt</span> <span class="hljs-string">'prototype'</span></pre></div></div>
            
        </li>
        
        
        <li id="section-47">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-47">&#182;</a>
              </div>
              <p>The value can be unwrapped as its inner node, if there are no attached
properties.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">unwrap</span>:<span class="hljs-function"> -&gt;</span>
    <span class="hljs-keyword">if</span> <span class="hljs-property">@properties</span>.length <span class="hljs-keyword">then</span> <span class="hljs-keyword">this</span> <span class="hljs-keyword">else</span> <span class="hljs-property">@base</span></pre></div></div>
            
        </li>
        
        
        <li id="section-48">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-48">&#182;</a>
              </div>
              <p>A reference has base part (<code>this</code> value) and name part.
We cache them separately for compiling complex expressions.
<code>a()[b()] ?= c</code> -&gt; <code>(_base = a())[_name = b()] ? _base[_name] = c</code></p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">cacheReference</span>: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    [..., name] = <span class="hljs-property">@properties</span>
    <span class="hljs-keyword">if</span> <span class="hljs-property">@properties</span>.length &lt; <span class="hljs-number">2</span> <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> <span class="hljs-property">@base</span>.isComplex() <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> name?.isComplex()
      <span class="hljs-keyword">return</span> [<span class="hljs-keyword">this</span>, <span class="hljs-keyword">this</span>]  <span class="hljs-comment"># `a` `a.b`</span>
    base = <span class="hljs-keyword">new</span> Value <span class="hljs-property">@base</span>, <span class="hljs-property">@properties</span>[...-<span class="hljs-number">1</span>]
    <span class="hljs-keyword">if</span> base.isComplex()  <span class="hljs-comment"># `a().b`</span>
      bref = <span class="hljs-keyword">new</span> Literal o.scope.freeVariable <span class="hljs-string">'base'</span>
      base = <span class="hljs-keyword">new</span> Value <span class="hljs-keyword">new</span> Parens <span class="hljs-keyword">new</span> Assign bref, base
    <span class="hljs-keyword">return</span> [base, bref] <span class="hljs-keyword">unless</span> name  <span class="hljs-comment"># `a()`</span>
    <span class="hljs-keyword">if</span> name.isComplex()  <span class="hljs-comment"># `a[b()]`</span>
      nref = <span class="hljs-keyword">new</span> Literal o.scope.freeVariable <span class="hljs-string">'name'</span>
      name = <span class="hljs-keyword">new</span> Index <span class="hljs-keyword">new</span> Assign nref, name.index
      nref = <span class="hljs-keyword">new</span> Index nref
    [base.add(name), <span class="hljs-keyword">new</span> Value(bref <span class="hljs-keyword">or</span> base.base, [nref <span class="hljs-keyword">or</span> name])]</pre></div></div>
            
        </li>
        
        
        <li id="section-49">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-49">&#182;</a>
              </div>
              <p>We compile a value to JavaScript by compiling and joining each property.
Things get much more interesting if the chain of properties has <em>soak</em>
operators <code>?.</code> interspersed. Then we have to take care not to accidentally
evaluate anything twice when building the soak chain.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">compileNode</span>: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-property">@base</span>.front = <span class="hljs-property">@front</span>
    props = <span class="hljs-property">@properties</span>
    fragments = <span class="hljs-property">@base</span>.compileToFragments o, (<span class="hljs-keyword">if</span> props.length <span class="hljs-keyword">then</span> LEVEL_ACCESS <span class="hljs-keyword">else</span> <span class="hljs-literal">null</span>)
    <span class="hljs-keyword">if</span> (<span class="hljs-property">@base</span> <span class="hljs-keyword">instanceof</span> Parens <span class="hljs-keyword">or</span> props.length) <span class="hljs-keyword">and</span> SIMPLENUM.test fragmentsToText fragments
      fragments.push <span class="hljs-property">@makeCode</span> <span class="hljs-string">'.'</span>
    <span class="hljs-keyword">for</span> prop <span class="hljs-keyword">in</span> props
      fragments.push (prop.compileToFragments o)...
    fragments</pre></div></div>
            
        </li>
        
        
        <li id="section-50">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-50">&#182;</a>
              </div>
              <p>Unfold a soak into an <code>If</code>: <code>a?.b</code> -&gt; <code>a.b if a?</code></p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">unfoldSoak</span>: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-property">@unfoldedSoak</span> ?= <span class="hljs-keyword">do</span><span class="hljs-function"> =&gt;</span>
      <span class="hljs-keyword">if</span> ifn = <span class="hljs-property">@base</span>.unfoldSoak o
        ifn.body.properties.push <span class="hljs-property">@properties</span>...
        <span class="hljs-keyword">return</span> ifn
      <span class="hljs-keyword">for</span> prop, i <span class="hljs-keyword">in</span> <span class="hljs-property">@properties</span> <span class="hljs-keyword">when</span> prop.soak
        prop.soak = <span class="hljs-literal">off</span>
        fst = <span class="hljs-keyword">new</span> Value <span class="hljs-property">@base</span>, <span class="hljs-property">@properties</span>[...i]
        snd = <span class="hljs-keyword">new</span> Value <span class="hljs-property">@base</span>, <span class="hljs-property">@properties</span>[i..]
        <span class="hljs-keyword">if</span> fst.isComplex()
          ref = <span class="hljs-keyword">new</span> Literal o.scope.freeVariable <span class="hljs-string">'ref'</span>
          fst = <span class="hljs-keyword">new</span> Parens <span class="hljs-keyword">new</span> Assign ref, fst
          snd.base = ref
        <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> If <span class="hljs-keyword">new</span> Existence(fst), snd, <span class="hljs-attribute">soak</span>: <span class="hljs-literal">on</span>
      <span class="hljs-literal">no</span></pre></div></div>
            
        </li>
        
        
        <li id="section-51">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-51">&#182;</a>
              </div>
              <h3 id="comment">Comment</h3>

            </div>
            
        </li>
        
        
        <li id="section-52">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-52">&#182;</a>
              </div>
              <p>CoffeeScript passes through block comments as JavaScript block comments
at the same position.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.Comment = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Comment</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  <span class="hljs-attribute">constructor</span>: <span class="hljs-function"><span class="hljs-params">(<span class="hljs-property">@comment</span>)</span> -&gt;</span>

  <span class="hljs-attribute">isStatement</span>:     YES
  <span class="hljs-attribute">makeReturn</span>:      THIS

  <span class="hljs-attribute">compileNode</span>: <span class="hljs-function"><span class="hljs-params">(o, level)</span> -&gt;</span>
    comment = <span class="hljs-property">@comment</span>.replace <span class="hljs-regexp">/^(\s*)#(?=\s)/gm</span>, <span class="hljs-string">"$1 *"</span>
    code = <span class="hljs-string">"/*<span class="hljs-subst">#{multident comment, <span class="hljs-property">@tab</span>}</span><span class="hljs-subst">#{<span class="hljs-keyword">if</span> <span class="hljs-string">'\n'</span> <span class="hljs-keyword">in</span> comment <span class="hljs-keyword">then</span> <span class="hljs-string">"\n<span class="hljs-subst">#{<span class="hljs-property">@tab</span>}</span>"</span> <span class="hljs-keyword">else</span> <span class="hljs-string">''</span>}</span> */"</span>
    code = o.indent + code <span class="hljs-keyword">if</span> (level <span class="hljs-keyword">or</span> o.level) <span class="hljs-keyword">is</span> LEVEL_TOP
    [<span class="hljs-property">@makeCode</span>(<span class="hljs-string">"\n"</span>), <span class="hljs-property">@makeCode</span>(code)]</pre></div></div>
            
        </li>
        
        
        <li id="section-53">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-53">&#182;</a>
              </div>
              <h3 id="call">Call</h3>

            </div>
            
        </li>
        
        
        <li id="section-54">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-54">&#182;</a>
              </div>
              <p>Node for a function invocation. Takes care of converting <code>super()</code> calls into
calls against the prototype’s function of the same name.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.Call = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Call</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  <span class="hljs-attribute">constructor</span>: <span class="hljs-function"><span class="hljs-params">(variable, <span class="hljs-property">@args</span> = [], <span class="hljs-property">@soak</span>)</span> -&gt;</span>
    <span class="hljs-property">@isNew</span>    = <span class="hljs-literal">false</span>
    <span class="hljs-property">@isSuper</span>  = variable <span class="hljs-keyword">is</span> <span class="hljs-string">'super'</span>
    <span class="hljs-property">@variable</span> = <span class="hljs-keyword">if</span> <span class="hljs-property">@isSuper</span> <span class="hljs-keyword">then</span> <span class="hljs-literal">null</span> <span class="hljs-keyword">else</span> variable
    <span class="hljs-keyword">if</span> variable <span class="hljs-keyword">instanceof</span> Value <span class="hljs-keyword">and</span> variable.isNotCallable()
      variable.error <span class="hljs-string">"literal is not a function"</span>

  <span class="hljs-attribute">children</span>: [<span class="hljs-string">'variable'</span>, <span class="hljs-string">'args'</span>]</pre></div></div>
            
        </li>
        
        
        <li id="section-55">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-55">&#182;</a>
              </div>
              <p>Tag this invocation as creating a new instance.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">newInstance</span>:<span class="hljs-function"> -&gt;</span>
    base = <span class="hljs-property">@variable</span>?.base <span class="hljs-keyword">or</span> <span class="hljs-property">@variable</span>
    <span class="hljs-keyword">if</span> base <span class="hljs-keyword">instanceof</span> Call <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> base.isNew
      base.newInstance()
    <span class="hljs-keyword">else</span>
      <span class="hljs-property">@isNew</span> = <span class="hljs-literal">true</span>
    <span class="hljs-keyword">this</span></pre></div></div>
            
        </li>
        
        
        <li id="section-56">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-56">&#182;</a>
              </div>
              <p>Grab the reference to the superclass’s implementation of the current
method.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">superReference</span>: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    method = o.scope.namedMethod()
    <span class="hljs-keyword">if</span> method?.klass
      {klass, name, variable} = method
      <span class="hljs-keyword">if</span> klass.isComplex()
        bref = <span class="hljs-keyword">new</span> Literal o.scope.parent.freeVariable <span class="hljs-string">'base'</span>
        base = <span class="hljs-keyword">new</span> Value <span class="hljs-keyword">new</span> Parens <span class="hljs-keyword">new</span> Assign bref, klass
        variable.base = base
        variable.properties.splice <span class="hljs-number">0</span>, klass.properties.length
      <span class="hljs-keyword">if</span> name.isComplex() <span class="hljs-keyword">or</span> (name <span class="hljs-keyword">instanceof</span> Index <span class="hljs-keyword">and</span> name.index.isAssignable())
        nref = <span class="hljs-keyword">new</span> Literal o.scope.parent.freeVariable <span class="hljs-string">'name'</span>
        name = <span class="hljs-keyword">new</span> Index <span class="hljs-keyword">new</span> Assign nref, name.index
        variable.properties.pop()
        variable.properties.push name
      accesses = [<span class="hljs-keyword">new</span> Access <span class="hljs-keyword">new</span> Literal <span class="hljs-string">'__super__'</span>]
      accesses.push <span class="hljs-keyword">new</span> Access <span class="hljs-keyword">new</span> Literal <span class="hljs-string">'constructor'</span> <span class="hljs-keyword">if</span> method.static
      accesses.push <span class="hljs-keyword">if</span> nref? <span class="hljs-keyword">then</span> <span class="hljs-keyword">new</span> Index nref <span class="hljs-keyword">else</span> name
      (<span class="hljs-keyword">new</span> Value bref ? klass, accesses).compile o
    <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> method?.ctor
      <span class="hljs-string">"<span class="hljs-subst">#{method.name}</span>.__super__.constructor"</span>
    <span class="hljs-keyword">else</span>
      <span class="hljs-property">@error</span> <span class="hljs-string">'cannot call super outside of an instance method.'</span></pre></div></div>
            
        </li>
        
        
        <li id="section-57">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-57">&#182;</a>
              </div>
              <p>The appropriate <code>this</code> value for a <code>super</code> call.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  superThis : <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    method = o.scope.method
    (method <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> method.klass <span class="hljs-keyword">and</span> method.context) <span class="hljs-keyword">or</span> <span class="hljs-string">"this"</span></pre></div></div>
            
        </li>
        
        
        <li id="section-58">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-58">&#182;</a>
              </div>
              <p>Soaked chained invocations unfold into if/else ternary structures.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">unfoldSoak</span>: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-keyword">if</span> <span class="hljs-property">@soak</span>
      <span class="hljs-keyword">if</span> <span class="hljs-property">@variable</span>
        <span class="hljs-keyword">return</span> ifn <span class="hljs-keyword">if</span> ifn = unfoldSoak o, <span class="hljs-keyword">this</span>, <span class="hljs-string">'variable'</span>
        [left, rite] = <span class="hljs-keyword">new</span> Value(<span class="hljs-property">@variable</span>).cacheReference o
      <span class="hljs-keyword">else</span>
        left = <span class="hljs-keyword">new</span> Literal <span class="hljs-property">@superReference</span> o
        rite = <span class="hljs-keyword">new</span> Value left
      rite = <span class="hljs-keyword">new</span> Call rite, <span class="hljs-property">@args</span>
      rite.isNew = <span class="hljs-property">@isNew</span>
      left = <span class="hljs-keyword">new</span> Literal <span class="hljs-string">"typeof <span class="hljs-subst">#{ left.compile o }</span> === \"function\""</span>
      <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> If left, <span class="hljs-keyword">new</span> Value(rite), <span class="hljs-attribute">soak</span>: <span class="hljs-literal">yes</span>
    call = <span class="hljs-keyword">this</span>
    list = []
    <span class="hljs-keyword">loop</span>
      <span class="hljs-keyword">if</span> call.variable <span class="hljs-keyword">instanceof</span> Call
        list.push call
        call = call.variable
        <span class="hljs-keyword">continue</span>
      <span class="hljs-keyword">break</span> <span class="hljs-keyword">unless</span> call.variable <span class="hljs-keyword">instanceof</span> Value
      list.push call
      <span class="hljs-keyword">break</span> <span class="hljs-keyword">unless</span> (call = call.variable.base) <span class="hljs-keyword">instanceof</span> Call
    <span class="hljs-keyword">for</span> call <span class="hljs-keyword">in</span> list.reverse()
      <span class="hljs-keyword">if</span> ifn
        <span class="hljs-keyword">if</span> call.variable <span class="hljs-keyword">instanceof</span> Call
          call.variable = ifn
        <span class="hljs-keyword">else</span>
          call.variable.base = ifn
      ifn = unfoldSoak o, call, <span class="hljs-string">'variable'</span>
    ifn</pre></div></div>
            
        </li>
        
        
        <li id="section-59">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-59">&#182;</a>
              </div>
              <p>Compile a vanilla function call.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">compileNode</span>: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-property">@variable</span>?.front = <span class="hljs-property">@front</span>
    compiledArray = Splat.compileSplattedArray o, <span class="hljs-property">@args</span>, <span class="hljs-literal">true</span>
    <span class="hljs-keyword">if</span> compiledArray.length
      <span class="hljs-keyword">return</span> <span class="hljs-property">@compileSplat</span> o, compiledArray
    compiledArgs = []
    <span class="hljs-keyword">for</span> arg, argIndex <span class="hljs-keyword">in</span> <span class="hljs-property">@args</span>
      <span class="hljs-keyword">if</span> argIndex <span class="hljs-keyword">then</span> compiledArgs.push <span class="hljs-property">@makeCode</span> <span class="hljs-string">", "</span>
      compiledArgs.push (arg.compileToFragments o, LEVEL_LIST)...

    fragments = []
    <span class="hljs-keyword">if</span> <span class="hljs-property">@isSuper</span>
      preface = <span class="hljs-property">@superReference</span>(o) + <span class="hljs-string">".call(<span class="hljs-subst">#{<span class="hljs-property">@superThis</span>(o)}</span>"</span>
      <span class="hljs-keyword">if</span> compiledArgs.length <span class="hljs-keyword">then</span> preface += <span class="hljs-string">", "</span>
      fragments.push <span class="hljs-property">@makeCode</span> preface
    <span class="hljs-keyword">else</span>
      <span class="hljs-keyword">if</span> <span class="hljs-property">@isNew</span> <span class="hljs-keyword">then</span> fragments.push <span class="hljs-property">@makeCode</span> <span class="hljs-string">'new '</span>
      fragments.push <span class="hljs-property">@variable</span>.compileToFragments(o, LEVEL_ACCESS)...
      fragments.push <span class="hljs-property">@makeCode</span> <span class="hljs-string">"("</span>
    fragments.push compiledArgs...
    fragments.push <span class="hljs-property">@makeCode</span> <span class="hljs-string">")"</span>
    fragments</pre></div></div>
            
        </li>
        
        
        <li id="section-60">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-60">&#182;</a>
              </div>
              <p>If you call a function with a splat, it’s converted into a JavaScript
<code>.apply()</code> call to allow an array of arguments to be passed.
If it’s a constructor, then things get real tricky. We have to inject an
inner constructor in order to be able to pass the varargs.</p>
<p>splatArgs is an array of CodeFragments to put into the ‘apply’.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">compileSplat</span>: <span class="hljs-function"><span class="hljs-params">(o, splatArgs)</span> -&gt;</span>
    <span class="hljs-keyword">if</span> <span class="hljs-property">@isSuper</span>
      <span class="hljs-keyword">return</span> [].concat <span class="hljs-property">@makeCode</span>(<span class="hljs-string">"<span class="hljs-subst">#{ <span class="hljs-property">@superReference</span> o }</span>.apply(<span class="hljs-subst">#{<span class="hljs-property">@superThis</span>(o)}</span>, "</span>),
        splatArgs, <span class="hljs-property">@makeCode</span>(<span class="hljs-string">")"</span>)

    <span class="hljs-keyword">if</span> <span class="hljs-property">@isNew</span>
      idt = <span class="hljs-property">@tab</span> + TAB
      <span class="hljs-keyword">return</span> [].concat <span class="hljs-property">@makeCode</span>(<span class="hljs-string">"""
        (function(func, args, ctor) {
        <span class="hljs-subst">#{idt}</span>ctor.prototype = func.prototype;
        <span class="hljs-subst">#{idt}</span>var child = new ctor, result = func.apply(child, args);
        <span class="hljs-subst">#{idt}</span>return Object(result) === result ? result : child;
        <span class="hljs-subst">#{<span class="hljs-property">@tab</span>}</span>})("""</span>),
        (<span class="hljs-property">@variable</span>.compileToFragments o, LEVEL_LIST),
        <span class="hljs-property">@makeCode</span>(<span class="hljs-string">", "</span>), splatArgs, <span class="hljs-property">@makeCode</span>(<span class="hljs-string">", function(){})"</span>)

    answer = []
    base = <span class="hljs-keyword">new</span> Value <span class="hljs-property">@variable</span>
    <span class="hljs-keyword">if</span> (name = base.properties.pop()) <span class="hljs-keyword">and</span> base.isComplex()
      ref = o.scope.freeVariable <span class="hljs-string">'ref'</span>
      answer = answer.concat <span class="hljs-property">@makeCode</span>(<span class="hljs-string">"(<span class="hljs-subst">#{ref}</span> = "</span>),
        (base.compileToFragments o, LEVEL_LIST),
        <span class="hljs-property">@makeCode</span>(<span class="hljs-string">")"</span>),
        name.compileToFragments(o)
    <span class="hljs-keyword">else</span>
      fun = base.compileToFragments o, LEVEL_ACCESS
      fun = <span class="hljs-property">@wrapInBraces</span> fun <span class="hljs-keyword">if</span> SIMPLENUM.test fragmentsToText fun
      <span class="hljs-keyword">if</span> name
        ref = fragmentsToText fun
        fun.push (name.compileToFragments o)...
      <span class="hljs-keyword">else</span>
        ref = <span class="hljs-string">'null'</span>
      answer = answer.concat fun
    answer = answer.concat <span class="hljs-property">@makeCode</span>(<span class="hljs-string">".apply(<span class="hljs-subst">#{ref}</span>, "</span>), splatArgs, <span class="hljs-property">@makeCode</span>(<span class="hljs-string">")"</span>)</pre></div></div>
            
        </li>
        
        
        <li id="section-61">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-61">&#182;</a>
              </div>
              <h3 id="extends">Extends</h3>

            </div>
            
        </li>
        
        
        <li id="section-62">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-62">&#182;</a>
              </div>
              <p>Node to extend an object’s prototype with an ancestor object.
After <code>goog.inherits</code> from the
<a href="http://closure-library.googlecode.com/svn/docs/closureGoogBase.js.html">Closure Library</a>.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.Extends = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Extends</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  <span class="hljs-attribute">constructor</span>: <span class="hljs-function"><span class="hljs-params">(<span class="hljs-property">@child</span>, <span class="hljs-property">@parent</span>)</span> -&gt;</span>

  <span class="hljs-attribute">children</span>: [<span class="hljs-string">'child'</span>, <span class="hljs-string">'parent'</span>]</pre></div></div>
            
        </li>
        
        
        <li id="section-63">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-63">&#182;</a>
              </div>
              <p>Hooks one constructor into another’s prototype chain.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">compileToFragments</span>: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-keyword">new</span> Call(<span class="hljs-keyword">new</span> Value(<span class="hljs-keyword">new</span> Literal utility <span class="hljs-string">'extend'</span>, o), [<span class="hljs-property">@child</span>, <span class="hljs-property">@parent</span>]).compileToFragments o</pre></div></div>
            
        </li>
        
        
        <li id="section-64">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-64">&#182;</a>
              </div>
              <h3 id="access">Access</h3>

            </div>
            
        </li>
        
        
        <li id="section-65">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-65">&#182;</a>
              </div>
              <p>A <code>.</code> access into a property of a value, or the <code>::</code> shorthand for
an access into the object’s prototype.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.Access = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Access</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  <span class="hljs-attribute">constructor</span>: <span class="hljs-function"><span class="hljs-params">(<span class="hljs-property">@name</span>, tag)</span> -&gt;</span>
    <span class="hljs-property">@name</span>.asKey = <span class="hljs-literal">yes</span>
    <span class="hljs-property">@soak</span>  = tag <span class="hljs-keyword">is</span> <span class="hljs-string">'soak'</span>

  <span class="hljs-attribute">children</span>: [<span class="hljs-string">'name'</span>]

  <span class="hljs-attribute">compileToFragments</span>: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    name = <span class="hljs-property">@name</span>.compileToFragments o
    <span class="hljs-keyword">if</span> IDENTIFIER.test fragmentsToText name
      name.unshift <span class="hljs-property">@makeCode</span> <span class="hljs-string">"."</span>
    <span class="hljs-keyword">else</span>
      name.unshift <span class="hljs-property">@makeCode</span> <span class="hljs-string">"["</span>
      name.push <span class="hljs-property">@makeCode</span> <span class="hljs-string">"]"</span>
    name

  <span class="hljs-attribute">isComplex</span>: NO</pre></div></div>
            
        </li>
        
        
        <li id="section-66">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-66">&#182;</a>
              </div>
              <h3 id="index">Index</h3>

            </div>
            
        </li>
        
        
        <li id="section-67">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-67">&#182;</a>
              </div>
              <p>A <code>[ ... ]</code> indexed access into an array or object.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.Index = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Index</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  <span class="hljs-attribute">constructor</span>: <span class="hljs-function"><span class="hljs-params">(<span class="hljs-property">@index</span>)</span> -&gt;</span>

  <span class="hljs-attribute">children</span>: [<span class="hljs-string">'index'</span>]

  <span class="hljs-attribute">compileToFragments</span>: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    [].concat <span class="hljs-property">@makeCode</span>(<span class="hljs-string">"["</span>), <span class="hljs-property">@index</span>.compileToFragments(o, LEVEL_PAREN), <span class="hljs-property">@makeCode</span>(<span class="hljs-string">"]"</span>)

  <span class="hljs-attribute">isComplex</span>:<span class="hljs-function"> -&gt;</span>
    <span class="hljs-property">@index</span>.isComplex()</pre></div></div>
            
        </li>
        
        
        <li id="section-68">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-68">&#182;</a>
              </div>
              <h3 id="range">Range</h3>

            </div>
            
        </li>
        
        
        <li id="section-69">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-69">&#182;</a>
              </div>
              <p>A range literal. Ranges can be used to extract portions (slices) of arrays,
to specify a range for comprehensions, or as a value, to be expanded into the
corresponding array of integers at runtime.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.Range = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Range</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>

  <span class="hljs-attribute">children</span>: [<span class="hljs-string">'from'</span>, <span class="hljs-string">'to'</span>]

  <span class="hljs-attribute">constructor</span>: <span class="hljs-function"><span class="hljs-params">(<span class="hljs-property">@from</span>, <span class="hljs-property">@to</span>, tag)</span> -&gt;</span>
    <span class="hljs-property">@exclusive</span> = tag <span class="hljs-keyword">is</span> <span class="hljs-string">'exclusive'</span>
    <span class="hljs-property">@equals</span> = <span class="hljs-keyword">if</span> <span class="hljs-property">@exclusive</span> <span class="hljs-keyword">then</span> <span class="hljs-string">''</span> <span class="hljs-keyword">else</span> <span class="hljs-string">'='</span></pre></div></div>
            
        </li>
        
        
        <li id="section-70">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-70">&#182;</a>
              </div>
              <p>Compiles the range’s source variables — where it starts and where it ends.
But only if they need to be cached to avoid double evaluation.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">compileVariables</span>: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    o = merge o, <span class="hljs-attribute">top</span>: <span class="hljs-literal">true</span>
    isComplex = del o, <span class="hljs-string">'isComplex'</span>
    [<span class="hljs-property">@fromC</span>, <span class="hljs-property">@fromVar</span>]  =  <span class="hljs-property">@cacheToCodeFragments</span> <span class="hljs-property">@from</span>.cache o, LEVEL_LIST, isComplex
    [<span class="hljs-property">@toC</span>, <span class="hljs-property">@toVar</span>]      =  <span class="hljs-property">@cacheToCodeFragments</span> <span class="hljs-property">@to</span>.cache o, LEVEL_LIST, isComplex
    [<span class="hljs-property">@step</span>, <span class="hljs-property">@stepVar</span>]   =  <span class="hljs-property">@cacheToCodeFragments</span> step.cache o, LEVEL_LIST, isComplex <span class="hljs-keyword">if</span> step = del o, <span class="hljs-string">'step'</span>
    [<span class="hljs-property">@fromNum</span>, <span class="hljs-property">@toNum</span>]  = [<span class="hljs-property">@fromVar</span>.match(NUMBER), <span class="hljs-property">@toVar</span>.match(NUMBER)]
    <span class="hljs-property">@stepNum</span>            = <span class="hljs-property">@stepVar</span>.match(NUMBER) <span class="hljs-keyword">if</span> <span class="hljs-property">@stepVar</span></pre></div></div>
            
        </li>
        
        
        <li id="section-71">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-71">&#182;</a>
              </div>
              <p>When compiled normally, the range returns the contents of the <em>for loop</em>
needed to iterate over the values in the range. Used by comprehensions.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">compileNode</span>: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-property">@compileVariables</span> o <span class="hljs-keyword">unless</span> <span class="hljs-property">@fromVar</span>
    <span class="hljs-keyword">return</span> <span class="hljs-property">@compileArray</span>(o) <span class="hljs-keyword">unless</span> o.index</pre></div></div>
            
        </li>
        
        
        <li id="section-72">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-72">&#182;</a>
              </div>
              <p>Set up endpoints.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    known    = <span class="hljs-property">@fromNum</span> <span class="hljs-keyword">and</span> <span class="hljs-property">@toNum</span>
    idx      = del o, <span class="hljs-string">'index'</span>
    idxName  = del o, <span class="hljs-string">'name'</span>
    namedIndex = idxName <span class="hljs-keyword">and</span> idxName <span class="hljs-keyword">isnt</span> idx
    varPart  = <span class="hljs-string">"<span class="hljs-subst">#{idx}</span> = <span class="hljs-subst">#{<span class="hljs-property">@fromC</span>}</span>"</span>
    varPart += <span class="hljs-string">", <span class="hljs-subst">#{<span class="hljs-property">@toC</span>}</span>"</span> <span class="hljs-keyword">if</span> <span class="hljs-property">@toC</span> <span class="hljs-keyword">isnt</span> <span class="hljs-property">@toVar</span>
    varPart += <span class="hljs-string">", <span class="hljs-subst">#{<span class="hljs-property">@step</span>}</span>"</span> <span class="hljs-keyword">if</span> <span class="hljs-property">@step</span> <span class="hljs-keyword">isnt</span> <span class="hljs-property">@stepVar</span>
    [lt, gt] = [<span class="hljs-string">"<span class="hljs-subst">#{idx}</span> &lt;<span class="hljs-subst">#{<span class="hljs-property">@equals</span>}</span>"</span>, <span class="hljs-string">"<span class="hljs-subst">#{idx}</span> &gt;<span class="hljs-subst">#{<span class="hljs-property">@equals</span>}</span>"</span>]</pre></div></div>
            
        </li>
        
        
        <li id="section-73">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-73">&#182;</a>
              </div>
              <p>Generate the condition.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    condPart = <span class="hljs-keyword">if</span> <span class="hljs-property">@stepNum</span>
      <span class="hljs-keyword">if</span> parseNum(<span class="hljs-property">@stepNum</span>[<span class="hljs-number">0</span>]) &gt; <span class="hljs-number">0</span> <span class="hljs-keyword">then</span> <span class="hljs-string">"<span class="hljs-subst">#{lt}</span> <span class="hljs-subst">#{<span class="hljs-property">@toVar</span>}</span>"</span> <span class="hljs-keyword">else</span> <span class="hljs-string">"<span class="hljs-subst">#{gt}</span> <span class="hljs-subst">#{<span class="hljs-property">@toVar</span>}</span>"</span>
    <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> known
      [from, to] = [parseNum(<span class="hljs-property">@fromNum</span>[<span class="hljs-number">0</span>]), parseNum(<span class="hljs-property">@toNum</span>[<span class="hljs-number">0</span>])]
      <span class="hljs-keyword">if</span> from &lt;= to <span class="hljs-keyword">then</span> <span class="hljs-string">"<span class="hljs-subst">#{lt}</span> <span class="hljs-subst">#{to}</span>"</span> <span class="hljs-keyword">else</span> <span class="hljs-string">"<span class="hljs-subst">#{gt}</span> <span class="hljs-subst">#{to}</span>"</span>
    <span class="hljs-keyword">else</span>
      cond = <span class="hljs-keyword">if</span> <span class="hljs-property">@stepVar</span> <span class="hljs-keyword">then</span> <span class="hljs-string">"<span class="hljs-subst">#{<span class="hljs-property">@stepVar</span>}</span> &gt; 0"</span> <span class="hljs-keyword">else</span> <span class="hljs-string">"<span class="hljs-subst">#{<span class="hljs-property">@fromVar</span>}</span> &lt;= <span class="hljs-subst">#{<span class="hljs-property">@toVar</span>}</span>"</span>
      <span class="hljs-string">"<span class="hljs-subst">#{cond}</span> ? <span class="hljs-subst">#{lt}</span> <span class="hljs-subst">#{<span class="hljs-property">@toVar</span>}</span> : <span class="hljs-subst">#{gt}</span> <span class="hljs-subst">#{<span class="hljs-property">@toVar</span>}</span>"</span></pre></div></div>
            
        </li>
        
        
        <li id="section-74">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-74">&#182;</a>
              </div>
              <p>Generate the step.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    stepPart = <span class="hljs-keyword">if</span> <span class="hljs-property">@stepVar</span>
      <span class="hljs-string">"<span class="hljs-subst">#{idx}</span> += <span class="hljs-subst">#{<span class="hljs-property">@stepVar</span>}</span>"</span>
    <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> known
      <span class="hljs-keyword">if</span> namedIndex
        <span class="hljs-keyword">if</span> from &lt;= to <span class="hljs-keyword">then</span> <span class="hljs-string">"++<span class="hljs-subst">#{idx}</span>"</span> <span class="hljs-keyword">else</span> <span class="hljs-string">"--<span class="hljs-subst">#{idx}</span>"</span>
      <span class="hljs-keyword">else</span>
        <span class="hljs-keyword">if</span> from &lt;= to <span class="hljs-keyword">then</span> <span class="hljs-string">"<span class="hljs-subst">#{idx}</span>++"</span> <span class="hljs-keyword">else</span> <span class="hljs-string">"<span class="hljs-subst">#{idx}</span>--"</span>
    <span class="hljs-keyword">else</span>
      <span class="hljs-keyword">if</span> namedIndex
        <span class="hljs-string">"<span class="hljs-subst">#{cond}</span> ? ++<span class="hljs-subst">#{idx}</span> : --<span class="hljs-subst">#{idx}</span>"</span>
      <span class="hljs-keyword">else</span>
        <span class="hljs-string">"<span class="hljs-subst">#{cond}</span> ? <span class="hljs-subst">#{idx}</span>++ : <span class="hljs-subst">#{idx}</span>--"</span>

    varPart  = <span class="hljs-string">"<span class="hljs-subst">#{idxName}</span> = <span class="hljs-subst">#{varPart}</span>"</span> <span class="hljs-keyword">if</span> namedIndex
    stepPart = <span class="hljs-string">"<span class="hljs-subst">#{idxName}</span> = <span class="hljs-subst">#{stepPart}</span>"</span> <span class="hljs-keyword">if</span> namedIndex</pre></div></div>
            
        </li>
        
        
        <li id="section-75">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-75">&#182;</a>
              </div>
              <p>The final loop body.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    [<span class="hljs-property">@makeCode</span> <span class="hljs-string">"<span class="hljs-subst">#{varPart}</span>; <span class="hljs-subst">#{condPart}</span>; <span class="hljs-subst">#{stepPart}</span>"</span>]</pre></div></div>
            
        </li>
        
        
        <li id="section-76">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-76">&#182;</a>
              </div>
              <p>When used as a value, expand the range into the equivalent array.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">compileArray</span>: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-keyword">if</span> <span class="hljs-property">@fromNum</span> <span class="hljs-keyword">and</span> <span class="hljs-property">@toNum</span> <span class="hljs-keyword">and</span> Math.abs(<span class="hljs-property">@fromNum</span> - <span class="hljs-property">@toNum</span>) &lt;= <span class="hljs-number">20</span>
      range = [+<span class="hljs-property">@fromNum</span>..+<span class="hljs-property">@toNum</span>]
      range.pop() <span class="hljs-keyword">if</span> <span class="hljs-property">@exclusive</span>
      <span class="hljs-keyword">return</span> [<span class="hljs-property">@makeCode</span> <span class="hljs-string">"[<span class="hljs-subst">#{ range.join(<span class="hljs-string">', '</span>) }</span>]"</span>]
    idt    = <span class="hljs-property">@tab</span> + TAB
    i      = o.scope.freeVariable <span class="hljs-string">'i'</span>, <span class="hljs-attribute">single</span>: <span class="hljs-literal">true</span>
    result = o.scope.freeVariable <span class="hljs-string">'results'</span>
    pre    = <span class="hljs-string">"\n<span class="hljs-subst">#{idt}</span><span class="hljs-subst">#{result}</span> = [];"</span>
    <span class="hljs-keyword">if</span> <span class="hljs-property">@fromNum</span> <span class="hljs-keyword">and</span> <span class="hljs-property">@toNum</span>
      o.index = i
      body    = fragmentsToText <span class="hljs-property">@compileNode</span> o
    <span class="hljs-keyword">else</span>
      vars    = <span class="hljs-string">"<span class="hljs-subst">#{i}</span> = <span class="hljs-subst">#{<span class="hljs-property">@fromC</span>}</span>"</span> + <span class="hljs-keyword">if</span> <span class="hljs-property">@toC</span> <span class="hljs-keyword">isnt</span> <span class="hljs-property">@toVar</span> <span class="hljs-keyword">then</span> <span class="hljs-string">", <span class="hljs-subst">#{<span class="hljs-property">@toC</span>}</span>"</span> <span class="hljs-keyword">else</span> <span class="hljs-string">''</span>
      cond    = <span class="hljs-string">"<span class="hljs-subst">#{<span class="hljs-property">@fromVar</span>}</span> &lt;= <span class="hljs-subst">#{<span class="hljs-property">@toVar</span>}</span>"</span>
      body    = <span class="hljs-string">"var <span class="hljs-subst">#{vars}</span>; <span class="hljs-subst">#{cond}</span> ? <span class="hljs-subst">#{i}</span> &lt;<span class="hljs-subst">#{<span class="hljs-property">@equals</span>}</span> <span class="hljs-subst">#{<span class="hljs-property">@toVar</span>}</span> : <span class="hljs-subst">#{i}</span> &gt;<span class="hljs-subst">#{<span class="hljs-property">@equals</span>}</span> <span class="hljs-subst">#{<span class="hljs-property">@toVar</span>}</span>; <span class="hljs-subst">#{cond}</span> ? <span class="hljs-subst">#{i}</span>++ : <span class="hljs-subst">#{i}</span>--"</span>
    post   = <span class="hljs-string">"{ <span class="hljs-subst">#{result}</span>.push(<span class="hljs-subst">#{i}</span>); }\n<span class="hljs-subst">#{idt}</span>return <span class="hljs-subst">#{result}</span>;\n<span class="hljs-subst">#{o.indent}</span>"</span>
    <span class="hljs-function"><span class="hljs-title">hasArgs</span> = <span class="hljs-params">(node)</span> -&gt;</span> node?.contains isLiteralArguments
    args   = <span class="hljs-string">', arguments'</span> <span class="hljs-keyword">if</span> hasArgs(<span class="hljs-property">@from</span>) <span class="hljs-keyword">or</span> hasArgs(<span class="hljs-property">@to</span>)
    [<span class="hljs-property">@makeCode</span> <span class="hljs-string">"(function() {<span class="hljs-subst">#{pre}</span>\n<span class="hljs-subst">#{idt}</span>for (<span class="hljs-subst">#{body}</span>)<span class="hljs-subst">#{post}</span>}).apply(this<span class="hljs-subst">#{args ? <span class="hljs-string">''</span>}</span>)"</span>]</pre></div></div>
            
        </li>
        
        
        <li id="section-77">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-77">&#182;</a>
              </div>
              <h3 id="slice">Slice</h3>

            </div>
            
        </li>
        
        
        <li id="section-78">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-78">&#182;</a>
              </div>
              <p>An array slice literal. Unlike JavaScript’s <code>Array#slice</code>, the second parameter
specifies the index of the end of the slice, just as the first parameter
is the index of the beginning.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.Slice = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Slice</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>

  <span class="hljs-attribute">children</span>: [<span class="hljs-string">'range'</span>]

  <span class="hljs-attribute">constructor</span>: <span class="hljs-function"><span class="hljs-params">(<span class="hljs-property">@range</span>)</span> -&gt;</span>
    <span class="hljs-keyword">super</span>()</pre></div></div>
            
        </li>
        
        
        <li id="section-79">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-79">&#182;</a>
              </div>
              <p>We have to be careful when trying to slice through the end of the array,
<code>9e9</code> is used because not all implementations respect <code>undefined</code> or <code>1/0</code>.
<code>9e9</code> should be safe because <code>9e9</code> &gt; <code>2**32</code>, the max array length.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">compileNode</span>: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    {to, from} = <span class="hljs-property">@range</span>
    fromCompiled = from <span class="hljs-keyword">and</span> from.compileToFragments(o, LEVEL_PAREN) <span class="hljs-keyword">or</span> [<span class="hljs-property">@makeCode</span> <span class="hljs-string">'0'</span>]</pre></div></div>
            
        </li>
        
        
        <li id="section-80">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-80">&#182;</a>
              </div>
              <p>TODO: jwalton - move this into the ‘if’?</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    <span class="hljs-keyword">if</span> to
      compiled     = to.compileToFragments o, LEVEL_PAREN
      compiledText = fragmentsToText compiled
      <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> (<span class="hljs-keyword">not</span> <span class="hljs-property">@range</span>.exclusive <span class="hljs-keyword">and</span> +compiledText <span class="hljs-keyword">is</span> -<span class="hljs-number">1</span>)
        toStr = <span class="hljs-string">', '</span> + <span class="hljs-keyword">if</span> <span class="hljs-property">@range</span>.exclusive
          compiledText
        <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> SIMPLENUM.test compiledText
          <span class="hljs-string">"<span class="hljs-subst">#{+compiledText + <span class="hljs-number">1</span>}</span>"</span>
        <span class="hljs-keyword">else</span>
          compiled = to.compileToFragments o, LEVEL_ACCESS
          <span class="hljs-string">"+<span class="hljs-subst">#{fragmentsToText compiled}</span> + 1 || 9e9"</span>
    [<span class="hljs-property">@makeCode</span> <span class="hljs-string">".slice(<span class="hljs-subst">#{ fragmentsToText fromCompiled }</span><span class="hljs-subst">#{ toStr <span class="hljs-keyword">or</span> <span class="hljs-string">''</span> }</span>)"</span>]</pre></div></div>
            
        </li>
        
        
        <li id="section-81">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-81">&#182;</a>
              </div>
              <h3 id="obj">Obj</h3>

            </div>
            
        </li>
        
        
        <li id="section-82">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-82">&#182;</a>
              </div>
              <p>An object literal, nothing fancy.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.Obj = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Obj</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  <span class="hljs-attribute">constructor</span>: <span class="hljs-function"><span class="hljs-params">(props, <span class="hljs-property">@generated</span> = <span class="hljs-literal">false</span>)</span> -&gt;</span>
    <span class="hljs-property">@objects</span> = <span class="hljs-property">@properties</span> = props <span class="hljs-keyword">or</span> []

  <span class="hljs-attribute">children</span>: [<span class="hljs-string">'properties'</span>]

  <span class="hljs-attribute">compileNode</span>: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    props = <span class="hljs-property">@properties</span>
    <span class="hljs-keyword">if</span> <span class="hljs-property">@generated</span>
      <span class="hljs-keyword">for</span> node <span class="hljs-keyword">in</span> props <span class="hljs-keyword">when</span> node <span class="hljs-keyword">instanceof</span> Value
        node.error <span class="hljs-string">'cannot have an implicit value in an implicit object'</span>
    <span class="hljs-keyword">break</span> <span class="hljs-keyword">for</span> prop, dynamicIndex <span class="hljs-keyword">in</span> props <span class="hljs-keyword">when</span> (prop.variable <span class="hljs-keyword">or</span> prop).base <span class="hljs-keyword">instanceof</span> Parens
    hasDynamic  = dynamicIndex &lt; props.length
    idt         = o.indent += TAB
    lastNoncom  = <span class="hljs-property">@lastNonComment</span> <span class="hljs-property">@properties</span>
    answer = []
    <span class="hljs-keyword">if</span> hasDynamic
      oref = o.scope.freeVariable <span class="hljs-string">'obj'</span>
      answer.push <span class="hljs-property">@makeCode</span> <span class="hljs-string">"(\n<span class="hljs-subst">#{idt}</span><span class="hljs-subst">#{oref}</span> = "</span>
    answer.push <span class="hljs-property">@makeCode</span> <span class="hljs-string">"{<span class="hljs-subst">#{<span class="hljs-keyword">if</span> props.length <span class="hljs-keyword">is</span> <span class="hljs-number">0</span> <span class="hljs-keyword">or</span> dynamicIndex <span class="hljs-keyword">is</span> <span class="hljs-number">0</span> <span class="hljs-keyword">then</span> <span class="hljs-string">'}'</span> <span class="hljs-keyword">else</span> <span class="hljs-string">'\n'</span>}</span>"</span>
    <span class="hljs-keyword">for</span> prop, i <span class="hljs-keyword">in</span> props
      <span class="hljs-keyword">if</span> i <span class="hljs-keyword">is</span> dynamicIndex
        answer.push <span class="hljs-property">@makeCode</span> <span class="hljs-string">"\n<span class="hljs-subst">#{idt}</span>}"</span> <span class="hljs-keyword">unless</span> i <span class="hljs-keyword">is</span> <span class="hljs-number">0</span>
        answer.push <span class="hljs-property">@makeCode</span> <span class="hljs-string">',\n'</span>
      join = <span class="hljs-keyword">if</span> i <span class="hljs-keyword">is</span> props.length - <span class="hljs-number">1</span> <span class="hljs-keyword">or</span> i <span class="hljs-keyword">is</span> dynamicIndex - <span class="hljs-number">1</span>
        <span class="hljs-string">''</span>
      <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> prop <span class="hljs-keyword">is</span> lastNoncom <span class="hljs-keyword">or</span> prop <span class="hljs-keyword">instanceof</span> Comment
        <span class="hljs-string">'\n'</span>
      <span class="hljs-keyword">else</span>
        <span class="hljs-string">',\n'</span>
      indent = <span class="hljs-keyword">if</span> prop <span class="hljs-keyword">instanceof</span> Comment <span class="hljs-keyword">then</span> <span class="hljs-string">''</span> <span class="hljs-keyword">else</span> idt
      indent += TAB <span class="hljs-keyword">if</span> hasDynamic <span class="hljs-keyword">and</span> i &lt; dynamicIndex
      <span class="hljs-keyword">if</span> prop <span class="hljs-keyword">instanceof</span> Assign
        <span class="hljs-keyword">if</span> prop.context <span class="hljs-keyword">isnt</span> <span class="hljs-string">'object'</span>
          prop.operatorToken.error <span class="hljs-string">"unexpected <span class="hljs-subst">#{prop.operatorToken.value}</span>"</span>
        <span class="hljs-keyword">if</span> prop.variable <span class="hljs-keyword">instanceof</span> Value <span class="hljs-keyword">and</span> prop.variable.hasProperties()
          prop.variable.error <span class="hljs-string">'invalid object key'</span>
      <span class="hljs-keyword">if</span> prop <span class="hljs-keyword">instanceof</span> Value <span class="hljs-keyword">and</span> prop.<span class="hljs-keyword">this</span>
        prop = <span class="hljs-keyword">new</span> Assign prop.properties[<span class="hljs-number">0</span>].name, prop, <span class="hljs-string">'object'</span>
      <span class="hljs-keyword">if</span> prop <span class="hljs-keyword">not</span> <span class="hljs-keyword">instanceof</span> Comment
        <span class="hljs-keyword">if</span> i &lt; dynamicIndex
          <span class="hljs-keyword">if</span> prop <span class="hljs-keyword">not</span> <span class="hljs-keyword">instanceof</span> Assign
            prop = <span class="hljs-keyword">new</span> Assign prop, prop, <span class="hljs-string">'object'</span>
          (prop.variable.base <span class="hljs-keyword">or</span> prop.variable).asKey = <span class="hljs-literal">yes</span>
        <span class="hljs-keyword">else</span>
          <span class="hljs-keyword">if</span> prop <span class="hljs-keyword">instanceof</span> Assign
            key = prop.variable
            value = prop.value
          <span class="hljs-keyword">else</span>
            [key, value] = prop.base.cache o
          prop = <span class="hljs-keyword">new</span> Assign (<span class="hljs-keyword">new</span> Value (<span class="hljs-keyword">new</span> Literal oref), [<span class="hljs-keyword">new</span> Access key]), value
      <span class="hljs-keyword">if</span> indent <span class="hljs-keyword">then</span> answer.push <span class="hljs-property">@makeCode</span> indent
      answer.push prop.compileToFragments(o, LEVEL_TOP)...
      <span class="hljs-keyword">if</span> join <span class="hljs-keyword">then</span> answer.push <span class="hljs-property">@makeCode</span> join
    <span class="hljs-keyword">if</span> hasDynamic
      answer.push <span class="hljs-property">@makeCode</span> <span class="hljs-string">",\n<span class="hljs-subst">#{idt}</span><span class="hljs-subst">#{oref}</span>\n<span class="hljs-subst">#{<span class="hljs-property">@tab</span>}</span>)"</span>
    <span class="hljs-keyword">else</span>
      answer.push <span class="hljs-property">@makeCode</span> <span class="hljs-string">"\n<span class="hljs-subst">#{<span class="hljs-property">@tab</span>}</span>}"</span> <span class="hljs-keyword">unless</span> props.length <span class="hljs-keyword">is</span> <span class="hljs-number">0</span>
    <span class="hljs-keyword">if</span> <span class="hljs-property">@front</span> <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> hasDynamic <span class="hljs-keyword">then</span> <span class="hljs-property">@wrapInBraces</span> answer <span class="hljs-keyword">else</span> answer

  <span class="hljs-attribute">assigns</span>: <span class="hljs-function"><span class="hljs-params">(name)</span> -&gt;</span>
    <span class="hljs-keyword">for</span> prop <span class="hljs-keyword">in</span> <span class="hljs-property">@properties</span> <span class="hljs-keyword">when</span> prop.assigns name <span class="hljs-keyword">then</span> <span class="hljs-keyword">return</span> <span class="hljs-literal">yes</span>
    <span class="hljs-literal">no</span></pre></div></div>
            
        </li>
        
        
        <li id="section-83">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-83">&#182;</a>
              </div>
              <h3 id="arr">Arr</h3>

            </div>
            
        </li>
        
        
        <li id="section-84">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-84">&#182;</a>
              </div>
              <p>An array literal.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.Arr = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Arr</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  <span class="hljs-attribute">constructor</span>: <span class="hljs-function"><span class="hljs-params">(objs)</span> -&gt;</span>
    <span class="hljs-property">@objects</span> = objs <span class="hljs-keyword">or</span> []

  <span class="hljs-attribute">children</span>: [<span class="hljs-string">'objects'</span>]

  <span class="hljs-attribute">compileNode</span>: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-keyword">return</span> [<span class="hljs-property">@makeCode</span> <span class="hljs-string">'[]'</span>] <span class="hljs-keyword">unless</span> <span class="hljs-property">@objects</span>.length
    o.indent += TAB
    answer = Splat.compileSplattedArray o, <span class="hljs-property">@objects</span>
    <span class="hljs-keyword">return</span> answer <span class="hljs-keyword">if</span> answer.length

    answer = []
    compiledObjs = (obj.compileToFragments o, LEVEL_LIST <span class="hljs-keyword">for</span> obj <span class="hljs-keyword">in</span> <span class="hljs-property">@objects</span>)
    <span class="hljs-keyword">for</span> fragments, index <span class="hljs-keyword">in</span> compiledObjs
      <span class="hljs-keyword">if</span> index
        answer.push <span class="hljs-property">@makeCode</span> <span class="hljs-string">", "</span>
      answer.push fragments...
    <span class="hljs-keyword">if</span> fragmentsToText(answer).indexOf(<span class="hljs-string">'\n'</span>) &gt;= <span class="hljs-number">0</span>
      answer.unshift <span class="hljs-property">@makeCode</span> <span class="hljs-string">"[\n<span class="hljs-subst">#{o.indent}</span>"</span>
      answer.push <span class="hljs-property">@makeCode</span> <span class="hljs-string">"\n<span class="hljs-subst">#{<span class="hljs-property">@tab</span>}</span>]"</span>
    <span class="hljs-keyword">else</span>
      answer.unshift <span class="hljs-property">@makeCode</span> <span class="hljs-string">"["</span>
      answer.push <span class="hljs-property">@makeCode</span> <span class="hljs-string">"]"</span>
    answer

  <span class="hljs-attribute">assigns</span>: <span class="hljs-function"><span class="hljs-params">(name)</span> -&gt;</span>
    <span class="hljs-keyword">for</span> obj <span class="hljs-keyword">in</span> <span class="hljs-property">@objects</span> <span class="hljs-keyword">when</span> obj.assigns name <span class="hljs-keyword">then</span> <span class="hljs-keyword">return</span> <span class="hljs-literal">yes</span>
    <span class="hljs-literal">no</span></pre></div></div>
            
        </li>
        
        
        <li id="section-85">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-85">&#182;</a>
              </div>
              <h3 id="class">Class</h3>

            </div>
            
        </li>
        
        
        <li id="section-86">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-86">&#182;</a>
              </div>
              <p>The CoffeeScript class definition.
Initialize a <strong>Class</strong> with its name, an optional superclass, and a
list of prototype property assignments.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.Class = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Class</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  <span class="hljs-attribute">constructor</span>: <span class="hljs-function"><span class="hljs-params">(<span class="hljs-property">@variable</span>, <span class="hljs-property">@parent</span>, <span class="hljs-property">@body</span> = <span class="hljs-keyword">new</span> Block)</span> -&gt;</span>
    <span class="hljs-property">@boundFuncs</span> = []
    <span class="hljs-property">@body</span>.classBody = <span class="hljs-literal">yes</span>

  <span class="hljs-attribute">children</span>: [<span class="hljs-string">'variable'</span>, <span class="hljs-string">'parent'</span>, <span class="hljs-string">'body'</span>]</pre></div></div>
            
        </li>
        
        
        <li id="section-87">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-87">&#182;</a>
              </div>
              <p>Figure out the appropriate name for the constructor function of this class.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">determineName</span>:<span class="hljs-function"> -&gt;</span>
    <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span> <span class="hljs-keyword">unless</span> <span class="hljs-property">@variable</span>
    [..., tail] = <span class="hljs-property">@variable</span>.properties
    decl = <span class="hljs-keyword">if</span> tail
      tail <span class="hljs-keyword">instanceof</span> Access <span class="hljs-keyword">and</span> tail.name.value
    <span class="hljs-keyword">else</span>
      <span class="hljs-property">@variable</span>.base.value
    <span class="hljs-keyword">if</span> decl <span class="hljs-keyword">in</span> STRICT_PROSCRIBED
      <span class="hljs-property">@variable</span>.error <span class="hljs-string">"class variable name may not be <span class="hljs-subst">#{decl}</span>"</span>
    decl <span class="hljs-keyword">and</span>= IDENTIFIER.test(decl) <span class="hljs-keyword">and</span> decl</pre></div></div>
            
        </li>
        
        
        <li id="section-88">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-88">&#182;</a>
              </div>
              <p>For all <code>this</code>-references and bound functions in the class definition,
<code>this</code> is the Class being constructed.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">setContext</span>: <span class="hljs-function"><span class="hljs-params">(name)</span> -&gt;</span>
    <span class="hljs-property">@body</span>.traverseChildren <span class="hljs-literal">false</span>, <span class="hljs-function"><span class="hljs-params">(node)</span> -&gt;</span>
      <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span> <span class="hljs-keyword">if</span> node.classBody
      <span class="hljs-keyword">if</span> node <span class="hljs-keyword">instanceof</span> Literal <span class="hljs-keyword">and</span> node.value <span class="hljs-keyword">is</span> <span class="hljs-string">'this'</span>
        node.value    = name
      <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> node <span class="hljs-keyword">instanceof</span> Code
        node.context  = name <span class="hljs-keyword">if</span> node.bound</pre></div></div>
            
        </li>
        
        
        <li id="section-89">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-89">&#182;</a>
              </div>
              <p>Ensure that all functions bound to the instance are proxied in the
constructor.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">addBoundFunctions</span>: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-keyword">for</span> bvar <span class="hljs-keyword">in</span> <span class="hljs-property">@boundFuncs</span>
      lhs = (<span class="hljs-keyword">new</span> Value (<span class="hljs-keyword">new</span> Literal <span class="hljs-string">"this"</span>), [<span class="hljs-keyword">new</span> Access bvar]).compile o
      <span class="hljs-property">@ctor</span>.body.unshift <span class="hljs-keyword">new</span> Literal <span class="hljs-string">"<span class="hljs-subst">#{lhs}</span> = <span class="hljs-subst">#{utility <span class="hljs-string">'bind'</span>, o}</span>(<span class="hljs-subst">#{lhs}</span>, this)"</span>
    <span class="hljs-keyword">return</span></pre></div></div>
            
        </li>
        
        
        <li id="section-90">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-90">&#182;</a>
              </div>
              <p>Merge the properties from a top-level object as prototypal properties
on the class.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">addProperties</span>: <span class="hljs-function"><span class="hljs-params">(node, name, o)</span> -&gt;</span>
    props = node.base.properties[..]
    exprs = <span class="hljs-keyword">while</span> assign = props.shift()
      <span class="hljs-keyword">if</span> assign <span class="hljs-keyword">instanceof</span> Assign
        base = assign.variable.base
        <span class="hljs-keyword">delete</span> assign.context
        func = assign.value
        <span class="hljs-keyword">if</span> base.value <span class="hljs-keyword">is</span> <span class="hljs-string">'constructor'</span>
          <span class="hljs-keyword">if</span> <span class="hljs-property">@ctor</span>
            assign.error <span class="hljs-string">'cannot define more than one constructor in a class'</span>
          <span class="hljs-keyword">if</span> func.bound
            assign.error <span class="hljs-string">'cannot define a constructor as a bound function'</span>
          <span class="hljs-keyword">if</span> func <span class="hljs-keyword">instanceof</span> Code
            assign = <span class="hljs-property">@ctor</span> = func
          <span class="hljs-keyword">else</span>
            <span class="hljs-property">@externalCtor</span> = o.classScope.freeVariable <span class="hljs-string">'class'</span>
            assign = <span class="hljs-keyword">new</span> Assign <span class="hljs-keyword">new</span> Literal(<span class="hljs-property">@externalCtor</span>), func
        <span class="hljs-keyword">else</span>
          <span class="hljs-keyword">if</span> assign.variable.<span class="hljs-keyword">this</span>
            func.static = <span class="hljs-literal">yes</span>
          <span class="hljs-keyword">else</span>
            acc = <span class="hljs-keyword">if</span> base.isComplex() <span class="hljs-keyword">then</span> <span class="hljs-keyword">new</span> Index base <span class="hljs-keyword">else</span> <span class="hljs-keyword">new</span> Access base
            assign.variable = <span class="hljs-keyword">new</span> Value(<span class="hljs-keyword">new</span> Literal(name), [(<span class="hljs-keyword">new</span> Access <span class="hljs-keyword">new</span> Literal <span class="hljs-string">'prototype'</span>), acc])
            <span class="hljs-keyword">if</span> func <span class="hljs-keyword">instanceof</span> Code <span class="hljs-keyword">and</span> func.bound
              <span class="hljs-property">@boundFuncs</span>.push base
              func.bound = <span class="hljs-literal">no</span>
      assign
    compact exprs</pre></div></div>
            
        </li>
        
        
        <li id="section-91">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-91">&#182;</a>
              </div>
              <p>Walk the body of the class, looking for prototype properties to be converted
and tagging static assignments.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">walkBody</span>: <span class="hljs-function"><span class="hljs-params">(name, o)</span> -&gt;</span>
    <span class="hljs-property">@traverseChildren</span> <span class="hljs-literal">false</span>, <span class="hljs-function"><span class="hljs-params">(child)</span> =&gt;</span>
      cont = <span class="hljs-literal">true</span>
      <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span> <span class="hljs-keyword">if</span> child <span class="hljs-keyword">instanceof</span> Class
      <span class="hljs-keyword">if</span> child <span class="hljs-keyword">instanceof</span> Block
        <span class="hljs-keyword">for</span> node, i <span class="hljs-keyword">in</span> exps = child.expressions
          <span class="hljs-keyword">if</span> node <span class="hljs-keyword">instanceof</span> Assign <span class="hljs-keyword">and</span> node.variable.looksStatic name
            node.value.static = <span class="hljs-literal">yes</span>
          <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> node <span class="hljs-keyword">instanceof</span> Value <span class="hljs-keyword">and</span> node.isObject(<span class="hljs-literal">true</span>)
            cont = <span class="hljs-literal">false</span>
            exps[i] = <span class="hljs-property">@addProperties</span> node, name, o
        child.expressions = exps = flatten exps
      cont <span class="hljs-keyword">and</span> child <span class="hljs-keyword">not</span> <span class="hljs-keyword">instanceof</span> Class</pre></div></div>
            
        </li>
        
        
        <li id="section-92">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-92">&#182;</a>
              </div>
              <p><code>use strict</code> (and other directives) must be the first expression statement(s)
of a function body. This method ensures the prologue is correctly positioned
above the <code>constructor</code>.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">hoistDirectivePrologue</span>:<span class="hljs-function"> -&gt;</span>
    index = <span class="hljs-number">0</span>
    {expressions} = <span class="hljs-property">@body</span>
    ++index <span class="hljs-keyword">while</span> (node = expressions[index]) <span class="hljs-keyword">and</span> node <span class="hljs-keyword">instanceof</span> Comment <span class="hljs-keyword">or</span>
      node <span class="hljs-keyword">instanceof</span> Value <span class="hljs-keyword">and</span> node.isString()
    <span class="hljs-property">@directives</span> = expressions.splice <span class="hljs-number">0</span>, index</pre></div></div>
            
        </li>
        
        
        <li id="section-93">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-93">&#182;</a>
              </div>
              <p>Make sure that a constructor is defined for the class, and properly
configured.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">ensureConstructor</span>: <span class="hljs-function"><span class="hljs-params">(name)</span> -&gt;</span>
    <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> <span class="hljs-property">@ctor</span>
      <span class="hljs-property">@ctor</span> = <span class="hljs-keyword">new</span> Code
      <span class="hljs-keyword">if</span> <span class="hljs-property">@externalCtor</span>
        <span class="hljs-property">@ctor</span>.body.push <span class="hljs-keyword">new</span> Literal <span class="hljs-string">"<span class="hljs-subst">#{<span class="hljs-property">@externalCtor</span>}</span>.apply(this, arguments)"</span>
      <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> <span class="hljs-property">@parent</span>
        <span class="hljs-property">@ctor</span>.body.push <span class="hljs-keyword">new</span> Literal <span class="hljs-string">"<span class="hljs-subst">#{name}</span>.__super__.constructor.apply(this, arguments)"</span>
      <span class="hljs-property">@ctor</span>.body.makeReturn()
      <span class="hljs-property">@body</span>.expressions.unshift <span class="hljs-property">@ctor</span>
    <span class="hljs-property">@ctor</span>.ctor = <span class="hljs-property">@ctor</span>.name = name
    <span class="hljs-property">@ctor</span>.klass = <span class="hljs-literal">null</span>
    <span class="hljs-property">@ctor</span>.noReturn = <span class="hljs-literal">yes</span></pre></div></div>
            
        </li>
        
        
        <li id="section-94">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-94">&#182;</a>
              </div>
              <p>Instead of generating the JavaScript string directly, we build up the
equivalent syntax tree and compile that, in pieces. You can see the
constructor, property assignments, and inheritance getting built out below.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">compileNode</span>: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-keyword">if</span> jumpNode = <span class="hljs-property">@body</span>.jumps()
      jumpNode.error <span class="hljs-string">'Class bodies cannot contain pure statements'</span>
    <span class="hljs-keyword">if</span> argumentsNode = <span class="hljs-property">@body</span>.contains isLiteralArguments
      argumentsNode.error <span class="hljs-string">"Class bodies shouldn't reference arguments"</span>

    name  = <span class="hljs-property">@determineName</span>() <span class="hljs-keyword">or</span> <span class="hljs-string">'_Class'</span>
    name  = <span class="hljs-string">"_<span class="hljs-subst">#{name}</span>"</span> <span class="hljs-keyword">if</span> name.reserved
    lname = <span class="hljs-keyword">new</span> Literal name
    func  = <span class="hljs-keyword">new</span> Code [], Block.wrap [<span class="hljs-property">@body</span>]
    args  = []
    o.classScope = func.makeScope o.scope

    <span class="hljs-property">@hoistDirectivePrologue</span>()
    <span class="hljs-property">@setContext</span> name
    <span class="hljs-property">@walkBody</span> name, o
    <span class="hljs-property">@ensureConstructor</span> name
    <span class="hljs-property">@addBoundFunctions</span> o
    <span class="hljs-property">@body</span>.spaced = <span class="hljs-literal">yes</span>
    <span class="hljs-property">@body</span>.expressions.push lname

    <span class="hljs-keyword">if</span> <span class="hljs-property">@parent</span>
      superClass = <span class="hljs-keyword">new</span> Literal o.classScope.freeVariable <span class="hljs-string">'superClass'</span>, <span class="hljs-attribute">reserve</span>: <span class="hljs-literal">no</span>
      <span class="hljs-property">@body</span>.expressions.unshift <span class="hljs-keyword">new</span> Extends lname, superClass
      func.params.push <span class="hljs-keyword">new</span> Param superClass
      args.push <span class="hljs-property">@parent</span>

    <span class="hljs-property">@body</span>.expressions.unshift <span class="hljs-property">@directives</span>...

    klass = <span class="hljs-keyword">new</span> Parens <span class="hljs-keyword">new</span> Call func, args
    klass = <span class="hljs-keyword">new</span> Assign <span class="hljs-property">@variable</span>, klass <span class="hljs-keyword">if</span> <span class="hljs-property">@variable</span>
    klass.compileToFragments o</pre></div></div>
            
        </li>
        
        
        <li id="section-95">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-95">&#182;</a>
              </div>
              <h3 id="assign">Assign</h3>

            </div>
            
        </li>
        
        
        <li id="section-96">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-96">&#182;</a>
              </div>
              <p>The <strong>Assign</strong> is used to assign a local variable to value, or to set the
property of an object — including within object literals.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.Assign = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Assign</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  <span class="hljs-attribute">constructor</span>: <span class="hljs-function"><span class="hljs-params">(<span class="hljs-property">@variable</span>, <span class="hljs-property">@value</span>, <span class="hljs-property">@context</span>, options = {})</span> -&gt;</span>
    {<span class="hljs-property">@param</span>, <span class="hljs-property">@subpattern</span>, <span class="hljs-property">@operatorToken</span>} = options
    forbidden = (name = <span class="hljs-property">@variable</span>.unwrapAll().value) <span class="hljs-keyword">in</span> STRICT_PROSCRIBED
    <span class="hljs-keyword">if</span> forbidden <span class="hljs-keyword">and</span> <span class="hljs-property">@context</span> <span class="hljs-keyword">isnt</span> <span class="hljs-string">'object'</span>
      <span class="hljs-property">@variable</span>.error <span class="hljs-string">"variable name may not be \"<span class="hljs-subst">#{name}</span>\""</span>

  <span class="hljs-attribute">children</span>: [<span class="hljs-string">'variable'</span>, <span class="hljs-string">'value'</span>]

  <span class="hljs-attribute">isStatement</span>: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    o?.level <span class="hljs-keyword">is</span> LEVEL_TOP <span class="hljs-keyword">and</span> <span class="hljs-property">@context</span>? <span class="hljs-keyword">and</span> <span class="hljs-string">"?"</span> <span class="hljs-keyword">in</span> <span class="hljs-property">@context</span>

  <span class="hljs-attribute">assigns</span>: <span class="hljs-function"><span class="hljs-params">(name)</span> -&gt;</span>
    @[<span class="hljs-keyword">if</span> <span class="hljs-property">@context</span> <span class="hljs-keyword">is</span> <span class="hljs-string">'object'</span> <span class="hljs-keyword">then</span> <span class="hljs-string">'value'</span> <span class="hljs-keyword">else</span> <span class="hljs-string">'variable'</span>].assigns name

  <span class="hljs-attribute">unfoldSoak</span>: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    unfoldSoak o, <span class="hljs-keyword">this</span>, <span class="hljs-string">'variable'</span></pre></div></div>
            
        </li>
        
        
        <li id="section-97">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-97">&#182;</a>
              </div>
              <p>Compile an assignment, delegating to <code>compilePatternMatch</code> or
<code>compileSplice</code> if appropriate. Keep track of the name of the base object
we’ve been assigned to, for correct internal references. If the variable
has not been seen yet within the current scope, declare it.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">compileNode</span>: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-keyword">if</span> isValue = <span class="hljs-property">@variable</span> <span class="hljs-keyword">instanceof</span> Value
      <span class="hljs-keyword">return</span> <span class="hljs-property">@compilePatternMatch</span> o <span class="hljs-keyword">if</span> <span class="hljs-property">@variable</span>.isArray() <span class="hljs-keyword">or</span> <span class="hljs-property">@variable</span>.isObject()
      <span class="hljs-keyword">return</span> <span class="hljs-property">@compileSplice</span>       o <span class="hljs-keyword">if</span> <span class="hljs-property">@variable</span>.isSplice()
      <span class="hljs-keyword">return</span> <span class="hljs-property">@compileConditional</span>  o <span class="hljs-keyword">if</span> <span class="hljs-property">@context</span> <span class="hljs-keyword">in</span> [<span class="hljs-string">'||='</span>, <span class="hljs-string">'&amp;&amp;='</span>, <span class="hljs-string">'?='</span>]
      <span class="hljs-keyword">return</span> <span class="hljs-property">@compileSpecialMath</span>  o <span class="hljs-keyword">if</span> <span class="hljs-property">@context</span> <span class="hljs-keyword">in</span> [<span class="hljs-string">'**='</span>, <span class="hljs-string">'//='</span>, <span class="hljs-string">'%%='</span>]
    <span class="hljs-keyword">if</span> <span class="hljs-property">@value</span> <span class="hljs-keyword">instanceof</span> Code
      <span class="hljs-keyword">if</span> <span class="hljs-property">@value</span>.static
        <span class="hljs-property">@value</span>.klass = <span class="hljs-property">@variable</span>.base
        <span class="hljs-property">@value</span>.name  = <span class="hljs-property">@variable</span>.properties[<span class="hljs-number">0</span>]
        <span class="hljs-property">@value</span>.variable = <span class="hljs-property">@variable</span>
      <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> <span class="hljs-property">@variable</span>.properties?.length &gt;= <span class="hljs-number">2</span>
        [properties..., prototype, name] = <span class="hljs-property">@variable</span>.properties
        <span class="hljs-keyword">if</span> prototype.name?.value <span class="hljs-keyword">is</span> <span class="hljs-string">'prototype'</span>
          <span class="hljs-property">@value</span>.klass = <span class="hljs-keyword">new</span> Value <span class="hljs-property">@variable</span>.base, properties
          <span class="hljs-property">@value</span>.name  = name
          <span class="hljs-property">@value</span>.variable = <span class="hljs-property">@variable</span>
    <span class="hljs-keyword">unless</span> <span class="hljs-property">@context</span>
      varBase = <span class="hljs-property">@variable</span>.unwrapAll()
      <span class="hljs-keyword">unless</span> varBase.isAssignable()
        <span class="hljs-property">@variable</span>.error <span class="hljs-string">"\"<span class="hljs-subst">#{<span class="hljs-property">@variable</span>.compile o}</span>\" cannot be assigned"</span>
      <span class="hljs-keyword">unless</span> varBase.hasProperties?()
        <span class="hljs-keyword">if</span> <span class="hljs-property">@param</span>
          o.scope.add varBase.value, <span class="hljs-string">'var'</span>
        <span class="hljs-keyword">else</span>
          o.scope.find varBase.value
    val = <span class="hljs-property">@value</span>.compileToFragments o, LEVEL_LIST
    <span class="hljs-property">@variable</span>.front = <span class="hljs-literal">true</span> <span class="hljs-keyword">if</span> isValue <span class="hljs-keyword">and</span> <span class="hljs-property">@variable</span>.base <span class="hljs-keyword">instanceof</span> Obj
    compiledName = <span class="hljs-property">@variable</span>.compileToFragments o, LEVEL_LIST
    <span class="hljs-keyword">return</span> (compiledName.concat <span class="hljs-property">@makeCode</span>(<span class="hljs-string">": "</span>), val) <span class="hljs-keyword">if</span> <span class="hljs-property">@context</span> <span class="hljs-keyword">is</span> <span class="hljs-string">'object'</span>
    answer = compiledName.concat <span class="hljs-property">@makeCode</span>(<span class="hljs-string">" <span class="hljs-subst">#{ <span class="hljs-property">@context</span> <span class="hljs-keyword">or</span> <span class="hljs-string">'='</span> }</span> "</span>), val
    <span class="hljs-keyword">if</span> o.level &lt;= LEVEL_LIST <span class="hljs-keyword">then</span> answer <span class="hljs-keyword">else</span> <span class="hljs-property">@wrapInBraces</span> answer</pre></div></div>
            
        </li>
        
        
        <li id="section-98">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-98">&#182;</a>
              </div>
              <p>Brief implementation of recursive pattern matching, when assigning array or
object literals to a value. Peeks at their properties to assign inner names.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">compilePatternMatch</span>: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    top       = o.level <span class="hljs-keyword">is</span> LEVEL_TOP
    {value}   = <span class="hljs-keyword">this</span>
    {objects} = <span class="hljs-property">@variable</span>.base
    <span class="hljs-keyword">unless</span> olen = objects.length
      code = value.compileToFragments o
      <span class="hljs-keyword">return</span> <span class="hljs-keyword">if</span> o.level &gt;= LEVEL_OP <span class="hljs-keyword">then</span> <span class="hljs-property">@wrapInBraces</span> code <span class="hljs-keyword">else</span> code
    [obj] = objects
    <span class="hljs-keyword">if</span> olen <span class="hljs-keyword">is</span> <span class="hljs-number">1</span> <span class="hljs-keyword">and</span> obj <span class="hljs-keyword">instanceof</span> Expansion
      obj.error <span class="hljs-string">'Destructuring assignment has no target'</span>
    isObject = <span class="hljs-property">@variable</span>.isObject()
    <span class="hljs-keyword">if</span> top <span class="hljs-keyword">and</span> olen <span class="hljs-keyword">is</span> <span class="hljs-number">1</span> <span class="hljs-keyword">and</span> obj <span class="hljs-keyword">not</span> <span class="hljs-keyword">instanceof</span> Splat</pre></div></div>
            
        </li>
        
        
        <li id="section-99">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-99">&#182;</a>
              </div>
              <p>Pick the property straight off the value when there’s just one to pick
(no need to cache the value into a variable).</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>      defaultValue = <span class="hljs-literal">null</span>
      <span class="hljs-keyword">if</span> obj <span class="hljs-keyword">instanceof</span> Assign <span class="hljs-keyword">and</span> obj.context <span class="hljs-keyword">is</span> <span class="hljs-string">'object'</span></pre></div></div>
            
        </li>
        
        
        <li id="section-100">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-100">&#182;</a>
              </div>
              <p>A regular object pattern-match.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>        {<span class="hljs-attribute">variable</span>: {<span class="hljs-attribute">base</span>: idx}, <span class="hljs-attribute">value</span>: obj} = obj
        <span class="hljs-keyword">if</span> obj <span class="hljs-keyword">instanceof</span> Assign
          defaultValue = obj.value
          obj = obj.variable
      <span class="hljs-keyword">else</span>
        <span class="hljs-keyword">if</span> obj <span class="hljs-keyword">instanceof</span> Assign
          defaultValue = obj.value
          obj = obj.variable
        idx = <span class="hljs-keyword">if</span> isObject</pre></div></div>
            
        </li>
        
        
        <li id="section-101">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-101">&#182;</a>
              </div>
              <p>A shorthand <code>{a, b, @c} = val</code> pattern-match.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>          <span class="hljs-keyword">if</span> obj.<span class="hljs-keyword">this</span> <span class="hljs-keyword">then</span> obj.properties[<span class="hljs-number">0</span>].name <span class="hljs-keyword">else</span> obj
        <span class="hljs-keyword">else</span></pre></div></div>
            
        </li>
        
        
        <li id="section-102">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-102">&#182;</a>
              </div>
              <p>A regular array pattern-match.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>          <span class="hljs-keyword">new</span> Literal <span class="hljs-number">0</span>
      acc   = IDENTIFIER.test idx.unwrap().value
      value = <span class="hljs-keyword">new</span> Value value
      value.properties.push <span class="hljs-keyword">new</span> (<span class="hljs-keyword">if</span> acc <span class="hljs-keyword">then</span> Access <span class="hljs-keyword">else</span> Index) idx
      <span class="hljs-keyword">if</span> obj.unwrap().value <span class="hljs-keyword">in</span> RESERVED
        obj.error <span class="hljs-string">"assignment to a reserved word: <span class="hljs-subst">#{obj.compile o}</span>"</span>
      value = <span class="hljs-keyword">new</span> Op <span class="hljs-string">'?'</span>, value, defaultValue <span class="hljs-keyword">if</span> defaultValue
      <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> Assign(obj, value, <span class="hljs-literal">null</span>, <span class="hljs-attribute">param</span>: <span class="hljs-property">@param</span>).compileToFragments o, LEVEL_TOP
    vvar     = value.compileToFragments o, LEVEL_LIST
    vvarText = fragmentsToText vvar
    assigns  = []
    expandedIdx = <span class="hljs-literal">false</span></pre></div></div>
            
        </li>
        
        
        <li id="section-103">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-103">&#182;</a>
              </div>
              <p>Make vvar into a simple variable if it isn’t already.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> IDENTIFIER.test(vvarText) <span class="hljs-keyword">or</span> <span class="hljs-property">@variable</span>.assigns(vvarText)
      assigns.push [<span class="hljs-property">@makeCode</span>(<span class="hljs-string">"<span class="hljs-subst">#{ ref = o.scope.freeVariable <span class="hljs-string">'ref'</span> }</span> = "</span>), vvar...]
      vvar = [<span class="hljs-property">@makeCode</span> ref]
      vvarText = ref
    <span class="hljs-keyword">for</span> obj, i <span class="hljs-keyword">in</span> objects
      idx = i
      <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> expandedIdx <span class="hljs-keyword">and</span> obj <span class="hljs-keyword">instanceof</span> Splat
        name = obj.name.unwrap().value
        obj = obj.unwrap()
        val = <span class="hljs-string">"<span class="hljs-subst">#{olen}</span> &lt;= <span class="hljs-subst">#{vvarText}</span>.length ? <span class="hljs-subst">#{ utility <span class="hljs-string">'slice'</span>, o }</span>.call(<span class="hljs-subst">#{vvarText}</span>, <span class="hljs-subst">#{i}</span>"</span>
        <span class="hljs-keyword">if</span> rest = olen - i - <span class="hljs-number">1</span>
          ivar = o.scope.freeVariable <span class="hljs-string">'i'</span>, <span class="hljs-attribute">single</span>: <span class="hljs-literal">true</span>
          val += <span class="hljs-string">", <span class="hljs-subst">#{ivar}</span> = <span class="hljs-subst">#{vvarText}</span>.length - <span class="hljs-subst">#{rest}</span>) : (<span class="hljs-subst">#{ivar}</span> = <span class="hljs-subst">#{i}</span>, [])"</span>
        <span class="hljs-keyword">else</span>
          val += <span class="hljs-string">") : []"</span>
        val   = <span class="hljs-keyword">new</span> Literal val
        expandedIdx = <span class="hljs-string">"<span class="hljs-subst">#{ivar}</span>++"</span>
      <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> expandedIdx <span class="hljs-keyword">and</span> obj <span class="hljs-keyword">instanceof</span> Expansion
        <span class="hljs-keyword">if</span> rest = olen - i - <span class="hljs-number">1</span>
          <span class="hljs-keyword">if</span> rest <span class="hljs-keyword">is</span> <span class="hljs-number">1</span>
            expandedIdx = <span class="hljs-string">"<span class="hljs-subst">#{vvarText}</span>.length - 1"</span>
          <span class="hljs-keyword">else</span>
            ivar = o.scope.freeVariable <span class="hljs-string">'i'</span>, <span class="hljs-attribute">single</span>: <span class="hljs-literal">true</span>
            val = <span class="hljs-keyword">new</span> Literal <span class="hljs-string">"<span class="hljs-subst">#{ivar}</span> = <span class="hljs-subst">#{vvarText}</span>.length - <span class="hljs-subst">#{rest}</span>"</span>
            expandedIdx = <span class="hljs-string">"<span class="hljs-subst">#{ivar}</span>++"</span>
            assigns.push val.compileToFragments o, LEVEL_LIST
        <span class="hljs-keyword">continue</span>
      <span class="hljs-keyword">else</span>
        <span class="hljs-keyword">if</span> obj <span class="hljs-keyword">instanceof</span> Splat <span class="hljs-keyword">or</span> obj <span class="hljs-keyword">instanceof</span> Expansion
          obj.error <span class="hljs-string">"multiple splats/expansions are disallowed in an assignment"</span>
        defaultValue = <span class="hljs-literal">null</span>
        <span class="hljs-keyword">if</span> obj <span class="hljs-keyword">instanceof</span> Assign <span class="hljs-keyword">and</span> obj.context <span class="hljs-keyword">is</span> <span class="hljs-string">'object'</span></pre></div></div>
            
        </li>
        
        
        <li id="section-104">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-104">&#182;</a>
              </div>
              <p>A regular object pattern-match.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>          {<span class="hljs-attribute">variable</span>: {<span class="hljs-attribute">base</span>: idx}, <span class="hljs-attribute">value</span>: obj} = obj
          <span class="hljs-keyword">if</span> obj <span class="hljs-keyword">instanceof</span> Assign
            defaultValue = obj.value
            obj = obj.variable
        <span class="hljs-keyword">else</span>
          <span class="hljs-keyword">if</span> obj <span class="hljs-keyword">instanceof</span> Assign
            defaultValue = obj.value
            obj = obj.variable
          idx = <span class="hljs-keyword">if</span> isObject</pre></div></div>
            
        </li>
        
        
        <li id="section-105">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-105">&#182;</a>
              </div>
              <p>A shorthand <code>{a, b, @c} = val</code> pattern-match.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>            <span class="hljs-keyword">if</span> obj.<span class="hljs-keyword">this</span> <span class="hljs-keyword">then</span> obj.properties[<span class="hljs-number">0</span>].name <span class="hljs-keyword">else</span> obj
          <span class="hljs-keyword">else</span></pre></div></div>
            
        </li>
        
        
        <li id="section-106">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-106">&#182;</a>
              </div>
              <p>A regular array pattern-match.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>            <span class="hljs-keyword">new</span> Literal expandedIdx <span class="hljs-keyword">or</span> idx
        name = obj.unwrap().value
        acc = IDENTIFIER.test idx.unwrap().value
        val = <span class="hljs-keyword">new</span> Value <span class="hljs-keyword">new</span> Literal(vvarText), [<span class="hljs-keyword">new</span> (<span class="hljs-keyword">if</span> acc <span class="hljs-keyword">then</span> Access <span class="hljs-keyword">else</span> Index) idx]
        val = <span class="hljs-keyword">new</span> Op <span class="hljs-string">'?'</span>, val, defaultValue <span class="hljs-keyword">if</span> defaultValue
      <span class="hljs-keyword">if</span> name? <span class="hljs-keyword">and</span> name <span class="hljs-keyword">in</span> RESERVED
        obj.error <span class="hljs-string">"assignment to a reserved word: <span class="hljs-subst">#{obj.compile o}</span>"</span>
      assigns.push <span class="hljs-keyword">new</span> Assign(obj, val, <span class="hljs-literal">null</span>, <span class="hljs-attribute">param</span>: <span class="hljs-property">@param</span>, <span class="hljs-attribute">subpattern</span>: <span class="hljs-literal">yes</span>).compileToFragments o, LEVEL_LIST
    assigns.push vvar <span class="hljs-keyword">unless</span> top <span class="hljs-keyword">or</span> <span class="hljs-property">@subpattern</span>
    fragments = <span class="hljs-property">@joinFragmentArrays</span> assigns, <span class="hljs-string">', '</span>
    <span class="hljs-keyword">if</span> o.level &lt; LEVEL_LIST <span class="hljs-keyword">then</span> fragments <span class="hljs-keyword">else</span> <span class="hljs-property">@wrapInBraces</span> fragments</pre></div></div>
            
        </li>
        
        
        <li id="section-107">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-107">&#182;</a>
              </div>
              <p>When compiling a conditional assignment, take care to ensure that the
operands are only evaluated once, even though we have to reference them
more than once.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">compileConditional</span>: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    [left, right] = <span class="hljs-property">@variable</span>.cacheReference o</pre></div></div>
            
        </li>
        
        
        <li id="section-108">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-108">&#182;</a>
              </div>
              <p>Disallow conditional assignment of undefined variables.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> left.properties.length <span class="hljs-keyword">and</span> left.base <span class="hljs-keyword">instanceof</span> Literal <span class="hljs-keyword">and</span>
           left.base.value != <span class="hljs-string">"this"</span> <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> o.scope.check left.base.value
      <span class="hljs-property">@variable</span>.error <span class="hljs-string">"the variable \"<span class="hljs-subst">#{left.base.value}</span>\" can't be assigned with <span class="hljs-subst">#{<span class="hljs-property">@context</span>}</span> because it has not been declared before"</span>
    <span class="hljs-keyword">if</span> <span class="hljs-string">"?"</span> <span class="hljs-keyword">in</span> <span class="hljs-property">@context</span>
      o.isExistentialEquals = <span class="hljs-literal">true</span>
      <span class="hljs-keyword">new</span> If(<span class="hljs-keyword">new</span> Existence(left), right, <span class="hljs-attribute">type</span>: <span class="hljs-string">'if'</span>).addElse(<span class="hljs-keyword">new</span> Assign(right, <span class="hljs-property">@value</span>, <span class="hljs-string">'='</span>)).compileToFragments o
    <span class="hljs-keyword">else</span>
      fragments = <span class="hljs-keyword">new</span> Op(<span class="hljs-property">@context</span>[...-<span class="hljs-number">1</span>], left, <span class="hljs-keyword">new</span> Assign(right, <span class="hljs-property">@value</span>, <span class="hljs-string">'='</span>)).compileToFragments o
      <span class="hljs-keyword">if</span> o.level &lt;= LEVEL_LIST <span class="hljs-keyword">then</span> fragments <span class="hljs-keyword">else</span> <span class="hljs-property">@wrapInBraces</span> fragments</pre></div></div>
            
        </li>
        
        
        <li id="section-109">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-109">&#182;</a>
              </div>
              <p>Convert special math assignment operators like <code>a **= b</code> to the equivalent
extended form <code>a = a ** b</code> and then compiles that.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">compileSpecialMath</span>: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    [left, right] = <span class="hljs-property">@variable</span>.cacheReference o
    <span class="hljs-keyword">new</span> Assign(left, <span class="hljs-keyword">new</span> Op(<span class="hljs-property">@context</span>[...-<span class="hljs-number">1</span>], right, <span class="hljs-property">@value</span>)).compileToFragments o</pre></div></div>
            
        </li>
        
        
        <li id="section-110">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-110">&#182;</a>
              </div>
              <p>Compile the assignment from an array splice literal, using JavaScript’s
<code>Array#splice</code> method.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">compileSplice</span>: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    {<span class="hljs-attribute">range</span>: {from, to, exclusive}} = <span class="hljs-property">@variable</span>.properties.pop()
    name = <span class="hljs-property">@variable</span>.compile o
    <span class="hljs-keyword">if</span> from
      [fromDecl, fromRef] = <span class="hljs-property">@cacheToCodeFragments</span> from.cache o, LEVEL_OP
    <span class="hljs-keyword">else</span>
      fromDecl = fromRef = <span class="hljs-string">'0'</span>
    <span class="hljs-keyword">if</span> to
      <span class="hljs-keyword">if</span> from <span class="hljs-keyword">instanceof</span> Value <span class="hljs-keyword">and</span> from.isSimpleNumber() <span class="hljs-keyword">and</span>
         to <span class="hljs-keyword">instanceof</span> Value <span class="hljs-keyword">and</span> to.isSimpleNumber()
        to = to.compile(o) - fromRef
        to += <span class="hljs-number">1</span> <span class="hljs-keyword">unless</span> exclusive
      <span class="hljs-keyword">else</span>
        to = to.compile(o, LEVEL_ACCESS) + <span class="hljs-string">' - '</span> + fromRef
        to += <span class="hljs-string">' + 1'</span> <span class="hljs-keyword">unless</span> exclusive
    <span class="hljs-keyword">else</span>
      to = <span class="hljs-string">"9e9"</span>
    [valDef, valRef] = <span class="hljs-property">@value</span>.cache o, LEVEL_LIST
    answer = [].concat <span class="hljs-property">@makeCode</span>(<span class="hljs-string">"[].splice.apply(<span class="hljs-subst">#{name}</span>, [<span class="hljs-subst">#{fromDecl}</span>, <span class="hljs-subst">#{to}</span>].concat("</span>), valDef, <span class="hljs-property">@makeCode</span>(<span class="hljs-string">")), "</span>), valRef
    <span class="hljs-keyword">if</span> o.level &gt; LEVEL_TOP <span class="hljs-keyword">then</span> <span class="hljs-property">@wrapInBraces</span> answer <span class="hljs-keyword">else</span> answer</pre></div></div>
            
        </li>
        
        
        <li id="section-111">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-111">&#182;</a>
              </div>
              <h3 id="code">Code</h3>

            </div>
            
        </li>
        
        
        <li id="section-112">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-112">&#182;</a>
              </div>
              <p>A function definition. This is the only node that creates a new Scope.
When for the purposes of walking the contents of a function body, the Code
has no <em>children</em> — they’re within the inner scope.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.Code = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Code</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  <span class="hljs-attribute">constructor</span>: <span class="hljs-function"><span class="hljs-params">(params, body, tag)</span> -&gt;</span>
    <span class="hljs-property">@params</span>      = params <span class="hljs-keyword">or</span> []
    <span class="hljs-property">@body</span>        = body <span class="hljs-keyword">or</span> <span class="hljs-keyword">new</span> Block
    <span class="hljs-property">@bound</span>       = tag <span class="hljs-keyword">is</span> <span class="hljs-string">'boundfunc'</span>
    <span class="hljs-property">@isGenerator</span> = !!<span class="hljs-property">@body</span>.contains <span class="hljs-function"><span class="hljs-params">(node)</span> -&gt;</span>
      node <span class="hljs-keyword">instanceof</span> Op <span class="hljs-keyword">and</span> node.operator <span class="hljs-keyword">in</span> [<span class="hljs-string">'yield'</span>, <span class="hljs-string">'yield*'</span>]

  <span class="hljs-attribute">children</span>: [<span class="hljs-string">'params'</span>, <span class="hljs-string">'body'</span>]

  <span class="hljs-attribute">isStatement</span>:<span class="hljs-function"> -&gt;</span> !!<span class="hljs-property">@ctor</span>

  <span class="hljs-attribute">jumps</span>: NO

  <span class="hljs-attribute">makeScope</span>: <span class="hljs-function"><span class="hljs-params">(parentScope)</span> -&gt;</span> <span class="hljs-keyword">new</span> Scope parentScope, <span class="hljs-property">@body</span>, <span class="hljs-keyword">this</span></pre></div></div>
            
        </li>
        
        
        <li id="section-113">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-113">&#182;</a>
              </div>
              <p>Compilation creates a new scope unless explicitly asked to share with the
outer scope. Handles splat parameters in the parameter list by peeking at
the JavaScript <code>arguments</code> object. If the function is bound with the <code>=&gt;</code>
arrow, generates a wrapper that saves the current value of <code>this</code> through
a closure.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">compileNode</span>: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>

    <span class="hljs-keyword">if</span> <span class="hljs-property">@bound</span> <span class="hljs-keyword">and</span> o.scope.method?.bound
      <span class="hljs-property">@context</span> = o.scope.method.context</pre></div></div>
            
        </li>
        
        
        <li id="section-114">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-114">&#182;</a>
              </div>
              <p>Handle bound functions early.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    <span class="hljs-keyword">if</span> <span class="hljs-property">@bound</span> <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> <span class="hljs-property">@context</span>
      <span class="hljs-property">@context</span> = <span class="hljs-string">'_this'</span>
      wrapper = <span class="hljs-keyword">new</span> Code [<span class="hljs-keyword">new</span> Param <span class="hljs-keyword">new</span> Literal <span class="hljs-property">@context</span>], <span class="hljs-keyword">new</span> Block [<span class="hljs-keyword">this</span>]
      boundfunc = <span class="hljs-keyword">new</span> Call(wrapper, [<span class="hljs-keyword">new</span> Literal <span class="hljs-string">'this'</span>])
      boundfunc.updateLocationDataIfMissing <span class="hljs-property">@locationData</span>
      <span class="hljs-keyword">return</span> boundfunc.compileNode(o)

    o.scope         = del(o, <span class="hljs-string">'classScope'</span>) <span class="hljs-keyword">or</span> <span class="hljs-property">@makeScope</span> o.scope
    o.scope.shared  = del(o, <span class="hljs-string">'sharedScope'</span>)
    o.indent        += TAB
    <span class="hljs-keyword">delete</span> o.bare
    <span class="hljs-keyword">delete</span> o.isExistentialEquals
    params = []
    exprs  = []
    <span class="hljs-keyword">for</span> param <span class="hljs-keyword">in</span> <span class="hljs-property">@params</span> <span class="hljs-keyword">when</span> param <span class="hljs-keyword">not</span> <span class="hljs-keyword">instanceof</span> Expansion
      o.scope.parameter param.asReference o
    <span class="hljs-keyword">for</span> param <span class="hljs-keyword">in</span> <span class="hljs-property">@params</span> <span class="hljs-keyword">when</span> param.splat <span class="hljs-keyword">or</span> param <span class="hljs-keyword">instanceof</span> Expansion
      <span class="hljs-keyword">for</span> p <span class="hljs-keyword">in</span> <span class="hljs-property">@params</span> <span class="hljs-keyword">when</span> p <span class="hljs-keyword">not</span> <span class="hljs-keyword">instanceof</span> Expansion <span class="hljs-keyword">and</span> p.name.value
        o.scope.add p.name.value, <span class="hljs-string">'var'</span>, <span class="hljs-literal">yes</span>
      splats = <span class="hljs-keyword">new</span> Assign <span class="hljs-keyword">new</span> Value(<span class="hljs-keyword">new</span> Arr(p.asReference o <span class="hljs-keyword">for</span> p <span class="hljs-keyword">in</span> <span class="hljs-property">@params</span>)),
                          <span class="hljs-keyword">new</span> Value <span class="hljs-keyword">new</span> Literal <span class="hljs-string">'arguments'</span>
      <span class="hljs-keyword">break</span>
    <span class="hljs-keyword">for</span> param <span class="hljs-keyword">in</span> <span class="hljs-property">@params</span>
      <span class="hljs-keyword">if</span> param.isComplex()
        val = ref = param.asReference o
        val = <span class="hljs-keyword">new</span> Op <span class="hljs-string">'?'</span>, ref, param.value <span class="hljs-keyword">if</span> param.value
        exprs.push <span class="hljs-keyword">new</span> Assign <span class="hljs-keyword">new</span> Value(param.name), val, <span class="hljs-string">'='</span>, <span class="hljs-attribute">param</span>: <span class="hljs-literal">yes</span>
      <span class="hljs-keyword">else</span>
        ref = param
        <span class="hljs-keyword">if</span> param.value
          lit = <span class="hljs-keyword">new</span> Literal ref.name.value + <span class="hljs-string">' == null'</span>
          val = <span class="hljs-keyword">new</span> Assign <span class="hljs-keyword">new</span> Value(param.name), param.value, <span class="hljs-string">'='</span>
          exprs.push <span class="hljs-keyword">new</span> If lit, val
      params.push ref <span class="hljs-keyword">unless</span> splats
    wasEmpty = <span class="hljs-property">@body</span>.isEmpty()
    exprs.unshift splats <span class="hljs-keyword">if</span> splats
    <span class="hljs-property">@body</span>.expressions.unshift exprs... <span class="hljs-keyword">if</span> exprs.length
    <span class="hljs-keyword">for</span> p, i <span class="hljs-keyword">in</span> params
      params[i] = p.compileToFragments o
      o.scope.parameter fragmentsToText params[i]
    uniqs = []
    <span class="hljs-property">@eachParamName</span> <span class="hljs-function"><span class="hljs-params">(name, node)</span> -&gt;</span>
      node.error <span class="hljs-string">"multiple parameters named <span class="hljs-subst">#{name}</span>"</span> <span class="hljs-keyword">if</span> name <span class="hljs-keyword">in</span> uniqs
      uniqs.push name
    <span class="hljs-property">@body</span>.makeReturn() <span class="hljs-keyword">unless</span> wasEmpty <span class="hljs-keyword">or</span> <span class="hljs-property">@noReturn</span>
    code = <span class="hljs-string">'function'</span>
    code += <span class="hljs-string">'*'</span> <span class="hljs-keyword">if</span> <span class="hljs-property">@isGenerator</span>
    code += <span class="hljs-string">' '</span> + <span class="hljs-property">@name</span> <span class="hljs-keyword">if</span> <span class="hljs-property">@ctor</span>
    code += <span class="hljs-string">'('</span>
    answer = [<span class="hljs-property">@makeCode</span>(code)]
    <span class="hljs-keyword">for</span> p, i <span class="hljs-keyword">in</span> params
      <span class="hljs-keyword">if</span> i <span class="hljs-keyword">then</span> answer.push <span class="hljs-property">@makeCode</span> <span class="hljs-string">", "</span>
      answer.push p...
    answer.push <span class="hljs-property">@makeCode</span> <span class="hljs-string">') {'</span>
    answer = answer.concat(<span class="hljs-property">@makeCode</span>(<span class="hljs-string">"\n"</span>), <span class="hljs-property">@body</span>.compileWithDeclarations(o), <span class="hljs-property">@makeCode</span>(<span class="hljs-string">"\n<span class="hljs-subst">#{<span class="hljs-property">@tab</span>}</span>"</span>)) <span class="hljs-keyword">unless</span> <span class="hljs-property">@body</span>.isEmpty()
    answer.push <span class="hljs-property">@makeCode</span> <span class="hljs-string">'}'</span>

    <span class="hljs-keyword">return</span> [<span class="hljs-property">@makeCode</span>(<span class="hljs-property">@tab</span>), answer...] <span class="hljs-keyword">if</span> <span class="hljs-property">@ctor</span>
    <span class="hljs-keyword">if</span> <span class="hljs-property">@front</span> <span class="hljs-keyword">or</span> (o.level &gt;= LEVEL_ACCESS) <span class="hljs-keyword">then</span> <span class="hljs-property">@wrapInBraces</span> answer <span class="hljs-keyword">else</span> answer

  <span class="hljs-attribute">eachParamName</span>: <span class="hljs-function"><span class="hljs-params">(iterator)</span> -&gt;</span>
    param.eachName iterator <span class="hljs-keyword">for</span> param <span class="hljs-keyword">in</span> <span class="hljs-property">@params</span></pre></div></div>
            
        </li>
        
        
        <li id="section-115">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-115">&#182;</a>
              </div>
              <p>Short-circuit <code>traverseChildren</code> method to prevent it from crossing scope boundaries
unless <code>crossScope</code> is <code>true</code>.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">traverseChildren</span>: <span class="hljs-function"><span class="hljs-params">(crossScope, func)</span> -&gt;</span>
    <span class="hljs-keyword">super</span>(crossScope, func) <span class="hljs-keyword">if</span> crossScope</pre></div></div>
            
        </li>
        
        
        <li id="section-116">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-116">&#182;</a>
              </div>
              <h3 id="param">Param</h3>

            </div>
            
        </li>
        
        
        <li id="section-117">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-117">&#182;</a>
              </div>
              <p>A parameter in a function definition. Beyond a typical Javascript parameter,
these parameters can also attach themselves to the context of the function,
as well as be a splat, gathering up a group of parameters into an array.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.Param = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Param</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  <span class="hljs-attribute">constructor</span>: <span class="hljs-function"><span class="hljs-params">(<span class="hljs-property">@name</span>, <span class="hljs-property">@value</span>, <span class="hljs-property">@splat</span>)</span> -&gt;</span>
    <span class="hljs-keyword">if</span> (name = <span class="hljs-property">@name</span>.unwrapAll().value) <span class="hljs-keyword">in</span> STRICT_PROSCRIBED
      <span class="hljs-property">@name</span>.error <span class="hljs-string">"parameter name \"<span class="hljs-subst">#{name}</span>\" is not allowed"</span>
    <span class="hljs-keyword">if</span> <span class="hljs-property">@name</span> <span class="hljs-keyword">instanceof</span> Obj <span class="hljs-keyword">and</span> <span class="hljs-property">@name</span>.generated
      token = <span class="hljs-property">@name</span>.objects[<span class="hljs-number">0</span>].operatorToken
      token.error <span class="hljs-string">"unexpected <span class="hljs-subst">#{token.value}</span>"</span>

  <span class="hljs-attribute">children</span>: [<span class="hljs-string">'name'</span>, <span class="hljs-string">'value'</span>]

  <span class="hljs-attribute">compileToFragments</span>: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-property">@name</span>.compileToFragments o, LEVEL_LIST

  <span class="hljs-attribute">asReference</span>: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-keyword">return</span> <span class="hljs-property">@reference</span> <span class="hljs-keyword">if</span> <span class="hljs-property">@reference</span>
    node = <span class="hljs-property">@name</span>
    <span class="hljs-keyword">if</span> node.<span class="hljs-keyword">this</span>
      name = node.properties[<span class="hljs-number">0</span>].name.value
      name = <span class="hljs-string">"_<span class="hljs-subst">#{name}</span>"</span> <span class="hljs-keyword">if</span> name.reserved
      node = <span class="hljs-keyword">new</span> Literal o.scope.freeVariable name
    <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> node.isComplex()
      node = <span class="hljs-keyword">new</span> Literal o.scope.freeVariable <span class="hljs-string">'arg'</span>
    node = <span class="hljs-keyword">new</span> Value node
    node = <span class="hljs-keyword">new</span> Splat node <span class="hljs-keyword">if</span> <span class="hljs-property">@splat</span>
    node.updateLocationDataIfMissing <span class="hljs-property">@locationData</span>
    <span class="hljs-property">@reference</span> = node

  <span class="hljs-attribute">isComplex</span>:<span class="hljs-function"> -&gt;</span>
    <span class="hljs-property">@name</span>.isComplex()</pre></div></div>
            
        </li>
        
        
        <li id="section-118">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-118">&#182;</a>
              </div>
              <p>Iterates the name or names of a <code>Param</code>.
In a sense, a destructured parameter represents multiple JS parameters. This
method allows to iterate them all.
The <code>iterator</code> function will be called as <code>iterator(name, node)</code> where
<code>name</code> is the name of the parameter and <code>node</code> is the AST node corresponding
to that name.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">eachName</span>: <span class="hljs-function"><span class="hljs-params">(iterator, name = <span class="hljs-property">@name</span>)</span>-&gt;</span>
    <span class="hljs-function"><span class="hljs-title">atParam</span> = <span class="hljs-params">(obj)</span> -&gt;</span> iterator <span class="hljs-string">"@<span class="hljs-subst">#{obj.properties[<span class="hljs-number">0</span>].name.value}</span>"</span>, obj</pre></div></div>
            
        </li>
        
        
        <li id="section-119">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-119">&#182;</a>
              </div>
              <ul>
<li>simple literals <code>foo</code></li>
</ul>

            </div>
            
            <div class="content"><div class='highlight'><pre>    <span class="hljs-keyword">return</span> iterator name.value, name <span class="hljs-keyword">if</span> name <span class="hljs-keyword">instanceof</span> Literal</pre></div></div>
            
        </li>
        
        
        <li id="section-120">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-120">&#182;</a>
              </div>
              <ul>
<li>at-params <code>@foo</code></li>
</ul>

            </div>
            
            <div class="content"><div class='highlight'><pre>    <span class="hljs-keyword">return</span> atParam name <span class="hljs-keyword">if</span> name <span class="hljs-keyword">instanceof</span> Value
    <span class="hljs-keyword">for</span> obj <span class="hljs-keyword">in</span> name.objects</pre></div></div>
            
        </li>
        
        
        <li id="section-121">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-121">&#182;</a>
              </div>
              <ul>
<li>destructured parameter with default value</li>
</ul>

            </div>
            
            <div class="content"><div class='highlight'><pre>      <span class="hljs-keyword">if</span> obj <span class="hljs-keyword">instanceof</span> Assign <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> obj.context?
        obj = obj.variable</pre></div></div>
            
        </li>
        
        
        <li id="section-122">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-122">&#182;</a>
              </div>
              <ul>
<li>assignments within destructured parameters <code>{foo:bar}</code></li>
</ul>

            </div>
            
            <div class="content"><div class='highlight'><pre>      <span class="hljs-keyword">if</span> obj <span class="hljs-keyword">instanceof</span> Assign
        <span class="hljs-property">@eachName</span> iterator, obj.value.unwrap()</pre></div></div>
            
        </li>
        
        
        <li id="section-123">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-123">&#182;</a>
              </div>
              <ul>
<li>splats within destructured parameters <code>[xs...]</code></li>
</ul>

            </div>
            
            <div class="content"><div class='highlight'><pre>      <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> obj <span class="hljs-keyword">instanceof</span> Splat
        node = obj.name.unwrap()
        iterator node.value, node
      <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> obj <span class="hljs-keyword">instanceof</span> Value</pre></div></div>
            
        </li>
        
        
        <li id="section-124">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-124">&#182;</a>
              </div>
              <ul>
<li>destructured parameters within destructured parameters <code>[{a}]</code></li>
</ul>

            </div>
            
            <div class="content"><div class='highlight'><pre>        <span class="hljs-keyword">if</span> obj.isArray() <span class="hljs-keyword">or</span> obj.isObject()
          <span class="hljs-property">@eachName</span> iterator, obj.base</pre></div></div>
            
        </li>
        
        
        <li id="section-125">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-125">&#182;</a>
              </div>
              <ul>
<li>at-params within destructured parameters <code>{@foo}</code></li>
</ul>

            </div>
            
            <div class="content"><div class='highlight'><pre>        <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> obj.<span class="hljs-keyword">this</span>
          atParam obj</pre></div></div>
            
        </li>
        
        
        <li id="section-126">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-126">&#182;</a>
              </div>
              <ul>
<li>simple destructured parameters {foo}</li>
</ul>

            </div>
            
            <div class="content"><div class='highlight'><pre>        <span class="hljs-keyword">else</span> iterator obj.base.value, obj.base
      <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> obj <span class="hljs-keyword">not</span> <span class="hljs-keyword">instanceof</span> Expansion
        obj.error <span class="hljs-string">"illegal parameter <span class="hljs-subst">#{obj.compile()}</span>"</span>
    <span class="hljs-keyword">return</span></pre></div></div>
            
        </li>
        
        
        <li id="section-127">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-127">&#182;</a>
              </div>
              <h3 id="splat">Splat</h3>

            </div>
            
        </li>
        
        
        <li id="section-128">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-128">&#182;</a>
              </div>
              <p>A splat, either as a parameter to a function, an argument to a call,
or as part of a destructuring assignment.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.Splat = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Splat</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>

  <span class="hljs-attribute">children</span>: [<span class="hljs-string">'name'</span>]

  <span class="hljs-attribute">isAssignable</span>: YES

  <span class="hljs-attribute">constructor</span>: <span class="hljs-function"><span class="hljs-params">(name)</span> -&gt;</span>
    <span class="hljs-property">@name</span> = <span class="hljs-keyword">if</span> name.compile <span class="hljs-keyword">then</span> name <span class="hljs-keyword">else</span> <span class="hljs-keyword">new</span> Literal name

  <span class="hljs-attribute">assigns</span>: <span class="hljs-function"><span class="hljs-params">(name)</span> -&gt;</span>
    <span class="hljs-property">@name</span>.assigns name

  <span class="hljs-attribute">compileToFragments</span>: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-property">@name</span>.compileToFragments o

  <span class="hljs-attribute">unwrap</span>:<span class="hljs-function"> -&gt;</span> <span class="hljs-property">@name</span></pre></div></div>
            
        </li>
        
        
        <li id="section-129">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-129">&#182;</a>
              </div>
              <p>Utility function that converts an arbitrary number of elements, mixed with
splats, to a proper array.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  <span class="hljs-property">@compileSplattedArray</span>: <span class="hljs-function"><span class="hljs-params">(o, list, apply)</span> -&gt;</span>
    index = -<span class="hljs-number">1</span>
    <span class="hljs-keyword">continue</span> <span class="hljs-keyword">while</span> (node = list[++index]) <span class="hljs-keyword">and</span> node <span class="hljs-keyword">not</span> <span class="hljs-keyword">instanceof</span> Splat
    <span class="hljs-keyword">return</span> [] <span class="hljs-keyword">if</span> index &gt;= list.length
    <span class="hljs-keyword">if</span> list.length <span class="hljs-keyword">is</span> <span class="hljs-number">1</span>
      node = list[<span class="hljs-number">0</span>]
      fragments = node.compileToFragments o, LEVEL_LIST
      <span class="hljs-keyword">return</span> fragments <span class="hljs-keyword">if</span> apply
      <span class="hljs-keyword">return</span> [].concat node.makeCode(<span class="hljs-string">"<span class="hljs-subst">#{ utility <span class="hljs-string">'slice'</span>, o }</span>.call("</span>), fragments, node.makeCode(<span class="hljs-string">")"</span>)
    args = list[index..]
    <span class="hljs-keyword">for</span> node, i <span class="hljs-keyword">in</span> args
      compiledNode = node.compileToFragments o, LEVEL_LIST
      args[i] = <span class="hljs-keyword">if</span> node <span class="hljs-keyword">instanceof</span> Splat
      <span class="hljs-keyword">then</span> [].concat node.makeCode(<span class="hljs-string">"<span class="hljs-subst">#{ utility <span class="hljs-string">'slice'</span>, o }</span>.call("</span>), compiledNode, node.makeCode(<span class="hljs-string">")"</span>)
      <span class="hljs-keyword">else</span> [].concat node.makeCode(<span class="hljs-string">"["</span>), compiledNode, node.makeCode(<span class="hljs-string">"]"</span>)
    <span class="hljs-keyword">if</span> index <span class="hljs-keyword">is</span> <span class="hljs-number">0</span>
      node = list[<span class="hljs-number">0</span>]
      concatPart = (node.joinFragmentArrays args[<span class="hljs-number">1.</span>.], <span class="hljs-string">', '</span>)
      <span class="hljs-keyword">return</span> args[<span class="hljs-number">0</span>].concat node.makeCode(<span class="hljs-string">".concat("</span>), concatPart, node.makeCode(<span class="hljs-string">")"</span>)
    base = (node.compileToFragments o, LEVEL_LIST <span class="hljs-keyword">for</span> node <span class="hljs-keyword">in</span> list[...index])
    base = list[<span class="hljs-number">0</span>].joinFragmentArrays base, <span class="hljs-string">', '</span>
    concatPart = list[index].joinFragmentArrays args, <span class="hljs-string">', '</span>
    [..., last] = list
    [].concat list[<span class="hljs-number">0</span>].makeCode(<span class="hljs-string">"["</span>), base, list[index].makeCode(<span class="hljs-string">"].concat("</span>), concatPart, last.makeCode(<span class="hljs-string">")"</span>)</pre></div></div>
            
        </li>
        
        
        <li id="section-130">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-130">&#182;</a>
              </div>
              <h3 id="expansion">Expansion</h3>

            </div>
            
        </li>
        
        
        <li id="section-131">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-131">&#182;</a>
              </div>
              <p>Used to skip values inside an array destructuring (pattern matching) or
parameter list.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.Expansion = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Expansion</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>

  <span class="hljs-attribute">isComplex</span>: NO

  <span class="hljs-attribute">compileNode</span>: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-property">@error</span> <span class="hljs-string">'Expansion must be used inside a destructuring assignment or parameter list'</span>

  <span class="hljs-attribute">asReference</span>: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-keyword">this</span>

  <span class="hljs-attribute">eachName</span>: <span class="hljs-function"><span class="hljs-params">(iterator)</span> -&gt;</span></pre></div></div>
            
        </li>
        
        
        <li id="section-132">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-132">&#182;</a>
              </div>
              <h3 id="while">While</h3>

            </div>
            
        </li>
        
        
        <li id="section-133">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-133">&#182;</a>
              </div>
              <p>A while loop, the only sort of low-level loop exposed by CoffeeScript. From
it, all other loops can be manufactured. Useful in cases where you need more
flexibility or more speed than a comprehension can provide.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.While = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">While</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  <span class="hljs-attribute">constructor</span>: <span class="hljs-function"><span class="hljs-params">(condition, options)</span> -&gt;</span>
    <span class="hljs-property">@condition</span> = <span class="hljs-keyword">if</span> options?.invert <span class="hljs-keyword">then</span> condition.invert() <span class="hljs-keyword">else</span> condition
    <span class="hljs-property">@guard</span>     = options?.guard

  <span class="hljs-attribute">children</span>: [<span class="hljs-string">'condition'</span>, <span class="hljs-string">'guard'</span>, <span class="hljs-string">'body'</span>]

  <span class="hljs-attribute">isStatement</span>: YES

  <span class="hljs-attribute">makeReturn</span>: <span class="hljs-function"><span class="hljs-params">(res)</span> -&gt;</span>
    <span class="hljs-keyword">if</span> res
      <span class="hljs-keyword">super</span>
    <span class="hljs-keyword">else</span>
      <span class="hljs-property">@returns</span> = <span class="hljs-keyword">not</span> <span class="hljs-property">@jumps</span> <span class="hljs-attribute">loop</span>: <span class="hljs-literal">yes</span>
      <span class="hljs-keyword">this</span>

  <span class="hljs-attribute">addBody</span>: <span class="hljs-function"><span class="hljs-params">(<span class="hljs-property">@body</span>)</span> -&gt;</span>
    <span class="hljs-keyword">this</span>

  <span class="hljs-attribute">jumps</span>:<span class="hljs-function"> -&gt;</span>
    {expressions} = <span class="hljs-property">@body</span>
    <span class="hljs-keyword">return</span> <span class="hljs-literal">no</span> <span class="hljs-keyword">unless</span> expressions.length
    <span class="hljs-keyword">for</span> node <span class="hljs-keyword">in</span> expressions
      <span class="hljs-keyword">return</span> jumpNode <span class="hljs-keyword">if</span> jumpNode = node.jumps <span class="hljs-attribute">loop</span>: <span class="hljs-literal">yes</span>
    <span class="hljs-literal">no</span></pre></div></div>
            
        </li>
        
        
        <li id="section-134">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-134">&#182;</a>
              </div>
              <p>The main difference from a JavaScript <em>while</em> is that the CoffeeScript
<em>while</em> can be used as a part of a larger expression — while loops may
return an array containing the computed result of each iteration.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">compileNode</span>: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    o.indent += TAB
    set      = <span class="hljs-string">''</span>
    {body}   = <span class="hljs-keyword">this</span>
    <span class="hljs-keyword">if</span> body.isEmpty()
      body = <span class="hljs-property">@makeCode</span> <span class="hljs-string">''</span>
    <span class="hljs-keyword">else</span>
      <span class="hljs-keyword">if</span> <span class="hljs-property">@returns</span>
        body.makeReturn rvar = o.scope.freeVariable <span class="hljs-string">'results'</span>
        set  = <span class="hljs-string">"<span class="hljs-subst">#{<span class="hljs-property">@tab</span>}</span><span class="hljs-subst">#{rvar}</span> = [];\n"</span>
      <span class="hljs-keyword">if</span> <span class="hljs-property">@guard</span>
        <span class="hljs-keyword">if</span> body.expressions.length &gt; <span class="hljs-number">1</span>
          body.expressions.unshift <span class="hljs-keyword">new</span> If (<span class="hljs-keyword">new</span> Parens <span class="hljs-property">@guard</span>).invert(), <span class="hljs-keyword">new</span> Literal <span class="hljs-string">"continue"</span>
        <span class="hljs-keyword">else</span>
          body = Block.wrap [<span class="hljs-keyword">new</span> If <span class="hljs-property">@guard</span>, body] <span class="hljs-keyword">if</span> <span class="hljs-property">@guard</span>
      body = [].concat <span class="hljs-property">@makeCode</span>(<span class="hljs-string">"\n"</span>), (body.compileToFragments o, LEVEL_TOP), <span class="hljs-property">@makeCode</span>(<span class="hljs-string">"\n<span class="hljs-subst">#{<span class="hljs-property">@tab</span>}</span>"</span>)
    answer = [].concat <span class="hljs-property">@makeCode</span>(set + <span class="hljs-property">@tab</span> + <span class="hljs-string">"while ("</span>), <span class="hljs-property">@condition</span>.compileToFragments(o, LEVEL_PAREN),
      <span class="hljs-property">@makeCode</span>(<span class="hljs-string">") {"</span>), body, <span class="hljs-property">@makeCode</span>(<span class="hljs-string">"}"</span>)
    <span class="hljs-keyword">if</span> <span class="hljs-property">@returns</span>
      answer.push <span class="hljs-property">@makeCode</span> <span class="hljs-string">"\n<span class="hljs-subst">#{<span class="hljs-property">@tab</span>}</span>return <span class="hljs-subst">#{rvar}</span>;"</span>
    answer</pre></div></div>
            
        </li>
        
        
        <li id="section-135">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-135">&#182;</a>
              </div>
              <h3 id="op">Op</h3>

            </div>
            
        </li>
        
        
        <li id="section-136">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-136">&#182;</a>
              </div>
              <p>Simple Arithmetic and logical operations. Performs some conversion from
CoffeeScript operations into their JavaScript equivalents.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.Op = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Op</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  <span class="hljs-attribute">constructor</span>: <span class="hljs-function"><span class="hljs-params">(op, first, second, flip )</span> -&gt;</span>
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> In first, second <span class="hljs-keyword">if</span> op <span class="hljs-keyword">is</span> <span class="hljs-string">'in'</span>
    <span class="hljs-keyword">if</span> op <span class="hljs-keyword">is</span> <span class="hljs-string">'do'</span>
      <span class="hljs-keyword">return</span> <span class="hljs-property">@generateDo</span> first
    <span class="hljs-keyword">if</span> op <span class="hljs-keyword">is</span> <span class="hljs-string">'new'</span>
      <span class="hljs-keyword">return</span> first.newInstance() <span class="hljs-keyword">if</span> first <span class="hljs-keyword">instanceof</span> Call <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> first.<span class="hljs-keyword">do</span> <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> first.isNew
      first = <span class="hljs-keyword">new</span> Parens first   <span class="hljs-keyword">if</span> first <span class="hljs-keyword">instanceof</span> Code <span class="hljs-keyword">and</span> first.bound <span class="hljs-keyword">or</span> first.<span class="hljs-keyword">do</span>
    <span class="hljs-property">@operator</span> = CONVERSIONS[op] <span class="hljs-keyword">or</span> op
    <span class="hljs-property">@first</span>    = first
    <span class="hljs-property">@second</span>   = second
    <span class="hljs-property">@flip</span>     = !!flip
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span></pre></div></div>
            
        </li>
        
        
        <li id="section-137">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-137">&#182;</a>
              </div>
              <p>The map of conversions from CoffeeScript to JavaScript symbols.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  CONVERSIONS =
    <span class="hljs-string">'=='</span>:        <span class="hljs-string">'==='</span>
    <span class="hljs-string">'!='</span>:        <span class="hljs-string">'!=='</span>
    <span class="hljs-string">'of'</span>:        <span class="hljs-string">'in'</span>
    <span class="hljs-string">'yieldfrom'</span>: <span class="hljs-string">'yield*'</span></pre></div></div>
            
        </li>
        
        
        <li id="section-138">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-138">&#182;</a>
              </div>
              <p>The map of invertible operators.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  INVERSIONS =
    <span class="hljs-string">'!=='</span>: <span class="hljs-string">'==='</span>
    <span class="hljs-string">'==='</span>: <span class="hljs-string">'!=='</span>

  <span class="hljs-attribute">children</span>: [<span class="hljs-string">'first'</span>, <span class="hljs-string">'second'</span>]

  <span class="hljs-attribute">isSimpleNumber</span>: NO

  <span class="hljs-attribute">isYield</span>:<span class="hljs-function"> -&gt;</span>
    <span class="hljs-property">@operator</span> <span class="hljs-keyword">in</span> [<span class="hljs-string">'yield'</span>, <span class="hljs-string">'yield*'</span>]

  <span class="hljs-attribute">isYieldReturn</span>:<span class="hljs-function"> -&gt;</span>
    <span class="hljs-property">@isYield</span>() <span class="hljs-keyword">and</span> <span class="hljs-property">@first</span> <span class="hljs-keyword">instanceof</span> Return

  <span class="hljs-attribute">isUnary</span>:<span class="hljs-function"> -&gt;</span>
    <span class="hljs-keyword">not</span> <span class="hljs-property">@second</span>

  <span class="hljs-attribute">isComplex</span>:<span class="hljs-function"> -&gt;</span>
    <span class="hljs-keyword">not</span> (<span class="hljs-property">@isUnary</span>() <span class="hljs-keyword">and</span> <span class="hljs-property">@operator</span> <span class="hljs-keyword">in</span> [<span class="hljs-string">'+'</span>, <span class="hljs-string">'-'</span>] <span class="hljs-keyword">and</span>
         <span class="hljs-property">@first</span> <span class="hljs-keyword">instanceof</span> Value <span class="hljs-keyword">and</span> <span class="hljs-property">@first</span>.isSimpleNumber())</pre></div></div>
            
        </li>
        
        
        <li id="section-139">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-139">&#182;</a>
              </div>
              <p>Am I capable of
<a href="http://docs.python.org/reference/expressions.html#notin">Python-style comparison chaining</a>?</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">isChainable</span>:<span class="hljs-function"> -&gt;</span>
    <span class="hljs-property">@operator</span> <span class="hljs-keyword">in</span> [<span class="hljs-string">'&lt;'</span>, <span class="hljs-string">'&gt;'</span>, <span class="hljs-string">'&gt;='</span>, <span class="hljs-string">'&lt;='</span>, <span class="hljs-string">'==='</span>, <span class="hljs-string">'!=='</span>]

  <span class="hljs-attribute">invert</span>:<span class="hljs-function"> -&gt;</span>
    <span class="hljs-keyword">if</span> <span class="hljs-property">@isChainable</span>() <span class="hljs-keyword">and</span> <span class="hljs-property">@first</span>.isChainable()
      allInvertable = <span class="hljs-literal">yes</span>
      curr = <span class="hljs-keyword">this</span>
      <span class="hljs-keyword">while</span> curr <span class="hljs-keyword">and</span> curr.operator
        allInvertable <span class="hljs-keyword">and</span>= (curr.operator <span class="hljs-keyword">of</span> INVERSIONS)
        curr = curr.first
      <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> Parens(<span class="hljs-keyword">this</span>).invert() <span class="hljs-keyword">unless</span> allInvertable
      curr = <span class="hljs-keyword">this</span>
      <span class="hljs-keyword">while</span> curr <span class="hljs-keyword">and</span> curr.operator
        curr.invert = !curr.invert
        curr.operator = INVERSIONS[curr.operator]
        curr = curr.first
      <span class="hljs-keyword">this</span>
    <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> op = INVERSIONS[<span class="hljs-property">@operator</span>]
      <span class="hljs-property">@operator</span> = op
      <span class="hljs-keyword">if</span> <span class="hljs-property">@first</span>.unwrap() <span class="hljs-keyword">instanceof</span> Op
        <span class="hljs-property">@first</span>.invert()
      <span class="hljs-keyword">this</span>
    <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> <span class="hljs-property">@second</span>
      <span class="hljs-keyword">new</span> Parens(<span class="hljs-keyword">this</span>).invert()
    <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> <span class="hljs-property">@operator</span> <span class="hljs-keyword">is</span> <span class="hljs-string">'!'</span> <span class="hljs-keyword">and</span> (fst = <span class="hljs-property">@first</span>.unwrap()) <span class="hljs-keyword">instanceof</span> Op <span class="hljs-keyword">and</span>
                                  fst.operator <span class="hljs-keyword">in</span> [<span class="hljs-string">'!'</span>, <span class="hljs-string">'in'</span>, <span class="hljs-string">'instanceof'</span>]
      fst
    <span class="hljs-keyword">else</span>
      <span class="hljs-keyword">new</span> Op <span class="hljs-string">'!'</span>, <span class="hljs-keyword">this</span>

  <span class="hljs-attribute">unfoldSoak</span>: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-property">@operator</span> <span class="hljs-keyword">in</span> [<span class="hljs-string">'++'</span>, <span class="hljs-string">'--'</span>, <span class="hljs-string">'delete'</span>] <span class="hljs-keyword">and</span> unfoldSoak o, <span class="hljs-keyword">this</span>, <span class="hljs-string">'first'</span>

  <span class="hljs-attribute">generateDo</span>: <span class="hljs-function"><span class="hljs-params">(exp)</span> -&gt;</span>
    passedParams = []
    func = <span class="hljs-keyword">if</span> exp <span class="hljs-keyword">instanceof</span> Assign <span class="hljs-keyword">and</span> (ref = exp.value.unwrap()) <span class="hljs-keyword">instanceof</span> Code
      ref
    <span class="hljs-keyword">else</span>
      exp
    <span class="hljs-keyword">for</span> param <span class="hljs-keyword">in</span> func.params <span class="hljs-keyword">or</span> []
      <span class="hljs-keyword">if</span> param.value
        passedParams.push param.value
        <span class="hljs-keyword">delete</span> param.value
      <span class="hljs-keyword">else</span>
        passedParams.push param
    call = <span class="hljs-keyword">new</span> Call exp, passedParams
    call.<span class="hljs-keyword">do</span> = <span class="hljs-literal">yes</span>
    call

  <span class="hljs-attribute">compileNode</span>: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    isChain = <span class="hljs-property">@isChainable</span>() <span class="hljs-keyword">and</span> <span class="hljs-property">@first</span>.isChainable()</pre></div></div>
            
        </li>
        
        
        <li id="section-140">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-140">&#182;</a>
              </div>
              <p>In chains, there’s no need to wrap bare obj literals in parens,
as the chained expression is wrapped.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    <span class="hljs-property">@first</span>.front = <span class="hljs-property">@front</span> <span class="hljs-keyword">unless</span> isChain
    <span class="hljs-keyword">if</span> <span class="hljs-property">@operator</span> <span class="hljs-keyword">is</span> <span class="hljs-string">'delete'</span> <span class="hljs-keyword">and</span> o.scope.check(<span class="hljs-property">@first</span>.unwrapAll().value)
      <span class="hljs-property">@error</span> <span class="hljs-string">'delete operand may not be argument or var'</span>
    <span class="hljs-keyword">if</span> <span class="hljs-property">@operator</span> <span class="hljs-keyword">in</span> [<span class="hljs-string">'--'</span>, <span class="hljs-string">'++'</span>] <span class="hljs-keyword">and</span> <span class="hljs-property">@first</span>.unwrapAll().value <span class="hljs-keyword">in</span> STRICT_PROSCRIBED
      <span class="hljs-property">@error</span> <span class="hljs-string">"cannot increment/decrement \"<span class="hljs-subst">#{<span class="hljs-property">@first</span>.unwrapAll().value}</span>\""</span>
    <span class="hljs-keyword">return</span> <span class="hljs-property">@compileYield</span>     o <span class="hljs-keyword">if</span> <span class="hljs-property">@isYield</span>()
    <span class="hljs-keyword">return</span> <span class="hljs-property">@compileUnary</span>     o <span class="hljs-keyword">if</span> <span class="hljs-property">@isUnary</span>()
    <span class="hljs-keyword">return</span> <span class="hljs-property">@compileChain</span>     o <span class="hljs-keyword">if</span> isChain
    <span class="hljs-keyword">switch</span> <span class="hljs-property">@operator</span>
      <span class="hljs-keyword">when</span> <span class="hljs-string">'?'</span>  <span class="hljs-keyword">then</span> <span class="hljs-property">@compileExistence</span> o
      <span class="hljs-keyword">when</span> <span class="hljs-string">'**'</span> <span class="hljs-keyword">then</span> <span class="hljs-property">@compilePower</span> o
      <span class="hljs-keyword">when</span> <span class="hljs-string">'//'</span> <span class="hljs-keyword">then</span> <span class="hljs-property">@compileFloorDivision</span> o
      <span class="hljs-keyword">when</span> <span class="hljs-string">'%%'</span> <span class="hljs-keyword">then</span> <span class="hljs-property">@compileModulo</span> o
      <span class="hljs-keyword">else</span>
        lhs = <span class="hljs-property">@first</span>.compileToFragments o, LEVEL_OP
        rhs = <span class="hljs-property">@second</span>.compileToFragments o, LEVEL_OP
        answer = [].concat lhs, <span class="hljs-property">@makeCode</span>(<span class="hljs-string">" <span class="hljs-subst">#{<span class="hljs-property">@operator</span>}</span> "</span>), rhs
        <span class="hljs-keyword">if</span> o.level &lt;= LEVEL_OP <span class="hljs-keyword">then</span> answer <span class="hljs-keyword">else</span> <span class="hljs-property">@wrapInBraces</span> answer</pre></div></div>
            
        </li>
        
        
        <li id="section-141">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-141">&#182;</a>
              </div>
              <p>Mimic Python’s chained comparisons when multiple comparison operators are
used sequentially. For example:</p>
<pre><code>bin/coffee -e <span class="hljs-string">'console.log 50 &lt; 65 &gt; 10'</span>
<span class="hljs-literal">true</span>
</code></pre>
            </div>
            
            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">compileChain</span>: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    [<span class="hljs-property">@first</span>.second, shared] = <span class="hljs-property">@first</span>.second.cache o
    fst = <span class="hljs-property">@first</span>.compileToFragments o, LEVEL_OP
    fragments = fst.concat <span class="hljs-property">@makeCode</span>(<span class="hljs-string">" <span class="hljs-subst">#{<span class="hljs-keyword">if</span> <span class="hljs-property">@invert</span> <span class="hljs-keyword">then</span> <span class="hljs-string">'&amp;&amp;'</span> <span class="hljs-keyword">else</span> <span class="hljs-string">'||'</span>}</span> "</span>),
      (shared.compileToFragments o), <span class="hljs-property">@makeCode</span>(<span class="hljs-string">" <span class="hljs-subst">#{<span class="hljs-property">@operator</span>}</span> "</span>), (<span class="hljs-property">@second</span>.compileToFragments o, LEVEL_OP)
    <span class="hljs-property">@wrapInBraces</span> fragments</pre></div></div>
            
        </li>
        
        
        <li id="section-142">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-142">&#182;</a>
              </div>
              <p>Keep reference to the left expression, unless this an existential assignment</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">compileExistence</span>: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-keyword">if</span> <span class="hljs-property">@first</span>.isComplex()
      ref = <span class="hljs-keyword">new</span> Literal o.scope.freeVariable <span class="hljs-string">'ref'</span>
      fst = <span class="hljs-keyword">new</span> Parens <span class="hljs-keyword">new</span> Assign ref, <span class="hljs-property">@first</span>
    <span class="hljs-keyword">else</span>
      fst = <span class="hljs-property">@first</span>
      ref = fst
    <span class="hljs-keyword">new</span> If(<span class="hljs-keyword">new</span> Existence(fst), ref, <span class="hljs-attribute">type</span>: <span class="hljs-string">'if'</span>).addElse(<span class="hljs-property">@second</span>).compileToFragments o</pre></div></div>
            
        </li>
        
        
        <li id="section-143">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-143">&#182;</a>
              </div>
              <p>Compile a unary <strong>Op</strong>.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">compileUnary</span>: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    parts = []
    op = <span class="hljs-property">@operator</span>
    parts.push [<span class="hljs-property">@makeCode</span> op]
    <span class="hljs-keyword">if</span> op <span class="hljs-keyword">is</span> <span class="hljs-string">'!'</span> <span class="hljs-keyword">and</span> <span class="hljs-property">@first</span> <span class="hljs-keyword">instanceof</span> Existence
      <span class="hljs-property">@first</span>.negated = <span class="hljs-keyword">not</span> <span class="hljs-property">@first</span>.negated
      <span class="hljs-keyword">return</span> <span class="hljs-property">@first</span>.compileToFragments o
    <span class="hljs-keyword">if</span> o.level &gt;= LEVEL_ACCESS
      <span class="hljs-keyword">return</span> (<span class="hljs-keyword">new</span> Parens <span class="hljs-keyword">this</span>).compileToFragments o
    plusMinus = op <span class="hljs-keyword">in</span> [<span class="hljs-string">'+'</span>, <span class="hljs-string">'-'</span>]
    parts.push [<span class="hljs-property">@makeCode</span>(<span class="hljs-string">' '</span>)] <span class="hljs-keyword">if</span> op <span class="hljs-keyword">in</span> [<span class="hljs-string">'new'</span>, <span class="hljs-string">'typeof'</span>, <span class="hljs-string">'delete'</span>] <span class="hljs-keyword">or</span>
                      plusMinus <span class="hljs-keyword">and</span> <span class="hljs-property">@first</span> <span class="hljs-keyword">instanceof</span> Op <span class="hljs-keyword">and</span> <span class="hljs-property">@first</span>.operator <span class="hljs-keyword">is</span> op
    <span class="hljs-keyword">if</span> (plusMinus <span class="hljs-keyword">and</span> <span class="hljs-property">@first</span> <span class="hljs-keyword">instanceof</span> Op) <span class="hljs-keyword">or</span> (op <span class="hljs-keyword">is</span> <span class="hljs-string">'new'</span> <span class="hljs-keyword">and</span> <span class="hljs-property">@first</span>.isStatement o)
      <span class="hljs-property">@first</span> = <span class="hljs-keyword">new</span> Parens <span class="hljs-property">@first</span>
    parts.push <span class="hljs-property">@first</span>.compileToFragments o, LEVEL_OP
    parts.reverse() <span class="hljs-keyword">if</span> <span class="hljs-property">@flip</span>
    <span class="hljs-property">@joinFragmentArrays</span> parts, <span class="hljs-string">''</span>

  <span class="hljs-attribute">compileYield</span>: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    parts = []
    op = <span class="hljs-property">@operator</span>
    <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> o.scope.parent?
      <span class="hljs-property">@error</span> <span class="hljs-string">'yield statements must occur within a function generator.'</span>
    <span class="hljs-keyword">if</span> <span class="hljs-string">'expression'</span> <span class="hljs-keyword">in</span> Object.keys(<span class="hljs-property">@first</span>) <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> (<span class="hljs-property">@first</span> <span class="hljs-keyword">instanceof</span> Throw)
      <span class="hljs-keyword">if</span> <span class="hljs-property">@isYieldReturn</span>()
        parts.push <span class="hljs-property">@first</span>.compileToFragments o, LEVEL_TOP
      <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> <span class="hljs-property">@first</span>.expression?
        parts.push <span class="hljs-property">@first</span>.expression.compileToFragments o, LEVEL_OP
    <span class="hljs-keyword">else</span>
      parts.push [<span class="hljs-property">@makeCode</span> <span class="hljs-string">"(<span class="hljs-subst">#{op}</span> "</span>]
      parts.push <span class="hljs-property">@first</span>.compileToFragments o, LEVEL_OP
      parts.push [<span class="hljs-property">@makeCode</span> <span class="hljs-string">")"</span>]
    <span class="hljs-property">@joinFragmentArrays</span> parts, <span class="hljs-string">''</span>

  <span class="hljs-attribute">compilePower</span>: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span></pre></div></div>
            
        </li>
        
        
        <li id="section-144">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-144">&#182;</a>
              </div>
              <p>Make a Math.pow call</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    pow = <span class="hljs-keyword">new</span> Value <span class="hljs-keyword">new</span> Literal(<span class="hljs-string">'Math'</span>), [<span class="hljs-keyword">new</span> Access <span class="hljs-keyword">new</span> Literal <span class="hljs-string">'pow'</span>]
    <span class="hljs-keyword">new</span> Call(pow, [<span class="hljs-property">@first</span>, <span class="hljs-property">@second</span>]).compileToFragments o

  <span class="hljs-attribute">compileFloorDivision</span>: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    floor = <span class="hljs-keyword">new</span> Value <span class="hljs-keyword">new</span> Literal(<span class="hljs-string">'Math'</span>), [<span class="hljs-keyword">new</span> Access <span class="hljs-keyword">new</span> Literal <span class="hljs-string">'floor'</span>]
    div = <span class="hljs-keyword">new</span> Op <span class="hljs-string">'/'</span>, <span class="hljs-property">@first</span>, <span class="hljs-property">@second</span>
    <span class="hljs-keyword">new</span> Call(floor, [div]).compileToFragments o

  <span class="hljs-attribute">compileModulo</span>: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    mod = <span class="hljs-keyword">new</span> Value <span class="hljs-keyword">new</span> Literal utility <span class="hljs-string">'modulo'</span>, o
    <span class="hljs-keyword">new</span> Call(mod, [<span class="hljs-property">@first</span>, <span class="hljs-property">@second</span>]).compileToFragments o

  <span class="hljs-attribute">toString</span>: <span class="hljs-function"><span class="hljs-params">(idt)</span> -&gt;</span>
    <span class="hljs-keyword">super</span> idt, <span class="hljs-property">@constructor</span>.name + <span class="hljs-string">' '</span> + <span class="hljs-property">@operator</span></pre></div></div>
            
        </li>
        
        
        <li id="section-145">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-145">&#182;</a>
              </div>
              <h3 id="in">In</h3>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.In = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">In</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  <span class="hljs-attribute">constructor</span>: <span class="hljs-function"><span class="hljs-params">(<span class="hljs-property">@object</span>, <span class="hljs-property">@array</span>)</span> -&gt;</span>

  <span class="hljs-attribute">children</span>: [<span class="hljs-string">'object'</span>, <span class="hljs-string">'array'</span>]

  <span class="hljs-attribute">invert</span>: NEGATE

  <span class="hljs-attribute">compileNode</span>: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-keyword">if</span> <span class="hljs-property">@array</span> <span class="hljs-keyword">instanceof</span> Value <span class="hljs-keyword">and</span> <span class="hljs-property">@array</span>.isArray() <span class="hljs-keyword">and</span> <span class="hljs-property">@array</span>.base.objects.length
      <span class="hljs-keyword">for</span> obj <span class="hljs-keyword">in</span> <span class="hljs-property">@array</span>.base.objects <span class="hljs-keyword">when</span> obj <span class="hljs-keyword">instanceof</span> Splat
        hasSplat = <span class="hljs-literal">yes</span>
        <span class="hljs-keyword">break</span></pre></div></div>
            
        </li>
        
        
        <li id="section-146">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-146">&#182;</a>
              </div>
              <p><code>compileOrTest</code> only if we have an array literal with no splats</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>      <span class="hljs-keyword">return</span> <span class="hljs-property">@compileOrTest</span> o <span class="hljs-keyword">unless</span> hasSplat
    <span class="hljs-property">@compileLoopTest</span> o

  <span class="hljs-attribute">compileOrTest</span>: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    [sub, ref] = <span class="hljs-property">@object</span>.cache o, LEVEL_OP
    [cmp, cnj] = <span class="hljs-keyword">if</span> <span class="hljs-property">@negated</span> <span class="hljs-keyword">then</span> [<span class="hljs-string">' !== '</span>, <span class="hljs-string">' &amp;&amp; '</span>] <span class="hljs-keyword">else</span> [<span class="hljs-string">' === '</span>, <span class="hljs-string">' || '</span>]
    tests = []
    <span class="hljs-keyword">for</span> item, i <span class="hljs-keyword">in</span> <span class="hljs-property">@array</span>.base.objects
      <span class="hljs-keyword">if</span> i <span class="hljs-keyword">then</span> tests.push <span class="hljs-property">@makeCode</span> cnj
      tests = tests.concat (<span class="hljs-keyword">if</span> i <span class="hljs-keyword">then</span> ref <span class="hljs-keyword">else</span> sub), <span class="hljs-property">@makeCode</span>(cmp), item.compileToFragments(o, LEVEL_ACCESS)
    <span class="hljs-keyword">if</span> o.level &lt; LEVEL_OP <span class="hljs-keyword">then</span> tests <span class="hljs-keyword">else</span> <span class="hljs-property">@wrapInBraces</span> tests

  <span class="hljs-attribute">compileLoopTest</span>: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    [sub, ref] = <span class="hljs-property">@object</span>.cache o, LEVEL_LIST
    fragments = [].concat <span class="hljs-property">@makeCode</span>(utility(<span class="hljs-string">'indexOf'</span>, o) + <span class="hljs-string">".call("</span>), <span class="hljs-property">@array</span>.compileToFragments(o, LEVEL_LIST),
      <span class="hljs-property">@makeCode</span>(<span class="hljs-string">", "</span>), ref, <span class="hljs-property">@makeCode</span>(<span class="hljs-string">") "</span> + <span class="hljs-keyword">if</span> <span class="hljs-property">@negated</span> <span class="hljs-keyword">then</span> <span class="hljs-string">'&lt; 0'</span> <span class="hljs-keyword">else</span> <span class="hljs-string">'&gt;= 0'</span>)
    <span class="hljs-keyword">return</span> fragments <span class="hljs-keyword">if</span> fragmentsToText(sub) <span class="hljs-keyword">is</span> fragmentsToText(ref)
    fragments = sub.concat <span class="hljs-property">@makeCode</span>(<span class="hljs-string">', '</span>), fragments
    <span class="hljs-keyword">if</span> o.level &lt; LEVEL_LIST <span class="hljs-keyword">then</span> fragments <span class="hljs-keyword">else</span> <span class="hljs-property">@wrapInBraces</span> fragments

  <span class="hljs-attribute">toString</span>: <span class="hljs-function"><span class="hljs-params">(idt)</span> -&gt;</span>
    <span class="hljs-keyword">super</span> idt, <span class="hljs-property">@constructor</span>.name + <span class="hljs-keyword">if</span> <span class="hljs-property">@negated</span> <span class="hljs-keyword">then</span> <span class="hljs-string">'!'</span> <span class="hljs-keyword">else</span> <span class="hljs-string">''</span></pre></div></div>
            
        </li>
        
        
        <li id="section-147">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-147">&#182;</a>
              </div>
              <h3 id="try">Try</h3>

            </div>
            
        </li>
        
        
        <li id="section-148">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-148">&#182;</a>
              </div>
              <p>A classic <em>try/catch/finally</em> block.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.Try = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Try</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  <span class="hljs-attribute">constructor</span>: <span class="hljs-function"><span class="hljs-params">(<span class="hljs-property">@attempt</span>, <span class="hljs-property">@errorVariable</span>, <span class="hljs-property">@recovery</span>, <span class="hljs-property">@ensure</span>)</span> -&gt;</span>

  <span class="hljs-attribute">children</span>: [<span class="hljs-string">'attempt'</span>, <span class="hljs-string">'recovery'</span>, <span class="hljs-string">'ensure'</span>]

  <span class="hljs-attribute">isStatement</span>: YES

  <span class="hljs-attribute">jumps</span>: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span> <span class="hljs-property">@attempt</span>.jumps(o) <span class="hljs-keyword">or</span> <span class="hljs-property">@recovery</span>?.jumps(o)

  <span class="hljs-attribute">makeReturn</span>: <span class="hljs-function"><span class="hljs-params">(res)</span> -&gt;</span>
    <span class="hljs-property">@attempt</span>  = <span class="hljs-property">@attempt</span> .makeReturn res <span class="hljs-keyword">if</span> <span class="hljs-property">@attempt</span>
    <span class="hljs-property">@recovery</span> = <span class="hljs-property">@recovery</span>.makeReturn res <span class="hljs-keyword">if</span> <span class="hljs-property">@recovery</span>
    <span class="hljs-keyword">this</span></pre></div></div>
            
        </li>
        
        
        <li id="section-149">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-149">&#182;</a>
              </div>
              <p>Compilation is more or less as you would expect — the <em>finally</em> clause
is optional, the <em>catch</em> is not.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">compileNode</span>: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    o.indent  += TAB
    tryPart   = <span class="hljs-property">@attempt</span>.compileToFragments o, LEVEL_TOP

    catchPart = <span class="hljs-keyword">if</span> <span class="hljs-property">@recovery</span>
      generatedErrorVariableName = o.scope.freeVariable <span class="hljs-string">'error'</span>
      placeholder = <span class="hljs-keyword">new</span> Literal generatedErrorVariableName
      <span class="hljs-property">@recovery</span>.unshift <span class="hljs-keyword">new</span> Assign <span class="hljs-property">@errorVariable</span>, placeholder <span class="hljs-keyword">if</span> <span class="hljs-property">@errorVariable</span>
      [].concat <span class="hljs-property">@makeCode</span>(<span class="hljs-string">" catch ("</span>), placeholder.compileToFragments(o), <span class="hljs-property">@makeCode</span>(<span class="hljs-string">") {\n"</span>),
        <span class="hljs-property">@recovery</span>.compileToFragments(o, LEVEL_TOP), <span class="hljs-property">@makeCode</span>(<span class="hljs-string">"\n<span class="hljs-subst">#{<span class="hljs-property">@tab</span>}</span>}"</span>)
    <span class="hljs-keyword">else</span> <span class="hljs-keyword">unless</span> <span class="hljs-property">@ensure</span> <span class="hljs-keyword">or</span> <span class="hljs-property">@recovery</span>
      [<span class="hljs-property">@makeCode</span>(<span class="hljs-string">" catch (<span class="hljs-subst">#{generatedErrorVariableName}</span>) {}"</span>)]
    <span class="hljs-keyword">else</span>
      []

    ensurePart = <span class="hljs-keyword">if</span> <span class="hljs-property">@ensure</span> <span class="hljs-keyword">then</span> ([].concat <span class="hljs-property">@makeCode</span>(<span class="hljs-string">" finally {\n"</span>), <span class="hljs-property">@ensure</span>.compileToFragments(o, LEVEL_TOP),
      <span class="hljs-property">@makeCode</span>(<span class="hljs-string">"\n<span class="hljs-subst">#{<span class="hljs-property">@tab</span>}</span>}"</span>)) <span class="hljs-keyword">else</span> []

    [].concat <span class="hljs-property">@makeCode</span>(<span class="hljs-string">"<span class="hljs-subst">#{<span class="hljs-property">@tab</span>}</span>try {\n"</span>),
      tryPart,
      <span class="hljs-property">@makeCode</span>(<span class="hljs-string">"\n<span class="hljs-subst">#{<span class="hljs-property">@tab</span>}</span>}"</span>), catchPart, ensurePart</pre></div></div>
            
        </li>
        
        
        <li id="section-150">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-150">&#182;</a>
              </div>
              <h3 id="throw">Throw</h3>

            </div>
            
        </li>
        
        
        <li id="section-151">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-151">&#182;</a>
              </div>
              <p>Simple node to throw an exception.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.Throw = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Throw</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  <span class="hljs-attribute">constructor</span>: <span class="hljs-function"><span class="hljs-params">(<span class="hljs-property">@expression</span>)</span> -&gt;</span>

  <span class="hljs-attribute">children</span>: [<span class="hljs-string">'expression'</span>]

  <span class="hljs-attribute">isStatement</span>: YES
  <span class="hljs-attribute">jumps</span>:       NO</pre></div></div>
            
        </li>
        
        
        <li id="section-152">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-152">&#182;</a>
              </div>
              <p>A <strong>Throw</strong> is already a return, of sorts…</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">makeReturn</span>: THIS

  <span class="hljs-attribute">compileNode</span>: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    [].concat <span class="hljs-property">@makeCode</span>(<span class="hljs-property">@tab</span> + <span class="hljs-string">"throw "</span>), <span class="hljs-property">@expression</span>.compileToFragments(o), <span class="hljs-property">@makeCode</span>(<span class="hljs-string">";"</span>)</pre></div></div>
            
        </li>
        
        
        <li id="section-153">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-153">&#182;</a>
              </div>
              <h3 id="existence">Existence</h3>

            </div>
            
        </li>
        
        
        <li id="section-154">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-154">&#182;</a>
              </div>
              <p>Checks a variable for existence — not <em>null</em> and not <em>undefined</em>. This is
similar to <code>.nil?</code> in Ruby, and avoids having to consult a JavaScript truth
table.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.Existence = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Existence</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  <span class="hljs-attribute">constructor</span>: <span class="hljs-function"><span class="hljs-params">(<span class="hljs-property">@expression</span>)</span> -&gt;</span>

  <span class="hljs-attribute">children</span>: [<span class="hljs-string">'expression'</span>]

  <span class="hljs-attribute">invert</span>: NEGATE

  <span class="hljs-attribute">compileNode</span>: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-property">@expression</span>.front = <span class="hljs-property">@front</span>
    code = <span class="hljs-property">@expression</span>.compile o, LEVEL_OP
    <span class="hljs-keyword">if</span> IDENTIFIER.test(code) <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> o.scope.check code
      [cmp, cnj] = <span class="hljs-keyword">if</span> <span class="hljs-property">@negated</span> <span class="hljs-keyword">then</span> [<span class="hljs-string">'==='</span>, <span class="hljs-string">'||'</span>] <span class="hljs-keyword">else</span> [<span class="hljs-string">'!=='</span>, <span class="hljs-string">'&amp;&amp;'</span>]
      code = <span class="hljs-string">"typeof <span class="hljs-subst">#{code}</span> <span class="hljs-subst">#{cmp}</span> \"undefined\" <span class="hljs-subst">#{cnj}</span> <span class="hljs-subst">#{code}</span> <span class="hljs-subst">#{cmp}</span> null"</span>
    <span class="hljs-keyword">else</span></pre></div></div>
            
        </li>
        
        
        <li id="section-155">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-155">&#182;</a>
              </div>
              <p>do not use strict equality here; it will break existing code</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>      code = <span class="hljs-string">"<span class="hljs-subst">#{code}</span> <span class="hljs-subst">#{<span class="hljs-keyword">if</span> <span class="hljs-property">@negated</span> <span class="hljs-keyword">then</span> <span class="hljs-string">'=='</span> <span class="hljs-keyword">else</span> <span class="hljs-string">'!='</span>}</span> null"</span>
    [<span class="hljs-property">@makeCode</span>(<span class="hljs-keyword">if</span> o.level &lt;= LEVEL_COND <span class="hljs-keyword">then</span> code <span class="hljs-keyword">else</span> <span class="hljs-string">"(<span class="hljs-subst">#{code}</span>)"</span>)]</pre></div></div>
            
        </li>
        
        
        <li id="section-156">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-156">&#182;</a>
              </div>
              <h3 id="parens">Parens</h3>

            </div>
            
        </li>
        
        
        <li id="section-157">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-157">&#182;</a>
              </div>
              <p>An extra set of parentheses, specified explicitly in the source. At one time
we tried to clean up the results by detecting and removing redundant
parentheses, but no longer — you can put in as many as you please.</p>
<p>Parentheses are a good way to force any statement to become an expression.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.Parens = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Parens</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  <span class="hljs-attribute">constructor</span>: <span class="hljs-function"><span class="hljs-params">(<span class="hljs-property">@body</span>)</span> -&gt;</span>

  <span class="hljs-attribute">children</span>: [<span class="hljs-string">'body'</span>]

  unwrap    :<span class="hljs-function"> -&gt;</span> <span class="hljs-property">@body</span>
  isComplex :<span class="hljs-function"> -&gt;</span> <span class="hljs-property">@body</span>.isComplex()

  <span class="hljs-attribute">compileNode</span>: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    expr = <span class="hljs-property">@body</span>.unwrap()
    <span class="hljs-keyword">if</span> expr <span class="hljs-keyword">instanceof</span> Value <span class="hljs-keyword">and</span> expr.isAtomic()
      expr.front = <span class="hljs-property">@front</span>
      <span class="hljs-keyword">return</span> expr.compileToFragments o
    fragments = expr.compileToFragments o, LEVEL_PAREN
    bare = o.level &lt; LEVEL_OP <span class="hljs-keyword">and</span> (expr <span class="hljs-keyword">instanceof</span> Op <span class="hljs-keyword">or</span> expr <span class="hljs-keyword">instanceof</span> Call <span class="hljs-keyword">or</span>
      (expr <span class="hljs-keyword">instanceof</span> For <span class="hljs-keyword">and</span> expr.returns))
    <span class="hljs-keyword">if</span> bare <span class="hljs-keyword">then</span> fragments <span class="hljs-keyword">else</span> <span class="hljs-property">@wrapInBraces</span> fragments</pre></div></div>
            
        </li>
        
        
        <li id="section-158">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-158">&#182;</a>
              </div>
              <h3 id="for">For</h3>

            </div>
            
        </li>
        
        
        <li id="section-159">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-159">&#182;</a>
              </div>
              <p>CoffeeScript’s replacement for the <em>for</em> loop is our array and object
comprehensions, that compile into <em>for</em> loops here. They also act as an
expression, able to return the result of each filtered iteration.</p>
<p>Unlike Python array comprehensions, they can be multi-line, and you can pass
the current index of the loop as a second parameter. Unlike Ruby blocks,
you can map and filter in a single pass.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.For = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">For</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">While</span></span>
  <span class="hljs-attribute">constructor</span>: <span class="hljs-function"><span class="hljs-params">(body, source)</span> -&gt;</span>
    {<span class="hljs-property">@source</span>, <span class="hljs-property">@guard</span>, <span class="hljs-property">@step</span>, <span class="hljs-property">@name</span>, <span class="hljs-property">@index</span>} = source
    <span class="hljs-property">@body</span>    = Block.wrap [body]
    <span class="hljs-property">@own</span>     = !!source.own
    <span class="hljs-property">@object</span>  = !!source.object
    [<span class="hljs-property">@name</span>, <span class="hljs-property">@index</span>] = [<span class="hljs-property">@index</span>, <span class="hljs-property">@name</span>] <span class="hljs-keyword">if</span> <span class="hljs-property">@object</span>
    <span class="hljs-property">@index</span>.error <span class="hljs-string">'index cannot be a pattern matching expression'</span> <span class="hljs-keyword">if</span> <span class="hljs-property">@index</span> <span class="hljs-keyword">instanceof</span> Value
    <span class="hljs-property">@range</span>   = <span class="hljs-property">@source</span> <span class="hljs-keyword">instanceof</span> Value <span class="hljs-keyword">and</span> <span class="hljs-property">@source</span>.base <span class="hljs-keyword">instanceof</span> Range <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> <span class="hljs-property">@source</span>.properties.length
    <span class="hljs-property">@pattern</span> = <span class="hljs-property">@name</span> <span class="hljs-keyword">instanceof</span> Value
    <span class="hljs-property">@index</span>.error <span class="hljs-string">'indexes do not apply to range loops'</span> <span class="hljs-keyword">if</span> <span class="hljs-property">@range</span> <span class="hljs-keyword">and</span> <span class="hljs-property">@index</span>
    <span class="hljs-property">@name</span>.error <span class="hljs-string">'cannot pattern match over range loops'</span> <span class="hljs-keyword">if</span> <span class="hljs-property">@range</span> <span class="hljs-keyword">and</span> <span class="hljs-property">@pattern</span>
    <span class="hljs-property">@name</span>.error <span class="hljs-string">'cannot use own with for-in'</span> <span class="hljs-keyword">if</span> <span class="hljs-property">@own</span> <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> <span class="hljs-property">@object</span>
    <span class="hljs-property">@returns</span> = <span class="hljs-literal">false</span>

  <span class="hljs-attribute">children</span>: [<span class="hljs-string">'body'</span>, <span class="hljs-string">'source'</span>, <span class="hljs-string">'guard'</span>, <span class="hljs-string">'step'</span>]</pre></div></div>
            
        </li>
        
        
        <li id="section-160">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-160">&#182;</a>
              </div>
              <p>Welcome to the hairiest method in all of CoffeeScript. Handles the inner
loop, filtering, stepping, and result saving for array, object, and range
comprehensions. Some of the generated code can be shared in common, and
some cannot.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">compileNode</span>: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    body        = Block.wrap [<span class="hljs-property">@body</span>]
    [..., last] = body.expressions
    <span class="hljs-property">@returns</span>    = <span class="hljs-literal">no</span> <span class="hljs-keyword">if</span> last?.jumps() <span class="hljs-keyword">instanceof</span> Return
    source      = <span class="hljs-keyword">if</span> <span class="hljs-property">@range</span> <span class="hljs-keyword">then</span> <span class="hljs-property">@source</span>.base <span class="hljs-keyword">else</span> <span class="hljs-property">@source</span>
    scope       = o.scope
    name        = <span class="hljs-property">@name</span>  <span class="hljs-keyword">and</span> (<span class="hljs-property">@name</span>.compile o, LEVEL_LIST) <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> <span class="hljs-property">@pattern</span>
    index       = <span class="hljs-property">@index</span> <span class="hljs-keyword">and</span> (<span class="hljs-property">@index</span>.compile o, LEVEL_LIST)
    scope.find(name)  <span class="hljs-keyword">if</span> name <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> <span class="hljs-property">@pattern</span>
    scope.find(index) <span class="hljs-keyword">if</span> index
    rvar        = scope.freeVariable <span class="hljs-string">'results'</span> <span class="hljs-keyword">if</span> <span class="hljs-property">@returns</span>
    ivar        = (<span class="hljs-property">@object</span> <span class="hljs-keyword">and</span> index) <span class="hljs-keyword">or</span> scope.freeVariable <span class="hljs-string">'i'</span>, <span class="hljs-attribute">single</span>: <span class="hljs-literal">true</span>
    kvar        = (<span class="hljs-property">@range</span> <span class="hljs-keyword">and</span> name) <span class="hljs-keyword">or</span> index <span class="hljs-keyword">or</span> ivar
    kvarAssign  = <span class="hljs-keyword">if</span> kvar <span class="hljs-keyword">isnt</span> ivar <span class="hljs-keyword">then</span> <span class="hljs-string">"<span class="hljs-subst">#{kvar}</span> = "</span> <span class="hljs-keyword">else</span> <span class="hljs-string">""</span>
    <span class="hljs-keyword">if</span> <span class="hljs-property">@step</span> <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> <span class="hljs-property">@range</span>
      [step, stepVar] = <span class="hljs-property">@cacheToCodeFragments</span> <span class="hljs-property">@step</span>.cache o, LEVEL_LIST, isComplexOrAssignable
      stepNum = stepVar.match NUMBER
    name        = ivar <span class="hljs-keyword">if</span> <span class="hljs-property">@pattern</span>
    varPart     = <span class="hljs-string">''</span>
    guardPart   = <span class="hljs-string">''</span>
    defPart     = <span class="hljs-string">''</span>
    idt1        = <span class="hljs-property">@tab</span> + TAB
    <span class="hljs-keyword">if</span> <span class="hljs-property">@range</span>
      forPartFragments = source.compileToFragments merge o,
        {<span class="hljs-attribute">index</span>: ivar, name, <span class="hljs-property">@step</span>, <span class="hljs-attribute">isComplex</span>: isComplexOrAssignable}
    <span class="hljs-keyword">else</span>
      svar    = <span class="hljs-property">@source</span>.compile o, LEVEL_LIST
      <span class="hljs-keyword">if</span> (name <span class="hljs-keyword">or</span> <span class="hljs-property">@own</span>) <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> IDENTIFIER.test svar
        defPart    += <span class="hljs-string">"<span class="hljs-subst">#{<span class="hljs-property">@tab</span>}</span><span class="hljs-subst">#{ref = scope.freeVariable <span class="hljs-string">'ref'</span>}</span> = <span class="hljs-subst">#{svar}</span>;\n"</span>
        svar       = ref
      <span class="hljs-keyword">if</span> name <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> <span class="hljs-property">@pattern</span>
        namePart   = <span class="hljs-string">"<span class="hljs-subst">#{name}</span> = <span class="hljs-subst">#{svar}</span>[<span class="hljs-subst">#{kvar}</span>]"</span>
      <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> <span class="hljs-property">@object</span>
        defPart += <span class="hljs-string">"<span class="hljs-subst">#{<span class="hljs-property">@tab</span>}</span><span class="hljs-subst">#{step}</span>;\n"</span> <span class="hljs-keyword">if</span> step <span class="hljs-keyword">isnt</span> stepVar
        lvar = scope.freeVariable <span class="hljs-string">'len'</span> <span class="hljs-keyword">unless</span> <span class="hljs-property">@step</span> <span class="hljs-keyword">and</span> stepNum <span class="hljs-keyword">and</span> down = (parseNum(stepNum[<span class="hljs-number">0</span>]) &lt; <span class="hljs-number">0</span>)
        declare = <span class="hljs-string">"<span class="hljs-subst">#{kvarAssign}</span><span class="hljs-subst">#{ivar}</span> = 0, <span class="hljs-subst">#{lvar}</span> = <span class="hljs-subst">#{svar}</span>.length"</span>
        declareDown = <span class="hljs-string">"<span class="hljs-subst">#{kvarAssign}</span><span class="hljs-subst">#{ivar}</span> = <span class="hljs-subst">#{svar}</span>.length - 1"</span>
        compare = <span class="hljs-string">"<span class="hljs-subst">#{ivar}</span> &lt; <span class="hljs-subst">#{lvar}</span>"</span>
        compareDown = <span class="hljs-string">"<span class="hljs-subst">#{ivar}</span> &gt;= 0"</span>
        <span class="hljs-keyword">if</span> <span class="hljs-property">@step</span>
          <span class="hljs-keyword">if</span> stepNum
            <span class="hljs-keyword">if</span> down
              compare = compareDown
              declare = declareDown
          <span class="hljs-keyword">else</span>
            compare = <span class="hljs-string">"<span class="hljs-subst">#{stepVar}</span> &gt; 0 ? <span class="hljs-subst">#{compare}</span> : <span class="hljs-subst">#{compareDown}</span>"</span>
            declare = <span class="hljs-string">"(<span class="hljs-subst">#{stepVar}</span> &gt; 0 ? (<span class="hljs-subst">#{declare}</span>) : <span class="hljs-subst">#{declareDown}</span>)"</span>
          increment = <span class="hljs-string">"<span class="hljs-subst">#{ivar}</span> += <span class="hljs-subst">#{stepVar}</span>"</span>
        <span class="hljs-keyword">else</span>
          increment = <span class="hljs-string">"<span class="hljs-subst">#{<span class="hljs-keyword">if</span> kvar <span class="hljs-keyword">isnt</span> ivar <span class="hljs-keyword">then</span> <span class="hljs-string">"++<span class="hljs-subst">#{ivar}</span>"</span> <span class="hljs-keyword">else</span> <span class="hljs-string">"<span class="hljs-subst">#{ivar}</span>++"</span>}</span>"</span>
        forPartFragments  = [<span class="hljs-property">@makeCode</span>(<span class="hljs-string">"<span class="hljs-subst">#{declare}</span>; <span class="hljs-subst">#{compare}</span>; <span class="hljs-subst">#{kvarAssign}</span><span class="hljs-subst">#{increment}</span>"</span>)]
    <span class="hljs-keyword">if</span> <span class="hljs-property">@returns</span>
      resultPart   = <span class="hljs-string">"<span class="hljs-subst">#{<span class="hljs-property">@tab</span>}</span><span class="hljs-subst">#{rvar}</span> = [];\n"</span>
      returnResult = <span class="hljs-string">"\n<span class="hljs-subst">#{<span class="hljs-property">@tab</span>}</span>return <span class="hljs-subst">#{rvar}</span>;"</span>
      body.makeReturn rvar
    <span class="hljs-keyword">if</span> <span class="hljs-property">@guard</span>
      <span class="hljs-keyword">if</span> body.expressions.length &gt; <span class="hljs-number">1</span>
        body.expressions.unshift <span class="hljs-keyword">new</span> If (<span class="hljs-keyword">new</span> Parens <span class="hljs-property">@guard</span>).invert(), <span class="hljs-keyword">new</span> Literal <span class="hljs-string">"continue"</span>
      <span class="hljs-keyword">else</span>
        body = Block.wrap [<span class="hljs-keyword">new</span> If <span class="hljs-property">@guard</span>, body] <span class="hljs-keyword">if</span> <span class="hljs-property">@guard</span>
    <span class="hljs-keyword">if</span> <span class="hljs-property">@pattern</span>
      body.expressions.unshift <span class="hljs-keyword">new</span> Assign <span class="hljs-property">@name</span>, <span class="hljs-keyword">new</span> Literal <span class="hljs-string">"<span class="hljs-subst">#{svar}</span>[<span class="hljs-subst">#{kvar}</span>]"</span>
    defPartFragments = [].concat <span class="hljs-property">@makeCode</span>(defPart), <span class="hljs-property">@pluckDirectCall</span>(o, body)
    varPart = <span class="hljs-string">"\n<span class="hljs-subst">#{idt1}</span><span class="hljs-subst">#{namePart}</span>;"</span> <span class="hljs-keyword">if</span> namePart
    <span class="hljs-keyword">if</span> <span class="hljs-property">@object</span>
      forPartFragments   = [<span class="hljs-property">@makeCode</span>(<span class="hljs-string">"<span class="hljs-subst">#{kvar}</span> in <span class="hljs-subst">#{svar}</span>"</span>)]
      guardPart = <span class="hljs-string">"\n<span class="hljs-subst">#{idt1}</span>if (!<span class="hljs-subst">#{utility <span class="hljs-string">'hasProp'</span>, o}</span>.call(<span class="hljs-subst">#{svar}</span>, <span class="hljs-subst">#{kvar}</span>)) continue;"</span> <span class="hljs-keyword">if</span> <span class="hljs-property">@own</span>
    bodyFragments = body.compileToFragments merge(o, <span class="hljs-attribute">indent</span>: idt1), LEVEL_TOP
    <span class="hljs-keyword">if</span> bodyFragments <span class="hljs-keyword">and</span> (bodyFragments.length &gt; <span class="hljs-number">0</span>)
      bodyFragments = [].concat <span class="hljs-property">@makeCode</span>(<span class="hljs-string">"\n"</span>), bodyFragments, <span class="hljs-property">@makeCode</span>(<span class="hljs-string">"\n"</span>)
    [].concat defPartFragments, <span class="hljs-property">@makeCode</span>(<span class="hljs-string">"<span class="hljs-subst">#{resultPart <span class="hljs-keyword">or</span> <span class="hljs-string">''</span>}</span><span class="hljs-subst">#{<span class="hljs-property">@tab</span>}</span>for ("</span>),
      forPartFragments, <span class="hljs-property">@makeCode</span>(<span class="hljs-string">") {<span class="hljs-subst">#{guardPart}</span><span class="hljs-subst">#{varPart}</span>"</span>), bodyFragments,
      <span class="hljs-property">@makeCode</span>(<span class="hljs-string">"<span class="hljs-subst">#{<span class="hljs-property">@tab</span>}</span>}<span class="hljs-subst">#{returnResult <span class="hljs-keyword">or</span> <span class="hljs-string">''</span>}</span>"</span>)

  <span class="hljs-attribute">pluckDirectCall</span>: <span class="hljs-function"><span class="hljs-params">(o, body)</span> -&gt;</span>
    defs = []
    <span class="hljs-keyword">for</span> expr, idx <span class="hljs-keyword">in</span> body.expressions
      expr = expr.unwrapAll()
      <span class="hljs-keyword">continue</span> <span class="hljs-keyword">unless</span> expr <span class="hljs-keyword">instanceof</span> Call
      val = expr.variable?.unwrapAll()
      <span class="hljs-keyword">continue</span> <span class="hljs-keyword">unless</span> (val <span class="hljs-keyword">instanceof</span> Code) <span class="hljs-keyword">or</span>
                      (val <span class="hljs-keyword">instanceof</span> Value <span class="hljs-keyword">and</span>
                      val.base?.unwrapAll() <span class="hljs-keyword">instanceof</span> Code <span class="hljs-keyword">and</span>
                      val.properties.length <span class="hljs-keyword">is</span> <span class="hljs-number">1</span> <span class="hljs-keyword">and</span>
                      val.properties[<span class="hljs-number">0</span>].name?.value <span class="hljs-keyword">in</span> [<span class="hljs-string">'call'</span>, <span class="hljs-string">'apply'</span>])
      fn    = val.base?.unwrapAll() <span class="hljs-keyword">or</span> val
      ref   = <span class="hljs-keyword">new</span> Literal o.scope.freeVariable <span class="hljs-string">'fn'</span>
      base  = <span class="hljs-keyword">new</span> Value ref
      <span class="hljs-keyword">if</span> val.base
        [val.base, base] = [base, val]
      body.expressions[idx] = <span class="hljs-keyword">new</span> Call base, expr.args
      defs = defs.concat <span class="hljs-property">@makeCode</span>(<span class="hljs-property">@tab</span>), (<span class="hljs-keyword">new</span> Assign(ref, fn).compileToFragments(o, LEVEL_TOP)), <span class="hljs-property">@makeCode</span>(<span class="hljs-string">';\n'</span>)
    defs</pre></div></div>
            
        </li>
        
        
        <li id="section-161">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-161">&#182;</a>
              </div>
              <h3 id="switch">Switch</h3>

            </div>
            
        </li>
        
        
        <li id="section-162">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-162">&#182;</a>
              </div>
              <p>A JavaScript <em>switch</em> statement. Converts into a returnable expression on-demand.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.Switch = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Switch</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  <span class="hljs-attribute">constructor</span>: <span class="hljs-function"><span class="hljs-params">(<span class="hljs-property">@subject</span>, <span class="hljs-property">@cases</span>, <span class="hljs-property">@otherwise</span>)</span> -&gt;</span>

  <span class="hljs-attribute">children</span>: [<span class="hljs-string">'subject'</span>, <span class="hljs-string">'cases'</span>, <span class="hljs-string">'otherwise'</span>]

  <span class="hljs-attribute">isStatement</span>: YES

  <span class="hljs-attribute">jumps</span>: <span class="hljs-function"><span class="hljs-params">(o = {block: <span class="hljs-literal">yes</span>})</span> -&gt;</span>
    <span class="hljs-keyword">for</span> [conds, block] <span class="hljs-keyword">in</span> <span class="hljs-property">@cases</span>
      <span class="hljs-keyword">return</span> jumpNode <span class="hljs-keyword">if</span> jumpNode = block.jumps o
    <span class="hljs-property">@otherwise</span>?.jumps o

  <span class="hljs-attribute">makeReturn</span>: <span class="hljs-function"><span class="hljs-params">(res)</span> -&gt;</span>
    pair[<span class="hljs-number">1</span>].makeReturn res <span class="hljs-keyword">for</span> pair <span class="hljs-keyword">in</span> <span class="hljs-property">@cases</span>
    <span class="hljs-property">@otherwise</span> <span class="hljs-keyword">or</span>= <span class="hljs-keyword">new</span> Block [<span class="hljs-keyword">new</span> Literal <span class="hljs-string">'void 0'</span>] <span class="hljs-keyword">if</span> res
    <span class="hljs-property">@otherwise</span>?.makeReturn res
    <span class="hljs-keyword">this</span>

  <span class="hljs-attribute">compileNode</span>: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    idt1 = o.indent + TAB
    idt2 = o.indent = idt1 + TAB
    fragments = [].concat <span class="hljs-property">@makeCode</span>(<span class="hljs-property">@tab</span> + <span class="hljs-string">"switch ("</span>),
      (<span class="hljs-keyword">if</span> <span class="hljs-property">@subject</span> <span class="hljs-keyword">then</span> <span class="hljs-property">@subject</span>.compileToFragments(o, LEVEL_PAREN) <span class="hljs-keyword">else</span> <span class="hljs-property">@makeCode</span> <span class="hljs-string">"false"</span>),
      <span class="hljs-property">@makeCode</span>(<span class="hljs-string">") {\n"</span>)
    <span class="hljs-keyword">for</span> [conditions, block], i <span class="hljs-keyword">in</span> <span class="hljs-property">@cases</span>
      <span class="hljs-keyword">for</span> cond <span class="hljs-keyword">in</span> flatten [conditions]
        cond  = cond.invert() <span class="hljs-keyword">unless</span> <span class="hljs-property">@subject</span>
        fragments = fragments.concat <span class="hljs-property">@makeCode</span>(idt1 + <span class="hljs-string">"case "</span>), cond.compileToFragments(o, LEVEL_PAREN), <span class="hljs-property">@makeCode</span>(<span class="hljs-string">":\n"</span>)
      fragments = fragments.concat body, <span class="hljs-property">@makeCode</span>(<span class="hljs-string">'\n'</span>) <span class="hljs-keyword">if</span> (body = block.compileToFragments o, LEVEL_TOP).length &gt; <span class="hljs-number">0</span>
      <span class="hljs-keyword">break</span> <span class="hljs-keyword">if</span> i <span class="hljs-keyword">is</span> <span class="hljs-property">@cases</span>.length - <span class="hljs-number">1</span> <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> <span class="hljs-property">@otherwise</span>
      expr = <span class="hljs-property">@lastNonComment</span> block.expressions
      <span class="hljs-keyword">continue</span> <span class="hljs-keyword">if</span> expr <span class="hljs-keyword">instanceof</span> Return <span class="hljs-keyword">or</span> (expr <span class="hljs-keyword">instanceof</span> Literal <span class="hljs-keyword">and</span> expr.jumps() <span class="hljs-keyword">and</span> expr.value <span class="hljs-keyword">isnt</span> <span class="hljs-string">'debugger'</span>)
      fragments.push cond.makeCode(idt2 + <span class="hljs-string">'break;\n'</span>)
    <span class="hljs-keyword">if</span> <span class="hljs-property">@otherwise</span> <span class="hljs-keyword">and</span> <span class="hljs-property">@otherwise</span>.expressions.length
      fragments.push <span class="hljs-property">@makeCode</span>(idt1 + <span class="hljs-string">"default:\n"</span>), (<span class="hljs-property">@otherwise</span>.compileToFragments o, LEVEL_TOP)..., <span class="hljs-property">@makeCode</span>(<span class="hljs-string">"\n"</span>)
    fragments.push <span class="hljs-property">@makeCode</span> <span class="hljs-property">@tab</span> + <span class="hljs-string">'}'</span>
    fragments</pre></div></div>
            
        </li>
        
        
        <li id="section-163">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-163">&#182;</a>
              </div>
              <h3 id="if">If</h3>

            </div>
            
        </li>
        
        
        <li id="section-164">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-164">&#182;</a>
              </div>
              <p><em>If/else</em> statements. Acts as an expression by pushing down requested returns
to the last line of each clause.</p>
<p>Single-expression <strong>Ifs</strong> are compiled into conditional operators if possible,
because ternaries are already proper expressions, and don’t need conversion.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.If = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">If</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Base</span></span>
  <span class="hljs-attribute">constructor</span>: <span class="hljs-function"><span class="hljs-params">(condition, <span class="hljs-property">@body</span>, options = {})</span> -&gt;</span>
    <span class="hljs-property">@condition</span> = <span class="hljs-keyword">if</span> options.type <span class="hljs-keyword">is</span> <span class="hljs-string">'unless'</span> <span class="hljs-keyword">then</span> condition.invert() <span class="hljs-keyword">else</span> condition
    <span class="hljs-property">@elseBody</span>  = <span class="hljs-literal">null</span>
    <span class="hljs-property">@isChain</span>   = <span class="hljs-literal">false</span>
    {<span class="hljs-property">@soak</span>}    = options

  <span class="hljs-attribute">children</span>: [<span class="hljs-string">'condition'</span>, <span class="hljs-string">'body'</span>, <span class="hljs-string">'elseBody'</span>]

  <span class="hljs-attribute">bodyNode</span>:<span class="hljs-function">     -&gt;</span> <span class="hljs-property">@body</span>?.unwrap()
  <span class="hljs-attribute">elseBodyNode</span>:<span class="hljs-function"> -&gt;</span> <span class="hljs-property">@elseBody</span>?.unwrap()</pre></div></div>
            
        </li>
        
        
        <li id="section-165">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-165">&#182;</a>
              </div>
              <p>Rewrite a chain of <strong>Ifs</strong> to add a default case as the final <em>else</em>.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">addElse</span>: <span class="hljs-function"><span class="hljs-params">(elseBody)</span> -&gt;</span>
    <span class="hljs-keyword">if</span> <span class="hljs-property">@isChain</span>
      <span class="hljs-property">@elseBodyNode</span>().addElse elseBody
    <span class="hljs-keyword">else</span>
      <span class="hljs-property">@isChain</span>  = elseBody <span class="hljs-keyword">instanceof</span> If
      <span class="hljs-property">@elseBody</span> = <span class="hljs-property">@ensureBlock</span> elseBody
      <span class="hljs-property">@elseBody</span>.updateLocationDataIfMissing elseBody.locationData
    <span class="hljs-keyword">this</span></pre></div></div>
            
        </li>
        
        
        <li id="section-166">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-166">&#182;</a>
              </div>
              <p>The <strong>If</strong> only compiles into a statement if either of its bodies needs
to be a statement. Otherwise a conditional operator is safe.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">isStatement</span>: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    o?.level <span class="hljs-keyword">is</span> LEVEL_TOP <span class="hljs-keyword">or</span>
      <span class="hljs-property">@bodyNode</span>().isStatement(o) <span class="hljs-keyword">or</span> <span class="hljs-property">@elseBodyNode</span>()?.isStatement(o)

  <span class="hljs-attribute">jumps</span>: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span> <span class="hljs-property">@body</span>.jumps(o) <span class="hljs-keyword">or</span> <span class="hljs-property">@elseBody</span>?.jumps(o)

  <span class="hljs-attribute">compileNode</span>: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    <span class="hljs-keyword">if</span> <span class="hljs-property">@isStatement</span> o <span class="hljs-keyword">then</span> <span class="hljs-property">@compileStatement</span> o <span class="hljs-keyword">else</span> <span class="hljs-property">@compileExpression</span> o

  <span class="hljs-attribute">makeReturn</span>: <span class="hljs-function"><span class="hljs-params">(res)</span> -&gt;</span>
    <span class="hljs-property">@elseBody</span>  <span class="hljs-keyword">or</span>= <span class="hljs-keyword">new</span> Block [<span class="hljs-keyword">new</span> Literal <span class="hljs-string">'void 0'</span>] <span class="hljs-keyword">if</span> res
    <span class="hljs-property">@body</span>     <span class="hljs-keyword">and</span>= <span class="hljs-keyword">new</span> Block [<span class="hljs-property">@body</span>.makeReturn res]
    <span class="hljs-property">@elseBody</span> <span class="hljs-keyword">and</span>= <span class="hljs-keyword">new</span> Block [<span class="hljs-property">@elseBody</span>.makeReturn res]
    <span class="hljs-keyword">this</span>

  <span class="hljs-attribute">ensureBlock</span>: <span class="hljs-function"><span class="hljs-params">(node)</span> -&gt;</span>
    <span class="hljs-keyword">if</span> node <span class="hljs-keyword">instanceof</span> Block <span class="hljs-keyword">then</span> node <span class="hljs-keyword">else</span> <span class="hljs-keyword">new</span> Block [node]</pre></div></div>
            
        </li>
        
        
        <li id="section-167">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-167">&#182;</a>
              </div>
              <p>Compile the <code>If</code> as a regular <em>if-else</em> statement. Flattened chains
force inner <em>else</em> bodies into statement form.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">compileStatement</span>: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    child    = del o, <span class="hljs-string">'chainChild'</span>
    exeq     = del o, <span class="hljs-string">'isExistentialEquals'</span>

    <span class="hljs-keyword">if</span> exeq
      <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> If(<span class="hljs-property">@condition</span>.invert(), <span class="hljs-property">@elseBodyNode</span>(), <span class="hljs-attribute">type</span>: <span class="hljs-string">'if'</span>).compileToFragments o

    indent   = o.indent + TAB
    cond     = <span class="hljs-property">@condition</span>.compileToFragments o, LEVEL_PAREN
    body     = <span class="hljs-property">@ensureBlock</span>(<span class="hljs-property">@body</span>).compileToFragments merge o, {indent}
    ifPart   = [].concat <span class="hljs-property">@makeCode</span>(<span class="hljs-string">"if ("</span>), cond, <span class="hljs-property">@makeCode</span>(<span class="hljs-string">") {\n"</span>), body, <span class="hljs-property">@makeCode</span>(<span class="hljs-string">"\n<span class="hljs-subst">#{<span class="hljs-property">@tab</span>}</span>}"</span>)
    ifPart.unshift <span class="hljs-property">@makeCode</span> <span class="hljs-property">@tab</span> <span class="hljs-keyword">unless</span> child
    <span class="hljs-keyword">return</span> ifPart <span class="hljs-keyword">unless</span> <span class="hljs-property">@elseBody</span>
    answer = ifPart.concat <span class="hljs-property">@makeCode</span>(<span class="hljs-string">' else '</span>)
    <span class="hljs-keyword">if</span> <span class="hljs-property">@isChain</span>
      o.chainChild = <span class="hljs-literal">yes</span>
      answer = answer.concat <span class="hljs-property">@elseBody</span>.unwrap().compileToFragments o, LEVEL_TOP
    <span class="hljs-keyword">else</span>
      answer = answer.concat <span class="hljs-property">@makeCode</span>(<span class="hljs-string">"{\n"</span>), <span class="hljs-property">@elseBody</span>.compileToFragments(merge(o, {indent}), LEVEL_TOP), <span class="hljs-property">@makeCode</span>(<span class="hljs-string">"\n<span class="hljs-subst">#{<span class="hljs-property">@tab</span>}</span>}"</span>)
    answer</pre></div></div>
            
        </li>
        
        
        <li id="section-168">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-168">&#182;</a>
              </div>
              <p>Compile the <code>If</code> as a conditional operator.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">compileExpression</span>: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
    cond = <span class="hljs-property">@condition</span>.compileToFragments o, LEVEL_COND
    body = <span class="hljs-property">@bodyNode</span>().compileToFragments o, LEVEL_LIST
    alt  = <span class="hljs-keyword">if</span> <span class="hljs-property">@elseBodyNode</span>() <span class="hljs-keyword">then</span> <span class="hljs-property">@elseBodyNode</span>().compileToFragments(o, LEVEL_LIST) <span class="hljs-keyword">else</span> [<span class="hljs-property">@makeCode</span>(<span class="hljs-string">'void 0'</span>)]
    fragments = cond.concat <span class="hljs-property">@makeCode</span>(<span class="hljs-string">" ? "</span>), body, <span class="hljs-property">@makeCode</span>(<span class="hljs-string">" : "</span>), alt
    <span class="hljs-keyword">if</span> o.level &gt;= LEVEL_COND <span class="hljs-keyword">then</span> <span class="hljs-property">@wrapInBraces</span> fragments <span class="hljs-keyword">else</span> fragments

  <span class="hljs-attribute">unfoldSoak</span>:<span class="hljs-function"> -&gt;</span>
    <span class="hljs-property">@soak</span> <span class="hljs-keyword">and</span> <span class="hljs-keyword">this</span></pre></div></div>
            
        </li>
        
        
        <li id="section-169">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-169">&#182;</a>
              </div>
              <h2 id="constants">Constants</h2>

            </div>
            
        </li>
        
        
        <li id="section-170">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-170">&#182;</a>
              </div>
              
            </div>
            
            <div class="content"><div class='highlight'><pre>
UTILITIES =</pre></div></div>
            
        </li>
        
        
        <li id="section-171">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-171">&#182;</a>
              </div>
              <p>Correctly set up a prototype chain for inheritance, including a reference
to the superclass for <code>super()</code> calls, and copies of any static properties.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">extend</span>: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span> <span class="hljs-string">"
    function(child, parent) {
      for (var key in parent) {
        if (<span class="hljs-subst">#{utility <span class="hljs-string">'hasProp'</span>, o}</span>.call(parent, key)) child[key] = parent[key];
      }
      function ctor() {
        this.constructor = child;
      }
      ctor.prototype = parent.prototype;
      child.prototype = new ctor();
      child.__super__ = parent.prototype;
      return child;
    }
  "</span></pre></div></div>
            
        </li>
        
        
        <li id="section-172">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-172">&#182;</a>
              </div>
              <p>Create a function bound to the current value of “this”.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">bind</span>:<span class="hljs-function"> -&gt;</span> <span class="hljs-string">'
    function(fn, me){
      return function(){
        return fn.apply(me, arguments);
      };
    }
  '</span></pre></div></div>
            
        </li>
        
        
        <li id="section-173">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-173">&#182;</a>
              </div>
              <p>Discover if an item is in an array.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">indexOf</span>:<span class="hljs-function"> -&gt;</span> <span class="hljs-string">"
    [].indexOf || function(item) {
      for (var i = 0, l = this.length; i &lt; l; i++) {
        if (i in this &amp;&amp; this[i] === item) return i;
      }
      return -1;
    }
  "</span>

  <span class="hljs-attribute">modulo</span>:<span class="hljs-function"> -&gt;</span> <span class="hljs-string">"""
    function(a, b) { return (+a % (b = +b) + b) % b; }
  """</span></pre></div></div>
            
        </li>
        
        
        <li id="section-174">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-174">&#182;</a>
              </div>
              <p>Shortcuts to speed up the lookup time for native functions.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">hasProp</span>:<span class="hljs-function"> -&gt;</span> <span class="hljs-string">'{}.hasOwnProperty'</span>
  slice  :<span class="hljs-function"> -&gt;</span> <span class="hljs-string">'[].slice'</span></pre></div></div>
            
        </li>
        
        
        <li id="section-175">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-175">&#182;</a>
              </div>
              <p>Levels indicate a node’s position in the AST. Useful for knowing if
parens are necessary or superfluous.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>LEVEL_TOP    = <span class="hljs-number">1</span>  <span class="hljs-comment"># ...;</span>
LEVEL_PAREN  = <span class="hljs-number">2</span>  <span class="hljs-comment"># (...)</span>
LEVEL_LIST   = <span class="hljs-number">3</span>  <span class="hljs-comment"># [...]</span>
LEVEL_COND   = <span class="hljs-number">4</span>  <span class="hljs-comment"># ... ? x : y</span>
LEVEL_OP     = <span class="hljs-number">5</span>  <span class="hljs-comment"># !...</span>
LEVEL_ACCESS = <span class="hljs-number">6</span>  <span class="hljs-comment"># ...[0]</span></pre></div></div>
            
        </li>
        
        
        <li id="section-176">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-176">&#182;</a>
              </div>
              <p>Tabs are two spaces for pretty printing.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>TAB = <span class="hljs-string">'  '</span>

IDENTIFIER = <span class="hljs-regexp">/// ^ (?!\d) [$\w\x7f-\uffff]+ $ ///</span>
SIMPLENUM  = <span class="hljs-regexp">/^[+-]?\d+$/</span>
HEXNUM = <span class="hljs-regexp">/^[+-]?0x[\da-f]+/i</span>
NUMBER    = <span class="hljs-regexp">///^[+-]?(?:
  0x[\da-f]+ |              <span class="hljs-comment"># hex</span>
  \d*\.?\d+ (?:e[+-]?\d+)?  <span class="hljs-comment"># decimal</span>
)$///</span>i</pre></div></div>
            
        </li>
        
        
        <li id="section-177">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-177">&#182;</a>
              </div>
              <p>Is a literal value a string/regex?</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>IS_STRING = <span class="hljs-regexp">/^['"]/</span>
IS_REGEX = <span class="hljs-regexp">/^\//</span></pre></div></div>
            
        </li>
        
        
        <li id="section-178">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-178">&#182;</a>
              </div>
              <h2 id="helper-functions">Helper Functions</h2>

            </div>
            
        </li>
        
        
        <li id="section-179">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-179">&#182;</a>
              </div>
              
            </div>
            
        </li>
        
        
        <li id="section-180">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-180">&#182;</a>
              </div>
              <p>Helper for ensuring that utility functions are assigned at the top level.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">utility</span> = <span class="hljs-params">(name, o)</span> -&gt;</span>
  {root} = o.scope
  <span class="hljs-keyword">if</span> name <span class="hljs-keyword">of</span> root.utilities
    root.utilities[name]
  <span class="hljs-keyword">else</span>
    ref = root.freeVariable name
    root.assign ref, UTILITIES[name] o
    root.utilities[name] = ref

<span class="hljs-function"><span class="hljs-title">multident</span> = <span class="hljs-params">(code, tab)</span> -&gt;</span>
  code = code.replace <span class="hljs-regexp">/\n/g</span>, <span class="hljs-string">'$&amp;'</span> + tab
  code.replace <span class="hljs-regexp">/\s+$/</span>, <span class="hljs-string">''</span></pre></div></div>
            
        </li>
        
        
        <li id="section-181">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-181">&#182;</a>
              </div>
              <p>Parse a number (+- decimal/hexadecimal)
Examples: 0, -1, 1, 2e3, 2e-3, -0xfe, 0xfe</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">parseNum</span> = <span class="hljs-params">(x)</span> -&gt;</span>
  <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> x?
    <span class="hljs-number">0</span>
  <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> x.match HEXNUM
    parseInt x, <span class="hljs-number">16</span>
  <span class="hljs-keyword">else</span>
    parseFloat x

<span class="hljs-function"><span class="hljs-title">isLiteralArguments</span> = <span class="hljs-params">(node)</span> -&gt;</span>
  node <span class="hljs-keyword">instanceof</span> Literal <span class="hljs-keyword">and</span> node.value <span class="hljs-keyword">is</span> <span class="hljs-string">'arguments'</span> <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> node.asKey

<span class="hljs-function"><span class="hljs-title">isLiteralThis</span> = <span class="hljs-params">(node)</span> -&gt;</span>
  (node <span class="hljs-keyword">instanceof</span> Literal <span class="hljs-keyword">and</span> node.value <span class="hljs-keyword">is</span> <span class="hljs-string">'this'</span> <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> node.asKey) <span class="hljs-keyword">or</span>
    (node <span class="hljs-keyword">instanceof</span> Code <span class="hljs-keyword">and</span> node.bound) <span class="hljs-keyword">or</span>
    (node <span class="hljs-keyword">instanceof</span> Call <span class="hljs-keyword">and</span> node.isSuper)

<span class="hljs-function"><span class="hljs-title">isComplexOrAssignable</span> = <span class="hljs-params">(node)</span> -&gt;</span> node.isComplex() <span class="hljs-keyword">or</span> node.isAssignable?()</pre></div></div>
            
        </li>
        
        
        <li id="section-182">
            <div class="annotation">
              
              <div class="pilwrap ">
                <a class="pilcrow" href="#section-182">&#182;</a>
              </div>
              <p>Unfold a node’s child if soak, then tuck the node under created <code>If</code></p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">unfoldSoak</span> = <span class="hljs-params">(o, parent, name)</span> -&gt;</span>
  <span class="hljs-keyword">return</span> <span class="hljs-keyword">unless</span> ifn = parent[name].unfoldSoak o
  parent[name] = ifn.body
  ifn.body = <span class="hljs-keyword">new</span> Value parent
  ifn</pre></div></div>
            
        </li>
        
    </ul>
  </div>
</body>
</html>