1
0
Fork 0
mirror of https://github.com/jashkenas/coffeescript.git synced 2022-11-09 12:23:24 -05:00

CoffeeScript 0.6.2

This commit is contained in:
Jeremy Ashkenas 2010-05-15 01:18:05 -04:00
parent a8d4c3a567
commit 485346f0e5
34 changed files with 479 additions and 323 deletions

View file

@ -10,4 +10,4 @@ futurists: {
}
}
{poet: {name: poet, address: [street, city]}}: futurists
{poet: {name, address: [street, city]}}: futurists

View file

@ -1,7 +1,7 @@
# Econ 101
if this.studying_economics
while supply > demand then buy()
while supply < demand then sell()
buy() while supply > demand
sell() until supply > demand
# Nursery Rhyme
num: 6

View file

@ -1,5 +1,5 @@
<!DOCTYPE html> <html> <head> <title>cake.coffee</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <link rel="stylesheet" media="all" href="docco.css" /> </head> <body> <div id="container"> <div id="background"></div> <div id="jump_to"> Jump To &hellip; <div id="jump_wrapper"> <div id="jump_page"> <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.coffee </a> </div> </div> </div> <table cellpadding="0" cellspacing="0"> <thead> <tr> <th class="docs"> <h1> cake.coffee </h1> </th> <th class="code"> </th> </tr> </thead> <tbody> <tr id="section-1"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-1">#</a> </div> <p><code>cake</code> is a simplified version of <a href="http://www.gnu.org/software/make/">Make</a>
(<a href="<a href='http://rake.rubyforge.org/'>http://rake.rubyforge.org/</a>">Rake</a>, <a href="<a href='http://github.com/280north/jake'>http://github.com/280north/jake</a>">Jake</a>)
(<a href="http://rake.rubyforge.org/">Rake</a>, <a href="http://github.com/280north/jake">Jake</a>)
for CoffeeScript. You define tasks with names and descriptions in a Cakefile,
and can call them from the command line, or invoke them from other tasks.</p>
@ -27,7 +27,7 @@ If no tasks are passed, print the help screen.</p> </td>
<span class="nx">path</span><span class="p">.</span><span class="nx">exists</span> <span class="s1">&#39;Cakefile&#39;</span><span class="p">,</span> <span class="p">(</span><span class="nx">exists</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="k">throw</span> <span class="k">new</span> <span class="nb">Error</span><span class="p">(</span><span class="s2">&quot;Cakefile not found in ${process.cwd()}&quot;</span><span class="p">)</span> <span class="nx">unless</span> <span class="nx">exists</span>
<span class="nv">args: </span><span class="nx">process</span><span class="p">.</span><span class="nx">argv</span><span class="p">[</span><span class="mi">2</span><span class="p">...</span><span class="nx">process</span><span class="p">.</span><span class="nx">argv</span><span class="p">.</span><span class="nx">length</span><span class="p">]</span>
<span class="nx">CoffeeScript</span><span class="p">.</span><span class="nx">run</span> <span class="nx">fs</span><span class="p">.</span><span class="nx">readFileSync</span><span class="p">(</span><span class="s1">&#39;Cakefile&#39;</span><span class="p">),</span> <span class="p">{</span><span class="nv">source: </span><span class="s1">&#39;Cakefile&#39;</span><span class="p">}</span>
<span class="nx">CoffeeScript</span><span class="p">.</span><span class="nx">run</span> <span class="nx">fs</span><span class="p">.</span><span class="nx">readFileSync</span><span class="p">(</span><span class="s1">&#39;Cakefile&#39;</span><span class="p">).</span><span class="nx">toString</span><span class="p">(),</span> <span class="p">{</span><span class="nv">source: </span><span class="s1">&#39;Cakefile&#39;</span><span class="p">}</span>
<span class="nv">oparse: </span><span class="k">new</span> <span class="nx">optparse</span><span class="p">.</span><span class="nx">OptionParser</span> <span class="nx">switches</span>
<span class="k">return</span> <span class="nx">print_tasks</span><span class="p">()</span> <span class="nx">unless</span> <span class="nx">args</span><span class="p">.</span><span class="nx">length</span>
<span class="nv">options: </span><span class="nx">oparse</span><span class="p">.</span><span class="nx">parse</span><span class="p">(</span><span class="nx">args</span><span class="p">)</span>

View file

@ -16,7 +16,7 @@ execute all scripts present in <code>text/coffeescript</code> tags.</p>
<span class="k">this</span><span class="p">.</span><span class="nv">exports: </span><span class="k">this</span><span class="p">.</span><span class="nv">CoffeeScript: </span><span class="p">{}</span>
<span class="nv">Lexer: </span> <span class="k">this</span><span class="p">.</span><span class="nx">Lexer</span>
<span class="nv">parser: </span> <span class="k">this</span><span class="p">.</span><span class="nx">parser</span>
<span class="nv">helpers: </span> <span class="k">this</span><span class="p">.</span><span class="nx">helpers</span></pre></div> </td> </tr> <tr id="section-3"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-3">#</a> </div> <p>The current CoffeeScript version number.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.VERSION: </span><span class="s1">&#39;0.6.1&#39;</span></pre></div> </td> </tr> <tr id="section-4"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-4">#</a> </div> <p>Instantiate a Lexer for our use here.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">lexer: </span><span class="k">new</span> <span class="nx">Lexer</span><span class="p">()</span></pre></div> </td> </tr> <tr id="section-5"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-5">#</a> </div> <p>Compile a string of CoffeeScript code to JavaScript, using the Coffee/Jison
<span class="nv">helpers: </span> <span class="k">this</span><span class="p">.</span><span class="nx">helpers</span></pre></div> </td> </tr> <tr id="section-3"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-3">#</a> </div> <p>The current CoffeeScript version number.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.VERSION: </span><span class="s1">&#39;0.6.2&#39;</span></pre></div> </td> </tr> <tr id="section-4"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-4">#</a> </div> <p>Instantiate a Lexer for our use here.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">lexer: </span><span class="k">new</span> <span class="nx">Lexer</span><span class="p">()</span></pre></div> </td> </tr> <tr id="section-5"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-5">#</a> </div> <p>Compile a string of CoffeeScript code to JavaScript, using the Coffee/Jison
compiler.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.compile: compile: </span><span class="p">(</span><span class="nx">code</span><span class="p">,</span> <span class="nx">options</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">options: </span><span class="o">or</span> <span class="p">{}</span>
<span class="k">try</span>

View file

@ -57,7 +57,7 @@ files in it and all subdirectories.</p> </td> <td class=
<span class="k">for</span> <span class="nx">file</span> <span class="k">in</span> <span class="nx">files</span>
<span class="nx">compile</span> <span class="nx">path</span><span class="p">.</span><span class="nx">join</span><span class="p">(</span><span class="nx">source</span><span class="p">,</span> <span class="nx">file</span><span class="p">)</span>
<span class="k">else</span> <span class="k">if</span> <span class="nx">path</span><span class="p">.</span><span class="nx">extname</span><span class="p">(</span><span class="nx">source</span><span class="p">)</span> <span class="o">is</span> <span class="s1">&#39;.coffee&#39;</span>
<span class="nx">fs</span><span class="p">.</span><span class="nx">readFile</span> <span class="nx">source</span><span class="p">,</span> <span class="p">(</span><span class="nx">err</span><span class="p">,</span> <span class="nx">code</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nx">compile_script</span><span class="p">(</span><span class="nx">source</span><span class="p">,</span> <span class="nx">code</span><span class="p">,</span> <span class="nx">base</span><span class="p">)</span>
<span class="nx">fs</span><span class="p">.</span><span class="nx">readFile</span> <span class="nx">source</span><span class="p">,</span> <span class="p">(</span><span class="nx">err</span><span class="p">,</span> <span class="nx">code</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nx">compile_script</span><span class="p">(</span><span class="nx">source</span><span class="p">,</span> <span class="nx">code</span><span class="p">.</span><span class="nx">toString</span><span class="p">(),</span> <span class="nx">base</span><span class="p">)</span>
<span class="nx">watch</span> <span class="nx">source</span><span class="p">,</span> <span class="nx">base</span> <span class="k">if</span> <span class="nx">options</span><span class="p">.</span><span class="nx">watch</span>
<span class="nx">compile</span> <span class="nx">source</span></pre></div> </td> </tr> <tr id="section-8"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-8">#</a> </div> <p>Compile a single source script, containing the given code, according to the
requested options. If evaluating the script directly sets <code>__filename</code>,
@ -87,7 +87,7 @@ such as <code>--lint</code> or <code>--print</code>.</p> </td>
<span class="nx">fs</span><span class="p">.</span><span class="nx">watchFile</span> <span class="nx">source</span><span class="p">,</span> <span class="p">{</span><span class="nv">persistent: </span><span class="kc">true</span><span class="p">,</span> <span class="nv">interval: </span><span class="mi">500</span><span class="p">},</span> <span class="p">(</span><span class="nx">curr</span><span class="p">,</span> <span class="nx">prev</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="k">return</span> <span class="k">if</span> <span class="nx">curr</span><span class="p">.</span><span class="nx">mtime</span><span class="p">.</span><span class="nx">getTime</span><span class="p">()</span> <span class="o">is</span> <span class="nx">prev</span><span class="p">.</span><span class="nx">mtime</span><span class="p">.</span><span class="nx">getTime</span><span class="p">()</span>
<span class="nx">puts</span> <span class="s2">&quot;Compiled $source&quot;</span> <span class="k">if</span> <span class="nx">options</span><span class="p">.</span><span class="nx">compile</span>
<span class="nx">fs</span><span class="p">.</span><span class="nx">readFile</span> <span class="nx">source</span><span class="p">,</span> <span class="p">(</span><span class="nx">err</span><span class="p">,</span> <span class="nx">code</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nx">compile_script</span><span class="p">(</span><span class="nx">source</span><span class="p">,</span> <span class="nx">code</span><span class="p">,</span> <span class="nx">base</span><span class="p">)</span></pre></div> </td> </tr> <tr id="section-11"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-11">#</a> </div> <p>Write out a JavaScript source file with the compiled code. By default, files
<span class="nx">fs</span><span class="p">.</span><span class="nx">readFile</span> <span class="nx">source</span><span class="p">,</span> <span class="p">(</span><span class="nx">err</span><span class="p">,</span> <span class="nx">code</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nx">compile_script</span><span class="p">(</span><span class="nx">source</span><span class="p">,</span> <span class="nx">code</span><span class="p">.</span><span class="nx">toString</span><span class="p">(),</span> <span class="nx">base</span><span class="p">)</span></pre></div> </td> </tr> <tr id="section-11"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-11">#</a> </div> <p>Write out a JavaScript source file with the compiled code. By default, files
are written out in <code>cwd</code> as <code>.js</code> files with the same name, but the output
directory can be customized with <code>--output</code>.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">write_js: </span><span class="p">(</span><span class="nx">source</span><span class="p">,</span> <span class="nx">js</span><span class="p">,</span> <span class="nx">base</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">filename: </span><span class="nx">path</span><span class="p">.</span><span class="nx">basename</span><span class="p">(</span><span class="nx">source</span><span class="p">,</span> <span class="nx">path</span><span class="p">.</span><span class="nx">extname</span><span class="p">(</span><span class="nx">source</span><span class="p">))</span> <span class="o">+</span> <span class="s1">&#39;.js&#39;</span>

View file

@ -1,14 +1,14 @@
<!DOCTYPE html> <html> <head> <title>grammar.coffee</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <link rel="stylesheet" media="all" href="docco.css" /> </head> <body> <div id="container"> <div id="background"></div> <div id="jump_to"> Jump To &hellip; <div id="jump_wrapper"> <div id="jump_page"> <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.coffee </a> </div> </div> </div> <table cellpadding="0" cellspacing="0"> <thead> <tr> <th class="docs"> <h1> grammar.coffee </h1> </th> <th class="code"> </th> </tr> </thead> <tbody> <tr id="section-1"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-1">#</a> </div> <p>The CoffeeScript parser is generated by <a href="http://github.com/zaach/jison">Jison</a>
from this grammar file. Jison is a bottom-up parser generator, similar in
style to <a href="<a href='http://www.gnu.org/software/bison'>http://www.gnu.org/software/bison</a>">Bison</a>, implemented in JavaScript.
It can recognize <a href="<a href='http://en.wikipedia.org/wiki/LR_grammar'>http://en.wikipedia.org/wiki/LR_grammar</a>">LALR(1), LR(0), SLR(1), and LR(1)</a>
style to <a href="http://www.gnu.org/software/bison">Bison</a>, implemented in JavaScript.
It can recognize <a href="http://en.wikipedia.org/wiki/LR_grammar">LALR(1), LR(0), SLR(1), and LR(1)</a>
type grammars. To create the Jison parser, we list the pattern to match
on the left-hand side, and the action to take (usually the creation of syntax
tree nodes) on the right. As the parser runs, it
shifts tokens from our token stream, from left to right, and
<a href="<a href='http://en.wikipedia.org/wiki/Bottom-up_parsing'>http://en.wikipedia.org/wiki/Bottom-up_parsing</a>">attempts to match</a>
<a href="http://en.wikipedia.org/wiki/Bottom-up_parsing">attempts to match</a>
the token sequence against the rules below. When a match can be made, it
reduces into the <a href="<a href='http://en.wikipedia.org/wiki/Terminal_and_nonterminal_symbols'>http://en.wikipedia.org/wiki/Terminal_and_nonterminal_symbols</a>">nonterminal</a>
reduces into the <a href="http://en.wikipedia.org/wiki/Terminal_and_nonterminal_symbols">nonterminal</a>
(the enclosing name at the top), and we proceed from there.</p>
<p>If you run the <code>cake build:parser</code> command, Jison constructs a parse table
@ -109,6 +109,7 @@ the ordinary <strong>Assign</strong> is that these allow numbers and strings as
have to parse comments like any other construct, and identify all of the
positions in which they can occur in the grammar.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Comment: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;COMMENT&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">CommentNode</span> <span class="nx">$1</span>
<span class="nx">o</span> <span class="s2">&quot;HERECOMMENT&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">CommentNode</span> <span class="nx">$1</span><span class="p">,</span> <span class="s1">&#39;herecomment&#39;</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-21"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-21">#</a> </div> <p><a href="http://jashkenas.github.com/coffee-script/#existence">The existential operator</a>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Existence: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;Expression ?&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">ExistenceNode</span> <span class="nx">$1</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-22"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-22">#</a> </div> <p>The <strong>Code</strong> node is the function literal. It's defined by an indented block
@ -168,9 +169,8 @@ comma, as in JavaScript, or simply by newline.</p> </td>
<span class="nx">o</span> <span class="s2">&quot;&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="p">[]</span>
<span class="nx">o</span> <span class="s2">&quot;AssignObj&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="p">[</span><span class="nx">$1</span><span class="p">]</span>
<span class="nx">o</span> <span class="s2">&quot;AssignList , AssignObj&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="nx">$1</span><span class="p">.</span><span class="nx">concat</span> <span class="p">[</span><span class="nx">$3</span><span class="p">]</span>
<span class="nx">o</span> <span class="s2">&quot;AssignList TERMINATOR AssignObj&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="nx">$1</span><span class="p">.</span><span class="nx">concat</span> <span class="p">[</span><span class="nx">$3</span><span class="p">]</span>
<span class="nx">o</span> <span class="s2">&quot;AssignList , TERMINATOR AssignObj&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="nx">$1</span><span class="p">.</span><span class="nx">concat</span> <span class="p">[</span><span class="nx">$4</span><span class="p">]</span>
<span class="nx">o</span> <span class="s2">&quot;INDENT AssignList OptComma OUTDENT&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="nx">$2</span>
<span class="nx">o</span> <span class="s2">&quot;AssignList OptComma TERMINATOR AssignObj&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="nx">$1</span><span class="p">.</span><span class="nx">concat</span> <span class="p">[</span><span class="nx">$4</span><span class="p">]</span>
<span class="nx">o</span> <span class="s2">&quot;AssignList OptComma INDENT AssignList OptComma OUTDENT&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="nx">$1</span><span class="p">.</span><span class="nx">concat</span> <span class="nx">$4</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-35"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-35">#</a> </div> <p>Class definitions have optional bodies of prototype property assignments,
and optional references to the superclass.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Class: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;CLASS SimpleAssignable&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">ClassNode</span> <span class="nx">$2</span>
@ -287,6 +287,8 @@ in fixed-size increments.</p> </td> <td class="code">
switch/case/default by compiling into an if-else chain.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Switch: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;SWITCH Expression INDENT Whens OUTDENT&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="nx">$4</span><span class="p">.</span><span class="nx">switches_over</span> <span class="nx">$2</span>
<span class="nx">o</span> <span class="s2">&quot;SWITCH Expression INDENT Whens ELSE Block OUTDENT&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="nx">$4</span><span class="p">.</span><span class="nx">switches_over</span><span class="p">(</span><span class="nx">$2</span><span class="p">).</span><span class="nx">add_else</span> <span class="nx">$6</span><span class="p">,</span> <span class="kc">true</span>
<span class="nx">o</span> <span class="s2">&quot;SWITCH INDENT Whens OUTDENT&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="nx">$3</span>
<span class="nx">o</span> <span class="s2">&quot;SWITCH INDENT Whens ELSE Block OUTDENT&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="nx">$3</span><span class="p">.</span><span class="nx">add_else</span> <span class="nx">$5</span><span class="p">,</span> <span class="kc">true</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-63"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-63">#</a> </div> <p>The inner list of whens is left recursive. At code-generation time, the
IfNode will rewrite them into a proper chain.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Whens: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;When&quot;</span>
@ -395,10 +397,10 @@ down. Following these rules is what makes <code>2 + 3 * 4</code> parse as:</p>
<span class="p">[</span><span class="s2">&quot;right&quot;</span><span class="p">,</span> <span class="s1">&#39;INDENT&#39;</span><span class="p">]</span>
<span class="p">[</span><span class="s2">&quot;left&quot;</span><span class="p">,</span> <span class="s1">&#39;OUTDENT&#39;</span><span class="p">]</span>
<span class="p">[</span><span class="s2">&quot;right&quot;</span><span class="p">,</span> <span class="s1">&#39;WHEN&#39;</span><span class="p">,</span> <span class="s1">&#39;LEADING_WHEN&#39;</span><span class="p">,</span> <span class="s1">&#39;IN&#39;</span><span class="p">,</span> <span class="s1">&#39;OF&#39;</span><span class="p">,</span> <span class="s1">&#39;BY&#39;</span><span class="p">,</span> <span class="s1">&#39;THROW&#39;</span><span class="p">]</span>
<span class="p">[</span><span class="s2">&quot;right&quot;</span><span class="p">,</span> <span class="s1">&#39;FOR&#39;</span><span class="p">,</span> <span class="s1">&#39;NEW&#39;</span><span class="p">,</span> <span class="s1">&#39;SUPER&#39;</span><span class="p">,</span> <span class="s1">&#39;CLASS&#39;</span><span class="p">]</span>
<span class="p">[</span><span class="s2">&quot;right&quot;</span><span class="p">,</span> <span class="s1">&#39;FOR&#39;</span><span class="p">,</span> <span class="s1">&#39;WHILE&#39;</span><span class="p">,</span> <span class="s1">&#39;UNTIL&#39;</span><span class="p">,</span> <span class="s1">&#39;NEW&#39;</span><span class="p">,</span> <span class="s1">&#39;SUPER&#39;</span><span class="p">,</span> <span class="s1">&#39;CLASS&#39;</span><span class="p">]</span>
<span class="p">[</span><span class="s2">&quot;left&quot;</span><span class="p">,</span> <span class="s1">&#39;EXTENDS&#39;</span><span class="p">]</span>
<span class="p">[</span><span class="s2">&quot;right&quot;</span><span class="p">,</span> <span class="s1">&#39;ASSIGN&#39;</span><span class="p">,</span> <span class="s1">&#39;RETURN&#39;</span><span class="p">]</span>
<span class="p">[</span><span class="s2">&quot;right&quot;</span><span class="p">,</span> <span class="s1">&#39;-&gt;&#39;</span><span class="p">,</span> <span class="s1">&#39;=&gt;&#39;</span><span class="p">,</span> <span class="s1">&#39;&lt;-&#39;</span><span class="p">,</span> <span class="s1">&#39;UNLESS&#39;</span><span class="p">,</span> <span class="s1">&#39;IF&#39;</span><span class="p">,</span> <span class="s1">&#39;ELSE&#39;</span><span class="p">,</span> <span class="s1">&#39;WHILE&#39;</span><span class="p">,</span> <span class="s1">&#39;UNTIL&#39;</span><span class="p">]</span>
<span class="p">[</span><span class="s2">&quot;right&quot;</span><span class="p">,</span> <span class="s1">&#39;-&gt;&#39;</span><span class="p">,</span> <span class="s1">&#39;=&gt;&#39;</span><span class="p">,</span> <span class="s1">&#39;&lt;-&#39;</span><span class="p">,</span> <span class="s1">&#39;UNLESS&#39;</span><span class="p">,</span> <span class="s1">&#39;IF&#39;</span><span class="p">,</span> <span class="s1">&#39;ELSE&#39;</span><span class="p">]</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-72"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-72">#</a> </div> <h2>Wrapping Up</h2> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-73"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-73">#</a> </div> <p>Finally, now what we have our <strong>grammar</strong> and our <strong>operators</strong>, we can create
our <strong>Jison.Parser</strong>. We do this by processing all of our rules, recording all
terminals (every symbol which does not appear as the name of a rule above)

View file

@ -1,32 +1,37 @@
<!DOCTYPE html> <html> <head> <title>helpers.coffee</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <link rel="stylesheet" media="all" href="docco.css" /> </head> <body> <div id="container"> <div id="background"></div> <div id="jump_to"> Jump To &hellip; <div id="jump_wrapper"> <div id="jump_page"> <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.coffee </a> </div> </div> </div> <table cellpadding="0" cellspacing="0"> <thead> <tr> <th class="docs"> <h1> helpers.coffee </h1> </th> <th class="code"> </th> </tr> </thead> <tbody> <tr id="section-1"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-1">#</a> </div> <p>This file contains the common helper functions that we'd like to share among
the <strong>Lexer</strong>, <strong>Rewriter</strong>, and the <strong>Nodes</strong>. Merge objects, flatten
arrays, count characters, that sort of thing.</p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-2"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-2">#</a> </div> <p>Set up exported variables for both <strong>Node.js</strong> and the browser.</p> </td> <td class="code"> <div class="highlight"><pre><span class="k">this</span><span class="p">.</span><span class="nv">exports: </span><span class="k">this</span> <span class="nx">unless</span> <span class="nx">process</span><span class="o">?</span>
<span class="nv">helpers: exports.helpers: </span><span class="p">{}</span></pre></div> </td> </tr> <tr id="section-3"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-3">#</a> </div> <p>Does a list include a value?</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">helpers.include: include: </span><span class="p">(</span><span class="nx">list</span><span class="p">,</span> <span class="nx">value</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nx">list</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="nx">value</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="mi">0</span></pre></div> </td> </tr> <tr id="section-4"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-4">#</a> </div> <p>Peek at the beginning of a given string to see if it matches a sequence.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">helpers.starts: starts: </span><span class="p">(</span><span class="nx">string</span><span class="p">,</span> <span class="nx">literal</span><span class="p">,</span> <span class="nx">start</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nx">string</span><span class="p">.</span><span class="nx">substring</span><span class="p">(</span><span class="nx">start</span><span class="p">,</span> <span class="p">(</span><span class="nx">start</span> <span class="o">or</span> <span class="mi">0</span><span class="p">)</span> <span class="o">+</span> <span class="nx">literal</span><span class="p">.</span><span class="nx">length</span><span class="p">)</span> <span class="o">is</span> <span class="nx">literal</span></pre></div> </td> </tr> <tr id="section-5"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-5">#</a> </div> <p>Trim out all falsy values from an array.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">helpers.compact: compact: </span><span class="p">(</span><span class="nx">array</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nx">item</span> <span class="k">for</span> <span class="nx">item</span> <span class="k">in</span> <span class="nx">array</span> <span class="k">when</span> <span class="nx">item</span></pre></div> </td> </tr> <tr id="section-6"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-6">#</a> </div> <p>Count the number of occurences of a character in a string.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">helpers.count: count: </span><span class="p">(</span><span class="nx">string</span><span class="p">,</span> <span class="nx">letter</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">helpers: exports.helpers: </span><span class="p">{}</span></pre></div> </td> </tr> <tr id="section-3"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-3">#</a> </div> <p>Cross-browser indexOf, so that IE can join the party.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">helpers.index_of: index_of: </span><span class="p">(</span><span class="nx">array</span><span class="p">,</span> <span class="nx">item</span><span class="p">,</span> <span class="nx">from</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="k">return</span> <span class="nx">array</span><span class="p">.</span><span class="nx">indexOf</span> <span class="nx">item</span><span class="p">,</span> <span class="nx">from</span> <span class="k">if</span> <span class="nx">array</span><span class="p">.</span><span class="nx">indexOf</span>
<span class="k">for</span> <span class="nx">other</span><span class="p">,</span> <span class="nx">index</span> <span class="k">in</span> <span class="nx">array</span>
<span class="k">if</span> <span class="nx">other</span> <span class="o">is</span> <span class="nx">item</span> <span class="o">and</span> <span class="p">(</span><span class="o">not</span> <span class="nx">from</span> <span class="o">or</span> <span class="p">(</span><span class="nx">from</span> <span class="o">&lt;=</span> <span class="nx">index</span><span class="p">))</span>
<span class="k">return</span> <span class="nx">index</span>
<span class="o">-</span><span class="mi">1</span></pre></div> </td> </tr> <tr id="section-4"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-4">#</a> </div> <p>Does a list include a value?</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">helpers.include: include: </span><span class="p">(</span><span class="nx">list</span><span class="p">,</span> <span class="nx">value</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nx">index_of</span><span class="p">(</span><span class="nx">list</span><span class="p">,</span> <span class="nx">value</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="mi">0</span></pre></div> </td> </tr> <tr id="section-5"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-5">#</a> </div> <p>Peek at the beginning of a given string to see if it matches a sequence.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">helpers.starts: starts: </span><span class="p">(</span><span class="nx">string</span><span class="p">,</span> <span class="nx">literal</span><span class="p">,</span> <span class="nx">start</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nx">string</span><span class="p">.</span><span class="nx">substring</span><span class="p">(</span><span class="nx">start</span><span class="p">,</span> <span class="p">(</span><span class="nx">start</span> <span class="o">or</span> <span class="mi">0</span><span class="p">)</span> <span class="o">+</span> <span class="nx">literal</span><span class="p">.</span><span class="nx">length</span><span class="p">)</span> <span class="o">is</span> <span class="nx">literal</span></pre></div> </td> </tr> <tr id="section-6"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-6">#</a> </div> <p>Trim out all falsy values from an array.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">helpers.compact: compact: </span><span class="p">(</span><span class="nx">array</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nx">item</span> <span class="k">for</span> <span class="nx">item</span> <span class="k">in</span> <span class="nx">array</span> <span class="k">when</span> <span class="nx">item</span></pre></div> </td> </tr> <tr id="section-7"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-7">#</a> </div> <p>Count the number of occurences of a character in a string.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">helpers.count: count: </span><span class="p">(</span><span class="nx">string</span><span class="p">,</span> <span class="nx">letter</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">num: </span><span class="mi">0</span>
<span class="nv">pos: </span><span class="nx">string</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="nx">letter</span><span class="p">)</span>
<span class="nv">pos: </span><span class="nx">index_of</span> <span class="nx">string</span><span class="p">,</span> <span class="nx">letter</span>
<span class="k">while</span> <span class="nx">pos</span> <span class="o">isnt</span> <span class="o">-</span><span class="mi">1</span>
<span class="nv">num: </span><span class="o">+</span> <span class="mi">1</span>
<span class="nv">pos: </span><span class="nx">string</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="nx">letter</span><span class="p">,</span> <span class="nx">pos</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span>
<span class="nx">num</span></pre></div> </td> </tr> <tr id="section-7"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-7">#</a> </div> <p>Merge objects, returning a fresh copy with attributes from both sides.
<span class="nv">pos: </span><span class="nx">index_of</span> <span class="nx">string</span><span class="p">,</span> <span class="nx">letter</span><span class="p">,</span> <span class="nx">pos</span> <span class="o">+</span> <span class="mi">1</span>
<span class="nx">num</span></pre></div> </td> </tr> <tr id="section-8"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-8">#</a> </div> <p>Merge objects, returning a fresh copy with attributes from both sides.
Used every time <code>BaseNode#compile</code> is called, to allow properties in the
options hash to propagate down the tree without polluting other branches.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">helpers.merge: merge: </span><span class="p">(</span><span class="nx">options</span><span class="p">,</span> <span class="nx">overrides</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">fresh: </span><span class="p">{}</span>
<span class="p">(</span><span class="nx">fresh</span><span class="p">[</span><span class="nx">key</span><span class="p">]</span><span class="o">:</span> <span class="nx">val</span><span class="p">)</span> <span class="k">for</span> <span class="nx">key</span><span class="p">,</span> <span class="nx">val</span> <span class="k">of</span> <span class="nx">options</span>
<span class="p">(</span><span class="nx">fresh</span><span class="p">[</span><span class="nx">key</span><span class="p">]</span><span class="o">:</span> <span class="nx">val</span><span class="p">)</span> <span class="k">for</span> <span class="nx">key</span><span class="p">,</span> <span class="nx">val</span> <span class="k">of</span> <span class="nx">overrides</span> <span class="k">if</span> <span class="nx">overrides</span>
<span class="nx">fresh</span></pre></div> </td> </tr> <tr id="section-8"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-8">#</a> </div> <p>Extend a source object with the properties of another object (shallow copy).
<span class="nx">fresh</span></pre></div> </td> </tr> <tr id="section-9"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-9">#</a> </div> <p>Extend a source object with the properties of another object (shallow copy).
We use this to simulate Node's deprecated <code>process.mixin</code></p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">helpers.extend: extend: </span><span class="p">(</span><span class="nx">object</span><span class="p">,</span> <span class="nx">properties</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="p">(</span><span class="nx">object</span><span class="p">[</span><span class="nx">key</span><span class="p">]</span><span class="o">:</span> <span class="nx">val</span><span class="p">)</span> <span class="k">for</span> <span class="nx">key</span><span class="p">,</span> <span class="nx">val</span> <span class="k">of</span> <span class="nx">properties</span></pre></div> </td> </tr> <tr id="section-9"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-9">#</a> </div> <p>Return a completely flattened version of an array. Handy for getting a
<span class="p">(</span><span class="nx">object</span><span class="p">[</span><span class="nx">key</span><span class="p">]</span><span class="o">:</span> <span class="nx">val</span><span class="p">)</span> <span class="k">for</span> <span class="nx">key</span><span class="p">,</span> <span class="nx">val</span> <span class="k">of</span> <span class="nx">properties</span></pre></div> </td> </tr> <tr id="section-10"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-10">#</a> </div> <p>Return a completely flattened version of an array. Handy for getting a
list of <code>children</code> from the nodes.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">helpers.flatten: flatten: </span><span class="p">(</span><span class="nx">array</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">memo: </span><span class="p">[]</span>
<span class="k">for</span> <span class="nx">item</span> <span class="k">in</span> <span class="nx">array</span>
<span class="k">if</span> <span class="nx">item</span> <span class="k">instanceof</span> <span class="nb">Array</span> <span class="k">then</span> <span class="nv">memo: </span><span class="nx">memo</span><span class="p">.</span><span class="nx">concat</span><span class="p">(</span><span class="nx">item</span><span class="p">)</span> <span class="k">else</span> <span class="nx">memo</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">item</span><span class="p">)</span>
<span class="nx">memo</span></pre></div> </td> </tr> <tr id="section-10"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-10">#</a> </div> <p>Delete a key from an object, returning the value. Useful when a node is
<span class="nx">memo</span></pre></div> </td> </tr> <tr id="section-11"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-11">#</a> </div> <p>Delete a key from an object, returning the value. Useful when a node is
looking for a particular method in an options hash.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">helpers.del: del: </span><span class="p">(</span><span class="nx">obj</span><span class="p">,</span> <span class="nx">key</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">val: </span><span class="nx">obj</span><span class="p">[</span><span class="nx">key</span><span class="p">]</span>
<span class="k">delete</span> <span class="nx">obj</span><span class="p">[</span><span class="nx">key</span><span class="p">]</span>
<span class="nx">val</span></pre></div> </td> </tr> <tr id="section-11"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-11">#</a> </div> <p>Matches a balanced group such as a single or double-quoted string. Pass in
<span class="nx">val</span></pre></div> </td> </tr> <tr id="section-12"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-12">#</a> </div> <p>Matches a balanced group such as a single or double-quoted string. Pass in
a series of delimiters, all of which must be nested correctly within the
contents of the string. This method allows us to have strings within
interpolations within strings, ad infinitum.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">helpers.balanced_string: balanced_string: </span><span class="p">(</span><span class="nx">str</span><span class="p">,</span> <span class="nx">delimited</span><span class="p">,</span> <span class="nx">options</span><span class="p">)</span> <span class="o">-&gt;</span>

View file

@ -91,23 +91,38 @@ are balanced within the string's contents, and within nested interpolations.</p>
preserve whitespace, but ignore indentation to the left.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">heredoc_token: </span><span class="o">-&gt;</span>
<span class="k">return</span> <span class="kc">false</span> <span class="nx">unless</span> <span class="nv">match: </span><span class="nx">@chunk</span><span class="p">.</span><span class="nx">match</span><span class="p">(</span><span class="nx">HEREDOC</span><span class="p">)</span>
<span class="nv">quote: </span><span class="nx">match</span><span class="p">[</span><span class="mi">1</span><span class="p">].</span><span class="nx">substr</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span>
<span class="nv">doc: </span><span class="nx">@sanitize_heredoc</span> <span class="nx">match</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="o">or</span> <span class="nx">match</span><span class="p">[</span><span class="mi">4</span><span class="p">],</span> <span class="nx">quote</span>
<span class="nv">doc: </span><span class="nx">@sanitize_heredoc</span> <span class="nx">match</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="o">or</span> <span class="nx">match</span><span class="p">[</span><span class="mi">4</span><span class="p">],</span> <span class="p">{</span><span class="nx">quote</span><span class="p">}</span>
<span class="nx">@interpolate_string</span> <span class="s2">&quot;$quote$doc$quote&quot;</span>
<span class="vi">@line: </span><span class="o">+</span> <span class="nx">count</span> <span class="nx">match</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="s2">&quot;\n&quot;</span>
<span class="vi">@i: </span><span class="o">+</span> <span class="nx">match</span><span class="p">[</span><span class="mi">1</span><span class="p">].</span><span class="nx">length</span>
<span class="kc">true</span></pre></div> </td> </tr> <tr id="section-14"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-14">#</a> </div> <p>Matches JavaScript interpolated directly into the source via backticks.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">js_token: </span><span class="o">-&gt;</span>
<span class="kc">true</span></pre></div> </td> </tr> <tr id="section-14"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-14">#</a> </div> <p>Matches and conumes comments. We pass through comments into JavaScript,
so they're treated as real tokens, like any other part of the language.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">comment_token: </span><span class="o">-&gt;</span>
<span class="k">return</span> <span class="kc">false</span> <span class="nx">unless</span> <span class="nv">match: </span><span class="nx">@chunk</span><span class="p">.</span><span class="nx">match</span><span class="p">(</span><span class="nx">COMMENT</span><span class="p">)</span>
<span class="k">if</span> <span class="nx">match</span><span class="p">[</span><span class="mi">3</span><span class="p">]</span>
<span class="nv">comment: </span><span class="nx">@sanitize_heredoc</span> <span class="nx">match</span><span class="p">[</span><span class="mi">3</span><span class="p">],</span> <span class="p">{</span><span class="nv">herecomment: </span><span class="kc">true</span><span class="p">}</span>
<span class="nx">@token</span> <span class="s1">&#39;HERECOMMENT&#39;</span><span class="p">,</span> <span class="nx">comment</span><span class="p">.</span><span class="nx">split</span> <span class="nx">MULTILINER</span>
<span class="k">else</span>
<span class="nv">lines: </span><span class="nx">compact</span> <span class="nx">match</span><span class="p">[</span><span class="mi">1</span><span class="p">].</span><span class="nx">replace</span><span class="p">(</span><span class="nx">COMMENT_CLEANER</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">).</span><span class="nx">split</span> <span class="nx">MULTILINER</span>
<span class="nv">i: </span><span class="nx">@tokens</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="mi">1</span>
<span class="k">if</span> <span class="nx">@unfinished</span><span class="p">()</span>
<span class="nv">i: </span><span class="o">-</span> <span class="mi">1</span> <span class="k">while</span> <span class="nx">@tokens</span><span class="p">[</span><span class="nx">i</span><span class="p">]</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">include</span> <span class="nx">LINE_BREAK</span><span class="p">,</span> <span class="nx">@tokens</span><span class="p">[</span><span class="nx">i</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span>
<span class="nx">@tokens</span><span class="p">.</span><span class="nx">splice</span><span class="p">(</span><span class="nx">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="p">[</span><span class="s1">&#39;COMMENT&#39;</span><span class="p">,</span> <span class="nx">lines</span><span class="p">,</span> <span class="nx">@line</span><span class="p">],</span> <span class="p">[</span><span class="s1">&#39;TERMINATOR&#39;</span><span class="p">,</span> <span class="s1">&#39;\n&#39;</span><span class="p">,</span> <span class="nx">@line</span><span class="p">])</span>
<span class="vi">@line: </span><span class="o">+</span> <span class="nx">count</span> <span class="nx">match</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="s2">&quot;\n&quot;</span>
<span class="vi">@i: </span><span class="o">+</span> <span class="nx">match</span><span class="p">[</span><span class="mi">1</span><span class="p">].</span><span class="nx">length</span>
<span class="kc">true</span></pre></div> </td> </tr> <tr id="section-15"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-15">#</a> </div> <p>Matches JavaScript interpolated directly into the source via backticks.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">js_token: </span><span class="o">-&gt;</span>
<span class="k">return</span> <span class="kc">false</span> <span class="nx">unless</span> <span class="nx">starts</span> <span class="nx">@chunk</span><span class="p">,</span> <span class="s1">&#39;`&#39;</span>
<span class="k">return</span> <span class="kc">false</span> <span class="nx">unless</span> <span class="nv">script: </span><span class="nx">@balanced_token</span> <span class="p">[</span><span class="s1">&#39;`&#39;</span><span class="p">,</span> <span class="s1">&#39;`&#39;</span><span class="p">]</span>
<span class="nx">@token</span> <span class="s1">&#39;JS&#39;</span><span class="p">,</span> <span class="nx">script</span><span class="p">.</span><span class="nx">replace</span> <span class="nx">JS_CLEANER</span><span class="p">,</span> <span class="s1">&#39;&#39;</span>
<span class="vi">@i: </span><span class="o">+</span> <span class="nx">script</span><span class="p">.</span><span class="nx">length</span>
<span class="kc">true</span></pre></div> </td> </tr> <tr id="section-15"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-15">#</a> </div> <p>Matches regular expression literals. Lexing regular expressions is difficult
<span class="kc">true</span></pre></div> </td> </tr> <tr id="section-16"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-16">#</a> </div> <p>Matches regular expression literals. Lexing regular expressions is difficult
to distinguish from division, so we borrow some basic heuristics from
JavaScript and Ruby, borrow slash balancing from <code>@balanced_token</code>, and
borrow interpolation from <code>@interpolate_string</code>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">regex_token: </span><span class="o">-&gt;</span>
<span class="k">return</span> <span class="kc">false</span> <span class="nx">unless</span> <span class="nx">@chunk</span><span class="p">.</span><span class="nx">match</span> <span class="nx">REGEX_START</span>
<span class="k">return</span> <span class="kc">false</span> <span class="k">if</span> <span class="nx">include</span> <span class="nx">NOT_REGEX</span><span class="p">,</span> <span class="nx">@tag</span><span class="p">()</span>
<span class="k">return</span> <span class="kc">false</span> <span class="nx">unless</span> <span class="nv">regex: </span><span class="nx">@balanced_token</span> <span class="p">[</span><span class="s1">&#39;/&#39;</span><span class="p">,</span> <span class="s1">&#39;/&#39;</span><span class="p">]</span>
<span class="nv">regex: </span><span class="o">+</span> <span class="p">(</span><span class="nv">flags: </span><span class="nx">@chunk</span><span class="p">.</span><span class="nx">substr</span><span class="p">(</span><span class="nx">regex</span><span class="p">.</span><span class="nx">length</span><span class="p">).</span><span class="nx">match</span> <span class="nx">REGEX_FLAGS</span><span class="p">)</span>
<span class="k">return</span> <span class="kc">false</span> <span class="nx">unless</span> <span class="nv">end: </span><span class="nx">@chunk</span><span class="p">.</span><span class="nx">substr</span><span class="p">(</span><span class="nx">regex</span><span class="p">.</span><span class="nx">length</span><span class="p">).</span><span class="nx">match</span> <span class="nx">REGEX_END</span>
<span class="nv">regex: </span><span class="o">+</span> <span class="nv">flags: </span><span class="nx">end</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="k">if</span> <span class="nx">end</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span>
<span class="k">if</span> <span class="nx">regex</span><span class="p">.</span><span class="nx">match</span> <span class="nx">REGEX_INTERPOLATION</span>
<span class="nv">str: </span><span class="nx">regex</span><span class="p">.</span><span class="nx">substring</span><span class="p">(</span><span class="mi">1</span><span class="p">).</span><span class="nx">split</span><span class="p">(</span><span class="s1">&#39;/&#39;</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>
<span class="nv">str: </span><span class="nx">str</span><span class="p">.</span><span class="nx">replace</span> <span class="nx">REGEX_ESCAPE</span><span class="p">,</span> <span class="p">(</span><span class="nx">escaped</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="s1">&#39;\\&#39;</span> <span class="o">+</span> <span class="nx">escaped</span>
@ -117,19 +132,9 @@ borrow interpolation from <code>@interpolate_string</code>.</p> </td
<span class="k">else</span>
<span class="nx">@token</span> <span class="s1">&#39;REGEX&#39;</span><span class="p">,</span> <span class="nx">regex</span>
<span class="vi">@i: </span><span class="o">+</span> <span class="nx">regex</span><span class="p">.</span><span class="nx">length</span>
<span class="kc">true</span></pre></div> </td> </tr> <tr id="section-16"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-16">#</a> </div> <p>Matches a token in which which the passed delimiter pairs must be correctly
<span class="kc">true</span></pre></div> </td> </tr> <tr id="section-17"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-17">#</a> </div> <p>Matches a token in which which the passed delimiter pairs must be correctly
balanced (ie. strings, JS literals).</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">balanced_token: </span><span class="p">(</span><span class="nx">delimited</span><span class="p">...)</span> <span class="o">-&gt;</span>
<span class="nx">balanced_string</span> <span class="nx">@chunk</span><span class="p">,</span> <span class="nx">delimited</span></pre></div> </td> </tr> <tr id="section-17"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-17">#</a> </div> <p>Matches and conumes comments. We pass through comments into JavaScript,
so they're treated as real tokens, like any other part of the language.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">comment_token: </span><span class="o">-&gt;</span>
<span class="k">return</span> <span class="kc">false</span> <span class="nx">unless</span> <span class="nv">comment: </span><span class="nx">@match</span> <span class="nx">COMMENT</span><span class="p">,</span> <span class="mi">1</span>
<span class="vi">@line: </span><span class="o">+</span> <span class="p">(</span><span class="nx">comment</span><span class="p">.</span><span class="nx">match</span><span class="p">(</span><span class="nx">MULTILINER</span><span class="p">)</span> <span class="o">or</span> <span class="p">[]).</span><span class="nx">length</span>
<span class="nv">lines: </span><span class="nx">compact</span> <span class="nx">comment</span><span class="p">.</span><span class="nx">replace</span><span class="p">(</span><span class="nx">COMMENT_CLEANER</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">).</span><span class="nx">split</span> <span class="nx">MULTILINER</span>
<span class="nv">i: </span><span class="nx">@tokens</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="mi">1</span>
<span class="k">if</span> <span class="nx">@unfinished</span><span class="p">()</span>
<span class="nv">i: </span><span class="o">-</span> <span class="mi">1</span> <span class="k">while</span> <span class="nx">@tokens</span><span class="p">[</span><span class="nx">i</span><span class="p">]</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">include</span> <span class="nx">LINE_BREAK</span><span class="p">,</span> <span class="nx">@tokens</span><span class="p">[</span><span class="nx">i</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span>
<span class="nx">@tokens</span><span class="p">.</span><span class="nx">splice</span><span class="p">(</span><span class="nx">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="p">[</span><span class="s1">&#39;COMMENT&#39;</span><span class="p">,</span> <span class="nx">lines</span><span class="p">,</span> <span class="nx">@line</span><span class="p">],</span> <span class="p">[</span><span class="s1">&#39;TERMINATOR&#39;</span><span class="p">,</span> <span class="s1">&#39;\n&#39;</span><span class="p">,</span> <span class="nx">@line</span><span class="p">])</span>
<span class="vi">@i: </span><span class="o">+</span> <span class="nx">comment</span><span class="p">.</span><span class="nx">length</span>
<span class="kc">true</span></pre></div> </td> </tr> <tr id="section-18"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-18">#</a> </div> <p>Matches newlines, indents, and outdents, and determines which is which.
<span class="nx">balanced_string</span> <span class="nx">@chunk</span><span class="p">,</span> <span class="nx">delimited</span></pre></div> </td> </tr> <tr id="section-18"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-18">#</a> </div> <p>Matches newlines, indents, and outdents, and determines which is which.
If we can detect that the current line is continued onto the the next line,
then the newline is suppressed:</p>
@ -141,7 +146,7 @@ then the newline is suppressed:</p>
<p>Keeps track of the level of indentation, because a single outdent token
can close multiple indents, so we need to know how far in we happen to be.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">line_token: </span><span class="o">-&gt;</span>
<span class="k">return</span> <span class="kc">false</span> <span class="nx">unless</span> <span class="nv">indent: </span><span class="nx">@match</span> <span class="nx">MULTI_DENT</span><span class="p">,</span> <span class="mi">1</span>
<span class="vi">@line: </span><span class="o">+</span> <span class="nx">indent</span><span class="p">.</span><span class="nx">match</span><span class="p">(</span><span class="nx">MULTILINER</span><span class="p">).</span><span class="nx">length</span>
<span class="vi">@line: </span><span class="o">+</span> <span class="nx">count</span> <span class="nx">indent</span><span class="p">,</span> <span class="s2">&quot;\n&quot;</span>
<span class="vi">@i : </span><span class="o">+</span> <span class="nx">indent</span><span class="p">.</span><span class="nx">length</span>
<span class="nv">prev: </span><span class="nx">@prev</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
<span class="nv">size: </span><span class="nx">indent</span><span class="p">.</span><span class="nx">match</span><span class="p">(</span><span class="nx">LAST_DENTS</span><span class="p">).</span><span class="nx">reverse</span><span class="p">()[</span><span class="mi">0</span><span class="p">].</span><span class="nx">match</span><span class="p">(</span><span class="nx">LAST_DENT</span><span class="p">)[</span><span class="mi">1</span><span class="p">].</span><span class="nx">length</span>
@ -214,12 +219,15 @@ if it's a special kind of accessor.</p> </td> <td class=
<span class="nx">@tag</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="s1">&#39;SOAK_ACCESS&#39;</span><span class="p">)</span>
<span class="nx">@tokens</span><span class="p">.</span><span class="nx">splice</span><span class="p">(</span><span class="o">-</span><span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
<span class="k">else</span>
<span class="nx">@tag</span> <span class="mi">1</span><span class="p">,</span> <span class="s1">&#39;PROPERTY_ACCESS&#39;</span></pre></div> </td> </tr> <tr id="section-26"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-26">#</a> </div> <p>Sanitize a heredoc by escaping internal double quotes and erasing all
external indentation on the left-hand side.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">sanitize_heredoc: </span><span class="p">(</span><span class="nx">doc</span><span class="p">,</span> <span class="nx">quote</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">indent: </span><span class="p">(</span><span class="nx">doc</span><span class="p">.</span><span class="nx">match</span><span class="p">(</span><span class="nx">HEREDOC_INDENT</span><span class="p">)</span> <span class="o">or</span> <span class="p">[</span><span class="s1">&#39;&#39;</span><span class="p">]).</span><span class="nx">sort</span><span class="p">()[</span><span class="mi">0</span><span class="p">]</span>
<span class="nx">doc</span><span class="p">.</span><span class="nx">replace</span><span class="p">(</span><span class="k">new</span> <span class="nb">RegExp</span><span class="p">(</span><span class="s2">&quot;^&quot;</span> <span class="o">+</span><span class="nx">indent</span><span class="p">,</span> <span class="s1">&#39;gm&#39;</span><span class="p">),</span> <span class="s1">&#39;&#39;</span><span class="p">)</span>
<span class="p">.</span><span class="nx">replace</span><span class="p">(</span><span class="nx">MULTILINER</span><span class="p">,</span> <span class="s2">&quot;\\n&quot;</span><span class="p">)</span>
<span class="p">.</span><span class="nx">replace</span><span class="p">(</span><span class="k">new</span> <span class="nb">RegExp</span><span class="p">(</span><span class="nx">quote</span><span class="p">,</span> <span class="s1">&#39;g&#39;</span><span class="p">),</span> <span class="s1">&#39;\\&quot;&#39;</span><span class="p">)</span></pre></div> </td> </tr> <tr id="section-27"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-27">#</a> </div> <p>Tag a half assignment.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">tag_half_assignment: </span><span class="p">(</span><span class="nx">tag</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nx">@tag</span> <span class="mi">1</span><span class="p">,</span> <span class="s1">&#39;PROPERTY_ACCESS&#39;</span></pre></div> </td> </tr> <tr id="section-26"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-26">#</a> </div> <p>Sanitize a heredoc or herecomment by escaping internal double quotes and
erasing all external indentation on the left-hand side.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">sanitize_heredoc: </span><span class="p">(</span><span class="nx">doc</span><span class="p">,</span> <span class="nx">options</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="k">while</span> <span class="nv">match: </span><span class="nx">HEREDOC_INDENT</span><span class="p">.</span><span class="nx">exec</span> <span class="nx">doc</span>
<span class="nv">attempt: </span><span class="k">if</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="k">then</span> <span class="nx">match</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="k">else</span> <span class="nx">match</span><span class="p">[</span><span class="mi">3</span><span class="p">]</span>
<span class="nv">indent: </span><span class="nx">attempt</span> <span class="k">if</span> <span class="o">not</span> <span class="nx">indent</span> <span class="o">or</span> <span class="nx">attempt</span><span class="p">.</span><span class="nx">length</span> <span class="o">&lt;</span> <span class="nx">indent</span><span class="p">.</span><span class="nx">length</span>
<span class="nv">doc: </span><span class="nx">doc</span><span class="p">.</span><span class="nx">replace</span><span class="p">(</span><span class="k">new</span> <span class="nb">RegExp</span><span class="p">(</span><span class="s2">&quot;^&quot;</span> <span class="o">+</span><span class="nx">indent</span><span class="p">,</span> <span class="s1">&#39;gm&#39;</span><span class="p">),</span> <span class="s1">&#39;&#39;</span><span class="p">)</span>
<span class="k">return</span> <span class="nx">doc</span> <span class="k">if</span> <span class="nx">options</span><span class="p">.</span><span class="nx">herecomment</span>
<span class="nx">doc</span><span class="p">.</span><span class="nx">replace</span><span class="p">(</span><span class="nx">MULTILINER</span><span class="p">,</span> <span class="s2">&quot;\\n&quot;</span><span class="p">)</span>
<span class="p">.</span><span class="nx">replace</span><span class="p">(</span><span class="k">new</span> <span class="nb">RegExp</span><span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">quote</span><span class="p">,</span> <span class="s1">&#39;g&#39;</span><span class="p">),</span> <span class="s1">&#39;\\&quot;&#39;</span><span class="p">)</span></pre></div> </td> </tr> <tr id="section-27"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-27">#</a> </div> <p>Tag a half assignment.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">tag_half_assignment: </span><span class="p">(</span><span class="nx">tag</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">last: </span><span class="nx">@tokens</span><span class="p">.</span><span class="nx">pop</span><span class="p">()</span>
<span class="nx">@tokens</span><span class="p">.</span><span class="nx">push</span> <span class="p">[</span><span class="s2">&quot;$tag=&quot;</span><span class="p">,</span> <span class="s2">&quot;$tag=&quot;</span><span class="p">,</span> <span class="nx">last</span><span class="p">[</span><span class="mi">2</span><span class="p">]]</span>
<span class="kc">true</span></pre></div> </td> </tr> <tr id="section-28"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-28">#</a> </div> <p>A source of ambiguity in our grammar used to be parameter lists in function
@ -339,26 +347,26 @@ be used as identifiers or properties.</p> </td> <td clas
<span class="nv">INTERPOLATION : </span><span class="sr">/^\$([a-zA-Z_@]\w*(\.\w+)*)/</span>
<span class="nv">OPERATOR : </span><span class="sr">/^([+\*&amp;|\/\-%=&lt;&gt;:!?]+)([ \t]*)/</span>
<span class="nv">WHITESPACE : </span><span class="sr">/^([ \t]+)/</span>
<span class="nv">COMMENT : </span><span class="sr">/^(((\n?[ \t]*)?#[^\n]*)+)/</span>
<span class="nv">COMMENT : </span><span class="sr">/^((\n?[ \t]*)?#{3}(?!#)\n*([\s\S]*?)\n*([ \t]*)#{3}|((\n?[ \t]*)?#[^\n]*)+)/</span>
<span class="nv">CODE : </span><span class="sr">/^((-|=)&gt;)/</span>
<span class="nv">MULTI_DENT : </span><span class="sr">/^((\n([ \t]*))+)(\.)?/</span>
<span class="nv">LAST_DENTS : </span><span class="sr">/\n([ \t]*)/g</span>
<span class="nv">LAST_DENT : </span><span class="sr">/\n([ \t]*)/</span>
<span class="nv">ASSIGNMENT : </span><span class="sr">/^(:|=)$/</span></pre></div> </td> </tr> <tr id="section-49"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-49">#</a> </div> <p>Regex-matching-regexes.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">REGEX_START : </span><span class="sr">/^\/[^\/ ]/</span>
<span class="nv">REGEX_INTERPOLATION: </span><span class="sr">/([^\\]\$[a-zA-Z_@]|[^\\]\$\{.*[^\\]\})/</span>
<span class="nv">REGEX_FLAGS : </span><span class="sr">/^[imgy]{0,4}/</span>
<span class="nv">REGEX_END : </span><span class="sr">/^(([imgy]{1,4})\b|\W)/</span>
<span class="nv">REGEX_ESCAPE : </span><span class="sr">/\\[^\$]/g</span></pre></div> </td> </tr> <tr id="section-50"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-50">#</a> </div> <p>Token cleaning regexes.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">JS_CLEANER : </span><span class="sr">/(^`|`$)/g</span>
<span class="nv">MULTILINER : </span><span class="sr">/\n/g</span>
<span class="nv">STRING_NEWLINES : </span><span class="sr">/\n[ \t]*/g</span>
<span class="nv">COMMENT_CLEANER : </span><span class="sr">/(^[ \t]*#|\n[ \t]*$)/mg</span>
<span class="nv">NO_NEWLINE : </span><span class="sr">/^([+\*&amp;|\/\-%=&lt;&gt;:!.\\][&lt;&gt;=&amp;|]*|and|or|is|isnt|not|delete|typeof|instanceof)$/</span>
<span class="nv">HEREDOC_INDENT : </span><span class="sr">/^[ \t]+/mg</span></pre></div> </td> </tr> <tr id="section-51"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-51">#</a> </div> <p>Tokens which a regular expression will never immediately follow, but which
<span class="nv">HEREDOC_INDENT : </span><span class="sr">/(\n+([ \t]*)|^([ \t]+))/g</span></pre></div> </td> </tr> <tr id="section-51"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-51">#</a> </div> <p>Tokens which a regular expression will never immediately follow, but which
a division operator might.</p>
<p>See: <a href='http://www.mozilla.org/js/language/js20-2002-04/rationale/syntax.html#regular-expressions'>http://www.mozilla.org/js/language/js20-2002-04/rationale/syntax.html#regular-expressions</a></p>
<p>See: http://www.mozilla.org/js/language/js20-2002-04/rationale/syntax.html#regular-expressions</p>
<p>Our list is shorter, due to sans-parentheses method calls.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">NOT_REGEX: </span><span class="p">[</span>
<span class="s1">&#39;NUMBER&#39;</span><span class="p">,</span> <span class="s1">&#39;REGEX&#39;</span><span class="p">,</span> <span class="s1">&#39;++&#39;</span><span class="p">,</span> <span class="s1">&#39;--&#39;</span><span class="p">,</span> <span class="s1">&#39;FALSE&#39;</span><span class="p">,</span> <span class="s1">&#39;NULL&#39;</span><span class="p">,</span> <span class="s1">&#39;TRUE&#39;</span>
<span class="s1">&#39;NUMBER&#39;</span><span class="p">,</span> <span class="s1">&#39;REGEX&#39;</span><span class="p">,</span> <span class="s1">&#39;++&#39;</span><span class="p">,</span> <span class="s1">&#39;--&#39;</span><span class="p">,</span> <span class="s1">&#39;FALSE&#39;</span><span class="p">,</span> <span class="s1">&#39;NULL&#39;</span><span class="p">,</span> <span class="s1">&#39;TRUE&#39;</span><span class="p">,</span> <span class="s1">&#39;]&#39;</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-52"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-52">#</a> </div> <p>Tokens which could legitimately be invoked or indexed. A opening
parentheses or bracket following these tokens will be recorded as the start
of a function invocation or indexing operation.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">CALLABLE: </span><span class="p">[</span><span class="s1">&#39;IDENTIFIER&#39;</span><span class="p">,</span> <span class="s1">&#39;SUPER&#39;</span><span class="p">,</span> <span class="s1">&#39;)&#39;</span><span class="p">,</span> <span class="s1">&#39;]&#39;</span><span class="p">,</span> <span class="s1">&#39;}&#39;</span><span class="p">,</span> <span class="s1">&#39;STRING&#39;</span><span class="p">,</span> <span class="s1">&#39;@&#39;</span><span class="p">,</span> <span class="s1">&#39;THIS&#39;</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-53"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-53">#</a> </div> <p>Tokens that indicate an access -- keywords immediately following will be

View file

@ -8,12 +8,15 @@ including the <a href="scope.html">Scope</a> class and the <a href="helpers.html
<span class="k">else</span>
<span class="k">this</span><span class="p">.</span><span class="nv">exports: </span><span class="k">this</span>
<span class="nv">helpers: </span> <span class="k">this</span><span class="p">.</span><span class="nx">helpers</span>
<span class="nv">Scope: </span> <span class="k">this</span><span class="p">.</span><span class="nx">Scope</span></pre></div> </td> </tr> <tr id="section-3"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-3">#</a> </div> <p>Import the helpers we plan to use.</p> </td> <td class="code"> <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">merge</span><span class="p">,</span> <span class="nx">del</span><span class="p">}</span><span class="o">:</span> <span class="nx">helpers</span></pre></div> </td> </tr> <tr id="section-4"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-4">#</a> </div> <p>Helper function that marks a node as a JavaScript <em>statement</em>, or as a
<span class="nv">Scope: </span> <span class="k">this</span><span class="p">.</span><span class="nx">Scope</span></pre></div> </td> </tr> <tr id="section-3"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-3">#</a> </div> <p>Import the helpers we plan to use.</p> </td> <td class="code"> <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">merge</span><span class="p">,</span> <span class="nx">del</span><span class="p">,</span> <span class="nx">index_of</span><span class="p">}</span><span class="o">:</span> <span class="nx">helpers</span></pre></div> </td> </tr> <tr id="section-4"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-4">#</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> <td class="code"> <div class="highlight"><pre><span class="nv">statement: </span><span class="p">(</span><span class="nx">klass</span><span class="p">,</span> <span class="nx">only</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">klass::is_statement: </span><span class="o">-&gt;</span> <span class="kc">true</span>
<span class="p">(</span><span class="nv">klass::is_pure_statement: </span><span class="o">-&gt;</span> <span class="kc">true</span><span class="p">)</span> <span class="k">if</span> <span class="nx">only</span></pre></div> </td> </tr> <tr id="section-5"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-5">#</a> </div> <h3>BaseNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-6"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-6">#</a> </div> <p>The <strong>BaseNode</strong> is the abstract base class for all nodes in the syntax tree.
<span class="p">(</span><span class="nv">klass::is_pure_statement: </span><span class="o">-&gt;</span> <span class="kc">true</span><span class="p">)</span> <span class="k">if</span> <span class="nx">only</span>
<span class="nv">children: </span><span class="p">(</span><span class="nx">klass</span><span class="p">,</span> <span class="nx">child_attrs</span><span class="p">...)</span> <span class="o">-&gt;</span>
<span class="nv">klass::children_attributes: </span><span class="nx">child_attrs</span></pre></div> </td> </tr> <tr id="section-5"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-5">#</a> </div> <h3>BaseNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-6"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-6">#</a> </div> <p>The <strong>BaseNode</strong> is the abstract base class for all nodes in the syntax tree.
Each subclass implements the <code>compile_node</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>compile_node</code> in some generic extra smarts,
@ -60,21 +63,35 @@ many statement nodes (eg IfNode, ForNode)...</p> </td> <
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
scope boundaries.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">contains: </span><span class="p">(</span><span class="nx">block</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="k">for</span> <span class="nx">node</span> <span class="k">in</span> <span class="nx">@children</span>
<span class="k">return</span> <span class="kc">true</span> <span class="k">if</span> <span class="nx">block</span><span class="p">(</span><span class="nx">node</span><span class="p">)</span>
<span class="k">return</span> <span class="kc">true</span> <span class="k">if</span> <span class="nx">node</span><span class="p">.</span><span class="nx">contains</span> <span class="o">and</span> <span class="nx">node</span><span class="p">.</span><span class="nx">contains</span> <span class="nx">block</span>
<span class="kc">false</span></pre></div> </td> </tr> <tr id="section-13"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-13">#</a> </div> <p>Is this node of a certain type, or does it contain the type?</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">contains_type: </span><span class="p">(</span><span class="nx">type</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">contains: </span><span class="kc">false</span>
<span class="nx">@traverse_children</span> <span class="kc">false</span><span class="p">,</span> <span class="p">(</span><span class="nx">node</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="k">if</span> <span class="nx">block</span><span class="p">(</span><span class="nx">node</span><span class="p">)</span>
<span class="nv">contains: </span><span class="kc">true</span>
<span class="k">return</span> <span class="kc">false</span>
<span class="nx">contains</span></pre></div> </td> </tr> <tr id="section-13"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-13">#</a> </div> <p>Is this node of a certain type, or does it contain the type?</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">contains_type: </span><span class="p">(</span><span class="nx">type</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="k">this</span> <span class="k">instanceof</span> <span class="nx">type</span> <span class="o">or</span> <span class="nx">@contains</span> <span class="p">(</span><span class="nx">n</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nx">n</span> <span class="k">instanceof</span> <span class="nx">type</span></pre></div> </td> </tr> <tr id="section-14"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-14">#</a> </div> <p>Convenience for the most common use of contains. Does the node contain
a pure statement?</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">contains_pure_statement: </span><span class="o">-&gt;</span>
<span class="nx">@is_pure_statement</span><span class="p">()</span> <span class="o">or</span> <span class="nx">@contains</span> <span class="p">(</span><span class="nx">n</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nx">n</span><span class="p">.</span><span class="nx">is_pure_statement</span><span class="p">()</span></pre></div> </td> </tr> <tr id="section-15"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-15">#</a> </div> <p>Perform an in-order traversal of the AST. Crosses scope boundaries.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">traverse: </span><span class="p">(</span><span class="nx">block</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="k">for</span> <span class="nx">node</span> <span class="k">in</span> <span class="nx">@children</span>
<span class="nx">block</span> <span class="nx">node</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">traverse</span> <span class="nx">block</span> <span class="k">if</span> <span class="nx">node</span><span class="p">.</span><span class="nx">traverse</span></pre></div> </td> </tr> <tr id="section-16"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-16">#</a> </div> <p><code>toString</code> representation of the node, for inspecting the parse tree.
<span class="nx">@is_pure_statement</span><span class="p">()</span> <span class="o">or</span> <span class="nx">@contains</span> <span class="p">(</span><span class="nx">n</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nx">n</span><span class="p">.</span><span class="nx">is_pure_statement</span><span class="p">()</span></pre></div> </td> </tr> <tr id="section-15"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-15">#</a> </div> <p>Perform an in-order traversal of the AST. Crosses scope boundaries.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">traverse: </span><span class="p">(</span><span class="nx">block</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nx">@traverse_children</span> <span class="kc">true</span><span class="p">,</span> <span class="nx">block</span></pre></div> </td> </tr> <tr id="section-16"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-16">#</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> <td class="code"> <div class="highlight"><pre> <span class="nv">toString: </span><span class="p">(</span><span class="nx">idt</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">idt: </span><span class="o">or</span> <span class="s1">&#39;&#39;</span>
<span class="s1">&#39;\n&#39;</span> <span class="o">+</span> <span class="nx">idt</span> <span class="o">+</span> <span class="nx">@constructor</span><span class="p">.</span><span class="nx">name</span> <span class="o">+</span> <span class="p">(</span><span class="nx">child</span><span class="p">.</span><span class="nx">toString</span><span class="p">(</span><span class="nx">idt</span> <span class="o">+</span> <span class="nx">TAB</span><span class="p">)</span> <span class="k">for</span> <span class="nx">child</span> <span class="k">in</span> <span class="nx">@children</span><span class="p">).</span><span class="nx">join</span><span class="p">(</span><span class="s1">&#39;&#39;</span><span class="p">)</span></pre></div> </td> </tr> <tr id="section-17"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-17">#</a> </div> <p>Default implementations of the common node identification methods. Nodes
<span class="s1">&#39;\n&#39;</span> <span class="o">+</span> <span class="nx">idt</span> <span class="o">+</span> <span class="nx">@constructor</span><span class="p">.</span><span class="nx">name</span> <span class="o">+</span> <span class="p">(</span><span class="nx">child</span><span class="p">.</span><span class="nx">toString</span><span class="p">(</span><span class="nx">idt</span> <span class="o">+</span> <span class="nx">TAB</span><span class="p">)</span> <span class="k">for</span> <span class="nx">child</span> <span class="k">in</span> <span class="nx">@children</span><span class="p">()).</span><span class="nx">join</span><span class="p">(</span><span class="s1">&#39;&#39;</span><span class="p">)</span>
<span class="nv">children: </span><span class="o">-&gt;</span>
<span class="nv">nodes: </span><span class="p">[]</span>
<span class="nx">@each_child</span> <span class="p">(</span><span class="nx">node</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nx">nodes</span><span class="p">.</span><span class="nx">push</span> <span class="nx">node</span>
<span class="nx">nodes</span>
<span class="nv">each_child: </span><span class="p">(</span><span class="nx">func</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="k">for</span> <span class="nx">attr</span> <span class="k">in</span> <span class="nx">@children_attributes</span> <span class="k">when</span> <span class="k">this</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="k">this</span><span class="p">[</span><span class="nx">attr</span><span class="p">]]</span>
<span class="k">return</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="nv">traverse_children: </span><span class="p">(</span><span class="nx">cross_scope</span><span class="p">,</span> <span class="nx">func</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="k">return</span> <span class="nx">unless</span> <span class="nx">@children_attributes</span>
<span class="nx">@each_child</span> <span class="p">(</span><span class="nx">child</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nx">func</span><span class="p">.</span><span class="nx">apply</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="nx">arguments</span><span class="p">)</span>
<span class="nx">child</span><span class="p">.</span><span class="nx">traverse_children</span><span class="p">(</span><span class="nx">cross_scope</span><span class="p">,</span> <span class="nx">func</span><span class="p">)</span> <span class="k">if</span> <span class="nx">child</span> <span class="k">instanceof</span> <span class="nx">BaseNode</span></pre></div> </td> </tr> <tr id="section-17"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-17">#</a> </div> <p>Default implementations of the common node identification methods. Nodes
will override these with custom logic, if needed.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">unwrap: </span> <span class="o">-&gt;</span> <span class="k">this</span>
<span class="nv">children: </span> <span class="p">[]</span>
<span class="nv">is_statement: </span> <span class="o">-&gt;</span> <span class="kc">false</span>
<span class="nv">is_pure_statement: </span> <span class="o">-&gt;</span> <span class="kc">false</span>
<span class="nv">top_sensitive: </span> <span class="o">-&gt;</span> <span class="kc">false</span></pre></div> </td> </tr> <tr id="section-18"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-18">#</a> </div> <h3>Expressions</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-19"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-19">#</a> </div> <p>The expressions body is the list of expressions that forms the body of an
@ -82,53 +99,53 @@ 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> <td class="code"> <div class="highlight"><pre><span class="nv">exports.Expressions: </span><span class="nx">class</span> <span class="nx">Expressions</span> <span class="k">extends</span> <span class="nx">BaseNode</span>
<span class="nv">constructor: </span><span class="p">(</span><span class="nx">nodes</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="vi">@children: @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></pre></div> </td> </tr> <tr id="section-20"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-20">#</a> </div> <p>Tack an expression on to the end of this expression list.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">push: </span><span class="p">(</span><span class="nx">node</span><span class="p">)</span> <span class="o">-&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></pre></div> </td> </tr> <tr id="section-20"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-20">#</a> </div> <p>Tack an expression on to the end of this expression list.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">push: </span><span class="p">(</span><span class="nx">node</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nx">@expressions</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">node</span><span class="p">)</span>
<span class="k">this</span></pre></div> </td> </tr> <tr id="section-21"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-21">#</a> </div> <p>Add an expression at the beginning of this expression list.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">unshift: </span><span class="p">(</span><span class="nx">node</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nx">@expressions</span><span class="p">.</span><span class="nx">unshift</span><span class="p">(</span><span class="nx">node</span><span class="p">)</span>
<span class="k">this</span></pre></div> </td> </tr> <tr id="section-22"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-22">#</a> </div> <p>If this Expressions consists of just a single node, unwrap it by pulling
it back out.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">unwrap: </span><span class="o">-&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> </td> </tr> <tr id="section-23"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-23">#</a> </div> <p>Is this an empty block of code?</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">empty: </span><span class="o">-&gt;</span>
<span class="nx">@expressions</span><span class="p">.</span><span class="nx">length</span> <span class="o">is</span> <span class="mi">0</span></pre></div> </td> </tr> <tr id="section-24"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-24">#</a> </div> <p>Make a copy of this node.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">copy: </span><span class="o">-&gt;</span>
<span class="k">new</span> <span class="nx">Expressions</span> <span class="nx">@children</span><span class="p">.</span><span class="nx">slice</span><span class="p">()</span></pre></div> </td> </tr> <tr id="section-25"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-25">#</a> </div> <p>An Expressions node does not return its entire body, rather it
<span class="nx">@expressions</span><span class="p">.</span><span class="nx">length</span> <span class="o">is</span> <span class="mi">0</span></pre></div> </td> </tr> <tr id="section-24"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-24">#</a> </div> <p>An Expressions node does not return its entire body, rather it
ensures that the final expression is returned.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">make_return: </span><span class="o">-&gt;</span>
<span class="nv">idx: </span> <span class="nx">@expressions</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="mi">1</span>
<span class="nv">last: </span><span class="nx">@expressions</span><span class="p">[</span><span class="nx">idx</span><span class="p">]</span>
<span class="nv">last: </span><span class="nx">@expressions</span><span class="p">[</span><span class="nv">idx: </span><span class="o">-</span> <span class="mi">1</span><span class="p">]</span> <span class="k">if</span> <span class="nx">last</span> <span class="k">instanceof</span> <span class="nx">CommentNode</span>
<span class="k">return</span> <span class="k">this</span> <span class="k">if</span> <span class="o">not</span> <span class="nx">last</span> <span class="o">or</span> <span class="nx">last</span> <span class="k">instanceof</span> <span class="nx">ReturnNode</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="nx">last</span><span class="p">.</span><span class="nx">make_return</span><span class="p">()</span> <span class="nx">unless</span> <span class="nx">last</span><span class="p">.</span><span class="nx">contains_pure_statement</span><span class="p">()</span>
<span class="k">this</span></pre></div> </td> </tr> <tr id="section-26"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-26">#</a> </div> <p>An <strong>Expressions</strong> is the only node that can serve as the root.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compile: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="k">this</span></pre></div> </td> </tr> <tr id="section-25"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-25">#</a> </div> <p>An <strong>Expressions</strong> is the only node that can serve as the root.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compile: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">o: </span><span class="o">or</span> <span class="p">{}</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="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="k">else</span> <span class="nx">@compile_root</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span>
<span class="nv">compile_node: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="p">(</span><span class="nx">@compile_expression</span><span class="p">(</span><span class="nx">node</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="k">for</span> <span class="nx">node</span> <span class="k">in</span> <span class="nx">@expressions</span><span class="p">).</span><span class="nx">join</span><span class="p">(</span><span class="s2">&quot;\n&quot;</span><span class="p">)</span></pre></div> </td> </tr> <tr id="section-27"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-27">#</a> </div> <p>If we happen to be the top-level <strong>Expressions</strong>, wrap everything in
<span class="p">(</span><span class="nx">@compile_expression</span><span class="p">(</span><span class="nx">node</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="k">for</span> <span class="nx">node</span> <span class="k">in</span> <span class="nx">@expressions</span><span class="p">).</span><span class="nx">join</span><span class="p">(</span><span class="s2">&quot;\n&quot;</span><span class="p">)</span></pre></div> </td> </tr> <tr id="section-26"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-26">#</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> <td class="code"> <div class="highlight"><pre> <span class="nv">compile_root: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">o.indent: </span><span class="vi">@tab: </span><span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">no_wrap</span> <span class="k">then</span> <span class="s1">&#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="p">(</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="p">)</span>
<span class="nv">code: </span><span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">globals</span> <span class="k">then</span> <span class="nx">@compile_node</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="k">else</span> <span class="nx">@compile_with_declarations</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span>
<span class="nv">code: </span><span class="nx">code</span><span class="p">.</span><span class="nx">replace</span><span class="p">(</span><span class="nx">TRAILING_WHITESPACE</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">)</span>
<span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">no_wrap</span> <span class="k">then</span> <span class="nx">code</span> <span class="k">else</span> <span class="s2">&quot;(function(){\n$code\n})();\n&quot;</span></pre></div> </td> </tr> <tr id="section-28"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-28">#</a> </div> <p>Compile the expressions body for the contents of a function, with
<span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">no_wrap</span> <span class="k">then</span> <span class="nx">code</span> <span class="k">else</span> <span class="s2">&quot;(function(){\n$code\n})();\n&quot;</span></pre></div> </td> </tr> <tr id="section-27"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-27">#</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> <td class="code"> <div class="highlight"><pre> <span class="nv">compile_with_declarations: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">code: </span><span class="nx">@compile_node</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span>
<span class="nv">code: </span><span class="s2">&quot;${@tab}var ${o.scope.compiled_assignments()};\n$code&quot;</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">has_assignments</span><span class="p">(</span><span class="k">this</span><span class="p">)</span>
<span class="nv">code: </span><span class="s2">&quot;${@tab}var ${o.scope.compiled_declarations()};\n$code&quot;</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">has_declarations</span><span class="p">(</span><span class="k">this</span><span class="p">)</span>
<span class="nx">code</span></pre></div> </td> </tr> <tr id="section-29"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-29">#</a> </div> <p>Compiles a single expression within the expressions body. If we need to
<span class="nx">code</span></pre></div> </td> </tr> <tr id="section-28"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-28">#</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> <td class="code"> <div class="highlight"><pre> <span class="nv">compile_expression: </span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="nx">o</span><span class="p">)</span> <span class="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">compiled_node: </span><span class="nx">node</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">merge</span> <span class="nx">o</span><span class="p">,</span> <span class="p">{</span><span class="nv">top: </span><span class="kc">true</span><span class="p">}</span>
<span class="k">if</span> <span class="nx">node</span><span class="p">.</span><span class="nx">is_statement</span><span class="p">()</span> <span class="k">then</span> <span class="nx">compiled_node</span> <span class="k">else</span> <span class="s2">&quot;${@idt()}$compiled_node;&quot;</span></pre></div> </td> </tr> <tr id="section-30"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-30">#</a> </div> <p>Wrap up the given nodes as an <strong>Expressions</strong>, unless it already happens
<span class="k">if</span> <span class="nx">node</span><span class="p">.</span><span class="nx">is_statement</span><span class="p">()</span> <span class="k">then</span> <span class="nx">compiled_node</span> <span class="k">else</span> <span class="s2">&quot;${@idt()}$compiled_node;&quot;</span></pre></div> </td> </tr> <tr id="section-29"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-29">#</a> </div> <p>Wrap up the given nodes as an <strong>Expressions</strong>, unless it already happens
to be one.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">Expressions.wrap: </span><span class="p">(</span><span class="nx">nodes</span><span class="p">)</span> <span class="o">-&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">Expressions</span>
<span class="k">new</span> <span class="nx">Expressions</span><span class="p">(</span><span class="nx">nodes</span><span class="p">)</span>
<span class="nx">statement</span> <span class="nx">Expressions</span></pre></div> </td> </tr> <tr id="section-31"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-31">#</a> </div> <h3>LiteralNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-32"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-32">#</a> </div> <p>Literals are static values that can be passed through directly into
<span class="nx">children</span> <span class="nx">Expressions</span><span class="p">,</span> <span class="s1">&#39;expressions&#39;</span>
<span class="nx">statement</span> <span class="nx">Expressions</span></pre></div> </td> </tr> <tr id="section-30"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-30">#</a> </div> <h3>LiteralNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-31"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-31">#</a> </div> <p>Literals are static values that can be passed through directly into
JavaScript without translation, such as: strings, numbers,
<code>true</code>, <code>false</code>, <code>null</code>...</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.LiteralNode: </span><span class="nx">class</span> <span class="nx">LiteralNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span>
<span class="nv">constructor: </span><span class="p">(</span><span class="nx">value</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="vi">@value: </span><span class="nx">value</span></pre></div> </td> </tr> <tr id="section-33"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-33">#</a> </div> <p>Break and continue must be treated as pure statements -- they lose their
<span class="vi">@value: </span><span class="nx">value</span></pre></div> </td> </tr> <tr id="section-32"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-32">#</a> </div> <p>Break and continue must be treated as pure statements -- they lose their
meaning when wrapped in a closure.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">is_statement: </span><span class="o">-&gt;</span>
<span class="nx">@value</span> <span class="o">is</span> <span class="s1">&#39;break&#39;</span> <span class="o">or</span> <span class="nx">@value</span> <span class="o">is</span> <span class="s1">&#39;continue&#39;</span>
<span class="nv">is_pure_statement: </span><span class="nx">LiteralNode</span><span class="o">::</span><span class="nx">is_statement</span>
@ -139,11 +156,11 @@ meaning when wrapped in a closure.</p> </td> <td class="
<span class="s2">&quot;$idt$@value$end&quot;</span>
<span class="nv">toString: </span><span class="p">(</span><span class="nx">idt</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="s2">&quot; \&quot;$@value\&quot;&quot;</span></pre></div> </td> </tr> <tr id="section-34"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-34">#</a> </div> <h3>ReturnNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-35"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-35">#</a> </div> <p>A <code>return</code> is a <em>pure_statement</em> -- wrapping it in a closure wouldn't
<span class="s2">&quot; \&quot;$@value\&quot;&quot;</span></pre></div> </td> </tr> <tr id="section-33"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-33">#</a> </div> <h3>ReturnNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-34"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-34">#</a> </div> <p>A <code>return</code> is a <em>pure_statement</em> -- wrapping it in a closure wouldn't
make sense.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.ReturnNode: </span><span class="nx">class</span> <span class="nx">ReturnNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span>
<span class="nv">constructor: </span><span class="p">(</span><span class="nx">expression</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="vi">@children: </span><span class="p">[</span><span class="vi">@expression: </span><span class="nx">expression</span><span class="p">]</span>
<span class="vi">@expression: </span><span class="nx">expression</span>
<span class="nv">top_sensitive: </span><span class="o">-&gt;</span>
<span class="kc">true</span>
@ -155,17 +172,18 @@ make sense.</p> </td> <td class="code"> <d
<span class="nv">o.as_statement: </span><span class="kc">true</span> <span class="k">if</span> <span class="nx">@expression</span><span class="p">.</span><span class="nx">is_statement</span><span class="p">()</span>
<span class="s2">&quot;${@tab}return ${@expression.compile(o)};&quot;</span>
<span class="nx">statement</span> <span class="nx">ReturnNode</span><span class="p">,</span> <span class="kc">true</span></pre></div> </td> </tr> <tr id="section-36"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-36">#</a> </div> <h3>ValueNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-37"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-37">#</a> </div> <p>A value, variable or literal or parenthesized, indexed or dotted into,
<span class="nx">statement</span> <span class="nx">ReturnNode</span><span class="p">,</span> <span class="kc">true</span>
<span class="nx">children</span> <span class="nx">ReturnNode</span><span class="p">,</span> <span class="s1">&#39;expression&#39;</span></pre></div> </td> </tr> <tr id="section-35"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-35">#</a> </div> <h3>ValueNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-36"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-36">#</a> </div> <p>A value, variable or literal or parenthesized, indexed or dotted into,
or vanilla.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.ValueNode: </span><span class="nx">class</span> <span class="nx">ValueNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span>
<span class="nv">SOAK: </span><span class="s2">&quot; == undefined ? undefined : &quot;</span></pre></div> </td> </tr> <tr id="section-38"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-38">#</a> </div> <p>A <strong>ValueNode</strong> has a base and a list of property accesses.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">constructor: </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="o">-&gt;</span>
<span class="vi">@children: </span> <span class="nx">flatten</span> <span class="p">[</span><span class="vi">@base: </span><span class="nx">base</span><span class="p">,</span> <span class="vi">@properties: </span><span class="p">(</span><span class="nx">properties</span> <span class="o">or</span> <span class="p">[])]</span></pre></div> </td> </tr> <tr id="section-39"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-39">#</a> </div> <p>Add a property access to the list.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">push: </span><span class="p">(</span><span class="nx">prop</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">SOAK: </span><span class="s2">&quot; == undefined ? undefined : &quot;</span></pre></div> </td> </tr> <tr id="section-37"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-37">#</a> </div> <p>A <strong>ValueNode</strong> has a base and a list of property accesses.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">constructor: </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="o">-&gt;</span>
<span class="vi">@base: </span><span class="nx">base</span>
<span class="vi">@properties: </span><span class="p">(</span><span class="nx">properties</span> <span class="o">or</span> <span class="p">[])</span></pre></div> </td> </tr> <tr id="section-38"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-38">#</a> </div> <p>Add a property access to the list.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">push: </span><span class="p">(</span><span class="nx">prop</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nx">@properties</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">@children</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="k">this</span>
<span class="nv">has_properties: </span><span class="o">-&gt;</span>
<span class="o">!!</span><span class="nx">@properties</span><span class="p">.</span><span class="nx">length</span></pre></div> </td> </tr> <tr id="section-40"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-40">#</a> </div> <p>Some boolean checks for the benefit of other nodes.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">is_array: </span><span class="o">-&gt;</span>
<span class="o">!!</span><span class="nx">@properties</span><span class="p">.</span><span class="nx">length</span></pre></div> </td> </tr> <tr id="section-39"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-39">#</a> </div> <p>Some boolean checks for the benefit of other nodes.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">is_array: </span><span class="o">-&gt;</span>
<span class="nx">@base</span> <span class="k">instanceof</span> <span class="nx">ArrayNode</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">@has_properties</span><span class="p">()</span>
<span class="nv">is_object: </span><span class="o">-&gt;</span>
@ -175,47 +193,58 @@ or vanilla.</p> </td> <td class="code"> <d
<span class="nx">@has_properties</span><span class="p">()</span> <span class="o">and</span> <span class="nx">@properties</span><span class="p">[</span><span class="nx">@properties</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]</span> <span class="k">instanceof</span> <span class="nx">SliceNode</span>
<span class="nv">make_return: </span><span class="o">-&gt;</span>
<span class="k">if</span> <span class="nx">@has_properties</span><span class="p">()</span> <span class="k">then</span> <span class="k">super</span><span class="p">()</span> <span class="k">else</span> <span class="nx">@base</span><span class="p">.</span><span class="nx">make_return</span><span class="p">()</span></pre></div> </td> </tr> <tr id="section-41"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-41">#</a> </div> <p>The value can be unwrapped as its inner node, if there are no attached
<span class="k">if</span> <span class="nx">@has_properties</span><span class="p">()</span> <span class="k">then</span> <span class="k">super</span><span class="p">()</span> <span class="k">else</span> <span class="nx">@base</span><span class="p">.</span><span class="nx">make_return</span><span class="p">()</span></pre></div> </td> </tr> <tr id="section-40"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-40">#</a> </div> <p>The value can be unwrapped as its inner node, if there are no attached
properties.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">unwrap: </span><span class="o">-&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> </td> </tr> <tr id="section-42"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-42">#</a> </div> <p>Values are considered to be statements if their base is a statement.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">is_statement: </span><span class="o">-&gt;</span>
<span class="nx">@base</span><span class="p">.</span><span class="nx">is_statement</span> <span class="o">and</span> <span class="nx">@base</span><span class="p">.</span><span class="nx">is_statement</span><span class="p">()</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">@has_properties</span><span class="p">()</span></pre></div> </td> </tr> <tr id="section-43"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-43">#</a> </div> <p>We compile a value to JavaScript by compiling and joining each property.
<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> </td> </tr> <tr id="section-41"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-41">#</a> </div> <p>Values are considered to be statements if their base is a statement.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">is_statement: </span><span class="o">-&gt;</span>
<span class="nx">@base</span><span class="p">.</span><span class="nx">is_statement</span> <span class="o">and</span> <span class="nx">@base</span><span class="p">.</span><span class="nx">is_statement</span><span class="p">()</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">@has_properties</span><span class="p">()</span></pre></div> </td> </tr> <tr id="section-42"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-42">#</a> </div> <p>Works out if the value is the start of a chain.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">is_start: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="k">return</span> <span class="kc">true</span> <span class="k">if</span> <span class="k">this</span> <span class="o">is</span> <span class="nx">o</span><span class="p">.</span><span class="nx">chain_root</span> <span class="o">and</span> <span class="nx">@properties</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">instanceof</span> <span class="nx">AccessorNode</span>
<span class="nv">node: </span><span class="nx">o</span><span class="p">.</span><span class="nx">chain_root</span><span class="p">.</span><span class="nx">base</span> <span class="o">or</span> <span class="nx">o</span><span class="p">.</span><span class="nx">chain_root</span><span class="p">.</span><span class="nx">variable</span>
<span class="k">while</span> <span class="nx">node</span> <span class="k">instanceof</span> <span class="nx">CallNode</span> <span class="k">then</span> <span class="nv">node: </span><span class="nx">node</span><span class="p">.</span><span class="nx">variable</span>
<span class="nx">node</span> <span class="o">is</span> <span class="k">this</span></pre></div> </td> </tr> <tr id="section-43"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-43">#</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> <td class="code"> <div class="highlight"><pre> <span class="nv">compile_node: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">only: </span> <span class="nx">del</span><span class="p">(</span><span class="nx">o</span><span class="p">,</span> <span class="s1">&#39;only_first&#39;</span><span class="p">)</span>
<span class="nv">op: </span> <span class="nx">del</span><span class="p">(</span><span class="nx">o</span><span class="p">,</span> <span class="s1">&#39;operation&#39;</span><span class="p">)</span>
<span class="nv">props: </span> <span class="k">if</span> <span class="nx">only</span> <span class="k">then</span> <span class="nx">@properties</span><span class="p">[</span><span class="mi">0</span><span class="p">...</span><span class="nx">@properties</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]</span> <span class="k">else</span> <span class="nx">@properties</span>
<span class="nv">o.chain_root: </span><span class="k">this</span> <span class="nx">unless</span> <span class="nx">o</span><span class="p">.</span><span class="nx">chain_root</span>
<span class="nv">o.chain_root: </span><span class="o">or</span> <span class="k">this</span>
<span class="nv">baseline: </span> <span class="nx">@base</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">o</span>
<span class="nv">baseline: </span> <span class="s2">&quot;($baseline)&quot;</span> <span class="k">if</span> <span class="nx">@base</span> <span class="k">instanceof</span> <span class="nx">ObjectNode</span> <span class="o">and</span> <span class="nx">@has_properties</span><span class="p">()</span>
<span class="nv">complete: </span> <span class="vi">@last: </span><span class="nx">baseline</span>
<span class="k">for</span> <span class="nx">prop</span> <span class="k">in</span> <span class="nx">props</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="vi">@source: </span><span class="nx">baseline</span>
<span class="k">if</span> <span class="nx">prop</span><span class="p">.</span><span class="nx">soak_node</span>
<span class="k">if</span> <span class="nx">@base</span> <span class="k">instanceof</span> <span class="nx">CallNode</span> <span class="o">and</span> <span class="nx">prop</span> <span class="o">is</span> <span class="nx">props</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="k">if</span> <span class="nx">@base</span> <span class="k">instanceof</span> <span class="nx">CallNode</span> <span class="o">and</span> <span class="nx">i</span> <span class="o">is</span> <span class="mi">0</span>
<span class="nv">temp: </span><span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">free_variable</span><span class="p">()</span>
<span class="nv">complete: </span><span class="s2">&quot;($temp = $complete)$@SOAK&quot;</span> <span class="o">+</span> <span class="p">(</span><span class="nv">baseline: </span><span class="nx">temp</span> <span class="o">+</span> <span class="nx">prop</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="k">else</span>
<span class="nv">complete: </span><span class="nx">complete</span> <span class="o">+</span> <span class="nx">@SOAK</span> <span class="o">+</span> <span class="p">(</span><span class="nv">baseline: </span><span class="o">+</span> <span class="nx">prop</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="nv">complete: </span><span class="s2">&quot;(${ baseline: temp } = ($complete))&quot;</span>
<span class="nv">complete: </span><span class="s2">&quot;typeof $complete === \&quot;undefined\&quot; || $baseline&quot;</span> <span class="k">if</span> <span class="nx">i</span> <span class="o">is</span> <span class="mi">0</span> <span class="o">and</span> <span class="nx">@is_start</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span>
<span class="nv">complete: </span><span class="o">+</span> <span class="nx">@SOAK</span> <span class="o">+</span> <span class="p">(</span><span class="nv">baseline: </span><span class="o">+</span> <span class="nx">prop</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="k">else</span>
<span class="nv">part: </span><span class="nx">prop</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="nv">baseline: </span><span class="o">+</span> <span class="nx">part</span>
<span class="nv">complete: </span><span class="o">+</span> <span class="nx">part</span>
<span class="vi">@last: </span><span class="nx">part</span>
<span class="k">if</span> <span class="nx">op</span> <span class="o">and</span> <span class="nx">@wrapped</span> <span class="k">then</span> <span class="s2">&quot;($complete)&quot;</span> <span class="k">else</span> <span class="nx">complete</span></pre></div> </td> </tr> <tr id="section-44"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-44">#</a> </div> <h3>CommentNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-45"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-45">#</a> </div> <p>CoffeeScript passes through comments as JavaScript comments at the
<span class="k">if</span> <span class="nx">op</span> <span class="o">and</span> <span class="nx">@wrapped</span> <span class="k">then</span> <span class="s2">&quot;($complete)&quot;</span> <span class="k">else</span> <span class="nx">complete</span>
<span class="nx">children</span> <span class="nx">ValueNode</span><span class="p">,</span> <span class="s1">&#39;base&#39;</span><span class="p">,</span> <span class="s1">&#39;properties&#39;</span></pre></div> </td> </tr> <tr id="section-44"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-44">#</a> </div> <h3>CommentNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-45"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-45">#</a> </div> <p>CoffeeScript passes through comments as JavaScript comments at the
same position.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.CommentNode: </span><span class="nx">class</span> <span class="nx">CommentNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span>
<span class="nv">constructor: </span><span class="p">(</span><span class="nx">lines</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">constructor: </span><span class="p">(</span><span class="nx">lines</span><span class="p">,</span> <span class="nx">type</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="vi">@lines: </span><span class="nx">lines</span>
<span class="vi">@type: </span><span class="nx">type</span>
<span class="k">this</span>
<span class="nv">make_return: </span><span class="o">-&gt;</span>
<span class="k">this</span>
<span class="nv">compile_node: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="s2">&quot;$@tab//&quot;</span> <span class="o">+</span> <span class="nx">@lines</span><span class="p">.</span><span class="nx">join</span><span class="p">(</span><span class="s2">&quot;\n$@tab//&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="nx">@type</span> <span class="o">is</span> <span class="s1">&#39;herecomment&#39;</span>
<span class="nv">sep: </span><span class="s1">&#39;\n&#39;</span> <span class="o">+</span> <span class="nx">@tab</span>
<span class="s2">&quot;$@tab/*$sep${ @lines.join(sep) }\n$@tab*/&quot;</span>
<span class="k">else</span>
<span class="s2">&quot;$@tab//&quot;</span> <span class="o">+</span> <span class="nx">@lines</span><span class="p">.</span><span class="nx">join</span><span class="p">(</span><span class="s2">&quot;\n$@tab//&quot;</span><span class="p">)</span>
<span class="nx">statement</span> <span class="nx">CommentNode</span></pre></div> </td> </tr> <tr id="section-46"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-46">#</a> </div> <h3>CallNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-47"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-47">#</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> <td class="code"> <div class="highlight"><pre><span class="nv">exports.CallNode: </span><span class="nx">class</span> <span class="nx">CallNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span>
@ -224,7 +253,7 @@ calls against the prototype's function of the same name.</p> </td>
<span class="vi">@is_new: </span> <span class="kc">false</span>
<span class="vi">@is_super: </span><span class="nx">variable</span> <span class="o">is</span> <span class="s1">&#39;super&#39;</span>
<span class="vi">@variable: </span><span class="k">if</span> <span class="nx">@is_super</span> <span class="k">then</span> <span class="kc">null</span> <span class="k">else</span> <span class="nx">variable</span>
<span class="vi">@children: </span><span class="nx">compact</span> <span class="nx">flatten</span> <span class="p">[</span><span class="nx">@variable</span><span class="p">,</span> <span class="vi">@args: </span><span class="p">(</span><span class="nx">args</span> <span class="o">or</span> <span class="p">[])]</span>
<span class="vi">@args: </span><span class="p">(</span><span class="nx">args</span> <span class="o">or</span> <span class="p">[])</span>
<span class="vi">@compile_splat_arguments: </span><span class="nx">SplatNode</span><span class="p">.</span><span class="nx">compile_mixed_array</span> <span class="o">&lt;-</span> <span class="err">@</span><span class="p">,</span> <span class="nx">@args</span></pre></div> </td> </tr> <tr id="section-48"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-48">#</a> </div> <p>Tag this invocation as creating a new instance.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">new_instance: </span><span class="o">-&gt;</span>
<span class="vi">@is_new: </span><span class="kc">true</span>
<span class="k">this</span>
@ -254,12 +283,16 @@ of the current function.</p> </td> <td class="code">
<span class="nv">temp: </span><span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">free_variable</span><span class="p">()</span>
<span class="nv">obj: </span> <span class="nx">temp</span>
<span class="nv">meth: </span><span class="s2">&quot;($temp = ${ @variable.source })${ @variable.last }&quot;</span>
<span class="s2">&quot;${@prefix()}${meth}.apply($obj, ${ @compile_splat_arguments(o) })&quot;</span></pre></div> </td> </tr> <tr id="section-53"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-53">#</a> </div> <h3>CurryNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-54"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-54">#</a> </div> <p>Binds a context object and a list of arguments to a function,
<span class="s2">&quot;${@prefix()}${meth}.apply($obj, ${ @compile_splat_arguments(o) })&quot;</span>
<span class="nx">children</span> <span class="nx">CallNode</span><span class="p">,</span> <span class="s1">&#39;variable&#39;</span><span class="p">,</span> <span class="s1">&#39;args&#39;</span></pre></div> </td> </tr> <tr id="section-53"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-53">#</a> </div> <h3>CurryNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-54"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-54">#</a> </div> <p>Binds a context object and a list of arguments to a function,
returning the bound function. After ECMAScript 5, Prototype.js, and
Underscore's <code>bind</code> functions.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.CurryNode: </span><span class="nx">class</span> <span class="nx">CurryNode</span> <span class="k">extends</span> <span class="nx">CallNode</span>
<span class="nv">constructor: </span><span class="p">(</span><span class="nx">meth</span><span class="p">,</span> <span class="nx">args</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="vi">@children: </span> <span class="nx">flatten</span> <span class="p">[</span><span class="vi">@meth: </span><span class="nx">meth</span><span class="p">,</span> <span class="vi">@context: </span><span class="nx">args</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="vi">@args: </span><span class="p">(</span><span class="nx">args</span><span class="p">.</span><span class="nx">slice</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="o">or</span> <span class="p">[])]</span>
<span class="vi">@meth: </span><span class="nx">meth</span>
<span class="vi">@context: </span><span class="nx">args</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="vi">@args: </span><span class="p">(</span><span class="nx">args</span><span class="p">.</span><span class="nx">slice</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="o">or</span> <span class="p">[])</span>
<span class="vi">@compile_splat_arguments: </span><span class="nx">SplatNode</span><span class="p">.</span><span class="nx">compile_mixed_array</span> <span class="o">&lt;-</span> <span class="err">@</span><span class="p">,</span> <span class="nx">@args</span>
<span class="nv">arguments: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
@ -270,18 +303,23 @@ Underscore's <code>bind</code> functions.</p> </td> <td
<span class="nv">compile_node: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nx">utility</span> <span class="s1">&#39;slice&#39;</span>
<span class="nv">ref: </span><span class="k">new</span> <span class="nx">ValueNode</span> <span class="nx">literal</span> <span class="nx">utility</span> <span class="s1">&#39;bind&#39;</span>
<span class="p">(</span><span class="k">new</span> <span class="nx">CallNode</span><span class="p">(</span><span class="nx">ref</span><span class="p">,</span> <span class="p">[</span><span class="nx">@meth</span><span class="p">,</span> <span class="nx">@context</span><span class="p">,</span> <span class="nx">literal</span><span class="p">(</span><span class="nx">@arguments</span><span class="p">(</span><span class="nx">o</span><span class="p">))])).</span><span class="nx">compile</span> <span class="nx">o</span></pre></div> </td> </tr> <tr id="section-55"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-55">#</a> </div> <h3>ExtendsNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-56"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-56">#</a> </div> <p>Node to extend an object's prototype with an ancestor object.
<span class="p">(</span><span class="k">new</span> <span class="nx">CallNode</span><span class="p">(</span><span class="nx">ref</span><span class="p">,</span> <span class="p">[</span><span class="nx">@meth</span><span class="p">,</span> <span class="nx">@context</span><span class="p">,</span> <span class="nx">literal</span><span class="p">(</span><span class="nx">@arguments</span><span class="p">(</span><span class="nx">o</span><span class="p">))])).</span><span class="nx">compile</span> <span class="nx">o</span>
<span class="nx">children</span> <span class="nx">CurryNode</span><span class="p">,</span> <span class="s1">&#39;meth&#39;</span><span class="p">,</span> <span class="s1">&#39;context&#39;</span><span class="p">,</span> <span class="s1">&#39;args&#39;</span></pre></div> </td> </tr> <tr id="section-55"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-55">#</a> </div> <h3>ExtendsNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-56"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-56">#</a> </div> <p>Node to extend an object's prototype with an ancestor object.
After <code>goog.inherits</code> from the
<a href="http://closure-library.googlecode.com/svn/docs/closure_goog_base.js.html">Closure Library</a>.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.ExtendsNode: </span><span class="nx">class</span> <span class="nx">ExtendsNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span>
<span class="nv">constructor: </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="o">-&gt;</span>
<span class="vi">@children: </span> <span class="p">[</span><span class="vi">@child: </span><span class="nx">child</span><span class="p">,</span> <span class="vi">@parent: </span><span class="nx">parent</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-57"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-57">#</a> </div> <p>Hooks one constructor into another's prototype chain.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compile_node: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="vi">@child: </span><span class="nx">child</span>
<span class="vi">@parent: </span><span class="nx">parent</span></pre></div> </td> </tr> <tr id="section-57"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-57">#</a> </div> <p>Hooks one constructor into another's prototype chain.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compile_node: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">ref: </span> <span class="k">new</span> <span class="nx">ValueNode</span> <span class="nx">literal</span> <span class="nx">utility</span> <span class="s1">&#39;extends&#39;</span>
<span class="p">(</span><span class="k">new</span> <span class="nx">CallNode</span> <span class="nx">ref</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">compile</span> <span class="nx">o</span></pre></div> </td> </tr> <tr id="section-58"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-58">#</a> </div> <h3>AccessorNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-59"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-59">#</a> </div> <p>A <code>.</code> accessor into a property of a value, or the <code>::</code> shorthand for
<span class="p">(</span><span class="k">new</span> <span class="nx">CallNode</span> <span class="nx">ref</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">compile</span> <span class="nx">o</span>
<span class="nx">children</span> <span class="nx">ExtendsNode</span><span class="p">,</span> <span class="s1">&#39;child&#39;</span><span class="p">,</span> <span class="s1">&#39;parent&#39;</span></pre></div> </td> </tr> <tr id="section-58"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-58">#</a> </div> <h3>AccessorNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-59"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-59">#</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> <td class="code"> <div class="highlight"><pre><span class="nv">exports.AccessorNode: </span><span class="nx">class</span> <span class="nx">AccessorNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span>
<span class="nv">constructor: </span><span class="p">(</span><span class="nx">name</span><span class="p">,</span> <span class="nx">tag</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="vi">@children: </span> <span class="p">[</span><span class="vi">@name: </span><span class="nx">name</span><span class="p">]</span>
<span class="vi">@name: </span><span class="nx">name</span>
<span class="vi">@prototype: </span><span class="nx">tag</span> <span class="o">is</span> <span class="s1">&#39;prototype&#39;</span>
<span class="vi">@soak_node: </span><span class="nx">tag</span> <span class="o">is</span> <span class="s1">&#39;soak&#39;</span>
<span class="k">this</span>
@ -289,21 +327,26 @@ an accessor into the object's prototype.</p> </td> <td c
<span class="nv">compile_node: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">o.chain_root.wrapped: </span><span class="o">or</span> <span class="nx">@soak_node</span>
<span class="nv">proto_part: </span><span class="k">if</span> <span class="nx">@prototype</span> <span class="k">then</span> <span class="s1">&#39;prototype.&#39;</span> <span class="k">else</span> <span class="s1">&#39;&#39;</span>
<span class="s2">&quot;.$proto_part${@name.compile(o)}&quot;</span></pre></div> </td> </tr> <tr id="section-60"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-60">#</a> </div> <h3>IndexNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-61"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-61">#</a> </div> <p>A <code>[ ... ]</code> indexed accessor into an array or object.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.IndexNode: </span><span class="nx">class</span> <span class="nx">IndexNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span>
<span class="s2">&quot;.$proto_part${@name.compile(o)}&quot;</span>
<span class="nx">children</span> <span class="nx">AccessorNode</span><span class="p">,</span> <span class="s1">&#39;name&#39;</span></pre></div> </td> </tr> <tr id="section-60"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-60">#</a> </div> <h3>IndexNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-61"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-61">#</a> </div> <p>A <code>[ ... ]</code> indexed accessor into an array or object.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.IndexNode: </span><span class="nx">class</span> <span class="nx">IndexNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span>
<span class="nv">constructor: </span><span class="p">(</span><span class="nx">index</span><span class="p">,</span> <span class="nx">tag</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="vi">@children: </span> <span class="p">[</span><span class="vi">@index: </span><span class="nx">index</span><span class="p">]</span>
<span class="vi">@index: </span><span class="nx">index</span>
<span class="vi">@soak_node: </span><span class="nx">tag</span> <span class="o">is</span> <span class="s1">&#39;soak&#39;</span>
<span class="nv">compile_node: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">o.chain_root.wrapped: </span><span class="o">or</span> <span class="nx">@soak_node</span>
<span class="nv">idx: </span><span class="nx">@index</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">o</span>
<span class="s2">&quot;[$idx]&quot;</span></pre></div> </td> </tr> <tr id="section-62"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-62">#</a> </div> <h3>RangeNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-63"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-63">#</a> </div> <p>A range literal. Ranges can be used to extract portions (slices) of arrays,
<span class="s2">&quot;[$idx]&quot;</span>
<span class="nx">children</span> <span class="nx">IndexNode</span><span class="p">,</span> <span class="s1">&#39;index&#39;</span></pre></div> </td> </tr> <tr id="section-62"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-62">#</a> </div> <h3>RangeNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-63"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-63">#</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> <td class="code"> <div class="highlight"><pre><span class="nv">exports.RangeNode: </span><span class="nx">class</span> <span class="nx">RangeNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span>
<span class="nv">constructor: </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">-&gt;</span>
<span class="vi">@children: </span> <span class="p">[</span><span class="vi">@from: </span><span class="nx">from</span><span class="p">,</span> <span class="vi">@to: </span><span class="nx">to</span><span class="p">]</span>
<span class="vi">@from: </span><span class="nx">from</span>
<span class="vi">@to: </span><span class="nx">to</span>
<span class="vi">@exclusive: </span><span class="o">!!</span><span class="nx">exclusive</span></pre></div> </td> </tr> <tr id="section-64"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-64">#</a> </div> <p>Compiles the range's source variables -- where it starts and where it ends.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compile_variables: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="vi">@tab: </span><span class="nx">o</span><span class="p">.</span><span class="nx">indent</span>
<span class="p">[</span><span class="nx">@from_var</span><span class="p">,</span> <span class="nx">@to_var</span><span class="p">]</span><span class="o">:</span> <span class="p">[</span><span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">free_variable</span><span class="p">(),</span> <span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">free_variable</span><span class="p">()]</span>
@ -325,22 +368,26 @@ it instead of wrapping nodes.</p> </td> <td class="code"
<span class="nv">name: </span><span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">free_variable</span><span class="p">()</span>
<span class="nv">body: </span><span class="nx">Expressions</span><span class="p">.</span><span class="nx">wrap</span><span class="p">([</span><span class="nx">literal</span><span class="p">(</span><span class="nx">name</span><span class="p">)])</span>
<span class="nv">arr: </span> <span class="nx">Expressions</span><span class="p">.</span><span class="nx">wrap</span><span class="p">([</span><span class="k">new</span> <span class="nx">ForNode</span><span class="p">(</span><span class="nx">body</span><span class="p">,</span> <span class="p">{</span><span class="nv">source: </span><span class="p">(</span><span class="k">new</span> <span class="nx">ValueNode</span><span class="p">(</span><span class="k">this</span><span class="p">))},</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">ParentheticalNode</span><span class="p">(</span><span class="k">new</span> <span class="nx">CallNode</span><span class="p">(</span><span class="k">new</span> <span class="nx">CodeNode</span><span class="p">([],</span> <span class="nx">arr</span><span class="p">.</span><span class="nx">make_return</span><span class="p">())))).</span><span class="nx">compile</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span></pre></div> </td> </tr> <tr id="section-67"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-67">#</a> </div> <h3>SliceNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-68"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-68">#</a> </div> <p>An array slice literal. Unlike JavaScript's <code>Array#slice</code>, the second parameter
<span class="p">(</span><span class="k">new</span> <span class="nx">ParentheticalNode</span><span class="p">(</span><span class="k">new</span> <span class="nx">CallNode</span><span class="p">(</span><span class="k">new</span> <span class="nx">CodeNode</span><span class="p">([],</span> <span class="nx">arr</span><span class="p">.</span><span class="nx">make_return</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">children</span> <span class="nx">RangeNode</span><span class="p">,</span> <span class="s1">&#39;from&#39;</span><span class="p">,</span> <span class="s1">&#39;to&#39;</span></pre></div> </td> </tr> <tr id="section-67"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-67">#</a> </div> <h3>SliceNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-68"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-68">#</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> <td class="code"> <div class="highlight"><pre><span class="nv">exports.SliceNode: </span><span class="nx">class</span> <span class="nx">SliceNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span>
<span class="nv">constructor: </span><span class="p">(</span><span class="nx">range</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="vi">@children: </span><span class="p">[</span><span class="vi">@range: </span><span class="nx">range</span><span class="p">]</span>
<span class="vi">@range: </span><span class="nx">range</span>
<span class="k">this</span>
<span class="nv">compile_node: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">from: </span> <span class="nx">@range</span><span class="p">.</span><span class="nx">from</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="nv">to: </span> <span class="nx">@range</span><span class="p">.</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="nv">plus_part: </span> <span class="k">if</span> <span class="nx">@range</span><span class="p">.</span><span class="nx">exclusive</span> <span class="k">then</span> <span class="s1">&#39;&#39;</span> <span class="k">else</span> <span class="s1">&#39; + 1&#39;</span>
<span class="s2">&quot;.slice($from, $to$plus_part)&quot;</span></pre></div> </td> </tr> <tr id="section-69"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-69">#</a> </div> <h3>ObjectNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-70"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-70">#</a> </div> <p>An object literal, nothing fancy.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.ObjectNode: </span><span class="nx">class</span> <span class="nx">ObjectNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span>
<span class="s2">&quot;.slice($from, $to$plus_part)&quot;</span>
<span class="nx">children</span> <span class="nx">SliceNode</span><span class="p">,</span> <span class="s1">&#39;range&#39;</span></pre></div> </td> </tr> <tr id="section-69"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-69">#</a> </div> <h3>ObjectNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-70"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-70">#</a> </div> <p>An object literal, nothing fancy.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.ObjectNode: </span><span class="nx">class</span> <span class="nx">ObjectNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span>
<span class="nv">constructor: </span><span class="p">(</span><span class="nx">props</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="vi">@children: @objects: @properties: </span><span class="nx">props</span> <span class="o">or</span> <span class="p">[]</span></pre></div> </td> </tr> <tr id="section-71"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-71">#</a> </div> <p>All the mucking about with commas is to make sure that CommentNodes and
<span class="vi">@objects: @properties: </span><span class="nx">props</span> <span class="o">or</span> <span class="p">[]</span></pre></div> </td> </tr> <tr id="section-71"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-71">#</a> </div> <p>All the mucking about with commas is to make sure that CommentNodes and
AssignNodes get interleaved correctly, with no trailing commas or
commas affixed to comments.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compile_node: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">o.indent: </span><span class="nx">@idt</span> <span class="mi">1</span>
@ -355,10 +402,12 @@ commas affixed to comments.</p> </td> <td class="code">
<span class="nx">indent</span> <span class="o">+</span> <span class="nx">prop</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="nx">join</span>
<span class="nv">props: </span><span class="nx">props</span><span class="p">.</span><span class="nx">join</span><span class="p">(</span><span class="s1">&#39;&#39;</span><span class="p">)</span>
<span class="nv">inner: </span><span class="k">if</span> <span class="nx">props</span> <span class="k">then</span> <span class="s1">&#39;\n&#39;</span> <span class="o">+</span> <span class="nx">props</span> <span class="o">+</span> <span class="s1">&#39;\n&#39;</span> <span class="o">+</span> <span class="nx">@idt</span><span class="p">()</span> <span class="k">else</span> <span class="s1">&#39;&#39;</span>
<span class="s2">&quot;{$inner}&quot;</span></pre></div> </td> </tr> <tr id="section-72"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-72">#</a> </div> <h3>ArrayNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-73"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-73">#</a> </div> <p>An array literal.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.ArrayNode: </span><span class="nx">class</span> <span class="nx">ArrayNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span>
<span class="s2">&quot;{$inner}&quot;</span>
<span class="nx">children</span> <span class="nx">ObjectNode</span><span class="p">,</span> <span class="s1">&#39;properties&#39;</span></pre></div> </td> </tr> <tr id="section-72"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-72">#</a> </div> <h3>ArrayNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-73"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-73">#</a> </div> <p>An array literal.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.ArrayNode: </span><span class="nx">class</span> <span class="nx">ArrayNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span>
<span class="nv">constructor: </span><span class="p">(</span><span class="nx">objects</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="vi">@children: @objects: </span><span class="nx">objects</span> <span class="o">or</span> <span class="p">[]</span>
<span class="vi">@objects: </span><span class="nx">objects</span> <span class="o">or</span> <span class="p">[]</span>
<span class="vi">@compile_splat_literal: </span><span class="nx">SplatNode</span><span class="p">.</span><span class="nx">compile_mixed_array</span> <span class="o">&lt;-</span> <span class="err">@</span><span class="p">,</span> <span class="nx">@objects</span>
<span class="nv">compile_node: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
@ -375,12 +424,16 @@ commas affixed to comments.</p> </td> <td class="code">
<span class="k">else</span>
<span class="nx">objects</span><span class="p">.</span><span class="nx">push</span> <span class="s2">&quot;$code, &quot;</span>
<span class="nv">objects: </span><span class="nx">objects</span><span class="p">.</span><span class="nx">join</span><span class="p">(</span><span class="s1">&#39;&#39;</span><span class="p">)</span>
<span class="k">if</span> <span class="nx">objects</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="s1">&#39;\n&#39;</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="mi">0</span>
<span class="k">if</span> <span class="nx">index_of</span><span class="p">(</span><span class="nx">objects</span><span class="p">,</span> <span class="s1">&#39;\n&#39;</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="mi">0</span>
<span class="s2">&quot;[\n${@idt(1)}$objects\n$@tab]&quot;</span>
<span class="k">else</span>
<span class="s2">&quot;[$objects]&quot;</span></pre></div> </td> </tr> <tr id="section-74"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-74">#</a> </div> <h3>ClassNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-75"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-75">#</a> </div> <p>The CoffeeScript class definition.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.ClassNode: </span><span class="nx">class</span> <span class="nx">ClassNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span></pre></div> </td> </tr> <tr id="section-76"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-76">#</a> </div> <p>Initialize a <strong>ClassNode</strong> with its name, an optional superclass, and a
<span class="s2">&quot;[$objects]&quot;</span>
<span class="nx">children</span> <span class="nx">ArrayNode</span><span class="p">,</span> <span class="s1">&#39;objects&#39;</span></pre></div> </td> </tr> <tr id="section-74"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-74">#</a> </div> <h3>ClassNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-75"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-75">#</a> </div> <p>The CoffeeScript class definition.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.ClassNode: </span><span class="nx">class</span> <span class="nx">ClassNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span></pre></div> </td> </tr> <tr id="section-76"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-76">#</a> </div> <p>Initialize a <strong>ClassNode</strong> with its name, an optional superclass, and a
list of prototype property assignments.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">constructor: </span><span class="p">(</span><span class="nx">variable</span><span class="p">,</span> <span class="nx">parent</span><span class="p">,</span> <span class="nx">props</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="vi">@children: </span><span class="nx">compact</span> <span class="nx">flatten</span> <span class="p">[</span><span class="vi">@variable: </span><span class="nx">variable</span><span class="p">,</span> <span class="vi">@parent: </span><span class="nx">parent</span><span class="p">,</span> <span class="vi">@properties: </span><span class="nx">props</span> <span class="o">or</span> <span class="p">[]]</span>
<span class="vi">@variable: </span><span class="nx">variable</span>
<span class="vi">@parent: </span><span class="nx">parent</span>
<span class="vi">@properties: </span><span class="nx">props</span> <span class="o">or</span> <span class="p">[]</span>
<span class="vi">@returns: </span> <span class="kc">false</span>
<span class="nv">make_return: </span><span class="o">-&gt;</span>
@ -420,12 +473,14 @@ constructor, property assignments, and inheritance getting built out below.</p>
<span class="nv">returns: </span> <span class="k">if</span> <span class="nx">@returns</span> <span class="k">then</span> <span class="k">new</span> <span class="nx">ReturnNode</span><span class="p">(</span><span class="nx">@variable</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="k">else</span> <span class="s1">&#39;&#39;</span>
<span class="s2">&quot;$construct$extension$props$returns&quot;</span>
<span class="nx">statement</span> <span class="nx">ClassNode</span></pre></div> </td> </tr> <tr id="section-78"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-78">#</a> </div> <h3>AssignNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-79"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-79">#</a> </div> <p>The <strong>AssignNode</strong> is used to assign a local variable to value, or to set the
<span class="nx">statement</span> <span class="nx">ClassNode</span>
<span class="nx">children</span> <span class="nx">ClassNode</span><span class="p">,</span> <span class="s1">&#39;variable&#39;</span><span class="p">,</span> <span class="s1">&#39;parent&#39;</span><span class="p">,</span> <span class="s1">&#39;properties&#39;</span></pre></div> </td> </tr> <tr id="section-78"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-78">#</a> </div> <h3>AssignNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-79"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-79">#</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> <td class="code"> <div class="highlight"><pre><span class="nv">exports.AssignNode: </span><span class="nx">class</span> <span class="nx">AssignNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span></pre></div> </td> </tr> <tr id="section-80"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-80">#</a> </div> <p>Matchers for detecting prototype assignments.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">PROTO_ASSIGN: </span><span class="sr">/^(\S+)\.prototype/</span>
<span class="nv">LEADING_DOT: </span> <span class="sr">/^\.(prototype\.)?/</span>
<span class="nv">constructor: </span><span class="p">(</span><span class="nx">variable</span><span class="p">,</span> <span class="nx">value</span><span class="p">,</span> <span class="nx">context</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="vi">@children: </span><span class="p">[</span><span class="vi">@variable: </span><span class="nx">variable</span><span class="p">,</span> <span class="vi">@value: </span><span class="nx">value</span><span class="p">]</span>
<span class="vi">@variable: </span><span class="nx">variable</span>
<span class="vi">@value: </span><span class="nx">value</span>
<span class="vi">@context: </span><span class="nx">context</span>
<span class="nv">top_sensitive: </span><span class="o">-&gt;</span>
@ -478,7 +533,7 @@ for details.</p> </td> <td class="code"> <
<span class="nv">access_class: </span><span class="k">if</span> <span class="nx">is_string</span> <span class="o">or</span> <span class="nx">@variable</span><span class="p">.</span><span class="nx">is_array</span><span class="p">()</span> <span class="k">then</span> <span class="nx">IndexNode</span> <span class="k">else</span> <span class="nx">AccessorNode</span>
<span class="k">if</span> <span class="nx">obj</span> <span class="k">instanceof</span> <span class="nx">SplatNode</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">splat</span>
<span class="nv">val: </span><span class="nx">literal</span><span class="p">(</span><span class="nx">obj</span><span class="p">.</span><span class="nx">compile_value</span><span class="p">(</span><span class="nx">o</span><span class="p">,</span> <span class="nx">val_var</span><span class="p">,</span>
<span class="p">(</span><span class="nv">oindex: </span><span class="nx">@variable</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">indexOf</span><span class="p">(</span><span class="nx">obj</span><span class="p">)),</span>
<span class="p">(</span><span class="nv">oindex: </span><span class="nx">index_of</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">objects</span><span class="p">,</span> <span class="nx">obj</span><span class="p">)),</span>
<span class="p">(</span><span class="nv">olength: </span><span class="nx">@variable</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="p">)</span> <span class="o">-</span> <span class="nx">oindex</span> <span class="o">-</span> <span class="mi">1</span><span class="p">))</span>
<span class="nv">splat: </span><span class="kc">true</span>
<span class="k">else</span>
@ -495,7 +550,9 @@ for details.</p> </td> <td class="code"> <
<span class="nv">from: </span> <span class="nx">range</span><span class="p">.</span><span class="nx">from</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="nv">to: </span> <span class="nx">range</span><span class="p">.</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="s1">&#39; - &#39;</span> <span class="o">+</span> <span class="nx">from</span> <span class="o">+</span> <span class="nx">plus</span>
<span class="nv">val: </span> <span class="nx">@value</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="s2">&quot;${name}.splice.apply($name, [$from, $to].concat($val))&quot;</span></pre></div> </td> </tr> <tr id="section-87"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-87">#</a> </div> <h3>CodeNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-88"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-88">#</a> </div> <p>A function definition. This is the only node that creates a new Scope.
<span class="s2">&quot;${name}.splice.apply($name, [$from, $to].concat($val))&quot;</span>
<span class="nx">children</span> <span class="nx">AssignNode</span><span class="p">,</span> <span class="s1">&#39;variable&#39;</span><span class="p">,</span> <span class="s1">&#39;value&#39;</span></pre></div> </td> </tr> <tr id="section-87"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-87">#</a> </div> <h3>CodeNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-88"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-88">#</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> <td class="code"> <div class="highlight"><pre><span class="nv">exports.CodeNode: </span><span class="nx">class</span> <span class="nx">CodeNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span>
@ -521,8 +578,9 @@ a closure.</p> </td> <td class="code"> <di
<span class="k">if</span> <span class="nx">param</span> <span class="k">instanceof</span> <span class="nx">SplatNode</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">splat</span><span class="o">?</span>
<span class="nv">splat: </span><span class="nx">param</span>
<span class="nv">splat.index: </span><span class="nx">i</span>
<span class="nx">@body</span><span class="p">.</span><span class="nx">unshift</span><span class="p">(</span><span class="nx">splat</span><span class="p">)</span>
<span class="nv">splat.trailings: </span><span class="p">[]</span>
<span class="nv">splat.arglength: </span><span class="nx">@params</span><span class="p">.</span><span class="nx">length</span>
<span class="nx">@body</span><span class="p">.</span><span class="nx">unshift</span><span class="p">(</span><span class="nx">splat</span><span class="p">)</span>
<span class="k">else</span> <span class="k">if</span> <span class="nx">splat</span><span class="o">?</span>
<span class="nx">splat</span><span class="p">.</span><span class="nx">trailings</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">param</span><span class="p">)</span>
<span class="k">else</span>
@ -532,8 +590,7 @@ a closure.</p> </td> <td class="code"> <di
<span class="nx">@body</span><span class="p">.</span><span class="nx">make_return</span><span class="p">()</span>
<span class="p">(</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="p">(</span><span class="nx">param</span><span class="p">))</span> <span class="k">for</span> <span class="nx">param</span> <span class="k">in</span> <span class="nx">params</span>
<span class="nv">code: </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="k">then</span> <span class="s2">&quot;\n${ @body.compile_with_declarations(o) }\n&quot;</span> <span class="k">else</span> <span class="s1">&#39;&#39;</span>
<span class="nv">name_part: </span><span class="k">if</span> <span class="nx">@name</span> <span class="k">then</span> <span class="s1">&#39; &#39;</span> <span class="o">+</span> <span class="nx">@name</span> <span class="k">else</span> <span class="s1">&#39;&#39;</span>
<span class="nv">func: </span><span class="s2">&quot;function${ if @bound then &#39;&#39; else name_part }(${ params.join(&#39;, &#39;) }) {$code${@idt(if @bound then 1 else 0)}}&quot;</span>
<span class="nv">func: </span><span class="s2">&quot;function(${ params.join(&#39;, &#39;) }) {$code${@idt(if @bound then 1 else 0)}}&quot;</span>
<span class="nv">func: </span><span class="s2">&quot;($func)&quot;</span> <span class="k">if</span> <span class="nx">top</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">@bound</span>
<span class="k">return</span> <span class="nx">func</span> <span class="nx">unless</span> <span class="nx">@bound</span>
<span class="nx">utility</span> <span class="s1">&#39;slice&#39;</span>
@ -541,35 +598,37 @@ a closure.</p> </td> <td class="code"> <di
<span class="p">(</span><span class="k">new</span> <span class="nx">CallNode</span> <span class="nx">ref</span><span class="p">,</span> <span class="p">[</span><span class="nx">literal</span><span class="p">(</span><span class="nx">func</span><span class="p">),</span> <span class="nx">literal</span><span class="p">(</span><span class="s1">&#39;this&#39;</span><span class="p">)]).</span><span class="nx">compile</span> <span class="nx">o</span>
<span class="nv">top_sensitive: </span><span class="o">-&gt;</span>
<span class="kc">true</span></pre></div> </td> </tr> <tr id="section-90"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-90">#</a> </div> <p>When traversing (for printing or inspecting), return the real children of
the function -- the parameters and body of expressions.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">real_children: </span><span class="o">-&gt;</span>
<span class="nx">flatten</span> <span class="p">[</span><span class="nx">@params</span><span class="p">,</span> <span class="nx">@body</span><span class="p">.</span><span class="nx">expressions</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-91"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-91">#</a> </div> <p>Custom <code>traverse</code> implementation that uses the <code>real_children</code>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">traverse: </span><span class="p">(</span><span class="nx">block</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nx">block</span> <span class="k">this</span>
<span class="nx">child</span><span class="p">.</span><span class="nx">traverse</span> <span class="nx">block</span> <span class="k">for</span> <span class="nx">child</span> <span class="k">in</span> <span class="nx">@real_children</span><span class="p">()</span>
<span class="kc">true</span></pre></div> </td> </tr> <tr id="section-90"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-90">#</a> </div> <p>Short-circuit traverse<em>children method to prevent it from crossing scope boundaries
unless cross</em>scope is true</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">traverse_children: </span><span class="p">(</span><span class="nx">cross_scope</span><span class="p">,</span> <span class="nx">func</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="k">super</span><span class="p">(</span><span class="nx">cross_scope</span><span class="p">,</span> <span class="nx">func</span><span class="p">)</span> <span class="k">if</span> <span class="nx">cross_scope</span>
<span class="nv">toString: </span><span class="p">(</span><span class="nx">idt</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">idt: </span><span class="o">or</span> <span class="s1">&#39;&#39;</span>
<span class="nv">children: </span><span class="p">(</span><span class="nx">child</span><span class="p">.</span><span class="nx">toString</span><span class="p">(</span><span class="nx">idt</span> <span class="o">+</span> <span class="nx">TAB</span><span class="p">)</span> <span class="k">for</span> <span class="nx">child</span> <span class="k">in</span> <span class="nx">@real_children</span><span class="p">()).</span><span class="nx">join</span><span class="p">(</span><span class="s1">&#39;&#39;</span><span class="p">)</span>
<span class="s2">&quot;\n$idt$children&quot;</span></pre></div> </td> </tr> <tr id="section-92"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-92">#</a> </div> <h3>SplatNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-93"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-93">#</a> </div> <p>A splat, either as a parameter to a function, an argument to a call,
<span class="nv">children: </span><span class="p">(</span><span class="nx">child</span><span class="p">.</span><span class="nx">toString</span><span class="p">(</span><span class="nx">idt</span> <span class="o">+</span> <span class="nx">TAB</span><span class="p">)</span> <span class="k">for</span> <span class="nx">child</span> <span class="k">in</span> <span class="nx">@children</span><span class="p">()).</span><span class="nx">join</span><span class="p">(</span><span class="s1">&#39;&#39;</span><span class="p">)</span>
<span class="s2">&quot;\n$idt$children&quot;</span>
<span class="nx">children</span> <span class="nx">CodeNode</span><span class="p">,</span> <span class="s1">&#39;params&#39;</span><span class="p">,</span> <span class="s1">&#39;body&#39;</span></pre></div> </td> </tr> <tr id="section-91"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-91">#</a> </div> <h3>SplatNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-92"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-92">#</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> <td class="code"> <div class="highlight"><pre><span class="nv">exports.SplatNode: </span><span class="nx">class</span> <span class="nx">SplatNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span>
<span class="nv">constructor: </span><span class="p">(</span><span class="nx">name</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">name: </span><span class="nx">literal</span><span class="p">(</span><span class="nx">name</span><span class="p">)</span> <span class="nx">unless</span> <span class="nx">name</span><span class="p">.</span><span class="nx">compile</span>
<span class="vi">@children: </span><span class="p">[</span><span class="vi">@name: </span><span class="nx">name</span><span class="p">]</span>
<span class="vi">@name: </span><span class="nx">name</span>
<span class="nv">compile_node: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="k">if</span> <span class="nx">@index</span><span class="o">?</span> <span class="k">then</span> <span class="nx">@compile_param</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="k">else</span> <span class="nx">@name</span><span class="p">.</span><span class="nx">compile</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span></pre></div> </td> </tr> <tr id="section-94"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-94">#</a> </div> <p>Compiling a parameter splat means recovering the parameters that succeed
<span class="k">if</span> <span class="nx">@index</span><span class="o">?</span> <span class="k">then</span> <span class="nx">@compile_param</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="k">else</span> <span class="nx">@name</span><span class="p">.</span><span class="nx">compile</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span></pre></div> </td> </tr> <tr id="section-93"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-93">#</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> <td class="code"> <div class="highlight"><pre> <span class="nv">compile_param: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">name: </span><span class="nx">@name</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">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="nv">i: </span><span class="mi">0</span>
<span class="k">for</span> <span class="nx">trailing</span> <span class="k">in</span> <span class="nx">@trailings</span>
<span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">assign</span><span class="p">(</span><span class="nx">trailing</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="s2">&quot;arguments[arguments.length - $@trailings.length + $i]&quot;</span><span class="p">)</span>
<span class="nv">i: </span><span class="o">+</span> <span class="mi">1</span>
<span class="s2">&quot;$name = ${utility(&#39;slice&#39;)}.call(arguments, $@index, arguments.length - ${@trailings.length})&quot;</span></pre></div> </td> </tr> <tr id="section-95"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-95">#</a> </div> <p>A compiling a splat as a destructuring assignment means slicing arguments
<span class="nv">len: </span><span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">free_variable</span><span class="p">()</span>
<span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">assign</span> <span class="nx">len</span><span class="p">,</span> <span class="s2">&quot;arguments.length&quot;</span>
<span class="nv">variadic: </span><span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">free_variable</span><span class="p">()</span>
<span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">assign</span> <span class="nx">variadic</span><span class="p">,</span> <span class="s2">&quot;$len &gt;= $@arglength&quot;</span>
<span class="k">for</span> <span class="nx">trailing</span><span class="p">,</span> <span class="nx">idx</span> <span class="k">in</span> <span class="nx">@trailings</span>
<span class="nv">pos: </span><span class="nx">@trailings</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="nx">idx</span>
<span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">assign</span><span class="p">(</span><span class="nx">trailing</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="s2">&quot;arguments[$variadic ? $len - $pos : ${@index + idx}]&quot;</span><span class="p">)</span>
<span class="s2">&quot;$name = ${utility(&#39;slice&#39;)}.call(arguments, $@index, $len - ${@trailings.length})&quot;</span></pre></div> </td> </tr> <tr id="section-94"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-94">#</a> </div> <p>A compiling a splat as a destructuring assignment means slicing arguments
from the right-hand-side's corresponding array.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compile_value: </span><span class="p">(</span><span class="nx">o</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="nx">trailings</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">trail: </span><span class="k">if</span> <span class="nx">trailings</span> <span class="k">then</span> <span class="s2">&quot;, ${name}.length - $trailings&quot;</span> <span class="k">else</span> <span class="s1">&#39;&#39;</span>
<span class="s2">&quot;${utility &#39;slice&#39;}.call($name, $index$trail)&quot;</span></pre></div> </td> </tr> <tr id="section-96"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-96">#</a> </div> <p>Utility function that converts arbitrary number of elements, mixed with
<span class="s2">&quot;${utility &#39;slice&#39;}.call($name, $index$trail)&quot;</span></pre></div> </td> </tr> <tr id="section-95"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-95">#</a> </div> <p>Utility function that converts arbitrary number of elements, mixed with
splats, to a proper array</p> </td> <td class="code"> <div class="highlight"><pre> <span class="vi">@compile_mixed_array: </span><span class="p">(</span><span class="nx">list</span><span class="p">,</span> <span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">args: </span><span class="p">[]</span>
<span class="nv">i: </span><span class="mi">0</span>
@ -587,17 +646,21 @@ splats, to a proper array</p> </td> <td class="code">
<span class="nv">code: </span><span class="s2">&quot;[$code]&quot;</span>
<span class="nx">args</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="k">if</span> <span class="nx">i</span> <span class="o">is</span> <span class="mi">0</span> <span class="k">then</span> <span class="nx">code</span> <span class="k">else</span> <span class="s2">&quot;.concat($code)&quot;</span><span class="p">)</span>
<span class="nv">i: </span><span class="o">+</span> <span class="mi">1</span>
<span class="nx">args</span><span class="p">.</span><span class="nx">join</span><span class="p">(</span><span class="s1">&#39;&#39;</span><span class="p">)</span></pre></div> </td> </tr> <tr id="section-97"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-97">#</a> </div> <h3>WhileNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-98"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-98">#</a> </div> <p>A while loop, the only sort of low-level loop exposed by CoffeeScript. From
<span class="nx">args</span><span class="p">.</span><span class="nx">join</span><span class="p">(</span><span class="s1">&#39;&#39;</span><span class="p">)</span>
<span class="nx">children</span> <span class="nx">SplatNode</span><span class="p">,</span> <span class="s1">&#39;name&#39;</span></pre></div> </td> </tr> <tr id="section-96"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-96">#</a> </div> <h3>WhileNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-97"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-97">#</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> <td class="code"> <div class="highlight"><pre><span class="nv">exports.WhileNode: </span><span class="nx">class</span> <span class="nx">WhileNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span>
<span class="nv">constructor: </span><span class="p">(</span><span class="nx">condition</span><span class="p">,</span> <span class="nx">opts</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">condition: </span><span class="k">new</span> <span class="nx">OpNode</span><span class="p">(</span><span class="s1">&#39;!&#39;</span><span class="p">,</span> <span class="nx">condition</span><span class="p">)</span> <span class="k">if</span> <span class="nx">opts</span> <span class="o">and</span> <span class="nx">opts</span><span class="p">.</span><span class="nx">invert</span>
<span class="nx">@children</span><span class="o">:</span><span class="p">[</span><span class="vi">@condition: </span><span class="nx">condition</span><span class="p">]</span>
<span class="k">if</span> <span class="nx">opts</span> <span class="o">and</span> <span class="nx">opts</span><span class="p">.</span><span class="nx">invert</span>
<span class="nv">condition: </span><span class="k">new</span> <span class="nx">ParentheticalNode</span> <span class="nx">condition</span> <span class="k">if</span> <span class="nx">condition</span> <span class="k">instanceof</span> <span class="nx">OpNode</span>
<span class="nv">condition: </span><span class="k">new</span> <span class="nx">OpNode</span><span class="p">(</span><span class="s1">&#39;!&#39;</span><span class="p">,</span> <span class="nx">condition</span><span class="p">)</span>
<span class="vi">@condition: </span><span class="nx">condition</span>
<span class="vi">@guard: </span><span class="nx">opts</span> <span class="o">and</span> <span class="nx">opts</span><span class="p">.</span><span class="nx">guard</span>
<span class="nv">add_body: </span><span class="p">(</span><span class="nx">body</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nx">@children</span><span class="p">.</span><span class="nx">push</span> <span class="vi">@body: </span><span class="nx">body</span>
<span class="vi">@body: </span><span class="nx">body</span>
<span class="k">this</span>
<span class="nv">make_return: </span><span class="o">-&gt;</span>
@ -605,7 +668,7 @@ flexibility or more speed than a comprehension can provide.</p> </td
<span class="k">this</span>
<span class="nv">top_sensitive: </span><span class="o">-&gt;</span>
<span class="kc">true</span></pre></div> </td> </tr> <tr id="section-99"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-99">#</a> </div> <p>The main difference from a JavaScript <em>while</em> is that the CoffeeScript
<span class="kc">true</span></pre></div> </td> </tr> <tr id="section-98"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-98">#</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> <td class="code"> <div class="highlight"><pre> <span class="nv">compile_node: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">top: </span> <span class="nx">del</span><span class="p">(</span><span class="nx">o</span><span class="p">,</span> <span class="s1">&#39;top&#39;</span><span class="p">)</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">@returns</span>
@ -618,24 +681,25 @@ return an array containing the computed result of each iteration.</p>
<span class="nv">set: </span> <span class="s2">&quot;$@tab$rvar = [];\n&quot;</span>
<span class="vi">@body: </span> <span class="nx">PushNode</span><span class="p">.</span><span class="nx">wrap</span><span class="p">(</span><span class="nx">rvar</span><span class="p">,</span> <span class="nx">@body</span><span class="p">)</span> <span class="k">if</span> <span class="nx">@body</span>
<span class="nv">pre: </span> <span class="s2">&quot;$set${@tab}while ($cond)&quot;</span>
<span class="k">return</span> <span class="s2">&quot;$pre null;$post&quot;</span> <span class="k">if</span> <span class="o">not</span> <span class="nx">@body</span>
<span class="vi">@body: </span> <span class="nx">Expressions</span><span class="p">.</span><span class="nx">wrap</span><span class="p">([</span><span class="k">new</span> <span class="nx">IfNode</span><span class="p">(</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">@returns</span>
<span class="nv">post: </span><span class="k">new</span> <span class="nx">ReturnNode</span><span class="p">(</span><span class="nx">literal</span><span class="p">(</span><span class="nx">rvar</span><span class="p">)).</span><span class="nx">compile</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="nv">indent: </span><span class="nx">@idt</span><span class="p">()}))</span>
<span class="nv">post: </span><span class="s1">&#39;\n&#39;</span> <span class="o">+</span> <span class="k">new</span> <span class="nx">ReturnNode</span><span class="p">(</span><span class="nx">literal</span><span class="p">(</span><span class="nx">rvar</span><span class="p">)).</span><span class="nx">compile</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="nv">indent: </span><span class="nx">@idt</span><span class="p">()}))</span>
<span class="k">else</span>
<span class="nv">post: </span><span class="s1">&#39;&#39;</span>
<span class="s2">&quot;$pre {\n${ @body.compile(o) }\n$@tab}\n$post&quot;</span>
<span class="s2">&quot;$pre {\n${ @body.compile(o) }\n$@tab}$post&quot;</span>
<span class="nx">statement</span> <span class="nx">WhileNode</span></pre></div> </td> </tr> <tr id="section-100"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-100">#</a> </div> <h3>OpNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-101"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-101">#</a> </div> <p>Simple Arithmetic and logical operations. Performs some conversion from
CoffeeScript operations into their JavaScript equivalents.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.OpNode: </span><span class="nx">class</span> <span class="nx">OpNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span></pre></div> </td> </tr> <tr id="section-102"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-102">#</a> </div> <p>The map of conversions from CoffeeScript to JavaScript symbols.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">CONVERSIONS: </span><span class="p">{</span>
<span class="nx">statement</span> <span class="nx">WhileNode</span>
<span class="nx">children</span> <span class="nx">WhileNode</span><span class="p">,</span> <span class="s1">&#39;condition&#39;</span><span class="p">,</span> <span class="s1">&#39;guard&#39;</span><span class="p">,</span> <span class="s1">&#39;body&#39;</span></pre></div> </td> </tr> <tr id="section-99"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-99">#</a> </div> <h3>OpNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-100"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-100">#</a> </div> <p>Simple Arithmetic and logical operations. Performs some conversion from
CoffeeScript operations into their JavaScript equivalents.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.OpNode: </span><span class="nx">class</span> <span class="nx">OpNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span></pre></div> </td> </tr> <tr id="section-101"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-101">#</a> </div> <p>The map of conversions from CoffeeScript to JavaScript symbols.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">CONVERSIONS: </span><span class="p">{</span>
<span class="s1">&#39;==&#39;</span><span class="o">:</span> <span class="s1">&#39;===&#39;</span>
<span class="s1">&#39;!=&#39;</span><span class="o">:</span> <span class="s1">&#39;!==&#39;</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-103"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-103">#</a> </div> <p>The list of operators for which we perform
<a href="http://docs.python.org/reference/expressions.html#notin">Python-style comparison chaining</a>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">CHAINABLE: </span> <span class="p">[</span><span class="s1">&#39;&lt;&#39;</span><span class="p">,</span> <span class="s1">&#39;&gt;&#39;</span><span class="p">,</span> <span class="s1">&#39;&gt;=&#39;</span><span class="p">,</span> <span class="s1">&#39;&lt;=&#39;</span><span class="p">,</span> <span class="s1">&#39;===&#39;</span><span class="p">,</span> <span class="s1">&#39;!==&#39;</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-104"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-104">#</a> </div> <p>Our assignment operators that have no JavaScript equivalent.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">ASSIGNMENT: </span> <span class="p">[</span><span class="s1">&#39;||=&#39;</span><span class="p">,</span> <span class="s1">&#39;&amp;&amp;=&#39;</span><span class="p">,</span> <span class="s1">&#39;?=&#39;</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-105"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-105">#</a> </div> <p>Operators must come before their operands with a space.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">PREFIX_OPERATORS: </span><span class="p">[</span><span class="s1">&#39;typeof&#39;</span><span class="p">,</span> <span class="s1">&#39;delete&#39;</span><span class="p">]</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-102"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-102">#</a> </div> <p>The list of operators for which we perform
<a href="http://docs.python.org/reference/expressions.html#notin">Python-style comparison chaining</a>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">CHAINABLE: </span> <span class="p">[</span><span class="s1">&#39;&lt;&#39;</span><span class="p">,</span> <span class="s1">&#39;&gt;&#39;</span><span class="p">,</span> <span class="s1">&#39;&gt;=&#39;</span><span class="p">,</span> <span class="s1">&#39;&lt;=&#39;</span><span class="p">,</span> <span class="s1">&#39;===&#39;</span><span class="p">,</span> <span class="s1">&#39;!==&#39;</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-103"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-103">#</a> </div> <p>Our assignment operators that have no JavaScript equivalent.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">ASSIGNMENT: </span> <span class="p">[</span><span class="s1">&#39;||=&#39;</span><span class="p">,</span> <span class="s1">&#39;&amp;&amp;=&#39;</span><span class="p">,</span> <span class="s1">&#39;?=&#39;</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-104"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-104">#</a> </div> <p>Operators must come before their operands with a space.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">PREFIX_OPERATORS: </span><span class="p">[</span><span class="s1">&#39;typeof&#39;</span><span class="p">,</span> <span class="s1">&#39;delete&#39;</span><span class="p">]</span>
<span class="nv">constructor: </span><span class="p">(</span><span class="nx">operator</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">flip</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="vi">@constructor.name: </span><span class="o">+</span> <span class="s1">&#39; &#39;</span> <span class="o">+</span> <span class="nx">operator</span>
<span class="vi">@children: </span><span class="nx">compact</span> <span class="p">[</span><span class="vi">@first: </span><span class="nx">first</span><span class="p">,</span> <span class="vi">@second: </span><span class="nx">second</span><span class="p">]</span>
<span class="vi">@first: </span><span class="nx">first</span>
<span class="vi">@second: </span><span class="nx">second</span>
<span class="vi">@operator: </span><span class="nx">@CONVERSIONS</span><span class="p">[</span><span class="nx">operator</span><span class="p">]</span> <span class="o">or</span> <span class="nx">operator</span>
<span class="vi">@flip: </span><span class="o">!!</span><span class="nx">flip</span>
@ -643,15 +707,15 @@ CoffeeScript operations into their JavaScript equivalents.</p> </td>
<span class="o">not</span> <span class="nx">@second</span>
<span class="nv">is_chainable: </span><span class="o">-&gt;</span>
<span class="nx">@CHAINABLE</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="nx">@operator</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="mi">0</span>
<span class="nx">index_of</span><span class="p">(</span><span class="nx">@CHAINABLE</span><span class="p">,</span> <span class="nx">@operator</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="mi">0</span>
<span class="nv">compile_node: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">o.operation: </span><span class="kc">true</span>
<span class="k">return</span> <span class="nx">@compile_chain</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="k">if</span> <span class="nx">@is_chainable</span><span class="p">()</span> <span class="o">and</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">OpNode</span> <span class="o">and</span> <span class="nx">@first</span><span class="p">.</span><span class="nx">unwrap</span><span class="p">().</span><span class="nx">is_chainable</span><span class="p">()</span>
<span class="k">return</span> <span class="nx">@compile_assignment</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="k">if</span> <span class="nx">@ASSIGNMENT</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="nx">@operator</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="mi">0</span>
<span class="k">return</span> <span class="nx">@compile_assignment</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="k">if</span> <span class="nx">index_of</span><span class="p">(</span><span class="nx">@ASSIGNMENT</span><span class="p">,</span> <span class="nx">@operator</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="mi">0</span>
<span class="k">return</span> <span class="nx">@compile_unary</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="k">if</span> <span class="nx">@is_unary</span><span class="p">()</span>
<span class="k">return</span> <span class="nx">@compile_existence</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="k">if</span> <span class="nx">@operator</span> <span class="o">is</span> <span class="s1">&#39;?&#39;</span>
<span class="p">[</span><span class="nx">@first</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">@operator</span><span class="p">,</span> <span class="nx">@second</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">join</span> <span class="s1">&#39; &#39;</span></pre></div> </td> </tr> <tr id="section-106"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-106">#</a> </div> <p>Mimic Python's chained comparisons when multiple comparison operators are
<span class="p">[</span><span class="nx">@first</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">@operator</span><span class="p">,</span> <span class="nx">@second</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">join</span> <span class="s1">&#39; &#39;</span></pre></div> </td> </tr> <tr id="section-105"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-105">#</a> </div> <p>Mimic Python's chained comparisons when multiple comparison operators are
used sequentially. For example:</p>
<pre><code>bin/coffee -e "puts 50 &lt; 65 &gt; 10"
@ -660,31 +724,35 @@ true
<span class="nv">shared: </span><span class="nx">@first</span><span class="p">.</span><span class="nx">unwrap</span><span class="p">().</span><span class="nx">second</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">shared</span><span class="p">.</span><span class="nx">compile_reference</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="k">if</span> <span class="nx">shared</span><span class="p">.</span><span class="nx">contains_type</span> <span class="nx">CallNode</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="p">[</span><span class="nx">@first</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">@second</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">shared</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="s2">&quot;($first) &amp;&amp; ($shared $@operator $second)&quot;</span></pre></div> </td> </tr> <tr id="section-107"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-107">#</a> </div> <p>When compiling a conditional assignment, take care to ensure that the
<span class="s2">&quot;($first) &amp;&amp; ($shared $@operator $second)&quot;</span></pre></div> </td> </tr> <tr id="section-106"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-106">#</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> <td class="code"> <div class="highlight"><pre> <span class="nv">compile_assignment: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="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="o">:</span> <span class="p">[</span><span class="nx">@first</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">@second</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">o</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">first</span><span class="p">)</span> <span class="k">if</span> <span class="nx">first</span><span class="p">.</span><span class="nx">match</span><span class="p">(</span><span class="nx">IDENTIFIER</span><span class="p">)</span>
<span class="k">return</span> <span class="s2">&quot;$first = ${ ExistenceNode.compile_test(o, @first) } ? $first : $second&quot;</span> <span class="k">if</span> <span class="nx">@operator</span> <span class="o">is</span> <span class="s1">&#39;?=&#39;</span>
<span class="s2">&quot;$first = $first ${ @operator.substr(0, 2) } $second&quot;</span></pre></div> </td> </tr> <tr id="section-108"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-108">#</a> </div> <p>If this is an existence operator, we delegate to <code>ExistenceNode.compile_test</code>
<span class="s2">&quot;$first = $first ${ @operator.substr(0, 2) } $second&quot;</span></pre></div> </td> </tr> <tr id="section-107"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-107">#</a> </div> <p>If this is an existence operator, we delegate to <code>ExistenceNode.compile_test</code>
to give us the safe references for the variables.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compile_existence: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="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="o">:</span> <span class="p">[</span><span class="nx">@first</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">@second</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="nv">test: </span><span class="nx">ExistenceNode</span><span class="p">.</span><span class="nx">compile_test</span><span class="p">(</span><span class="nx">o</span><span class="p">,</span> <span class="nx">@first</span><span class="p">)</span>
<span class="s2">&quot;$test ? $first : $second&quot;</span></pre></div> </td> </tr> <tr id="section-109"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-109">#</a> </div> <p>Compile a unary <strong>OpNode</strong>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compile_unary: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">space: </span><span class="k">if</span> <span class="nx">@PREFIX_OPERATORS</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="nx">@operator</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="mi">0</span> <span class="k">then</span> <span class="s1">&#39; &#39;</span> <span class="k">else</span> <span class="s1">&#39;&#39;</span>
<span class="s2">&quot;$test ? $first : $second&quot;</span></pre></div> </td> </tr> <tr id="section-108"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-108">#</a> </div> <p>Compile a unary <strong>OpNode</strong>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compile_unary: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">space: </span><span class="k">if</span> <span class="nx">index_of</span><span class="p">(</span><span class="nx">@PREFIX_OPERATORS</span><span class="p">,</span> <span class="nx">@operator</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="mi">0</span> <span class="k">then</span> <span class="s1">&#39; &#39;</span> <span class="k">else</span> <span class="s1">&#39;&#39;</span>
<span class="nv">parts: </span><span class="p">[</span><span class="nx">@operator</span><span class="p">,</span> <span class="nx">space</span><span class="p">,</span> <span class="nx">@first</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="nv">parts: </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">parts</span><span class="p">.</span><span class="nx">join</span><span class="p">(</span><span class="s1">&#39;&#39;</span><span class="p">)</span></pre></div> </td> </tr> <tr id="section-110"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-110">#</a> </div> <h3>TryNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-111"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-111">#</a> </div> <p>A classic <em>try/catch/finally</em> block.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.TryNode: </span><span class="nx">class</span> <span class="nx">TryNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span>
<span class="nx">parts</span><span class="p">.</span><span class="nx">join</span><span class="p">(</span><span class="s1">&#39;&#39;</span><span class="p">)</span>
<span class="nx">children</span> <span class="nx">OpNode</span><span class="p">,</span> <span class="s1">&#39;first&#39;</span><span class="p">,</span> <span class="s1">&#39;second&#39;</span></pre></div> </td> </tr> <tr id="section-109"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-109">#</a> </div> <h3>TryNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-110"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-110">#</a> </div> <p>A classic <em>try/catch/finally</em> block.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.TryNode: </span><span class="nx">class</span> <span class="nx">TryNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span>
<span class="nv">constructor: </span><span class="p">(</span><span class="nx">attempt</span><span class="p">,</span> <span class="nx">error</span><span class="p">,</span> <span class="nx">recovery</span><span class="p">,</span> <span class="nx">ensure</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="vi">@children: </span><span class="nx">compact</span> <span class="p">[</span><span class="vi">@attempt: </span><span class="nx">attempt</span><span class="p">,</span> <span class="vi">@recovery: </span><span class="nx">recovery</span><span class="p">,</span> <span class="vi">@ensure: </span><span class="nx">ensure</span><span class="p">]</span>
<span class="vi">@attempt: </span><span class="nx">attempt</span>
<span class="vi">@recovery: </span><span class="nx">recovery</span>
<span class="vi">@ensure: </span><span class="nx">ensure</span>
<span class="vi">@error: </span><span class="nx">error</span>
<span class="k">this</span>
<span class="nv">make_return: </span><span class="o">-&gt;</span>
<span class="vi">@attempt: </span><span class="nx">@attempt</span><span class="p">.</span><span class="nx">make_return</span><span class="p">()</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">make_return</span><span class="p">()</span> <span class="k">if</span> <span class="nx">@recovery</span>
<span class="k">this</span></pre></div> </td> </tr> <tr id="section-112"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-112">#</a> </div> <p>Compilation is more or less as you would expect -- the <em>finally</em> clause
<span class="k">this</span></pre></div> </td> </tr> <tr id="section-111"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-111">#</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> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compile_node: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">o.indent: </span> <span class="nx">@idt</span> <span class="mi">1</span>
<span class="nv">o.top: </span> <span class="kc">true</span>
@ -694,38 +762,42 @@ is optional, the <em>catch</em> is not.</p> </td> <td cl
<span class="nv">finally_part: </span><span class="p">(</span><span class="nx">@ensure</span> <span class="o">or</span> <span class="s1">&#39;&#39;</span><span class="p">)</span> <span class="o">and</span> <span class="s1">&#39; finally {\n&#39;</span> <span class="o">+</span> <span class="nx">@ensure</span><span class="p">.</span><span class="nx">compile</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="o">+</span> <span class="s2">&quot;\n$@tab}&quot;</span>
<span class="s2">&quot;${@tab}try {\n$attempt_part\n$@tab}$catch_part$finally_part&quot;</span>
<span class="nx">statement</span> <span class="nx">TryNode</span></pre></div> </td> </tr> <tr id="section-113"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-113">#</a> </div> <h3>ThrowNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-114"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-114">#</a> </div> <p>Simple node to throw an exception.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.ThrowNode: </span><span class="nx">class</span> <span class="nx">ThrowNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span>
<span class="nx">statement</span> <span class="nx">TryNode</span>
<span class="nx">children</span> <span class="nx">TryNode</span><span class="p">,</span> <span class="s1">&#39;attempt&#39;</span><span class="p">,</span> <span class="s1">&#39;recovery&#39;</span><span class="p">,</span> <span class="s1">&#39;ensure&#39;</span></pre></div> </td> </tr> <tr id="section-112"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-112">#</a> </div> <h3>ThrowNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-113"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-113">#</a> </div> <p>Simple node to throw an exception.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.ThrowNode: </span><span class="nx">class</span> <span class="nx">ThrowNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span>
<span class="nv">constructor: </span><span class="p">(</span><span class="nx">expression</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="vi">@children: </span><span class="p">[</span><span class="vi">@expression: </span><span class="nx">expression</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-115"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-115">#</a> </div> <p>A <strong>ThrowNode</strong> is already a return, of sorts...</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">make_return: </span><span class="o">-&gt;</span>
<span class="vi">@expression: </span><span class="nx">expression</span></pre></div> </td> </tr> <tr id="section-114"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-114">#</a> </div> <p>A <strong>ThrowNode</strong> is already a return, of sorts...</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">make_return: </span><span class="o">-&gt;</span>
<span class="k">return</span> <span class="k">this</span>
<span class="nv">compile_node: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="s2">&quot;${@tab}throw ${@expression.compile(o)};&quot;</span>
<span class="nx">statement</span> <span class="nx">ThrowNode</span></pre></div> </td> </tr> <tr id="section-116"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-116">#</a> </div> <h3>ExistenceNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-117"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-117">#</a> </div> <p>Checks a variable for existence -- not <em>null</em> and not <em>undefined</em>. This is
<span class="nx">statement</span> <span class="nx">ThrowNode</span>
<span class="nx">children</span> <span class="nx">ThrowNode</span><span class="p">,</span> <span class="s1">&#39;expression&#39;</span></pre></div> </td> </tr> <tr id="section-115"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-115">#</a> </div> <h3>ExistenceNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-116"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-116">#</a> </div> <p>Checks a variable for existence -- not <em>null</em> and not <em>undefined</em>. This is
similar to <code>.nil?</code> in Ruby, and avoids having to consult a JavaScript truth
table.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.ExistenceNode: </span><span class="nx">class</span> <span class="nx">ExistenceNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span>
<span class="nv">constructor: </span><span class="p">(</span><span class="nx">expression</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="vi">@children: </span><span class="p">[</span><span class="vi">@expression: </span><span class="nx">expression</span><span class="p">]</span>
<span class="vi">@expression: </span><span class="nx">expression</span>
<span class="nv">compile_node: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nx">ExistenceNode</span><span class="p">.</span><span class="nx">compile_test</span><span class="p">(</span><span class="nx">o</span><span class="p">,</span> <span class="nx">@expression</span><span class="p">)</span></pre></div> </td> </tr> <tr id="section-118"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-118">#</a> </div> <p>The meat of the <strong>ExistenceNode</strong> is in this static <code>compile_test</code> method
<span class="nx">ExistenceNode</span><span class="p">.</span><span class="nx">compile_test</span><span class="p">(</span><span class="nx">o</span><span class="p">,</span> <span class="nx">@expression</span><span class="p">)</span></pre></div> </td> </tr> <tr id="section-117"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-117">#</a> </div> <p>The meat of the <strong>ExistenceNode</strong> is in this static <code>compile_test</code> method
because other nodes like to check the existence of their variables as well.
Be careful not to double-evaluate anything.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="vi">@compile_test: </span><span class="p">(</span><span class="nx">o</span><span class="p">,</span> <span class="nx">variable</span><span class="p">)</span> <span class="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="o">:</span> <span class="p">[</span><span class="nx">variable</span><span class="p">,</span> <span class="nx">variable</span><span class="p">]</span>
<span class="k">if</span> <span class="nx">variable</span> <span class="k">instanceof</span> <span class="nx">CallNode</span> <span class="o">or</span> <span class="p">(</span><span class="nx">variable</span> <span class="k">instanceof</span> <span class="nx">ValueNode</span> <span class="o">and</span> <span class="nx">variable</span><span class="p">.</span><span class="nx">has_properties</span><span class="p">())</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="o">:</span> <span class="nx">variable</span><span class="p">.</span><span class="nx">compile_reference</span><span class="p">(</span><span class="nx">o</span><span class="p">)</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="o">:</span> <span class="p">[</span><span class="nx">first</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">second</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="s2">&quot;(typeof $first !== \&quot;undefined\&quot; &amp;&amp; $second !== null)&quot;</span></pre></div> </td> </tr> <tr id="section-119"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-119">#</a> </div> <h3>ParentheticalNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-120"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-120">#</a> </div> <p>An extra set of parentheses, specified explicitly in the source. At one time
<span class="s2">&quot;(typeof $first !== \&quot;undefined\&quot; &amp;&amp; $second !== null)&quot;</span>
<span class="nx">children</span> <span class="nx">ExistenceNode</span><span class="p">,</span> <span class="s1">&#39;expression&#39;</span></pre></div> </td> </tr> <tr id="section-118"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-118">#</a> </div> <h3>ParentheticalNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-119"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-119">#</a> </div> <p>An extra set of parentheses, specified explicitly in the source. At one time
we tried to clean up the results by detecting and removing redundant
parentheses, but no longer -- you can put in as many as you please.</p>
<p>Parentheses are a good way to force any statement to become an expression.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.ParentheticalNode: </span><span class="nx">class</span> <span class="nx">ParentheticalNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span>
<span class="nv">constructor: </span><span class="p">(</span><span class="nx">expression</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="vi">@children: </span><span class="p">[</span><span class="vi">@expression: </span><span class="nx">expression</span><span class="p">]</span>
<span class="vi">@expression: </span><span class="nx">expression</span>
<span class="nv">is_statement: </span><span class="o">-&gt;</span>
<span class="nx">@expression</span><span class="p">.</span><span class="nx">is_statement</span><span class="p">()</span>
@ -738,7 +810,9 @@ parentheses, but no longer -- you can put in as many as you please.</p>
<span class="k">return</span> <span class="nx">code</span> <span class="k">if</span> <span class="nx">@is_statement</span><span class="p">()</span>
<span class="nv">l: </span> <span class="nx">code</span><span class="p">.</span><span class="nx">length</span>
<span class="nv">code: </span><span class="nx">code</span><span class="p">.</span><span class="nx">substr</span><span class="p">(</span><span class="nx">o</span><span class="p">,</span> <span class="nx">l</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="k">if</span> <span class="nx">code</span><span class="p">.</span><span class="nx">substr</span><span class="p">(</span><span class="nx">l</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span> <span class="o">is</span> <span class="s1">&#39;;&#39;</span>
<span class="k">if</span> <span class="nx">@expression</span> <span class="k">instanceof</span> <span class="nx">AssignNode</span> <span class="k">then</span> <span class="nx">code</span> <span class="k">else</span> <span class="s2">&quot;($code)&quot;</span></pre></div> </td> </tr> <tr id="section-121"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-121">#</a> </div> <h3>ForNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-122"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-122">#</a> </div> <p>CoffeeScript's replacement for the <em>for</em> loop is our array and object
<span class="k">if</span> <span class="nx">@expression</span> <span class="k">instanceof</span> <span class="nx">AssignNode</span> <span class="k">then</span> <span class="nx">code</span> <span class="k">else</span> <span class="s2">&quot;($code)&quot;</span>
<span class="nx">children</span> <span class="nx">ParentheticalNode</span><span class="p">,</span> <span class="s1">&#39;expression&#39;</span></pre></div> </td> </tr> <tr id="section-120"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-120">#</a> </div> <h3>ForNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-121"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-121">#</a> </div> <p>CoffeeScript's replacement for the <em>for</em> loop is our array and object
comprehensions, that compile into <em>for</em> loops here. They also act as an
expression, able to return the result of each filtered iteration.</p>
@ -757,7 +831,6 @@ you can map and filter in a single pass.</p> </td> <td c
<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="vi">@pattern: </span><span class="nx">@name</span> <span class="k">instanceof</span> <span class="nx">ValueNode</span>
<span class="k">throw</span> <span class="k">new</span> <span class="nb">Error</span><span class="p">(</span><span class="s1">&#39;index cannot be a pattern matching expression&#39;</span><span class="p">)</span> <span class="k">if</span> <span class="nx">@index</span> <span class="k">instanceof</span> <span class="nx">ValueNode</span>
<span class="vi">@children: </span><span class="nx">compact</span> <span class="p">[</span><span class="nx">@body</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="vi">@returns: </span><span class="kc">false</span>
<span class="nv">top_sensitive: </span><span class="o">-&gt;</span>
@ -768,8 +841,9 @@ you can map and filter in a single pass.</p> </td> <td c
<span class="k">this</span>
<span class="nv">compile_return_value: </span><span class="p">(</span><span class="nx">val</span><span class="p">,</span> <span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="k">return</span> <span class="k">new</span> <span class="nx">ReturnNode</span><span class="p">(</span><span class="nx">literal</span><span class="p">(</span><span class="nx">val</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="k">if</span> <span class="nx">@returns</span>
<span class="nx">val</span> <span class="o">or</span> <span class="s1">&#39;&#39;</span></pre></div> </td> </tr> <tr id="section-123"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-123">#</a> </div> <p>Welcome to the hairiest method in all of CoffeeScript. Handles the inner
<span class="k">return</span> <span class="s1">&#39;\n&#39;</span> <span class="o">+</span> <span class="k">new</span> <span class="nx">ReturnNode</span><span class="p">(</span><span class="nx">literal</span><span class="p">(</span><span class="nx">val</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="k">if</span> <span class="nx">@returns</span>
<span class="k">return</span> <span class="s1">&#39;\n&#39;</span> <span class="o">+</span> <span class="nx">val</span> <span class="k">if</span> <span class="nx">val</span>
<span class="s1">&#39;&#39;</span></pre></div> </td> </tr> <tr id="section-122"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-122">#</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> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compile_node: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
@ -811,10 +885,11 @@ some cannot.</p> </td> <td class="code"> <
<span class="nv">for_part: </span><span class="s2">&quot;$ivar in $svar) { if (${utility(&#39;hasProp&#39;)}.call($svar, $ivar)&quot;</span>
<span class="nv">body: </span> <span class="nx">body</span><span class="p">.</span><span class="nx">compile</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="nv">indent: </span><span class="nx">body_dent</span><span class="p">,</span> <span class="nv">top: </span><span class="kc">true</span><span class="p">}))</span>
<span class="nv">vars: </span> <span class="k">if</span> <span class="nx">range</span> <span class="k">then</span> <span class="nx">name</span> <span class="k">else</span> <span class="s2">&quot;$name, $ivar&quot;</span>
<span class="nv">close: </span> <span class="k">if</span> <span class="nx">@object</span> <span class="k">then</span> <span class="s1">&#39;}}\n&#39;</span> <span class="k">else</span> <span class="s1">&#39;}\n&#39;</span>
<span class="nv">close: </span> <span class="k">if</span> <span class="nx">@object</span> <span class="k">then</span> <span class="s1">&#39;}}&#39;</span> <span class="k">else</span> <span class="s1">&#39;}&#39;</span>
<span class="s2">&quot;$set_result${source_part}for ($for_part) {\n$var_part$body\n$@tab$close$return_result&quot;</span>
<span class="nx">statement</span> <span class="nx">ForNode</span></pre></div> </td> </tr> <tr id="section-124"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-124">#</a> </div> <h3>IfNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-125"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-125">#</a> </div> <p><em>If/else</em> statements. Our <em>switch/when</em> will be compiled into this. Acts as an
<span class="nx">statement</span> <span class="nx">ForNode</span>
<span class="nx">children</span> <span class="nx">ForNode</span><span class="p">,</span> <span class="s1">&#39;body&#39;</span><span class="p">,</span> <span class="s1">&#39;source&#39;</span><span class="p">,</span> <span class="s1">&#39;guard&#39;</span></pre></div> </td> </tr> <tr id="section-123"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-123">#</a> </div> <h3>IfNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-124"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-124">#</a> </div> <p><em>If/else</em> statements. Our <em>switch/when</em> will be compiled into this. Acts as an
expression by pushing down requested returns to the last line of each clause.</p>
<p>Single-expression <strong>IfNodes</strong> are compiled into ternary operators if possible,
@ -824,45 +899,36 @@ because ternaries are already proper expressions, and don't need conversion.</p>
<span class="vi">@condition: </span><span class="nx">condition</span>
<span class="vi">@body: </span> <span class="nx">body</span>
<span class="vi">@else_body: </span><span class="kc">null</span>
<span class="nx">@populate_children</span><span class="p">()</span>
<span class="vi">@tags: </span> <span class="nx">tags</span> <span class="o">or</span> <span class="p">{}</span>
<span class="vi">@multiple: </span> <span class="kc">true</span> <span class="k">if</span> <span class="nx">@condition</span> <span class="k">instanceof</span> <span class="nb">Array</span>
<span class="vi">@condition: </span><span class="k">new</span> <span class="nx">OpNode</span><span class="p">(</span><span class="s1">&#39;!&#39;</span><span class="p">,</span> <span class="k">new</span> <span class="nx">ParentheticalNode</span><span class="p">(</span><span class="nx">@condition</span><span class="p">))</span> <span class="k">if</span> <span class="nx">@tags</span><span class="p">.</span><span class="nx">invert</span>
<span class="vi">@is_chain: </span> <span class="kc">false</span>
<span class="nv">populate_children: </span><span class="o">-&gt;</span>
<span class="vi">@children: </span> <span class="nx">compact</span> <span class="nx">flatten</span> <span class="p">[</span><span class="nx">@condition</span><span class="p">,</span> <span class="nx">@body</span><span class="p">,</span> <span class="nx">@else_body</span><span class="p">]</span>
<span class="nv">body_node: </span><span class="o">-&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">else_body_node: </span><span class="o">-&gt;</span> <span class="nx">@else_body</span><span class="o">?</span><span class="p">.</span><span class="nx">unwrap</span><span class="p">()</span>
<span class="nv">force_statement: </span><span class="o">-&gt;</span>
<span class="vi">@tags.statement: </span><span class="kc">true</span>
<span class="k">this</span></pre></div> </td> </tr> <tr id="section-126"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-126">#</a> </div> <p>Tag a chain of <strong>IfNodes</strong> with their object(s) to switch on for equality
<span class="k">this</span></pre></div> </td> </tr> <tr id="section-125"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-125">#</a> </div> <p>Tag a chain of <strong>IfNodes</strong> with their object(s) to switch on for equality
tests. <code>rewrite_switch</code> will perform the actual change at compile time.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">switches_over: </span><span class="p">(</span><span class="nx">expression</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="vi">@switch_subject: </span><span class="nx">expression</span>
<span class="k">this</span></pre></div> </td> </tr> <tr id="section-127"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-127">#</a> </div> <p>Rewrite a chain of <strong>IfNodes</strong> with their switch condition for equality.
<span class="k">this</span></pre></div> </td> </tr> <tr id="section-126"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-126">#</a> </div> <p>Rewrite a chain of <strong>IfNodes</strong> with their switch condition for equality.
Ensure that the switch expression isn't evaluated more than once.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">rewrite_switch: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">assigner: </span><span class="nx">@switch_subject</span>
<span class="vi">@assigner: </span><span class="nx">@switch_subject</span>
<span class="nx">unless</span> <span class="p">(</span><span class="nx">@switch_subject</span><span class="p">.</span><span class="nx">unwrap</span><span class="p">()</span> <span class="k">instanceof</span> <span class="nx">LiteralNode</span><span class="p">)</span>
<span class="nv">variable: </span><span class="nx">literal</span><span class="p">(</span><span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">free_variable</span><span class="p">())</span>
<span class="nv">assigner: </span><span class="k">new</span> <span class="nx">AssignNode</span><span class="p">(</span><span class="nx">variable</span><span class="p">,</span> <span class="nx">@switch_subject</span><span class="p">)</span>
<span class="nx">@children</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">assigner</span><span class="p">)</span>
<span class="vi">@assigner: </span><span class="k">new</span> <span class="nx">AssignNode</span><span class="p">(</span><span class="nx">variable</span><span class="p">,</span> <span class="nx">@switch_subject</span><span class="p">)</span>
<span class="vi">@switch_subject: </span><span class="nx">variable</span>
<span class="vi">@condition: </span><span class="k">if</span> <span class="nx">@multiple</span>
<span class="k">for</span> <span class="nx">cond</span><span class="p">,</span> <span class="nx">i</span> <span class="k">in</span> <span class="nx">@condition</span>
<span class="k">new</span> <span class="nx">OpNode</span><span class="p">(</span><span class="s1">&#39;==&#39;</span><span class="p">,</span> <span class="p">(</span><span class="k">if</span> <span class="nx">i</span> <span class="o">is</span> <span class="mi">0</span> <span class="k">then</span> <span class="nx">assigner</span> <span class="k">else</span> <span class="nx">@switch_subject</span><span class="p">),</span> <span class="nx">cond</span><span class="p">)</span>
<span class="k">else</span>
<span class="k">new</span> <span class="nx">OpNode</span><span class="p">(</span><span class="s1">&#39;==&#39;</span><span class="p">,</span> <span class="nx">assigner</span><span class="p">,</span> <span class="nx">@condition</span><span class="p">)</span>
<span class="nx">@else_body_node</span><span class="p">().</span><span class="nx">switches_over</span><span class="p">(</span><span class="nx">@switch_subject</span><span class="p">)</span> <span class="k">if</span> <span class="nx">@is_chain</span></pre></div> </td> </tr> <tr id="section-128"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-128">#</a> </div> <p>prevent this rewrite from happening again</p> </td> <td class="code"> <div class="highlight"><pre> <span class="vi">@switch_subject: </span><span class="kc">undefined</span>
<span class="k">this</span></pre></div> </td> </tr> <tr id="section-129"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-129">#</a> </div> <p>Rewrite a chain of <strong>IfNodes</strong> to add a default case as the final <em>else</em>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">add_else: </span><span class="p">(</span><span class="nx">else_body</span><span class="p">,</span> <span class="nx">statement</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="vi">@condition: </span><span class="k">for</span> <span class="nx">cond</span><span class="p">,</span> <span class="nx">i</span> <span class="k">in</span> <span class="nx">flatten</span> <span class="p">[</span><span class="nx">@condition</span><span class="p">]</span>
<span class="nv">cond: </span><span class="k">new</span> <span class="nx">ParentheticalNode</span><span class="p">(</span><span class="nx">cond</span><span class="p">)</span> <span class="k">if</span> <span class="nx">cond</span> <span class="k">instanceof</span> <span class="nx">OpNode</span>
<span class="k">new</span> <span class="nx">OpNode</span><span class="p">(</span><span class="s1">&#39;==&#39;</span><span class="p">,</span> <span class="p">(</span><span class="k">if</span> <span class="nx">i</span> <span class="o">is</span> <span class="mi">0</span> <span class="k">then</span> <span class="nx">@assigner</span> <span class="k">else</span> <span class="nx">@switch_subject</span><span class="p">),</span> <span class="nx">cond</span><span class="p">)</span>
<span class="nx">@else_body_node</span><span class="p">().</span><span class="nx">switches_over</span><span class="p">(</span><span class="nx">@switch_subject</span><span class="p">)</span> <span class="k">if</span> <span class="nx">@is_chain</span></pre></div> </td> </tr> <tr id="section-127"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-127">#</a> </div> <p>prevent this rewrite from happening again</p> </td> <td class="code"> <div class="highlight"><pre> <span class="vi">@switch_subject: </span><span class="kc">undefined</span>
<span class="k">this</span></pre></div> </td> </tr> <tr id="section-128"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-128">#</a> </div> <p>Rewrite a chain of <strong>IfNodes</strong> to add a default case as the final <em>else</em>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">add_else: </span><span class="p">(</span><span class="nx">else_body</span><span class="p">,</span> <span class="nx">statement</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="k">if</span> <span class="nx">@is_chain</span>
<span class="nx">@else_body_node</span><span class="p">().</span><span class="nx">add_else</span> <span class="nx">else_body</span><span class="p">,</span> <span class="nx">statement</span>
<span class="k">else</span>
<span class="vi">@is_chain: </span><span class="nx">else_body</span> <span class="k">instanceof</span> <span class="nx">IfNode</span>
<span class="vi">@else_body: </span><span class="nx">@ensure_expressions</span> <span class="nx">else_body</span>
<span class="nx">@populate_children</span><span class="p">()</span>
<span class="k">this</span></pre></div> </td> </tr> <tr id="section-130"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-130">#</a> </div> <p>The <strong>IfNode</strong> only compiles into a statement if either of its bodies needs
<span class="k">this</span></pre></div> </td> </tr> <tr id="section-129"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-129">#</a> </div> <p>The <strong>IfNode</strong> only compiles into a statement if either of its bodies needs
to be a statement. Otherwise a ternary is safe.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">is_statement: </span><span class="o">-&gt;</span>
<span class="vi">@statement: </span><span class="o">or</span> <span class="o">!!</span><span class="p">(</span><span class="nx">@comment</span> <span class="o">or</span> <span class="nx">@tags</span><span class="p">.</span><span class="nx">statement</span> <span class="o">or</span> <span class="nx">@body_node</span><span class="p">().</span><span class="nx">is_statement</span><span class="p">()</span> <span class="o">or</span> <span class="p">(</span><span class="nx">@else_body</span> <span class="o">and</span> <span class="nx">@else_body_node</span><span class="p">().</span><span class="nx">is_statement</span><span class="p">()))</span>
@ -879,7 +945,7 @@ to be a statement. Otherwise a ternary is safe.</p> </td>
<span class="nv">ensure_expressions: </span><span class="p">(</span><span class="nx">node</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">node: </span><span class="k">new</span> <span class="nx">Expressions</span><span class="p">([</span><span class="nx">node</span><span class="p">])</span> <span class="nx">unless</span> <span class="nx">node</span> <span class="k">instanceof</span> <span class="nx">Expressions</span>
<span class="nx">node</span></pre></div> </td> </tr> <tr id="section-131"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-131">#</a> </div> <p>Compile the <strong>IfNode</strong> as a regular <em>if-else</em> statement. Flattened chains
<span class="nx">node</span></pre></div> </td> </tr> <tr id="section-130"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-130">#</a> </div> <p>Compile the <strong>IfNode</strong> as a regular <em>if-else</em> statement. Flattened chains
force inner <em>else</em> bodies into statement form.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compile_statement: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nx">@rewrite_switch</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="k">if</span> <span class="nx">@switch_subject</span>
<span class="nv">child: </span> <span class="nx">del</span> <span class="nx">o</span><span class="p">,</span> <span class="s1">&#39;chain_child&#39;</span>
@ -896,10 +962,13 @@ force inner <em>else</em> bodies into statement form.</p> </td>
<span class="s1">&#39; else &#39;</span> <span class="o">+</span> <span class="nx">@else_body_node</span><span class="p">().</span><span class="nx">compile</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="nv">indent: </span><span class="nx">@idt</span><span class="p">(),</span> <span class="nv">chain_child: </span><span class="kc">true</span><span class="p">}))</span>
<span class="k">else</span>
<span class="s2">&quot; else {\n${ @else_body.compile(o) }\n$@tab}&quot;</span>
<span class="s2">&quot;$if_part$else_part&quot;</span></pre></div> </td> </tr> <tr id="section-132"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-132">#</a> </div> <p>Compile the IfNode as a ternary operator.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compile_ternary: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="s2">&quot;$if_part$else_part&quot;</span></pre></div> </td> </tr> <tr id="section-131"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-131">#</a> </div> <p>Compile the IfNode as a ternary operator.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compile_ternary: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">if_part: </span> <span class="nx">@condition</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="s1">&#39; ? &#39;</span> <span class="o">+</span> <span class="nx">@body_node</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="nv">else_part: </span> <span class="k">if</span> <span class="nx">@else_body</span> <span class="k">then</span> <span class="nx">@else_body_node</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="k">else</span> <span class="s1">&#39;null&#39;</span>
<span class="s2">&quot;$if_part : $else_part&quot;</span></pre></div> </td> </tr> <tr id="section-133"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-133">#</a> </div> <h2>Faux-Nodes</h2> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-134"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-134">#</a> </div> <h3>PushNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-135"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-135">#</a> </div> <p>Faux-nodes are never created by the grammar, but are used during code
<span class="s2">&quot;$if_part : $else_part&quot;</span>
<span class="nx">children</span> <span class="nx">IfNode</span><span class="p">,</span> <span class="s1">&#39;condition&#39;</span><span class="p">,</span> <span class="s1">&#39;body&#39;</span><span class="p">,</span> <span class="s1">&#39;else_body&#39;</span><span class="p">,</span> <span class="s1">&#39;assigner&#39;</span></pre></div> </td> </tr> <tr id="section-132"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-132">#</a> </div> <h2>Faux-Nodes</h2> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-133"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-133">#</a> </div> <h3>PushNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-134"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-134">#</a> </div> <p>Faux-nodes are never created by the grammar, but are used during code
generation to generate other combinations of nodes. The <strong>PushNode</strong> creates
the tree for <code>array.push(value)</code>, which is helpful for recording the result
arrays from comprehensions.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">PushNode: exports.PushNode: </span><span class="p">{</span>
@ -911,7 +980,7 @@ arrays from comprehensions.</p> </td> <td class="code">
<span class="k">new</span> <span class="nx">ValueNode</span><span class="p">(</span><span class="nx">literal</span><span class="p">(</span><span class="nx">array</span><span class="p">),</span> <span class="p">[</span><span class="k">new</span> <span class="nx">AccessorNode</span><span class="p">(</span><span class="nx">literal</span><span class="p">(</span><span class="s1">&#39;push&#39;</span><span class="p">))]),</span> <span class="p">[</span><span class="nx">expr</span><span class="p">]</span>
<span class="p">)])</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-136"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-136">#</a> </div> <h3>ClosureNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-137"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-137">#</a> </div> <p>A faux-node used to wrap an expressions body in a closure.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">ClosureNode: exports.ClosureNode: </span><span class="p">{</span></pre></div> </td> </tr> <tr id="section-138"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-138">#</a> </div> <p>Wrap the expressions body, unless it contains a pure statement,
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-135"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-135">#</a> </div> <h3>ClosureNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-136"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-136">#</a> </div> <p>A faux-node used to wrap an expressions body in a closure.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">ClosureNode: exports.ClosureNode: </span><span class="p">{</span></pre></div> </td> </tr> <tr id="section-137"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-137">#</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> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">wrap: </span><span class="p">(</span><span class="nx">expressions</span><span class="p">,</span> <span class="nx">statement</span><span class="p">)</span> <span class="o">-&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">contains_pure_statement</span><span class="p">()</span>
@ -927,7 +996,7 @@ then make sure that the closure wrapper preserves the original values.</p>
<span class="nv">call: </span><span class="k">new</span> <span class="nx">CallNode</span><span class="p">(</span><span class="nx">func</span><span class="p">,</span> <span class="nx">args</span><span class="p">)</span>
<span class="k">if</span> <span class="nx">statement</span> <span class="k">then</span> <span class="nx">Expressions</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="p">}</span></pre></div> </td> </tr> <tr id="section-139"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-139">#</a> </div> <h2>Utility Functions</h2> </td> <td class="code"> <div class="highlight"><pre><span class="nv">UTILITIES: </span><span class="p">{</span></pre></div> </td> </tr> <tr id="section-140"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-140">#</a> </div> <p>Correctly set up a prototype chain for inheritance, including a reference
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-138"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-138">#</a> </div> <h2>Utility Functions</h2> </td> <td class="code"> <div class="highlight"><pre><span class="nv">UTILITIES: </span><span class="p">{</span></pre></div> </td> </tr> <tr id="section-139"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-139">#</a> </div> <p>Correctly set up a prototype chain for inheritance, including a reference
to the superclass for <code>super()</code> calls. See:
<a href="http://closure-library.googlecode.com/svn/docs/closure_goog_base.js.source.html#line1206">goog.inherits</a>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">__extends: </span> <span class="s2">&quot;&quot;&quot;</span>
<span class="s2"> function(child, parent) {</span>
@ -937,19 +1006,19 @@ to the superclass for <code>super()</code> calls. See:
<span class="s2"> child.prototype = new ctor();</span>
<span class="s2"> child.prototype.constructor = child;</span>
<span class="s2"> }</span>
<span class="s2"> &quot;&quot;&quot;</span></pre></div> </td> </tr> <tr id="section-141"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-141">#</a> </div> <p>Bind a function to a calling context, optionally including curried arguments.
<span class="s2"> &quot;&quot;&quot;</span></pre></div> </td> </tr> <tr id="section-140"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-140">#</a> </div> <p>Bind a function to a calling context, optionally including curried arguments.
See <a href="http://jashkenas.github.com/coffee-script/documentation/docs/underscore.html#section-47">Underscore's implementation</a>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">__bind: </span> <span class="s2">&quot;&quot;&quot;</span>
<span class="s2"> function(func, obj, args) {</span>
<span class="s2"> return function() {</span>
<span class="s2"> return func.apply(obj || {}, args ? args.concat(__slice.call(arguments, 0)) : arguments);</span>
<span class="s2"> };</span>
<span class="s2"> }</span>
<span class="s2"> &quot;&quot;&quot;</span></pre></div> </td> </tr> <tr id="section-142"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-142">#</a> </div> <p>Shortcuts to speed up the lookup time for native functions.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">__hasProp: </span><span class="s1">&#39;Object.prototype.hasOwnProperty&#39;</span>
<span class="s2"> &quot;&quot;&quot;</span></pre></div> </td> </tr> <tr id="section-141"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-141">#</a> </div> <p>Shortcuts to speed up the lookup time for native functions.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">__hasProp: </span><span class="s1">&#39;Object.prototype.hasOwnProperty&#39;</span>
<span class="nv">__slice: </span><span class="s1">&#39;Array.prototype.slice&#39;</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-143"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-143">#</a> </div> <h2>Constants</h2> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-144"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-144">#</a> </div> <p>Tabs are two spaces for pretty printing.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">TAB: </span><span class="s1">&#39; &#39;</span></pre></div> </td> </tr> <tr id="section-145"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-145">#</a> </div> <p>Trim out all trailing whitespace, so that the generated code plays nice
with Git.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">TRAILING_WHITESPACE: </span><span class="sr">/\s+$/gm</span></pre></div> </td> </tr> <tr id="section-146"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-146">#</a> </div> <p>Keep this identifier regex in sync with the Lexer.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">IDENTIFIER: </span><span class="sr">/^[a-zA-Z\$_](\w|\$)*$/</span></pre></div> </td> </tr> <tr id="section-147"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-147">#</a> </div> <p>Is a literal value a string?</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">IS_STRING: </span><span class="sr">/^[&#39;&quot;]/</span></pre></div> </td> </tr> <tr id="section-148"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-148">#</a> </div> <h2>Utility Functions</h2> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-149"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-149">#</a> </div> <p>Handy helper for a generating LiteralNode.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">literal: </span><span class="p">(</span><span class="nx">name</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="k">new</span> <span class="nx">LiteralNode</span><span class="p">(</span><span class="nx">name</span><span class="p">)</span></pre></div> </td> </tr> <tr id="section-150"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-150">#</a> </div> <p>Helper for ensuring that utility functions are assigned at the top level.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">utility: </span><span class="p">(</span><span class="nx">name</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-142"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-142">#</a> </div> <h2>Constants</h2> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-143"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-143">#</a> </div> <p>Tabs are two spaces for pretty printing.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">TAB: </span><span class="s1">&#39; &#39;</span></pre></div> </td> </tr> <tr id="section-144"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-144">#</a> </div> <p>Trim out all trailing whitespace, so that the generated code plays nice
with Git.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">TRAILING_WHITESPACE: </span><span class="sr">/[ \t]+$/gm</span></pre></div> </td> </tr> <tr id="section-145"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-145">#</a> </div> <p>Keep this identifier regex in sync with the Lexer.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">IDENTIFIER: </span><span class="sr">/^[a-zA-Z\$_](\w|\$)*$/</span></pre></div> </td> </tr> <tr id="section-146"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-146">#</a> </div> <p>Is a literal value a string?</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">IS_STRING: </span><span class="sr">/^[&#39;&quot;]/</span></pre></div> </td> </tr> <tr id="section-147"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-147">#</a> </div> <h2>Utility Functions</h2> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-148"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-148">#</a> </div> <p>Handy helper for a generating LiteralNode.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">literal: </span><span class="p">(</span><span class="nx">name</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="k">new</span> <span class="nx">LiteralNode</span><span class="p">(</span><span class="nx">name</span><span class="p">)</span></pre></div> </td> </tr> <tr id="section-149"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-149">#</a> </div> <p>Helper for ensuring that utility functions are assigned at the top level.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">utility: </span><span class="p">(</span><span class="nx">name</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">ref: </span><span class="s2">&quot;__$name&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">ref</span><span class="p">]</span>
<span class="nx">ref</span>

View file

@ -92,7 +92,7 @@ deal with them.</p> </td> <td class="code">
<span class="nv">tag: </span><span class="nx">token</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="nx">stack</span><span class="p">[</span><span class="nx">stack</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="mi">2</span><span class="p">]</span><span class="o">:</span> <span class="o">+</span> <span class="nx">stack</span><span class="p">.</span><span class="nx">pop</span><span class="p">()</span> <span class="k">if</span> <span class="nx">tag</span> <span class="o">is</span> <span class="s1">&#39;OUTDENT&#39;</span>
<span class="nv">open: </span><span class="nx">stack</span><span class="p">[</span><span class="nx">stack</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]</span> <span class="o">&gt;</span> <span class="mi">0</span>
<span class="k">if</span> <span class="nx">prev</span> <span class="o">and</span> <span class="nx">include</span><span class="p">(</span><span class="nx">IMPLICIT_FUNC</span><span class="p">,</span> <span class="nx">prev</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span> <span class="o">and</span> <span class="nx">include</span><span class="p">(</span><span class="nx">IMPLICIT_CALL</span><span class="p">,</span> <span class="nx">tag</span><span class="p">)</span>
<span class="k">if</span> <span class="nx">prev</span> <span class="o">and</span> <span class="nx">prev</span><span class="p">.</span><span class="nx">spaced</span> <span class="o">and</span> <span class="nx">include</span><span class="p">(</span><span class="nx">IMPLICIT_FUNC</span><span class="p">,</span> <span class="nx">prev</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span> <span class="o">and</span> <span class="nx">include</span><span class="p">(</span><span class="nx">IMPLICIT_CALL</span><span class="p">,</span> <span class="nx">tag</span><span class="p">)</span>
<span class="nx">@tokens</span><span class="p">.</span><span class="nx">splice</span> <span class="nx">i</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="p">[</span><span class="s1">&#39;CALL_START&#39;</span><span class="p">,</span> <span class="s1">&#39;(&#39;</span><span class="p">,</span> <span class="nx">token</span><span class="p">[</span><span class="mi">2</span><span class="p">]]</span>
<span class="nx">stack</span><span class="p">[</span><span class="nx">stack</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]</span><span class="o">:</span> <span class="o">+</span> <span class="mi">1</span>
<span class="nx">stack</span><span class="p">.</span><span class="nx">push</span> <span class="mi">0</span> <span class="k">if</span> <span class="nx">include</span><span class="p">(</span><span class="nx">EXPRESSION_START</span><span class="p">,</span> <span class="nx">tag</span><span class="p">)</span>
@ -217,7 +217,7 @@ rewriting.</li>
look things up from either end.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">INVERSES: </span><span class="p">{}</span>
<span class="k">for</span> <span class="nx">pair</span> <span class="k">in</span> <span class="nx">BALANCED_PAIRS</span>
<span class="nx">INVERSES</span><span class="p">[</span><span class="nx">pair</span><span class="p">[</span><span class="mi">0</span><span class="p">]]</span><span class="o">:</span> <span class="nx">pair</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
<span class="nx">INVERSES</span><span class="p">[</span><span class="nx">pair</span><span class="p">[</span><span class="mi">1</span><span class="p">]]</span><span class="o">:</span> <span class="nx">pair</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-18"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-18">#</a> </div> <p>The tokens that signal the start of a balanced pair.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">EXPRESSION_START: </span><span class="nx">pair</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">for</span> <span class="nx">pair</span> <span class="k">in</span> <span class="nx">BALANCED_PAIRS</span></pre></div> </td> </tr> <tr id="section-19"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-19">#</a> </div> <p>The tokens that signal the end of a balanced pair.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">EXPRESSION_END: </span> <span class="nx">pair</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="k">for</span> <span class="nx">pair</span> <span class="k">in</span> <span class="nx">BALANCED_PAIRS</span></pre></div> </td> </tr> <tr id="section-20"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-20">#</a> </div> <p>Tokens that indicate the close of a clause of an expression.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">EXPRESSION_CLOSE: </span><span class="p">[</span><span class="s1">&#39;CATCH&#39;</span><span class="p">,</span> <span class="s1">&#39;WHEN&#39;</span><span class="p">,</span> <span class="s1">&#39;ELSE&#39;</span><span class="p">,</span> <span class="s1">&#39;FINALLY&#39;</span><span class="p">].</span><span class="nx">concat</span> <span class="nx">EXPRESSION_END</span></pre></div> </td> </tr> <tr id="section-21"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-21">#</a> </div> <p>Tokens that, if followed by an <code>IMPLICIT_CALL</code>, indicate a function invocation.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">IMPLICIT_FUNC: </span> <span class="p">[</span><span class="s1">&#39;IDENTIFIER&#39;</span><span class="p">,</span> <span class="s1">&#39;SUPER&#39;</span><span class="p">,</span> <span class="s1">&#39;)&#39;</span><span class="p">,</span> <span class="s1">&#39;CALL_END&#39;</span><span class="p">,</span> <span class="s1">&#39;]&#39;</span><span class="p">,</span> <span class="s1">&#39;INDEX_END&#39;</span><span class="p">,</span> <span class="s1">&#39;&lt;-&#39;</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-22"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-22">#</a> </div> <p>If preceded by an <code>IMPLICIT_FUNC</code>, indicates a function invocation.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">IMPLICIT_CALL: </span> <span class="p">[</span><span class="s1">&#39;IDENTIFIER&#39;</span><span class="p">,</span> <span class="s1">&#39;NUMBER&#39;</span><span class="p">,</span> <span class="s1">&#39;STRING&#39;</span><span class="p">,</span> <span class="s1">&#39;JS&#39;</span><span class="p">,</span> <span class="s1">&#39;REGEX&#39;</span><span class="p">,</span> <span class="s1">&#39;NEW&#39;</span><span class="p">,</span> <span class="s1">&#39;PARAM_START&#39;</span><span class="p">,</span>
<span class="nx">INVERSES</span><span class="p">[</span><span class="nx">pair</span><span class="p">[</span><span class="mi">1</span><span class="p">]]</span><span class="o">:</span> <span class="nx">pair</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-18"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-18">#</a> </div> <p>The tokens that signal the start of a balanced pair.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">EXPRESSION_START: </span><span class="nx">pair</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">for</span> <span class="nx">pair</span> <span class="k">in</span> <span class="nx">BALANCED_PAIRS</span></pre></div> </td> </tr> <tr id="section-19"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-19">#</a> </div> <p>The tokens that signal the end of a balanced pair.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">EXPRESSION_END: </span> <span class="nx">pair</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="k">for</span> <span class="nx">pair</span> <span class="k">in</span> <span class="nx">BALANCED_PAIRS</span></pre></div> </td> </tr> <tr id="section-20"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-20">#</a> </div> <p>Tokens that indicate the close of a clause of an expression.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">EXPRESSION_CLOSE: </span><span class="p">[</span><span class="s1">&#39;CATCH&#39;</span><span class="p">,</span> <span class="s1">&#39;WHEN&#39;</span><span class="p">,</span> <span class="s1">&#39;ELSE&#39;</span><span class="p">,</span> <span class="s1">&#39;FINALLY&#39;</span><span class="p">].</span><span class="nx">concat</span> <span class="nx">EXPRESSION_END</span></pre></div> </td> </tr> <tr id="section-21"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-21">#</a> </div> <p>Tokens that, if followed by an <code>IMPLICIT_CALL</code>, indicate a function invocation.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">IMPLICIT_FUNC: </span> <span class="p">[</span><span class="s1">&#39;IDENTIFIER&#39;</span><span class="p">,</span> <span class="s1">&#39;SUPER&#39;</span><span class="p">,</span> <span class="s1">&#39;)&#39;</span><span class="p">,</span> <span class="s1">&#39;CALL_END&#39;</span><span class="p">,</span> <span class="s1">&#39;]&#39;</span><span class="p">,</span> <span class="s1">&#39;INDEX_END&#39;</span><span class="p">,</span> <span class="s1">&#39;&lt;-&#39;</span><span class="p">,</span> <span class="s1">&#39;@&#39;</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-22"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-22">#</a> </div> <p>If preceded by an <code>IMPLICIT_FUNC</code>, indicates a function invocation.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">IMPLICIT_CALL: </span> <span class="p">[</span><span class="s1">&#39;IDENTIFIER&#39;</span><span class="p">,</span> <span class="s1">&#39;NUMBER&#39;</span><span class="p">,</span> <span class="s1">&#39;STRING&#39;</span><span class="p">,</span> <span class="s1">&#39;JS&#39;</span><span class="p">,</span> <span class="s1">&#39;REGEX&#39;</span><span class="p">,</span> <span class="s1">&#39;NEW&#39;</span><span class="p">,</span> <span class="s1">&#39;PARAM_START&#39;</span><span class="p">,</span>
<span class="s1">&#39;TRY&#39;</span><span class="p">,</span> <span class="s1">&#39;DELETE&#39;</span><span class="p">,</span> <span class="s1">&#39;TYPEOF&#39;</span><span class="p">,</span> <span class="s1">&#39;SWITCH&#39;</span><span class="p">,</span> <span class="s1">&#39;EXTENSION&#39;</span><span class="p">,</span>
<span class="s1">&#39;TRUE&#39;</span><span class="p">,</span> <span class="s1">&#39;FALSE&#39;</span><span class="p">,</span> <span class="s1">&#39;YES&#39;</span><span class="p">,</span> <span class="s1">&#39;NO&#39;</span><span class="p">,</span> <span class="s1">&#39;ON&#39;</span><span class="p">,</span> <span class="s1">&#39;OFF&#39;</span><span class="p">,</span> <span class="s1">&#39;!&#39;</span><span class="p">,</span> <span class="s1">&#39;!!&#39;</span><span class="p">,</span> <span class="s1">&#39;NOT&#39;</span><span class="p">,</span>
<span class="s1">&#39;THIS&#39;</span><span class="p">,</span> <span class="s1">&#39;NULL&#39;</span><span class="p">,</span>

View file

@ -7,7 +7,7 @@ Portions of Underscore are inspired by or borrowed from
<a href="http://osteele.com">Functional</a>, and John Resig's
<a href="http://ejohn.com">Micro-Templating</a>.
For all details and documentation:
<a href='http://documentcloud.github.com/underscore/'>http://documentcloud.github.com/underscore/</a></p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-3"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-3">#</a> </div> <h2>Baseline setup</h2> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-4"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-4">#</a> </div> <p>Establish the root object, <code>window</code> in the browser, or <code>global</code> on the server.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">root: </span><span class="k">this</span></pre></div> </td> </tr> <tr id="section-5"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-5">#</a> </div> <p>Save the previous value of the <code>_</code> variable.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">previousUnderscore: </span><span class="nx">root</span><span class="p">.</span><span class="nx">_</span></pre></div> </td> </tr> <tr id="section-6"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-6">#</a> </div> <p>Establish the object that gets thrown to break out of a loop iteration.
http://documentcloud.github.com/underscore/</p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-3"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-3">#</a> </div> <h2>Baseline setup</h2> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-4"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-4">#</a> </div> <p>Establish the root object, <code>window</code> in the browser, or <code>global</code> on the server.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">root: </span><span class="k">this</span></pre></div> </td> </tr> <tr id="section-5"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-5">#</a> </div> <p>Save the previous value of the <code>_</code> variable.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">previousUnderscore: </span><span class="nx">root</span><span class="p">.</span><span class="nx">_</span></pre></div> </td> </tr> <tr id="section-6"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-6">#</a> </div> <p>Establish the object that gets thrown to break out of a loop iteration.
<code>StopIteration</code> is SOP on Mozilla.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">breaker: </span><span class="k">if</span> <span class="k">typeof</span><span class="p">(</span><span class="nx">StopIteration</span><span class="p">)</span> <span class="o">is</span> <span class="s1">&#39;undefined&#39;</span> <span class="k">then</span> <span class="s1">&#39;__break__&#39;</span> <span class="k">else</span> <span class="nx">StopIteration</span></pre></div> </td> </tr> <tr id="section-7"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-7">#</a> </div> <p>Helper function to escape <strong>RegExp</strong> contents, because JS doesn't have one.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">escapeRegExp: </span><span class="p">(</span><span class="nx">string</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nx">string</span><span class="p">.</span><span class="nx">replace</span><span class="p">(</span><span class="sr">/([.*+?^${}()|[\]\/\\])/g</span><span class="p">,</span> <span class="s1">&#39;\\$1&#39;</span><span class="p">)</span></pre></div> </td> </tr> <tr id="section-8"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-8">#</a> </div> <p>Save bytes in the minified (but not gzipped) version:</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">ArrayProto: </span> <span class="nb">Array</span><span class="p">.</span><span class="nx">prototype</span>
<span class="nv">ObjProto: </span> <span class="nb">Object</span><span class="p">.</span><span class="nx">prototype</span></pre></div> </td> </tr> <tr id="section-9"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-9">#</a> </div> <p>Create quick reference variables for speed access to core prototypes.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">slice: </span> <span class="nx">ArrayProto</span><span class="p">.</span><span class="nx">slice</span>
<span class="nv">unshift: </span> <span class="nx">ArrayProto</span><span class="p">.</span><span class="nx">unshift</span>

View file

@ -46,7 +46,7 @@
<a href="#conditionals">Conditionals, Ternaries, and Conditional Assignment</a>
<a href="#aliases">Aliases</a>
<a href="#splats">Splats...</a>
<a href="#while">While Loops</a>
<a href="#while">While &amp; Until Loops</a>
<a href="#comprehensions">Comprehensions (Arrays, Objects, and Ranges)</a>
<a href="#slice_splice">Array Slicing and Splicing with Ranges</a>
<a href="#expressions">Everything is an Expression</a>
@ -130,7 +130,7 @@ alert reverse '.eeffoC yrT'</textarea></div>
<p>
<b>Latest Version:</b>
<a href="http://github.com/jashkenas/coffee-script/tarball/0.6.1">0.6.1</a>
<a href="http://github.com/jashkenas/coffee-script/tarball/0.6.2">0.6.2</a>
</p>
<h2>
@ -176,7 +176,7 @@ alert reverse '.eeffoC yrT'</textarea></div>
Then clone the CoffeeScript
<a href="http://github.com/jashkenas/coffee-script">source repository</a>
from GitHub, or download the latest
release: <a href="http://github.com/jashkenas/coffee-script/tarball/0.6.1">0.6.1</a>.
release: <a href="http://github.com/jashkenas/coffee-script/tarball/0.6.2">0.6.2</a>.
To install the CoffeeScript compiler system-wide
under <tt>/usr/local</tt>, open the directory and run:
</p>
@ -483,7 +483,7 @@ coffee --print app/scripts/*.coffee > concatenation.js</pre>
<p>
<span id="while" class="bookmark"></span>
<b class="header">While Loops</b>
<b class="header">While &amp; Until Loops</b>
The only low-level loop that CoffeeScript provides is the <b>while</b> loop. The
main difference from JavaScript is that the <b>while</b> loop can be used
as an expression, returning an array containing the result of each iteration
@ -491,6 +491,7 @@ coffee --print app/scripts/*.coffee > concatenation.js</pre>
</p>
<%= code_for('while', 'lyrics.join("\n")') %>
<p>
For readability, the <b>until</b> loop serves as an inverted <b>while</b> loop.
Other JavaScript loops, such as <b>for</b> loops and <b>do-while</b> loops
can be mimicked by variations on <b>while</b>, but the hope is that you
won't need to do that with CoffeeScript, either because you're using
@ -665,7 +666,7 @@ coffee --print app/scripts/*.coffee > concatenation.js</pre>
Pattern matching can be used with any depth of array and object nesting,
to help pull out deeply nested properties.
</p>
<%= code_for('object_extraction', 'poet + " — " + street') %>
<%= code_for('object_extraction', 'name + " — " + street') %>
<p>
Pattern matching can even be combined with splats.
</p>
@ -858,6 +859,11 @@ coffee --print app/scripts/*.coffee > concatenation.js</pre>
IRC client of your choice, or on
<a href="http://webchat.freenode.net/">webchat.freenode.net</a>.
</li>
<li>
<b>yeungda</b>'s <a href="http://github.com/yeungda/jcoffeescript">JCoffeeScript</a>
&mdash; A Java Library that uses Rhino to compile CoffeeScript, allowing
compilation within Java projects or on systems that Node.js doesn't support.
</li>
<li>
<b>defunkt</b>'s <a href="http://github.com/defunkt/coffee-mode">CoffeeScript Major Mode</a>
&mdash; a Emacs major mode that provides syntax highlighting, indentation
@ -886,6 +892,11 @@ coffee --print app/scripts/*.coffee > concatenation.js</pre>
&mdash; a plugin that serves and bundles CoffeeScript from within your
Rails application.
</li>
<li>
<b>sutto</b>'s <a href="http://github.com/Sutto/barista">Barista</a>
&mdash; a BistroCar alternative that integrates well with
<a href="http://documentcloud.github.com/jammit">Jammit</a> and Rails 3.
</li>
<li>
<b>inem</b> and <b>gerad</b>'s <a href="http://github.com/gerad/coffee-haml-filter">coffee-haml-filter</a>
&mdash; a custom filter for rendering CoffeeScript inline within
@ -912,7 +923,22 @@ coffee --print app/scripts/*.coffee > concatenation.js</pre>
<span id="change_log" class="bookmark"></span>
Change Log
</h2>
<p>
<b class="header" style="margin-top: 20px;">0.6.2</b>
The <tt>coffee</tt> command will now preserve directory structure when
compiling a directory full of scripts. Fixed two omissions that were preventing
the CoffeeScript compiler from running live within Internet Explorer.
There's now a syntax for block comments, similar in spirit to CoffeeScript's heredocs.
ECMA Harmony DRY-style pattern matching is now supported, where the name
of the property is the same as the name of the value: <tt>{name, length}: func</tt>.
Pattern matching is now allowed within comprehension variables. <tt>unless</tt>
is now allowed in block form. <tt>until</tt> loops were added, as the inverse
of <tt>while</tt> loops. <tt>switch</tt> statements are now allowed without
switch object clauses. Compatible
with Node.js <b>v0.1.95</b>.
</p>
<p>
<b class="header" style="margin-top: 20px;">0.6.1</b>
Upgraded CoffeeScript for compatibility with the new Node.js <b>v0.1.90</b>

View file

@ -7,28 +7,31 @@
child.prototype = new ctor();
child.prototype.constructor = child;
};
Animal = function Animal() { };
Animal.prototype.move = function move(meters) {
Animal = function() { };
Animal.prototype.move = function(meters) {
return alert(this.name + " moved " + meters + "m.");
};
Snake = function Snake(name) {
Snake = function(name) {
this.name = name;
return this;
};
__extends(Snake, Animal);
Snake.prototype.move = function move() {
Snake.prototype.move = function() {
alert("Slithering...");
return Snake.__superClass__.move.call(this, 5);
};
Horse = function Horse(name) {
Horse = function(name) {
this.name = name;
return this;
};
__extends(Horse, Animal);
Horse.prototype.move = function move() {
Horse.prototype.move = function() {
alert("Galloping...");
return Horse.__superClass__.move.call(this, 45);
};
sam = new Snake("Sammy the Python");
tom = new Horse("Tommy the Palomino");
sam.move();

View file

@ -1,6 +1,6 @@
(function(){
var eldest, grade;
grade = function grade(student) {
grade = function(student) {
if (student.excellent_work) {
return "A+";
} else if (student.okay_stuff) {

View file

@ -5,7 +5,7 @@
return func.apply(obj || {}, args ? args.concat(__slice.call(arguments, 0)) : arguments);
};
};
Account = function Account(customer, cart) {
Account = function(customer, cart) {
this.customer = customer;
this.cart = cart;
return $('.shopping_cart').bind('click', __bind(function(event) {

View file

@ -1,9 +1,9 @@
(function(){
var cube, square;
square = function square(x) {
square = function(x) {
return x * x;
};
cube = function cube(x) {
cube = function(x) {
return square(x) * x;
};
})();

View file

@ -1,6 +1,6 @@
(function(){
var _a, city, forecast, temp, weather_report;
weather_report = function weather_report(location) {
weather_report = function(location) {
// Make an Ajax request to fetch the weather...
return [location, 72, "Mostly Sunny"];
};

View file

@ -1,5 +1,5 @@
(function(){
var _a, _b, _c, city, futurists, poet, street;
var _a, _b, _c, city, futurists, name, street;
futurists = {
sculptor: "Umberto Boccioni",
painter: "Vladimir Burliuk",
@ -10,7 +10,7 @@
};
_a = futurists;
_b = _a.poet;
poet = _b.name;
name = _b.name;
_c = _b.address;
street = _c[0];
city = _c[1];

View file

@ -9,7 +9,7 @@
number = -42;
}
// Functions:
square = function square(x) {
square = function(x) {
return x * x;
};
// Arrays:
@ -18,14 +18,15 @@
math = {
root: Math.sqrt,
square: square,
cube: function cube(x) {
cube: function(x) {
return x * square(x);
}
};
// Splats:
race = function race(winner) {
race = function(winner) {
var runners;
runners = __slice.call(arguments, 1, arguments.length - 0);
var _a = arguments.length, _b = _a >= 2;
runners = __slice.call(arguments, 1, _a - 0);
return print(winner, runners);
};
// Existence:

View file

@ -1,5 +1,5 @@
(function(){
String.prototype.dasherize = function dasherize() {
String.prototype.dasherize = function() {
return this.replace(/_/g, "-");
};
})();

View file

@ -1,21 +1,21 @@
(function(){
var _a, _b, _c, _d, countdown, egg_delivery, num;
var _a, _b, _c, countdown, egg_delivery, num;
countdown = (function() {
_a = []; _c = 10; _d = 1;
for (_b = 0, num = _c; (_c <= _d ? num <= _d : num >= _d); (_c <= _d ? num += 1 : num -= 1), _b++) {
_a = []; _b = 10; _c = 1;
for (num = _b; (_b <= _c ? num <= _c : num >= _c); (_b <= _c ? num += 1 : num -= 1)) {
_a.push(num);
}
return _a;
})();
egg_delivery = function egg_delivery() {
var _e, _f, _g, _h, dozen_eggs, i;
_e = []; _g = 0; _h = eggs.length;
for (_f = 0, i = _g; (_g <= _h ? i < _h : i > _h); (_g <= _h ? i += 12 : i -= 12), _f++) {
_e.push((function() {
egg_delivery = function() {
var _d, _e, _f, dozen_eggs, i;
_d = []; _e = 0; _f = eggs.length;
for (i = _e; (_e <= _f ? i < _f : i > _f); (_e <= _f ? i += 12 : i -= 12)) {
_d.push((function() {
dozen_eggs = eggs.slice(i, i + 12);
return deliver(new egg_carton(dozen));
})());
}
return _e;
return _d;
};
})();

View file

@ -1,7 +1,7 @@
(function(){
var change_numbers, new_num, num;
num = 1;
change_numbers = function change_numbers() {
change_numbers = function() {
var new_num;
new_num = -1;
num = 10;

View file

@ -1,4 +1,4 @@
(function(){
var _a;
(_a = lottery.draw_winner()) == undefined ? undefined : _a.address == undefined ? undefined : _a.address.zipcode;
typeof (_a = (lottery.draw_winner())) === "undefined" || _a == undefined ? undefined : _a.address == undefined ? undefined : _a.address.zipcode;
})();

View file

@ -2,9 +2,10 @@
var award_medals, contenders, gold, silver, the_field;
var __slice = Array.prototype.slice;
gold = (silver = (the_field = "unknown"));
award_medals = function award_medals(first, second) {
award_medals = function(first, second) {
var rest;
rest = __slice.call(arguments, 2, arguments.length - 0);
var _a = arguments.length, _b = _a >= 3;
rest = __slice.call(arguments, 2, _a - 0);
gold = first;
silver = second;
the_field = rest;

View file

@ -5,7 +5,7 @@
while (supply > demand) {
buy();
}
while (supply < demand) {
while (!(supply > demand)) {
sell();
}
}

File diff suppressed because one or more lines are too long

View file

@ -32,7 +32,7 @@
<a href="#conditionals">Conditionals, Ternaries, and Conditional Assignment</a>
<a href="#aliases">Aliases</a>
<a href="#splats">Splats...</a>
<a href="#while">While Loops</a>
<a href="#while">While &amp; Until Loops</a>
<a href="#comprehensions">Comprehensions (Arrays, Objects, and Ranges)</a>
<a href="#slice_splice">Array Slicing and Splicing with Ranges</a>
<a href="#expressions">Everything is an Expression</a>
@ -116,7 +116,7 @@ alert reverse '.eeffoC yrT'</textarea></div>
<p>
<b>Latest Version:</b>
<a href="http://github.com/jashkenas/coffee-script/tarball/0.6.1">0.6.1</a>
<a href="http://github.com/jashkenas/coffee-script/tarball/0.6.2">0.6.2</a>
</p>
<h2>
@ -165,7 +165,7 @@ opposite_day <span class="Keyword">=</span> <span class="BuiltInConstant">true</
number <span class="Keyword">=</span> <span class="Keyword">-</span><span class="Number">42</span>;
}
<span class="Comment"><span class="Comment">//</span> Functions:</span>
square <span class="Keyword">=</span> <span class="Storage">function</span> <span class="FunctionName">square</span>(<span class="FunctionArgument">x</span>) {
<span class="FunctionName">square</span> = <span class="Storage">function</span>(<span class="FunctionArgument">x</span>) {
<span class="Keyword">return</span> x <span class="Keyword">*</span> x;
};
<span class="Comment"><span class="Comment">//</span> Arrays:</span>
@ -174,14 +174,15 @@ list <span class="Keyword">=</span> [<span class="Number">1</span>, <span class=
math <span class="Keyword">=</span> {
root: <span class="LibraryClassType">Math</span>.sqrt,
square: square,
cube: <span class="Storage">function</span> <span class="FunctionName">cube</span>(<span class="FunctionArgument">x</span>) {
<span class="FunctionName">cube</span>: <span class="Storage">function</span>(<span class="FunctionArgument">x</span>) {
<span class="Keyword">return</span> x <span class="Keyword">*</span> square(x);
}
};
<span class="Comment"><span class="Comment">//</span> Splats:</span>
race <span class="Keyword">=</span> <span class="Storage">function</span> <span class="FunctionName">race</span>(<span class="FunctionArgument">winner</span>) {
<span class="FunctionName">race</span> = <span class="Storage">function</span>(<span class="FunctionArgument">winner</span>) {
<span class="Storage">var</span> runners;
runners <span class="Keyword">=</span> __slice.<span class="LibraryFunction">call</span>(arguments, <span class="Number">1</span>, arguments.<span class="LibraryConstant">length</span> <span class="Keyword">-</span> <span class="Number">0</span>);
<span class="Storage">var</span> _a <span class="Keyword">=</span> arguments.<span class="LibraryConstant">length</span>, _b <span class="Keyword">=</span> _a <span class="Keyword">&gt;=</span> <span class="Number">2</span>;
runners <span class="Keyword">=</span> __slice.<span class="LibraryFunction">call</span>(arguments, <span class="Number">1</span>, _a <span class="Keyword">-</span> <span class="Number">0</span>);
<span class="Keyword">return</span> <span class="LibraryFunction">print</span>(winner, runners);
};
<span class="Comment"><span class="Comment">//</span> Existence:</span>
@ -207,7 +208,7 @@ if (opposite_day) {
number = -42;
}
// Functions:
square = function square(x) {
square = function(x) {
return x * x;
};
// Arrays:
@ -216,14 +217,15 @@ list = [1, 2, 3, 4, 5];
math = {
root: Math.sqrt,
square: square,
cube: function cube(x) {
cube: function(x) {
return x * square(x);
}
};
// Splats:
race = function race(winner) {
race = function(winner) {
var runners;
runners = __slice.call(arguments, 1, arguments.length - 0);
var _a = arguments.length, _b = _a >= 2;
runners = __slice.call(arguments, 1, _a - 0);
return print(winner, runners);
};
// Existence:
@ -275,7 +277,7 @@ cubed_list = (function() {
Then clone the CoffeeScript
<a href="http://github.com/jashkenas/coffee-script">source repository</a>
from GitHub, or download the latest
release: <a href="http://github.com/jashkenas/coffee-script/tarball/0.6.1">0.6.1</a>.
release: <a href="http://github.com/jashkenas/coffee-script/tarball/0.6.2">0.6.2</a>.
To install the CoffeeScript compiler system-wide
under <tt>/usr/local</tt>, open the directory and run:
</p>
@ -450,17 +452,17 @@ coffee --print app/scripts/*.coffee > concatenation.js</pre>
<div class='code'><pre class="idle"><span class="FunctionName">square</span><span class="Keyword">:</span> <span class="FunctionArgument">(</span><span class="FunctionArgument">x</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span> x <span class="Keyword">*</span> x
<span class="FunctionName">cube</span><span class="Keyword">:</span> <span class="FunctionArgument">(</span><span class="FunctionArgument">x</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span> square(x) <span class="Keyword">*</span> x
</pre><pre class="idle"><span class="Storage">var</span> cube, square;
square <span class="Keyword">=</span> <span class="Storage">function</span> <span class="FunctionName">square</span>(<span class="FunctionArgument">x</span>) {
<span class="FunctionName">square</span> = <span class="Storage">function</span>(<span class="FunctionArgument">x</span>) {
<span class="Keyword">return</span> x <span class="Keyword">*</span> x;
};
cube <span class="Keyword">=</span> <span class="Storage">function</span> <span class="FunctionName">cube</span>(<span class="FunctionArgument">x</span>) {
<span class="FunctionName">cube</span> = <span class="Storage">function</span>(<span class="FunctionArgument">x</span>) {
<span class="Keyword">return</span> square(x) <span class="Keyword">*</span> x;
};
</pre><button onclick='javascript: var cube, square;
square = function square(x) {
square = function(x) {
return x * x;
};
cube = function cube(x) {
cube = function(x) {
return square(x) * x;
};
;alert(cube(5));'>run: cube(5)</button><br class='clear' /></div>
@ -546,7 +548,7 @@ matrix = [1, 0, 1, 0, 0, 1, 1, 1, 0];
new_num<span class="Keyword">:</span> change_numbers()
</pre><pre class="idle"><span class="Storage">var</span> change_numbers, new_num, num;
num <span class="Keyword">=</span> <span class="Number">1</span>;
change_numbers <span class="Keyword">=</span> <span class="Storage">function</span> <span class="FunctionName">change_numbers</span>() {
<span class="FunctionName">change_numbers</span> = <span class="Storage">function</span>() {
<span class="Storage">var</span> new_num;
new_num <span class="Keyword">=</span> <span class="Keyword">-</span><span class="Number">1</span>;
num <span class="Keyword">=</span> <span class="Number">10</span>;
@ -555,7 +557,7 @@ change_numbers <span class="Keyword">=</span> <span class="Storage">function</sp
new_num <span class="Keyword">=</span> change_numbers();
</pre><button onclick='javascript: var change_numbers, new_num, num;
num = 1;
change_numbers = function change_numbers() {
change_numbers = function() {
var new_num;
new_num = -1;
num = 10;
@ -722,9 +724,10 @@ alert <span class="String"><span class="String">&quot;</span>The Field: <span cl
</pre><pre class="idle"><span class="Storage">var</span> award_medals, contenders, gold, silver, the_field;
<span class="Storage">var</span> __slice <span class="Keyword">=</span> <span class="LibraryClassType">Array</span>.<span class="LibraryConstant">prototype</span>.slice;
gold <span class="Keyword">=</span> (silver <span class="Keyword">=</span> (the_field <span class="Keyword">=</span> <span class="String"><span class="String">&quot;</span>unknown<span class="String">&quot;</span></span>));
award_medals <span class="Keyword">=</span> <span class="Storage">function</span> <span class="FunctionName">award_medals</span>(<span class="FunctionArgument">first, second</span>) {
<span class="FunctionName">award_medals</span> = <span class="Storage">function</span>(<span class="FunctionArgument">first, second</span>) {
<span class="Storage">var</span> rest;
rest <span class="Keyword">=</span> __slice.<span class="LibraryFunction">call</span>(arguments, <span class="Number">2</span>, arguments.<span class="LibraryConstant">length</span> <span class="Keyword">-</span> <span class="Number">0</span>);
<span class="Storage">var</span> _a <span class="Keyword">=</span> arguments.<span class="LibraryConstant">length</span>, _b <span class="Keyword">=</span> _a <span class="Keyword">&gt;=</span> <span class="Number">3</span>;
rest <span class="Keyword">=</span> __slice.<span class="LibraryFunction">call</span>(arguments, <span class="Number">2</span>, _a <span class="Keyword">-</span> <span class="Number">0</span>);
gold <span class="Keyword">=</span> first;
silver <span class="Keyword">=</span> second;
the_field <span class="Keyword">=</span> rest;
@ -738,9 +741,10 @@ award_medals.<span class="LibraryFunction">apply</span>(<span class="Variable">t
</pre><button onclick='javascript: var award_medals, contenders, gold, silver, the_field;
var __slice = Array.prototype.slice;
gold = (silver = (the_field = "unknown"));
award_medals = function award_medals(first, second) {
award_medals = function(first, second) {
var rest;
rest = __slice.call(arguments, 2, arguments.length - 0);
var _a = arguments.length, _b = _a >= 3;
rest = __slice.call(arguments, 2, _a - 0);
gold = first;
silver = second;
the_field = rest;
@ -755,7 +759,7 @@ alert("The Field: " + the_field);
<p>
<span id="while" class="bookmark"></span>
<b class="header">While Loops</b>
<b class="header">While &amp; Until Loops</b>
The only low-level loop that CoffeeScript provides is the <b>while</b> loop. The
main difference from JavaScript is that the <b>while</b> loop can be used
as an expression, returning an array containing the result of each iteration
@ -763,8 +767,8 @@ alert("The Field: " + the_field);
</p>
<div class='code'><pre class="idle"><span class="Comment"><span class="Comment">#</span> Econ 101</span>
<span class="Keyword">if</span> <span class="Variable">this</span>.studying_economics
<span class="Keyword">while</span> supply <span class="Keyword">&gt;</span> demand <span class="Keyword">then</span> buy()
<span class="Keyword">while</span> supply <span class="Keyword">&lt;</span> demand <span class="Keyword">then</span> sell()
buy() <span class="Keyword">while</span> supply <span class="Keyword">&gt;</span> demand
sell() <span class="Keyword">until</span> supply <span class="Keyword">&gt;</span> demand
<span class="Comment"><span class="Comment">#</span> Nursery Rhyme</span>
num<span class="Keyword">:</span> <span class="Number">6</span>
@ -777,7 +781,7 @@ lyrics<span class="Keyword">:</span> <span class="Keyword">while</span> num <spa
<span class="Keyword">while</span> (supply <span class="Keyword">&gt;</span> demand) {
buy();
}
<span class="Keyword">while</span> (supply <span class="Keyword">&lt;</span> demand) {
<span class="Keyword">while</span> (<span class="Keyword">!</span>(supply <span class="Keyword">&gt;</span> demand)) {
sell();
}
}
@ -797,7 +801,7 @@ if (this.studying_economics) {
while (supply > demand) {
buy();
}
while (supply < demand) {
while (!(supply > demand)) {
sell();
}
}
@ -813,6 +817,7 @@ One fell out and bumped his head.");
})();
;alert(lyrics.join("\n"));'>run: lyrics.join("\n")</button><br class='clear' /></div>
<p>
For readability, the <b>until</b> loop serves as an inverted <b>while</b> loop.
Other JavaScript loops, such as <b>for</b> loops and <b>do-while</b> loops
can be mimicked by variations on <b>while</b>, but the hope is that you
won't need to do that with CoffeeScript, either because you're using
@ -873,43 +878,43 @@ _f <span class="Keyword">=</span> asteroids;
<span class="Keyword">for</span> i <span class="Keyword">in</span> [<span class="Number">0</span>...eggs.length] <span class="Keyword">by</span> <span class="Number">12</span>
dozen_eggs<span class="Keyword">:</span> eggs[i...i<span class="Keyword">+</span><span class="Number">12</span>]
deliver <span class="Keyword">new</span> <span class="TypeName">egg_carton</span>(dozen)
</pre><pre class="idle"><span class="Storage">var</span> _a, _b, _c, _d, countdown, egg_delivery, num;
</pre><pre class="idle"><span class="Storage">var</span> _a, _b, _c, countdown, egg_delivery, num;
countdown <span class="Keyword">=</span> (<span class="Storage">function</span>() {
_a <span class="Keyword">=</span> []; _c <span class="Keyword">=</span> <span class="Number">10</span>; _d <span class="Keyword">=</span> <span class="Number">1</span>;
<span class="Keyword">for</span> (_b <span class="Keyword">=</span> <span class="Number">0</span>, num <span class="Keyword">=</span> _c; (_c <span class="Keyword">&lt;=</span> _d ? num <span class="Keyword">&lt;=</span> _d : num <span class="Keyword">&gt;=</span> _d); (_c <span class="Keyword">&lt;=</span> _d ? num <span class="Keyword">+</span><span class="Keyword">=</span> <span class="Number">1</span> : num <span class="Keyword">-</span><span class="Keyword">=</span> <span class="Number">1</span>), _b<span class="Keyword">++</span>) {
_a <span class="Keyword">=</span> []; _b <span class="Keyword">=</span> <span class="Number">10</span>; _c <span class="Keyword">=</span> <span class="Number">1</span>;
<span class="Keyword">for</span> (num <span class="Keyword">=</span> _b; (_b <span class="Keyword">&lt;=</span> _c ? num <span class="Keyword">&lt;=</span> _c : num <span class="Keyword">&gt;=</span> _c); (_b <span class="Keyword">&lt;=</span> _c ? num <span class="Keyword">+</span><span class="Keyword">=</span> <span class="Number">1</span> : num <span class="Keyword">-</span><span class="Keyword">=</span> <span class="Number">1</span>)) {
_a.<span class="LibraryFunction">push</span>(num);
}
<span class="Keyword">return</span> _a;
})();
egg_delivery <span class="Keyword">=</span> <span class="Storage">function</span> <span class="FunctionName">egg_delivery</span>() {
<span class="Storage">var</span> _e, _f, _g, _h, dozen_eggs, i;
_e <span class="Keyword">=</span> []; _g <span class="Keyword">=</span> <span class="Number">0</span>; _h <span class="Keyword">=</span> eggs.<span class="LibraryConstant">length</span>;
<span class="Keyword">for</span> (_f <span class="Keyword">=</span> <span class="Number">0</span>, i <span class="Keyword">=</span> _g; (_g <span class="Keyword">&lt;=</span> _h ? i <span class="Keyword">&lt;</span> _h : i <span class="Keyword">&gt;</span> _h); (_g <span class="Keyword">&lt;=</span> _h ? i <span class="Keyword">+</span><span class="Keyword">=</span> <span class="Number">12</span> : i <span class="Keyword">-</span><span class="Keyword">=</span> <span class="Number">12</span>), _f<span class="Keyword">++</span>) {
_e.<span class="LibraryFunction">push</span>((<span class="Storage">function</span>() {
<span class="FunctionName">egg_delivery</span> = <span class="Storage">function</span>() {
<span class="Storage">var</span> _d, _e, _f, dozen_eggs, i;
_d <span class="Keyword">=</span> []; _e <span class="Keyword">=</span> <span class="Number">0</span>; _f <span class="Keyword">=</span> eggs.<span class="LibraryConstant">length</span>;
<span class="Keyword">for</span> (i <span class="Keyword">=</span> _e; (_e <span class="Keyword">&lt;=</span> _f ? i <span class="Keyword">&lt;</span> _f : i <span class="Keyword">&gt;</span> _f); (_e <span class="Keyword">&lt;=</span> _f ? i <span class="Keyword">+</span><span class="Keyword">=</span> <span class="Number">12</span> : i <span class="Keyword">-</span><span class="Keyword">=</span> <span class="Number">12</span>)) {
_d.<span class="LibraryFunction">push</span>((<span class="Storage">function</span>() {
dozen_eggs <span class="Keyword">=</span> eggs.<span class="LibraryFunction">slice</span>(i, i <span class="Keyword">+</span> <span class="Number">12</span>);
<span class="Keyword">return</span> deliver(<span class="Keyword">new</span> <span class="TypeName">egg_carton</span>(dozen));
})());
}
<span class="Keyword">return</span> _e;
<span class="Keyword">return</span> _d;
};
</pre><button onclick='javascript: var _a, _b, _c, _d, countdown, egg_delivery, num;
</pre><button onclick='javascript: var _a, _b, _c, countdown, egg_delivery, num;
countdown = (function() {
_a = []; _c = 10; _d = 1;
for (_b = 0, num = _c; (_c <= _d ? num <= _d : num >= _d); (_c <= _d ? num += 1 : num -= 1), _b++) {
_a = []; _b = 10; _c = 1;
for (num = _b; (_b <= _c ? num <= _c : num >= _c); (_b <= _c ? num += 1 : num -= 1)) {
_a.push(num);
}
return _a;
})();
egg_delivery = function egg_delivery() {
var _e, _f, _g, _h, dozen_eggs, i;
_e = []; _g = 0; _h = eggs.length;
for (_f = 0, i = _g; (_g <= _h ? i < _h : i > _h); (_g <= _h ? i += 12 : i -= 12), _f++) {
_e.push((function() {
egg_delivery = function() {
var _d, _e, _f, dozen_eggs, i;
_d = []; _e = 0; _f = eggs.length;
for (i = _e; (_e <= _f ? i < _f : i > _f); (_e <= _f ? i += 12 : i -= 12)) {
_d.push((function() {
dozen_eggs = eggs.slice(i, i + 12);
return deliver(new egg_carton(dozen));
})());
}
return _e;
return _d;
};
;alert(countdown);'>run: countdown</button><br class='clear' /></div>
<p>
@ -1015,7 +1020,7 @@ numbers.splice.apply(numbers, [3, 6 - 3 + 1].concat([-3, -4, -5, -6]));
eldest<span class="Keyword">:</span> <span class="Keyword">if</span> <span class="Number">24</span> <span class="Keyword">&gt;</span> <span class="Number">21</span> <span class="Keyword">then</span> <span class="String"><span class="String">&quot;</span>Liz<span class="String">&quot;</span></span> <span class="Keyword">else</span> <span class="String"><span class="String">&quot;</span>Ike<span class="String">&quot;</span></span>
</pre><pre class="idle"><span class="Storage">var</span> eldest, grade;
grade <span class="Keyword">=</span> <span class="Storage">function</span> <span class="FunctionName">grade</span>(<span class="FunctionArgument">student</span>) {
<span class="FunctionName">grade</span> = <span class="Storage">function</span>(<span class="FunctionArgument">student</span>) {
<span class="Keyword">if</span> (student.excellent_work) {
<span class="Keyword">return</span> <span class="String"><span class="String">&quot;</span>A+<span class="String">&quot;</span></span>;
} <span class="Keyword">else</span> <span class="Keyword">if</span> (student.okay_stuff) {
@ -1030,7 +1035,7 @@ grade <span class="Keyword">=</span> <span class="Storage">function</span> <span
};
eldest <span class="Keyword">=</span> <span class="Number">24</span> <span class="Keyword">&gt;</span> <span class="Number">21</span> ? <span class="String"><span class="String">&quot;</span>Liz<span class="String">&quot;</span></span> : <span class="String"><span class="String">&quot;</span>Ike<span class="String">&quot;</span></span>;
</pre><button onclick='javascript: var eldest, grade;
grade = function grade(student) {
grade = function(student) {
if (student.excellent_work) {
return "A+";
} else if (student.okay_stuff) {
@ -1164,7 +1169,7 @@ speed = (typeof speed !== "undefined" && speed !== null) ? speed : 140;
</p>
<div class='code'><pre class="idle">lottery.draw_winner()<span class="Keyword">?</span>.address<span class="Keyword">?</span>.zipcode
</pre><pre class="idle"><span class="Storage">var</span> _a;
(_a <span class="Keyword">=</span> lottery.draw_winner()) <span class="Keyword">==</span> undefined ? undefined : _a.address <span class="Keyword">==</span> undefined ? undefined : _a.address.zipcode;
<span class="Keyword">typeof</span> (_a <span class="Keyword">=</span> (lottery.draw_winner())) <span class="Keyword">===</span> <span class="String"><span class="String">&quot;</span>undefined<span class="String">&quot;</span></span> <span class="Keyword">||</span> _a <span class="Keyword">==</span> undefined ? undefined : _a.address <span class="Keyword">==</span> undefined ? undefined : _a.address.zipcode;
</pre><br class='clear' /></div>
<p>
Soaking up nulls is similar to Ruby's
@ -1231,28 +1236,31 @@ tom.move()
<span class="LibraryClassType">child</span>.<span class="LibraryConstant">prototype</span> = <span class="Keyword">new</span> <span class="TypeName">ctor</span>();
<span class="LibraryClassType">child</span>.<span class="LibraryConstant">prototype</span>.<span class="FunctionName">constructor</span> = child;
};
Animal <span class="Keyword">=</span> <span class="Storage">function</span> <span class="FunctionName">Animal</span>() { };
<span class="LibraryClassType">Animal</span>.<span class="LibraryConstant">prototype</span>.<span class="FunctionName">move</span> = <span class="Storage">function</span> <span class="FunctionName">move</span>(<span class="FunctionArgument">meters</span>) {
<span class="FunctionName">Animal</span> = <span class="Storage">function</span>() { };
<span class="LibraryClassType">Animal</span>.<span class="LibraryConstant">prototype</span>.<span class="FunctionName">move</span> = <span class="Storage">function</span>(<span class="FunctionArgument">meters</span>) {
<span class="Keyword">return</span> <span class="LibraryFunction">alert</span>(<span class="Variable">this</span>.<span class="LibraryConstant">name</span> <span class="Keyword">+</span> <span class="String"><span class="String">&quot;</span> moved <span class="String">&quot;</span></span> <span class="Keyword">+</span> meters <span class="Keyword">+</span> <span class="String"><span class="String">&quot;</span>m.<span class="String">&quot;</span></span>);
};
Snake <span class="Keyword">=</span> <span class="Storage">function</span> <span class="FunctionName">Snake</span>(<span class="FunctionArgument">name</span>) {
<span class="FunctionName">Snake</span> = <span class="Storage">function</span>(<span class="FunctionArgument">name</span>) {
<span class="Variable">this</span>.<span class="LibraryConstant">name</span> <span class="Keyword">=</span> name;
<span class="Keyword">return</span> <span class="Variable">this</span>;
};
__extends(Snake, Animal);
<span class="LibraryClassType">Snake</span>.<span class="LibraryConstant">prototype</span>.<span class="FunctionName">move</span> = <span class="Storage">function</span> <span class="FunctionName">move</span>() {
<span class="LibraryClassType">Snake</span>.<span class="LibraryConstant">prototype</span>.<span class="FunctionName">move</span> = <span class="Storage">function</span>() {
<span class="LibraryFunction">alert</span>(<span class="String"><span class="String">&quot;</span>Slithering...<span class="String">&quot;</span></span>);
<span class="Keyword">return</span> Snake.__superClass__.move.<span class="LibraryFunction">call</span>(<span class="Variable">this</span>, <span class="Number">5</span>);
};
Horse <span class="Keyword">=</span> <span class="Storage">function</span> <span class="FunctionName">Horse</span>(<span class="FunctionArgument">name</span>) {
<span class="FunctionName">Horse</span> = <span class="Storage">function</span>(<span class="FunctionArgument">name</span>) {
<span class="Variable">this</span>.<span class="LibraryConstant">name</span> <span class="Keyword">=</span> name;
<span class="Keyword">return</span> <span class="Variable">this</span>;
};
__extends(Horse, Animal);
<span class="LibraryClassType">Horse</span>.<span class="LibraryConstant">prototype</span>.<span class="FunctionName">move</span> = <span class="Storage">function</span> <span class="FunctionName">move</span>() {
<span class="LibraryClassType">Horse</span>.<span class="LibraryConstant">prototype</span>.<span class="FunctionName">move</span> = <span class="Storage">function</span>() {
<span class="LibraryFunction">alert</span>(<span class="String"><span class="String">&quot;</span>Galloping...<span class="String">&quot;</span></span>);
<span class="Keyword">return</span> Horse.__superClass__.move.<span class="LibraryFunction">call</span>(<span class="Variable">this</span>, <span class="Number">45</span>);
};
sam <span class="Keyword">=</span> <span class="Keyword">new</span> <span class="TypeName">Snake</span>(<span class="String"><span class="String">&quot;</span>Sammy the Python<span class="String">&quot;</span></span>);
tom <span class="Keyword">=</span> <span class="Keyword">new</span> <span class="TypeName">Horse</span>(<span class="String"><span class="String">&quot;</span>Tommy the Palomino<span class="String">&quot;</span></span>);
sam.move();
@ -1265,28 +1273,31 @@ var __extends = function(child, parent) {
child.prototype = new ctor();
child.prototype.constructor = child;
};
Animal = function Animal() { };
Animal.prototype.move = function move(meters) {
Animal = function() { };
Animal.prototype.move = function(meters) {
return alert(this.name + " moved " + meters + "m.");
};
Snake = function Snake(name) {
Snake = function(name) {
this.name = name;
return this;
};
__extends(Snake, Animal);
Snake.prototype.move = function move() {
Snake.prototype.move = function() {
alert("Slithering...");
return Snake.__superClass__.move.call(this, 5);
};
Horse = function Horse(name) {
Horse = function(name) {
this.name = name;
return this;
};
__extends(Horse, Animal);
Horse.prototype.move = function move() {
Horse.prototype.move = function() {
alert("Galloping...");
return Horse.__superClass__.move.call(this, 45);
};
sam = new Snake("Sammy the Python");
tom = new Horse("Tommy the Palomino");
sam.move();
@ -1301,10 +1312,10 @@ tom.move();
</p>
<div class='code'><pre class="idle"><span class="FunctionName">String::dasherize</span><span class="Keyword">:</span> <span class="Storage">-&gt;</span>
<span class="Variable">this</span>.replace(<span class="String"><span class="String">/</span>_<span class="String">/</span>g</span>, <span class="String"><span class="String">&quot;</span>-<span class="String">&quot;</span></span>)
</pre><pre class="idle"><span class="LibraryClassType">String</span>.<span class="LibraryConstant">prototype</span>.<span class="FunctionName">dasherize</span> = <span class="Storage">function</span> <span class="FunctionName">dasherize</span>() {
</pre><pre class="idle"><span class="LibraryClassType">String</span>.<span class="LibraryConstant">prototype</span>.<span class="FunctionName">dasherize</span> = <span class="Storage">function</span>() {
<span class="Keyword">return</span> <span class="Variable">this</span>.<span class="LibraryFunction">replace</span>(<span class="String"><span class="String">/</span>_<span class="String">/</span>g</span>, <span class="String"><span class="String">&quot;</span>-<span class="String">&quot;</span></span>);
};
</pre><button onclick='javascript: String.prototype.dasherize = function dasherize() {
</pre><button onclick='javascript: String.prototype.dasherize = function() {
return this.replace(/_/g, "-");
};
;alert("one_two".dasherize());'>run: "one_two".dasherize()</button><br class='clear' /></div>
@ -1351,7 +1362,7 @@ and_switch = _a[1];
<span class="Keyword">[</span>city, temp, forecast<span class="Keyword">]:</span> weather_report <span class="String"><span class="String">&quot;</span>Berkeley, CA<span class="String">&quot;</span></span>
</pre><pre class="idle"><span class="Storage">var</span> _a, city, forecast, temp, weather_report;
weather_report <span class="Keyword">=</span> <span class="Storage">function</span> <span class="FunctionName">weather_report</span>(<span class="FunctionArgument">location</span>) {
<span class="FunctionName">weather_report</span> = <span class="Storage">function</span>(<span class="FunctionArgument">location</span>) {
<span class="Comment"><span class="Comment">//</span> Make an Ajax request to fetch the weather...</span>
<span class="Keyword">return</span> [location, <span class="Number">72</span>, <span class="String"><span class="String">&quot;</span>Mostly Sunny<span class="String">&quot;</span></span>];
};
@ -1360,7 +1371,7 @@ city <span class="Keyword">=</span> _a[<span class="Number">0</span>];
temp <span class="Keyword">=</span> _a[<span class="Number">1</span>];
forecast <span class="Keyword">=</span> _a[<span class="Number">2</span>];
</pre><button onclick='javascript: var _a, city, forecast, temp, weather_report;
weather_report = function weather_report(location) {
weather_report = function(location) {
// Make an Ajax request to fetch the weather...
return [location, 72, "Mostly Sunny"];
};
@ -1385,8 +1396,8 @@ forecast = _a[2];
}
}
{poet<span class="Keyword">:</span> {name<span class="Keyword">:</span> poet, address<span class="Keyword">:</span> [street, city]}}<span class="Keyword">:</span> futurists
</pre><pre class="idle"><span class="Storage">var</span> _a, _b, _c, city, futurists, poet, street;
{poet<span class="Keyword">:</span> {name, address<span class="Keyword">:</span> [street, city]}}<span class="Keyword">:</span> futurists
</pre><pre class="idle"><span class="Storage">var</span> _a, _b, _c, city, futurists, name, street;
futurists <span class="Keyword">=</span> {
sculptor: <span class="String"><span class="String">&quot;</span>Umberto Boccioni<span class="String">&quot;</span></span>,
painter: <span class="String"><span class="String">&quot;</span>Vladimir Burliuk<span class="String">&quot;</span></span>,
@ -1397,11 +1408,11 @@ futurists <span class="Keyword">=</span> {
};
_a <span class="Keyword">=</span> futurists;
_b <span class="Keyword">=</span> _a.poet;
poet <span class="Keyword">=</span> _b.<span class="LibraryConstant">name</span>;
name <span class="Keyword">=</span> _b.<span class="LibraryConstant">name</span>;
_c <span class="Keyword">=</span> _b.address;
street <span class="Keyword">=</span> _c[<span class="Number">0</span>];
city <span class="Keyword">=</span> _c[<span class="Number">1</span>];
</pre><button onclick='javascript: var _a, _b, _c, city, futurists, poet, street;
</pre><button onclick='javascript: var _a, _b, _c, city, futurists, name, street;
futurists = {
sculptor: "Umberto Boccioni",
painter: "Vladimir Burliuk",
@ -1412,11 +1423,11 @@ futurists = {
};
_a = futurists;
_b = _a.poet;
poet = _b.name;
name = _b.name;
_c = _b.address;
street = _c[0];
city = _c[1];
;alert(poet + " — " + street);'>run: poet + " — " + street</button><br class='clear' /></div>
;alert(name + " — " + street);'>run: name + " — " + street</button><br class='clear' /></div>
<p>
Pattern matching can even be combined with splats.
</p>
@ -1473,7 +1484,7 @@ close = _a[_a.length - 1];
<span class="Keyword">return</span> func.<span class="LibraryFunction">apply</span>(obj <span class="Keyword">||</span> {}, args ? args.<span class="LibraryFunction">concat</span>(__slice.<span class="LibraryFunction">call</span>(arguments, <span class="Number">0</span>)) : arguments);
};
};
Account <span class="Keyword">=</span> <span class="Storage">function</span> <span class="FunctionName">Account</span>(<span class="FunctionArgument">customer, cart</span>) {
<span class="FunctionName">Account</span> = <span class="Storage">function</span>(<span class="FunctionArgument">customer, cart</span>) {
<span class="Variable">this</span>.customer <span class="Keyword">=</span> customer;
<span class="Variable">this</span>.cart <span class="Keyword">=</span> cart;
<span class="Keyword">return</span> <span class="Keyword">$</span>(<span class="String"><span class="String">'</span>.shopping_cart<span class="String">'</span></span>).bind(<span class="String"><span class="String">'</span>click<span class="String">'</span></span>, __bind(<span class="Storage">function</span>(<span class="LibraryClassType">event</span>) {
@ -1806,6 +1817,11 @@ html <span class="Keyword">=</span> <span class="String"><span class="String">'<
IRC client of your choice, or on
<a href="http://webchat.freenode.net/">webchat.freenode.net</a>.
</li>
<li>
<b>yeungda</b>'s <a href="http://github.com/yeungda/jcoffeescript">JCoffeeScript</a>
&mdash; A Java Library that uses Rhino to compile CoffeeScript, allowing
compilation within Java projects or on systems that Node.js doesn't support.
</li>
<li>
<b>defunkt</b>'s <a href="http://github.com/defunkt/coffee-mode">CoffeeScript Major Mode</a>
&mdash; a Emacs major mode that provides syntax highlighting, indentation
@ -1834,6 +1850,11 @@ html <span class="Keyword">=</span> <span class="String"><span class="String">'<
&mdash; a plugin that serves and bundles CoffeeScript from within your
Rails application.
</li>
<li>
<b>sutto</b>'s <a href="http://github.com/Sutto/barista">Barista</a>
&mdash; a BistroCar alternative that integrates well with
<a href="http://documentcloud.github.com/jammit">Jammit</a> and Rails 3.
</li>
<li>
<b>inem</b> and <b>gerad</b>'s <a href="http://github.com/gerad/coffee-haml-filter">coffee-haml-filter</a>
&mdash; a custom filter for rendering CoffeeScript inline within
@ -1860,7 +1881,22 @@ html <span class="Keyword">=</span> <span class="String"><span class="String">'<
<span id="change_log" class="bookmark"></span>
Change Log
</h2>
<p>
<b class="header" style="margin-top: 20px;">0.6.2</b>
The <tt>coffee</tt> command will now preserve directory structure when
compiling a directory full of scripts. Fixed two omissions that were preventing
the CoffeeScript compiler from running live within Internet Explorer.
There's now a syntax for block comments, similar in spirit to CoffeeScript's heredocs.
ECMA Harmony DRY-style pattern matching is now supported, where the name
of the property is the same as the name of the value: <tt>{name, length}: func</tt>.
Pattern matching is now allowed within comprehension variables. <tt>unless</tt>
is now allowed in block form. <tt>until</tt> loops were added, as the inverse
of <tt>while</tt> loops. <tt>switch</tt> statements are now allowed without
switch object clauses. Compatible
with Node.js <b>v0.1.95</b>.
</p>
<p>
<b class="header" style="margin-top: 20px;">0.6.1</b>
Upgraded CoffeeScript for compatibility with the new Node.js <b>v0.1.90</b>

View file

@ -23,7 +23,7 @@
helpers = this.helpers;
}
// The current CoffeeScript version number.
exports.VERSION = '0.6.1';
exports.VERSION = '0.6.2';
// Instantiate a Lexer for our use here.
lexer = new Lexer();
// Compile a string of CoffeeScript code to JavaScript, using the Coffee/Jison

View file

@ -422,9 +422,9 @@
// Sanitize a heredoc or herecomment by escaping internal double quotes and
// erasing all external indentation on the left-hand side.
Lexer.prototype.sanitize_heredoc = function(doc, options) {
var attempt, indent, match;
var _d, attempt, indent, match;
while (match = HEREDOC_INDENT.exec(doc)) {
attempt = match[2] || match[3];
attempt = (typeof (_d = match[2]) !== "undefined" && _d !== null) ? match[2] : match[3];
if (!indent || attempt.length < indent.length) {
indent = attempt;
}

View file

@ -1256,6 +1256,9 @@
exports.WhileNode = (function() {
WhileNode = function(condition, opts) {
if (opts && opts.invert) {
if (condition instanceof OpNode) {
condition = new ParentheticalNode(condition);
}
condition = new OpNode('!', condition);
}
this.condition = condition;

View file

@ -3,5 +3,5 @@
"description": "Unfancy JavaScript",
"keywords": ["javascript", "language"],
"author": "Jeremy Ashkenas",
"version": "0.6.1"
"version": "0.6.2"
}

View file

@ -22,7 +22,7 @@ else
helpers: this.helpers
# The current CoffeeScript version number.
exports.VERSION: '0.6.1'
exports.VERSION: '0.6.2'
# Instantiate a Lexer for our use here.
lexer: new Lexer()

View file

@ -295,7 +295,7 @@ exports.Lexer: class Lexer
# erasing all external indentation on the left-hand side.
sanitize_heredoc: (doc, options) ->
while match: HEREDOC_INDENT.exec doc
attempt: match[2] or match[3]
attempt: if match[2]? then match[2] else match[3]
indent: attempt if not indent or attempt.length < indent.length
doc: doc.replace(new RegExp("^" +indent, 'gm'), '')
return doc if options.herecomment

View file

@ -920,7 +920,9 @@ children SplatNode, 'name'
exports.WhileNode: class WhileNode extends BaseNode
constructor: (condition, opts) ->
condition: new OpNode('!', condition) if opts and opts.invert
if opts and opts.invert
condition: new ParentheticalNode condition if condition instanceof OpNode
condition: new OpNode('!', condition)
@condition: condition
@guard: opts and opts.guard