Files
coffeescript/documentation/docs/nodes.html

4221 lines
365 KiB
HTML

<!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">
<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="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.coffee
</a>
</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><span class="nb">Error</span><span class="p">.</span><span class="nv">stackTraceLimit = </span><span class="kc">Infinity</span>
<span class="p">{</span><span class="nx">Scope</span><span class="p">}</span> <span class="o">=</span> <span class="nx">require</span> <span class="s">&#39;./scope&#39;</span>
<span class="p">{</span><span class="nx">RESERVED</span><span class="p">,</span> <span class="nx">STRICT_PROSCRIBED</span><span class="p">}</span> <span class="o">=</span> <span class="nx">require</span> <span class="s">&#39;./lexer&#39;</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><span class="p">{</span><span class="nx">compact</span><span class="p">,</span> <span class="nx">flatten</span><span class="p">,</span> <span class="nx">extend</span><span class="p">,</span> <span class="nx">merge</span><span class="p">,</span> <span class="nx">del</span><span class="p">,</span> <span class="nx">starts</span><span class="p">,</span> <span class="nx">ends</span><span class="p">,</span> <span class="nx">last</span><span class="p">,</span> <span class="nx">some</span><span class="p">,</span>
<span class="nx">addLocationDataFn</span><span class="p">,</span> <span class="nx">locationDataToString</span><span class="p">,</span> <span class="nx">throwSyntaxError</span><span class="p">}</span> <span class="o">=</span> <span class="nx">require</span> <span class="s">&#39;./helpers&#39;</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="nv">exports.extend = </span><span class="nx">extend</span>
<span class="nv">exports.addLocationDataFn = </span><span class="nx">addLocationDataFn</span></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&#39;t need customization.
</p>
</div>
<div class="content"><div class="highlight"><pre><span class="nv">YES = </span><span class="nf">-&gt;</span> <span class="kc">yes</span>
<span class="nv">NO = </span><span class="nf">-&gt;</span> <span class="kc">no</span>
<span class="nv">THIS = </span><span class="nf">-&gt;</span> <span class="k">this</span>
<span class="nv">NEGATE = </span><span class="nf">-&gt;</span> <span class="vi">@negated = </span><span class="o">not</span> <span class="nx">@negated</span><span class="p">;</span> <span class="k">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>CodeFragment</h3>
<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&#39; <code>code</code> snippets, in order.
</p>
</div>
<div class="content"><div class="highlight"><pre><span class="nv">exports.CodeFragment = </span><span class="k">class</span> <span class="nx">CodeFragment</span>
<span class="nv">constructor: </span><span class="nf">(parent, code) -&gt;</span>
<span class="vi">@code = </span><span class="s">&quot;</span><span class="si">#{</span><span class="nx">code</span><span class="si">}</span><span class="s">&quot;</span>
<span class="vi">@locationData = </span><span class="nx">parent</span><span class="o">?</span><span class="p">.</span><span class="nx">locationData</span>
<span class="vi">@type = </span><span class="nx">parent</span><span class="o">?</span><span class="p">.</span><span class="nx">constructor</span><span class="o">?</span><span class="p">.</span><span class="nx">name</span> <span class="o">or</span> <span class="s">&#39;unknown&#39;</span>
<span class="nv">toString: </span><span class="p">()</span> <span class="nf">-&gt;</span>
<span class="s">&quot;</span><span class="si">#{</span><span class="nx">@code</span><span class="si">}#{</span><span class="p">[</span><span class="k">if</span> <span class="nx">@locationData</span> <span class="k">then</span> <span class="s">&quot;: &quot;</span> <span class="o">+</span> <span class="nx">locationDataToString</span><span class="p">(</span><span class="nx">@locationData</span><span class="p">)]</span><span class="si">}</span><span class="s">&quot;</span></pre></div></div>
</li>
<li id="section-6">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-6">&#182;</a>
</div>
<p>Convert an array of CodeFragments into a string.
</p>
</div>
<div class="content"><div class="highlight"><pre><span class="nv">fragmentsToText = </span><span class="nf">(fragments) -&gt;</span>
<span class="p">(</span><span class="nx">fragment</span><span class="p">.</span><span class="nx">code</span> <span class="k">for</span> <span class="nx">fragment</span> <span class="k">in</span> <span class="nx">fragments</span><span class="p">).</span><span class="nx">join</span><span class="p">(</span><span class="s">&#39;&#39;</span><span class="p">)</span></pre></div></div>
</li>
<li id="section-7">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-7">&#182;</a>
</div>
<h3>Base</h3>
<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="nv">exports.Base = </span><span class="k">class</span> <span class="nx">Base</span>
<span class="nv">compile: </span><span class="nf">(o, lvl) -&gt;</span>
<span class="nx">fragmentsToText</span> <span class="nx">@compileToFragments</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">lvl</span></pre></div></div>
</li>
<li id="section-8">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-8">&#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&#39;s not a <em>pureStatement</em>, and we&#39;re not at
the top level of a block (which would be unnecessary), and we haven&#39;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="nv">compileToFragments: </span><span class="nf">(o, lvl) -&gt;</span>
<span class="nv">o = </span><span class="nx">extend</span> <span class="p">{},</span> <span class="nx">o</span>
<span class="nv">o.level = </span><span class="nx">lvl</span> <span class="k">if</span> <span class="nx">lvl</span>
<span class="nv">node = </span><span class="nx">@unfoldSoak</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">or</span> <span class="k">this</span>
<span class="nv">node.tab = </span><span class="nx">o</span><span class="p">.</span><span class="nx">indent</span>
<span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">level</span> <span class="o">is</span> <span class="nx">LEVEL_TOP</span> <span class="o">or</span> <span class="o">not</span> <span class="nx">node</span><span class="p">.</span><span class="nx">isStatement</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">compileNode</span> <span class="nx">o</span>
<span class="k">else</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">compileClosure</span> <span class="nx">o</span></pre></div></div>
</li>
<li id="section-9">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-9">&#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="nv">compileClosure: </span><span class="nf">(o) -&gt;</span>
<span class="k">if</span> <span class="nv">jumpNode = </span><span class="nx">@jumps</span><span class="p">()</span>
<span class="nx">jumpNode</span><span class="p">.</span><span class="nx">error</span> <span class="s">&#39;cannot use a pure statement in an expression&#39;</span>
<span class="nv">o.sharedScope = </span><span class="kc">yes</span>
<span class="nx">Closure</span><span class="p">.</span><span class="nx">wrap</span><span class="p">(</span><span class="k">this</span><span class="p">).</span><span class="nx">compileNode</span> <span class="nx">o</span></pre></div></div>
</li>
<li id="section-10">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-10">&#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="nv">cache: </span><span class="nf">(o, level, reused) -&gt;</span>
<span class="k">unless</span> <span class="nx">@isComplex</span><span class="p">()</span>
<span class="nv">ref = </span><span class="k">if</span> <span class="nx">level</span> <span class="k">then</span> <span class="nx">@compileToFragments</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">level</span> <span class="k">else</span> <span class="k">this</span>
<span class="p">[</span><span class="nx">ref</span><span class="p">,</span> <span class="nx">ref</span><span class="p">]</span>
<span class="k">else</span>
<span class="nv">ref = </span><span class="k">new</span> <span class="nx">Literal</span> <span class="nx">reused</span> <span class="o">or</span> <span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span> <span class="s">&#39;ref&#39;</span>
<span class="nv">sub = </span><span class="k">new</span> <span class="nx">Assign</span> <span class="nx">ref</span><span class="p">,</span> <span class="k">this</span>
<span class="k">if</span> <span class="nx">level</span> <span class="k">then</span> <span class="p">[</span><span class="nx">sub</span><span class="p">.</span><span class="nx">compileToFragments</span><span class="p">(</span><span class="nx">o</span><span class="p">,</span> <span class="nx">level</span><span class="p">),</span> <span class="p">[</span><span class="nx">@makeCode</span><span class="p">(</span><span class="nx">ref</span><span class="p">.</span><span class="nx">value</span><span class="p">)]]</span> <span class="k">else</span> <span class="p">[</span><span class="nx">sub</span><span class="p">,</span> <span class="nx">ref</span><span class="p">]</span>
<span class="nv">cacheToCodeFragments: </span><span class="nf">(cacheValues) -&gt;</span>
<span class="p">[</span><span class="nx">fragmentsToText</span><span class="p">(</span><span class="nx">cacheValues</span><span class="p">[</span><span class="mi">0</span><span class="p">]),</span> <span class="nx">fragmentsToText</span><span class="p">(</span><span class="nx">cacheValues</span><span class="p">[</span><span class="mi">1</span><span class="p">])]</span></pre></div></div>
</li>
<li id="section-11">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-11">&#182;</a>
</div>
<p>Construct a node that returns the current node&#39;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="nv">makeReturn: </span><span class="nf">(res) -&gt;</span>
<span class="nv">me = </span><span class="nx">@unwrapAll</span><span class="p">()</span>
<span class="k">if</span> <span class="nx">res</span>
<span class="k">new</span> <span class="nx">Call</span> <span class="k">new</span> <span class="nx">Literal</span><span class="p">(</span><span class="s">&quot;</span><span class="si">#{</span><span class="nx">res</span><span class="si">}</span><span class="s">.push&quot;</span><span class="p">),</span> <span class="p">[</span><span class="nx">me</span><span class="p">]</span>
<span class="k">else</span>
<span class="k">new</span> <span class="nx">Return</span> <span class="nx">me</span></pre></div></div>
</li>
<li id="section-12">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-12">&#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="nv">contains: </span><span class="nf">(pred) -&gt;</span>
<span class="nv">node = </span><span class="kc">undefined</span>
<span class="nx">@traverseChildren</span> <span class="kc">no</span><span class="p">,</span> <span class="nf">(n) -&gt;</span>
<span class="k">if</span> <span class="nx">pred</span> <span class="nx">n</span>
<span class="nv">node = </span><span class="nx">n</span>
<span class="k">return</span> <span class="kc">no</span>
<span class="nx">node</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>Pull out the last non-comment node of a node list.
</p>
</div>
<div class="content"><div class="highlight"><pre> <span class="nv">lastNonComment: </span><span class="nf">(list) -&gt;</span>
<span class="nv">i = </span><span class="nx">list</span><span class="p">.</span><span class="nx">length</span>
<span class="k">return</span> <span class="nx">list</span><span class="p">[</span><span class="nx">i</span><span class="p">]</span> <span class="k">while</span> <span class="nx">i</span><span class="o">--</span> <span class="k">when</span> <span class="nx">list</span><span class="p">[</span><span class="nx">i</span><span class="p">]</span> <span class="o">not</span> <span class="k">instanceof</span> <span class="nx">Comment</span>
<span class="kc">null</span></pre></div></div>
</li>
<li id="section-14">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-14">&#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="nv">toString: </span><span class="nf">(idt = &#39;&#39;, name = @constructor.name) -&gt;</span>
<span class="nv">tree = </span><span class="s">&#39;\n&#39;</span> <span class="o">+</span> <span class="nx">idt</span> <span class="o">+</span> <span class="nx">name</span>
<span class="nx">tree</span> <span class="o">+=</span> <span class="s">&#39;?&#39;</span> <span class="k">if</span> <span class="nx">@soak</span>
<span class="nx">@eachChild</span> <span class="nf">(node) -&gt;</span> <span class="nx">tree</span> <span class="o">+=</span> <span class="nx">node</span><span class="p">.</span><span class="nx">toString</span> <span class="nx">idt</span> <span class="o">+</span> <span class="nx">TAB</span>
<span class="nx">tree</span></pre></div></div>
</li>
<li id="section-15">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-15">&#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="nv">eachChild: </span><span class="nf">(func) -&gt;</span>
<span class="k">return</span> <span class="k">this</span> <span class="k">unless</span> <span class="nx">@children</span>
<span class="k">for</span> <span class="nx">attr</span> <span class="k">in</span> <span class="nx">@children</span> <span class="k">when</span> <span class="nx">@</span><span class="p">[</span><span class="nx">attr</span><span class="p">]</span>
<span class="k">for</span> <span class="nx">child</span> <span class="k">in</span> <span class="nx">flatten</span> <span class="p">[</span><span class="nx">@</span><span class="p">[</span><span class="nx">attr</span><span class="p">]]</span>
<span class="k">return</span> <span class="k">this</span> <span class="k">if</span> <span class="nx">func</span><span class="p">(</span><span class="nx">child</span><span class="p">)</span> <span class="o">is</span> <span class="kc">false</span>
<span class="k">this</span>
<span class="nv">traverseChildren: </span><span class="nf">(crossScope, func) -&gt;</span>
<span class="nx">@eachChild</span> <span class="nf">(child) -&gt;</span>
<span class="k">return</span> <span class="kc">false</span> <span class="k">if</span> <span class="nx">func</span><span class="p">(</span><span class="nx">child</span><span class="p">)</span> <span class="o">is</span> <span class="kc">false</span>
<span class="nx">child</span><span class="p">.</span><span class="nx">traverseChildren</span> <span class="nx">crossScope</span><span class="p">,</span> <span class="nx">func</span>
<span class="nv">invert: </span><span class="nf">-&gt;</span>
<span class="k">new</span> <span class="nx">Op</span> <span class="s">&#39;!&#39;</span><span class="p">,</span> <span class="k">this</span>
<span class="nv">unwrapAll: </span><span class="nf">-&gt;</span>
<span class="nv">node = </span><span class="k">this</span>
<span class="k">continue</span> <span class="k">until</span> <span class="nx">node</span> <span class="o">is</span> <span class="nv">node = </span><span class="nx">node</span><span class="p">.</span><span class="nx">unwrap</span><span class="p">()</span>
<span class="nx">node</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>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="nv">children: </span><span class="p">[]</span>
<span class="nv">isStatement : </span><span class="nx">NO</span>
<span class="nv">jumps : </span><span class="nx">NO</span>
<span class="nv">isComplex : </span><span class="nx">YES</span>
<span class="nv">isChainable : </span><span class="nx">NO</span>
<span class="nv">isAssignable : </span><span class="nx">NO</span>
<span class="nv">unwrap : </span><span class="nx">THIS</span>
<span class="nv">unfoldSoak : </span><span class="nx">NO</span></pre></div></div>
</li>
<li id="section-17">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-17">&#182;</a>
</div>
<p>Is this node used to assign a certain variable?
</p>
</div>
<div class="content"><div class="highlight"><pre> <span class="nv">assigns: </span><span class="nx">NO</span></pre></div></div>
</li>
<li id="section-18">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-18">&#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="nv">updateLocationDataIfMissing: </span><span class="nf">(locationData) -&gt;</span>
<span class="nx">@locationData</span> <span class="o">or=</span> <span class="nx">locationData</span>
<span class="nx">@eachChild</span> <span class="nf">(child) -&gt;</span>
<span class="nx">child</span><span class="p">.</span><span class="nx">updateLocationDataIfMissing</span> <span class="nx">locationData</span></pre></div></div>
</li>
<li id="section-19">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-19">&#182;</a>
</div>
<p>Throw a SyntaxError associated with this node&#39;s location.
</p>
</div>
<div class="content"><div class="highlight"><pre> <span class="nv">error: </span><span class="nf">(message) -&gt;</span>
<span class="nx">throwSyntaxError</span> <span class="nx">message</span><span class="p">,</span> <span class="nx">@locationData</span>
<span class="nv">makeCode: </span><span class="nf">(code) -&gt;</span>
<span class="k">new</span> <span class="nx">CodeFragment</span> <span class="k">this</span><span class="p">,</span> <span class="nx">code</span>
<span class="nv">wrapInBraces: </span><span class="nf">(fragments) -&gt;</span>
<span class="p">[].</span><span class="nx">concat</span> <span class="nx">@makeCode</span><span class="p">(</span><span class="s">&#39;(&#39;</span><span class="p">),</span> <span class="nx">fragments</span><span class="p">,</span> <span class="nx">@makeCode</span><span class="p">(</span><span class="s">&#39;)&#39;</span><span class="p">)</span></pre></div></div>
</li>
<li id="section-20">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-20">&#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="nv">joinFragmentArrays: </span><span class="nf">(fragmentsList, joinStr) -&gt;</span>
<span class="nv">answer = </span><span class="p">[]</span>
<span class="k">for</span> <span class="nx">fragments</span><span class="p">,</span><span class="nx">i</span> <span class="k">in</span> <span class="nx">fragmentsList</span>
<span class="k">if</span> <span class="nx">i</span> <span class="k">then</span> <span class="nx">answer</span><span class="p">.</span><span class="nx">push</span> <span class="nx">@makeCode</span> <span class="nx">joinStr</span>
<span class="nv">answer = </span><span class="nx">answer</span><span class="p">.</span><span class="nx">concat</span> <span class="nx">fragments</span>
<span class="nx">answer</span></pre></div></div>
</li>
<li id="section-21">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-21">&#182;</a>
</div>
<h3>Block</h3>
<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="nv">exports.Block = </span><span class="k">class</span> <span class="nx">Block</span> <span class="k">extends</span> <span class="nx">Base</span>
<span class="nv">constructor: </span><span class="nf">(nodes) -&gt;</span>
<span class="vi">@expressions = </span><span class="nx">compact</span> <span class="nx">flatten</span> <span class="nx">nodes</span> <span class="o">or</span> <span class="p">[]</span>
<span class="nv">children: </span><span class="p">[</span><span class="s">&#39;expressions&#39;</span><span class="p">]</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>Tack an expression on to the end of this expression list.
</p>
</div>
<div class="content"><div class="highlight"><pre> <span class="nv">push: </span><span class="nf">(node) -&gt;</span>
<span class="nx">@expressions</span><span class="p">.</span><span class="nx">push</span> <span class="nx">node</span>
<span class="k">this</span></pre></div></div>
</li>
<li id="section-23">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-23">&#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="nv">pop: </span><span class="nf">-&gt;</span>
<span class="nx">@expressions</span><span class="p">.</span><span class="nx">pop</span><span class="p">()</span></pre></div></div>
</li>
<li id="section-24">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-24">&#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="nv">unshift: </span><span class="nf">(node) -&gt;</span>
<span class="nx">@expressions</span><span class="p">.</span><span class="nx">unshift</span> <span class="nx">node</span>
<span class="k">this</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>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="nv">unwrap: </span><span class="nf">-&gt;</span>
<span class="k">if</span> <span class="nx">@expressions</span><span class="p">.</span><span class="nx">length</span> <span class="o">is</span> <span class="mi">1</span> <span class="k">then</span> <span class="nx">@expressions</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">else</span> <span class="k">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>Is this an empty block of code?
</p>
</div>
<div class="content"><div class="highlight"><pre> <span class="nv">isEmpty: </span><span class="nf">-&gt;</span>
<span class="o">not</span> <span class="nx">@expressions</span><span class="p">.</span><span class="nx">length</span>
<span class="nv">isStatement: </span><span class="nf">(o) -&gt;</span>
<span class="k">for</span> <span class="nx">exp</span> <span class="k">in</span> <span class="nx">@expressions</span> <span class="k">when</span> <span class="nx">exp</span><span class="p">.</span><span class="nx">isStatement</span> <span class="nx">o</span>
<span class="k">return</span> <span class="kc">yes</span>
<span class="kc">no</span>
<span class="nv">jumps: </span><span class="nf">(o) -&gt;</span>
<span class="k">for</span> <span class="nx">exp</span> <span class="k">in</span> <span class="nx">@expressions</span>
<span class="k">return</span> <span class="nx">exp</span> <span class="k">if</span> <span class="nx">exp</span><span class="p">.</span><span class="nx">jumps</span> <span class="nx">o</span></pre></div></div>
</li>
<li id="section-27">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-27">&#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="nv">makeReturn: </span><span class="nf">(res) -&gt;</span>
<span class="nv">len = </span><span class="nx">@expressions</span><span class="p">.</span><span class="nx">length</span>
<span class="k">while</span> <span class="nx">len</span><span class="o">--</span>
<span class="nv">expr = </span><span class="nx">@expressions</span><span class="p">[</span><span class="nx">len</span><span class="p">]</span>
<span class="k">if</span> <span class="nx">expr</span> <span class="o">not</span> <span class="k">instanceof</span> <span class="nx">Comment</span>
<span class="nx">@expressions</span><span class="p">[</span><span class="nx">len</span><span class="p">]</span> <span class="o">=</span> <span class="nx">expr</span><span class="p">.</span><span class="nx">makeReturn</span> <span class="nx">res</span>
<span class="nx">@expressions</span><span class="p">.</span><span class="nx">splice</span><span class="p">(</span><span class="nx">len</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span> <span class="k">if</span> <span class="nx">expr</span> <span class="k">instanceof</span> <span class="nx">Return</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">expr</span><span class="p">.</span><span class="nx">expression</span>
<span class="k">break</span>
<span class="k">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>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="nv">compileToFragments: </span><span class="nf">(o = {}, level) -&gt;</span>
<span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">scope</span> <span class="k">then</span> <span class="k">super</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">level</span> <span class="k">else</span> <span class="nx">@compileRoot</span> <span class="nx">o</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>Compile all expressions within the <strong>Block</strong> body. If we need to
return the result, and it&#39;s an expression, simply return it. If it&#39;s a
statement, ask the statement to do so.
</p>
</div>
<div class="content"><div class="highlight"><pre> <span class="nv">compileNode: </span><span class="nf">(o) -&gt;</span>
<span class="vi">@tab = </span><span class="nx">o</span><span class="p">.</span><span class="nx">indent</span>
<span class="nv">top = </span><span class="nx">o</span><span class="p">.</span><span class="nx">level</span> <span class="o">is</span> <span class="nx">LEVEL_TOP</span>
<span class="nv">compiledNodes = </span><span class="p">[]</span>
<span class="k">for</span> <span class="nx">node</span><span class="p">,</span> <span class="nx">index</span> <span class="k">in</span> <span class="nx">@expressions</span>
<span class="nv">node = </span><span class="nx">node</span><span class="p">.</span><span class="nx">unwrapAll</span><span class="p">()</span>
<span class="nv">node = </span><span class="p">(</span><span class="nx">node</span><span class="p">.</span><span class="nx">unfoldSoak</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">or</span> <span class="nx">node</span><span class="p">)</span>
<span class="k">if</span> <span class="nx">node</span> <span class="k">instanceof</span> <span class="nx">Block</span></pre></div></div>
</li>
<li id="section-30">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-30">&#182;</a>
</div>
<p>This is a nested block. We don&#39;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> <span class="nx">compiledNodes</span><span class="p">.</span><span class="nx">push</span> <span class="nx">node</span><span class="p">.</span><span class="nx">compileNode</span> <span class="nx">o</span>
<span class="k">else</span> <span class="k">if</span> <span class="nx">top</span>
<span class="nv">node.front = </span><span class="kc">true</span>
<span class="nv">fragments = </span><span class="nx">node</span><span class="p">.</span><span class="nx">compileToFragments</span> <span class="nx">o</span>
<span class="k">unless</span> <span class="nx">node</span><span class="p">.</span><span class="nx">isStatement</span> <span class="nx">o</span>
<span class="nx">fragments</span><span class="p">.</span><span class="nx">unshift</span> <span class="nx">@makeCode</span> <span class="s">&quot;</span><span class="si">#{</span><span class="nx">@tab</span><span class="si">}</span><span class="s">&quot;</span>
<span class="nx">fragments</span><span class="p">.</span><span class="nx">push</span> <span class="nx">@makeCode</span> <span class="s">&quot;;&quot;</span>
<span class="nx">compiledNodes</span><span class="p">.</span><span class="nx">push</span> <span class="nx">fragments</span>
<span class="k">else</span>
<span class="nx">compiledNodes</span><span class="p">.</span><span class="nx">push</span> <span class="nx">node</span><span class="p">.</span><span class="nx">compileToFragments</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_LIST</span>
<span class="k">if</span> <span class="nx">top</span>
<span class="k">if</span> <span class="nx">@spaced</span>
<span class="k">return</span> <span class="p">[].</span><span class="nx">concat</span> <span class="nx">@makeCode</span><span class="p">(</span><span class="s">&quot;\n&quot;</span><span class="p">),</span> <span class="nx">@joinFragmentArrays</span><span class="p">(</span><span class="nx">compiledNodes</span><span class="p">,</span> <span class="s">&#39;\n\n&#39;</span><span class="p">),</span> <span class="nx">@makeCode</span><span class="p">(</span><span class="s">&quot;\n&quot;</span><span class="p">)</span>
<span class="k">else</span>
<span class="k">return</span> <span class="nx">@joinFragmentArrays</span><span class="p">(</span><span class="nx">compiledNodes</span><span class="p">,</span> <span class="s">&#39;\n&#39;</span><span class="p">)</span>
<span class="k">if</span> <span class="nx">compiledNodes</span><span class="p">.</span><span class="nx">length</span>
<span class="nv">answer = </span><span class="nx">@joinFragmentArrays</span><span class="p">(</span><span class="nx">compiledNodes</span><span class="p">,</span> <span class="s">&#39;, &#39;</span><span class="p">)</span>
<span class="k">else</span>
<span class="nv">answer = </span><span class="p">[</span><span class="nx">@makeCode</span> <span class="s">&quot;void 0&quot;</span><span class="p">]</span>
<span class="k">if</span> <span class="nx">compiledNodes</span><span class="p">.</span><span class="nx">length</span> <span class="o">&gt;</span> <span class="mi">1</span> <span class="o">and</span> <span class="nx">o</span><span class="p">.</span><span class="nx">level</span> <span class="o">&gt;=</span> <span class="nx">LEVEL_LIST</span> <span class="k">then</span> <span class="nx">@wrapInBraces</span> <span class="nx">answer</span> <span class="k">else</span> <span class="nx">answer</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>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="nv">compileRoot: </span><span class="nf">(o) -&gt;</span>
<span class="nv">o.indent = </span><span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">bare</span> <span class="k">then</span> <span class="s">&#39;&#39;</span> <span class="k">else</span> <span class="nx">TAB</span>
<span class="nv">o.scope = </span><span class="k">new</span> <span class="nx">Scope</span> <span class="kc">null</span><span class="p">,</span> <span class="k">this</span><span class="p">,</span> <span class="kc">null</span>
<span class="nv">o.level = </span><span class="nx">LEVEL_TOP</span>
<span class="vi">@spaced = </span><span class="kc">yes</span>
<span class="nv">prelude = </span><span class="p">[]</span>
<span class="k">unless</span> <span class="nx">o</span><span class="p">.</span><span class="nx">bare</span>
<span class="nv">preludeExps = </span><span class="k">for</span> <span class="nx">exp</span><span class="p">,</span> <span class="nx">i</span> <span class="k">in</span> <span class="nx">@expressions</span>
<span class="k">break</span> <span class="k">unless</span> <span class="nx">exp</span><span class="p">.</span><span class="nx">unwrap</span><span class="p">()</span> <span class="k">instanceof</span> <span class="nx">Comment</span>
<span class="nx">exp</span>
<span class="nv">rest = </span><span class="nx">@expressions</span><span class="p">[</span><span class="nx">preludeExps</span><span class="p">.</span><span class="nx">length</span><span class="p">...]</span>
<span class="vi">@expressions = </span><span class="nx">preludeExps</span>
<span class="k">if</span> <span class="nx">preludeExps</span><span class="p">.</span><span class="nx">length</span>
<span class="nv">prelude = </span><span class="nx">@compileNode</span> <span class="nx">merge</span><span class="p">(</span><span class="nx">o</span><span class="p">,</span> <span class="nv">indent: </span><span class="s">&#39;&#39;</span><span class="p">)</span>
<span class="nx">prelude</span><span class="p">.</span><span class="nx">push</span> <span class="nx">@makeCode</span> <span class="s">&quot;\n&quot;</span>
<span class="vi">@expressions = </span><span class="nx">rest</span>
<span class="nv">fragments = </span><span class="nx">@compileWithDeclarations</span> <span class="nx">o</span>
<span class="k">return</span> <span class="nx">fragments</span> <span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">bare</span>
<span class="p">[].</span><span class="nx">concat</span> <span class="nx">prelude</span><span class="p">,</span> <span class="nx">@makeCode</span><span class="p">(</span><span class="s">&quot;(function() {\n&quot;</span><span class="p">),</span> <span class="nx">fragments</span><span class="p">,</span> <span class="nx">@makeCode</span><span class="p">(</span><span class="s">&quot;\n}).call(this);\n&quot;</span><span class="p">)</span></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 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="nv">compileWithDeclarations: </span><span class="nf">(o) -&gt;</span>
<span class="nv">fragments = </span><span class="p">[]</span>
<span class="nv">post = </span><span class="p">[]</span>
<span class="k">for</span> <span class="nx">exp</span><span class="p">,</span> <span class="nx">i</span> <span class="k">in</span> <span class="nx">@expressions</span>
<span class="nv">exp = </span><span class="nx">exp</span><span class="p">.</span><span class="nx">unwrap</span><span class="p">()</span>
<span class="k">break</span> <span class="k">unless</span> <span class="nx">exp</span> <span class="k">instanceof</span> <span class="nx">Comment</span> <span class="o">or</span> <span class="nx">exp</span> <span class="k">instanceof</span> <span class="nx">Literal</span>
<span class="nv">o = </span><span class="nx">merge</span><span class="p">(</span><span class="nx">o</span><span class="p">,</span> <span class="nv">level: </span><span class="nx">LEVEL_TOP</span><span class="p">)</span>
<span class="k">if</span> <span class="nx">i</span>
<span class="nv">rest = </span><span class="nx">@expressions</span><span class="p">.</span><span class="nx">splice</span> <span class="nx">i</span><span class="p">,</span> <span class="mi">9</span><span class="nx">e9</span>
<span class="p">[</span><span class="nx">spaced</span><span class="p">,</span> <span class="nx">@spaced</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="nx">@spaced</span><span class="p">,</span> <span class="kc">no</span><span class="p">]</span>
<span class="p">[</span><span class="nx">fragments</span><span class="p">,</span> <span class="nx">@spaced</span><span class="p">]</span> <span class="o">=</span> <span class="p">[(</span><span class="nx">@compileNode</span> <span class="nx">o</span><span class="p">),</span> <span class="nx">spaced</span><span class="p">]</span>
<span class="vi">@expressions = </span><span class="nx">rest</span>
<span class="nv">post = </span><span class="nx">@compileNode</span> <span class="nx">o</span>
<span class="p">{</span><span class="nx">scope</span><span class="p">}</span> <span class="o">=</span> <span class="nx">o</span>
<span class="k">if</span> <span class="nx">scope</span><span class="p">.</span><span class="nx">expressions</span> <span class="o">is</span> <span class="k">this</span>
<span class="nv">declars = </span><span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">hasDeclarations</span><span class="p">()</span>
<span class="nv">assigns = </span><span class="nx">scope</span><span class="p">.</span><span class="nx">hasAssignments</span>
<span class="k">if</span> <span class="nx">declars</span> <span class="o">or</span> <span class="nx">assigns</span>
<span class="nx">fragments</span><span class="p">.</span><span class="nx">push</span> <span class="nx">@makeCode</span> <span class="s">&#39;\n&#39;</span> <span class="k">if</span> <span class="nx">i</span>
<span class="nx">fragments</span><span class="p">.</span><span class="nx">push</span> <span class="nx">@makeCode</span> <span class="s">&quot;</span><span class="si">#{</span><span class="nx">@tab</span><span class="si">}</span><span class="s">var &quot;</span>
<span class="k">if</span> <span class="nx">declars</span>
<span class="nx">fragments</span><span class="p">.</span><span class="nx">push</span> <span class="nx">@makeCode</span><span class="p">(</span><span class="nx">scope</span><span class="p">.</span><span class="nx">declaredVariables</span><span class="p">().</span><span class="nx">join</span> <span class="s">&#39;, &#39;</span><span class="p">)</span>
<span class="k">if</span> <span class="nx">assigns</span>
<span class="nx">fragments</span><span class="p">.</span><span class="nx">push</span> <span class="nx">@makeCode</span> <span class="s">&quot;,\n</span><span class="si">#{</span><span class="nx">@tab</span> <span class="o">+</span> <span class="nx">TAB</span><span class="si">}</span><span class="s">&quot;</span> <span class="k">if</span> <span class="nx">declars</span>
<span class="nx">fragments</span><span class="p">.</span><span class="nx">push</span> <span class="nx">@makeCode</span> <span class="p">(</span><span class="nx">scope</span><span class="p">.</span><span class="nx">assignedVariables</span><span class="p">().</span><span class="nx">join</span> <span class="s">&quot;,\n</span><span class="si">#{</span><span class="nx">@tab</span> <span class="o">+</span> <span class="nx">TAB</span><span class="si">}</span><span class="s">&quot;</span><span class="p">)</span>
<span class="nx">fragments</span><span class="p">.</span><span class="nx">push</span> <span class="nx">@makeCode</span> <span class="s">&#39;;\n&#39;</span>
<span class="nx">fragments</span><span class="p">.</span><span class="nx">concat</span> <span class="nx">post</span></pre></div></div>
</li>
<li id="section-33">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-33">&#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="vi">@wrap: </span><span class="nf">(nodes) -&gt;</span>
<span class="k">return</span> <span class="nx">nodes</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">if</span> <span class="nx">nodes</span><span class="p">.</span><span class="nx">length</span> <span class="o">is</span> <span class="mi">1</span> <span class="o">and</span> <span class="nx">nodes</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">instanceof</span> <span class="nx">Block</span>
<span class="k">new</span> <span class="nx">Block</span> <span class="nx">nodes</span></pre></div></div>
</li>
<li id="section-34">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-34">&#182;</a>
</div>
<h3>Literal</h3>
<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="nv">exports.Literal = </span><span class="k">class</span> <span class="nx">Literal</span> <span class="k">extends</span> <span class="nx">Base</span>
<span class="nv">constructor: </span><span class="nf">(@value) -&gt;</span>
<span class="nv">makeReturn: </span><span class="nf">-&gt;</span>
<span class="k">if</span> <span class="nx">@isStatement</span><span class="p">()</span> <span class="k">then</span> <span class="k">this</span> <span class="k">else</span> <span class="k">super</span>
<span class="nv">isAssignable: </span><span class="nf">-&gt;</span>
<span class="nx">IDENTIFIER</span><span class="p">.</span><span class="nx">test</span> <span class="nx">@value</span>
<span class="nv">isStatement: </span><span class="nf">-&gt;</span>
<span class="nx">@value</span> <span class="k">in</span> <span class="p">[</span><span class="s">&#39;break&#39;</span><span class="p">,</span> <span class="s">&#39;continue&#39;</span><span class="p">,</span> <span class="s">&#39;debugger&#39;</span><span class="p">]</span>
<span class="nv">isComplex: </span><span class="nx">NO</span>
<span class="nv">assigns: </span><span class="nf">(name) -&gt;</span>
<span class="nx">name</span> <span class="o">is</span> <span class="nx">@value</span>
<span class="nv">jumps: </span><span class="nf">(o) -&gt;</span>
<span class="k">return</span> <span class="k">this</span> <span class="k">if</span> <span class="nx">@value</span> <span class="o">is</span> <span class="s">&#39;break&#39;</span> <span class="o">and</span> <span class="o">not</span> <span class="p">(</span><span class="nx">o</span><span class="o">?</span><span class="p">.</span><span class="nx">loop</span> <span class="o">or</span> <span class="nx">o</span><span class="o">?</span><span class="p">.</span><span class="nx">block</span><span class="p">)</span>
<span class="k">return</span> <span class="k">this</span> <span class="k">if</span> <span class="nx">@value</span> <span class="o">is</span> <span class="s">&#39;continue&#39;</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">o</span><span class="o">?</span><span class="p">.</span><span class="nx">loop</span>
<span class="nv">compileNode: </span><span class="nf">(o) -&gt;</span>
<span class="nv">code = </span><span class="k">if</span> <span class="nx">@value</span> <span class="o">is</span> <span class="s">&#39;this&#39;</span>
<span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">method</span><span class="o">?</span><span class="p">.</span><span class="nx">bound</span> <span class="k">then</span> <span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">method</span><span class="p">.</span><span class="nx">context</span> <span class="k">else</span> <span class="nx">@value</span>
<span class="k">else</span> <span class="k">if</span> <span class="nx">@value</span><span class="p">.</span><span class="nx">reserved</span>
<span class="s">&quot;\&quot;</span><span class="si">#{</span><span class="nx">@value</span><span class="si">}</span><span class="s">\&quot;&quot;</span>
<span class="k">else</span>
<span class="nx">@value</span>
<span class="nv">answer = </span><span class="k">if</span> <span class="nx">@isStatement</span><span class="p">()</span> <span class="k">then</span> <span class="s">&quot;</span><span class="si">#{</span><span class="nx">@tab</span><span class="si">}#{</span><span class="nx">code</span><span class="si">}</span><span class="s">;&quot;</span> <span class="k">else</span> <span class="nx">code</span>
<span class="p">[</span><span class="nx">@makeCode</span> <span class="nx">answer</span><span class="p">]</span>
<span class="nv">toString: </span><span class="nf">-&gt;</span>
<span class="s">&#39; &quot;&#39;</span> <span class="o">+</span> <span class="nx">@value</span> <span class="o">+</span> <span class="s">&#39;&quot;&#39;</span>
<span class="k">class</span> <span class="nx">exports</span><span class="p">.</span><span class="nx">Undefined</span> <span class="k">extends</span> <span class="nx">Base</span>
<span class="nv">isAssignable: </span><span class="nx">NO</span>
<span class="nv">isComplex: </span><span class="nx">NO</span>
<span class="nv">compileNode: </span><span class="nf">(o) -&gt;</span>
<span class="p">[</span><span class="nx">@makeCode</span> <span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">level</span> <span class="o">&gt;=</span> <span class="nx">LEVEL_ACCESS</span> <span class="k">then</span> <span class="s">&#39;(void 0)&#39;</span> <span class="k">else</span> <span class="s">&#39;void 0&#39;</span><span class="p">]</span>
<span class="k">class</span> <span class="nx">exports</span><span class="p">.</span><span class="nx">Null</span> <span class="k">extends</span> <span class="nx">Base</span>
<span class="nv">isAssignable: </span><span class="nx">NO</span>
<span class="nv">isComplex: </span><span class="nx">NO</span>
<span class="nv">compileNode: </span><span class="nf">-&gt;</span> <span class="p">[</span><span class="nx">@makeCode</span> <span class="s">&quot;null&quot;</span><span class="p">]</span>
<span class="k">class</span> <span class="nx">exports</span><span class="p">.</span><span class="nx">Bool</span> <span class="k">extends</span> <span class="nx">Base</span>
<span class="nv">isAssignable: </span><span class="nx">NO</span>
<span class="nv">isComplex: </span><span class="nx">NO</span>
<span class="nv">compileNode: </span><span class="nf">-&gt;</span> <span class="p">[</span><span class="nx">@makeCode</span> <span class="nx">@val</span><span class="p">]</span>
<span class="nv">constructor: </span><span class="nf">(@val) -&gt;</span></pre></div></div>
</li>
<li id="section-35">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-35">&#182;</a>
</div>
<h3>Return</h3>
<p>A <code>return</code> is a <em>pureStatement</em> -- wrapping it in a closure wouldn&#39;t
make sense.
</p>
</div>
<div class="content"><div class="highlight"><pre><span class="nv">exports.Return = </span><span class="k">class</span> <span class="nx">Return</span> <span class="k">extends</span> <span class="nx">Base</span>
<span class="nv">constructor: </span><span class="nf">(expr) -&gt;</span>
<span class="vi">@expression = </span><span class="nx">expr</span> <span class="k">if</span> <span class="nx">expr</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">expr</span><span class="p">.</span><span class="nx">unwrap</span><span class="p">().</span><span class="nx">isUndefined</span>
<span class="nv">children: </span><span class="p">[</span><span class="s">&#39;expression&#39;</span><span class="p">]</span>
<span class="nv">isStatement: </span> <span class="nx">YES</span>
<span class="nv">makeReturn: </span> <span class="nx">THIS</span>
<span class="nv">jumps: </span> <span class="nx">THIS</span>
<span class="nv">compileToFragments: </span><span class="nf">(o, level) -&gt;</span>
<span class="nv">expr = </span><span class="nx">@expression</span><span class="o">?</span><span class="p">.</span><span class="nx">makeReturn</span><span class="p">()</span>
<span class="k">if</span> <span class="nx">expr</span> <span class="o">and</span> <span class="nx">expr</span> <span class="o">not</span> <span class="k">instanceof</span> <span class="nx">Return</span> <span class="k">then</span> <span class="nx">expr</span><span class="p">.</span><span class="nx">compileToFragments</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">level</span> <span class="k">else</span> <span class="k">super</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">level</span>
<span class="nv">compileNode: </span><span class="nf">(o) -&gt;</span>
<span class="nv">answer = </span><span class="p">[]</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>TODO: If we call expression.compile() here twice, we&#39;ll sometimes get back different results!
</p>
</div>
<div class="content"><div class="highlight"><pre> <span class="nx">answer</span><span class="p">.</span><span class="nx">push</span> <span class="nx">@makeCode</span><span class="p">(</span><span class="nx">@tab</span> <span class="o">+</span> <span class="s">&quot;return</span><span class="si">#{</span><span class="p">[</span><span class="s">&quot; &quot;</span> <span class="k">if</span> <span class="nx">@expression</span><span class="p">]</span><span class="si">}</span><span class="s">&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="nx">@expression</span>
<span class="nv">answer = </span><span class="nx">answer</span><span class="p">.</span><span class="nx">concat</span> <span class="nx">@expression</span><span class="p">.</span><span class="nx">compileToFragments</span><span class="p">(</span><span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_PAREN</span><span class="p">)</span>
<span class="nx">answer</span><span class="p">.</span><span class="nx">push</span> <span class="nx">@makeCode</span> <span class="s">&quot;;&quot;</span>
<span class="k">return</span> <span class="nx">answer</span></pre></div></div>
</li>
<li id="section-37">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-37">&#182;</a>
</div>
<h3>Value</h3>
<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="nv">exports.Value = </span><span class="k">class</span> <span class="nx">Value</span> <span class="k">extends</span> <span class="nx">Base</span>
<span class="nv">constructor: </span><span class="nf">(base, props, tag) -&gt;</span>
<span class="k">return</span> <span class="nx">base</span> <span class="k">if</span> <span class="o">not</span> <span class="nx">props</span> <span class="o">and</span> <span class="nx">base</span> <span class="k">instanceof</span> <span class="nx">Value</span>
<span class="vi">@base = </span><span class="nx">base</span>
<span class="vi">@properties = </span><span class="nx">props</span> <span class="o">or</span> <span class="p">[]</span>
<span class="nx">@</span><span class="p">[</span><span class="nx">tag</span><span class="p">]</span> <span class="o">=</span> <span class="kc">true</span> <span class="k">if</span> <span class="nx">tag</span>
<span class="k">return</span> <span class="k">this</span>
<span class="nv">children: </span><span class="p">[</span><span class="s">&#39;base&#39;</span><span class="p">,</span> <span class="s">&#39;properties&#39;</span><span class="p">]</span></pre></div></div>
</li>
<li id="section-38">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-38">&#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="nv">add: </span><span class="nf">(props) -&gt;</span>
<span class="vi">@properties = </span><span class="nx">@properties</span><span class="p">.</span><span class="nx">concat</span> <span class="nx">props</span>
<span class="k">this</span>
<span class="nv">hasProperties: </span><span class="nf">-&gt;</span>
<span class="o">!!</span><span class="nx">@properties</span><span class="p">.</span><span class="nx">length</span></pre></div></div>
</li>
<li id="section-39">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-39">&#182;</a>
</div>
<p>Some boolean checks for the benefit of other nodes.
</p>
</div>
<div class="content"><div class="highlight"><pre> <span class="nv">isArray : </span><span class="nf">-&gt;</span> <span class="o">not</span> <span class="nx">@properties</span><span class="p">.</span><span class="nx">length</span> <span class="o">and</span> <span class="nx">@base</span> <span class="k">instanceof</span> <span class="nx">Arr</span>
<span class="nv">isComplex : </span><span class="nf">-&gt;</span> <span class="nx">@hasProperties</span><span class="p">()</span> <span class="o">or</span> <span class="nx">@base</span><span class="p">.</span><span class="nx">isComplex</span><span class="p">()</span>
<span class="nv">isAssignable : </span><span class="nf">-&gt;</span> <span class="nx">@hasProperties</span><span class="p">()</span> <span class="o">or</span> <span class="nx">@base</span><span class="p">.</span><span class="nx">isAssignable</span><span class="p">()</span>
<span class="nv">isSimpleNumber : </span><span class="nf">-&gt;</span> <span class="nx">@base</span> <span class="k">instanceof</span> <span class="nx">Literal</span> <span class="o">and</span> <span class="nx">SIMPLENUM</span><span class="p">.</span><span class="nx">test</span> <span class="nx">@base</span><span class="p">.</span><span class="nx">value</span>
<span class="nv">isString : </span><span class="nf">-&gt;</span> <span class="nx">@base</span> <span class="k">instanceof</span> <span class="nx">Literal</span> <span class="o">and</span> <span class="nx">IS_STRING</span><span class="p">.</span><span class="nx">test</span> <span class="nx">@base</span><span class="p">.</span><span class="nx">value</span>
<span class="nv">isAtomic : </span><span class="nf">-&gt;</span>
<span class="k">for</span> <span class="nx">node</span> <span class="k">in</span> <span class="nx">@properties</span><span class="p">.</span><span class="nx">concat</span> <span class="nx">@base</span>
<span class="k">return</span> <span class="kc">no</span> <span class="k">if</span> <span class="nx">node</span><span class="p">.</span><span class="nx">soak</span> <span class="o">or</span> <span class="nx">node</span> <span class="k">instanceof</span> <span class="nx">Call</span>
<span class="kc">yes</span>
<span class="nv">isStatement : </span><span class="nf">(o) -&gt;</span> <span class="o">not</span> <span class="nx">@properties</span><span class="p">.</span><span class="nx">length</span> <span class="o">and</span> <span class="nx">@base</span><span class="p">.</span><span class="nx">isStatement</span> <span class="nx">o</span>
<span class="nv">assigns : </span><span class="nf">(name) -&gt;</span> <span class="o">not</span> <span class="nx">@properties</span><span class="p">.</span><span class="nx">length</span> <span class="o">and</span> <span class="nx">@base</span><span class="p">.</span><span class="nx">assigns</span> <span class="nx">name</span>
<span class="nv">jumps : </span><span class="nf">(o) -&gt;</span> <span class="o">not</span> <span class="nx">@properties</span><span class="p">.</span><span class="nx">length</span> <span class="o">and</span> <span class="nx">@base</span><span class="p">.</span><span class="nx">jumps</span> <span class="nx">o</span>
<span class="nv">isObject: </span><span class="nf">(onlyGenerated) -&gt;</span>
<span class="k">return</span> <span class="kc">no</span> <span class="k">if</span> <span class="nx">@properties</span><span class="p">.</span><span class="nx">length</span>
<span class="p">(</span><span class="nx">@base</span> <span class="k">instanceof</span> <span class="nx">Obj</span><span class="p">)</span> <span class="o">and</span> <span class="p">(</span><span class="o">not</span> <span class="nx">onlyGenerated</span> <span class="o">or</span> <span class="nx">@base</span><span class="p">.</span><span class="nx">generated</span><span class="p">)</span>
<span class="nv">isSplice: </span><span class="nf">-&gt;</span>
<span class="nx">last</span><span class="p">(</span><span class="nx">@properties</span><span class="p">)</span> <span class="k">instanceof</span> <span class="nx">Slice</span></pre></div></div>
</li>
<li id="section-40">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-40">&#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="nv">unwrap: </span><span class="nf">-&gt;</span>
<span class="k">if</span> <span class="nx">@properties</span><span class="p">.</span><span class="nx">length</span> <span class="k">then</span> <span class="k">this</span> <span class="k">else</span> <span class="nx">@base</span></pre></div></div>
</li>
<li id="section-41">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-41">&#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="nv">cacheReference: </span><span class="nf">(o) -&gt;</span>
<span class="nv">name = </span><span class="nx">last</span> <span class="nx">@properties</span>
<span class="k">if</span> <span class="nx">@properties</span><span class="p">.</span><span class="nx">length</span> <span class="o">&lt;</span> <span class="mi">2</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">@base</span><span class="p">.</span><span class="nx">isComplex</span><span class="p">()</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">name</span><span class="o">?</span><span class="p">.</span><span class="nx">isComplex</span><span class="p">()</span>
<span class="k">return</span> <span class="p">[</span><span class="k">this</span><span class="p">,</span> <span class="k">this</span><span class="p">]</span> <span class="c1"># `a` `a.b`</span>
<span class="nv">base = </span><span class="k">new</span> <span class="nx">Value</span> <span class="nx">@base</span><span class="p">,</span> <span class="nx">@properties</span><span class="p">[...</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
<span class="k">if</span> <span class="nx">base</span><span class="p">.</span><span class="nx">isComplex</span><span class="p">()</span> <span class="c1"># `a().b`</span>
<span class="nv">bref = </span><span class="k">new</span> <span class="nx">Literal</span> <span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span> <span class="s">&#39;base&#39;</span>
<span class="nv">base = </span><span class="k">new</span> <span class="nx">Value</span> <span class="k">new</span> <span class="nx">Parens</span> <span class="k">new</span> <span class="nx">Assign</span> <span class="nx">bref</span><span class="p">,</span> <span class="nx">base</span>
<span class="k">return</span> <span class="p">[</span><span class="nx">base</span><span class="p">,</span> <span class="nx">bref</span><span class="p">]</span> <span class="k">unless</span> <span class="nx">name</span> <span class="c1"># `a()`</span>
<span class="k">if</span> <span class="nx">name</span><span class="p">.</span><span class="nx">isComplex</span><span class="p">()</span> <span class="c1"># `a[b()]`</span>
<span class="nv">nref = </span><span class="k">new</span> <span class="nx">Literal</span> <span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span> <span class="s">&#39;name&#39;</span>
<span class="nv">name = </span><span class="k">new</span> <span class="nx">Index</span> <span class="k">new</span> <span class="nx">Assign</span> <span class="nx">nref</span><span class="p">,</span> <span class="nx">name</span><span class="p">.</span><span class="nx">index</span>
<span class="nv">nref = </span><span class="k">new</span> <span class="nx">Index</span> <span class="nx">nref</span>
<span class="p">[</span><span class="nx">base</span><span class="p">.</span><span class="nx">add</span><span class="p">(</span><span class="nx">name</span><span class="p">),</span> <span class="k">new</span> <span class="nx">Value</span><span class="p">(</span><span class="nx">bref</span> <span class="o">or</span> <span class="nx">base</span><span class="p">.</span><span class="nx">base</span><span class="p">,</span> <span class="p">[</span><span class="nx">nref</span> <span class="o">or</span> <span class="nx">name</span><span class="p">])]</span></pre></div></div>
</li>
<li id="section-42">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-42">&#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="nv">compileNode: </span><span class="nf">(o) -&gt;</span>
<span class="vi">@base.front = </span><span class="nx">@front</span>
<span class="nv">props = </span><span class="nx">@properties</span>
<span class="nv">fragments = </span><span class="nx">@base</span><span class="p">.</span><span class="nx">compileToFragments</span> <span class="nx">o</span><span class="p">,</span> <span class="p">(</span><span class="k">if</span> <span class="nx">props</span><span class="p">.</span><span class="nx">length</span> <span class="k">then</span> <span class="nx">LEVEL_ACCESS</span> <span class="k">else</span> <span class="kc">null</span><span class="p">)</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">@base</span> <span class="k">instanceof</span> <span class="nx">Parens</span> <span class="o">or</span> <span class="nx">props</span><span class="p">.</span><span class="nx">length</span><span class="p">)</span> <span class="o">and</span> <span class="nx">SIMPLENUM</span><span class="p">.</span><span class="nx">test</span> <span class="nx">fragmentsToText</span> <span class="nx">fragments</span>
<span class="nx">fragments</span><span class="p">.</span><span class="nx">push</span> <span class="nx">@makeCode</span> <span class="s">&#39;.&#39;</span>
<span class="k">for</span> <span class="nx">prop</span> <span class="k">in</span> <span class="nx">props</span>
<span class="nx">fragments</span><span class="p">.</span><span class="nx">push</span> <span class="p">(</span><span class="nx">prop</span><span class="p">.</span><span class="nx">compileToFragments</span> <span class="nx">o</span><span class="p">)...</span>
<span class="nx">fragments</span></pre></div></div>
</li>
<li id="section-43">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-43">&#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="nv">unfoldSoak: </span><span class="nf">(o) -&gt;</span>
<span class="nx">@unfoldedSoak</span> <span class="o">?=</span> <span class="nx">do</span> <span class="o">=&gt;</span>
<span class="k">if</span> <span class="nv">ifn = </span><span class="nx">@base</span><span class="p">.</span><span class="nx">unfoldSoak</span> <span class="nx">o</span>
<span class="nx">ifn</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">properties</span><span class="p">.</span><span class="nx">push</span> <span class="nx">@properties</span><span class="p">...</span>
<span class="k">return</span> <span class="nx">ifn</span>
<span class="k">for</span> <span class="nx">prop</span><span class="p">,</span> <span class="nx">i</span> <span class="k">in</span> <span class="nx">@properties</span> <span class="k">when</span> <span class="nx">prop</span><span class="p">.</span><span class="nx">soak</span>
<span class="nv">prop.soak = </span><span class="kc">off</span>
<span class="nv">fst = </span><span class="k">new</span> <span class="nx">Value</span> <span class="nx">@base</span><span class="p">,</span> <span class="nx">@properties</span><span class="p">[...</span><span class="nx">i</span><span class="p">]</span>
<span class="nv">snd = </span><span class="k">new</span> <span class="nx">Value</span> <span class="nx">@base</span><span class="p">,</span> <span class="nx">@properties</span><span class="p">[</span><span class="nx">i</span><span class="p">..]</span>
<span class="k">if</span> <span class="nx">fst</span><span class="p">.</span><span class="nx">isComplex</span><span class="p">()</span>
<span class="nv">ref = </span><span class="k">new</span> <span class="nx">Literal</span> <span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span> <span class="s">&#39;ref&#39;</span>
<span class="nv">fst = </span><span class="k">new</span> <span class="nx">Parens</span> <span class="k">new</span> <span class="nx">Assign</span> <span class="nx">ref</span><span class="p">,</span> <span class="nx">fst</span>
<span class="nv">snd.base = </span><span class="nx">ref</span>
<span class="k">return</span> <span class="k">new</span> <span class="nx">If</span> <span class="k">new</span> <span class="nx">Existence</span><span class="p">(</span><span class="nx">fst</span><span class="p">),</span> <span class="nx">snd</span><span class="p">,</span> <span class="nv">soak: </span><span class="kc">on</span>
<span class="kc">no</span></pre></div></div>
</li>
<li id="section-44">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-44">&#182;</a>
</div>
<h3>Comment</h3>
<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="nv">exports.Comment = </span><span class="k">class</span> <span class="nx">Comment</span> <span class="k">extends</span> <span class="nx">Base</span>
<span class="nv">constructor: </span><span class="nf">(@comment) -&gt;</span>
<span class="nv">isStatement: </span> <span class="nx">YES</span>
<span class="nv">makeReturn: </span> <span class="nx">THIS</span>
<span class="nv">compileNode: </span><span class="nf">(o, level) -&gt;</span>
<span class="nv">code = </span><span class="s">&#39;/*&#39;</span> <span class="o">+</span> <span class="nx">multident</span><span class="p">(</span><span class="nx">@comment</span><span class="p">,</span> <span class="nx">@tab</span><span class="p">)</span> <span class="o">+</span> <span class="s">&quot;\n</span><span class="si">#{</span><span class="nx">@tab</span><span class="si">}</span><span class="s">*/\n&quot;</span>
<span class="nv">code = </span><span class="nx">o</span><span class="p">.</span><span class="nx">indent</span> <span class="o">+</span> <span class="nx">code</span> <span class="k">if</span> <span class="p">(</span><span class="nx">level</span> <span class="o">or</span> <span class="nx">o</span><span class="p">.</span><span class="nx">level</span><span class="p">)</span> <span class="o">is</span> <span class="nx">LEVEL_TOP</span>
<span class="p">[</span><span class="nx">@makeCode</span> <span class="nx">code</span><span class="p">]</span></pre></div></div>
</li>
<li id="section-45">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-45">&#182;</a>
</div>
<h3>Call</h3>
<p>Node for a function invocation. Takes care of converting <code>super()</code> calls into
calls against the prototype&#39;s function of the same name.
</p>
</div>
<div class="content"><div class="highlight"><pre><span class="nv">exports.Call = </span><span class="k">class</span> <span class="nx">Call</span> <span class="k">extends</span> <span class="nx">Base</span>
<span class="nv">constructor: </span><span class="nf">(variable, @args = [], @soak) -&gt;</span>
<span class="vi">@isNew = </span><span class="kc">false</span>
<span class="vi">@isSuper = </span><span class="nx">variable</span> <span class="o">is</span> <span class="s">&#39;super&#39;</span>
<span class="vi">@variable = </span><span class="k">if</span> <span class="nx">@isSuper</span> <span class="k">then</span> <span class="kc">null</span> <span class="k">else</span> <span class="nx">variable</span>
<span class="nv">children: </span><span class="p">[</span><span class="s">&#39;variable&#39;</span><span class="p">,</span> <span class="s">&#39;args&#39;</span><span class="p">]</span></pre></div></div>
</li>
<li id="section-46">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-46">&#182;</a>
</div>
<p>Tag this invocation as creating a new instance.
</p>
</div>
<div class="content"><div class="highlight"><pre> <span class="nv">newInstance: </span><span class="nf">-&gt;</span>
<span class="nv">base = </span><span class="nx">@variable</span><span class="o">?</span><span class="p">.</span><span class="nx">base</span> <span class="o">or</span> <span class="nx">@variable</span>
<span class="k">if</span> <span class="nx">base</span> <span class="k">instanceof</span> <span class="nx">Call</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">base</span><span class="p">.</span><span class="nx">isNew</span>
<span class="nx">base</span><span class="p">.</span><span class="nx">newInstance</span><span class="p">()</span>
<span class="k">else</span>
<span class="vi">@isNew = </span><span class="kc">true</span>
<span class="k">this</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>Grab the reference to the superclass&#39;s implementation of the current
method.
</p>
</div>
<div class="content"><div class="highlight"><pre> <span class="nv">superReference: </span><span class="nf">(o) -&gt;</span>
<span class="nv">method = </span><span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">namedMethod</span><span class="p">()</span>
<span class="k">if</span> <span class="nx">method</span><span class="o">?</span><span class="p">.</span><span class="nx">klass</span>
<span class="nv">accesses = </span><span class="p">[</span><span class="k">new</span> <span class="nx">Access</span><span class="p">(</span><span class="k">new</span> <span class="nx">Literal</span> <span class="s">&#39;__super__&#39;</span><span class="p">)]</span>
<span class="nx">accesses</span><span class="p">.</span><span class="nx">push</span> <span class="k">new</span> <span class="nx">Access</span> <span class="k">new</span> <span class="nx">Literal</span> <span class="s">&#39;constructor&#39;</span> <span class="k">if</span> <span class="nx">method</span><span class="p">.</span><span class="nx">static</span>
<span class="nx">accesses</span><span class="p">.</span><span class="nx">push</span> <span class="k">new</span> <span class="nx">Access</span> <span class="k">new</span> <span class="nx">Literal</span> <span class="nx">method</span><span class="p">.</span><span class="nx">name</span>
<span class="p">(</span><span class="k">new</span> <span class="nx">Value</span> <span class="p">(</span><span class="k">new</span> <span class="nx">Literal</span> <span class="nx">method</span><span class="p">.</span><span class="nx">klass</span><span class="p">),</span> <span class="nx">accesses</span><span class="p">).</span><span class="nx">compile</span> <span class="nx">o</span>
<span class="k">else</span> <span class="k">if</span> <span class="nx">method</span><span class="o">?</span><span class="p">.</span><span class="nx">ctor</span>
<span class="s">&quot;</span><span class="si">#{</span><span class="nx">method</span><span class="p">.</span><span class="nx">name</span><span class="si">}</span><span class="s">.__super__.constructor&quot;</span>
<span class="k">else</span>
<span class="nx">@error</span> <span class="s">&#39;cannot call super outside of an instance method.&#39;</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>The appropriate <code>this</code> value for a <code>super</code> call.
</p>
</div>
<div class="content"><div class="highlight"><pre> <span class="nv">superThis : </span><span class="nf">(o) -&gt;</span>
<span class="nv">method = </span><span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">method</span>
<span class="p">(</span><span class="nx">method</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">method</span><span class="p">.</span><span class="nx">klass</span> <span class="o">and</span> <span class="nx">method</span><span class="p">.</span><span class="nx">context</span><span class="p">)</span> <span class="o">or</span> <span class="s">&quot;this&quot;</span></pre></div></div>
</li>
<li id="section-49">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-49">&#182;</a>
</div>
<p>Soaked chained invocations unfold into if/else ternary structures.
</p>
</div>
<div class="content"><div class="highlight"><pre> <span class="nv">unfoldSoak: </span><span class="nf">(o) -&gt;</span>
<span class="k">if</span> <span class="nx">@soak</span>
<span class="k">if</span> <span class="nx">@variable</span>
<span class="k">return</span> <span class="nx">ifn</span> <span class="k">if</span> <span class="nv">ifn = </span><span class="nx">unfoldSoak</span> <span class="nx">o</span><span class="p">,</span> <span class="k">this</span><span class="p">,</span> <span class="s">&#39;variable&#39;</span>
<span class="p">[</span><span class="nx">left</span><span class="p">,</span> <span class="nx">rite</span><span class="p">]</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Value</span><span class="p">(</span><span class="nx">@variable</span><span class="p">).</span><span class="nx">cacheReference</span> <span class="nx">o</span>
<span class="k">else</span>
<span class="nv">left = </span><span class="k">new</span> <span class="nx">Literal</span> <span class="nx">@superReference</span> <span class="nx">o</span>
<span class="nv">rite = </span><span class="k">new</span> <span class="nx">Value</span> <span class="nx">left</span>
<span class="nv">rite = </span><span class="k">new</span> <span class="nx">Call</span> <span class="nx">rite</span><span class="p">,</span> <span class="nx">@args</span>
<span class="nv">rite.isNew = </span><span class="nx">@isNew</span>
<span class="nv">left = </span><span class="k">new</span> <span class="nx">Literal</span> <span class="s">&quot;typeof </span><span class="si">#{</span> <span class="nx">left</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">o</span> <span class="si">}</span><span class="s"> === \&quot;function\&quot;&quot;</span>
<span class="k">return</span> <span class="k">new</span> <span class="nx">If</span> <span class="nx">left</span><span class="p">,</span> <span class="k">new</span> <span class="nx">Value</span><span class="p">(</span><span class="nx">rite</span><span class="p">),</span> <span class="nv">soak: </span><span class="kc">yes</span>
<span class="nv">call = </span><span class="k">this</span>
<span class="nv">list = </span><span class="p">[]</span>
<span class="k">loop</span>
<span class="k">if</span> <span class="nx">call</span><span class="p">.</span><span class="nx">variable</span> <span class="k">instanceof</span> <span class="nx">Call</span>
<span class="nx">list</span><span class="p">.</span><span class="nx">push</span> <span class="nx">call</span>
<span class="nv">call = </span><span class="nx">call</span><span class="p">.</span><span class="nx">variable</span>
<span class="k">continue</span>
<span class="k">break</span> <span class="k">unless</span> <span class="nx">call</span><span class="p">.</span><span class="nx">variable</span> <span class="k">instanceof</span> <span class="nx">Value</span>
<span class="nx">list</span><span class="p">.</span><span class="nx">push</span> <span class="nx">call</span>
<span class="k">break</span> <span class="k">unless</span> <span class="p">(</span><span class="nv">call = </span><span class="nx">call</span><span class="p">.</span><span class="nx">variable</span><span class="p">.</span><span class="nx">base</span><span class="p">)</span> <span class="k">instanceof</span> <span class="nx">Call</span>
<span class="k">for</span> <span class="nx">call</span> <span class="k">in</span> <span class="nx">list</span><span class="p">.</span><span class="nx">reverse</span><span class="p">()</span>
<span class="k">if</span> <span class="nx">ifn</span>
<span class="k">if</span> <span class="nx">call</span><span class="p">.</span><span class="nx">variable</span> <span class="k">instanceof</span> <span class="nx">Call</span>
<span class="nv">call.variable = </span><span class="nx">ifn</span>
<span class="k">else</span>
<span class="nv">call.variable.base = </span><span class="nx">ifn</span>
<span class="nv">ifn = </span><span class="nx">unfoldSoak</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">call</span><span class="p">,</span> <span class="s">&#39;variable&#39;</span>
<span class="nx">ifn</span></pre></div></div>
</li>
<li id="section-50">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-50">&#182;</a>
</div>
<p>Compile a vanilla function call.
</p>
</div>
<div class="content"><div class="highlight"><pre> <span class="nv">compileNode: </span><span class="nf">(o) -&gt;</span>
<span class="nx">@variable</span><span class="o">?</span><span class="p">.</span><span class="nv">front = </span><span class="nx">@front</span>
<span class="nv">compiledArray = </span><span class="nx">Splat</span><span class="p">.</span><span class="nx">compileSplattedArray</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">@args</span><span class="p">,</span> <span class="kc">true</span>
<span class="k">if</span> <span class="nx">compiledArray</span><span class="p">.</span><span class="nx">length</span>
<span class="k">return</span> <span class="nx">@compileSplat</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">compiledArray</span>
<span class="nv">compiledArgs = </span><span class="p">[]</span>
<span class="k">for</span> <span class="nx">arg</span><span class="p">,</span> <span class="nx">argIndex</span> <span class="k">in</span> <span class="nx">@args</span>
<span class="k">if</span> <span class="nx">argIndex</span> <span class="k">then</span> <span class="nx">compiledArgs</span><span class="p">.</span><span class="nx">push</span> <span class="nx">@makeCode</span> <span class="s">&quot;, &quot;</span>
<span class="nx">compiledArgs</span><span class="p">.</span><span class="nx">push</span> <span class="p">(</span><span class="nx">arg</span><span class="p">.</span><span class="nx">compileToFragments</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_LIST</span><span class="p">)...</span>
<span class="nv">fragments = </span><span class="p">[]</span>
<span class="k">if</span> <span class="nx">@isSuper</span>
<span class="nv">preface = </span><span class="nx">@superReference</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">+</span> <span class="s">&quot;.call(</span><span class="si">#{</span><span class="nx">@superThis</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span><span class="si">}</span><span class="s">&quot;</span>
<span class="k">if</span> <span class="nx">compiledArgs</span><span class="p">.</span><span class="nx">length</span> <span class="k">then</span> <span class="nx">preface</span> <span class="o">+=</span> <span class="s">&quot;, &quot;</span>
<span class="nx">fragments</span><span class="p">.</span><span class="nx">push</span> <span class="nx">@makeCode</span> <span class="nx">preface</span>
<span class="k">else</span>
<span class="k">if</span> <span class="nx">@isNew</span> <span class="k">then</span> <span class="nx">fragments</span><span class="p">.</span><span class="nx">push</span> <span class="nx">@makeCode</span> <span class="s">&#39;new &#39;</span>
<span class="nx">fragments</span><span class="p">.</span><span class="nx">push</span> <span class="p">(</span><span class="nx">@variable</span><span class="p">.</span><span class="nx">compileToFragments</span><span class="p">(</span><span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_ACCESS</span><span class="p">))...</span>
<span class="nx">fragments</span><span class="p">.</span><span class="nx">push</span> <span class="nx">@makeCode</span> <span class="s">&quot;(&quot;</span>
<span class="nx">fragments</span><span class="p">.</span><span class="nx">push</span> <span class="nx">compiledArgs</span><span class="p">...</span>
<span class="nx">fragments</span><span class="p">.</span><span class="nx">push</span> <span class="nx">@makeCode</span> <span class="s">&quot;)&quot;</span>
<span class="nx">fragments</span></pre></div></div>
</li>
<li id="section-51">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-51">&#182;</a>
</div>
<p>If you call a function with a splat, it&#39;s converted into a JavaScript
<code>.apply()</code> call to allow an array of arguments to be passed.
If it&#39;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 &#39;apply&#39;.
</p>
</div>
<div class="content"><div class="highlight"><pre> <span class="nv">compileSplat: </span><span class="nf">(o, splatArgs) -&gt;</span>
<span class="k">if</span> <span class="nx">@isSuper</span>
<span class="k">return</span> <span class="p">[].</span><span class="nx">concat</span> <span class="nx">@makeCode</span><span class="p">(</span><span class="s">&quot;</span><span class="si">#{</span> <span class="nx">@superReference</span> <span class="nx">o</span> <span class="si">}</span><span class="s">.apply(</span><span class="si">#{</span><span class="nx">@superThis</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span><span class="si">}</span><span class="s">, &quot;</span><span class="p">),</span>
<span class="nx">splatArgs</span><span class="p">,</span> <span class="nx">@makeCode</span><span class="p">(</span><span class="s">&quot;)&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="nx">@isNew</span>
<span class="nv">idt = </span><span class="nx">@tab</span> <span class="o">+</span> <span class="nx">TAB</span>
<span class="k">return</span> <span class="p">[].</span><span class="nx">concat</span> <span class="nx">@makeCode</span><span class="p">(</span><span class="s">&quot;&quot;&quot;</span>
<span class="s"> (function(func, args, ctor) {</span>
<span class="s"> </span><span class="si">#{</span><span class="nx">idt</span><span class="si">}</span><span class="s">ctor.prototype = func.prototype;</span>
<span class="s"> </span><span class="si">#{</span><span class="nx">idt</span><span class="si">}</span><span class="s">var child = new ctor, result = func.apply(child, args);</span>
<span class="s"> </span><span class="si">#{</span><span class="nx">idt</span><span class="si">}</span><span class="s">return Object(result) === result ? result : child;</span>
<span class="s"> </span><span class="si">#{</span><span class="nx">@tab</span><span class="si">}</span><span class="s">})(&quot;&quot;&quot;</span><span class="p">),</span>
<span class="p">(</span><span class="nx">@variable</span><span class="p">.</span><span class="nx">compileToFragments</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_LIST</span><span class="p">),</span>
<span class="nx">@makeCode</span><span class="p">(</span><span class="s">&quot;, &quot;</span><span class="p">),</span> <span class="nx">splatArgs</span><span class="p">,</span> <span class="nx">@makeCode</span><span class="p">(</span><span class="s">&quot;, function(){})&quot;</span><span class="p">)</span>
<span class="nv">answer = </span><span class="p">[]</span>
<span class="nv">base = </span><span class="k">new</span> <span class="nx">Value</span> <span class="nx">@variable</span>
<span class="k">if</span> <span class="p">(</span><span class="nv">name = </span><span class="nx">base</span><span class="p">.</span><span class="nx">properties</span><span class="p">.</span><span class="nx">pop</span><span class="p">())</span> <span class="o">and</span> <span class="nx">base</span><span class="p">.</span><span class="nx">isComplex</span><span class="p">()</span>
<span class="nv">ref = </span><span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span> <span class="s">&#39;ref&#39;</span>
<span class="nv">answer = </span><span class="nx">answer</span><span class="p">.</span><span class="nx">concat</span> <span class="nx">@makeCode</span><span class="p">(</span><span class="s">&quot;(</span><span class="si">#{</span><span class="nx">ref</span><span class="si">}</span><span class="s"> = &quot;</span><span class="p">),</span>
<span class="p">(</span><span class="nx">base</span><span class="p">.</span><span class="nx">compileToFragments</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_LIST</span><span class="p">),</span>
<span class="nx">@makeCode</span><span class="p">(</span><span class="s">&quot;)&quot;</span><span class="p">),</span>
<span class="nx">name</span><span class="p">.</span><span class="nx">compileToFragments</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span>
<span class="k">else</span>
<span class="nv">fun = </span><span class="nx">base</span><span class="p">.</span><span class="nx">compileToFragments</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_ACCESS</span>
<span class="nv">fun = </span><span class="nx">@wrapInBraces</span> <span class="nx">fun</span> <span class="k">if</span> <span class="nx">SIMPLENUM</span><span class="p">.</span><span class="nx">test</span> <span class="nx">fragmentsToText</span> <span class="nx">fun</span>
<span class="k">if</span> <span class="nx">name</span>
<span class="nv">ref = </span><span class="nx">fragmentsToText</span> <span class="nx">fun</span>
<span class="nx">fun</span><span class="p">.</span><span class="nx">push</span> <span class="p">(</span><span class="nx">name</span><span class="p">.</span><span class="nx">compileToFragments</span> <span class="nx">o</span><span class="p">)...</span>
<span class="k">else</span>
<span class="nv">ref = </span><span class="s">&#39;null&#39;</span>
<span class="nv">answer = </span><span class="nx">answer</span><span class="p">.</span><span class="nx">concat</span> <span class="nx">fun</span>
<span class="nv">answer = </span><span class="nx">answer</span><span class="p">.</span><span class="nx">concat</span> <span class="nx">@makeCode</span><span class="p">(</span><span class="s">&quot;.apply(</span><span class="si">#{</span><span class="nx">ref</span><span class="si">}</span><span class="s">, &quot;</span><span class="p">),</span> <span class="nx">splatArgs</span><span class="p">,</span> <span class="nx">@makeCode</span><span class="p">(</span><span class="s">&quot;)&quot;</span><span class="p">)</span></pre></div></div>
</li>
<li id="section-52">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-52">&#182;</a>
</div>
<h3>Extends</h3>
<p>Node to extend an object&#39;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="nv">exports.Extends = </span><span class="k">class</span> <span class="nx">Extends</span> <span class="k">extends</span> <span class="nx">Base</span>
<span class="nv">constructor: </span><span class="nf">(@child, @parent) -&gt;</span>
<span class="nv">children: </span><span class="p">[</span><span class="s">&#39;child&#39;</span><span class="p">,</span> <span class="s">&#39;parent&#39;</span><span class="p">]</span></pre></div></div>
</li>
<li id="section-53">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-53">&#182;</a>
</div>
<p>Hooks one constructor into another&#39;s prototype chain.
</p>
</div>
<div class="content"><div class="highlight"><pre> <span class="nv">compileToFragments: </span><span class="nf">(o) -&gt;</span>
<span class="k">new</span> <span class="nx">Call</span><span class="p">(</span><span class="k">new</span> <span class="nx">Value</span><span class="p">(</span><span class="k">new</span> <span class="nx">Literal</span> <span class="nx">utility</span> <span class="s">&#39;extends&#39;</span><span class="p">),</span> <span class="p">[</span><span class="nx">@child</span><span class="p">,</span> <span class="nx">@parent</span><span class="p">]).</span><span class="nx">compileToFragments</span> <span class="nx">o</span></pre></div></div>
</li>
<li id="section-54">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-54">&#182;</a>
</div>
<h3>Access</h3>
<p>A <code>.</code> access into a property of a value, or the <code>::</code> shorthand for
an access into the object&#39;s prototype.
</p>
</div>
<div class="content"><div class="highlight"><pre><span class="nv">exports.Access = </span><span class="k">class</span> <span class="nx">Access</span> <span class="k">extends</span> <span class="nx">Base</span>
<span class="nv">constructor: </span><span class="nf">(@name, tag) -&gt;</span>
<span class="vi">@name.asKey = </span><span class="kc">yes</span>
<span class="vi">@soak = </span><span class="nx">tag</span> <span class="o">is</span> <span class="s">&#39;soak&#39;</span>
<span class="nv">children: </span><span class="p">[</span><span class="s">&#39;name&#39;</span><span class="p">]</span>
<span class="nv">compileToFragments: </span><span class="nf">(o) -&gt;</span>
<span class="nv">name = </span><span class="nx">@name</span><span class="p">.</span><span class="nx">compileToFragments</span> <span class="nx">o</span>
<span class="k">if</span> <span class="nx">IDENTIFIER</span><span class="p">.</span><span class="nx">test</span> <span class="nx">fragmentsToText</span> <span class="nx">name</span>
<span class="nx">name</span><span class="p">.</span><span class="nx">unshift</span> <span class="nx">@makeCode</span> <span class="s">&quot;.&quot;</span>
<span class="k">else</span>
<span class="nx">name</span><span class="p">.</span><span class="nx">unshift</span> <span class="nx">@makeCode</span> <span class="s">&quot;[&quot;</span>
<span class="nx">name</span><span class="p">.</span><span class="nx">push</span> <span class="nx">@makeCode</span> <span class="s">&quot;]&quot;</span>
<span class="nx">name</span>
<span class="nv">isComplex: </span><span class="nx">NO</span></pre></div></div>
</li>
<li id="section-55">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-55">&#182;</a>
</div>
<h3>Index</h3>
<p>A <code>[ ... ]</code> indexed access into an array or object.
</p>
</div>
<div class="content"><div class="highlight"><pre><span class="nv">exports.Index = </span><span class="k">class</span> <span class="nx">Index</span> <span class="k">extends</span> <span class="nx">Base</span>
<span class="nv">constructor: </span><span class="nf">(@index) -&gt;</span>
<span class="nv">children: </span><span class="p">[</span><span class="s">&#39;index&#39;</span><span class="p">]</span>
<span class="nv">compileToFragments: </span><span class="nf">(o) -&gt;</span>
<span class="p">[].</span><span class="nx">concat</span> <span class="nx">@makeCode</span><span class="p">(</span><span class="s">&quot;[&quot;</span><span class="p">),</span> <span class="p">(</span><span class="nx">@index</span><span class="p">.</span><span class="nx">compileToFragments</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_PAREN</span><span class="p">),</span> <span class="nx">@makeCode</span><span class="p">(</span><span class="s">&quot;]&quot;</span><span class="p">)</span>
<span class="nv">isComplex: </span><span class="nf">-&gt;</span>
<span class="nx">@index</span><span class="p">.</span><span class="nx">isComplex</span><span class="p">()</span></pre></div></div>
</li>
<li id="section-56">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-56">&#182;</a>
</div>
<h3>Range</h3>
<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="nv">exports.Range = </span><span class="k">class</span> <span class="nx">Range</span> <span class="k">extends</span> <span class="nx">Base</span>
<span class="nv">children: </span><span class="p">[</span><span class="s">&#39;from&#39;</span><span class="p">,</span> <span class="s">&#39;to&#39;</span><span class="p">]</span>
<span class="nv">constructor: </span><span class="nf">(@from, @to, tag) -&gt;</span>
<span class="vi">@exclusive = </span><span class="nx">tag</span> <span class="o">is</span> <span class="s">&#39;exclusive&#39;</span>
<span class="vi">@equals = </span><span class="k">if</span> <span class="nx">@exclusive</span> <span class="k">then</span> <span class="s">&#39;&#39;</span> <span class="k">else</span> <span class="s">&#39;=&#39;</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>Compiles the range&#39;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="nv">compileVariables: </span><span class="nf">(o) -&gt;</span>
<span class="nv">o = </span><span class="nx">merge</span> <span class="nx">o</span><span class="p">,</span> <span class="nv">top: </span><span class="kc">true</span>
<span class="p">[</span><span class="nx">@fromC</span><span class="p">,</span> <span class="nx">@fromVar</span><span class="p">]</span> <span class="o">=</span> <span class="nx">@cacheToCodeFragments</span> <span class="nx">@from</span><span class="p">.</span><span class="nx">cache</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_LIST</span>
<span class="p">[</span><span class="nx">@toC</span><span class="p">,</span> <span class="nx">@toVar</span><span class="p">]</span> <span class="o">=</span> <span class="nx">@cacheToCodeFragments</span> <span class="nx">@to</span><span class="p">.</span><span class="nx">cache</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_LIST</span>
<span class="p">[</span><span class="nx">@step</span><span class="p">,</span> <span class="nx">@stepVar</span><span class="p">]</span> <span class="o">=</span> <span class="nx">@cacheToCodeFragments</span> <span class="nx">step</span><span class="p">.</span><span class="nx">cache</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_LIST</span> <span class="k">if</span> <span class="nv">step = </span><span class="nx">del</span> <span class="nx">o</span><span class="p">,</span> <span class="s">&#39;step&#39;</span>
<span class="p">[</span><span class="nx">@fromNum</span><span class="p">,</span> <span class="nx">@toNum</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="nx">@fromVar</span><span class="p">.</span><span class="nx">match</span><span class="p">(</span><span class="nx">SIMPLENUM</span><span class="p">),</span> <span class="nx">@toVar</span><span class="p">.</span><span class="nx">match</span><span class="p">(</span><span class="nx">SIMPLENUM</span><span class="p">)]</span>
<span class="vi">@stepNum = </span><span class="nx">@stepVar</span><span class="p">.</span><span class="nx">match</span><span class="p">(</span><span class="nx">SIMPLENUM</span><span class="p">)</span> <span class="k">if</span> <span class="nx">@stepVar</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>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="nv">compileNode: </span><span class="nf">(o) -&gt;</span>
<span class="nx">@compileVariables</span> <span class="nx">o</span> <span class="k">unless</span> <span class="nx">@fromVar</span>
<span class="k">return</span> <span class="nx">@compileArray</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="k">unless</span> <span class="nx">o</span><span class="p">.</span><span class="nx">index</span></pre></div></div>
</li>
<li id="section-59">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-59">&#182;</a>
</div>
<p>Set up endpoints.
</p>
</div>
<div class="content"><div class="highlight"><pre> <span class="nv">known = </span><span class="nx">@fromNum</span> <span class="o">and</span> <span class="nx">@toNum</span>
<span class="nv">idx = </span><span class="nx">del</span> <span class="nx">o</span><span class="p">,</span> <span class="s">&#39;index&#39;</span>
<span class="nv">idxName = </span><span class="nx">del</span> <span class="nx">o</span><span class="p">,</span> <span class="s">&#39;name&#39;</span>
<span class="nv">namedIndex = </span><span class="nx">idxName</span> <span class="o">and</span> <span class="nx">idxName</span> <span class="o">isnt</span> <span class="nx">idx</span>
<span class="nv">varPart = </span><span class="s">&quot;</span><span class="si">#{</span><span class="nx">idx</span><span class="si">}</span><span class="s"> = </span><span class="si">#{</span><span class="nx">@fromC</span><span class="si">}</span><span class="s">&quot;</span>
<span class="nx">varPart</span> <span class="o">+=</span> <span class="s">&quot;, </span><span class="si">#{</span><span class="nx">@toC</span><span class="si">}</span><span class="s">&quot;</span> <span class="k">if</span> <span class="nx">@toC</span> <span class="o">isnt</span> <span class="nx">@toVar</span>
<span class="nx">varPart</span> <span class="o">+=</span> <span class="s">&quot;, </span><span class="si">#{</span><span class="nx">@step</span><span class="si">}</span><span class="s">&quot;</span> <span class="k">if</span> <span class="nx">@step</span> <span class="o">isnt</span> <span class="nx">@stepVar</span>
<span class="p">[</span><span class="nx">lt</span><span class="p">,</span> <span class="nx">gt</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="s">&quot;</span><span class="si">#{</span><span class="nx">idx</span><span class="si">}</span><span class="s"> &lt;</span><span class="si">#{</span><span class="nx">@equals</span><span class="si">}</span><span class="s">&quot;</span><span class="p">,</span> <span class="s">&quot;</span><span class="si">#{</span><span class="nx">idx</span><span class="si">}</span><span class="s"> &gt;</span><span class="si">#{</span><span class="nx">@equals</span><span class="si">}</span><span class="s">&quot;</span><span class="p">]</span></pre></div></div>
</li>
<li id="section-60">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-60">&#182;</a>
</div>
<p>Generate the condition.
</p>
</div>
<div class="content"><div class="highlight"><pre> <span class="nv">condPart = </span><span class="k">if</span> <span class="nx">@stepNum</span>
<span class="k">if</span> <span class="o">+</span><span class="nx">@stepNum</span> <span class="o">&gt;</span> <span class="mi">0</span> <span class="k">then</span> <span class="s">&quot;</span><span class="si">#{</span><span class="nx">lt</span><span class="si">}</span><span class="s"> </span><span class="si">#{</span><span class="nx">@toVar</span><span class="si">}</span><span class="s">&quot;</span> <span class="k">else</span> <span class="s">&quot;</span><span class="si">#{</span><span class="nx">gt</span><span class="si">}</span><span class="s"> </span><span class="si">#{</span><span class="nx">@toVar</span><span class="si">}</span><span class="s">&quot;</span>
<span class="k">else</span> <span class="k">if</span> <span class="nx">known</span>
<span class="p">[</span><span class="nx">from</span><span class="p">,</span> <span class="nx">to</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="o">+</span><span class="nx">@fromNum</span><span class="p">,</span> <span class="o">+</span><span class="nx">@toNum</span><span class="p">]</span>
<span class="k">if</span> <span class="nx">from</span> <span class="o">&lt;=</span> <span class="nx">to</span> <span class="k">then</span> <span class="s">&quot;</span><span class="si">#{</span><span class="nx">lt</span><span class="si">}</span><span class="s"> </span><span class="si">#{</span><span class="nx">to</span><span class="si">}</span><span class="s">&quot;</span> <span class="k">else</span> <span class="s">&quot;</span><span class="si">#{</span><span class="nx">gt</span><span class="si">}</span><span class="s"> </span><span class="si">#{</span><span class="nx">to</span><span class="si">}</span><span class="s">&quot;</span>
<span class="k">else</span>
<span class="nv">cond = </span><span class="k">if</span> <span class="nx">@stepVar</span> <span class="k">then</span> <span class="s">&quot;</span><span class="si">#{</span><span class="nx">@stepVar</span><span class="si">}</span><span class="s"> &gt; 0&quot;</span> <span class="k">else</span> <span class="s">&quot;</span><span class="si">#{</span><span class="nx">@fromVar</span><span class="si">}</span><span class="s"> &lt;= </span><span class="si">#{</span><span class="nx">@toVar</span><span class="si">}</span><span class="s">&quot;</span>
<span class="s">&quot;</span><span class="si">#{</span><span class="nx">cond</span><span class="si">}</span><span class="s"> ? </span><span class="si">#{</span><span class="nx">lt</span><span class="si">}</span><span class="s"> </span><span class="si">#{</span><span class="nx">@toVar</span><span class="si">}</span><span class="s"> : </span><span class="si">#{</span><span class="nx">gt</span><span class="si">}</span><span class="s"> </span><span class="si">#{</span><span class="nx">@toVar</span><span class="si">}</span><span class="s">&quot;</span></pre></div></div>
</li>
<li id="section-61">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-61">&#182;</a>
</div>
<p>Generate the step.
</p>
</div>
<div class="content"><div class="highlight"><pre> <span class="nv">stepPart = </span><span class="k">if</span> <span class="nx">@stepVar</span>
<span class="s">&quot;</span><span class="si">#{</span><span class="nx">idx</span><span class="si">}</span><span class="s"> += </span><span class="si">#{</span><span class="nx">@stepVar</span><span class="si">}</span><span class="s">&quot;</span>
<span class="k">else</span> <span class="k">if</span> <span class="nx">known</span>
<span class="k">if</span> <span class="nx">namedIndex</span>
<span class="k">if</span> <span class="nx">from</span> <span class="o">&lt;=</span> <span class="nx">to</span> <span class="k">then</span> <span class="s">&quot;++</span><span class="si">#{</span><span class="nx">idx</span><span class="si">}</span><span class="s">&quot;</span> <span class="k">else</span> <span class="s">&quot;--</span><span class="si">#{</span><span class="nx">idx</span><span class="si">}</span><span class="s">&quot;</span>
<span class="k">else</span>
<span class="k">if</span> <span class="nx">from</span> <span class="o">&lt;=</span> <span class="nx">to</span> <span class="k">then</span> <span class="s">&quot;</span><span class="si">#{</span><span class="nx">idx</span><span class="si">}</span><span class="s">++&quot;</span> <span class="k">else</span> <span class="s">&quot;</span><span class="si">#{</span><span class="nx">idx</span><span class="si">}</span><span class="s">--&quot;</span>
<span class="k">else</span>
<span class="k">if</span> <span class="nx">namedIndex</span>
<span class="s">&quot;</span><span class="si">#{</span><span class="nx">cond</span><span class="si">}</span><span class="s"> ? ++</span><span class="si">#{</span><span class="nx">idx</span><span class="si">}</span><span class="s"> : --</span><span class="si">#{</span><span class="nx">idx</span><span class="si">}</span><span class="s">&quot;</span>
<span class="k">else</span>
<span class="s">&quot;</span><span class="si">#{</span><span class="nx">cond</span><span class="si">}</span><span class="s"> ? </span><span class="si">#{</span><span class="nx">idx</span><span class="si">}</span><span class="s">++ : </span><span class="si">#{</span><span class="nx">idx</span><span class="si">}</span><span class="s">--&quot;</span>
<span class="nv">varPart = </span><span class="s">&quot;</span><span class="si">#{</span><span class="nx">idxName</span><span class="si">}</span><span class="s"> = </span><span class="si">#{</span><span class="nx">varPart</span><span class="si">}</span><span class="s">&quot;</span> <span class="k">if</span> <span class="nx">namedIndex</span>
<span class="nv">stepPart = </span><span class="s">&quot;</span><span class="si">#{</span><span class="nx">idxName</span><span class="si">}</span><span class="s"> = </span><span class="si">#{</span><span class="nx">stepPart</span><span class="si">}</span><span class="s">&quot;</span> <span class="k">if</span> <span class="nx">namedIndex</span></pre></div></div>
</li>
<li id="section-62">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-62">&#182;</a>
</div>
<p>The final loop body.
</p>
</div>
<div class="content"><div class="highlight"><pre> <span class="p">[</span><span class="nx">@makeCode</span> <span class="s">&quot;</span><span class="si">#{</span><span class="nx">varPart</span><span class="si">}</span><span class="s">; </span><span class="si">#{</span><span class="nx">condPart</span><span class="si">}</span><span class="s">; </span><span class="si">#{</span><span class="nx">stepPart</span><span class="si">}</span><span class="s">&quot;</span><span class="p">]</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>When used as a value, expand the range into the equivalent array.
</p>
</div>
<div class="content"><div class="highlight"><pre> <span class="nv">compileArray: </span><span class="nf">(o) -&gt;</span>
<span class="k">if</span> <span class="nx">@fromNum</span> <span class="o">and</span> <span class="nx">@toNum</span> <span class="o">and</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">abs</span><span class="p">(</span><span class="nx">@fromNum</span> <span class="o">-</span> <span class="nx">@toNum</span><span class="p">)</span> <span class="o">&lt;=</span> <span class="mi">20</span>
<span class="nv">range = </span><span class="p">[</span><span class="o">+</span><span class="nx">@fromNum</span><span class="p">..</span><span class="o">+</span><span class="nx">@toNum</span><span class="p">]</span>
<span class="nx">range</span><span class="p">.</span><span class="nx">pop</span><span class="p">()</span> <span class="k">if</span> <span class="nx">@exclusive</span>
<span class="k">return</span> <span class="p">[</span><span class="nx">@makeCode</span> <span class="s">&quot;[</span><span class="si">#{</span> <span class="nx">range</span><span class="p">.</span><span class="nx">join</span><span class="p">(</span><span class="s">&#39;, &#39;</span><span class="p">)</span> <span class="si">}</span><span class="s">]&quot;</span><span class="p">]</span>
<span class="nv">idt = </span><span class="nx">@tab</span> <span class="o">+</span> <span class="nx">TAB</span>
<span class="nv">i = </span><span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span> <span class="s">&#39;i&#39;</span>
<span class="nv">result = </span><span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span> <span class="s">&#39;results&#39;</span>
<span class="nv">pre = </span><span class="s">&quot;\n</span><span class="si">#{</span><span class="nx">idt</span><span class="si">}#{</span><span class="nx">result</span><span class="si">}</span><span class="s"> = [];&quot;</span>
<span class="k">if</span> <span class="nx">@fromNum</span> <span class="o">and</span> <span class="nx">@toNum</span>
<span class="nv">o.index = </span><span class="nx">i</span>
<span class="nv">body = </span><span class="nx">fragmentsToText</span> <span class="nx">@compileNode</span> <span class="nx">o</span>
<span class="k">else</span>
<span class="nv">vars = </span><span class="s">&quot;</span><span class="si">#{</span><span class="nx">i</span><span class="si">}</span><span class="s"> = </span><span class="si">#{</span><span class="nx">@fromC</span><span class="si">}</span><span class="s">&quot;</span> <span class="o">+</span> <span class="k">if</span> <span class="nx">@toC</span> <span class="o">isnt</span> <span class="nx">@toVar</span> <span class="k">then</span> <span class="s">&quot;, </span><span class="si">#{</span><span class="nx">@toC</span><span class="si">}</span><span class="s">&quot;</span> <span class="k">else</span> <span class="s">&#39;&#39;</span>
<span class="nv">cond = </span><span class="s">&quot;</span><span class="si">#{</span><span class="nx">@fromVar</span><span class="si">}</span><span class="s"> &lt;= </span><span class="si">#{</span><span class="nx">@toVar</span><span class="si">}</span><span class="s">&quot;</span>
<span class="nv">body = </span><span class="s">&quot;var </span><span class="si">#{</span><span class="nx">vars</span><span class="si">}</span><span class="s">; </span><span class="si">#{</span><span class="nx">cond</span><span class="si">}</span><span class="s"> ? </span><span class="si">#{</span><span class="nx">i</span><span class="si">}</span><span class="s"> &lt;</span><span class="si">#{</span><span class="nx">@equals</span><span class="si">}</span><span class="s"> </span><span class="si">#{</span><span class="nx">@toVar</span><span class="si">}</span><span class="s"> : </span><span class="si">#{</span><span class="nx">i</span><span class="si">}</span><span class="s"> &gt;</span><span class="si">#{</span><span class="nx">@equals</span><span class="si">}</span><span class="s"> </span><span class="si">#{</span><span class="nx">@toVar</span><span class="si">}</span><span class="s">; </span><span class="si">#{</span><span class="nx">cond</span><span class="si">}</span><span class="s"> ? </span><span class="si">#{</span><span class="nx">i</span><span class="si">}</span><span class="s">++ : </span><span class="si">#{</span><span class="nx">i</span><span class="si">}</span><span class="s">--&quot;</span>
<span class="nv">post = </span><span class="s">&quot;{ </span><span class="si">#{</span><span class="nx">result</span><span class="si">}</span><span class="s">.push(</span><span class="si">#{</span><span class="nx">i</span><span class="si">}</span><span class="s">); }\n</span><span class="si">#{</span><span class="nx">idt</span><span class="si">}</span><span class="s">return </span><span class="si">#{</span><span class="nx">result</span><span class="si">}</span><span class="s">;\n</span><span class="si">#{</span><span class="nx">o</span><span class="p">.</span><span class="nx">indent</span><span class="si">}</span><span class="s">&quot;</span>
<span class="nv">hasArgs = </span><span class="nf">(node) -&gt;</span> <span class="nx">node</span><span class="o">?</span><span class="p">.</span><span class="nx">contains</span> <span class="nf">(n) -&gt;</span> <span class="nx">n</span> <span class="k">instanceof</span> <span class="nx">Literal</span> <span class="o">and</span> <span class="nx">n</span><span class="p">.</span><span class="nx">value</span> <span class="o">is</span> <span class="s">&#39;arguments&#39;</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">n</span><span class="p">.</span><span class="nx">asKey</span>
<span class="nv">args = </span><span class="s">&#39;, arguments&#39;</span> <span class="k">if</span> <span class="nx">hasArgs</span><span class="p">(</span><span class="nx">@from</span><span class="p">)</span> <span class="o">or</span> <span class="nx">hasArgs</span><span class="p">(</span><span class="nx">@to</span><span class="p">)</span>
<span class="p">[</span><span class="nx">@makeCode</span> <span class="s">&quot;(function() {</span><span class="si">#{</span><span class="nx">pre</span><span class="si">}</span><span class="s">\n</span><span class="si">#{</span><span class="nx">idt</span><span class="si">}</span><span class="s">for (</span><span class="si">#{</span><span class="nx">body</span><span class="si">}</span><span class="s">)</span><span class="si">#{</span><span class="nx">post</span><span class="si">}</span><span class="s">}).apply(this</span><span class="si">#{</span><span class="nx">args</span> <span class="o">?</span> <span class="s">&#39;&#39;</span><span class="si">}</span><span class="s">)&quot;</span><span class="p">]</span></pre></div></div>
</li>
<li id="section-64">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-64">&#182;</a>
</div>
<h3>Slice</h3>
<p>An array slice literal. Unlike JavaScript&#39;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="nv">exports.Slice = </span><span class="k">class</span> <span class="nx">Slice</span> <span class="k">extends</span> <span class="nx">Base</span>
<span class="nv">children: </span><span class="p">[</span><span class="s">&#39;range&#39;</span><span class="p">]</span>
<span class="nv">constructor: </span><span class="nf">(@range) -&gt;</span>
<span class="k">super</span><span class="p">()</span></pre></div></div>
</li>
<li id="section-65">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-65">&#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="nv">compileNode: </span><span class="nf">(o) -&gt;</span>
<span class="p">{</span><span class="nx">to</span><span class="p">,</span> <span class="nx">from</span><span class="p">}</span> <span class="o">=</span> <span class="nx">@range</span>
<span class="nv">fromCompiled = </span><span class="nx">from</span> <span class="o">and</span> <span class="nx">from</span><span class="p">.</span><span class="nx">compileToFragments</span><span class="p">(</span><span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_PAREN</span><span class="p">)</span> <span class="o">or</span> <span class="p">[</span><span class="nx">@makeCode</span> <span class="s">&#39;0&#39;</span><span class="p">]</span></pre></div></div>
</li>
<li id="section-66">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-66">&#182;</a>
</div>
<p>TODO: jwalton - move this into the &#39;if&#39;?
</p>
</div>
<div class="content"><div class="highlight"><pre> <span class="k">if</span> <span class="nx">to</span>
<span class="nv">compiled = </span><span class="nx">to</span><span class="p">.</span><span class="nx">compileToFragments</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_PAREN</span>
<span class="nv">compiledText = </span><span class="nx">fragmentsToText</span> <span class="nx">compiled</span>
<span class="k">if</span> <span class="o">not</span> <span class="p">(</span><span class="o">not</span> <span class="nx">@range</span><span class="p">.</span><span class="nx">exclusive</span> <span class="o">and</span> <span class="o">+</span><span class="nx">compiledText</span> <span class="o">is</span> <span class="o">-</span><span class="mi">1</span><span class="p">)</span>
<span class="nv">toStr = </span><span class="s">&#39;, &#39;</span> <span class="o">+</span> <span class="k">if</span> <span class="nx">@range</span><span class="p">.</span><span class="nx">exclusive</span>
<span class="nx">compiledText</span>
<span class="k">else</span> <span class="k">if</span> <span class="nx">SIMPLENUM</span><span class="p">.</span><span class="nx">test</span> <span class="nx">compiledText</span>
<span class="s">&quot;</span><span class="si">#{</span><span class="o">+</span><span class="nx">compiledText</span> <span class="o">+</span> <span class="mi">1</span><span class="si">}</span><span class="s">&quot;</span>
<span class="k">else</span>
<span class="nv">compiled = </span><span class="nx">to</span><span class="p">.</span><span class="nx">compileToFragments</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_ACCESS</span>
<span class="s">&quot;+</span><span class="si">#{</span><span class="nx">fragmentsToText</span> <span class="nx">compiled</span><span class="si">}</span><span class="s"> + 1 || 9e9&quot;</span>
<span class="p">[</span><span class="nx">@makeCode</span> <span class="s">&quot;.slice(</span><span class="si">#{</span> <span class="nx">fragmentsToText</span> <span class="nx">fromCompiled</span> <span class="si">}#{</span> <span class="nx">toStr</span> <span class="o">or</span> <span class="s">&#39;&#39;</span> <span class="si">}</span><span class="s">)&quot;</span><span class="p">]</span></pre></div></div>
</li>
<li id="section-67">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-67">&#182;</a>
</div>
<h3>Obj</h3>
<p>An object literal, nothing fancy.
</p>
</div>
<div class="content"><div class="highlight"><pre><span class="nv">exports.Obj = </span><span class="k">class</span> <span class="nx">Obj</span> <span class="k">extends</span> <span class="nx">Base</span>
<span class="nv">constructor: </span><span class="nf">(props, @generated = false) -&gt;</span>
<span class="vi">@objects = @properties = </span><span class="nx">props</span> <span class="o">or</span> <span class="p">[]</span>
<span class="nv">children: </span><span class="p">[</span><span class="s">&#39;properties&#39;</span><span class="p">]</span>
<span class="nv">compileNode: </span><span class="nf">(o) -&gt;</span>
<span class="nv">props = </span><span class="nx">@properties</span>
<span class="k">return</span> <span class="p">[</span><span class="nx">@makeCode</span><span class="p">(</span><span class="k">if</span> <span class="nx">@front</span> <span class="k">then</span> <span class="s">&#39;({})&#39;</span> <span class="k">else</span> <span class="s">&#39;{}&#39;</span><span class="p">)]</span> <span class="k">unless</span> <span class="nx">props</span><span class="p">.</span><span class="nx">length</span>
<span class="k">if</span> <span class="nx">@generated</span>
<span class="k">for</span> <span class="nx">node</span> <span class="k">in</span> <span class="nx">props</span> <span class="k">when</span> <span class="nx">node</span> <span class="k">instanceof</span> <span class="nx">Value</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">error</span> <span class="s">&#39;cannot have an implicit value in an implicit object&#39;</span>
<span class="nv">idt = </span><span class="nx">o</span><span class="p">.</span><span class="nx">indent</span> <span class="o">+=</span> <span class="nx">TAB</span>
<span class="nv">lastNoncom = </span><span class="nx">@lastNonComment</span> <span class="nx">@properties</span>
<span class="nv">answer = </span><span class="p">[]</span>
<span class="k">for</span> <span class="nx">prop</span><span class="p">,</span> <span class="nx">i</span> <span class="k">in</span> <span class="nx">props</span>
<span class="nv">join = </span><span class="k">if</span> <span class="nx">i</span> <span class="o">is</span> <span class="nx">props</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="mi">1</span>
<span class="s">&#39;&#39;</span>
<span class="k">else</span> <span class="k">if</span> <span class="nx">prop</span> <span class="o">is</span> <span class="nx">lastNoncom</span> <span class="o">or</span> <span class="nx">prop</span> <span class="k">instanceof</span> <span class="nx">Comment</span>
<span class="s">&#39;\n&#39;</span>
<span class="k">else</span>
<span class="s">&#39;,\n&#39;</span>
<span class="nv">indent = </span><span class="k">if</span> <span class="nx">prop</span> <span class="k">instanceof</span> <span class="nx">Comment</span> <span class="k">then</span> <span class="s">&#39;&#39;</span> <span class="k">else</span> <span class="nx">idt</span>
<span class="k">if</span> <span class="nx">prop</span> <span class="k">instanceof</span> <span class="nx">Assign</span> <span class="o">and</span> <span class="nx">prop</span><span class="p">.</span><span class="nx">variable</span> <span class="k">instanceof</span> <span class="nx">Value</span> <span class="o">and</span> <span class="nx">prop</span><span class="p">.</span><span class="nx">variable</span><span class="p">.</span><span class="nx">hasProperties</span><span class="p">()</span>
<span class="k">throw</span> <span class="k">new</span> <span class="nx">SyntaxError</span> <span class="s">&#39;Invalid object key&#39;</span>
<span class="k">if</span> <span class="nx">prop</span> <span class="k">instanceof</span> <span class="nx">Value</span> <span class="o">and</span> <span class="nx">prop</span><span class="p">.</span><span class="nx">this</span>
<span class="nv">prop = </span><span class="k">new</span> <span class="nx">Assign</span> <span class="nx">prop</span><span class="p">.</span><span class="nx">properties</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nx">name</span><span class="p">,</span> <span class="nx">prop</span><span class="p">,</span> <span class="s">&#39;object&#39;</span>
<span class="k">if</span> <span class="nx">prop</span> <span class="o">not</span> <span class="k">instanceof</span> <span class="nx">Comment</span>
<span class="k">if</span> <span class="nx">prop</span> <span class="o">not</span> <span class="k">instanceof</span> <span class="nx">Assign</span>
<span class="nv">prop = </span><span class="k">new</span> <span class="nx">Assign</span> <span class="nx">prop</span><span class="p">,</span> <span class="nx">prop</span><span class="p">,</span> <span class="s">&#39;object&#39;</span>
<span class="p">(</span><span class="nx">prop</span><span class="p">.</span><span class="nx">variable</span><span class="p">.</span><span class="nx">base</span> <span class="o">or</span> <span class="nx">prop</span><span class="p">.</span><span class="nx">variable</span><span class="p">).</span><span class="nv">asKey = </span><span class="kc">yes</span>
<span class="k">if</span> <span class="nx">indent</span> <span class="k">then</span> <span class="nx">answer</span><span class="p">.</span><span class="nx">push</span> <span class="nx">@makeCode</span> <span class="nx">indent</span>
<span class="nx">answer</span><span class="p">.</span><span class="nx">push</span> <span class="nx">prop</span><span class="p">.</span><span class="nx">compileToFragments</span><span class="p">(</span><span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_TOP</span><span class="p">)...</span>
<span class="k">if</span> <span class="nx">join</span> <span class="k">then</span> <span class="nx">answer</span><span class="p">.</span><span class="nx">push</span> <span class="nx">@makeCode</span> <span class="nx">join</span>
<span class="nx">answer</span><span class="p">.</span><span class="nx">unshift</span> <span class="nx">@makeCode</span> <span class="s">&quot;{</span><span class="si">#{</span> <span class="nx">props</span><span class="p">.</span><span class="nx">length</span> <span class="o">and</span> <span class="s">&#39;\n&#39;</span> <span class="si">}</span><span class="s">&quot;</span>
<span class="nx">answer</span><span class="p">.</span><span class="nx">push</span> <span class="nx">@makeCode</span> <span class="s">&quot;</span><span class="si">#{</span> <span class="nx">props</span><span class="p">.</span><span class="nx">length</span> <span class="o">and</span> <span class="s">&#39;\n&#39;</span> <span class="o">+</span> <span class="nx">@tab</span> <span class="si">}</span><span class="s">}&quot;</span>
<span class="k">if</span> <span class="nx">@front</span> <span class="k">then</span> <span class="nx">@wrapInBraces</span> <span class="nx">answer</span> <span class="k">else</span> <span class="nx">answer</span>
<span class="nv">assigns: </span><span class="nf">(name) -&gt;</span>
<span class="k">for</span> <span class="nx">prop</span> <span class="k">in</span> <span class="nx">@properties</span> <span class="k">when</span> <span class="nx">prop</span><span class="p">.</span><span class="nx">assigns</span> <span class="nx">name</span> <span class="k">then</span> <span class="k">return</span> <span class="kc">yes</span>
<span class="kc">no</span></pre></div></div>
</li>
<li id="section-68">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-68">&#182;</a>
</div>
<h3>Arr</h3>
<p>An array literal.
</p>
</div>
<div class="content"><div class="highlight"><pre><span class="nv">exports.Arr = </span><span class="k">class</span> <span class="nx">Arr</span> <span class="k">extends</span> <span class="nx">Base</span>
<span class="nv">constructor: </span><span class="nf">(objs) -&gt;</span>
<span class="vi">@objects = </span><span class="nx">objs</span> <span class="o">or</span> <span class="p">[]</span>
<span class="nv">children: </span><span class="p">[</span><span class="s">&#39;objects&#39;</span><span class="p">]</span>
<span class="nv">compileNode: </span><span class="nf">(o) -&gt;</span>
<span class="k">return</span> <span class="p">[</span><span class="nx">@makeCode</span> <span class="s">&#39;[]&#39;</span><span class="p">]</span> <span class="k">unless</span> <span class="nx">@objects</span><span class="p">.</span><span class="nx">length</span>
<span class="nx">o</span><span class="p">.</span><span class="nx">indent</span> <span class="o">+=</span> <span class="nx">TAB</span>
<span class="nv">answer = </span><span class="nx">Splat</span><span class="p">.</span><span class="nx">compileSplattedArray</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">@objects</span>
<span class="k">return</span> <span class="nx">answer</span> <span class="k">if</span> <span class="nx">answer</span><span class="p">.</span><span class="nx">length</span>
<span class="nv">answer = </span><span class="p">[]</span>
<span class="nv">compiledObjs = </span><span class="p">(</span><span class="nx">obj</span><span class="p">.</span><span class="nx">compileToFragments</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_LIST</span> <span class="k">for</span> <span class="nx">obj</span> <span class="k">in</span> <span class="nx">@objects</span><span class="p">)</span>
<span class="k">for</span> <span class="nx">fragments</span><span class="p">,</span> <span class="nx">index</span> <span class="k">in</span> <span class="nx">compiledObjs</span>
<span class="k">if</span> <span class="nx">index</span>
<span class="nx">answer</span><span class="p">.</span><span class="nx">push</span> <span class="nx">@makeCode</span> <span class="s">&quot;, &quot;</span>
<span class="nx">answer</span><span class="p">.</span><span class="nx">push</span> <span class="nx">fragments</span><span class="p">...</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">fragmentsToText</span> <span class="nx">answer</span><span class="p">).</span><span class="nx">indexOf</span><span class="p">(</span><span class="s">&#39;\n&#39;</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="mi">0</span>
<span class="nx">answer</span><span class="p">.</span><span class="nx">unshift</span> <span class="nx">@makeCode</span> <span class="s">&quot;[\n</span><span class="si">#{</span><span class="nx">o</span><span class="p">.</span><span class="nx">indent</span><span class="si">}</span><span class="s">&quot;</span>
<span class="nx">answer</span><span class="p">.</span><span class="nx">push</span> <span class="nx">@makeCode</span> <span class="s">&quot;\n</span><span class="si">#{</span><span class="nx">@tab</span><span class="si">}</span><span class="s">]&quot;</span>
<span class="k">else</span>
<span class="nx">answer</span><span class="p">.</span><span class="nx">unshift</span> <span class="nx">@makeCode</span> <span class="s">&quot;[&quot;</span>
<span class="nx">answer</span><span class="p">.</span><span class="nx">push</span> <span class="nx">@makeCode</span> <span class="s">&quot;]&quot;</span>
<span class="nx">answer</span>
<span class="nv">assigns: </span><span class="nf">(name) -&gt;</span>
<span class="k">for</span> <span class="nx">obj</span> <span class="k">in</span> <span class="nx">@objects</span> <span class="k">when</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">assigns</span> <span class="nx">name</span> <span class="k">then</span> <span class="k">return</span> <span class="kc">yes</span>
<span class="kc">no</span></pre></div></div>
</li>
<li id="section-69">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-69">&#182;</a>
</div>
<h3>Class</h3>
<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="nv">exports.Class = </span><span class="k">class</span> <span class="nx">Class</span> <span class="k">extends</span> <span class="nx">Base</span>
<span class="nv">constructor: </span><span class="nf">(@variable, @parent, @body = new Block) -&gt;</span>
<span class="vi">@boundFuncs = </span><span class="p">[]</span>
<span class="vi">@body.classBody = </span><span class="kc">yes</span>
<span class="nv">children: </span><span class="p">[</span><span class="s">&#39;variable&#39;</span><span class="p">,</span> <span class="s">&#39;parent&#39;</span><span class="p">,</span> <span class="s">&#39;body&#39;</span><span class="p">]</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>Figure out the appropriate name for the constructor function of this class.
</p>
</div>
<div class="content"><div class="highlight"><pre> <span class="nv">determineName: </span><span class="nf">-&gt;</span>
<span class="k">return</span> <span class="kc">null</span> <span class="k">unless</span> <span class="nx">@variable</span>
<span class="nv">decl = </span><span class="k">if</span> <span class="nv">tail = </span><span class="nx">last</span> <span class="nx">@variable</span><span class="p">.</span><span class="nx">properties</span>
<span class="nx">tail</span> <span class="k">instanceof</span> <span class="nx">Access</span> <span class="o">and</span> <span class="nx">tail</span><span class="p">.</span><span class="nx">name</span><span class="p">.</span><span class="nx">value</span>
<span class="k">else</span>
<span class="nx">@variable</span><span class="p">.</span><span class="nx">base</span><span class="p">.</span><span class="nx">value</span>
<span class="k">if</span> <span class="nx">decl</span> <span class="k">in</span> <span class="nx">STRICT_PROSCRIBED</span>
<span class="nx">@variable</span><span class="p">.</span><span class="nx">error</span> <span class="s">&quot;class variable name may not be </span><span class="si">#{</span><span class="nx">decl</span><span class="si">}</span><span class="s">&quot;</span>
<span class="nx">decl</span> <span class="o">and=</span> <span class="nx">IDENTIFIER</span><span class="p">.</span><span class="nx">test</span><span class="p">(</span><span class="nx">decl</span><span class="p">)</span> <span class="o">and</span> <span class="nx">decl</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>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="nv">setContext: </span><span class="nf">(name) -&gt;</span>
<span class="nx">@body</span><span class="p">.</span><span class="nx">traverseChildren</span> <span class="kc">false</span><span class="p">,</span> <span class="nf">(node) -&gt;</span>
<span class="k">return</span> <span class="kc">false</span> <span class="k">if</span> <span class="nx">node</span><span class="p">.</span><span class="nx">classBody</span>
<span class="k">if</span> <span class="nx">node</span> <span class="k">instanceof</span> <span class="nx">Literal</span> <span class="o">and</span> <span class="nx">node</span><span class="p">.</span><span class="nx">value</span> <span class="o">is</span> <span class="s">&#39;this&#39;</span>
<span class="nv">node.value = </span><span class="nx">name</span>
<span class="k">else</span> <span class="k">if</span> <span class="nx">node</span> <span class="k">instanceof</span> <span class="nx">Code</span>
<span class="nv">node.klass = </span><span class="nx">name</span>
<span class="nv">node.context = </span><span class="nx">name</span> <span class="k">if</span> <span class="nx">node</span><span class="p">.</span><span class="nx">bound</span></pre></div></div>
</li>
<li id="section-72">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-72">&#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="nv">addBoundFunctions: </span><span class="nf">(o) -&gt;</span>
<span class="k">for</span> <span class="nx">bvar</span> <span class="k">in</span> <span class="nx">@boundFuncs</span>
<span class="nv">lhs = </span><span class="p">(</span><span class="k">new</span> <span class="nx">Value</span> <span class="p">(</span><span class="k">new</span> <span class="nx">Literal</span> <span class="s">&quot;this&quot;</span><span class="p">),</span> <span class="p">[</span><span class="k">new</span> <span class="nx">Access</span> <span class="nx">bvar</span><span class="p">]).</span><span class="nx">compile</span> <span class="nx">o</span>
<span class="nx">@ctor</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">unshift</span> <span class="k">new</span> <span class="nx">Literal</span> <span class="s">&quot;</span><span class="si">#{</span><span class="nx">lhs</span><span class="si">}</span><span class="s"> = </span><span class="si">#{</span><span class="nx">utility</span> <span class="s">&#39;bind&#39;</span><span class="si">}</span><span class="s">(</span><span class="si">#{</span><span class="nx">lhs</span><span class="si">}</span><span class="s">, this)&quot;</span>
<span class="k">return</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>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="nv">addProperties: </span><span class="nf">(node, name, o) -&gt;</span>
<span class="nv">props = </span><span class="nx">node</span><span class="p">.</span><span class="nx">base</span><span class="p">.</span><span class="nx">properties</span><span class="p">[..]</span>
<span class="nv">exprs = </span><span class="k">while</span> <span class="nv">assign = </span><span class="nx">props</span><span class="p">.</span><span class="nx">shift</span><span class="p">()</span>
<span class="k">if</span> <span class="nx">assign</span> <span class="k">instanceof</span> <span class="nx">Assign</span>
<span class="nv">base = </span><span class="nx">assign</span><span class="p">.</span><span class="nx">variable</span><span class="p">.</span><span class="nx">base</span>
<span class="k">delete</span> <span class="nx">assign</span><span class="p">.</span><span class="nx">context</span>
<span class="nv">func = </span><span class="nx">assign</span><span class="p">.</span><span class="nx">value</span>
<span class="k">if</span> <span class="nx">base</span><span class="p">.</span><span class="nx">value</span> <span class="o">is</span> <span class="s">&#39;constructor&#39;</span>
<span class="k">if</span> <span class="nx">@ctor</span>
<span class="nx">assign</span><span class="p">.</span><span class="nx">error</span> <span class="s">&#39;cannot define more than one constructor in a class&#39;</span>
<span class="k">if</span> <span class="nx">func</span><span class="p">.</span><span class="nx">bound</span>
<span class="nx">assign</span><span class="p">.</span><span class="nx">error</span> <span class="s">&#39;cannot define a constructor as a bound function&#39;</span>
<span class="k">if</span> <span class="nx">func</span> <span class="k">instanceof</span> <span class="nx">Code</span>
<span class="nv">assign = </span><span class="vi">@ctor = </span><span class="nx">func</span>
<span class="k">else</span>
<span class="vi">@externalCtor = </span><span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span> <span class="s">&#39;class&#39;</span>
<span class="nv">assign = </span><span class="k">new</span> <span class="nx">Assign</span> <span class="k">new</span> <span class="nx">Literal</span><span class="p">(</span><span class="nx">@externalCtor</span><span class="p">),</span> <span class="nx">func</span>
<span class="k">else</span>
<span class="k">if</span> <span class="nx">assign</span><span class="p">.</span><span class="nx">variable</span><span class="p">.</span><span class="nx">this</span>
<span class="nv">func.static = </span><span class="kc">yes</span>
<span class="k">if</span> <span class="nx">func</span><span class="p">.</span><span class="nx">bound</span>
<span class="nv">func.context = </span><span class="nx">name</span>
<span class="k">else</span>
<span class="nv">assign.variable = </span><span class="k">new</span> <span class="nx">Value</span><span class="p">(</span><span class="k">new</span> <span class="nx">Literal</span><span class="p">(</span><span class="nx">name</span><span class="p">),</span> <span class="p">[(</span><span class="k">new</span> <span class="nx">Access</span> <span class="k">new</span> <span class="nx">Literal</span> <span class="s">&#39;prototype&#39;</span><span class="p">),</span> <span class="k">new</span> <span class="nx">Access</span> <span class="nx">base</span> <span class="p">])</span>
<span class="k">if</span> <span class="nx">func</span> <span class="k">instanceof</span> <span class="nx">Code</span> <span class="o">and</span> <span class="nx">func</span><span class="p">.</span><span class="nx">bound</span>
<span class="nx">@boundFuncs</span><span class="p">.</span><span class="nx">push</span> <span class="nx">base</span>
<span class="nv">func.bound = </span><span class="kc">no</span>
<span class="nx">assign</span>
<span class="nx">compact</span> <span class="nx">exprs</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>Walk the body of the class, looking for prototype properties to be converted.
</p>
</div>
<div class="content"><div class="highlight"><pre> <span class="nv">walkBody: </span><span class="nf">(name, o) -&gt;</span>
<span class="nx">@traverseChildren</span> <span class="kc">false</span><span class="p">,</span> <span class="nf">(child) =&gt;</span>
<span class="nv">cont = </span><span class="kc">true</span>
<span class="k">return</span> <span class="kc">false</span> <span class="k">if</span> <span class="nx">child</span> <span class="k">instanceof</span> <span class="nx">Class</span>
<span class="k">if</span> <span class="nx">child</span> <span class="k">instanceof</span> <span class="nx">Block</span>
<span class="k">for</span> <span class="nx">node</span><span class="p">,</span> <span class="nx">i</span> <span class="k">in</span> <span class="nv">exps = </span><span class="nx">child</span><span class="p">.</span><span class="nx">expressions</span>
<span class="k">if</span> <span class="nx">node</span> <span class="k">instanceof</span> <span class="nx">Value</span> <span class="o">and</span> <span class="nx">node</span><span class="p">.</span><span class="nx">isObject</span><span class="p">(</span><span class="kc">true</span><span class="p">)</span>
<span class="nv">cont = </span><span class="kc">false</span>
<span class="nx">exps</span><span class="p">[</span><span class="nx">i</span><span class="p">]</span> <span class="o">=</span> <span class="nx">@addProperties</span> <span class="nx">node</span><span class="p">,</span> <span class="nx">name</span><span class="p">,</span> <span class="nx">o</span>
<span class="nv">child.expressions = exps = </span><span class="nx">flatten</span> <span class="nx">exps</span>
<span class="nx">cont</span> <span class="o">and</span> <span class="nx">child</span> <span class="o">not</span> <span class="k">instanceof</span> <span class="nx">Class</span></pre></div></div>
</li>
<li id="section-75">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-75">&#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="nv">hoistDirectivePrologue: </span><span class="nf">-&gt;</span>
<span class="nv">index = </span><span class="mi">0</span>
<span class="p">{</span><span class="nx">expressions</span><span class="p">}</span> <span class="o">=</span> <span class="nx">@body</span>
<span class="o">++</span><span class="nx">index</span> <span class="k">while</span> <span class="p">(</span><span class="nv">node = </span><span class="nx">expressions</span><span class="p">[</span><span class="nx">index</span><span class="p">])</span> <span class="o">and</span> <span class="nx">node</span> <span class="k">instanceof</span> <span class="nx">Comment</span> <span class="o">or</span>
<span class="nx">node</span> <span class="k">instanceof</span> <span class="nx">Value</span> <span class="o">and</span> <span class="nx">node</span><span class="p">.</span><span class="nx">isString</span><span class="p">()</span>
<span class="vi">@directives = </span><span class="nx">expressions</span><span class="p">.</span><span class="nx">splice</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">index</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>Make sure that a constructor is defined for the class, and properly
configured.
</p>
</div>
<div class="content"><div class="highlight"><pre> <span class="nv">ensureConstructor: </span><span class="nf">(name, o) -&gt;</span>
<span class="nv">missing = </span><span class="o">not</span> <span class="nx">@ctor</span>
<span class="nx">@ctor</span> <span class="o">or=</span> <span class="k">new</span> <span class="nx">Code</span>
<span class="vi">@ctor.ctor = @ctor.name = </span><span class="nx">name</span>
<span class="vi">@ctor.klass = </span><span class="kc">null</span>
<span class="vi">@ctor.noReturn = </span><span class="kc">yes</span>
<span class="k">if</span> <span class="nx">missing</span>
<span class="nv">superCall = </span><span class="k">new</span> <span class="nx">Literal</span> <span class="s">&quot;</span><span class="si">#{</span><span class="nx">name</span><span class="si">}</span><span class="s">.__super__.constructor.apply(this, arguments)&quot;</span> <span class="k">if</span> <span class="nx">@parent</span>
<span class="nv">superCall = </span><span class="k">new</span> <span class="nx">Literal</span> <span class="s">&quot;</span><span class="si">#{</span><span class="nx">@externalCtor</span><span class="si">}</span><span class="s">.apply(this, arguments)&quot;</span> <span class="k">if</span> <span class="nx">@externalCtor</span>
<span class="k">if</span> <span class="nx">superCall</span>
<span class="nv">ref = </span><span class="k">new</span> <span class="nx">Literal</span> <span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span> <span class="s">&#39;ref&#39;</span>
<span class="nx">@ctor</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">unshift</span> <span class="k">new</span> <span class="nx">Assign</span> <span class="nx">ref</span><span class="p">,</span> <span class="nx">superCall</span>
<span class="nx">@addBoundFunctions</span> <span class="nx">o</span>
<span class="k">if</span> <span class="nx">superCall</span>
<span class="nx">@ctor</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">push</span> <span class="nx">ref</span>
<span class="nx">@ctor</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">makeReturn</span><span class="p">()</span>
<span class="nx">@body</span><span class="p">.</span><span class="nx">expressions</span><span class="p">.</span><span class="nx">unshift</span> <span class="nx">@ctor</span>
<span class="k">else</span>
<span class="nx">@addBoundFunctions</span> <span class="nx">o</span></pre></div></div>
</li>
<li id="section-77">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-77">&#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="nv">compileNode: </span><span class="nf">(o) -&gt;</span>
<span class="nv">decl = </span><span class="nx">@determineName</span><span class="p">()</span>
<span class="nv">name = </span><span class="nx">decl</span> <span class="o">or</span> <span class="s">&#39;_Class&#39;</span>
<span class="nv">name = </span><span class="s">&quot;_</span><span class="si">#{</span><span class="nx">name</span><span class="si">}</span><span class="s">&quot;</span> <span class="k">if</span> <span class="nx">name</span><span class="p">.</span><span class="nx">reserved</span>
<span class="nv">lname = </span><span class="k">new</span> <span class="nx">Literal</span> <span class="nx">name</span>
<span class="nx">@hoistDirectivePrologue</span><span class="p">()</span>
<span class="nx">@setContext</span> <span class="nx">name</span>
<span class="nx">@walkBody</span> <span class="nx">name</span><span class="p">,</span> <span class="nx">o</span>
<span class="nx">@ensureConstructor</span> <span class="nx">name</span><span class="p">,</span> <span class="nx">o</span>
<span class="vi">@body.spaced = </span><span class="kc">yes</span>
<span class="nx">@body</span><span class="p">.</span><span class="nx">expressions</span><span class="p">.</span><span class="nx">unshift</span> <span class="nx">@ctor</span> <span class="k">unless</span> <span class="nx">@ctor</span> <span class="k">instanceof</span> <span class="nx">Code</span>
<span class="nx">@body</span><span class="p">.</span><span class="nx">expressions</span><span class="p">.</span><span class="nx">push</span> <span class="nx">lname</span>
<span class="nx">@body</span><span class="p">.</span><span class="nx">expressions</span><span class="p">.</span><span class="nx">unshift</span> <span class="nx">@directives</span><span class="p">...</span>
<span class="nv">call = </span><span class="nx">Closure</span><span class="p">.</span><span class="nx">wrap</span> <span class="nx">@body</span>
<span class="k">if</span> <span class="nx">@parent</span>
<span class="vi">@superClass = </span><span class="k">new</span> <span class="nx">Literal</span> <span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span> <span class="s">&#39;super&#39;</span><span class="p">,</span> <span class="kc">no</span>
<span class="nx">@body</span><span class="p">.</span><span class="nx">expressions</span><span class="p">.</span><span class="nx">unshift</span> <span class="k">new</span> <span class="nx">Extends</span> <span class="nx">lname</span><span class="p">,</span> <span class="nx">@superClass</span>
<span class="nx">call</span><span class="p">.</span><span class="nx">args</span><span class="p">.</span><span class="nx">push</span> <span class="nx">@parent</span>
<span class="nv">params = </span><span class="nx">call</span><span class="p">.</span><span class="nx">variable</span><span class="p">.</span><span class="nx">params</span> <span class="o">or</span> <span class="nx">call</span><span class="p">.</span><span class="nx">variable</span><span class="p">.</span><span class="nx">base</span><span class="p">.</span><span class="nx">params</span>
<span class="nx">params</span><span class="p">.</span><span class="nx">push</span> <span class="k">new</span> <span class="nx">Param</span> <span class="nx">@superClass</span>
<span class="nv">klass = </span><span class="k">new</span> <span class="nx">Parens</span> <span class="nx">call</span><span class="p">,</span> <span class="kc">yes</span>
<span class="nv">klass = </span><span class="k">new</span> <span class="nx">Assign</span> <span class="nx">@variable</span><span class="p">,</span> <span class="nx">klass</span> <span class="k">if</span> <span class="nx">@variable</span>
<span class="nx">klass</span><span class="p">.</span><span class="nx">compileToFragments</span> <span class="nx">o</span></pre></div></div>
</li>
<li id="section-78">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-78">&#182;</a>
</div>
<h3>Assign</h3>
<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="nv">exports.Assign = </span><span class="k">class</span> <span class="nx">Assign</span> <span class="k">extends</span> <span class="nx">Base</span>
<span class="nv">constructor: </span><span class="nf">(@variable, @value, @context, options) -&gt;</span>
<span class="vi">@param = </span><span class="nx">options</span> <span class="o">and</span> <span class="nx">options</span><span class="p">.</span><span class="nx">param</span>
<span class="vi">@subpattern = </span><span class="nx">options</span> <span class="o">and</span> <span class="nx">options</span><span class="p">.</span><span class="nx">subpattern</span>
<span class="nv">forbidden = </span><span class="p">(</span><span class="nv">name = </span><span class="nx">@variable</span><span class="p">.</span><span class="nx">unwrapAll</span><span class="p">().</span><span class="nx">value</span><span class="p">)</span> <span class="k">in</span> <span class="nx">STRICT_PROSCRIBED</span>
<span class="k">if</span> <span class="nx">forbidden</span> <span class="o">and</span> <span class="nx">@context</span> <span class="o">isnt</span> <span class="s">&#39;object&#39;</span>
<span class="nx">@variable</span><span class="p">.</span><span class="nx">error</span> <span class="s">&quot;variable name may not be \&quot;</span><span class="si">#{</span><span class="nx">name</span><span class="si">}</span><span class="s">\&quot;&quot;</span>
<span class="nv">children: </span><span class="p">[</span><span class="s">&#39;variable&#39;</span><span class="p">,</span> <span class="s">&#39;value&#39;</span><span class="p">]</span>
<span class="nv">isStatement: </span><span class="nf">(o) -&gt;</span>
<span class="nx">o</span><span class="o">?</span><span class="p">.</span><span class="nx">level</span> <span class="o">is</span> <span class="nx">LEVEL_TOP</span> <span class="o">and</span> <span class="nx">@context</span><span class="o">?</span> <span class="o">and</span> <span class="s">&quot;?&quot;</span> <span class="k">in</span> <span class="nx">@context</span>
<span class="nv">assigns: </span><span class="nf">(name) -&gt;</span>
<span class="nx">@</span><span class="p">[</span><span class="k">if</span> <span class="nx">@context</span> <span class="o">is</span> <span class="s">&#39;object&#39;</span> <span class="k">then</span> <span class="s">&#39;value&#39;</span> <span class="k">else</span> <span class="s">&#39;variable&#39;</span><span class="p">].</span><span class="nx">assigns</span> <span class="nx">name</span>
<span class="nv">unfoldSoak: </span><span class="nf">(o) -&gt;</span>
<span class="nx">unfoldSoak</span> <span class="nx">o</span><span class="p">,</span> <span class="k">this</span><span class="p">,</span> <span class="s">&#39;variable&#39;</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>Compile an assignment, delegating to <code>compilePatternMatch</code> or
<code>compileSplice</code> if appropriate. Keep track of the name of the base object
we&#39;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="nv">compileNode: </span><span class="nf">(o) -&gt;</span>
<span class="k">if</span> <span class="nv">isValue = </span><span class="nx">@variable</span> <span class="k">instanceof</span> <span class="nx">Value</span>
<span class="k">return</span> <span class="nx">@compilePatternMatch</span> <span class="nx">o</span> <span class="k">if</span> <span class="nx">@variable</span><span class="p">.</span><span class="nx">isArray</span><span class="p">()</span> <span class="o">or</span> <span class="nx">@variable</span><span class="p">.</span><span class="nx">isObject</span><span class="p">()</span>
<span class="k">return</span> <span class="nx">@compileSplice</span> <span class="nx">o</span> <span class="k">if</span> <span class="nx">@variable</span><span class="p">.</span><span class="nx">isSplice</span><span class="p">()</span>
<span class="k">return</span> <span class="nx">@compileConditional</span> <span class="nx">o</span> <span class="k">if</span> <span class="nx">@context</span> <span class="k">in</span> <span class="p">[</span><span class="s">&#39;||=&#39;</span><span class="p">,</span> <span class="s">&#39;&amp;&amp;=&#39;</span><span class="p">,</span> <span class="s">&#39;?=&#39;</span><span class="p">]</span>
<span class="nv">compiledName = </span><span class="nx">@variable</span><span class="p">.</span><span class="nx">compileToFragments</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_LIST</span>
<span class="nv">name = </span><span class="nx">fragmentsToText</span> <span class="nx">compiledName</span>
<span class="k">unless</span> <span class="nx">@context</span>
<span class="nv">varBase = </span><span class="nx">@variable</span><span class="p">.</span><span class="nx">unwrapAll</span><span class="p">()</span>
<span class="k">unless</span> <span class="nx">varBase</span><span class="p">.</span><span class="nx">isAssignable</span><span class="p">()</span>
<span class="nx">@variable</span><span class="p">.</span><span class="nx">error</span> <span class="s">&quot;\&quot;</span><span class="si">#{</span><span class="nx">@variable</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">o</span><span class="si">}</span><span class="s">\&quot; cannot be assigned&quot;</span>
<span class="k">unless</span> <span class="nx">varBase</span><span class="p">.</span><span class="nx">hasProperties</span><span class="o">?</span><span class="p">()</span>
<span class="k">if</span> <span class="nx">@param</span>
<span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">add</span> <span class="nx">name</span><span class="p">,</span> <span class="s">&#39;var&#39;</span>
<span class="k">else</span>
<span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">find</span> <span class="nx">name</span>
<span class="k">if</span> <span class="nx">@value</span> <span class="k">instanceof</span> <span class="nx">Code</span> <span class="o">and</span> <span class="nv">match = </span><span class="nx">METHOD_DEF</span><span class="p">.</span><span class="nx">exec</span> <span class="nx">name</span>
<span class="vi">@value.klass = </span><span class="nx">match</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="k">if</span> <span class="nx">match</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
<span class="vi">@value.name = </span><span class="nx">match</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="o">?</span> <span class="nx">match</span><span class="p">[</span><span class="mi">3</span><span class="p">]</span> <span class="o">?</span> <span class="nx">match</span><span class="p">[</span><span class="mi">4</span><span class="p">]</span> <span class="o">?</span> <span class="nx">match</span><span class="p">[</span><span class="mi">5</span><span class="p">]</span>
<span class="nv">val = </span><span class="nx">@value</span><span class="p">.</span><span class="nx">compileToFragments</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_LIST</span>
<span class="k">return</span> <span class="p">(</span><span class="nx">compiledName</span><span class="p">.</span><span class="nx">concat</span> <span class="nx">@makeCode</span><span class="p">(</span><span class="s">&quot;: &quot;</span><span class="p">),</span> <span class="nx">val</span><span class="p">)</span> <span class="k">if</span> <span class="nx">@context</span> <span class="o">is</span> <span class="s">&#39;object&#39;</span>
<span class="nv">answer = </span><span class="nx">compiledName</span><span class="p">.</span><span class="nx">concat</span> <span class="nx">@makeCode</span><span class="p">(</span><span class="s">&quot; </span><span class="si">#{</span> <span class="nx">@context</span> <span class="o">or</span> <span class="s">&#39;=&#39;</span> <span class="si">}</span><span class="s"> &quot;</span><span class="p">),</span> <span class="nx">val</span>
<span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">level</span> <span class="o">&lt;=</span> <span class="nx">LEVEL_LIST</span> <span class="k">then</span> <span class="nx">answer</span> <span class="k">else</span> <span class="nx">@wrapInBraces</span> <span class="nx">answer</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>Brief implementation of recursive pattern matching, when assigning array or
object literals to a value. Peeks at their properties to assign inner names.
See the <a href="http://wiki.ecmascript.org/doku.php?id=harmony:destructuring">ECMAScript Harmony Wiki</a>
for details.
</p>
</div>
<div class="content"><div class="highlight"><pre> <span class="nv">compilePatternMatch: </span><span class="nf">(o) -&gt;</span>
<span class="nv">top = </span><span class="nx">o</span><span class="p">.</span><span class="nx">level</span> <span class="o">is</span> <span class="nx">LEVEL_TOP</span>
<span class="p">{</span><span class="nx">value</span><span class="p">}</span> <span class="o">=</span> <span class="k">this</span>
<span class="p">{</span><span class="nx">objects</span><span class="p">}</span> <span class="o">=</span> <span class="nx">@variable</span><span class="p">.</span><span class="nx">base</span>
<span class="k">unless</span> <span class="nv">olen = </span><span class="nx">objects</span><span class="p">.</span><span class="nx">length</span>
<span class="nv">code = </span><span class="nx">value</span><span class="p">.</span><span class="nx">compileToFragments</span> <span class="nx">o</span>
<span class="k">return</span> <span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">level</span> <span class="o">&gt;=</span> <span class="nx">LEVEL_OP</span> <span class="k">then</span> <span class="nx">@wrapInBraces</span> <span class="nx">code</span> <span class="k">else</span> <span class="nx">code</span>
<span class="nv">isObject = </span><span class="nx">@variable</span><span class="p">.</span><span class="nx">isObject</span><span class="p">()</span>
<span class="k">if</span> <span class="nx">top</span> <span class="o">and</span> <span class="nx">olen</span> <span class="o">is</span> <span class="mi">1</span> <span class="o">and</span> <span class="p">(</span><span class="nv">obj = </span><span class="nx">objects</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span> <span class="o">not</span> <span class="k">instanceof</span> <span class="nx">Splat</span></pre></div></div>
</li>
<li id="section-81">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-81">&#182;</a>
</div>
<p>Unroll simplest cases: <code>{v} = x</code> -&gt; <code>v = x.v</code>
</p>
</div>
<div class="content"><div class="highlight"><pre> <span class="k">if</span> <span class="nx">obj</span> <span class="k">instanceof</span> <span class="nx">Assign</span>
<span class="p">{</span><span class="nv">variable: </span><span class="p">{</span><span class="nv">base: </span><span class="nx">idx</span><span class="p">},</span> <span class="nv">value: </span><span class="nx">obj</span><span class="p">}</span> <span class="o">=</span> <span class="nx">obj</span>
<span class="k">else</span>
<span class="nv">idx = </span><span class="k">if</span> <span class="nx">isObject</span>
<span class="k">if</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">this</span> <span class="k">then</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">properties</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nx">name</span> <span class="k">else</span> <span class="nx">obj</span>
<span class="k">else</span>
<span class="k">new</span> <span class="nx">Literal</span> <span class="mi">0</span>
<span class="nv">acc = </span><span class="nx">IDENTIFIER</span><span class="p">.</span><span class="nx">test</span> <span class="nx">idx</span><span class="p">.</span><span class="nx">unwrap</span><span class="p">().</span><span class="nx">value</span> <span class="o">or</span> <span class="mi">0</span>
<span class="nv">value = </span><span class="k">new</span> <span class="nx">Value</span> <span class="nx">value</span>
<span class="nx">value</span><span class="p">.</span><span class="nx">properties</span><span class="p">.</span><span class="nx">push</span> <span class="k">new</span> <span class="p">(</span><span class="k">if</span> <span class="nx">acc</span> <span class="k">then</span> <span class="nx">Access</span> <span class="k">else</span> <span class="nx">Index</span><span class="p">)</span> <span class="nx">idx</span>
<span class="k">if</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">unwrap</span><span class="p">().</span><span class="nx">value</span> <span class="k">in</span> <span class="nx">RESERVED</span>
<span class="nx">obj</span><span class="p">.</span><span class="nx">error</span> <span class="s">&quot;assignment to a reserved word: </span><span class="si">#{</span><span class="nx">obj</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">o</span><span class="si">}</span><span class="s">&quot;</span>
<span class="k">return</span> <span class="k">new</span> <span class="nx">Assign</span><span class="p">(</span><span class="nx">obj</span><span class="p">,</span> <span class="nx">value</span><span class="p">,</span> <span class="kc">null</span><span class="p">,</span> <span class="nv">param: </span><span class="nx">@param</span><span class="p">).</span><span class="nx">compileToFragments</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_TOP</span>
<span class="nv">vvar = </span><span class="nx">value</span><span class="p">.</span><span class="nx">compileToFragments</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_LIST</span>
<span class="nv">vvarText = </span><span class="nx">fragmentsToText</span> <span class="nx">vvar</span>
<span class="nv">assigns = </span><span class="p">[]</span>
<span class="nv">splat = </span><span class="kc">false</span></pre></div></div>
</li>
<li id="section-82">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-82">&#182;</a>
</div>
<p>Make vvar into a simple variable if it isn&#39;t already.
</p>
</div>
<div class="content"><div class="highlight"><pre> <span class="k">if</span> <span class="o">not</span> <span class="nx">IDENTIFIER</span><span class="p">.</span><span class="nx">test</span><span class="p">(</span><span class="nx">vvarText</span><span class="p">)</span> <span class="o">or</span> <span class="nx">@variable</span><span class="p">.</span><span class="nx">assigns</span><span class="p">(</span><span class="nx">vvarText</span><span class="p">)</span>
<span class="nx">assigns</span><span class="p">.</span><span class="nx">push</span> <span class="p">[</span><span class="nx">@makeCode</span><span class="p">(</span><span class="s">&quot;</span><span class="si">#{</span> <span class="nv">ref = </span><span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span> <span class="s">&#39;ref&#39;</span> <span class="si">}</span><span class="s"> = &quot;</span><span class="p">),</span> <span class="nx">vvar</span><span class="p">...]</span>
<span class="nv">vvar = </span><span class="p">[</span><span class="nx">@makeCode</span> <span class="nx">ref</span><span class="p">]</span>
<span class="nv">vvarText = </span><span class="nx">ref</span>
<span class="k">for</span> <span class="nx">obj</span><span class="p">,</span> <span class="nx">i</span> <span class="k">in</span> <span class="nx">objects</span></pre></div></div>
</li>
<li id="section-83">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-83">&#182;</a>
</div>
<p>A regular array pattern-match.
</p>
</div>
<div class="content"><div class="highlight"><pre> <span class="nv">idx = </span><span class="nx">i</span>
<span class="k">if</span> <span class="nx">isObject</span>
<span class="k">if</span> <span class="nx">obj</span> <span class="k">instanceof</span> <span class="nx">Assign</span></pre></div></div>
</li>
<li id="section-84">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-84">&#182;</a>
</div>
<p>A regular object pattern-match.
</p>
</div>
<div class="content"><div class="highlight"><pre> <span class="p">{</span><span class="nv">variable: </span><span class="p">{</span><span class="nv">base: </span><span class="nx">idx</span><span class="p">},</span> <span class="nv">value: </span><span class="nx">obj</span><span class="p">}</span> <span class="o">=</span> <span class="nx">obj</span>
<span class="k">else</span></pre></div></div>
</li>
<li id="section-85">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-85">&#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="k">if</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">base</span> <span class="k">instanceof</span> <span class="nx">Parens</span>
<span class="p">[</span><span class="nx">obj</span><span class="p">,</span> <span class="nx">idx</span><span class="p">]</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Value</span><span class="p">(</span><span class="nx">obj</span><span class="p">.</span><span class="nx">unwrapAll</span><span class="p">()).</span><span class="nx">cacheReference</span> <span class="nx">o</span>
<span class="k">else</span>
<span class="nv">idx = </span><span class="k">if</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">this</span> <span class="k">then</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">properties</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nx">name</span> <span class="k">else</span> <span class="nx">obj</span>
<span class="k">if</span> <span class="o">not</span> <span class="nx">splat</span> <span class="o">and</span> <span class="nx">obj</span> <span class="k">instanceof</span> <span class="nx">Splat</span>
<span class="nv">name = </span><span class="nx">obj</span><span class="p">.</span><span class="nx">name</span><span class="p">.</span><span class="nx">unwrap</span><span class="p">().</span><span class="nx">value</span>
<span class="nv">obj = </span><span class="nx">obj</span><span class="p">.</span><span class="nx">unwrap</span><span class="p">()</span>
<span class="nv">val = </span><span class="s">&quot;</span><span class="si">#{</span><span class="nx">olen</span><span class="si">}</span><span class="s"> &lt;= </span><span class="si">#{</span><span class="nx">vvarText</span><span class="si">}</span><span class="s">.length ? </span><span class="si">#{</span> <span class="nx">utility</span> <span class="s">&#39;slice&#39;</span> <span class="si">}</span><span class="s">.call(</span><span class="si">#{</span><span class="nx">vvarText</span><span class="si">}</span><span class="s">, </span><span class="si">#{</span><span class="nx">i</span><span class="si">}</span><span class="s">&quot;</span>
<span class="k">if</span> <span class="nv">rest = </span><span class="nx">olen</span> <span class="o">-</span> <span class="nx">i</span> <span class="o">-</span> <span class="mi">1</span>
<span class="nv">ivar = </span><span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span> <span class="s">&#39;i&#39;</span>
<span class="nx">val</span> <span class="o">+=</span> <span class="s">&quot;, </span><span class="si">#{</span><span class="nx">ivar</span><span class="si">}</span><span class="s"> = </span><span class="si">#{</span><span class="nx">vvarText</span><span class="si">}</span><span class="s">.length - </span><span class="si">#{</span><span class="nx">rest</span><span class="si">}</span><span class="s">) : (</span><span class="si">#{</span><span class="nx">ivar</span><span class="si">}</span><span class="s"> = </span><span class="si">#{</span><span class="nx">i</span><span class="si">}</span><span class="s">, [])&quot;</span>
<span class="k">else</span>
<span class="nx">val</span> <span class="o">+=</span> <span class="s">&quot;) : []&quot;</span>
<span class="nv">val = </span><span class="k">new</span> <span class="nx">Literal</span> <span class="nx">val</span>
<span class="nv">splat = </span><span class="s">&quot;</span><span class="si">#{</span><span class="nx">ivar</span><span class="si">}</span><span class="s">++&quot;</span>
<span class="k">else</span>
<span class="nv">name = </span><span class="nx">obj</span><span class="p">.</span><span class="nx">unwrap</span><span class="p">().</span><span class="nx">value</span>
<span class="k">if</span> <span class="nx">obj</span> <span class="k">instanceof</span> <span class="nx">Splat</span>
<span class="nx">obj</span><span class="p">.</span><span class="nx">error</span> <span class="s">&quot;multiple splats are disallowed in an assignment&quot;</span>
<span class="k">if</span> <span class="k">typeof</span> <span class="nx">idx</span> <span class="o">is</span> <span class="s">&#39;number&#39;</span>
<span class="nv">idx = </span><span class="k">new</span> <span class="nx">Literal</span> <span class="nx">splat</span> <span class="o">or</span> <span class="nx">idx</span>
<span class="nv">acc = </span><span class="kc">no</span>
<span class="k">else</span>
<span class="nv">acc = </span><span class="nx">isObject</span> <span class="o">and</span> <span class="nx">IDENTIFIER</span><span class="p">.</span><span class="nx">test</span> <span class="nx">idx</span><span class="p">.</span><span class="nx">unwrap</span><span class="p">().</span><span class="nx">value</span> <span class="o">or</span> <span class="mi">0</span>
<span class="nv">val = </span><span class="k">new</span> <span class="nx">Value</span> <span class="k">new</span> <span class="nx">Literal</span><span class="p">(</span><span class="nx">vvarText</span><span class="p">),</span> <span class="p">[</span><span class="k">new</span> <span class="p">(</span><span class="k">if</span> <span class="nx">acc</span> <span class="k">then</span> <span class="nx">Access</span> <span class="k">else</span> <span class="nx">Index</span><span class="p">)</span> <span class="nx">idx</span><span class="p">]</span>
<span class="k">if</span> <span class="nx">name</span><span class="o">?</span> <span class="o">and</span> <span class="nx">name</span> <span class="k">in</span> <span class="nx">RESERVED</span>
<span class="nx">obj</span><span class="p">.</span><span class="nx">error</span> <span class="s">&quot;assignment to a reserved word: </span><span class="si">#{</span><span class="nx">obj</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">o</span><span class="si">}</span><span class="s">&quot;</span>
<span class="nx">assigns</span><span class="p">.</span><span class="nx">push</span> <span class="k">new</span> <span class="nx">Assign</span><span class="p">(</span><span class="nx">obj</span><span class="p">,</span> <span class="nx">val</span><span class="p">,</span> <span class="kc">null</span><span class="p">,</span> <span class="nv">param: </span><span class="nx">@param</span><span class="p">,</span> <span class="nv">subpattern: </span><span class="kc">yes</span><span class="p">).</span><span class="nx">compileToFragments</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_LIST</span>
<span class="nx">assigns</span><span class="p">.</span><span class="nx">push</span> <span class="nx">vvar</span> <span class="k">unless</span> <span class="nx">top</span> <span class="o">or</span> <span class="nx">@subpattern</span>
<span class="nv">fragments = </span><span class="nx">@joinFragmentArrays</span> <span class="nx">assigns</span><span class="p">,</span> <span class="s">&#39;, &#39;</span>
<span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">level</span> <span class="o">&lt;</span> <span class="nx">LEVEL_LIST</span> <span class="k">then</span> <span class="nx">fragments</span> <span class="k">else</span> <span class="nx">@wrapInBraces</span> <span class="nx">fragments</span></pre></div></div>
</li>
<li id="section-86">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-86">&#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="nv">compileConditional: </span><span class="nf">(o) -&gt;</span>
<span class="p">[</span><span class="nx">left</span><span class="p">,</span> <span class="nx">right</span><span class="p">]</span> <span class="o">=</span> <span class="nx">@variable</span><span class="p">.</span><span class="nx">cacheReference</span> <span class="nx">o</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>Disallow conditional assignment of undefined variables.
</p>
</div>
<div class="content"><div class="highlight"><pre> <span class="k">if</span> <span class="o">not</span> <span class="nx">left</span><span class="p">.</span><span class="nx">properties</span><span class="p">.</span><span class="nx">length</span> <span class="o">and</span> <span class="nx">left</span><span class="p">.</span><span class="nx">base</span> <span class="k">instanceof</span> <span class="nx">Literal</span> <span class="o">and</span>
<span class="nx">left</span><span class="p">.</span><span class="nx">base</span><span class="p">.</span><span class="nx">value</span> <span class="o">!=</span> <span class="s">&quot;this&quot;</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">check</span> <span class="nx">left</span><span class="p">.</span><span class="nx">base</span><span class="p">.</span><span class="nx">value</span>
<span class="nx">@variable</span><span class="p">.</span><span class="nx">error</span> <span class="s">&quot;the variable \&quot;</span><span class="si">#{</span><span class="nx">left</span><span class="p">.</span><span class="nx">base</span><span class="p">.</span><span class="nx">value</span><span class="si">}</span><span class="s">\&quot; can&#39;t be assigned with </span><span class="si">#{</span><span class="nx">@context</span><span class="si">}</span><span class="s"> because it has not been declared before&quot;</span>
<span class="k">if</span> <span class="s">&quot;?&quot;</span> <span class="k">in</span> <span class="nx">@context</span> <span class="k">then</span> <span class="nv">o.isExistentialEquals = </span><span class="kc">true</span>
<span class="k">new</span> <span class="nx">Op</span><span class="p">(</span><span class="nx">@context</span><span class="p">[...</span><span class="o">-</span><span class="mi">1</span><span class="p">],</span> <span class="nx">left</span><span class="p">,</span> <span class="k">new</span> <span class="nx">Assign</span><span class="p">(</span><span class="nx">right</span><span class="p">,</span> <span class="nx">@value</span><span class="p">,</span> <span class="s">&#39;=&#39;</span><span class="p">)</span> <span class="p">).</span><span class="nx">compileToFragments</span> <span class="nx">o</span></pre></div></div>
</li>
<li id="section-88">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-88">&#182;</a>
</div>
<p>Compile the assignment from an array splice literal, using JavaScript&#39;s
<code>Array#splice</code> method.
</p>
</div>
<div class="content"><div class="highlight"><pre> <span class="nv">compileSplice: </span><span class="nf">(o) -&gt;</span>
<span class="p">{</span><span class="nv">range: </span><span class="p">{</span><span class="nx">from</span><span class="p">,</span> <span class="nx">to</span><span class="p">,</span> <span class="nx">exclusive</span><span class="p">}}</span> <span class="o">=</span> <span class="nx">@variable</span><span class="p">.</span><span class="nx">properties</span><span class="p">.</span><span class="nx">pop</span><span class="p">()</span>
<span class="nv">name = </span><span class="nx">@variable</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">o</span>
<span class="k">if</span> <span class="nx">from</span>
<span class="p">[</span><span class="nx">fromDecl</span><span class="p">,</span> <span class="nx">fromRef</span><span class="p">]</span> <span class="o">=</span> <span class="nx">@cacheToCodeFragments</span> <span class="nx">from</span><span class="p">.</span><span class="nx">cache</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_OP</span>
<span class="k">else</span>
<span class="nv">fromDecl = fromRef = </span><span class="s">&#39;0&#39;</span>
<span class="k">if</span> <span class="nx">to</span>
<span class="k">if</span> <span class="nx">from</span><span class="o">?</span><span class="p">.</span><span class="nx">isSimpleNumber</span><span class="p">()</span> <span class="o">and</span> <span class="nx">to</span><span class="p">.</span><span class="nx">isSimpleNumber</span><span class="p">()</span>
<span class="nv">to = </span><span class="o">+</span><span class="nx">to</span><span class="p">.</span><span class="nx">compile</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-</span> <span class="o">+</span><span class="nx">fromRef</span>
<span class="nx">to</span> <span class="o">+=</span> <span class="mi">1</span> <span class="k">unless</span> <span class="nx">exclusive</span>
<span class="k">else</span>
<span class="nv">to = </span><span class="nx">to</span><span class="p">.</span><span class="nx">compile</span><span class="p">(</span><span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_ACCESS</span><span class="p">)</span> <span class="o">+</span> <span class="s">&#39; - &#39;</span> <span class="o">+</span> <span class="nx">fromRef</span>
<span class="nx">to</span> <span class="o">+=</span> <span class="s">&#39; + 1&#39;</span> <span class="k">unless</span> <span class="nx">exclusive</span>
<span class="k">else</span>
<span class="nv">to = </span><span class="s">&quot;9e9&quot;</span>
<span class="p">[</span><span class="nx">valDef</span><span class="p">,</span> <span class="nx">valRef</span><span class="p">]</span> <span class="o">=</span> <span class="nx">@value</span><span class="p">.</span><span class="nx">cache</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_LIST</span>
<span class="nv">answer = </span><span class="p">[].</span><span class="nx">concat</span> <span class="nx">@makeCode</span><span class="p">(</span><span class="s">&quot;[].splice.apply(</span><span class="si">#{</span><span class="nx">name</span><span class="si">}</span><span class="s">, [</span><span class="si">#{</span><span class="nx">fromDecl</span><span class="si">}</span><span class="s">, </span><span class="si">#{</span><span class="nx">to</span><span class="si">}</span><span class="s">].concat(&quot;</span><span class="p">),</span> <span class="nx">valDef</span><span class="p">,</span> <span class="nx">@makeCode</span><span class="p">(</span><span class="s">&quot;)), &quot;</span><span class="p">),</span> <span class="nx">valRef</span>
<span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">level</span> <span class="o">&gt;</span> <span class="nx">LEVEL_TOP</span> <span class="k">then</span> <span class="nx">@wrapInBraces</span> <span class="nx">answer</span> <span class="k">else</span> <span class="nx">answer</span></pre></div></div>
</li>
<li id="section-89">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-89">&#182;</a>
</div>
<h3>Code</h3>
<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&#39;re within the inner scope.
</p>
</div>
<div class="content"><div class="highlight"><pre><span class="nv">exports.Code = </span><span class="k">class</span> <span class="nx">Code</span> <span class="k">extends</span> <span class="nx">Base</span>
<span class="nv">constructor: </span><span class="nf">(params, body, tag) -&gt;</span>
<span class="vi">@params = </span><span class="nx">params</span> <span class="o">or</span> <span class="p">[]</span>
<span class="vi">@body = </span><span class="nx">body</span> <span class="o">or</span> <span class="k">new</span> <span class="nx">Block</span>
<span class="vi">@bound = </span><span class="nx">tag</span> <span class="o">is</span> <span class="s">&#39;boundfunc&#39;</span>
<span class="vi">@context = </span><span class="s">&#39;_this&#39;</span> <span class="k">if</span> <span class="nx">@bound</span>
<span class="nv">children: </span><span class="p">[</span><span class="s">&#39;params&#39;</span><span class="p">,</span> <span class="s">&#39;body&#39;</span><span class="p">]</span>
<span class="nv">isStatement: </span><span class="nf">-&gt;</span> <span class="o">!!</span><span class="nx">@ctor</span>
<span class="nv">jumps: </span><span class="nx">NO</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>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="nv">compileNode: </span><span class="nf">(o) -&gt;</span>
<span class="nv">o.scope = </span><span class="k">new</span> <span class="nx">Scope</span> <span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">,</span> <span class="nx">@body</span><span class="p">,</span> <span class="k">this</span>
<span class="nv">o.scope.shared = </span><span class="nx">del</span><span class="p">(</span><span class="nx">o</span><span class="p">,</span> <span class="s">&#39;sharedScope&#39;</span><span class="p">)</span>
<span class="nx">o</span><span class="p">.</span><span class="nx">indent</span> <span class="o">+=</span> <span class="nx">TAB</span>
<span class="k">delete</span> <span class="nx">o</span><span class="p">.</span><span class="nx">bare</span>
<span class="k">delete</span> <span class="nx">o</span><span class="p">.</span><span class="nx">isExistentialEquals</span>
<span class="nv">params = </span><span class="p">[]</span>
<span class="nv">exprs = </span><span class="p">[]</span>
<span class="nx">@eachParamName</span> <span class="nf">(name) -&gt;</span> <span class="c1"># this step must be performed before the others</span>
<span class="k">unless</span> <span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">check</span> <span class="nx">name</span> <span class="k">then</span> <span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">parameter</span> <span class="nx">name</span>
<span class="k">for</span> <span class="nx">param</span> <span class="k">in</span> <span class="nx">@params</span> <span class="k">when</span> <span class="nx">param</span><span class="p">.</span><span class="nx">splat</span>
<span class="k">for</span> <span class="p">{</span><span class="nv">name: </span><span class="nx">p</span><span class="p">}</span> <span class="k">in</span> <span class="nx">@params</span>
<span class="k">if</span> <span class="nx">p</span><span class="p">.</span><span class="nx">this</span> <span class="k">then</span> <span class="nv">p = </span><span class="nx">p</span><span class="p">.</span><span class="nx">properties</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nx">name</span>
<span class="k">if</span> <span class="nx">p</span><span class="p">.</span><span class="nx">value</span> <span class="k">then</span> <span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">add</span> <span class="nx">p</span><span class="p">.</span><span class="nx">value</span><span class="p">,</span> <span class="s">&#39;var&#39;</span><span class="p">,</span> <span class="kc">yes</span>
<span class="nv">splats = </span><span class="k">new</span> <span class="nx">Assign</span> <span class="k">new</span> <span class="nx">Value</span><span class="p">(</span><span class="k">new</span> <span class="nx">Arr</span><span class="p">(</span><span class="nx">p</span><span class="p">.</span><span class="nx">asReference</span> <span class="nx">o</span> <span class="k">for</span> <span class="nx">p</span> <span class="k">in</span> <span class="nx">@params</span><span class="p">)),</span>
<span class="k">new</span> <span class="nx">Value</span> <span class="k">new</span> <span class="nx">Literal</span> <span class="s">&#39;arguments&#39;</span>
<span class="k">break</span>
<span class="k">for</span> <span class="nx">param</span> <span class="k">in</span> <span class="nx">@params</span>
<span class="k">if</span> <span class="nx">param</span><span class="p">.</span><span class="nx">isComplex</span><span class="p">()</span>
<span class="nv">val = ref = </span><span class="nx">param</span><span class="p">.</span><span class="nx">asReference</span> <span class="nx">o</span>
<span class="nv">val = </span><span class="k">new</span> <span class="nx">Op</span> <span class="s">&#39;?&#39;</span><span class="p">,</span> <span class="nx">ref</span><span class="p">,</span> <span class="nx">param</span><span class="p">.</span><span class="nx">value</span> <span class="k">if</span> <span class="nx">param</span><span class="p">.</span><span class="nx">value</span>
<span class="nx">exprs</span><span class="p">.</span><span class="nx">push</span> <span class="k">new</span> <span class="nx">Assign</span> <span class="k">new</span> <span class="nx">Value</span><span class="p">(</span><span class="nx">param</span><span class="p">.</span><span class="nx">name</span><span class="p">),</span> <span class="nx">val</span><span class="p">,</span> <span class="s">&#39;=&#39;</span><span class="p">,</span> <span class="nv">param: </span><span class="kc">yes</span>
<span class="k">else</span>
<span class="nv">ref = </span><span class="nx">param</span>
<span class="k">if</span> <span class="nx">param</span><span class="p">.</span><span class="nx">value</span>
<span class="nv">lit = </span><span class="k">new</span> <span class="nx">Literal</span> <span class="nx">ref</span><span class="p">.</span><span class="nx">name</span><span class="p">.</span><span class="nx">value</span> <span class="o">+</span> <span class="s">&#39; == null&#39;</span>
<span class="nv">val = </span><span class="k">new</span> <span class="nx">Assign</span> <span class="k">new</span> <span class="nx">Value</span><span class="p">(</span><span class="nx">param</span><span class="p">.</span><span class="nx">name</span><span class="p">),</span> <span class="nx">param</span><span class="p">.</span><span class="nx">value</span><span class="p">,</span> <span class="s">&#39;=&#39;</span>
<span class="nx">exprs</span><span class="p">.</span><span class="nx">push</span> <span class="k">new</span> <span class="nx">If</span> <span class="nx">lit</span><span class="p">,</span> <span class="nx">val</span>
<span class="nx">params</span><span class="p">.</span><span class="nx">push</span> <span class="nx">ref</span> <span class="k">unless</span> <span class="nx">splats</span>
<span class="nv">wasEmpty = </span><span class="nx">@body</span><span class="p">.</span><span class="nx">isEmpty</span><span class="p">()</span>
<span class="nx">exprs</span><span class="p">.</span><span class="nx">unshift</span> <span class="nx">splats</span> <span class="k">if</span> <span class="nx">splats</span>
<span class="nx">@body</span><span class="p">.</span><span class="nx">expressions</span><span class="p">.</span><span class="nx">unshift</span> <span class="nx">exprs</span><span class="p">...</span> <span class="k">if</span> <span class="nx">exprs</span><span class="p">.</span><span class="nx">length</span>
<span class="k">for</span> <span class="nx">p</span><span class="p">,</span> <span class="nx">i</span> <span class="k">in</span> <span class="nx">params</span>
<span class="nx">params</span><span class="p">[</span><span class="nx">i</span><span class="p">]</span> <span class="o">=</span> <span class="nx">p</span><span class="p">.</span><span class="nx">compileToFragments</span> <span class="nx">o</span>
<span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">parameter</span> <span class="nx">fragmentsToText</span> <span class="nx">params</span><span class="p">[</span><span class="nx">i</span><span class="p">]</span>
<span class="nv">uniqs = </span><span class="p">[]</span>
<span class="nx">@eachParamName</span> <span class="nf">(name, node) -&gt;</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">error</span> <span class="s">&quot;multiple parameters named &#39;</span><span class="si">#{</span><span class="nx">name</span><span class="si">}</span><span class="s">&#39;&quot;</span> <span class="k">if</span> <span class="nx">name</span> <span class="k">in</span> <span class="nx">uniqs</span>
<span class="nx">uniqs</span><span class="p">.</span><span class="nx">push</span> <span class="nx">name</span>
<span class="nx">@body</span><span class="p">.</span><span class="nx">makeReturn</span><span class="p">()</span> <span class="k">unless</span> <span class="nx">wasEmpty</span> <span class="o">or</span> <span class="nx">@noReturn</span>
<span class="k">if</span> <span class="nx">@bound</span>
<span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">parent</span><span class="p">.</span><span class="nx">method</span><span class="o">?</span><span class="p">.</span><span class="nx">bound</span>
<span class="vi">@bound = @context = </span><span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">parent</span><span class="p">.</span><span class="nx">method</span><span class="p">.</span><span class="nx">context</span>
<span class="k">else</span> <span class="k">if</span> <span class="o">not</span> <span class="nx">@static</span>
<span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">parent</span><span class="p">.</span><span class="nx">assign</span> <span class="s">&#39;_this&#39;</span><span class="p">,</span> <span class="s">&#39;this&#39;</span>
<span class="nv">idt = </span><span class="nx">o</span><span class="p">.</span><span class="nx">indent</span>
<span class="nv">code = </span><span class="s">&#39;function&#39;</span>
<span class="nx">code</span> <span class="o">+=</span> <span class="s">&#39; &#39;</span> <span class="o">+</span> <span class="nx">@name</span> <span class="k">if</span> <span class="nx">@ctor</span>
<span class="nx">code</span> <span class="o">+=</span> <span class="s">&#39;(&#39;</span>
<span class="nv">answer = </span><span class="p">[</span><span class="nx">@makeCode</span><span class="p">(</span><span class="nx">code</span><span class="p">)]</span>
<span class="k">for</span> <span class="nx">p</span><span class="p">,</span> <span class="nx">i</span> <span class="k">in</span> <span class="nx">params</span>
<span class="k">if</span> <span class="nx">i</span> <span class="k">then</span> <span class="nx">answer</span><span class="p">.</span><span class="nx">push</span> <span class="nx">@makeCode</span> <span class="s">&quot;, &quot;</span>
<span class="nx">answer</span><span class="p">.</span><span class="nx">push</span> <span class="nx">p</span><span class="p">...</span>
<span class="nx">answer</span><span class="p">.</span><span class="nx">push</span> <span class="nx">@makeCode</span> <span class="s">&#39;) {&#39;</span>
<span class="nv">answer = </span><span class="nx">answer</span><span class="p">.</span><span class="nx">concat</span><span class="p">(</span><span class="nx">@makeCode</span><span class="p">(</span><span class="s">&quot;\n&quot;</span><span class="p">),</span> <span class="nx">@body</span><span class="p">.</span><span class="nx">compileWithDeclarations</span><span class="p">(</span><span class="nx">o</span><span class="p">),</span> <span class="nx">@makeCode</span><span class="p">(</span><span class="s">&quot;\n</span><span class="si">#{</span><span class="nx">@tab</span><span class="si">}</span><span class="s">&quot;</span><span class="p">))</span> <span class="k">unless</span> <span class="nx">@body</span><span class="p">.</span><span class="nx">isEmpty</span><span class="p">()</span>
<span class="nx">answer</span><span class="p">.</span><span class="nx">push</span> <span class="nx">@makeCode</span> <span class="s">&#39;}&#39;</span>
<span class="k">return</span> <span class="p">[</span><span class="nx">@makeCode</span><span class="p">(</span><span class="nx">@tab</span><span class="p">),</span> <span class="nx">answer</span><span class="p">...]</span> <span class="k">if</span> <span class="nx">@ctor</span>
<span class="k">if</span> <span class="nx">@front</span> <span class="o">or</span> <span class="p">(</span><span class="nx">o</span><span class="p">.</span><span class="nx">level</span> <span class="o">&gt;=</span> <span class="nx">LEVEL_ACCESS</span><span class="p">)</span> <span class="k">then</span> <span class="nx">@wrapInBraces</span> <span class="nx">answer</span> <span class="k">else</span> <span class="nx">answer</span>
<span class="nv">eachParamName: </span><span class="nf">(iterator) -&gt;</span>
<span class="nx">param</span><span class="p">.</span><span class="nx">eachName</span> <span class="nx">iterator</span> <span class="k">for</span> <span class="nx">param</span> <span class="k">in</span> <span class="nx">@params</span></pre></div></div>
</li>
<li id="section-91">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-91">&#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="nv">traverseChildren: </span><span class="nf">(crossScope, func) -&gt;</span>
<span class="k">super</span><span class="p">(</span><span class="nx">crossScope</span><span class="p">,</span> <span class="nx">func</span><span class="p">)</span> <span class="k">if</span> <span class="nx">crossScope</span></pre></div></div>
</li>
<li id="section-92">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-92">&#182;</a>
</div>
<h3>Param</h3>
<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="nv">exports.Param = </span><span class="k">class</span> <span class="nx">Param</span> <span class="k">extends</span> <span class="nx">Base</span>
<span class="nv">constructor: </span><span class="nf">(@name, @value, @splat) -&gt;</span>
<span class="k">if</span> <span class="p">(</span><span class="nv">name = </span><span class="nx">@name</span><span class="p">.</span><span class="nx">unwrapAll</span><span class="p">().</span><span class="nx">value</span><span class="p">)</span> <span class="k">in</span> <span class="nx">STRICT_PROSCRIBED</span>
<span class="nx">@name</span><span class="p">.</span><span class="nx">error</span> <span class="s">&quot;parameter name \&quot;</span><span class="si">#{</span><span class="nx">name</span><span class="si">}</span><span class="s">\&quot; is not allowed&quot;</span>
<span class="nv">children: </span><span class="p">[</span><span class="s">&#39;name&#39;</span><span class="p">,</span> <span class="s">&#39;value&#39;</span><span class="p">]</span>
<span class="nv">compileToFragments: </span><span class="nf">(o) -&gt;</span>
<span class="nx">@name</span><span class="p">.</span><span class="nx">compileToFragments</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_LIST</span>
<span class="nv">asReference: </span><span class="nf">(o) -&gt;</span>
<span class="k">return</span> <span class="nx">@reference</span> <span class="k">if</span> <span class="nx">@reference</span>
<span class="nv">node = </span><span class="nx">@name</span>
<span class="k">if</span> <span class="nx">node</span><span class="p">.</span><span class="nx">this</span>
<span class="nv">node = </span><span class="nx">node</span><span class="p">.</span><span class="nx">properties</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nx">name</span>
<span class="k">if</span> <span class="nx">node</span><span class="p">.</span><span class="nx">value</span><span class="p">.</span><span class="nx">reserved</span>
<span class="nv">node = </span><span class="k">new</span> <span class="nx">Literal</span> <span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span> <span class="nx">node</span><span class="p">.</span><span class="nx">value</span>
<span class="k">else</span> <span class="k">if</span> <span class="nx">node</span><span class="p">.</span><span class="nx">isComplex</span><span class="p">()</span>
<span class="nv">node = </span><span class="k">new</span> <span class="nx">Literal</span> <span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span> <span class="s">&#39;arg&#39;</span>
<span class="nv">node = </span><span class="k">new</span> <span class="nx">Value</span> <span class="nx">node</span>
<span class="nv">node = </span><span class="k">new</span> <span class="nx">Splat</span> <span class="nx">node</span> <span class="k">if</span> <span class="nx">@splat</span>
<span class="vi">@reference = </span><span class="nx">node</span>
<span class="nv">isComplex: </span><span class="nf">-&gt;</span>
<span class="nx">@name</span><span class="p">.</span><span class="nx">isComplex</span><span class="p">()</span></pre></div></div>
</li>
<li id="section-93">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-93">&#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="nv">eachName: </span><span class="nf">(iterator, name = @name)-&gt;</span>
<span class="nv">atParam = </span><span class="nf">(obj) -&gt;</span>
<span class="nv">node = </span><span class="nx">obj</span><span class="p">.</span><span class="nx">properties</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nx">name</span>
<span class="nx">iterator</span> <span class="nx">node</span><span class="p">.</span><span class="nx">value</span><span class="p">,</span> <span class="nx">node</span> <span class="k">unless</span> <span class="nx">node</span><span class="p">.</span><span class="nx">value</span><span class="p">.</span><span class="nx">reserved</span></pre></div></div>
</li>
<li id="section-94">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-94">&#182;</a>
</div>
<ul>
<li>simple literals <code>foo</code></li>
</ul>
</div>
<div class="content"><div class="highlight"><pre> <span class="k">return</span> <span class="nx">iterator</span> <span class="nx">name</span><span class="p">.</span><span class="nx">value</span><span class="p">,</span> <span class="nx">name</span> <span class="k">if</span> <span class="nx">name</span> <span class="k">instanceof</span> <span class="nx">Literal</span></pre></div></div>
</li>
<li id="section-95">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-95">&#182;</a>
</div>
<ul>
<li>at-params <code>@foo</code></li>
</ul>
</div>
<div class="content"><div class="highlight"><pre> <span class="k">return</span> <span class="nx">atParam</span> <span class="nx">name</span> <span class="k">if</span> <span class="nx">name</span> <span class="k">instanceof</span> <span class="nx">Value</span>
<span class="k">for</span> <span class="nx">obj</span> <span class="k">in</span> <span class="nx">name</span><span class="p">.</span><span class="nx">objects</span></pre></div></div>
</li>
<li id="section-96">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-96">&#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="k">if</span> <span class="nx">obj</span> <span class="k">instanceof</span> <span class="nx">Assign</span>
<span class="nx">@eachName</span> <span class="nx">iterator</span><span class="p">,</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">value</span><span class="p">.</span><span class="nx">unwrap</span><span class="p">()</span></pre></div></div>
</li>
<li id="section-97">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-97">&#182;</a>
</div>
<ul>
<li>splats within destructured parameters <code>[xs...]</code></li>
</ul>
</div>
<div class="content"><div class="highlight"><pre> <span class="k">else</span> <span class="k">if</span> <span class="nx">obj</span> <span class="k">instanceof</span> <span class="nx">Splat</span>
<span class="nv">node = </span><span class="nx">obj</span><span class="p">.</span><span class="nx">name</span><span class="p">.</span><span class="nx">unwrap</span><span class="p">()</span>
<span class="nx">iterator</span> <span class="nx">node</span><span class="p">.</span><span class="nx">value</span><span class="p">,</span> <span class="nx">node</span>
<span class="k">else</span> <span class="k">if</span> <span class="nx">obj</span> <span class="k">instanceof</span> <span class="nx">Value</span></pre></div></div>
</li>
<li id="section-98">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-98">&#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="k">if</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">isArray</span><span class="p">()</span> <span class="o">or</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">isObject</span><span class="p">()</span>
<span class="nx">@eachName</span> <span class="nx">iterator</span><span class="p">,</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">base</span></pre></div></div>
</li>
<li id="section-99">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-99">&#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="k">else</span> <span class="k">if</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">this</span>
<span class="nx">atParam</span> <span class="nx">obj</span></pre></div></div>
</li>
<li id="section-100">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-100">&#182;</a>
</div>
<ul>
<li>simple destructured parameters {foo}</li>
</ul>
</div>
<div class="content"><div class="highlight"><pre> <span class="k">else</span> <span class="nx">iterator</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">base</span><span class="p">.</span><span class="nx">value</span><span class="p">,</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">base</span>
<span class="k">else</span>
<span class="nx">obj</span><span class="p">.</span><span class="nx">error</span> <span class="s">&quot;illegal parameter </span><span class="si">#{</span><span class="nx">obj</span><span class="p">.</span><span class="nx">compile</span><span class="p">()</span><span class="si">}</span><span class="s">&quot;</span>
<span class="k">return</span></pre></div></div>
</li>
<li id="section-101">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-101">&#182;</a>
</div>
<h3>Splat</h3>
<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="nv">exports.Splat = </span><span class="k">class</span> <span class="nx">Splat</span> <span class="k">extends</span> <span class="nx">Base</span>
<span class="nv">children: </span><span class="p">[</span><span class="s">&#39;name&#39;</span><span class="p">]</span>
<span class="nv">isAssignable: </span><span class="nx">YES</span>
<span class="nv">constructor: </span><span class="nf">(name) -&gt;</span>
<span class="vi">@name = </span><span class="k">if</span> <span class="nx">name</span><span class="p">.</span><span class="nx">compile</span> <span class="k">then</span> <span class="nx">name</span> <span class="k">else</span> <span class="k">new</span> <span class="nx">Literal</span> <span class="nx">name</span>
<span class="nv">assigns: </span><span class="nf">(name) -&gt;</span>
<span class="nx">@name</span><span class="p">.</span><span class="nx">assigns</span> <span class="nx">name</span>
<span class="nv">compileToFragments: </span><span class="nf">(o) -&gt;</span>
<span class="nx">@name</span><span class="p">.</span><span class="nx">compileToFragments</span> <span class="nx">o</span>
<span class="nv">unwrap: </span><span class="nf">-&gt;</span> <span class="nx">@name</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>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="vi">@compileSplattedArray: </span><span class="nf">(o, list, apply) -&gt;</span>
<span class="nv">index = </span><span class="o">-</span><span class="mi">1</span>
<span class="k">continue</span> <span class="k">while</span> <span class="p">(</span><span class="nv">node = </span><span class="nx">list</span><span class="p">[</span><span class="o">++</span><span class="nx">index</span><span class="p">])</span> <span class="o">and</span> <span class="nx">node</span> <span class="o">not</span> <span class="k">instanceof</span> <span class="nx">Splat</span>
<span class="k">return</span> <span class="p">[]</span> <span class="k">if</span> <span class="nx">index</span> <span class="o">&gt;=</span> <span class="nx">list</span><span class="p">.</span><span class="nx">length</span>
<span class="k">if</span> <span class="nx">list</span><span class="p">.</span><span class="nx">length</span> <span class="o">is</span> <span class="mi">1</span>
<span class="nv">node = </span><span class="nx">list</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="nv">fragments = </span><span class="nx">node</span><span class="p">.</span><span class="nx">compileToFragments</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_LIST</span>
<span class="k">return</span> <span class="nx">fragments</span> <span class="k">if</span> <span class="nx">apply</span>
<span class="k">return</span> <span class="p">[].</span><span class="nx">concat</span> <span class="nx">node</span><span class="p">.</span><span class="nx">makeCode</span><span class="p">(</span><span class="s">&quot;</span><span class="si">#{</span> <span class="nx">utility</span> <span class="s">&#39;slice&#39;</span> <span class="si">}</span><span class="s">.call(&quot;</span><span class="p">),</span> <span class="nx">fragments</span><span class="p">,</span> <span class="nx">node</span><span class="p">.</span><span class="nx">makeCode</span><span class="p">(</span><span class="s">&quot;)&quot;</span><span class="p">)</span>
<span class="nv">args = </span><span class="nx">list</span><span class="p">[</span><span class="nx">index</span><span class="p">..]</span>
<span class="k">for</span> <span class="nx">node</span><span class="p">,</span> <span class="nx">i</span> <span class="k">in</span> <span class="nx">args</span>
<span class="nv">compiledNode = </span><span class="nx">node</span><span class="p">.</span><span class="nx">compileToFragments</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_LIST</span>
<span class="nx">args</span><span class="p">[</span><span class="nx">i</span><span class="p">]</span> <span class="o">=</span> <span class="k">if</span> <span class="nx">node</span> <span class="k">instanceof</span> <span class="nx">Splat</span>
<span class="k">then</span> <span class="p">[].</span><span class="nx">concat</span> <span class="nx">node</span><span class="p">.</span><span class="nx">makeCode</span><span class="p">(</span><span class="s">&quot;</span><span class="si">#{</span> <span class="nx">utility</span> <span class="s">&#39;slice&#39;</span> <span class="si">}</span><span class="s">.call(&quot;</span><span class="p">),</span> <span class="nx">compiledNode</span><span class="p">,</span> <span class="nx">node</span><span class="p">.</span><span class="nx">makeCode</span><span class="p">(</span><span class="s">&quot;)&quot;</span><span class="p">)</span>
<span class="k">else</span> <span class="p">[].</span><span class="nx">concat</span> <span class="nx">node</span><span class="p">.</span><span class="nx">makeCode</span><span class="p">(</span><span class="s">&quot;[&quot;</span><span class="p">),</span> <span class="nx">compiledNode</span><span class="p">,</span> <span class="nx">node</span><span class="p">.</span><span class="nx">makeCode</span><span class="p">(</span><span class="s">&quot;]&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="nx">index</span> <span class="o">is</span> <span class="mi">0</span>
<span class="nv">node = </span><span class="nx">list</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="nv">concatPart = </span><span class="p">(</span><span class="nx">node</span><span class="p">.</span><span class="nx">joinFragmentArrays</span> <span class="nx">args</span><span class="p">[</span><span class="mi">1</span><span class="p">..],</span> <span class="s">&#39;, &#39;</span><span class="p">)</span>
<span class="k">return</span> <span class="nx">args</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nx">concat</span> <span class="nx">node</span><span class="p">.</span><span class="nx">makeCode</span><span class="p">(</span><span class="s">&quot;.concat(&quot;</span><span class="p">),</span> <span class="nx">concatPart</span><span class="p">,</span> <span class="nx">node</span><span class="p">.</span><span class="nx">makeCode</span><span class="p">(</span><span class="s">&quot;)&quot;</span><span class="p">)</span>
<span class="nv">base = </span><span class="p">(</span><span class="nx">node</span><span class="p">.</span><span class="nx">compileToFragments</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_LIST</span> <span class="k">for</span> <span class="nx">node</span> <span class="k">in</span> <span class="nx">list</span><span class="p">[...</span><span class="nx">index</span><span class="p">])</span>
<span class="nv">base = </span><span class="nx">list</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nx">joinFragmentArrays</span> <span class="nx">base</span><span class="p">,</span> <span class="s">&#39;, &#39;</span>
<span class="nv">concatPart = </span><span class="nx">list</span><span class="p">[</span><span class="nx">index</span><span class="p">].</span><span class="nx">joinFragmentArrays</span> <span class="nx">args</span><span class="p">,</span> <span class="s">&#39;, &#39;</span>
<span class="p">[].</span><span class="nx">concat</span> <span class="nx">list</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nx">makeCode</span><span class="p">(</span><span class="s">&quot;[&quot;</span><span class="p">),</span> <span class="nx">base</span><span class="p">,</span> <span class="nx">list</span><span class="p">[</span><span class="nx">index</span><span class="p">].</span><span class="nx">makeCode</span><span class="p">(</span><span class="s">&quot;].concat(&quot;</span><span class="p">),</span> <span class="nx">concatPart</span><span class="p">,</span> <span class="p">(</span><span class="nx">last</span> <span class="nx">list</span><span class="p">).</span><span class="nx">makeCode</span><span class="p">(</span><span class="s">&quot;)&quot;</span><span class="p">)</span></pre></div></div>
</li>
<li id="section-103">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-103">&#182;</a>
</div>
<h3>While</h3>
<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="nv">exports.While = </span><span class="k">class</span> <span class="nx">While</span> <span class="k">extends</span> <span class="nx">Base</span>
<span class="nv">constructor: </span><span class="nf">(condition, options) -&gt;</span>
<span class="vi">@condition = </span><span class="k">if</span> <span class="nx">options</span><span class="o">?</span><span class="p">.</span><span class="nx">invert</span> <span class="k">then</span> <span class="nx">condition</span><span class="p">.</span><span class="nx">invert</span><span class="p">()</span> <span class="k">else</span> <span class="nx">condition</span>
<span class="vi">@guard = </span><span class="nx">options</span><span class="o">?</span><span class="p">.</span><span class="nx">guard</span>
<span class="nv">children: </span><span class="p">[</span><span class="s">&#39;condition&#39;</span><span class="p">,</span> <span class="s">&#39;guard&#39;</span><span class="p">,</span> <span class="s">&#39;body&#39;</span><span class="p">]</span>
<span class="nv">isStatement: </span><span class="nx">YES</span>
<span class="nv">makeReturn: </span><span class="nf">(res) -&gt;</span>
<span class="k">if</span> <span class="nx">res</span>
<span class="k">super</span>
<span class="k">else</span>
<span class="vi">@returns = </span><span class="o">not</span> <span class="nx">@jumps</span> <span class="k">loop</span><span class="o">:</span> <span class="kc">yes</span>
<span class="k">this</span>
<span class="nv">addBody: </span><span class="nf">(@body) -&gt;</span>
<span class="k">this</span>
<span class="nv">jumps: </span><span class="nf">-&gt;</span>
<span class="p">{</span><span class="nx">expressions</span><span class="p">}</span> <span class="o">=</span> <span class="nx">@body</span>
<span class="k">return</span> <span class="kc">no</span> <span class="k">unless</span> <span class="nx">expressions</span><span class="p">.</span><span class="nx">length</span>
<span class="k">for</span> <span class="nx">node</span> <span class="k">in</span> <span class="nx">expressions</span>
<span class="k">return</span> <span class="nx">node</span> <span class="k">if</span> <span class="nx">node</span><span class="p">.</span><span class="nx">jumps</span> <span class="k">loop</span><span class="o">:</span> <span class="kc">yes</span>
<span class="kc">no</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>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="nv">compileNode: </span><span class="nf">(o) -&gt;</span>
<span class="nx">o</span><span class="p">.</span><span class="nx">indent</span> <span class="o">+=</span> <span class="nx">TAB</span>
<span class="nv">set = </span><span class="s">&#39;&#39;</span>
<span class="p">{</span><span class="nx">body</span><span class="p">}</span> <span class="o">=</span> <span class="k">this</span>
<span class="k">if</span> <span class="nx">body</span><span class="p">.</span><span class="nx">isEmpty</span><span class="p">()</span>
<span class="nv">body = </span><span class="s">&#39;&#39;</span>
<span class="k">else</span>
<span class="k">if</span> <span class="nx">@returns</span>
<span class="nx">body</span><span class="p">.</span><span class="nx">makeReturn</span> <span class="nv">rvar = </span><span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span> <span class="s">&#39;results&#39;</span>
<span class="nv">set = </span><span class="s">&quot;</span><span class="si">#{</span><span class="nx">@tab</span><span class="si">}#{</span><span class="nx">rvar</span><span class="si">}</span><span class="s"> = [];\n&quot;</span>
<span class="k">if</span> <span class="nx">@guard</span>
<span class="k">if</span> <span class="nx">body</span><span class="p">.</span><span class="nx">expressions</span><span class="p">.</span><span class="nx">length</span> <span class="o">&gt;</span> <span class="mi">1</span>
<span class="nx">body</span><span class="p">.</span><span class="nx">expressions</span><span class="p">.</span><span class="nx">unshift</span> <span class="k">new</span> <span class="nx">If</span> <span class="p">(</span><span class="k">new</span> <span class="nx">Parens</span> <span class="nx">@guard</span><span class="p">).</span><span class="nx">invert</span><span class="p">(),</span> <span class="k">new</span> <span class="nx">Literal</span> <span class="s">&quot;continue&quot;</span>
<span class="k">else</span>
<span class="nv">body = </span><span class="nx">Block</span><span class="p">.</span><span class="nx">wrap</span> <span class="p">[</span><span class="k">new</span> <span class="nx">If</span> <span class="nx">@guard</span><span class="p">,</span> <span class="nx">body</span><span class="p">]</span> <span class="k">if</span> <span class="nx">@guard</span>
<span class="nv">body = </span><span class="p">[].</span><span class="nx">concat</span> <span class="nx">@makeCode</span><span class="p">(</span><span class="s">&quot;\n&quot;</span><span class="p">),</span> <span class="p">(</span><span class="nx">body</span><span class="p">.</span><span class="nx">compileToFragments</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_TOP</span><span class="p">),</span> <span class="nx">@makeCode</span><span class="p">(</span><span class="s">&quot;\n</span><span class="si">#{</span><span class="nx">@tab</span><span class="si">}</span><span class="s">&quot;</span><span class="p">)</span>
<span class="nv">answer = </span><span class="p">[].</span><span class="nx">concat</span> <span class="nx">@makeCode</span><span class="p">(</span><span class="nx">set</span> <span class="o">+</span> <span class="nx">@tab</span> <span class="o">+</span> <span class="s">&quot;while (&quot;</span><span class="p">),</span> <span class="nx">@condition</span><span class="p">.</span><span class="nx">compileToFragments</span><span class="p">(</span><span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_PAREN</span><span class="p">),</span>
<span class="nx">@makeCode</span><span class="p">(</span><span class="s">&quot;) {&quot;</span><span class="p">),</span> <span class="nx">body</span><span class="p">,</span> <span class="nx">@makeCode</span><span class="p">(</span><span class="s">&quot;}&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="nx">@returns</span>
<span class="nx">answer</span><span class="p">.</span><span class="nx">push</span> <span class="nx">@makeCode</span> <span class="s">&quot;\n</span><span class="si">#{</span><span class="nx">@tab</span><span class="si">}</span><span class="s">return </span><span class="si">#{</span><span class="nx">rvar</span><span class="si">}</span><span class="s">;&quot;</span>
<span class="nx">answer</span></pre></div></div>
</li>
<li id="section-105">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-105">&#182;</a>
</div>
<h3>Op</h3>
<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="nv">exports.Op = </span><span class="k">class</span> <span class="nx">Op</span> <span class="k">extends</span> <span class="nx">Base</span>
<span class="nv">constructor: </span><span class="nf">(op, first, second, flip ) -&gt;</span>
<span class="k">return</span> <span class="k">new</span> <span class="nx">In</span> <span class="nx">first</span><span class="p">,</span> <span class="nx">second</span> <span class="k">if</span> <span class="nx">op</span> <span class="o">is</span> <span class="s">&#39;in&#39;</span>
<span class="k">if</span> <span class="nx">op</span> <span class="o">is</span> <span class="s">&#39;do&#39;</span>
<span class="k">return</span> <span class="nx">@generateDo</span> <span class="nx">first</span>
<span class="k">if</span> <span class="nx">op</span> <span class="o">is</span> <span class="s">&#39;new&#39;</span>
<span class="k">return</span> <span class="nx">first</span><span class="p">.</span><span class="nx">newInstance</span><span class="p">()</span> <span class="k">if</span> <span class="nx">first</span> <span class="k">instanceof</span> <span class="nx">Call</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">first</span><span class="p">.</span><span class="nx">do</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">first</span><span class="p">.</span><span class="nx">isNew</span>
<span class="nv">first = </span><span class="k">new</span> <span class="nx">Parens</span> <span class="nx">first</span> <span class="k">if</span> <span class="nx">first</span> <span class="k">instanceof</span> <span class="nx">Code</span> <span class="o">and</span> <span class="nx">first</span><span class="p">.</span><span class="nx">bound</span> <span class="o">or</span> <span class="nx">first</span><span class="p">.</span><span class="nx">do</span>
<span class="vi">@operator = </span><span class="nx">CONVERSIONS</span><span class="p">[</span><span class="nx">op</span><span class="p">]</span> <span class="o">or</span> <span class="nx">op</span>
<span class="vi">@first = </span><span class="nx">first</span>
<span class="vi">@second = </span><span class="nx">second</span>
<span class="vi">@flip = </span><span class="o">!!</span><span class="nx">flip</span>
<span class="k">return</span> <span class="k">this</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>The map of conversions from CoffeeScript to JavaScript symbols.
</p>
</div>
<div class="content"><div class="highlight"><pre> <span class="nv">CONVERSIONS =</span>
<span class="s">&#39;==&#39;</span><span class="o">:</span> <span class="s">&#39;===&#39;</span>
<span class="s">&#39;!=&#39;</span><span class="o">:</span> <span class="s">&#39;!==&#39;</span>
<span class="s">&#39;of&#39;</span><span class="o">:</span> <span class="s">&#39;in&#39;</span></pre></div></div>
</li>
<li id="section-107">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-107">&#182;</a>
</div>
<p>The map of invertible operators.
</p>
</div>
<div class="content"><div class="highlight"><pre> <span class="nv">INVERSIONS =</span>
<span class="s">&#39;!==&#39;</span><span class="o">:</span> <span class="s">&#39;===&#39;</span>
<span class="s">&#39;===&#39;</span><span class="o">:</span> <span class="s">&#39;!==&#39;</span>
<span class="nv">children: </span><span class="p">[</span><span class="s">&#39;first&#39;</span><span class="p">,</span> <span class="s">&#39;second&#39;</span><span class="p">]</span>
<span class="nv">isSimpleNumber: </span><span class="nx">NO</span>
<span class="nv">isUnary: </span><span class="nf">-&gt;</span>
<span class="o">not</span> <span class="nx">@second</span>
<span class="nv">isComplex: </span><span class="nf">-&gt;</span>
<span class="o">not</span> <span class="p">(</span><span class="nx">@isUnary</span><span class="p">()</span> <span class="o">and</span> <span class="p">(</span><span class="nx">@operator</span> <span class="k">in</span> <span class="p">[</span><span class="s">&#39;+&#39;</span><span class="p">,</span> <span class="s">&#39;-&#39;</span><span class="p">]))</span> <span class="o">or</span> <span class="nx">@first</span><span class="p">.</span><span class="nx">isComplex</span><span class="p">()</span></pre></div></div>
</li>
<li id="section-108">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-108">&#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="nv">isChainable: </span><span class="nf">-&gt;</span>
<span class="nx">@operator</span> <span class="k">in</span> <span class="p">[</span><span class="s">&#39;&lt;&#39;</span><span class="p">,</span> <span class="s">&#39;&gt;&#39;</span><span class="p">,</span> <span class="s">&#39;&gt;=&#39;</span><span class="p">,</span> <span class="s">&#39;&lt;=&#39;</span><span class="p">,</span> <span class="s">&#39;===&#39;</span><span class="p">,</span> <span class="s">&#39;!==&#39;</span><span class="p">]</span>
<span class="nv">invert: </span><span class="nf">-&gt;</span>
<span class="k">if</span> <span class="nx">@isChainable</span><span class="p">()</span> <span class="o">and</span> <span class="nx">@first</span><span class="p">.</span><span class="nx">isChainable</span><span class="p">()</span>
<span class="nv">allInvertable = </span><span class="kc">yes</span>
<span class="nv">curr = </span><span class="k">this</span>
<span class="k">while</span> <span class="nx">curr</span> <span class="o">and</span> <span class="nx">curr</span><span class="p">.</span><span class="nx">operator</span>
<span class="nx">allInvertable</span> <span class="o">and=</span> <span class="p">(</span><span class="nx">curr</span><span class="p">.</span><span class="nx">operator</span> <span class="k">of</span> <span class="nx">INVERSIONS</span><span class="p">)</span>
<span class="nv">curr = </span><span class="nx">curr</span><span class="p">.</span><span class="nx">first</span>
<span class="k">return</span> <span class="k">new</span> <span class="nx">Parens</span><span class="p">(</span><span class="k">this</span><span class="p">).</span><span class="nx">invert</span><span class="p">()</span> <span class="k">unless</span> <span class="nx">allInvertable</span>
<span class="nv">curr = </span><span class="k">this</span>
<span class="k">while</span> <span class="nx">curr</span> <span class="o">and</span> <span class="nx">curr</span><span class="p">.</span><span class="nx">operator</span>
<span class="nv">curr.invert = </span><span class="o">!</span><span class="nx">curr</span><span class="p">.</span><span class="nx">invert</span>
<span class="nv">curr.operator = </span><span class="nx">INVERSIONS</span><span class="p">[</span><span class="nx">curr</span><span class="p">.</span><span class="nx">operator</span><span class="p">]</span>
<span class="nv">curr = </span><span class="nx">curr</span><span class="p">.</span><span class="nx">first</span>
<span class="k">this</span>
<span class="k">else</span> <span class="k">if</span> <span class="nv">op = </span><span class="nx">INVERSIONS</span><span class="p">[</span><span class="nx">@operator</span><span class="p">]</span>
<span class="vi">@operator = </span><span class="nx">op</span>
<span class="k">if</span> <span class="nx">@first</span><span class="p">.</span><span class="nx">unwrap</span><span class="p">()</span> <span class="k">instanceof</span> <span class="nx">Op</span>
<span class="nx">@first</span><span class="p">.</span><span class="nx">invert</span><span class="p">()</span>
<span class="k">this</span>
<span class="k">else</span> <span class="k">if</span> <span class="nx">@second</span>
<span class="k">new</span> <span class="nx">Parens</span><span class="p">(</span><span class="k">this</span><span class="p">).</span><span class="nx">invert</span><span class="p">()</span>
<span class="k">else</span> <span class="k">if</span> <span class="nx">@operator</span> <span class="o">is</span> <span class="s">&#39;!&#39;</span> <span class="o">and</span> <span class="p">(</span><span class="nv">fst = </span><span class="nx">@first</span><span class="p">.</span><span class="nx">unwrap</span><span class="p">())</span> <span class="k">instanceof</span> <span class="nx">Op</span> <span class="o">and</span>
<span class="nx">fst</span><span class="p">.</span><span class="nx">operator</span> <span class="k">in</span> <span class="p">[</span><span class="s">&#39;!&#39;</span><span class="p">,</span> <span class="s">&#39;in&#39;</span><span class="p">,</span> <span class="s">&#39;instanceof&#39;</span><span class="p">]</span>
<span class="nx">fst</span>
<span class="k">else</span>
<span class="k">new</span> <span class="nx">Op</span> <span class="s">&#39;!&#39;</span><span class="p">,</span> <span class="k">this</span>
<span class="nv">unfoldSoak: </span><span class="nf">(o) -&gt;</span>
<span class="nx">@operator</span> <span class="k">in</span> <span class="p">[</span><span class="s">&#39;++&#39;</span><span class="p">,</span> <span class="s">&#39;--&#39;</span><span class="p">,</span> <span class="s">&#39;delete&#39;</span><span class="p">]</span> <span class="o">and</span> <span class="nx">unfoldSoak</span> <span class="nx">o</span><span class="p">,</span> <span class="k">this</span><span class="p">,</span> <span class="s">&#39;first&#39;</span>
<span class="nv">generateDo: </span><span class="nf">(exp) -&gt;</span>
<span class="nv">passedParams = </span><span class="p">[]</span>
<span class="nv">func = </span><span class="k">if</span> <span class="nx">exp</span> <span class="k">instanceof</span> <span class="nx">Assign</span> <span class="o">and</span> <span class="p">(</span><span class="nv">ref = </span><span class="nx">exp</span><span class="p">.</span><span class="nx">value</span><span class="p">.</span><span class="nx">unwrap</span><span class="p">())</span> <span class="k">instanceof</span> <span class="nx">Code</span>
<span class="nx">ref</span>
<span class="k">else</span>
<span class="nx">exp</span>
<span class="k">for</span> <span class="nx">param</span> <span class="k">in</span> <span class="nx">func</span><span class="p">.</span><span class="nx">params</span> <span class="o">or</span> <span class="p">[]</span>
<span class="k">if</span> <span class="nx">param</span><span class="p">.</span><span class="nx">value</span>
<span class="nx">passedParams</span><span class="p">.</span><span class="nx">push</span> <span class="nx">param</span><span class="p">.</span><span class="nx">value</span>
<span class="k">delete</span> <span class="nx">param</span><span class="p">.</span><span class="nx">value</span>
<span class="k">else</span>
<span class="nx">passedParams</span><span class="p">.</span><span class="nx">push</span> <span class="nx">param</span>
<span class="nv">call = </span><span class="k">new</span> <span class="nx">Call</span> <span class="nx">exp</span><span class="p">,</span> <span class="nx">passedParams</span>
<span class="nv">call.do = </span><span class="kc">yes</span>
<span class="nx">call</span>
<span class="nv">compileNode: </span><span class="nf">(o) -&gt;</span>
<span class="nv">isChain = </span><span class="nx">@isChainable</span><span class="p">()</span> <span class="o">and</span> <span class="nx">@first</span><span class="p">.</span><span class="nx">isChainable</span><span class="p">()</span></pre></div></div>
</li>
<li id="section-109">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-109">&#182;</a>
</div>
<p>In chains, there&#39;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="vi">@first.front = </span><span class="nx">@front</span> <span class="k">unless</span> <span class="nx">isChain</span>
<span class="k">if</span> <span class="nx">@operator</span> <span class="o">is</span> <span class="s">&#39;delete&#39;</span> <span class="o">and</span> <span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">check</span><span class="p">(</span><span class="nx">@first</span><span class="p">.</span><span class="nx">unwrapAll</span><span class="p">().</span><span class="nx">value</span><span class="p">)</span>
<span class="nx">@error</span> <span class="s">&#39;delete operand may not be argument or var&#39;</span>
<span class="k">if</span> <span class="nx">@operator</span> <span class="k">in</span> <span class="p">[</span><span class="s">&#39;--&#39;</span><span class="p">,</span> <span class="s">&#39;++&#39;</span><span class="p">]</span> <span class="o">and</span> <span class="nx">@first</span><span class="p">.</span><span class="nx">unwrapAll</span><span class="p">().</span><span class="nx">value</span> <span class="k">in</span> <span class="nx">STRICT_PROSCRIBED</span>
<span class="nx">@error</span> <span class="s">&quot;cannot increment/decrement \&quot;</span><span class="si">#{</span><span class="nx">@first</span><span class="p">.</span><span class="nx">unwrapAll</span><span class="p">().</span><span class="nx">value</span><span class="si">}</span><span class="s">\&quot;&quot;</span>
<span class="k">return</span> <span class="nx">@compileUnary</span> <span class="nx">o</span> <span class="k">if</span> <span class="nx">@isUnary</span><span class="p">()</span>
<span class="k">return</span> <span class="nx">@compileChain</span> <span class="nx">o</span> <span class="k">if</span> <span class="nx">isChain</span>
<span class="k">return</span> <span class="nx">@compileExistence</span> <span class="nx">o</span> <span class="k">if</span> <span class="nx">@operator</span> <span class="o">is</span> <span class="s">&#39;?&#39;</span>
<span class="nv">answer = </span><span class="p">[].</span><span class="nx">concat</span> <span class="nx">@first</span><span class="p">.</span><span class="nx">compileToFragments</span><span class="p">(</span><span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_OP</span><span class="p">),</span> <span class="nx">@makeCode</span><span class="p">(</span><span class="s">&#39; &#39;</span> <span class="o">+</span> <span class="nx">@operator</span> <span class="o">+</span> <span class="s">&#39; &#39;</span><span class="p">),</span>
<span class="nx">@second</span><span class="p">.</span><span class="nx">compileToFragments</span><span class="p">(</span><span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_OP</span><span class="p">)</span>
<span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">level</span> <span class="o">&lt;=</span> <span class="nx">LEVEL_OP</span> <span class="k">then</span> <span class="nx">answer</span> <span class="k">else</span> <span class="nx">@wrapInBraces</span> <span class="nx">answer</span></pre></div></div>
</li>
<li id="section-110">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-110">&#182;</a>
</div>
<p>Mimic Python&#39;s chained comparisons when multiple comparison operators are
used sequentially. For example:
</p>
<pre><code>bin/coffee -e &#39;console.log 50 &lt; 65 &gt; 10&#39;
true</code></pre>
</div>
<div class="content"><div class="highlight"><pre> <span class="nv">compileChain: </span><span class="nf">(o) -&gt;</span>
<span class="p">[</span><span class="nx">@first</span><span class="p">.</span><span class="nx">second</span><span class="p">,</span> <span class="nx">shared</span><span class="p">]</span> <span class="o">=</span> <span class="nx">@first</span><span class="p">.</span><span class="nx">second</span><span class="p">.</span><span class="nx">cache</span> <span class="nx">o</span>
<span class="nv">fst = </span><span class="nx">@first</span><span class="p">.</span><span class="nx">compileToFragments</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_OP</span>
<span class="nv">fragments = </span><span class="nx">fst</span><span class="p">.</span><span class="nx">concat</span> <span class="nx">@makeCode</span><span class="p">(</span><span class="s">&quot; </span><span class="si">#{</span><span class="k">if</span> <span class="nx">@invert</span> <span class="k">then</span> <span class="s">&#39;&amp;&amp;&#39;</span> <span class="k">else</span> <span class="s">&#39;||&#39;</span><span class="si">}</span><span class="s"> &quot;</span><span class="p">),</span>
<span class="p">(</span><span class="nx">shared</span><span class="p">.</span><span class="nx">compileToFragments</span> <span class="nx">o</span><span class="p">),</span> <span class="nx">@makeCode</span><span class="p">(</span><span class="s">&quot; </span><span class="si">#{</span><span class="nx">@operator</span><span class="si">}</span><span class="s"> &quot;</span><span class="p">),</span> <span class="p">(</span><span class="nx">@second</span><span class="p">.</span><span class="nx">compileToFragments</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_OP</span><span class="p">)</span>
<span class="nx">@wrapInBraces</span> <span class="nx">fragments</span>
<span class="nv">compileExistence: </span><span class="nf">(o) -&gt;</span>
<span class="k">if</span> <span class="nx">@first</span><span class="p">.</span><span class="nx">isComplex</span><span class="p">()</span>
<span class="nv">ref = </span><span class="k">new</span> <span class="nx">Literal</span> <span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span> <span class="s">&#39;ref&#39;</span>
<span class="nv">fst = </span><span class="k">new</span> <span class="nx">Parens</span> <span class="k">new</span> <span class="nx">Assign</span> <span class="nx">ref</span><span class="p">,</span> <span class="nx">@first</span>
<span class="k">else</span>
<span class="nv">fst = </span><span class="nx">@first</span>
<span class="nv">ref = </span><span class="nx">fst</span>
<span class="k">new</span> <span class="nx">If</span><span class="p">(</span><span class="k">new</span> <span class="nx">Existence</span><span class="p">(</span><span class="nx">fst</span><span class="p">),</span> <span class="nx">ref</span><span class="p">,</span> <span class="nv">type: </span><span class="s">&#39;if&#39;</span><span class="p">).</span><span class="nx">addElse</span><span class="p">(</span><span class="nx">@second</span><span class="p">).</span><span class="nx">compileToFragments</span> <span class="nx">o</span></pre></div></div>
</li>
<li id="section-111">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-111">&#182;</a>
</div>
<p>Compile a unary <strong>Op</strong>.
</p>
</div>
<div class="content"><div class="highlight"><pre> <span class="nv">compileUnary: </span><span class="nf">(o) -&gt;</span>
<span class="nv">parts = </span><span class="p">[]</span>
<span class="nv">op = </span><span class="nx">@operator</span>
<span class="nx">parts</span><span class="p">.</span><span class="nx">push</span> <span class="p">[</span><span class="nx">@makeCode</span> <span class="nx">op</span><span class="p">]</span>
<span class="k">if</span> <span class="nx">op</span> <span class="o">is</span> <span class="s">&#39;!&#39;</span> <span class="o">and</span> <span class="nx">@first</span> <span class="k">instanceof</span> <span class="nx">Existence</span>
<span class="vi">@first.negated = </span><span class="o">not</span> <span class="nx">@first</span><span class="p">.</span><span class="nx">negated</span>
<span class="k">return</span> <span class="nx">@first</span><span class="p">.</span><span class="nx">compileToFragments</span> <span class="nx">o</span>
<span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">level</span> <span class="o">&gt;=</span> <span class="nx">LEVEL_ACCESS</span>
<span class="k">return</span> <span class="p">(</span><span class="k">new</span> <span class="nx">Parens</span> <span class="k">this</span><span class="p">).</span><span class="nx">compileToFragments</span> <span class="nx">o</span>
<span class="nv">plusMinus = </span><span class="nx">op</span> <span class="k">in</span> <span class="p">[</span><span class="s">&#39;+&#39;</span><span class="p">,</span> <span class="s">&#39;-&#39;</span><span class="p">]</span>
<span class="nx">parts</span><span class="p">.</span><span class="nx">push</span> <span class="p">[</span><span class="nx">@makeCode</span><span class="p">(</span><span class="s">&#39; &#39;</span><span class="p">)]</span> <span class="k">if</span> <span class="nx">op</span> <span class="k">in</span> <span class="p">[</span><span class="s">&#39;new&#39;</span><span class="p">,</span> <span class="s">&#39;typeof&#39;</span><span class="p">,</span> <span class="s">&#39;delete&#39;</span><span class="p">]</span> <span class="o">or</span>
<span class="nx">plusMinus</span> <span class="o">and</span> <span class="nx">@first</span> <span class="k">instanceof</span> <span class="nx">Op</span> <span class="o">and</span> <span class="nx">@first</span><span class="p">.</span><span class="nx">operator</span> <span class="o">is</span> <span class="nx">op</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">plusMinus</span> <span class="o">&amp;&amp;</span> <span class="nx">@first</span> <span class="k">instanceof</span> <span class="nx">Op</span><span class="p">)</span> <span class="o">or</span> <span class="p">(</span><span class="nx">op</span> <span class="o">is</span> <span class="s">&#39;new&#39;</span> <span class="o">and</span> <span class="nx">@first</span><span class="p">.</span><span class="nx">isStatement</span> <span class="nx">o</span><span class="p">)</span>
<span class="vi">@first = </span><span class="k">new</span> <span class="nx">Parens</span> <span class="nx">@first</span>
<span class="nx">parts</span><span class="p">.</span><span class="nx">push</span> <span class="nx">@first</span><span class="p">.</span><span class="nx">compileToFragments</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_OP</span>
<span class="nx">parts</span><span class="p">.</span><span class="nx">reverse</span><span class="p">()</span> <span class="k">if</span> <span class="nx">@flip</span>
<span class="nx">@joinFragmentArrays</span> <span class="nx">parts</span><span class="p">,</span> <span class="s">&#39;&#39;</span>
<span class="nv">toString: </span><span class="nf">(idt) -&gt;</span>
<span class="k">super</span> <span class="nx">idt</span><span class="p">,</span> <span class="nx">@constructor</span><span class="p">.</span><span class="nx">name</span> <span class="o">+</span> <span class="s">&#39; &#39;</span> <span class="o">+</span> <span class="nx">@operator</span></pre></div></div>
</li>
<li id="section-112">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-112">&#182;</a>
</div>
<h3>In</h3>
</div>
<div class="content"><div class="highlight"><pre><span class="nv">exports.In = </span><span class="k">class</span> <span class="nx">In</span> <span class="k">extends</span> <span class="nx">Base</span>
<span class="nv">constructor: </span><span class="nf">(@object, @array) -&gt;</span>
<span class="nv">children: </span><span class="p">[</span><span class="s">&#39;object&#39;</span><span class="p">,</span> <span class="s">&#39;array&#39;</span><span class="p">]</span>
<span class="nv">invert: </span><span class="nx">NEGATE</span>
<span class="nv">compileNode: </span><span class="nf">(o) -&gt;</span>
<span class="k">if</span> <span class="nx">@array</span> <span class="k">instanceof</span> <span class="nx">Value</span> <span class="o">and</span> <span class="nx">@array</span><span class="p">.</span><span class="nx">isArray</span><span class="p">()</span>
<span class="k">for</span> <span class="nx">obj</span> <span class="k">in</span> <span class="nx">@array</span><span class="p">.</span><span class="nx">base</span><span class="p">.</span><span class="nx">objects</span> <span class="k">when</span> <span class="nx">obj</span> <span class="k">instanceof</span> <span class="nx">Splat</span>
<span class="nv">hasSplat = </span><span class="kc">yes</span>
<span class="k">break</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><code>compileOrTest</code> only if we have an array literal with no splats
</p>
</div>
<div class="content"><div class="highlight"><pre> <span class="k">return</span> <span class="nx">@compileOrTest</span> <span class="nx">o</span> <span class="k">unless</span> <span class="nx">hasSplat</span>
<span class="nx">@compileLoopTest</span> <span class="nx">o</span>
<span class="nv">compileOrTest: </span><span class="nf">(o) -&gt;</span>
<span class="k">return</span> <span class="p">[</span><span class="nx">@makeCode</span><span class="p">(</span><span class="s">&quot;</span><span class="si">#{</span><span class="o">!!</span><span class="nx">@negated</span><span class="si">}</span><span class="s">&quot;</span><span class="p">)]</span> <span class="k">if</span> <span class="nx">@array</span><span class="p">.</span><span class="nx">base</span><span class="p">.</span><span class="nx">objects</span><span class="p">.</span><span class="nx">length</span> <span class="o">is</span> <span class="mi">0</span>
<span class="p">[</span><span class="nx">sub</span><span class="p">,</span> <span class="nx">ref</span><span class="p">]</span> <span class="o">=</span> <span class="nx">@object</span><span class="p">.</span><span class="nx">cache</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_OP</span>
<span class="p">[</span><span class="nx">cmp</span><span class="p">,</span> <span class="nx">cnj</span><span class="p">]</span> <span class="o">=</span> <span class="k">if</span> <span class="nx">@negated</span> <span class="k">then</span> <span class="p">[</span><span class="s">&#39; !== &#39;</span><span class="p">,</span> <span class="s">&#39; &amp;&amp; &#39;</span><span class="p">]</span> <span class="k">else</span> <span class="p">[</span><span class="s">&#39; === &#39;</span><span class="p">,</span> <span class="s">&#39; || &#39;</span><span class="p">]</span>
<span class="nv">tests = </span><span class="p">[]</span>
<span class="k">for</span> <span class="nx">item</span><span class="p">,</span> <span class="nx">i</span> <span class="k">in</span> <span class="nx">@array</span><span class="p">.</span><span class="nx">base</span><span class="p">.</span><span class="nx">objects</span>
<span class="k">if</span> <span class="nx">i</span> <span class="k">then</span> <span class="nx">tests</span><span class="p">.</span><span class="nx">push</span> <span class="nx">@makeCode</span> <span class="nx">cnj</span>
<span class="nv">tests = </span><span class="nx">tests</span><span class="p">.</span><span class="nx">concat</span> <span class="p">(</span><span class="k">if</span> <span class="nx">i</span> <span class="k">then</span> <span class="nx">ref</span> <span class="k">else</span> <span class="nx">sub</span><span class="p">),</span> <span class="nx">@makeCode</span><span class="p">(</span><span class="nx">cmp</span><span class="p">),</span> <span class="nx">item</span><span class="p">.</span><span class="nx">compileToFragments</span><span class="p">(</span><span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_ACCESS</span><span class="p">)</span>
<span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">level</span> <span class="o">&lt;</span> <span class="nx">LEVEL_OP</span> <span class="k">then</span> <span class="nx">tests</span> <span class="k">else</span> <span class="nx">@wrapInBraces</span> <span class="nx">tests</span>
<span class="nv">compileLoopTest: </span><span class="nf">(o) -&gt;</span>
<span class="p">[</span><span class="nx">sub</span><span class="p">,</span> <span class="nx">ref</span><span class="p">]</span> <span class="o">=</span> <span class="nx">@object</span><span class="p">.</span><span class="nx">cache</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_LIST</span>
<span class="nv">fragments = </span><span class="p">[].</span><span class="nx">concat</span> <span class="nx">@makeCode</span><span class="p">(</span><span class="nx">utility</span><span class="p">(</span><span class="s">&#39;indexOf&#39;</span><span class="p">)</span> <span class="o">+</span> <span class="s">&quot;.call(&quot;</span><span class="p">),</span> <span class="nx">@array</span><span class="p">.</span><span class="nx">compileToFragments</span><span class="p">(</span><span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_LIST</span><span class="p">),</span>
<span class="nx">@makeCode</span><span class="p">(</span><span class="s">&quot;, &quot;</span><span class="p">),</span> <span class="nx">ref</span><span class="p">,</span> <span class="nx">@makeCode</span><span class="p">(</span><span class="s">&quot;) &quot;</span> <span class="o">+</span> <span class="k">if</span> <span class="nx">@negated</span> <span class="k">then</span> <span class="s">&#39;&lt; 0&#39;</span> <span class="k">else</span> <span class="s">&#39;&gt;= 0&#39;</span><span class="p">)</span>
<span class="k">return</span> <span class="nx">fragments</span> <span class="k">if</span> <span class="p">(</span><span class="nx">fragmentsToText</span> <span class="nx">sub</span><span class="p">)</span> <span class="o">is</span> <span class="p">(</span><span class="nx">fragmentsToText</span> <span class="nx">ref</span><span class="p">)</span>
<span class="nv">fragments = </span><span class="nx">sub</span><span class="p">.</span><span class="nx">concat</span> <span class="nx">@makeCode</span><span class="p">(</span><span class="s">&#39;, &#39;</span><span class="p">),</span> <span class="nx">fragments</span>
<span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">level</span> <span class="o">&lt;</span> <span class="nx">LEVEL_LIST</span> <span class="k">then</span> <span class="nx">fragments</span> <span class="k">else</span> <span class="nx">@wrapInBraces</span> <span class="nx">fragments</span>
<span class="nv">toString: </span><span class="nf">(idt) -&gt;</span>
<span class="k">super</span> <span class="nx">idt</span><span class="p">,</span> <span class="nx">@constructor</span><span class="p">.</span><span class="nx">name</span> <span class="o">+</span> <span class="k">if</span> <span class="nx">@negated</span> <span class="k">then</span> <span class="s">&#39;!&#39;</span> <span class="k">else</span> <span class="s">&#39;&#39;</span></pre></div></div>
</li>
<li id="section-114">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-114">&#182;</a>
</div>
<h3>Try</h3>
<p>A classic <em>try/catch/finally</em> block.
</p>
</div>
<div class="content"><div class="highlight"><pre><span class="nv">exports.Try = </span><span class="k">class</span> <span class="nx">Try</span> <span class="k">extends</span> <span class="nx">Base</span>
<span class="nv">constructor: </span><span class="nf">(@attempt, @errorVariable, @recovery, @ensure) -&gt;</span>
<span class="nv">children: </span><span class="p">[</span><span class="s">&#39;attempt&#39;</span><span class="p">,</span> <span class="s">&#39;recovery&#39;</span><span class="p">,</span> <span class="s">&#39;ensure&#39;</span><span class="p">]</span>
<span class="nv">isStatement: </span><span class="nx">YES</span>
<span class="nv">jumps: </span><span class="nf">(o) -&gt;</span> <span class="nx">@attempt</span><span class="p">.</span><span class="nx">jumps</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">or</span> <span class="nx">@recovery</span><span class="o">?</span><span class="p">.</span><span class="nx">jumps</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span>
<span class="nv">makeReturn: </span><span class="nf">(res) -&gt;</span>
<span class="vi">@attempt = </span><span class="nx">@attempt</span> <span class="p">.</span><span class="nx">makeReturn</span> <span class="nx">res</span> <span class="k">if</span> <span class="nx">@attempt</span>
<span class="vi">@recovery = </span><span class="nx">@recovery</span><span class="p">.</span><span class="nx">makeReturn</span> <span class="nx">res</span> <span class="k">if</span> <span class="nx">@recovery</span>
<span class="k">this</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>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="nv">compileNode: </span><span class="nf">(o) -&gt;</span>
<span class="nx">o</span><span class="p">.</span><span class="nx">indent</span> <span class="o">+=</span> <span class="nx">TAB</span>
<span class="nv">tryPart = </span><span class="nx">@attempt</span><span class="p">.</span><span class="nx">compileToFragments</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_TOP</span>
<span class="nv">catchPart = </span><span class="k">if</span> <span class="nx">@recovery</span>
<span class="nv">placeholder = </span><span class="k">new</span> <span class="nx">Literal</span> <span class="s">&#39;_error&#39;</span>
<span class="nx">@recovery</span><span class="p">.</span><span class="nx">unshift</span> <span class="k">new</span> <span class="nx">Assign</span> <span class="nx">@errorVariable</span><span class="p">,</span> <span class="nx">placeholder</span>
<span class="vi">@errorVariable = </span><span class="nx">placeholder</span>
<span class="k">if</span> <span class="nx">@errorVariable</span><span class="p">.</span><span class="nx">value</span> <span class="k">in</span> <span class="nx">STRICT_PROSCRIBED</span>
<span class="nx">@errorVariable</span><span class="p">.</span><span class="nx">error</span> <span class="s">&quot;catch variable may not be \&quot;</span><span class="si">#{</span><span class="nx">@errorVariable</span><span class="p">.</span><span class="nx">value</span><span class="si">}</span><span class="s">\&quot;&quot;</span>
<span class="p">[].</span><span class="nx">concat</span> <span class="nx">@makeCode</span><span class="p">(</span><span class="s">&quot; catch (&quot;</span><span class="p">),</span> <span class="nx">@errorVariable</span><span class="p">.</span><span class="nx">compileToFragments</span><span class="p">(</span><span class="nx">o</span><span class="p">),</span> <span class="nx">@makeCode</span><span class="p">(</span><span class="s">&quot;) {\n&quot;</span><span class="p">),</span>
<span class="nx">@recovery</span><span class="p">.</span><span class="nx">compileToFragments</span><span class="p">(</span><span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_TOP</span><span class="p">),</span> <span class="nx">@makeCode</span><span class="p">(</span><span class="s">&quot;\n</span><span class="si">#{</span><span class="nx">@tab</span><span class="si">}</span><span class="s">}&quot;</span><span class="p">)</span>
<span class="k">else</span> <span class="k">unless</span> <span class="nx">@ensure</span> <span class="o">or</span> <span class="nx">@recovery</span>
<span class="p">[</span><span class="nx">@makeCode</span><span class="p">(</span><span class="s">&#39; catch (_error) {}&#39;</span><span class="p">)]</span>
<span class="k">else</span>
<span class="p">[]</span>
<span class="nv">ensurePart = </span><span class="k">if</span> <span class="nx">@ensure</span> <span class="k">then</span> <span class="p">([].</span><span class="nx">concat</span> <span class="nx">@makeCode</span><span class="p">(</span><span class="s">&quot; finally {\n&quot;</span><span class="p">),</span> <span class="p">(</span><span class="nx">@ensure</span><span class="p">.</span><span class="nx">compileToFragments</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_TOP</span><span class="p">),</span> <span class="nx">@makeCode</span><span class="p">(</span><span class="s">&quot;\n</span><span class="si">#{</span><span class="nx">@tab</span><span class="si">}</span><span class="s">}&quot;</span><span class="p">))</span> <span class="k">else</span> <span class="p">[]</span>
<span class="p">[].</span><span class="nx">concat</span> <span class="nx">@makeCode</span><span class="p">(</span><span class="s">&quot;</span><span class="si">#{</span><span class="nx">@tab</span><span class="si">}</span><span class="s">try {\n&quot;</span><span class="p">),</span>
<span class="nx">tryPart</span><span class="p">,</span>
<span class="nx">@makeCode</span><span class="p">(</span><span class="s">&quot;\n</span><span class="si">#{</span><span class="nx">@tab</span><span class="si">}</span><span class="s">}&quot;</span><span class="p">),</span> <span class="nx">catchPart</span><span class="p">,</span> <span class="nx">ensurePart</span></pre></div></div>
</li>
<li id="section-116">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-116">&#182;</a>
</div>
<h3>Throw</h3>
<p>Simple node to throw an exception.
</p>
</div>
<div class="content"><div class="highlight"><pre><span class="nv">exports.Throw = </span><span class="k">class</span> <span class="nx">Throw</span> <span class="k">extends</span> <span class="nx">Base</span>
<span class="nv">constructor: </span><span class="nf">(@expression) -&gt;</span>
<span class="nv">children: </span><span class="p">[</span><span class="s">&#39;expression&#39;</span><span class="p">]</span>
<span class="nv">isStatement: </span><span class="nx">YES</span>
<span class="nv">jumps: </span> <span class="nx">NO</span></pre></div></div>
</li>
<li id="section-117">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-117">&#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="nv">makeReturn: </span><span class="nx">THIS</span>
<span class="nv">compileNode: </span><span class="nf">(o) -&gt;</span>
<span class="p">[].</span><span class="nx">concat</span> <span class="nx">@makeCode</span><span class="p">(</span><span class="nx">@tab</span> <span class="o">+</span> <span class="s">&quot;throw &quot;</span><span class="p">),</span> <span class="p">(</span><span class="nx">@expression</span><span class="p">.</span><span class="nx">compileToFragments</span> <span class="nx">o</span><span class="p">),</span> <span class="nx">@makeCode</span><span class="p">(</span><span class="s">&quot;;&quot;</span><span class="p">)</span></pre></div></div>
</li>
<li id="section-118">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-118">&#182;</a>
</div>
<h3>Existence</h3>
<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="nv">exports.Existence = </span><span class="k">class</span> <span class="nx">Existence</span> <span class="k">extends</span> <span class="nx">Base</span>
<span class="nv">constructor: </span><span class="nf">(@expression) -&gt;</span>
<span class="nv">children: </span><span class="p">[</span><span class="s">&#39;expression&#39;</span><span class="p">]</span>
<span class="nv">invert: </span><span class="nx">NEGATE</span>
<span class="nv">compileNode: </span><span class="nf">(o) -&gt;</span>
<span class="vi">@expression.front = </span><span class="nx">@front</span>
<span class="nv">code = </span><span class="nx">@expression</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_OP</span>
<span class="k">if</span> <span class="nx">IDENTIFIER</span><span class="p">.</span><span class="nx">test</span><span class="p">(</span><span class="nx">code</span><span class="p">)</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">check</span> <span class="nx">code</span>
<span class="p">[</span><span class="nx">cmp</span><span class="p">,</span> <span class="nx">cnj</span><span class="p">]</span> <span class="o">=</span> <span class="k">if</span> <span class="nx">@negated</span> <span class="k">then</span> <span class="p">[</span><span class="s">&#39;===&#39;</span><span class="p">,</span> <span class="s">&#39;||&#39;</span><span class="p">]</span> <span class="k">else</span> <span class="p">[</span><span class="s">&#39;!==&#39;</span><span class="p">,</span> <span class="s">&#39;&amp;&amp;&#39;</span><span class="p">]</span>
<span class="nv">code = </span><span class="s">&quot;typeof </span><span class="si">#{</span><span class="nx">code</span><span class="si">}</span><span class="s"> </span><span class="si">#{</span><span class="nx">cmp</span><span class="si">}</span><span class="s"> \&quot;undefined\&quot; </span><span class="si">#{</span><span class="nx">cnj</span><span class="si">}</span><span class="s"> </span><span class="si">#{</span><span class="nx">code</span><span class="si">}</span><span class="s"> </span><span class="si">#{</span><span class="nx">cmp</span><span class="si">}</span><span class="s"> null&quot;</span>
<span class="k">else</span></pre></div></div>
</li>
<li id="section-119">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-119">&#182;</a>
</div>
<p>do not use strict equality here; it will break existing code
</p>
</div>
<div class="content"><div class="highlight"><pre> <span class="nv">code = </span><span class="s">&quot;</span><span class="si">#{</span><span class="nx">code</span><span class="si">}</span><span class="s"> </span><span class="si">#{</span><span class="k">if</span> <span class="nx">@negated</span> <span class="k">then</span> <span class="s">&#39;==&#39;</span> <span class="k">else</span> <span class="s">&#39;!=&#39;</span><span class="si">}</span><span class="s"> null&quot;</span>
<span class="p">[</span><span class="nx">@makeCode</span><span class="p">(</span><span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">level</span> <span class="o">&lt;=</span> <span class="nx">LEVEL_COND</span> <span class="k">then</span> <span class="nx">code</span> <span class="k">else</span> <span class="s">&quot;(</span><span class="si">#{</span><span class="nx">code</span><span class="si">}</span><span class="s">)&quot;</span><span class="p">)]</span></pre></div></div>
</li>
<li id="section-120">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-120">&#182;</a>
</div>
<h3>Parens</h3>
<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="nv">exports.Parens = </span><span class="k">class</span> <span class="nx">Parens</span> <span class="k">extends</span> <span class="nx">Base</span>
<span class="nv">constructor: </span><span class="nf">(@body) -&gt;</span>
<span class="nv">children: </span><span class="p">[</span><span class="s">&#39;body&#39;</span><span class="p">]</span>
<span class="nv">unwrap : </span><span class="nf">-&gt;</span> <span class="nx">@body</span>
<span class="nv">isComplex : </span><span class="nf">-&gt;</span> <span class="nx">@body</span><span class="p">.</span><span class="nx">isComplex</span><span class="p">()</span>
<span class="nv">compileNode: </span><span class="nf">(o) -&gt;</span>
<span class="nv">expr = </span><span class="nx">@body</span><span class="p">.</span><span class="nx">unwrap</span><span class="p">()</span>
<span class="k">if</span> <span class="nx">expr</span> <span class="k">instanceof</span> <span class="nx">Value</span> <span class="o">and</span> <span class="nx">expr</span><span class="p">.</span><span class="nx">isAtomic</span><span class="p">()</span>
<span class="nv">expr.front = </span><span class="nx">@front</span>
<span class="k">return</span> <span class="nx">expr</span><span class="p">.</span><span class="nx">compileToFragments</span> <span class="nx">o</span>
<span class="nv">fragments = </span><span class="nx">expr</span><span class="p">.</span><span class="nx">compileToFragments</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_PAREN</span>
<span class="nv">bare = </span><span class="nx">o</span><span class="p">.</span><span class="nx">level</span> <span class="o">&lt;</span> <span class="nx">LEVEL_OP</span> <span class="o">and</span> <span class="p">(</span><span class="nx">expr</span> <span class="k">instanceof</span> <span class="nx">Op</span> <span class="o">or</span> <span class="nx">expr</span> <span class="k">instanceof</span> <span class="nx">Call</span> <span class="o">or</span>
<span class="p">(</span><span class="nx">expr</span> <span class="k">instanceof</span> <span class="nx">For</span> <span class="o">and</span> <span class="nx">expr</span><span class="p">.</span><span class="nx">returns</span><span class="p">))</span>
<span class="k">if</span> <span class="nx">bare</span> <span class="k">then</span> <span class="nx">fragments</span> <span class="k">else</span> <span class="nx">@wrapInBraces</span> <span class="nx">fragments</span></pre></div></div>
</li>
<li id="section-121">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-121">&#182;</a>
</div>
<h3>For</h3>
<p>CoffeeScript&#39;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="nv">exports.For = </span><span class="k">class</span> <span class="nx">For</span> <span class="k">extends</span> <span class="nx">While</span>
<span class="nv">constructor: </span><span class="nf">(body, source) -&gt;</span>
<span class="p">{</span><span class="nx">@source</span><span class="p">,</span> <span class="nx">@guard</span><span class="p">,</span> <span class="nx">@step</span><span class="p">,</span> <span class="nx">@name</span><span class="p">,</span> <span class="nx">@index</span><span class="p">}</span> <span class="o">=</span> <span class="nx">source</span>
<span class="vi">@body = </span><span class="nx">Block</span><span class="p">.</span><span class="nx">wrap</span> <span class="p">[</span><span class="nx">body</span><span class="p">]</span>
<span class="vi">@own = </span><span class="o">!!</span><span class="nx">source</span><span class="p">.</span><span class="nx">own</span>
<span class="vi">@object = </span><span class="o">!!</span><span class="nx">source</span><span class="p">.</span><span class="nx">object</span>
<span class="p">[</span><span class="nx">@name</span><span class="p">,</span> <span class="nx">@index</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="nx">@index</span><span class="p">,</span> <span class="nx">@name</span><span class="p">]</span> <span class="k">if</span> <span class="nx">@object</span>
<span class="nx">@index</span><span class="p">.</span><span class="nx">error</span> <span class="s">&#39;index cannot be a pattern matching expression&#39;</span> <span class="k">if</span> <span class="nx">@index</span> <span class="k">instanceof</span> <span class="nx">Value</span>
<span class="vi">@range = </span><span class="nx">@source</span> <span class="k">instanceof</span> <span class="nx">Value</span> <span class="o">and</span> <span class="nx">@source</span><span class="p">.</span><span class="nx">base</span> <span class="k">instanceof</span> <span class="nx">Range</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">@source</span><span class="p">.</span><span class="nx">properties</span><span class="p">.</span><span class="nx">length</span>
<span class="vi">@pattern = </span><span class="nx">@name</span> <span class="k">instanceof</span> <span class="nx">Value</span>
<span class="nx">@index</span><span class="p">.</span><span class="nx">error</span> <span class="s">&#39;indexes do not apply to range loops&#39;</span> <span class="k">if</span> <span class="nx">@range</span> <span class="o">and</span> <span class="nx">@index</span>
<span class="nx">@name</span><span class="p">.</span><span class="nx">error</span> <span class="s">&#39;cannot pattern match over range loops&#39;</span> <span class="k">if</span> <span class="nx">@range</span> <span class="o">and</span> <span class="nx">@pattern</span>
<span class="vi">@returns = </span><span class="kc">false</span>
<span class="nv">children: </span><span class="p">[</span><span class="s">&#39;body&#39;</span><span class="p">,</span> <span class="s">&#39;source&#39;</span><span class="p">,</span> <span class="s">&#39;guard&#39;</span><span class="p">,</span> <span class="s">&#39;step&#39;</span><span class="p">]</span></pre></div></div>
</li>
<li id="section-122">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-122">&#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="nv">compileNode: </span><span class="nf">(o) -&gt;</span>
<span class="nv">body = </span><span class="nx">Block</span><span class="p">.</span><span class="nx">wrap</span> <span class="p">[</span><span class="nx">@body</span><span class="p">]</span>
<span class="nv">lastJumps = </span><span class="nx">last</span><span class="p">(</span><span class="nx">body</span><span class="p">.</span><span class="nx">expressions</span><span class="p">)</span><span class="o">?</span><span class="p">.</span><span class="nx">jumps</span><span class="p">()</span>
<span class="vi">@returns = </span><span class="kc">no</span> <span class="k">if</span> <span class="nx">lastJumps</span> <span class="o">and</span> <span class="nx">lastJumps</span> <span class="k">instanceof</span> <span class="nx">Return</span>
<span class="nv">source = </span><span class="k">if</span> <span class="nx">@range</span> <span class="k">then</span> <span class="nx">@source</span><span class="p">.</span><span class="nx">base</span> <span class="k">else</span> <span class="nx">@source</span>
<span class="nv">scope = </span><span class="nx">o</span><span class="p">.</span><span class="nx">scope</span>
<span class="nv">name = </span><span class="nx">@name</span> <span class="o">and</span> <span class="p">(</span><span class="nx">@name</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_LIST</span><span class="p">)</span>
<span class="nv">index = </span><span class="nx">@index</span> <span class="o">and</span> <span class="p">(</span><span class="nx">@index</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_LIST</span><span class="p">)</span>
<span class="nx">scope</span><span class="p">.</span><span class="nx">find</span><span class="p">(</span><span class="nx">name</span><span class="p">)</span> <span class="k">if</span> <span class="nx">name</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">@pattern</span>
<span class="nx">scope</span><span class="p">.</span><span class="nx">find</span><span class="p">(</span><span class="nx">index</span><span class="p">)</span> <span class="k">if</span> <span class="nx">index</span>
<span class="nv">rvar = </span><span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span> <span class="s">&#39;results&#39;</span> <span class="k">if</span> <span class="nx">@returns</span>
<span class="nv">ivar = </span><span class="p">(</span><span class="nx">@object</span> <span class="o">and</span> <span class="nx">index</span><span class="p">)</span> <span class="o">or</span> <span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span> <span class="s">&#39;i&#39;</span>
<span class="nv">kvar = </span><span class="p">(</span><span class="nx">@range</span> <span class="o">and</span> <span class="nx">name</span><span class="p">)</span> <span class="o">or</span> <span class="nx">index</span> <span class="o">or</span> <span class="nx">ivar</span>
<span class="nv">kvarAssign = </span><span class="k">if</span> <span class="nx">kvar</span> <span class="o">isnt</span> <span class="nx">ivar</span> <span class="k">then</span> <span class="s">&quot;</span><span class="si">#{</span><span class="nx">kvar</span><span class="si">}</span><span class="s"> = &quot;</span> <span class="k">else</span> <span class="s">&quot;&quot;</span>
<span class="k">if</span> <span class="nx">@step</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">@range</span>
<span class="p">[</span><span class="nx">step</span><span class="p">,</span> <span class="nx">stepVar</span><span class="p">]</span> <span class="o">=</span> <span class="nx">@cacheToCodeFragments</span> <span class="nx">@step</span><span class="p">.</span><span class="nx">cache</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_LIST</span>
<span class="nv">stepNum = </span><span class="nx">stepVar</span><span class="p">.</span><span class="nx">match</span> <span class="nx">SIMPLENUM</span>
<span class="nv">name = </span><span class="nx">ivar</span> <span class="k">if</span> <span class="nx">@pattern</span>
<span class="nv">varPart = </span><span class="s">&#39;&#39;</span>
<span class="nv">guardPart = </span><span class="s">&#39;&#39;</span>
<span class="nv">defPart = </span><span class="s">&#39;&#39;</span>
<span class="nv">idt1 = </span><span class="nx">@tab</span> <span class="o">+</span> <span class="nx">TAB</span>
<span class="k">if</span> <span class="nx">@range</span>
<span class="nv">forPartFragments = </span><span class="nx">source</span><span class="p">.</span><span class="nx">compileToFragments</span> <span class="nx">merge</span><span class="p">(</span><span class="nx">o</span><span class="p">,</span> <span class="p">{</span><span class="nv">index: </span><span class="nx">ivar</span><span class="p">,</span> <span class="nx">name</span><span class="p">,</span> <span class="nx">@step</span><span class="p">})</span>
<span class="k">else</span>
<span class="nv">svar = </span><span class="nx">@source</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_LIST</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">name</span> <span class="o">or</span> <span class="nx">@</span><span class="k">own</span><span class="p">)</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">IDENTIFIER</span><span class="p">.</span><span class="nx">test</span> <span class="nx">svar</span>
<span class="nx">defPart</span> <span class="o">+=</span> <span class="s">&quot;</span><span class="si">#{</span><span class="nx">@tab</span><span class="si">}#{</span><span class="nv">ref = </span><span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span> <span class="s">&#39;ref&#39;</span><span class="si">}</span><span class="s"> = </span><span class="si">#{</span><span class="nx">svar</span><span class="si">}</span><span class="s">;\n&quot;</span>
<span class="nv">svar = </span><span class="nx">ref</span>
<span class="k">if</span> <span class="nx">name</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">@pattern</span>
<span class="nv">namePart = </span><span class="s">&quot;</span><span class="si">#{</span><span class="nx">name</span><span class="si">}</span><span class="s"> = </span><span class="si">#{</span><span class="nx">svar</span><span class="si">}</span><span class="s">[</span><span class="si">#{</span><span class="nx">kvar</span><span class="si">}</span><span class="s">]&quot;</span>
<span class="k">if</span> <span class="o">not</span> <span class="nx">@object</span>
<span class="nx">defPart</span> <span class="o">+=</span> <span class="s">&quot;</span><span class="si">#{</span><span class="nx">@tab</span><span class="si">}#{</span><span class="nx">step</span><span class="si">}</span><span class="s">;\n&quot;</span> <span class="k">if</span> <span class="nx">step</span> <span class="o">isnt</span> <span class="nx">stepVar</span>
<span class="nv">lvar = </span><span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span> <span class="s">&#39;len&#39;</span> <span class="k">unless</span> <span class="nx">@step</span> <span class="o">and</span> <span class="nx">stepNum</span> <span class="o">and</span> <span class="nv">down = </span><span class="p">(</span><span class="o">+</span><span class="nx">stepNum</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">)</span>
<span class="nv">declare = </span><span class="s">&quot;</span><span class="si">#{</span><span class="nx">kvarAssign</span><span class="si">}#{</span><span class="nx">ivar</span><span class="si">}</span><span class="s"> = 0, </span><span class="si">#{</span><span class="nx">lvar</span><span class="si">}</span><span class="s"> = </span><span class="si">#{</span><span class="nx">svar</span><span class="si">}</span><span class="s">.length&quot;</span>
<span class="nv">declareDown = </span><span class="s">&quot;</span><span class="si">#{</span><span class="nx">kvarAssign</span><span class="si">}#{</span><span class="nx">ivar</span><span class="si">}</span><span class="s"> = </span><span class="si">#{</span><span class="nx">svar</span><span class="si">}</span><span class="s">.length - 1&quot;</span>
<span class="nv">compare = </span><span class="s">&quot;</span><span class="si">#{</span><span class="nx">ivar</span><span class="si">}</span><span class="s"> &lt; </span><span class="si">#{</span><span class="nx">lvar</span><span class="si">}</span><span class="s">&quot;</span>
<span class="nv">compareDown = </span><span class="s">&quot;</span><span class="si">#{</span><span class="nx">ivar</span><span class="si">}</span><span class="s"> &gt;= 0&quot;</span>
<span class="k">if</span> <span class="nx">@step</span>
<span class="k">if</span> <span class="nx">stepNum</span>
<span class="k">if</span> <span class="nx">down</span>
<span class="nv">compare = </span><span class="nx">compareDown</span>
<span class="nv">declare = </span><span class="nx">declareDown</span>
<span class="k">else</span>
<span class="nv">compare = </span><span class="s">&quot;</span><span class="si">#{</span><span class="nx">stepVar</span><span class="si">}</span><span class="s"> &gt; 0 ? </span><span class="si">#{</span><span class="nx">compare</span><span class="si">}</span><span class="s"> : </span><span class="si">#{</span><span class="nx">compareDown</span><span class="si">}</span><span class="s">&quot;</span>
<span class="nv">declare = </span><span class="s">&quot;(</span><span class="si">#{</span><span class="nx">stepVar</span><span class="si">}</span><span class="s"> &gt; 0 ? (</span><span class="si">#{</span><span class="nx">declare</span><span class="si">}</span><span class="s">) : </span><span class="si">#{</span><span class="nx">declareDown</span><span class="si">}</span><span class="s">)&quot;</span>
<span class="nv">increment = </span><span class="s">&quot;</span><span class="si">#{</span><span class="nx">ivar</span><span class="si">}</span><span class="s"> += </span><span class="si">#{</span><span class="nx">stepVar</span><span class="si">}</span><span class="s">&quot;</span>
<span class="k">else</span>
<span class="nv">increment = </span><span class="s">&quot;</span><span class="si">#{</span><span class="k">if</span> <span class="nx">kvar</span> <span class="o">isnt</span> <span class="nx">ivar</span> <span class="k">then</span> <span class="s">&quot;++</span><span class="si">#{</span><span class="nx">ivar</span><span class="si">}</span><span class="s">&quot;</span> <span class="k">else</span> <span class="s">&quot;</span><span class="si">#{</span><span class="nx">ivar</span><span class="si">}</span><span class="s">++&quot;</span><span class="si">}</span><span class="s">&quot;</span>
<span class="nv">forPartFragments = </span><span class="p">[</span><span class="nx">@makeCode</span><span class="p">(</span><span class="s">&quot;</span><span class="si">#{</span><span class="nx">declare</span><span class="si">}</span><span class="s">; </span><span class="si">#{</span><span class="nx">compare</span><span class="si">}</span><span class="s">; </span><span class="si">#{</span><span class="nx">kvarAssign</span><span class="si">}#{</span><span class="nx">increment</span><span class="si">}</span><span class="s">&quot;</span><span class="p">)]</span>
<span class="k">if</span> <span class="nx">@returns</span>
<span class="nv">resultPart = </span><span class="s">&quot;</span><span class="si">#{</span><span class="nx">@tab</span><span class="si">}#{</span><span class="nx">rvar</span><span class="si">}</span><span class="s"> = [];\n&quot;</span>
<span class="nv">returnResult = </span><span class="s">&quot;\n</span><span class="si">#{</span><span class="nx">@tab</span><span class="si">}</span><span class="s">return </span><span class="si">#{</span><span class="nx">rvar</span><span class="si">}</span><span class="s">;&quot;</span>
<span class="nx">body</span><span class="p">.</span><span class="nx">makeReturn</span> <span class="nx">rvar</span>
<span class="k">if</span> <span class="nx">@guard</span>
<span class="k">if</span> <span class="nx">body</span><span class="p">.</span><span class="nx">expressions</span><span class="p">.</span><span class="nx">length</span> <span class="o">&gt;</span> <span class="mi">1</span>
<span class="nx">body</span><span class="p">.</span><span class="nx">expressions</span><span class="p">.</span><span class="nx">unshift</span> <span class="k">new</span> <span class="nx">If</span> <span class="p">(</span><span class="k">new</span> <span class="nx">Parens</span> <span class="nx">@guard</span><span class="p">).</span><span class="nx">invert</span><span class="p">(),</span> <span class="k">new</span> <span class="nx">Literal</span> <span class="s">&quot;continue&quot;</span>
<span class="k">else</span>
<span class="nv">body = </span><span class="nx">Block</span><span class="p">.</span><span class="nx">wrap</span> <span class="p">[</span><span class="k">new</span> <span class="nx">If</span> <span class="nx">@guard</span><span class="p">,</span> <span class="nx">body</span><span class="p">]</span> <span class="k">if</span> <span class="nx">@guard</span>
<span class="k">if</span> <span class="nx">@pattern</span>
<span class="nx">body</span><span class="p">.</span><span class="nx">expressions</span><span class="p">.</span><span class="nx">unshift</span> <span class="k">new</span> <span class="nx">Assign</span> <span class="nx">@name</span><span class="p">,</span> <span class="k">new</span> <span class="nx">Literal</span> <span class="s">&quot;</span><span class="si">#{</span><span class="nx">svar</span><span class="si">}</span><span class="s">[</span><span class="si">#{</span><span class="nx">kvar</span><span class="si">}</span><span class="s">]&quot;</span>
<span class="nv">defPartFragments = </span><span class="p">[].</span><span class="nx">concat</span> <span class="nx">@makeCode</span><span class="p">(</span><span class="nx">defPart</span><span class="p">),</span> <span class="nx">@pluckDirectCall</span><span class="p">(</span><span class="nx">o</span><span class="p">,</span> <span class="nx">body</span><span class="p">)</span>
<span class="nv">varPart = </span><span class="s">&quot;\n</span><span class="si">#{</span><span class="nx">idt1</span><span class="si">}#{</span><span class="nx">namePart</span><span class="si">}</span><span class="s">;&quot;</span> <span class="k">if</span> <span class="nx">namePart</span>
<span class="k">if</span> <span class="nx">@object</span>
<span class="nv">forPartFragments = </span><span class="p">[</span><span class="nx">@makeCode</span><span class="p">(</span><span class="s">&quot;</span><span class="si">#{</span><span class="nx">kvar</span><span class="si">}</span><span class="s"> in </span><span class="si">#{</span><span class="nx">svar</span><span class="si">}</span><span class="s">&quot;</span><span class="p">)]</span>
<span class="nv">guardPart = </span><span class="s">&quot;\n</span><span class="si">#{</span><span class="nx">idt1</span><span class="si">}</span><span class="s">if (!</span><span class="si">#{</span><span class="nx">utility</span> <span class="s">&#39;hasProp&#39;</span><span class="si">}</span><span class="s">.call(</span><span class="si">#{</span><span class="nx">svar</span><span class="si">}</span><span class="s">, </span><span class="si">#{</span><span class="nx">kvar</span><span class="si">}</span><span class="s">)) continue;&quot;</span> <span class="k">if</span> <span class="nx">@</span><span class="k">own</span>
<span class="nv">bodyFragments = </span><span class="nx">body</span><span class="p">.</span><span class="nx">compileToFragments</span> <span class="nx">merge</span><span class="p">(</span><span class="nx">o</span><span class="p">,</span> <span class="nv">indent: </span><span class="nx">idt1</span><span class="p">),</span> <span class="nx">LEVEL_TOP</span>
<span class="k">if</span> <span class="nx">bodyFragments</span> <span class="o">and</span> <span class="p">(</span><span class="nx">bodyFragments</span><span class="p">.</span><span class="nx">length</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span>
<span class="nv">bodyFragments = </span><span class="p">[].</span><span class="nx">concat</span> <span class="nx">@makeCode</span><span class="p">(</span><span class="s">&quot;\n&quot;</span><span class="p">),</span> <span class="nx">bodyFragments</span><span class="p">,</span> <span class="nx">@makeCode</span><span class="p">(</span><span class="s">&quot;\n&quot;</span><span class="p">)</span>
<span class="p">[].</span><span class="nx">concat</span> <span class="nx">defPartFragments</span><span class="p">,</span> <span class="nx">@makeCode</span><span class="p">(</span><span class="s">&quot;</span><span class="si">#{</span><span class="nx">resultPart</span> <span class="o">or</span> <span class="s">&#39;&#39;</span><span class="si">}#{</span><span class="nx">@tab</span><span class="si">}</span><span class="s">for (&quot;</span><span class="p">),</span>
<span class="nx">forPartFragments</span><span class="p">,</span> <span class="nx">@makeCode</span><span class="p">(</span><span class="s">&quot;) {</span><span class="si">#{</span><span class="nx">guardPart</span><span class="si">}#{</span><span class="nx">varPart</span><span class="si">}</span><span class="s">&quot;</span><span class="p">),</span> <span class="nx">bodyFragments</span><span class="p">,</span>
<span class="nx">@makeCode</span><span class="p">(</span><span class="s">&quot;</span><span class="si">#{</span><span class="nx">@tab</span><span class="si">}</span><span class="s">}</span><span class="si">#{</span><span class="nx">returnResult</span> <span class="o">or</span> <span class="s">&#39;&#39;</span><span class="si">}</span><span class="s">&quot;</span><span class="p">)</span>
<span class="nv">pluckDirectCall: </span><span class="nf">(o, body) -&gt;</span>
<span class="nv">defs = </span><span class="p">[]</span>
<span class="k">for</span> <span class="nx">expr</span><span class="p">,</span> <span class="nx">idx</span> <span class="k">in</span> <span class="nx">body</span><span class="p">.</span><span class="nx">expressions</span>
<span class="nv">expr = </span><span class="nx">expr</span><span class="p">.</span><span class="nx">unwrapAll</span><span class="p">()</span>
<span class="k">continue</span> <span class="k">unless</span> <span class="nx">expr</span> <span class="k">instanceof</span> <span class="nx">Call</span>
<span class="nv">val = </span><span class="nx">expr</span><span class="p">.</span><span class="nx">variable</span><span class="p">.</span><span class="nx">unwrapAll</span><span class="p">()</span>
<span class="k">continue</span> <span class="k">unless</span> <span class="p">(</span><span class="nx">val</span> <span class="k">instanceof</span> <span class="nx">Code</span><span class="p">)</span> <span class="o">or</span>
<span class="p">(</span><span class="nx">val</span> <span class="k">instanceof</span> <span class="nx">Value</span> <span class="o">and</span>
<span class="nx">val</span><span class="p">.</span><span class="nx">base</span><span class="o">?</span><span class="p">.</span><span class="nx">unwrapAll</span><span class="p">()</span> <span class="k">instanceof</span> <span class="nx">Code</span> <span class="o">and</span>
<span class="nx">val</span><span class="p">.</span><span class="nx">properties</span><span class="p">.</span><span class="nx">length</span> <span class="o">is</span> <span class="mi">1</span> <span class="o">and</span>
<span class="nx">val</span><span class="p">.</span><span class="nx">properties</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nx">name</span><span class="o">?</span><span class="p">.</span><span class="nx">value</span> <span class="k">in</span> <span class="p">[</span><span class="s">&#39;call&#39;</span><span class="p">,</span> <span class="s">&#39;apply&#39;</span><span class="p">])</span>
<span class="nv">fn = </span><span class="nx">val</span><span class="p">.</span><span class="nx">base</span><span class="o">?</span><span class="p">.</span><span class="nx">unwrapAll</span><span class="p">()</span> <span class="o">or</span> <span class="nx">val</span>
<span class="nv">ref = </span><span class="k">new</span> <span class="nx">Literal</span> <span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span> <span class="s">&#39;fn&#39;</span>
<span class="nv">base = </span><span class="k">new</span> <span class="nx">Value</span> <span class="nx">ref</span>
<span class="k">if</span> <span class="nx">val</span><span class="p">.</span><span class="nx">base</span>
<span class="p">[</span><span class="nx">val</span><span class="p">.</span><span class="nx">base</span><span class="p">,</span> <span class="nx">base</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="nx">base</span><span class="p">,</span> <span class="nx">val</span><span class="p">]</span>
<span class="nx">body</span><span class="p">.</span><span class="nx">expressions</span><span class="p">[</span><span class="nx">idx</span><span class="p">]</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Call</span> <span class="nx">base</span><span class="p">,</span> <span class="nx">expr</span><span class="p">.</span><span class="nx">args</span>
<span class="nv">defs = </span><span class="nx">defs</span><span class="p">.</span><span class="nx">concat</span> <span class="nx">@makeCode</span><span class="p">(</span><span class="nx">@tab</span><span class="p">),</span> <span class="p">(</span><span class="k">new</span> <span class="nx">Assign</span><span class="p">(</span><span class="nx">ref</span><span class="p">,</span> <span class="nx">fn</span><span class="p">).</span><span class="nx">compileToFragments</span><span class="p">(</span><span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_TOP</span><span class="p">)),</span> <span class="nx">@makeCode</span><span class="p">(</span><span class="s">&#39;;\n&#39;</span><span class="p">)</span>
<span class="nx">defs</span></pre></div></div>
</li>
<li id="section-123">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-123">&#182;</a>
</div>
<h3>Switch</h3>
<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="nv">exports.Switch = </span><span class="k">class</span> <span class="nx">Switch</span> <span class="k">extends</span> <span class="nx">Base</span>
<span class="nv">constructor: </span><span class="nf">(@subject, @cases, @otherwise) -&gt;</span>
<span class="nv">children: </span><span class="p">[</span><span class="s">&#39;subject&#39;</span><span class="p">,</span> <span class="s">&#39;cases&#39;</span><span class="p">,</span> <span class="s">&#39;otherwise&#39;</span><span class="p">]</span>
<span class="nv">isStatement: </span><span class="nx">YES</span>
<span class="nv">jumps: </span><span class="nf">(o = {block: yes}) -&gt;</span>
<span class="k">for</span> <span class="p">[</span><span class="nx">conds</span><span class="p">,</span> <span class="nx">block</span><span class="p">]</span> <span class="k">in</span> <span class="nx">@cases</span>
<span class="k">return</span> <span class="nx">block</span> <span class="k">if</span> <span class="nx">block</span><span class="p">.</span><span class="nx">jumps</span> <span class="nx">o</span>
<span class="nx">@otherwise</span><span class="o">?</span><span class="p">.</span><span class="nx">jumps</span> <span class="nx">o</span>
<span class="nv">makeReturn: </span><span class="nf">(res) -&gt;</span>
<span class="nx">pair</span><span class="p">[</span><span class="mi">1</span><span class="p">].</span><span class="nx">makeReturn</span> <span class="nx">res</span> <span class="k">for</span> <span class="nx">pair</span> <span class="k">in</span> <span class="nx">@cases</span>
<span class="nx">@otherwise</span> <span class="o">or=</span> <span class="k">new</span> <span class="nx">Block</span> <span class="p">[</span><span class="k">new</span> <span class="nx">Literal</span> <span class="s">&#39;void 0&#39;</span><span class="p">]</span> <span class="k">if</span> <span class="nx">res</span>
<span class="nx">@otherwise</span><span class="o">?</span><span class="p">.</span><span class="nx">makeReturn</span> <span class="nx">res</span>
<span class="k">this</span>
<span class="nv">compileNode: </span><span class="nf">(o) -&gt;</span>
<span class="nv">idt1 = </span><span class="nx">o</span><span class="p">.</span><span class="nx">indent</span> <span class="o">+</span> <span class="nx">TAB</span>
<span class="nv">idt2 = o.indent = </span><span class="nx">idt1</span> <span class="o">+</span> <span class="nx">TAB</span>
<span class="nv">fragments = </span><span class="p">[].</span><span class="nx">concat</span> <span class="nx">@makeCode</span><span class="p">(</span><span class="nx">@tab</span> <span class="o">+</span> <span class="s">&quot;switch (&quot;</span><span class="p">),</span>
<span class="p">(</span><span class="k">if</span> <span class="nx">@subject</span> <span class="k">then</span> <span class="nx">@subject</span><span class="p">.</span><span class="nx">compileToFragments</span><span class="p">(</span><span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_PAREN</span><span class="p">)</span> <span class="k">else</span> <span class="nx">@makeCode</span><span class="p">(</span><span class="s">&quot;false&quot;</span><span class="p">)),</span>
<span class="nx">@makeCode</span><span class="p">(</span><span class="s">&quot;) {\n&quot;</span><span class="p">)</span>
<span class="k">for</span> <span class="p">[</span><span class="nx">conditions</span><span class="p">,</span> <span class="nx">block</span><span class="p">],</span> <span class="nx">i</span> <span class="k">in</span> <span class="nx">@cases</span>
<span class="k">for</span> <span class="nx">cond</span> <span class="k">in</span> <span class="nx">flatten</span> <span class="p">[</span><span class="nx">conditions</span><span class="p">]</span>
<span class="nv">cond = </span><span class="nx">cond</span><span class="p">.</span><span class="nx">invert</span><span class="p">()</span> <span class="k">unless</span> <span class="nx">@subject</span>
<span class="nv">fragments = </span><span class="nx">fragments</span><span class="p">.</span><span class="nx">concat</span> <span class="nx">@makeCode</span><span class="p">(</span><span class="nx">idt1</span> <span class="o">+</span> <span class="s">&quot;case &quot;</span><span class="p">),</span> <span class="nx">cond</span><span class="p">.</span><span class="nx">compileToFragments</span><span class="p">(</span><span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_PAREN</span><span class="p">),</span> <span class="nx">@makeCode</span><span class="p">(</span><span class="s">&quot;:\n&quot;</span><span class="p">)</span>
<span class="nv">fragments = </span><span class="nx">fragments</span><span class="p">.</span><span class="nx">concat</span> <span class="nx">body</span><span class="p">,</span> <span class="nx">@makeCode</span><span class="p">(</span><span class="s">&#39;\n&#39;</span><span class="p">)</span> <span class="k">if</span> <span class="p">(</span><span class="nv">body = </span><span class="nx">block</span><span class="p">.</span><span class="nx">compileToFragments</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_TOP</span><span class="p">).</span><span class="nx">length</span> <span class="o">&gt;</span> <span class="mi">0</span>
<span class="k">break</span> <span class="k">if</span> <span class="nx">i</span> <span class="o">is</span> <span class="nx">@cases</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="mi">1</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">@otherwise</span>
<span class="nv">expr = </span><span class="nx">@lastNonComment</span> <span class="nx">block</span><span class="p">.</span><span class="nx">expressions</span>
<span class="k">continue</span> <span class="k">if</span> <span class="nx">expr</span> <span class="k">instanceof</span> <span class="nx">Return</span> <span class="o">or</span> <span class="p">(</span><span class="nx">expr</span> <span class="k">instanceof</span> <span class="nx">Literal</span> <span class="o">and</span> <span class="nx">expr</span><span class="p">.</span><span class="nx">jumps</span><span class="p">()</span> <span class="o">and</span> <span class="nx">expr</span><span class="p">.</span><span class="nx">value</span> <span class="o">isnt</span> <span class="s">&#39;debugger&#39;</span><span class="p">)</span>
<span class="nx">fragments</span><span class="p">.</span><span class="nx">push</span> <span class="nx">cond</span><span class="p">.</span><span class="nx">makeCode</span><span class="p">(</span><span class="nx">idt2</span> <span class="o">+</span> <span class="s">&#39;break;\n&#39;</span><span class="p">)</span>
<span class="k">if</span> <span class="nx">@otherwise</span> <span class="o">and</span> <span class="nx">@otherwise</span><span class="p">.</span><span class="nx">expressions</span><span class="p">.</span><span class="nx">length</span>
<span class="nx">fragments</span><span class="p">.</span><span class="nx">push</span> <span class="nx">@makeCode</span><span class="p">(</span><span class="nx">idt1</span> <span class="o">+</span> <span class="s">&quot;default:\n&quot;</span><span class="p">),</span> <span class="p">(</span><span class="nx">@otherwise</span><span class="p">.</span><span class="nx">compileToFragments</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_TOP</span><span class="p">)...,</span> <span class="nx">@makeCode</span><span class="p">(</span><span class="s">&quot;\n&quot;</span><span class="p">)</span>
<span class="nx">fragments</span><span class="p">.</span><span class="nx">push</span> <span class="nx">@makeCode</span> <span class="nx">@tab</span> <span class="o">+</span> <span class="s">&#39;}&#39;</span>
<span class="nx">fragments</span></pre></div></div>
</li>
<li id="section-124">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-124">&#182;</a>
</div>
<h3>If</h3>
<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&#39;t need conversion.
</p>
</div>
<div class="content"><div class="highlight"><pre><span class="nv">exports.If = </span><span class="k">class</span> <span class="nx">If</span> <span class="k">extends</span> <span class="nx">Base</span>
<span class="nv">constructor: </span><span class="nf">(condition, @body, options = {}) -&gt;</span>
<span class="vi">@condition = </span><span class="k">if</span> <span class="nx">options</span><span class="p">.</span><span class="nx">type</span> <span class="o">is</span> <span class="s">&#39;unless&#39;</span> <span class="k">then</span> <span class="nx">condition</span><span class="p">.</span><span class="nx">invert</span><span class="p">()</span> <span class="k">else</span> <span class="nx">condition</span>
<span class="vi">@elseBody = </span><span class="kc">null</span>
<span class="vi">@isChain = </span><span class="kc">false</span>
<span class="p">{</span><span class="nx">@soak</span><span class="p">}</span> <span class="o">=</span> <span class="nx">options</span>
<span class="nv">children: </span><span class="p">[</span><span class="s">&#39;condition&#39;</span><span class="p">,</span> <span class="s">&#39;body&#39;</span><span class="p">,</span> <span class="s">&#39;elseBody&#39;</span><span class="p">]</span>
<span class="nv">bodyNode: </span> <span class="nf">-&gt;</span> <span class="nx">@body</span><span class="o">?</span><span class="p">.</span><span class="nx">unwrap</span><span class="p">()</span>
<span class="nv">elseBodyNode: </span><span class="nf">-&gt;</span> <span class="nx">@elseBody</span><span class="o">?</span><span class="p">.</span><span class="nx">unwrap</span><span class="p">()</span></pre></div></div>
</li>
<li id="section-125">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-125">&#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="nv">addElse: </span><span class="nf">(elseBody) -&gt;</span>
<span class="k">if</span> <span class="nx">@isChain</span>
<span class="nx">@elseBodyNode</span><span class="p">().</span><span class="nx">addElse</span> <span class="nx">elseBody</span>
<span class="k">else</span>
<span class="vi">@isChain = </span><span class="nx">elseBody</span> <span class="k">instanceof</span> <span class="nx">If</span>
<span class="vi">@elseBody = </span><span class="nx">@ensureBlock</span> <span class="nx">elseBody</span>
<span class="k">this</span></pre></div></div>
</li>
<li id="section-126">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-126">&#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="nv">isStatement: </span><span class="nf">(o) -&gt;</span>
<span class="nx">o</span><span class="o">?</span><span class="p">.</span><span class="nx">level</span> <span class="o">is</span> <span class="nx">LEVEL_TOP</span> <span class="o">or</span>
<span class="nx">@bodyNode</span><span class="p">().</span><span class="nx">isStatement</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">or</span> <span class="nx">@elseBodyNode</span><span class="p">()</span><span class="o">?</span><span class="p">.</span><span class="nx">isStatement</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span>
<span class="nv">jumps: </span><span class="nf">(o) -&gt;</span> <span class="nx">@body</span><span class="p">.</span><span class="nx">jumps</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">or</span> <span class="nx">@elseBody</span><span class="o">?</span><span class="p">.</span><span class="nx">jumps</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span>
<span class="nv">compileNode: </span><span class="nf">(o) -&gt;</span>
<span class="k">if</span> <span class="nx">@isStatement</span> <span class="nx">o</span> <span class="k">then</span> <span class="nx">@compileStatement</span> <span class="nx">o</span> <span class="k">else</span> <span class="nx">@compileExpression</span> <span class="nx">o</span>
<span class="nv">makeReturn: </span><span class="nf">(res) -&gt;</span>
<span class="nx">@elseBody</span> <span class="o">or=</span> <span class="k">new</span> <span class="nx">Block</span> <span class="p">[</span><span class="k">new</span> <span class="nx">Literal</span> <span class="s">&#39;void 0&#39;</span><span class="p">]</span> <span class="k">if</span> <span class="nx">res</span>
<span class="nx">@body</span> <span class="o">and=</span> <span class="k">new</span> <span class="nx">Block</span> <span class="p">[</span><span class="nx">@body</span><span class="p">.</span><span class="nx">makeReturn</span> <span class="nx">res</span><span class="p">]</span>
<span class="nx">@elseBody</span> <span class="o">and=</span> <span class="k">new</span> <span class="nx">Block</span> <span class="p">[</span><span class="nx">@elseBody</span><span class="p">.</span><span class="nx">makeReturn</span> <span class="nx">res</span><span class="p">]</span>
<span class="k">this</span>
<span class="nv">ensureBlock: </span><span class="nf">(node) -&gt;</span>
<span class="k">if</span> <span class="nx">node</span> <span class="k">instanceof</span> <span class="nx">Block</span> <span class="k">then</span> <span class="nx">node</span> <span class="k">else</span> <span class="k">new</span> <span class="nx">Block</span> <span class="p">[</span><span class="nx">node</span><span class="p">]</span></pre></div></div>
</li>
<li id="section-127">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-127">&#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="nv">compileStatement: </span><span class="nf">(o) -&gt;</span>
<span class="nv">child = </span><span class="nx">del</span> <span class="nx">o</span><span class="p">,</span> <span class="s">&#39;chainChild&#39;</span>
<span class="nv">exeq = </span><span class="nx">del</span> <span class="nx">o</span><span class="p">,</span> <span class="s">&#39;isExistentialEquals&#39;</span>
<span class="k">if</span> <span class="nx">exeq</span>
<span class="k">return</span> <span class="k">new</span> <span class="nx">If</span><span class="p">(</span><span class="nx">@condition</span><span class="p">.</span><span class="nx">invert</span><span class="p">(),</span> <span class="nx">@elseBodyNode</span><span class="p">(),</span> <span class="nv">type: </span><span class="s">&#39;if&#39;</span><span class="p">).</span><span class="nx">compileToFragments</span> <span class="nx">o</span>
<span class="nv">indent = </span><span class="nx">o</span><span class="p">.</span><span class="nx">indent</span> <span class="o">+</span> <span class="nx">TAB</span>
<span class="nv">cond = </span><span class="nx">@condition</span><span class="p">.</span><span class="nx">compileToFragments</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_PAREN</span>
<span class="nv">body = </span><span class="nx">@ensureBlock</span><span class="p">(</span><span class="nx">@body</span><span class="p">).</span><span class="nx">compileToFragments</span> <span class="nx">merge</span> <span class="nx">o</span><span class="p">,</span> <span class="p">{</span><span class="nx">indent</span><span class="p">}</span>
<span class="nv">ifPart = </span><span class="p">[].</span><span class="nx">concat</span> <span class="nx">@makeCode</span><span class="p">(</span><span class="s">&quot;if (&quot;</span><span class="p">),</span> <span class="nx">cond</span><span class="p">,</span> <span class="nx">@makeCode</span><span class="p">(</span><span class="s">&quot;) {\n&quot;</span><span class="p">),</span> <span class="nx">body</span><span class="p">,</span> <span class="nx">@makeCode</span><span class="p">(</span><span class="s">&quot;\n</span><span class="si">#{</span><span class="nx">@tab</span><span class="si">}</span><span class="s">}&quot;</span><span class="p">)</span>
<span class="nx">ifPart</span><span class="p">.</span><span class="nx">unshift</span> <span class="nx">@makeCode</span> <span class="nx">@tab</span> <span class="k">unless</span> <span class="nx">child</span>
<span class="k">return</span> <span class="nx">ifPart</span> <span class="k">unless</span> <span class="nx">@elseBody</span>
<span class="nv">answer = </span><span class="nx">ifPart</span><span class="p">.</span><span class="nx">concat</span> <span class="nx">@makeCode</span><span class="p">(</span><span class="s">&#39; else &#39;</span><span class="p">)</span>
<span class="k">if</span> <span class="nx">@isChain</span>
<span class="nv">o.chainChild = </span><span class="kc">yes</span>
<span class="nv">answer = </span><span class="nx">answer</span><span class="p">.</span><span class="nx">concat</span> <span class="nx">@elseBody</span><span class="p">.</span><span class="nx">unwrap</span><span class="p">().</span><span class="nx">compileToFragments</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_TOP</span>
<span class="k">else</span>
<span class="nv">answer = </span><span class="nx">answer</span><span class="p">.</span><span class="nx">concat</span> <span class="nx">@makeCode</span><span class="p">(</span><span class="s">&quot;{\n&quot;</span><span class="p">),</span> <span class="nx">@elseBody</span><span class="p">.</span><span class="nx">compileToFragments</span><span class="p">(</span><span class="nx">merge</span><span class="p">(</span><span class="nx">o</span><span class="p">,</span> <span class="p">{</span><span class="nx">indent</span><span class="p">}),</span> <span class="nx">LEVEL_TOP</span><span class="p">),</span> <span class="nx">@makeCode</span><span class="p">(</span><span class="s">&quot;\n</span><span class="si">#{</span><span class="nx">@tab</span><span class="si">}</span><span class="s">}&quot;</span><span class="p">)</span>
<span class="nx">answer</span></pre></div></div>
</li>
<li id="section-128">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-128">&#182;</a>
</div>
<p>Compile the <code>If</code> as a conditional operator.
</p>
</div>
<div class="content"><div class="highlight"><pre> <span class="nv">compileExpression: </span><span class="nf">(o) -&gt;</span>
<span class="nv">cond = </span><span class="nx">@condition</span><span class="p">.</span><span class="nx">compileToFragments</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_COND</span>
<span class="nv">body = </span><span class="nx">@bodyNode</span><span class="p">().</span><span class="nx">compileToFragments</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_LIST</span>
<span class="nv">alt = </span><span class="k">if</span> <span class="nx">@elseBodyNode</span><span class="p">()</span> <span class="k">then</span> <span class="nx">@elseBodyNode</span><span class="p">().</span><span class="nx">compileToFragments</span><span class="p">(</span><span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_LIST</span><span class="p">)</span> <span class="k">else</span> <span class="p">[</span><span class="nx">@makeCode</span><span class="p">(</span><span class="s">&#39;void 0&#39;</span><span class="p">)]</span>
<span class="nv">fragments = </span><span class="nx">cond</span><span class="p">.</span><span class="nx">concat</span> <span class="nx">@makeCode</span><span class="p">(</span><span class="s">&quot; ? &quot;</span><span class="p">),</span> <span class="nx">body</span><span class="p">,</span> <span class="nx">@makeCode</span><span class="p">(</span><span class="s">&quot; : &quot;</span><span class="p">),</span> <span class="nx">alt</span>
<span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">level</span> <span class="o">&gt;=</span> <span class="nx">LEVEL_COND</span> <span class="k">then</span> <span class="nx">@wrapInBraces</span> <span class="nx">fragments</span> <span class="k">else</span> <span class="nx">fragments</span>
<span class="nv">unfoldSoak: </span><span class="nf">-&gt;</span>
<span class="nx">@soak</span> <span class="o">and</span> <span class="k">this</span></pre></div></div>
</li>
<li id="section-129">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-129">&#182;</a>
</div>
<h2>Faux-Nodes</h2>
<p>Faux-nodes are never created by the grammar, but are used during code
generation to generate other combinations of nodes.
</p>
<h3>Closure</h3>
<p>A faux-node used to wrap an expressions body in a closure.
</p>
</div>
<div class="content"><div class="highlight"><pre><span class="nv">Closure =</span></pre></div></div>
</li>
<li id="section-130">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-130">&#182;</a>
</div>
<p>Wrap the expressions body, unless it contains a pure statement,
in which case, no dice. If the body mentions <code>this</code> or <code>arguments</code>,
then make sure that the closure wrapper preserves the original values.
</p>
</div>
<div class="content"><div class="highlight"><pre> <span class="nv">wrap: </span><span class="nf">(expressions, statement, noReturn) -&gt;</span>
<span class="k">return</span> <span class="nx">expressions</span> <span class="k">if</span> <span class="nx">expressions</span><span class="p">.</span><span class="nx">jumps</span><span class="p">()</span>
<span class="nv">func = </span><span class="k">new</span> <span class="nx">Code</span> <span class="p">[],</span> <span class="nx">Block</span><span class="p">.</span><span class="nx">wrap</span> <span class="p">[</span><span class="nx">expressions</span><span class="p">]</span>
<span class="nv">args = </span><span class="p">[]</span>
<span class="nv">argumentsNode = </span><span class="nx">expressions</span><span class="p">.</span><span class="nx">contains</span> <span class="nx">@isLiteralArguments</span>
<span class="k">if</span> <span class="nx">argumentsNode</span> <span class="o">and</span> <span class="nx">expressions</span><span class="p">.</span><span class="nx">classBody</span>
<span class="nx">argumentsNode</span><span class="p">.</span><span class="nx">error</span> <span class="s">&quot;Class bodies shouldn&#39;t reference arguments&quot;</span>
<span class="k">if</span> <span class="nx">argumentsNode</span> <span class="o">or</span> <span class="nx">expressions</span><span class="p">.</span><span class="nx">contains</span> <span class="nx">@isLiteralThis</span>
<span class="nv">meth = </span><span class="k">new</span> <span class="nx">Literal</span> <span class="k">if</span> <span class="nx">argumentsNode</span> <span class="k">then</span> <span class="s">&#39;apply&#39;</span> <span class="k">else</span> <span class="s">&#39;call&#39;</span>
<span class="nv">args = </span><span class="p">[</span><span class="k">new</span> <span class="nx">Literal</span> <span class="s">&#39;this&#39;</span><span class="p">]</span>
<span class="nx">args</span><span class="p">.</span><span class="nx">push</span> <span class="k">new</span> <span class="nx">Literal</span> <span class="s">&#39;arguments&#39;</span> <span class="k">if</span> <span class="nx">argumentsNode</span>
<span class="nv">func = </span><span class="k">new</span> <span class="nx">Value</span> <span class="nx">func</span><span class="p">,</span> <span class="p">[</span><span class="k">new</span> <span class="nx">Access</span> <span class="nx">meth</span><span class="p">]</span>
<span class="nv">func.noReturn = </span><span class="nx">noReturn</span>
<span class="nv">call = </span><span class="k">new</span> <span class="nx">Call</span> <span class="nx">func</span><span class="p">,</span> <span class="nx">args</span>
<span class="k">if</span> <span class="nx">statement</span> <span class="k">then</span> <span class="nx">Block</span><span class="p">.</span><span class="nx">wrap</span> <span class="p">[</span><span class="nx">call</span><span class="p">]</span> <span class="k">else</span> <span class="nx">call</span>
<span class="nv">isLiteralArguments: </span><span class="nf">(node) -&gt;</span>
<span class="nx">node</span> <span class="k">instanceof</span> <span class="nx">Literal</span> <span class="o">and</span> <span class="nx">node</span><span class="p">.</span><span class="nx">value</span> <span class="o">is</span> <span class="s">&#39;arguments&#39;</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">node</span><span class="p">.</span><span class="nx">asKey</span>
<span class="nv">isLiteralThis: </span><span class="nf">(node) -&gt;</span>
<span class="p">(</span><span class="nx">node</span> <span class="k">instanceof</span> <span class="nx">Literal</span> <span class="o">and</span> <span class="nx">node</span><span class="p">.</span><span class="nx">value</span> <span class="o">is</span> <span class="s">&#39;this&#39;</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">node</span><span class="p">.</span><span class="nx">asKey</span><span class="p">)</span> <span class="o">or</span>
<span class="p">(</span><span class="nx">node</span> <span class="k">instanceof</span> <span class="nx">Code</span> <span class="o">and</span> <span class="nx">node</span><span class="p">.</span><span class="nx">bound</span><span class="p">)</span> <span class="o">or</span>
<span class="p">(</span><span class="nx">node</span> <span class="k">instanceof</span> <span class="nx">Call</span> <span class="o">and</span> <span class="nx">node</span><span class="p">.</span><span class="nx">isSuper</span><span class="p">)</span></pre></div></div>
</li>
<li id="section-131">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-131">&#182;</a>
</div>
<p>Unfold a node&#39;s child if soak, then tuck the node under created <code>If</code>
</p>
</div>
<div class="content"><div class="highlight"><pre><span class="nv">unfoldSoak = </span><span class="nf">(o, parent, name) -&gt;</span>
<span class="k">return</span> <span class="k">unless</span> <span class="nv">ifn = </span><span class="nx">parent</span><span class="p">[</span><span class="nx">name</span><span class="p">].</span><span class="nx">unfoldSoak</span> <span class="nx">o</span>
<span class="nx">parent</span><span class="p">[</span><span class="nx">name</span><span class="p">]</span> <span class="o">=</span> <span class="nx">ifn</span><span class="p">.</span><span class="nx">body</span>
<span class="nv">ifn.body = </span><span class="k">new</span> <span class="nx">Value</span> <span class="nx">parent</span>
<span class="nx">ifn</span></pre></div></div>
</li>
<li id="section-132">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-132">&#182;</a>
</div>
<h2>Constants</h2>
</div>
<div class="content"><div class="highlight"><pre><span class="nv">UTILITIES =</span></pre></div></div>
</li>
<li id="section-133">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-133">&#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="k">extends</span><span class="o">:</span> <span class="nf">-&gt;</span> <span class="s">&quot;&quot;&quot;</span>
<span class="s"> function(child, parent) { for (var key in parent) { if (</span><span class="si">#{</span><span class="nx">utility</span> <span class="s">&#39;hasProp&#39;</span><span class="si">}</span><span class="s">.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>
<span class="s"> &quot;&quot;&quot;</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>Create a function bound to the current value of &quot;this&quot;.
</p>
</div>
<div class="content"><div class="highlight"><pre> <span class="nv">bind: </span><span class="nf">-&gt;</span> <span class="s">&#39;&#39;&#39;</span>
<span class="s"> function(fn, me){ return function(){ return fn.apply(me, arguments); }; }</span>
<span class="s"> &#39;&#39;&#39;</span></pre></div></div>
</li>
<li id="section-135">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-135">&#182;</a>
</div>
<p>Discover if an item is in an array.
</p>
</div>
<div class="content"><div class="highlight"><pre> <span class="nv">indexOf: </span><span class="nf">-&gt;</span> <span class="s">&quot;&quot;&quot;</span>
<span class="s"> [].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="s"> &quot;&quot;&quot;</span></pre></div></div>
</li>
<li id="section-136">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-136">&#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="nv">hasProp: </span><span class="nf">-&gt;</span> <span class="s">&#39;{}.hasOwnProperty&#39;</span>
<span class="nv">slice : </span><span class="nf">-&gt;</span> <span class="s">&#39;[].slice&#39;</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>Levels indicate a node&#39;s position in the AST. Useful for knowing if
parens are necessary or superfluous.
</p>
</div>
<div class="content"><div class="highlight"><pre><span class="nv">LEVEL_TOP = </span><span class="mi">1</span> <span class="c1"># ...;</span>
<span class="nv">LEVEL_PAREN = </span><span class="mi">2</span> <span class="c1"># (...)</span>
<span class="nv">LEVEL_LIST = </span><span class="mi">3</span> <span class="c1"># [...]</span>
<span class="nv">LEVEL_COND = </span><span class="mi">4</span> <span class="c1"># ... ? x : y</span>
<span class="nv">LEVEL_OP = </span><span class="mi">5</span> <span class="c1"># !...</span>
<span class="nv">LEVEL_ACCESS = </span><span class="mi">6</span> <span class="c1"># ...[0]</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>Tabs are two spaces for pretty printing.
</p>
</div>
<div class="content"><div class="highlight"><pre><span class="nv">TAB = </span><span class="s">&#39; &#39;</span>
<span class="nv">IDENTIFIER_STR = </span><span class="s">&quot;[$A-Za-z_\\x7f-\\uffff][$\\w\\x7f-\\uffff]*&quot;</span>
<span class="nv">IDENTIFIER = </span><span class="sr">/// ^ </span><span class="si">#{</span><span class="nx">IDENTIFIER_STR</span><span class="si">}</span><span class="sr"> $ ///</span>
<span class="nv">SIMPLENUM = </span><span class="sr">/^[+-]?\d+$/</span>
<span class="nv">METHOD_DEF = </span><span class="sr">///</span>
<span class="sr"> ^</span>
<span class="sr"> (?:</span>
<span class="sr"> (</span><span class="si">#{</span><span class="nx">IDENTIFIER_STR</span><span class="si">}</span><span class="sr">)</span>
<span class="sr"> \.prototype</span>
<span class="sr"> (?:</span>
<span class="sr"> \.(</span><span class="si">#{</span><span class="nx">IDENTIFIER_STR</span><span class="si">}</span><span class="sr">)</span>
<span class="sr"> | \[(&quot;(?:[^\\&quot;\r\n]|\\.)*&quot;|&#39;(?:[^\\&#39;\r\n]|\\.)*&#39;)\]</span>
<span class="sr"> | \[(0x[\da-fA-F]+ | \d*\.?\d+ (?:[eE][+-]?\d+)?)\]</span>
<span class="sr"> )</span>
<span class="sr"> )</span>
<span class="sr"> |</span>
<span class="sr"> (</span><span class="si">#{</span><span class="nx">IDENTIFIER_STR</span><span class="si">}</span><span class="sr">)</span>
<span class="sr"> $</span>
<span class="sr">///</span></pre></div></div>
</li>
<li id="section-139">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-139">&#182;</a>
</div>
<p>Is a literal value a string?
</p>
</div>
<div class="content"><div class="highlight"><pre><span class="nv">IS_STRING = </span><span class="sr">/^[&#39;&quot;]/</span></pre></div></div>
</li>
<li id="section-140">
<div class="annotation">
<div class="pilwrap">
<a class="pilcrow" href="#section-140">&#182;</a>
</div>
<h2>Utility Functions</h2>
<p>Helper for ensuring that utility functions are assigned at the top level.
</p>
</div>
<div class="content"><div class="highlight"><pre><span class="nv">utility = </span><span class="nf">(name) -&gt;</span>
<span class="nv">ref = </span><span class="s">&quot;__</span><span class="si">#{</span><span class="nx">name</span><span class="si">}</span><span class="s">&quot;</span>
<span class="nx">Scope</span><span class="p">.</span><span class="nx">root</span><span class="p">.</span><span class="nx">assign</span> <span class="nx">ref</span><span class="p">,</span> <span class="nx">UTILITIES</span><span class="p">[</span><span class="nx">name</span><span class="p">]()</span>
<span class="nx">ref</span>
<span class="nv">multident = </span><span class="nf">(code, tab) -&gt;</span>
<span class="nv">code = </span><span class="nx">code</span><span class="p">.</span><span class="nx">replace</span> <span class="sr">/\n/g</span><span class="p">,</span> <span class="s">&#39;$&amp;&#39;</span> <span class="o">+</span> <span class="nx">tab</span>
<span class="nx">code</span><span class="p">.</span><span class="nx">replace</span> <span class="sr">/\s+$/</span><span class="p">,</span> <span class="s">&#39;&#39;</span>
</pre></div></div>
</li>
</ul>
</div>
</body>
</html>