<!DOCTYPE html><html><head><title>nodes.coffee</title><metahttp-equiv="content-type"content="text/html; charset=UTF-8"><linkrel="stylesheet"media="all"href="docco.css"/></head><body><divid="container"><divid="background"></div><divid="jump_to"> Jump To …<divid="jump_wrapper"><divid="jump_page"><aclass="source"href="cake.html"> cake.coffee </a><aclass="source"href="coffee-script.html"> coffee-script.coffee </a><aclass="source"href="command.html"> command.coffee </a><aclass="source"href="grammar.html"> grammar.coffee </a><aclass="source"href="lexer.html"> lexer.coffee </a><aclass="source"href="nodes.html"> nodes.coffee </a><aclass="source"href="optparse.html"> optparse.coffee </a><aclass="source"href="repl.html"> repl.coffee </a><aclass="source"href="rewriter.html"> rewriter.coffee </a><aclass="source"href="scope.html"> scope.coffee </a></div></div></div><tablecellpadding="0"cellspacing="0"><thead><tr><thclass="docs"><h1> nodes.coffee </h1></th><thclass="code"></th></tr></thead><tbody><trid="section-1"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-1">#</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 <ahref="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></td><tdclass="code"><divclass="highlight"><pre></pre></div></td></tr><trid="section-2"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-2">#</a></div><p>Set up for both <strong>Node.js</strong> and the browser, by
including the <ahref="scope.html">Scope</a> class.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="k">if</span><spanclass="nx">process</span><spanclass="o">?</span>
<spanclass="k">this</span><spanclass="p">.</span><spanclass="nv">exports: </span><spanclass="k">this</span></pre></div></td></tr><trid="section-3"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-3">#</a></div><p>Helper function that marks a node as a JavaScript <em>statement</em>, or as a
<em>pure_statement</em>. Statements must be wrapped in a closure when used as an
expression, and nodes tagged as <em>pure_statement</em> cannot be closure-wrapped
without losing their meaning.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">statement: </span><spanclass="p">(</span><spanclass="nx">klass</span><spanclass="p">,</span><spanclass="nx">only</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="p">(</span><spanclass="nv">klass::is_pure_statement: </span><spanclass="o">-></span><spanclass="kc">true</span><spanclass="p">)</span><spanclass="k">if</span><spanclass="nx">only</span></pre></div></td></tr><trid="section-4"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-4">#</a></div><h3>BaseNode</h3></td><tdclass="code"><divclass="highlight"><pre></pre></div></td></tr><trid="section-5"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-5">#</a></div><p>The <strong>BaseNode</strong> is the abstract base class for all nodes in the syntax tree.
scope, and indentation level.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">exports.BaseNode: </span><spanclass="nx">class</span><spanclass="nx">BaseNode</span></pre></div></td></tr><trid="section-6"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-6">#</a></div><p>Common logic for determining whether to wrap this node in a closure before
<p>If a Node is <em>top_sensitive</em>, that means that it needs to compile differently
depending on whether it's being used as part of a larger expression, or is a
top-level statement within the function body.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">compile: </span><spanclass="p">(</span><spanclass="nx">o</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="k">if</span><spanclass="nx">closure</span><spanclass="k">then</span><spanclass="err">@</span><spanclass="nx">compile_closure</span><spanclass="p">(</span><spanclass="err">@</span><spanclass="nx">options</span><spanclass="p">)</span><spanclass="k">else</span><spanclass="err">@</span><spanclass="nx">compile_node</span><spanclass="p">(</span><spanclass="err">@</span><spanclass="nx">options</span><spanclass="p">)</span></pre></div></td></tr><trid="section-7"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-7">#</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></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">compile_closure: </span><spanclass="p">(</span><spanclass="nx">o</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="nx">ClosureNode</span><spanclass="p">.</span><spanclass="nx">wrap</span><spanclass="p">(</span><spanclass="k">this</span><spanclass="p">).</span><spanclass="nx">compile</span><spanclass="nx">o</span></pre></div></td></tr><trid="section-8"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-8">#</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.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">compile_reference: </span><spanclass="p">(</span><spanclass="nx">o</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="p">[</span><spanclass="nx">compiled</span><spanclass="p">,</span><spanclass="nx">reference</span><spanclass="p">]</span></pre></div></td></tr><trid="section-9"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-9">#</a></div><p>Convenience method to grab the current indentation level, plus tabbing in.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">idt: </span><spanclass="p">(</span><spanclass="nx">tabs</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="nx">idt</span></pre></div></td></tr><trid="section-10"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-10">#</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> of the nodes, yielding to a block
and returning true when the block finds a match. <code>contains</code> does not cross
<spanclass="kc">false</span></pre></div></td></tr><trid="section-11"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-11">#</a></div><p>Perform an in-order traversal of the AST. Crosses scope boundaries.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">traverse: </span><spanclass="p">(</span><spanclass="nx">block</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="nx">node</span><spanclass="p">.</span><spanclass="nx">traverse</span><spanclass="nx">block</span><spanclass="k">if</span><spanclass="nx">node</span><spanclass="p">.</span><spanclass="nx">traverse</span></pre></div></td></tr><trid="section-12"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-12">#</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></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">toString: </span><spanclass="p">(</span><spanclass="nx">idt</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="s1">'\n'</span><spanclass="o">+</span><spanclass="nx">idt</span><spanclass="o">+</span><spanclass="err">@</span><spanclass="nx">type</span><spanclass="o">+</span><spanclass="p">(</span><spanclass="nx">child</span><spanclass="p">.</span><spanclass="nx">toString</span><spanclass="p">(</span><spanclass="nx">idt</span><spanclass="o">+</span><spanclass="nx">TAB</span><spanclass="p">)</span><spanclass="k">for</span><spanclass="nx">child</span><spanclass="k">in</span><spanclass="err">@</span><spanclass="nx">children</span><spanclass="p">).</span><spanclass="nx">join</span><spanclass="p">(</span><spanclass="s1">''</span><spanclass="p">)</span></pre></div></td></tr><trid="section-13"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-13">#</a></div><p>Default implementations of the common node identification methods. Nodes
will override these with custom logic, if needed.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">unwrap: </span><spanclass="o">-></span><spanclass="k">this</span>
<spanclass="nv">operation_sensitive: </span><spanclass="o">-></span><spanclass="kc">false</span></pre></div></td></tr><trid="section-14"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-14">#</a></div><h3>Expressions</h3></td><tdclass="code"><divclass="highlight"><pre></pre></div></td></tr><trid="section-15"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-15">#</a></div><p>The expressions body 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></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">exports.Expressions: </span><spanclass="nx">class</span><spanclass="nx">Expressions</span><spanclass="k">extends</span><spanclass="nx">BaseNode</span>
<spanclass="err">@</span><spanclass="nv">children: </span><spanclass="err">@</span><spanclass="nv">expressions: </span><spanclass="nx">compact</span><spanclass="nx">flatten</span><spanclass="nx">nodes</span><spanclass="o">or</span><spanclass="p">[]</span></pre></div></td></tr><trid="section-16"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-16">#</a></div><p>Tack an expression on to the end of this expression list.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">push: </span><spanclass="p">(</span><spanclass="nx">node</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="k">this</span></pre></div></td></tr><trid="section-17"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-17">#</a></div><p>Add an expression at the beginning of this expression list.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">unshift: </span><spanclass="p">(</span><spanclass="nx">node</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="k">this</span></pre></div></td></tr><trid="section-18"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-18">#</a></div><p>If this Expressions consists of just a single node, unwrap it by pulling
it back out.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">unwrap: </span><spanclass="o">-></span>
<spanclass="k">if</span><spanclass="err">@</span><spanclass="nx">expressions</span><spanclass="p">.</span><spanclass="nx">length</span><spanclass="o">is</span><spanclass="mi">1</span><spanclass="k">then</span><spanclass="err">@</span><spanclass="nx">expressions</span><spanclass="p">[</span><spanclass="mi">0</span><spanclass="p">]</span><spanclass="k">else</span><spanclass="k">this</span></pre></div></td></tr><trid="section-19"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-19">#</a></div><p>Is this an empty block of code?</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">empty: </span><spanclass="o">-></span>
<spanclass="err">@</span><spanclass="nx">expressions</span><spanclass="p">.</span><spanclass="nx">length</span><spanclass="o">is</span><spanclass="mi">0</span></pre></div></td></tr><trid="section-20"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-20">#</a></div><p>Is the given node the last one in this block of expressions?</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">is_last: </span><spanclass="p">(</span><spanclass="nx">node</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="nx">node</span><spanclass="o">is</span><spanclass="err">@</span><spanclass="nx">expressions</span><spanclass="p">[</span><spanclass="nx">l</span><spanclass="o">-</span><spanclass="nx">last_index</span><spanclass="p">]</span></pre></div></td></tr><trid="section-21"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-21">#</a></div><p>An <strong>Expressions</strong> is the only node that can serve as the root.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">compile: </span><spanclass="p">(</span><spanclass="nx">o</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="p">(</span><spanclass="err">@</span><spanclass="nx">compile_expression</span><spanclass="p">(</span><spanclass="nx">node</span><spanclass="p">,</span><spanclass="nx">merge</span><spanclass="p">(</span><spanclass="nx">o</span><spanclass="p">))</span><spanclass="k">for</span><spanclass="nx">node</span><spanclass="k">in</span><spanclass="err">@</span><spanclass="nx">expressions</span><spanclass="p">).</span><spanclass="nx">join</span><spanclass="p">(</span><spanclass="s2">"\n"</span><spanclass="p">)</span></pre></div></td></tr><trid="section-22"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-22">#</a></div><p>If we happen to be the top-level <strong>Expressions</strong>, wrap everything in
a safety closure, unless requested not to.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">compile_root: </span><spanclass="p">(</span><spanclass="nx">o</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="k">if</span><spanclass="nx">o</span><spanclass="p">.</span><spanclass="nx">no_wrap</span><spanclass="k">then</span><spanclass="nx">code</span><spanclass="k">else</span><spanclass="s2">"(function(){\n$code\n})();\n"</span></pre></div></td></tr><trid="section-23"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-23">#</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></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">compile_with_declarations: </span><spanclass="p">(</span><spanclass="nx">o</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="nx">code</span></pre></div></td></tr><trid="section-24"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-24">#</a></div><p>Compiles a single expression within the expressions body. If we need to
return the result, and it's an expression, simply return it. If it's a
statement, ask the statement to do so.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">compile_expression: </span><spanclass="p">(</span><spanclass="nx">node</span><spanclass="p">,</span><spanclass="nx">o</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="s2">"${@tab}return ${node.compile(o)};"</span></pre></div></td></tr><trid="section-25"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-25">#</a></div><p>Wrap up the given nodes as an <strong>Expressions</strong>, unless it already happens
to be one.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">Expressions.wrap: </span><spanclass="p">(</span><spanclass="nx">nodes</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="nx">statement</span><spanclass="nx">Expressions</span></pre></div></td></tr><trid="section-26"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-26">#</a></div><h3>LiteralNode</h3></td><tdclass="code"><divclass="highlight"><pre></pre></div></td></tr><trid="section-27"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-27">#</a></div><p>Literals are static values that can be passed through directly into
JavaScript without translation, such as: strings, numbers,
<spanclass="err">@</span><spanclass="nv">value: </span><spanclass="nx">value</span></pre></div></td></tr><trid="section-28"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-28">#</a></div><p>Break and continue must be treated as pure statements -- they lose their
meaning when wrapped in a closure.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">is_statement: </span><spanclass="o">-></span>
<spanclass="s2">" \"$@value\""</span></pre></div></td></tr><trid="section-29"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-29">#</a></div><h3>ReturnNode</h3></td><tdclass="code"><divclass="highlight"><pre></pre></div></td></tr><trid="section-30"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-30">#</a></div><p>A <code>return</code> is a <em>pure_statement</em> -- wrapping it in a closure wouldn't
make sense.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">exports.ReturnNode: </span><spanclass="nx">class</span><spanclass="nx">ReturnNode</span><spanclass="k">extends</span><spanclass="nx">BaseNode</span>
<spanclass="nx">statement</span><spanclass="nx">ReturnNode</span><spanclass="p">,</span><spanclass="kc">true</span></pre></div></td></tr><trid="section-31"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-31">#</a></div><h3>ValueNode</h3></td><tdclass="code"><divclass="highlight"><pre></pre></div></td></tr><trid="section-32"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-32">#</a></div><p>A value, variable or literal or parenthesized, indexed or dotted into,
or vanilla.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">exports.ValueNode: </span><spanclass="nx">class</span><spanclass="nx">ValueNode</span><spanclass="k">extends</span><spanclass="nx">BaseNode</span>
<spanclass="nv">SOAK: </span><spanclass="s2">" == undefined ? undefined : "</span></pre></div></td></tr><trid="section-33"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-33">#</a></div><p>A <strong>ValueNode</strong> has a base and a list of property accesses.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">constructor: </span><spanclass="p">(</span><spanclass="nx">base</span><spanclass="p">,</span><spanclass="nx">properties</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="err">@</span><spanclass="nv">children: </span><spanclass="nx">flatten</span><spanclass="p">[</span><spanclass="err">@</span><spanclass="nv">base: </span><spanclass="nx">base</span><spanclass="p">,</span><spanclass="err">@</span><spanclass="nv">properties: </span><spanclass="p">(</span><spanclass="nx">properties</span><spanclass="o">or</span><spanclass="p">[])]</span></pre></div></td></tr><trid="section-34"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-34">#</a></div><p>Add a property access to the list.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">push: </span><spanclass="p">(</span><spanclass="nx">prop</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="o">!!</span><spanclass="err">@</span><spanclass="nx">properties</span><spanclass="p">.</span><spanclass="nx">length</span></pre></div></td></tr><trid="section-35"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-35">#</a></div><p>Some boolean checks for the benefit of other nodes.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">is_array: </span><spanclass="o">-></span>
<spanclass="err">@</span><spanclass="nx">base</span><spanclass="p">.</span><spanclass="nx">value</span><spanclass="o">is</span><spanclass="s1">'arguments'</span></pre></div></td></tr><trid="section-36"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-36">#</a></div><p>The value can be unwrapped as its inner node, if there are no attached
<spanclass="k">if</span><spanclass="err">@</span><spanclass="nx">properties</span><spanclass="p">.</span><spanclass="nx">length</span><spanclass="k">then</span><spanclass="k">this</span><spanclass="k">else</span><spanclass="err">@</span><spanclass="nx">base</span></pre></div></td></tr><trid="section-37"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-37">#</a></div><p>Values are considered to be statements if their base is a statement.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">is_statement: </span><spanclass="o">-></span>
<spanclass="err">@</span><spanclass="nx">base</span><spanclass="p">.</span><spanclass="nx">is_statement</span><spanclass="o">and</span><spanclass="err">@</span><spanclass="nx">base</span><spanclass="p">.</span><spanclass="nx">is_statement</span><spanclass="p">()</span><spanclass="o">and</span><spanclass="o">not</span><spanclass="err">@</span><spanclass="nx">has_properties</span><spanclass="p">()</span></pre></div></td></tr><trid="section-38"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-38">#</a></div><p>We compile a value to JavaScript by compiling and joining each property.
Things get much more insteresting if the chain of properties has <em>soak</em>
operators <code>?.</code> interspersed. Then we have to take care not to accidentally
evaluate a anything twice when building the soak chain.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">compile_node: </span><spanclass="p">(</span><spanclass="nx">o</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="k">if</span><spanclass="nx">op</span><spanclass="o">and</span><spanclass="nx">soaked</span><spanclass="k">then</span><spanclass="s2">"($complete)"</span><spanclass="k">else</span><spanclass="nx">complete</span></pre></div></td></tr><trid="section-39"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-39">#</a></div><h3>CommentNode</h3></td><tdclass="code"><divclass="highlight"><pre></pre></div></td></tr><trid="section-40"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-40">#</a></div><p>CoffeeScript passes through comments as JavaScript comments at the
same position.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">exports.CommentNode: </span><spanclass="nx">class</span><spanclass="nx">CommentNode</span><spanclass="k">extends</span><spanclass="nx">BaseNode</span>
<spanclass="nx">statement</span><spanclass="nx">CommentNode</span></pre></div></td></tr><trid="section-41"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-41">#</a></div><h3>CallNode</h3></td><tdclass="code"><divclass="highlight"><pre></pre></div></td></tr><trid="section-42"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-42">#</a></div><p>Node for a function invocation. Takes care of converting <code>super()</code> calls into
calls against the prototype's function of the same name.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">exports.CallNode: </span><spanclass="nx">class</span><spanclass="nx">CallNode</span><spanclass="k">extends</span><spanclass="nx">BaseNode</span>
<spanclass="err">@</span><spanclass="nv">prefix: </span><spanclass="s1">''</span></pre></div></td></tr><trid="section-43"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-43">#</a></div><p>Tag this invocation as creating a new instance.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">new_instance: </span><spanclass="o">-></span>
<spanclass="k">this</span></pre></div></td></tr><trid="section-44"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-44">#</a></div><p>Add an argument to the call's arugment list.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">push: </span><spanclass="p">(</span><spanclass="nx">arg</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="k">this</span></pre></div></td></tr><trid="section-45"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-45">#</a></div><p>Compile a vanilla function call.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">compile_node: </span><spanclass="p">(</span><spanclass="nx">o</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="s2">"$@prefix${@variable.compile(o)}($args)"</span></pre></div></td></tr><trid="section-46"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-46">#</a></div><p><code>super()</code> is converted into a call against the superclass's implementation
of the current function.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">compile_super: </span><spanclass="p">(</span><spanclass="nx">args</span><spanclass="p">,</span><spanclass="nx">o</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="s2">"${meth}.call(this${ if args.length then ', ' else '' }$args)"</span></pre></div></td></tr><trid="section-47"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-47">#</a></div><p>If you call a function with a splat, it's converted into a JavaScript
<code>.apply()</code> call to allow the variable-length arguments.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">compile_splat: </span><spanclass="p">(</span><spanclass="nx">o</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="s2">"$@prefix${meth}.apply($obj, ${ args.join('') })"</span></pre></div></td></tr><trid="section-48"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-48">#</a></div><h3>ExtendsNode</h3></td><tdclass="code"><divclass="highlight"><pre></pre></div></td></tr><trid="section-49"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-49">#</a></div><p>Node to extend an object's prototype with an ancestor object.
<spanclass="nx">call</span><spanclass="p">.</span><spanclass="nx">compile</span><spanclass="p">(</span><spanclass="nx">o</span><spanclass="p">)</span></pre></div></td></tr><trid="section-51"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-51">#</a></div><h3>AccessorNode</h3></td><tdclass="code"><divclass="highlight"><pre></pre></div></td></tr><trid="section-52"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-52">#</a></div><p>A <code>.</code> accessor into a property of a value, or the <code>::</code> shorthand for
an accessor into the object's prototype.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">exports.AccessorNode: </span><spanclass="nx">class</span><spanclass="nx">AccessorNode</span><spanclass="k">extends</span><spanclass="nx">BaseNode</span>
<spanclass="s1">'.'</span><spanclass="o">+</span><spanclass="p">(</span><spanclass="k">if</span><spanclass="err">@</span><spanclass="nx">prototype</span><spanclass="k">then</span><spanclass="s1">'prototype.'</span><spanclass="k">else</span><spanclass="s1">''</span><spanclass="p">)</span><spanclass="o">+</span><spanclass="err">@</span><spanclass="nx">name</span><spanclass="p">.</span><spanclass="nx">compile</span><spanclass="p">(</span><spanclass="nx">o</span><spanclass="p">)</span></pre></div></td></tr><trid="section-53"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-53">#</a></div><h3>IndexNode</h3></td><tdclass="code"><divclass="highlight"><pre></pre></div></td></tr><trid="section-54"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-54">#</a></div><p>An indexed accessor into an array or object.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">exports.IndexNode: </span><spanclass="nx">class</span><spanclass="nx">IndexNode</span><spanclass="k">extends</span><spanclass="nx">BaseNode</span>
<spanclass="s2">"[$idx]"</span></pre></div></td></tr><trid="section-55"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-55">#</a></div><h3>RangeNode</h3></td><tdclass="code"><divclass="highlight"><pre></pre></div></td></tr><trid="section-56"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-56">#</a></div><p>A range literal. Ranges can be used to extract portions (slices) of arrays,
to specify a range for comprehensions, or as a value, to be expanded into the
corresponding array of integers at runtime.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">exports.RangeNode: </span><spanclass="nx">class</span><spanclass="nx">RangeNode</span><spanclass="k">extends</span><spanclass="nx">BaseNode</span>
<spanclass="err">@</span><spanclass="nv">exclusive: </span><spanclass="o">!!</span><spanclass="nx">exclusive</span></pre></div></td></tr><trid="section-57"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-57">#</a></div><p>Compiles the range's source variables -- where it starts and where it ends.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">compile_variables: </span><spanclass="p">(</span><spanclass="nx">o</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="s2">"$@from_var = $from; $@to_var = $to;\n$@tab"</span></pre></div></td></tr><trid="section-58"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-58">#</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></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">compile_node: </span><spanclass="p">(</span><spanclass="nx">o</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="s2">"$vars; $compare; $incr"</span></pre></div></td></tr><trid="section-59"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-59">#</a></div><p>When used as a value, expand the range into the equivalent array. In the
future, the code this generates should probably be cleaned up by handwriting
it instead of wrapping nodes.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">compile_array: </span><spanclass="p">(</span><spanclass="nx">o</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="p">(</span><spanclass="k">new</span><spanclass="nx">ParentheticalNode</span><spanclass="p">(</span><spanclass="k">new</span><spanclass="nx">CallNode</span><spanclass="p">(</span><spanclass="k">new</span><spanclass="nx">CodeNode</span><spanclass="p">([],</span><spanclass="nx">arr</span><spanclass="p">)))).</span><spanclass="nx">compile</span><spanclass="p">(</span><spanclass="nx">o</span><spanclass="p">)</span></pre></div></td></tr><trid="section-60"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-60">#</a></div><h3>SliceNode</h3></td><tdclass="code"><divclass="highlight"><pre></pre></div></td></tr><trid="section-61"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-61">#</a></div><p>An array slice literal. Unlike JavaScript's <code>Array#slice</code>, the second parameter
specifies the index of the end of the slice, just as the first parameter
is the index of the beginning.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">exports.SliceNode: </span><spanclass="nx">class</span><spanclass="nx">SliceNode</span><spanclass="k">extends</span><spanclass="nx">BaseNode</span>
<spanclass="err">@</span><spanclass="nv">children: </span><spanclass="err">@</span><spanclass="nv">objects: </span><spanclass="err">@</span><spanclass="nv">properties: </span><spanclass="nx">props</span><spanclass="o">or</span><spanclass="p">[]</span></pre></div></td></tr><trid="section-64"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-64">#</a></div><p>All the mucking about with commas is to make sure that CommentNodes and
<p><em>TODO: Extract this and add it to ArrayNode</em>.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">compile_node: </span><spanclass="p">(</span><spanclass="nx">o</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="s2">"[$objects$ending"</span></pre></div></td></tr><trid="section-67"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-67">#</a></div><h3>ClassNode</h3></td><tdclass="code"><divclass="highlight"><pre></pre></div></td></tr><trid="section-68"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-68">#</a></div><p>The CoffeeScript class definition.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">exports.ClassNode: </span><spanclass="nx">class</span><spanclass="nx">ClassNode</span><spanclass="k">extends</span><spanclass="nx">BaseNode</span>
<spanclass="nv">type: </span><spanclass="s1">'Class'</span></pre></div></td></tr><trid="section-69"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-69">#</a></div><p>Initialize a <strong>ClassNode</strong> with its name, an optional superclass, and a
list of prototype property assignments.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">constructor: </span><spanclass="p">(</span><spanclass="nx">variable</span><spanclass="p">,</span><spanclass="nx">parent</span><spanclass="p">,</span><spanclass="nx">props</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="err">@</span><spanclass="nv">children: </span><spanclass="nx">compact</span><spanclass="nx">flatten</span><spanclass="p">[</span><spanclass="err">@</span><spanclass="nv">variable: </span><spanclass="nx">variable</span><spanclass="p">,</span><spanclass="err">@</span><spanclass="nv">parent: </span><spanclass="nx">parent</span><spanclass="p">,</span><spanclass="err">@</span><spanclass="nv">properties: </span><spanclass="nx">props</span><spanclass="o">or</span><spanclass="p">[]]</span></pre></div></td></tr><trid="section-70"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-70">#</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></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">compile_node: </span><spanclass="p">(</span><spanclass="nx">o</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="nx">statement</span><spanclass="nx">ClassNode</span></pre></div></td></tr><trid="section-71"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-71">#</a></div><h3>PushNode</h3></td><tdclass="code"><divclass="highlight"><pre></pre></div></td></tr><trid="section-72"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-72">#</a></div><p>A faux-node that is never created by the grammar, but is used during
code generation to generate a quick <code>array.push(value)</code> tree of nodes.
Helpful for recording the result arrays from comprehensions.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">PushNode: exports.PushNode: </span><spanclass="p">{</span>
<spanclass="p">}</span></pre></div></td></tr><trid="section-73"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-73">#</a></div><h3>ClosureNode</h3></td><tdclass="code"><divclass="highlight"><pre></pre></div></td></tr><trid="section-74"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-74">#</a></div><p>A faux-node used to wrap an expressions body in a closure.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">ClosureNode: exports.ClosureNode: </span><spanclass="p">{</span>
<spanclass="p">}</span></pre></div></td></tr><trid="section-75"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-75">#</a></div><h3>AssignNode</h3></td><tdclass="code"><divclass="highlight"><pre></pre></div></td></tr><trid="section-76"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-76">#</a></div><p>The <strong>AssignNode</strong> is used to assign a local variable to value, or to set the
property of an object -- including within object literals.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">exports.AssignNode: </span><spanclass="nx">class</span><spanclass="nx">AssignNode</span><spanclass="k">extends</span><spanclass="nx">BaseNode</span>
<spanclass="nv">type: </span><spanclass="s1">'Assign'</span></pre></div></td></tr><trid="section-77"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-77">#</a></div><p>Matchers for detecting prototype assignments.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">PROTO_ASSIGN: </span><spanclass="sr">/^(\S+)\.prototype/</span>
<spanclass="err">@</span><spanclass="nx">is_value</span><spanclass="p">()</span><spanclass="o">and</span><spanclass="p">(</span><spanclass="err">@</span><spanclass="nx">variable</span><spanclass="p">.</span><spanclass="nx">is_array</span><spanclass="p">()</span><spanclass="o">or</span><spanclass="err">@</span><spanclass="nx">variable</span><spanclass="p">.</span><spanclass="nx">is_object</span><spanclass="p">())</span></pre></div></td></tr><trid="section-78"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-78">#</a></div><p>Compile an assignment, delegating to <code>compile_pattern_match</code> or
<code>compile_splice</code> if appropriate. Keep track of the name of the base object
we've been assigned to, for correct internal references. If the variable
has not been seen yet within the current scope, declare it.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">compile_node: </span><spanclass="p">(</span><spanclass="nx">o</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="nx">val</span></pre></div></td></tr><trid="section-79"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-79">#</a></div><p>Brief implementation of recursive pattern matching, when assigning array or
See the <ahref="http://wiki.ecmascript.org/doku.php?id=harmony:destructuring">ECMAScript Harmony Wiki</a>
for details.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">compile_pattern_match: </span><spanclass="p">(</span><spanclass="nx">o</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="nx">code</span></pre></div></td></tr><trid="section-80"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-80">#</a></div><p>Compile the assignment from an array splice literal, using JavaScript's
<spanclass="s2">"${name}.splice.apply($name, [$from, $to].concat($val))"</span></pre></div></td></tr><trid="section-81"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-81">#</a></div><h3>CodeNode</h3></td><tdclass="code"><divclass="highlight"><pre></pre></div></td></tr><trid="section-82"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-82">#</a></div><p>A function definition. This is the only node that creates a new Scope.
When for the purposes of walking the contents of a function body, the CodeNode
has no <em>children</em> -- they're within the inner scope.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">exports.CodeNode: </span><spanclass="nx">class</span><spanclass="nx">CodeNode</span><spanclass="k">extends</span><spanclass="nx">BaseNode</span>
<spanclass="err">@</span><spanclass="nv">bound: </span><spanclass="nx">tag</span><spanclass="o">is</span><spanclass="s1">'boundfunc'</span></pre></div></td></tr><trid="section-83"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-83">#</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> objects. If the function is bound with the <code>=></code>
arrow, generates a wrapper that saves the current value of <code>this</code> through
a closure.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">compile_node: </span><spanclass="p">(</span><spanclass="nx">o</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="kc">true</span></pre></div></td></tr><trid="section-84"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-84">#</a></div><p>When traversing (for printing or inspecting), return the real children of
the function -- the parameters and body of expressions.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">real_children: </span><spanclass="o">-></span>
<spanclass="nx">flatten</span><spanclass="p">[</span><spanclass="err">@</span><spanclass="nx">params</span><spanclass="p">,</span><spanclass="err">@</span><spanclass="nx">body</span><spanclass="p">.</span><spanclass="nx">expressions</span><spanclass="p">]</span></pre></div></td></tr><trid="section-85"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-85">#</a></div><p>Custom <code>traverse</code> implementation that uses the <code>real_children</code>.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">traverse: </span><spanclass="p">(</span><spanclass="nx">block</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="s2">"\n$idt$children"</span></pre></div></td></tr><trid="section-86"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-86">#</a></div><h3>SplatNode</h3></td><tdclass="code"><divclass="highlight"><pre></pre></div></td></tr><trid="section-87"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-87">#</a></div><p>A splat, either as a parameter to a function, an argument to a call,
or as part of a destructuring assignment.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">exports.SplatNode: </span><spanclass="nx">class</span><spanclass="nx">SplatNode</span><spanclass="k">extends</span><spanclass="nx">BaseNode</span>
<spanclass="k">if</span><spanclass="err">@</span><spanclass="nx">index</span><spanclass="o">?</span><spanclass="k">then</span><spanclass="err">@</span><spanclass="nx">compile_param</span><spanclass="p">(</span><spanclass="nx">o</span><spanclass="p">)</span><spanclass="k">else</span><spanclass="err">@</span><spanclass="nx">name</span><spanclass="p">.</span><spanclass="nx">compile</span><spanclass="p">(</span><spanclass="nx">o</span><spanclass="p">)</span></pre></div></td></tr><trid="section-88"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-88">#</a></div><p>Compiling a parameter splat means recovering the parameters that succeed
the splat in the parameter list, by slicing the arguments object.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">compile_param: </span><spanclass="p">(</span><spanclass="nx">o</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="s2">"$name = Array.prototype.slice.call(arguments, $@index)"</span></pre></div></td></tr><trid="section-89"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-89">#</a></div><p>A compiling a splat as a destructuring assignment means slicing arguments
from the right-hand-side's corresponding array.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">compile_value: </span><spanclass="p">(</span><spanclass="nx">o</span><spanclass="p">,</span><spanclass="nx">name</span><spanclass="p">,</span><spanclass="nx">index</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="s2">"Array.prototype.slice.call($name, $index)"</span></pre></div></td></tr><trid="section-90"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-90">#</a></div><h3>WhileNode</h3></td><tdclass="code"><divclass="highlight"><pre></pre></div></td></tr><trid="section-91"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-91">#</a></div><p>A while loop, the only sort of low-level loop exposed by CoffeeScript. From
it, all other loops can be manufactured. Useful in cases where you need more
flexibility or more speed than a comprehension can provide.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">exports.WhileNode: </span><spanclass="nx">class</span><spanclass="nx">WhileNode</span><spanclass="k">extends</span><spanclass="nx">BaseNode</span>
<spanclass="kc">true</span></pre></div></td></tr><trid="section-92"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-92">#</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></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">compile_node: </span><spanclass="p">(</span><spanclass="nx">o</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="nx">statement</span><spanclass="nx">WhileNode</span></pre></div></td></tr><trid="section-93"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-93">#</a></div><h3>OpNode</h3></td><tdclass="code"><divclass="highlight"><pre></pre></div></td></tr><trid="section-94"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-94">#</a></div><p>Simple Arithmetic and logical operations. Performs some conversion from
CoffeeScript operations into their JavaScript equivalents.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">exports.OpNode: </span><spanclass="nx">class</span><spanclass="nx">OpNode</span><spanclass="k">extends</span><spanclass="nx">BaseNode</span>
<spanclass="nv">type: </span><spanclass="s1">'Op'</span></pre></div></td></tr><trid="section-95"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-95">#</a></div><p>The map of conversions from CoffeeScript to JavaScript symbols.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">CONVERSIONS: </span><spanclass="p">{</span>
<spanclass="p">}</span></pre></div></td></tr><trid="section-96"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-96">#</a></div><p>The list of operators for which we perform
<ahref="http://docs.python.org/reference/expressions.html#notin">Python-style comparison chaining</a>.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">CHAINABLE: </span><spanclass="p">[</span><spanclass="s1">'<'</span><spanclass="p">,</span><spanclass="s1">'>'</span><spanclass="p">,</span><spanclass="s1">'>='</span><spanclass="p">,</span><spanclass="s1">'<='</span><spanclass="p">,</span><spanclass="s1">'==='</span><spanclass="p">,</span><spanclass="s1">'!=='</span><spanclass="p">]</span></pre></div></td></tr><trid="section-97"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-97">#</a></div><p>Our assignment operators that have no JavaScript equivalent.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">ASSIGNMENT: </span><spanclass="p">[</span><spanclass="s1">'||='</span><spanclass="p">,</span><spanclass="s1">'&&='</span><spanclass="p">,</span><spanclass="s1">'?='</span><spanclass="p">]</span></pre></div></td></tr><trid="section-98"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-98">#</a></div><p>Operators must come before their operands with a space.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">PREFIX_OPERATORS: </span><spanclass="p">[</span><spanclass="s1">'typeof'</span><spanclass="p">,</span><spanclass="s1">'delete'</span><spanclass="p">]</span>
<spanclass="p">[</span><spanclass="err">@</span><spanclass="nx">first</span><spanclass="p">.</span><spanclass="nx">compile</span><spanclass="p">(</span><spanclass="nx">o</span><spanclass="p">),</span><spanclass="err">@</span><spanclass="nx">operator</span><spanclass="p">,</span><spanclass="err">@</span><spanclass="nx">second</span><spanclass="p">.</span><spanclass="nx">compile</span><spanclass="p">(</span><spanclass="nx">o</span><spanclass="p">)].</span><spanclass="nx">join</span><spanclass="s1">''</span></pre></div></td></tr><trid="section-99"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-99">#</a></div><p>Mimic Python's chained comparisons when multiple comparison operators are
used sequentially. For example: <code>50 < 65 > 10</code></p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">compile_chain: </span><spanclass="p">(</span><spanclass="nx">o</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="s2">"($first) && ($shared $@operator $second)"</span></pre></div></td></tr><trid="section-100"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-100">#</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></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">compile_assignment: </span><spanclass="p">(</span><spanclass="nx">o</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="nx">statement</span><spanclass="nx">TryNode</span></pre></div></td></tr><trid="section-102"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-102">#</a></div><p>Throw an exception.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">exports.ThrowNode: </span><spanclass="nx">class</span><spanclass="nx">ThrowNode</span><spanclass="k">extends</span><spanclass="nx">BaseNode</span>
<spanclass="nx">statement</span><spanclass="nx">ThrowNode</span><spanclass="p">,</span><spanclass="kc">true</span></pre></div></td></tr><trid="section-103"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-103">#</a></div><p>Check an expression for existence (meaning not null or undefined).</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">exports.ExistenceNode: </span><spanclass="nx">class</span><spanclass="nx">ExistenceNode</span><spanclass="k">extends</span><spanclass="nx">BaseNode</span>
<spanclass="s2">"(typeof $first !== \"undefined\"&& $second !== null)"</span></pre></div></td></tr><trid="section-104"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-104">#</a></div><p>An extra set of parentheses, specified explicitly in the source.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">exports.ParentheticalNode: </span><spanclass="nx">class</span><spanclass="nx">ParentheticalNode</span><spanclass="k">extends</span><spanclass="nx">BaseNode</span>
<spanclass="s2">"($code)"</span></pre></div></td></tr><trid="section-105"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-105">#</a></div><p>The replacement for the for loop is an array comprehension (that compiles)
into a for loop. Also acts as an expression, able to return the result
of the comprehenion. Unlike Python array comprehensions, it's able to pass
the current index of the loop as a second parameter.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">exports.ForNode: </span><spanclass="nx">class</span><spanclass="nx">ForNode</span><spanclass="k">extends</span><spanclass="nx">BaseNode</span>
<spanclass="nx">statement</span><spanclass="nx">ForNode</span></pre></div></td></tr><trid="section-106"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-106">#</a></div><p>If/else statements. Switch/whens get compiled into these. Acts as an
expression by pushing down requested returns to the expression bodies.
Single-expression IfNodes are compiled into ternary operators if possible,
because ternaries are first-class returnable assignable expressions.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">exports.IfNode: </span><spanclass="nx">class</span><spanclass="nx">IfNode</span><spanclass="k">extends</span><spanclass="nx">BaseNode</span>
<spanclass="k">this</span></pre></div></td></tr><trid="section-107"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-107">#</a></div><p>Tag a chain of IfNodes with their switch condition for equality.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">rewrite_condition: </span><spanclass="p">(</span><spanclass="nx">expression</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="k">this</span></pre></div></td></tr><trid="section-108"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-108">#</a></div><p>Rewrite a chain of IfNodes with their switch condition for equality.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">rewrite_switch: </span><spanclass="p">(</span><spanclass="nx">o</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="k">this</span></pre></div></td></tr><trid="section-109"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-109">#</a></div><p>Rewrite a chain of IfNodes to add a default case as the final else.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">add_else: </span><spanclass="p">(</span><spanclass="nx">exprs</span><spanclass="p">,</span><spanclass="nx">statement</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="k">this</span></pre></div></td></tr><trid="section-110"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-110">#</a></div><p>If the else_body is an IfNode itself, then we've got an if-else chain.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">is_chain: </span><spanclass="o">-></span>
<spanclass="err">@</span><spanclass="nx">chain</span><spanclass="o">||=</span><spanclass="err">@</span><spanclass="nx">else_body</span><spanclass="o">and</span><spanclass="err">@</span><spanclass="nx">else_body</span><spanclass="k">instanceof</span><spanclass="nx">IfNode</span></pre></div></td></tr><trid="section-111"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-111">#</a></div><p>The IfNode only compiles into a statement if either of the bodies needs
<spanclass="k">if</span><spanclass="err">@</span><spanclass="nx">is_statement</span><spanclass="p">()</span><spanclass="k">then</span><spanclass="err">@</span><spanclass="nx">compile_statement</span><spanclass="p">(</span><spanclass="nx">o</span><spanclass="p">)</span><spanclass="k">else</span><spanclass="err">@</span><spanclass="nx">compile_ternary</span><spanclass="p">(</span><spanclass="nx">o</span><spanclass="p">)</span></pre></div></td></tr><trid="section-112"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-112">#</a></div><p>Compile the IfNode as a regular if-else statement. Flattened chains
force sub-else bodies into statement form.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">compile_statement: </span><spanclass="p">(</span><spanclass="nx">o</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="s2">"$if_part$else_part"</span></pre></div></td></tr><trid="section-113"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-113">#</a></div><p>Compile the IfNode into a ternary operator.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">compile_ternary: </span><spanclass="p">(</span><spanclass="nx">o</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="s2">"$if_part : $else_part"</span></pre></div></td></tr><trid="section-114"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-114">#</a></div><h2>Constants</h2></td><tdclass="code"><divclass="highlight"><pre></pre></div></td></tr><trid="section-115"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-115">#</a></div><p>Tabs are two spaces for pretty printing.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">TAB: </span><spanclass="s1">''</span>
<spanclass="nv">TRAILING_WHITESPACE: </span><spanclass="sr">/\s+$/gm</span></pre></div></td></tr><trid="section-116"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-116">#</a></div><p>Keep the identifier regex in sync with the Lexer.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">IDENTIFIER: </span><spanclass="sr">/^[a-zA-Z$_](\w|\$)*$/</span></pre></div></td></tr><trid="section-117"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-117">#</a></div><h2>Utility Functions</h2></td><tdclass="code"><divclass="highlight"><pre></pre></div></td></tr><trid="section-118"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-118">#</a></div><p>Merge objects.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">merge: </span><spanclass="p">(</span><spanclass="nx">options</span><spanclass="p">,</span><spanclass="nx">overrides</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="nx">fresh</span></pre></div></td></tr><trid="section-119"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-119">#</a></div><p>Trim out all falsy values from an array.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">compact: </span><spanclass="p">(</span><spanclass="nx">array</span><spanclass="p">)</span><spanclass="o">-></span><spanclass="nx">item</span><spanclass="k">for</span><spanclass="nx">item</span><spanclass="k">in</span><spanclass="nx">array</span><spanclass="k">when</span><spanclass="nx">item</span></pre></div></td></tr><trid="section-120"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-120">#</a></div><p>Return a completely flattened version of an array.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">flatten: </span><spanclass="p">(</span><spanclass="nx">array</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="nx">memo</span></pre></div></td></tr><trid="section-121"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-121">#</a></div><p>Delete a key from an object, returning the value.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">del: </span><spanclass="p">(</span><spanclass="nx">obj</span><spanclass="p">,</span><spanclass="nx">key</span><spanclass="p">)</span><spanclass="o">-></span>
<spanclass="nx">val</span></pre></div></td></tr><trid="section-122"><tdclass="docs"><divclass="octowrap"><aclass="octothorpe"href="#section-122">#</a></div><p>Quickie helper for a generated LiteralNode.</p></td><tdclass="code"><divclass="highlight"><pre><spanclass="nv">literal: </span><spanclass="p">(</span><spanclass="nx">name</span><spanclass="p">)</span><spanclass="o">-></span>