Compare commits

..

33 Commits
0.7.0 ... 0.7.1

Author SHA1 Message Date
Jeremy Ashkenas
e40d25e4bd rebuilding docs and compressed version for CoffeeScript 0.7.1 2010-07-11 10:40:44 -04:00
Jeremy Ashkenas
2a7a26482a fixing optparse to behave nicely in the presence of hashbangs -- stop parsing after the first non-option argument, and pass the rest along -- and adding an OptionParser test. 2010-07-11 09:57:42 -04:00
Jeremy Ashkenas
3d6cdfa636 making it possible to pass in command-line arguments to a hash-banged coffee script. Ticket #473 2010-07-10 15:36:54 -04:00
Jeremy Ashkenas
15a2b7d69a Fixing issue number #486 (which is debatable). Allowing an unparenthesized if/else ternary as a trailing parameter to a call. 2010-07-10 14:52:54 -04:00
Jeremy Ashkenas
9ff8433f21 fixing previously-escaped-inner-quotes-in-double-quoted-heredoc-interpolations. Issue #479 2010-07-10 11:54:59 -04:00
Jeremy Ashkenas
1c7d51a2c4 fixing issue #485, unary minus following an existential operator. 2010-07-10 11:27:43 -04:00
Jeremy Ashkenas
49020208f9 better printing for OpNodes with running with --nodes 2010-07-10 11:17:44 -04:00
Jeremy Ashkenas
6f32fe27f8 better formatting for top-level closured-values. 2010-07-10 09:49:01 -04:00
Jeremy Ashkenas
7a16db9ad3 fixing inline-loop object-in-array tests for instance variables. Issue #481 2010-07-10 09:01:22 -04:00
Jeremy Ashkenas
2f8a29b5a0 fixing a comment/block-comment combination lexing regex issue. Ticket #478 2010-07-10 08:44:30 -04:00
Jeremy Ashkenas
64b5ccc524 Fixes issue #477, missing global helpers in REPL. 2010-07-09 01:01:31 -04:00
Jeremy Ashkenas
4fc4edc7a0 adding wavded's gedit-coffeescript to the resources section of the docs 2010-07-08 10:18:18 -04:00
Jeremy Ashkenas
358edfb21f fixing return node squashing the possiblity of a ternary, when there should be one. Issue #475 2010-07-06 23:04:35 -04:00
Jeremy Ashkenas
577daf5457 fixing herecomment/indentation bugaboo ... issue #474 2010-07-06 22:20:42 -04:00
Jeremy Ashkenas
afa3bb4191 added dsc's coffeecup to the resources section. 2010-07-05 08:51:45 -04:00
Jeremy Ashkenas
e81810d845 fixing issue #427 -- incorrect stringification of reserved word 2010-07-04 20:55:21 -04:00
Jeremy Ashkenas
c57ebffe6f fixing Lexer::OPERATOR regex for non-spaced + unary arithmetic. Issue #471 2010-07-04 13:29:22 -04:00
Jeremy Ashkenas
e281133f12 fixing empty catch clauses ... Issue #470 2010-07-04 12:50:04 -04:00
Jeremy Ashkenas
92878558c6 fixing improper formatting in range-to-array expansion. 2010-07-03 17:00:30 -04:00
Jeremy Ashkenas
ec449158c6 fixing improperly-formatted-output of pattern matching within comprehension arguments. 2010-07-03 15:09:21 -04:00
Jeremy Ashkenas
eefa004b8f fixing the block comment test to use defined variables. 2010-07-01 21:51:28 -04:00
Jeremy Ashkenas
77a75ed365 adding passed-through block comments back to the grammar/lexer/rewriter/nodes ... thanks, Trevor Burnham. 2010-07-01 21:26:33 -04:00
Jeremy Ashkenas
364ec2a694 better syntax errors for tokens-not-in-the-grammar. Coming soon to a Jison near you (hopefully) 2010-07-01 20:40:08 -04:00
Jeremy Ashkenas
9a8a707016 throw a syntax error if you try to use the fat arrow to define a class constructor. 2010-06-30 22:03:20 -04:00
Jeremy Ashkenas
7a5f014014 fixing closurenode wrapping of bodies with bound function declarations inside -- this doesn't have to be mentioned explicitly. 2010-06-30 21:54:16 -04:00
Jeremy Ashkenas
5ca5a504a4 allowing empty bodies in try blocks and in catch blocks 2010-06-30 20:53:09 -04:00
Jeremy Ashkenas
cb45c8feac fixing html entity in the changelog 2010-06-30 19:51:49 -04:00
Jeremy Ashkenas
7d79d73b58 allowing paren-less instance creation, a la 'new Class' 2010-06-29 21:03:50 -04:00
Jeremy Ashkenas
7c426db36a fixing range literals (which had gone untested) oops. 2010-06-28 20:26:31 -04:00
Jeremy Ashkenas
744638ed08 adding a one-line exception test. 2010-06-28 08:52:13 -04:00
Jeremy Ashkenas
9bc7cd7904 adding a one-line exception test. 2010-06-28 08:50:44 -04:00
Jeremy Ashkenas
d83bbfb1d5 updating readme with NPM install. 2010-06-28 01:19:04 -04:00
Jeremy Ashkenas
4ad9e82f50 docs for the NPM install 2010-06-28 01:06:53 -04:00
47 changed files with 1138 additions and 709 deletions

View File

@@ -94,14 +94,14 @@ task 'loc', 'count the lines of source code in CoffeeScript', ->
task 'test', 'run the CoffeeScript language test suite', ->
helpers.extend global, require 'assert'
passedTests: failedTests: 0
startTime: new Date()
startTime: new Date
originalOk: ok
helpers.extend global, {
ok: (args...) -> passedTests += 1; originalOk(args...)
CoffeeScript: CoffeeScript
}
process.addListener 'exit', ->
time: ((new Date() - startTime) / 1000).toFixed(2)
time: ((new Date - startTime) / 1000).toFixed(2)
message: "passed $passedTests tests in $time seconds$reset"
if failedTests
log "failed $failedTests and $message", red

3
README
View File

@@ -25,6 +25,9 @@
Install Node.js, and then the CoffeeScript compiler:
sudo bin/cake install
Or, if you have the Node Package Manager installed:
sudo npm install coffee-script
Compile a script:
coffee /path/to/script.coffee

View File

@@ -6,7 +6,7 @@ require 'yui/compressor'
HEADER = <<-EOS
/**
* CoffeeScript Compiler v0.7.0
* CoffeeScript Compiler v0.7.1
* http://coffeescript.org
*
* Copyright 2010, Jeremy Ashkenas

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.7.0&#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.7.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></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

@@ -34,14 +34,17 @@ Many flags cause us to divert before compiling anything. Flags passed after
<span class="k">return</span> <span class="nx">usage</span><span class="p">()</span> <span class="k">if</span> <span class="nx">options</span><span class="p">.</span><span class="nx">help</span>
<span class="k">return</span> <span class="nx">version</span><span class="p">()</span> <span class="k">if</span> <span class="nx">options</span><span class="p">.</span><span class="nx">version</span>
<span class="k">return</span> <span class="nx">require</span> <span class="s1">&#39;./repl&#39;</span> <span class="k">if</span> <span class="nx">options</span><span class="p">.</span><span class="nx">interactive</span>
<span class="k">return</span> <span class="nx">compileStdio</span><span class="p">()</span> <span class="k">if</span> <span class="nx">options</span><span class="p">.</span><span class="nx">stdio</span>
<span class="k">return</span> <span class="nx">compileScript</span> <span class="s1">&#39;console&#39;</span><span class="p">,</span> <span class="nx">sources</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">if</span> <span class="nx">options</span><span class="p">.</span><span class="nb">eval</span>
<span class="k">return</span> <span class="nx">compileStdio</span><span class="p">()</span> <span class="k">if</span> <span class="nx">options</span><span class="p">.</span><span class="nx">stdio</span>
<span class="k">return</span> <span class="nx">compileScript</span> <span class="s1">&#39;console&#39;</span><span class="p">,</span> <span class="nx">sources</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">if</span> <span class="nx">options</span><span class="p">.</span><span class="nb">eval</span>
<span class="k">return</span> <span class="nx">require</span> <span class="s1">&#39;./repl&#39;</span> <span class="nx">unless</span> <span class="nx">sources</span><span class="p">.</span><span class="nx">length</span>
<span class="nv">separator: </span><span class="nx">sources</span><span class="p">.</span><span class="nx">indexOf</span> <span class="s1">&#39;--&#39;</span>
<span class="nv">flags: </span><span class="p">[]</span>
<span class="k">if</span> <span class="nx">separator</span> <span class="o">&gt;=</span> <span class="mi">0</span>
<span class="nv">flags: </span><span class="nx">sources</span><span class="p">[(</span><span class="nx">separator</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)...</span><span class="nx">sources</span><span class="p">.</span><span class="nx">length</span><span class="p">]</span>
<span class="nv">flags: </span> <span class="nx">sources</span><span class="p">[(</span><span class="nx">separator</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)...</span><span class="nx">sources</span><span class="p">.</span><span class="nx">length</span><span class="p">]</span>
<span class="nv">sources: </span><span class="nx">sources</span><span class="p">[</span><span class="mi">0</span><span class="p">...</span><span class="nx">separator</span><span class="p">]</span>
<span class="k">if</span> <span class="nx">options</span><span class="p">.</span><span class="nx">run</span>
<span class="nv">flags: </span> <span class="nx">sources</span><span class="p">[</span><span class="mi">1</span><span class="p">..</span><span class="nx">sources</span><span class="p">.</span><span class="nx">length</span><span class="p">].</span><span class="nx">concat</span> <span class="nx">flags</span>
<span class="nv">sources: </span><span class="p">[</span><span class="nx">sources</span><span class="p">[</span><span class="mi">0</span><span class="p">]]</span>
<span class="nv">process.ARGV: process.argv: </span><span class="nx">flags</span>
<span class="nx">compileScripts</span><span class="p">()</span></pre></div> </td> </tr> <tr id="section-7"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-7">#</a> </div> <p>Asynchronously read in each CoffeeScript in a list of source files and
compile them. If a directory is passed, recursively compile all
@@ -112,11 +115,11 @@ any errors or warnings that arise.</p> </td> <td class="
<span class="s2">&quot;[$tag $value]&quot;</span>
<span class="nx">puts</span> <span class="nx">strings</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-14"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-14">#</a> </div> <p>Use the <a href="optparse.html">OptionParser module</a> to extract all options from
<code>process.argv</code> that are specified in <code>SWITCHES</code>.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">parseOptions: </span><span class="o">-&gt;</span>
<span class="nv">optionParser: </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="p">,</span> <span class="nx">BANNER</span>
<span class="nv">o: options: </span> <span class="nx">optionParser</span><span class="p">.</span><span class="nx">parse</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="nv">optionParser: </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="p">,</span> <span class="nx">BANNER</span>
<span class="nv">o: options: </span> <span class="nx">optionParser</span><span class="p">.</span><span class="nx">parse</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="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="nv">options.run: </span> <span class="o">not</span> <span class="p">(</span><span class="nx">o</span><span class="p">.</span><span class="nx">compile</span> <span class="o">or</span> <span class="nx">o</span><span class="p">.</span><span class="nx">print</span> <span class="o">or</span> <span class="nx">o</span><span class="p">.</span><span class="nx">lint</span><span class="p">)</span>
<span class="nv">options.print: </span><span class="o">!!</span> <span class="p">(</span><span class="nx">o</span><span class="p">.</span><span class="nx">print</span> <span class="o">or</span> <span class="p">(</span><span class="nx">o</span><span class="p">.</span><span class="nb">eval</span> <span class="o">or</span> <span class="nx">o</span><span class="p">.</span><span class="nx">stdio</span> <span class="o">and</span> <span class="nx">o</span><span class="p">.</span><span class="nx">compile</span><span class="p">))</span>
<span class="nv">sources: </span> <span class="nx">options</span><span class="p">.</span><span class="nx">arguments</span><span class="p">[</span><span class="mi">2</span><span class="p">...</span><span class="nx">options</span><span class="p">.</span><span class="nx">arguments</span><span class="p">.</span><span class="nx">length</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>The compile-time options to pass to the CoffeeScript compiler.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">compileOptions: </span><span class="p">(</span><span class="nx">source</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">sources: </span> <span class="nx">options</span><span class="p">.</span><span class="nx">arguments</span></pre></div> </td> </tr> <tr id="section-15"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-15">#</a> </div> <p>The compile-time options to pass to the CoffeeScript compiler.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">compileOptions: </span><span class="p">(</span><span class="nx">source</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">o: </span><span class="p">{</span><span class="nx">source</span><span class="p">}</span>
<span class="nv">o.noWrap: </span><span class="nx">options</span><span class="p">[</span><span class="s1">&#39;no-wrap&#39;</span><span class="p">]</span>
<span class="nx">o</span></pre></div> </td> </tr> <tr id="section-16"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-16">#</a> </div> <p>Print the <code>--help</code> usage message and exit.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">usage: </span><span class="o">-&gt;</span>

View File

@@ -33,8 +33,8 @@ their numeric position, so in this rule:</p>
for the <code>UNLESS</code> terminal, and <code>$3</code> would be the value of the second
<code>Expression</code>.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">grammar: </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>The <strong>Root</strong> is the top-level node in the syntax tree. Since we parse bottom-up,
all parsing must end here.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Root: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">Expressions</span><span class="p">()</span>
<span class="nx">o</span> <span class="s2">&quot;TERMINATOR&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">Expressions</span><span class="p">()</span>
<span class="nx">o</span> <span class="s2">&quot;&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">Expressions</span>
<span class="nx">o</span> <span class="s2">&quot;TERMINATOR&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">Expressions</span>
<span class="nx">o</span> <span class="s2">&quot;Body&quot;</span>
<span class="nx">o</span> <span class="s2">&quot;Block TERMINATOR&quot;</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-9"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-9">#</a> </div> <p>Any list of statements and expressions, seperated by line breaks or semicolons.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Body: </span><span class="p">[</span>
@@ -67,11 +67,13 @@ them somewhat circular.</p> </td> <td class="code">
<span class="nx">o</span> <span class="s2">&quot;Class&quot;</span>
<span class="nx">o</span> <span class="s2">&quot;Splat&quot;</span>
<span class="nx">o</span> <span class="s2">&quot;Existence&quot;</span>
<span class="nx">o</span> <span class="s2">&quot;Comment&quot;</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-13"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-13">#</a> </div> <p>A an indented block of expressions. Note that the <a href="rewriter.html">Rewriter</a>
will convert some postfix forms into blocks for us, by adjusting the
token stream.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Block: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;INDENT Body 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;INDENT OUTDENT&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">Expressions</span><span class="p">()</span>
<span class="nx">o</span> <span class="s2">&quot;INDENT OUTDENT&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">Expressions</span>
<span class="nx">o</span> <span class="s2">&quot;TERMINATOR Comment&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="nx">Expressions</span><span class="p">.</span><span class="nx">wrap</span> <span class="p">[</span><span class="nx">$2</span><span class="p">]</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-14"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-14">#</a> </div> <p>A literal identifier, a variable name or property.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Identifier: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;IDENTIFIER&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">LiteralNode</span> <span class="nx">$1</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>Alphanumerics are separated from the other <strong>Literal</strong> matchers because
@@ -97,43 +99,46 @@ the ordinary <strong>Assign</strong> is that these allow numbers and strings as
<span class="nx">o</span> <span class="s2">&quot;AlphaNumeric&quot;</span>
<span class="nx">o</span> <span class="s2">&quot;Identifier ASSIGN Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">AssignNode</span> <span class="k">new</span> <span class="nx">ValueNode</span><span class="p">(</span><span class="nx">$1</span><span class="p">),</span> <span class="nx">$3</span><span class="p">,</span> <span class="s1">&#39;object&#39;</span>
<span class="nx">o</span> <span class="s2">&quot;AlphaNumeric ASSIGN Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">AssignNode</span> <span class="k">new</span> <span class="nx">ValueNode</span><span class="p">(</span><span class="nx">$1</span><span class="p">),</span> <span class="nx">$3</span><span class="p">,</span> <span class="s1">&#39;object&#39;</span>
<span class="nx">o</span> <span class="s2">&quot;Comment&quot;</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-19"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-19">#</a> </div> <p>A return statement from a function body.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Return: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;RETURN Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">ReturnNode</span> <span class="nx">$2</span>
<span class="nx">o</span> <span class="s2">&quot;RETURN&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">ReturnNode</span> <span class="k">new</span> <span class="nx">ValueNode</span> <span class="k">new</span> <span class="nx">LiteralNode</span> <span class="s1">&#39;null&#39;</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><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="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>A block comment.</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;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></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-21"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-21">#</a> </div> <p>The <strong>Code</strong> node is the function literal. It's defined by an indented block
<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
of <strong>Expressions</strong> preceded by a function arrow, with an optional parameter
list.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Code: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;PARAM_START ParamList PARAM_END FuncGlyph Block&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">CodeNode</span> <span class="nx">$2</span><span class="p">,</span> <span class="nx">$5</span><span class="p">,</span> <span class="nx">$4</span>
<span class="nx">o</span> <span class="s2">&quot;FuncGlyph Block&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">CodeNode</span> <span class="p">[],</span> <span class="nx">$2</span><span class="p">,</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>CoffeeScript has two different symbols for functions. <code>-&gt;</code> is for ordinary
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-23"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-23">#</a> </div> <p>CoffeeScript has two different symbols for functions. <code>-&gt;</code> is for ordinary
functions, and <code>=&gt;</code> is for functions bound to the current value of <em>this</em>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">FuncGlyph: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;-&gt;&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="s1">&#39;func&#39;</span>
<span class="nx">o</span> <span class="s2">&quot;=&gt;&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="s1">&#39;boundfunc&#39;</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-23"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-23">#</a> </div> <p>An optional, trailing comma.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">OptComma: </span><span class="p">[</span>
<span class="p">]</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 optional, trailing comma.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">OptComma: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s1">&#39;&#39;</span>
<span class="nx">o</span> <span class="s1">&#39;,&#39;</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-24"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-24">#</a> </div> <p>The list of parameters that a function accepts can be of any length.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">ParamList: </span><span class="p">[</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>The list of parameters that a function accepts can be of any length.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">ParamList: </span><span class="p">[</span>
<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;Param&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;ParamList , Param&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="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>A single parameter in a function definition can be ordinary, or a splat
<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>A single parameter in a function definition can be ordinary, or a splat
that hoovers up the remaining arguments.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Param: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;PARAM&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">LiteralNode</span> <span class="nx">$1</span>
<span class="nx">o</span> <span class="s2">&quot;Param . . .&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">SplatNode</span> <span class="nx">$1</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>A splat that occurs outside of a parameter list.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Splat: </span><span class="p">[</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>A splat that occurs outside of a parameter list.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Splat: </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">SplatNode</span> <span class="nx">$1</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>Variables and properties that can be assigned to.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">SimpleAssignable: </span><span class="p">[</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-28"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-28">#</a> </div> <p>Variables and properties that can be assigned to.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">SimpleAssignable: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;Identifier&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">ValueNode</span> <span class="nx">$1</span>
<span class="nx">o</span> <span class="s2">&quot;Value Accessor&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="nx">$1</span><span class="p">.</span><span class="nx">push</span> <span class="nx">$2</span>
<span class="nx">o</span> <span class="s2">&quot;Invocation Accessor&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">ValueNode</span> <span class="nx">$1</span><span class="p">,</span> <span class="p">[</span><span class="nx">$2</span><span class="p">]</span>
<span class="nx">o</span> <span class="s2">&quot;ThisProperty&quot;</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-28"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-28">#</a> </div> <p>Everything that can be assigned to.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Assignable: </span><span class="p">[</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-29"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-29">#</a> </div> <p>Everything that can be assigned to.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Assignable: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;SimpleAssignable&quot;</span>
<span class="nx">o</span> <span class="s2">&quot;Array&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">ValueNode</span> <span class="nx">$1</span>
<span class="nx">o</span> <span class="s2">&quot;Object&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">ValueNode</span> <span class="nx">$1</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-29"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-29">#</a> </div> <p>The types of things that can be treated as values -- assigned to, invoked
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-30"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-30">#</a> </div> <p>The types of things that can be treated as values -- assigned to, invoked
as functions, indexed into, named as a class, etc.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Value: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;Assignable&quot;</span>
<span class="nx">o</span> <span class="s2">&quot;Literal&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">ValueNode</span> <span class="nx">$1</span>
@@ -141,7 +146,7 @@ as functions, indexed into, named as a class, etc.</p> </td>
<span class="nx">o</span> <span class="s2">&quot;Range&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">ValueNode</span> <span class="nx">$1</span>
<span class="nx">o</span> <span class="s2">&quot;This&quot;</span>
<span class="nx">o</span> <span class="s2">&quot;NULL&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">ValueNode</span> <span class="k">new</span> <span class="nx">LiteralNode</span> <span class="s1">&#39;null&#39;</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-30"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-30">#</a> </div> <p>The general group of accessors into an object, by property, by prototype
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-31"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-31">#</a> </div> <p>The general group of accessors into an object, by property, by prototype
or by array index or slice.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Accessor: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;PROPERTY_ACCESS Identifier&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">AccessorNode</span> <span class="nx">$2</span>
<span class="nx">o</span> <span class="s2">&quot;PROTOTYPE_ACCESS Identifier&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">AccessorNode</span> <span class="nx">$2</span><span class="p">,</span> <span class="s1">&#39;prototype&#39;</span>
@@ -149,61 +154,62 @@ or by array index or slice.</p> </td> <td class="code">
<span class="nx">o</span> <span class="s2">&quot;SOAK_ACCESS Identifier&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">AccessorNode</span> <span class="nx">$2</span><span class="p">,</span> <span class="s1">&#39;soak&#39;</span>
<span class="nx">o</span> <span class="s2">&quot;Index&quot;</span>
<span class="nx">o</span> <span class="s2">&quot;Slice&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">SliceNode</span> <span class="nx">$1</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-31"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-31">#</a> </div> <p>Indexing into an object or array using bracket notation.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Index: </span><span class="p">[</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-32"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-32">#</a> </div> <p>Indexing into an object or array using bracket notation.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Index: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;INDEX_START Expression INDEX_END&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">IndexNode</span> <span class="nx">$2</span>
<span class="nx">o</span> <span class="s2">&quot;INDEX_SOAK Index&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="nv">$2.soakNode: </span><span class="kc">yes</span><span class="p">;</span> <span class="nx">$2</span>
<span class="nx">o</span> <span class="s2">&quot;INDEX_PROTO Index&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="nv">$2.proto: </span><span class="kc">yes</span><span class="p">;</span> <span class="nx">$2</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-32"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-32">#</a> </div> <p>In CoffeeScript, an object literal is simply a list of assignments.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nb">Object</span><span class="o">:</span> <span class="p">[</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-33"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-33">#</a> </div> <p>In CoffeeScript, an object literal is simply a list of assignments.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nb">Object</span><span class="o">:</span> <span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;{ AssignList OptComma }&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">ObjectNode</span> <span class="nx">$2</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-33"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-33">#</a> </div> <p>Assignment of properties within an object literal can be separated by
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-34"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-34">#</a> </div> <p>Assignment of properties within an object literal can be separated by
comma, as in JavaScript, or simply by newline.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">AssignList: </span><span class="p">[</span>
<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 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-34"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-34">#</a> </div> <p>Class definitions have optional bodies of prototype property assignments,
<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>
<span class="nx">o</span> <span class="s2">&quot;CLASS SimpleAssignable EXTENDS Value&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><span class="p">,</span> <span class="nx">$4</span>
<span class="nx">o</span> <span class="s2">&quot;CLASS SimpleAssignable INDENT ClassBody OUTDENT&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><span class="p">,</span> <span class="kc">null</span><span class="p">,</span> <span class="nx">$4</span>
<span class="nx">o</span> <span class="s2">&quot;CLASS SimpleAssignable EXTENDS Value INDENT ClassBody OUTDENT&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><span class="p">,</span> <span class="nx">$4</span><span class="p">,</span> <span class="nx">$6</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>Assignments that can happen directly inside a class declaration.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">ClassAssign: </span><span class="p">[</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-36"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-36">#</a> </div> <p>Assignments that can happen directly inside a class declaration.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">ClassAssign: </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="nx">$1</span>
<span class="nx">o</span> <span class="s2">&quot;ThisProperty ASSIGN Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">AssignNode</span> <span class="k">new</span> <span class="nx">ValueNode</span><span class="p">(</span><span class="nx">$1</span><span class="p">),</span> <span class="nx">$3</span><span class="p">,</span> <span class="s1">&#39;this&#39;</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-36"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-36">#</a> </div> <p>A list of assignments to a class.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">ClassBody: </span><span class="p">[</span>
<span class="p">]</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 list of assignments to a class.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">ClassBody: </span><span class="p">[</span>
<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;ClassAssign&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;ClassBody TERMINATOR ClassAssign&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">$3</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-37"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-37">#</a> </div> <p>The three flavors of function call: normal, object instantiation with <code>new</code>,
<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>The three flavors of function call: normal, object instantiation with <code>new</code>,
and calling <code>super()</code></p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Call: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;Invocation&quot;</span>
<span class="nx">o</span> <span class="s2">&quot;NEW Invocation&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="nx">$2</span><span class="p">.</span><span class="nx">newInstance</span><span class="p">()</span>
<span class="nx">o</span> <span class="s2">&quot;Super&quot;</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>Extending an object by setting its prototype chain to reference a parent
<span class="nx">o</span> <span class="s2">&quot;NEW Invocation&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="nx">$2</span><span class="p">.</span><span class="nx">newInstance</span><span class="p">()</span>
<span class="nx">o</span> <span class="s2">&quot;NEW Value&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="p">(</span><span class="k">new</span> <span class="nx">CallNode</span><span class="p">(</span><span class="nx">$2</span><span class="p">,</span> <span class="p">[])).</span><span class="nx">newInstance</span><span class="p">()</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>Extending an object by setting its prototype chain to reference a parent
object.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Extends: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;SimpleAssignable EXTENDS Value&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">ExtendsNode</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$3</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>Ordinary function invocation, or a chained series of calls.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Invocation: </span><span class="p">[</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>Ordinary function invocation, or a chained series of calls.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Invocation: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;Value Arguments&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">CallNode</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$2</span>
<span class="nx">o</span> <span class="s2">&quot;Invocation Arguments&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">CallNode</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$2</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 list of arguments to a function call.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Arguments: </span><span class="p">[</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 list of arguments to a function call.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Arguments: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;CALL_START ArgList OptComma CALL_END&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="nx">$2</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>Calling super.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Super: </span><span class="p">[</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>Calling super.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Super: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;SUPER Arguments&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">CallNode</span> <span class="s1">&#39;super&#39;</span><span class="p">,</span> <span class="nx">$2</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>A reference to the <em>this</em> current object.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">This: </span><span class="p">[</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>A reference to the <em>this</em> current object.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">This: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;THIS&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">ValueNode</span> <span class="k">new</span> <span class="nx">LiteralNode</span> <span class="s1">&#39;this&#39;</span>
<span class="nx">o</span> <span class="s2">&quot;@&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">ValueNode</span> <span class="k">new</span> <span class="nx">LiteralNode</span> <span class="s1">&#39;this&#39;</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>A reference to a property on <em>this</em>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">ThisProperty: </span><span class="p">[</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-44"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-44">#</a> </div> <p>A reference to a property on <em>this</em>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">ThisProperty: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;@ Identifier&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">ValueNode</span> <span class="k">new</span> <span class="nx">LiteralNode</span><span class="p">(</span><span class="s1">&#39;this&#39;</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">$2</span><span class="p">)]</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-44"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-44">#</a> </div> <p>The CoffeeScript range literal.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Range: </span><span class="p">[</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-45"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-45">#</a> </div> <p>The CoffeeScript range literal.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Range: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;[ Expression . . Expression ]&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">RangeNode</span> <span class="nx">$2</span><span class="p">,</span> <span class="nx">$5</span>
<span class="nx">o</span> <span class="s2">&quot;[ Expression . . . Expression ]&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">RangeNode</span> <span class="nx">$2</span><span class="p">,</span> <span class="nx">$6</span><span class="p">,</span> <span class="kc">true</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-45"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-45">#</a> </div> <p>The slice literal.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Slice: </span><span class="p">[</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-46"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-46">#</a> </div> <p>The slice literal.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Slice: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;INDEX_START Expression . . Expression INDEX_END&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">RangeNode</span> <span class="nx">$2</span><span class="p">,</span> <span class="nx">$5</span>
<span class="nx">o</span> <span class="s2">&quot;INDEX_START Expression . . . Expression INDEX_END&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">RangeNode</span> <span class="nx">$2</span><span class="p">,</span> <span class="nx">$6</span><span class="p">,</span> <span class="kc">true</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-46"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-46">#</a> </div> <p>The array literal.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nb">Array</span><span class="o">:</span> <span class="p">[</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-47"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-47">#</a> </div> <p>The array literal.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nb">Array</span><span class="o">:</span> <span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;[ ArgList OptComma ]&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">ArrayNode</span> <span class="nx">$2</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-47"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-47">#</a> </div> <p>The <strong>ArgList</strong> is both the list of objects passed into a function call,
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-48"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-48">#</a> </div> <p>The <strong>ArgList</strong> is both the list of objects passed into a function call,
as well as the contents of an array literal
(i.e. comma-separated expressions). Newlines work as well.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">ArgList: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="p">[]</span>
@@ -211,31 +217,31 @@ as well as the contents of an array literal
<span class="nx">o</span> <span class="s2">&quot;ArgList , Expression&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;ArgList OptComma TERMINATOR Expression&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;ArgList OptComma INDENT ArgList 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-48"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-48">#</a> </div> <p>Just simple, comma-separated, required arguments (no fancy syntax). We need
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-49"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-49">#</a> </div> <p>Just simple, comma-separated, required arguments (no fancy syntax). We need
this to be separate from the <strong>ArgList</strong> for use in <strong>Switch</strong> blocks, where
having the newlines wouldn't make sense.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">SimpleArgs: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;Expression&quot;</span>
<span class="nx">o</span> <span class="s2">&quot;SimpleArgs , Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span>
<span class="k">if</span> <span class="nx">$1</span> <span class="k">instanceof</span> <span class="nb">Array</span> <span class="k">then</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="k">else</span> <span class="p">[</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="p">]</span></pre></div> </td> </tr> <tr id="section-49"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-49">#</a> </div> <p>The variants of <em>try/catch/finally</em> exception handling blocks.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Try: </span><span class="p">[</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-50"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-50">#</a> </div> <p>The variants of <em>try/catch/finally</em> exception handling blocks.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Try: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;TRY Block Catch&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">TryNode</span> <span class="nx">$2</span><span class="p">,</span> <span class="nx">$3</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="nx">$3</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
<span class="nx">o</span> <span class="s2">&quot;TRY Block FINALLY Block&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">TryNode</span> <span class="nx">$2</span><span class="p">,</span> <span class="kc">null</span><span class="p">,</span> <span class="kc">null</span><span class="p">,</span> <span class="nx">$4</span>
<span class="nx">o</span> <span class="s2">&quot;TRY Block Catch FINALLY Block&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">TryNode</span> <span class="nx">$2</span><span class="p">,</span> <span class="nx">$3</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="nx">$3</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="nx">$5</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-50"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-50">#</a> </div> <p>A catch clause names its error and runs a block of code.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Catch: </span><span class="p">[</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-51"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-51">#</a> </div> <p>A catch clause names its error and runs a block of code.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Catch: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;CATCH Identifier Block&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="p">[</span><span class="nx">$2</span><span class="p">,</span> <span class="nx">$3</span><span class="p">]</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-51"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-51">#</a> </div> <p>Throw an exception object.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Throw: </span><span class="p">[</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>Throw an exception object.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Throw: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;THROW Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">ThrowNode</span> <span class="nx">$2</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>Parenthetical expressions. Note that the <strong>Parenthetical</strong> is a <strong>Value</strong>,
<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>Parenthetical expressions. Note that the <strong>Parenthetical</strong> is a <strong>Value</strong>,
not an <strong>Expression</strong>, so if you need to use an expression in a place
where only values are accepted, wrapping it in parentheses will always do
the trick.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Parenthetical: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;( Line )&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">ParentheticalNode</span> <span class="nx">$2</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>The condition portion of a while loop.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">WhileSource: </span><span class="p">[</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-54"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-54">#</a> </div> <p>The condition portion of a while loop.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">WhileSource: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;WHILE Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">WhileNode</span> <span class="nx">$2</span>
<span class="nx">o</span> <span class="s2">&quot;WHILE Expression WHEN Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">WhileNode</span> <span class="nx">$2</span><span class="p">,</span> <span class="p">{</span><span class="nv">guard : </span><span class="nx">$4</span><span class="p">}</span>
<span class="nx">o</span> <span class="s2">&quot;UNTIL Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">WhileNode</span> <span class="nx">$2</span><span class="p">,</span> <span class="p">{</span><span class="nv">invert: </span><span class="kc">true</span><span class="p">}</span>
<span class="nx">o</span> <span class="s2">&quot;UNTIL Expression WHEN Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">WhileNode</span> <span class="nx">$2</span><span class="p">,</span> <span class="p">{</span><span class="nv">invert: </span><span class="kc">true</span><span class="p">,</span> <span class="nv">guard: </span><span class="nx">$4</span><span class="p">}</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-54"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-54">#</a> </div> <p>The while loop can either be normal, with a block of expressions to execute,
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-55"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-55">#</a> </div> <p>The while loop can either be normal, with a block of expressions to execute,
or postfix, with a single expression. There is no do..while.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">While: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;WhileSource Block&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="nx">$1</span><span class="p">.</span><span class="nx">addBody</span> <span class="nx">$2</span>
<span class="nx">o</span> <span class="s2">&quot;Statement WhileSource&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="nx">$2</span><span class="p">.</span><span class="nx">addBody</span> <span class="nx">Expressions</span><span class="p">.</span><span class="nx">wrap</span> <span class="p">[</span><span class="nx">$1</span><span class="p">]</span>
@@ -246,23 +252,23 @@ or postfix, with a single expression. There is no do..while.</p> </t
<span class="nv">Loop: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;LOOP Block&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">WhileNode</span><span class="p">(</span><span class="k">new</span> <span class="nx">LiteralNode</span> <span class="s1">&#39;true&#39;</span><span class="p">).</span><span class="nx">addBody</span> <span class="nx">$2</span>
<span class="nx">o</span> <span class="s2">&quot;LOOP Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">WhileNode</span><span class="p">(</span><span class="k">new</span> <span class="nx">LiteralNode</span> <span class="s1">&#39;true&#39;</span><span class="p">).</span><span class="nx">addBody</span> <span class="nx">Expressions</span><span class="p">.</span><span class="nx">wrap</span> <span class="p">[</span><span class="nx">$2</span><span class="p">]</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-55"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-55">#</a> </div> <p>Array, object, and range comprehensions, at the most generic level.
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-56"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-56">#</a> </div> <p>Array, object, and range comprehensions, at the most generic level.
Comprehensions can either be normal, with a block of expressions to execute,
or postfix, with a single expression.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">For: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;Statement FOR ForVariables ForSource&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">ForNode</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$4</span><span class="p">,</span> <span class="nx">$3</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="nx">$3</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
<span class="nx">o</span> <span class="s2">&quot;Expression FOR ForVariables ForSource&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">ForNode</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$4</span><span class="p">,</span> <span class="nx">$3</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="nx">$3</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
<span class="nx">o</span> <span class="s2">&quot;FOR ForVariables ForSource Block&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">ForNode</span> <span class="nx">$4</span><span class="p">,</span> <span class="nx">$3</span><span class="p">,</span> <span class="nx">$2</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="nx">$2</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-56"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-56">#</a> </div> <p>An array of all accepted values for a variable inside the loop. This
<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>An array of all accepted values for a variable inside the loop. This
enables support for pattern matching.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">ForValue: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;Identifier&quot;</span>
<span class="nx">o</span> <span class="s2">&quot;Array&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">ValueNode</span> <span class="nx">$1</span>
<span class="nx">o</span> <span class="s2">&quot;Object&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">ValueNode</span> <span class="nx">$1</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>An array or range comprehension has variables for the current element and
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-58"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-58">#</a> </div> <p>An array or range comprehension has variables for the current element and
(optional) reference to the current index. Or, <em>key, value</em>, in the case
of object comprehensions.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">ForVariables: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;ForValue&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;ForValue , ForValue&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">$3</span><span class="p">]</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-58"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-58">#</a> </div> <p>The source of a comprehension is an array or object with an optional guard
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-59"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-59">#</a> </div> <p>The source of a comprehension is an array or object with an optional guard
clause. If it's an array comprehension, you can also choose to step through
in fixed-size increments.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">ForSource: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;IN Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="p">{</span><span class="nv">source: </span><span class="nx">$2</span><span class="p">}</span>
@@ -272,34 +278,34 @@ in fixed-size increments.</p> </td> <td class="code">
<span class="nx">o</span> <span class="s2">&quot;IN Expression BY Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="p">{</span><span class="nv">source: </span><span class="nx">$2</span><span class="p">,</span> <span class="nv">step: </span> <span class="nx">$4</span><span class="p">}</span>
<span class="nx">o</span> <span class="s2">&quot;IN Expression WHEN Expression BY Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="p">{</span><span class="nv">source: </span><span class="nx">$2</span><span class="p">,</span> <span class="nv">guard: </span><span class="nx">$4</span><span class="p">,</span> <span class="nv">step: </span> <span class="nx">$6</span><span class="p">}</span>
<span class="nx">o</span> <span class="s2">&quot;IN Expression BY Expression WHEN Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="p">{</span><span class="nv">source: </span><span class="nx">$2</span><span class="p">,</span> <span class="nv">step: </span> <span class="nx">$4</span><span class="p">,</span> <span class="nv">guard: </span><span class="nx">$6</span><span class="p">}</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-59"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-59">#</a> </div> <p>The CoffeeScript switch/when/else block replaces the JavaScript
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-60"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-60">#</a> </div> <p>The CoffeeScript switch/when/else block replaces the JavaScript
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">switchesOver</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">switchesOver</span><span class="p">(</span><span class="nx">$2</span><span class="p">).</span><span class="nx">addElse</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">addElse</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-60"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-60">#</a> </div> <p>The inner list of whens is left recursive. At code-generation time, the
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-61"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-61">#</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>
<span class="nx">o</span> <span class="s2">&quot;Whens When&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="nx">$1</span><span class="p">.</span><span class="nx">addElse</span> <span class="nx">$2</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-61"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-61">#</a> </div> <p>An individual <strong>When</strong> clause, with action.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">When: </span><span class="p">[</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-62"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-62">#</a> </div> <p>An individual <strong>When</strong> clause, with action.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">When: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;LEADING_WHEN SimpleArgs Block&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">IfNode</span> <span class="nx">$2</span><span class="p">,</span> <span class="nx">$3</span><span class="p">,</span> <span class="p">{</span><span class="nv">statement: </span><span class="kc">true</span><span class="p">}</span>
<span class="nx">o</span> <span class="s2">&quot;LEADING_WHEN SimpleArgs Block TERMINATOR&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">IfNode</span> <span class="nx">$2</span><span class="p">,</span> <span class="nx">$3</span><span class="p">,</span> <span class="p">{</span><span class="nv">statement: </span><span class="kc">true</span><span class="p">}</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-62"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-62">#</a> </div> <p>The most basic form of <em>if</em> is a condition and an action. The following
<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 most basic form of <em>if</em> is a condition and an action. The following
if-related rules are broken up along these lines in order to avoid
ambiguity.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">IfBlock: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;IF Expression Block&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">IfNode</span> <span class="nx">$2</span><span class="p">,</span> <span class="nx">$3</span>
<span class="nx">o</span> <span class="s2">&quot;UNLESS Expression Block&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">IfNode</span> <span class="nx">$2</span><span class="p">,</span> <span class="nx">$3</span><span class="p">,</span> <span class="p">{</span><span class="nv">invert: </span><span class="kc">true</span><span class="p">}</span>
<span class="nx">o</span> <span class="s2">&quot;IfBlock ELSE IF Expression Block&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="nx">$1</span><span class="p">.</span><span class="nx">addElse</span> <span class="p">(</span><span class="k">new</span> <span class="nx">IfNode</span><span class="p">(</span><span class="nx">$4</span><span class="p">,</span> <span class="nx">$5</span><span class="p">)).</span><span class="nx">forceStatement</span><span class="p">()</span>
<span class="nx">o</span> <span class="s2">&quot;IfBlock ELSE Block&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="nx">$1</span><span class="p">.</span><span class="nx">addElse</span> <span class="nx">$3</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 full complement of <em>if</em> expressions, including postfix one-liner
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-64"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-64">#</a> </div> <p>The full complement of <em>if</em> expressions, including postfix one-liner
<em>if</em> and <em>unless</em>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">If: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;IfBlock&quot;</span>
<span class="nx">o</span> <span class="s2">&quot;Statement IF Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">IfNode</span> <span class="nx">$3</span><span class="p">,</span> <span class="nx">Expressions</span><span class="p">.</span><span class="nx">wrap</span><span class="p">([</span><span class="nx">$1</span><span class="p">]),</span> <span class="p">{</span><span class="nv">statement: </span><span class="kc">true</span><span class="p">}</span>
<span class="nx">o</span> <span class="s2">&quot;Expression IF Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">IfNode</span> <span class="nx">$3</span><span class="p">,</span> <span class="nx">Expressions</span><span class="p">.</span><span class="nx">wrap</span><span class="p">([</span><span class="nx">$1</span><span class="p">]),</span> <span class="p">{</span><span class="nv">statement: </span><span class="kc">true</span><span class="p">}</span>
<span class="nx">o</span> <span class="s2">&quot;Statement UNLESS Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">IfNode</span> <span class="nx">$3</span><span class="p">,</span> <span class="nx">Expressions</span><span class="p">.</span><span class="nx">wrap</span><span class="p">([</span><span class="nx">$1</span><span class="p">]),</span> <span class="p">{</span><span class="nv">statement: </span><span class="kc">true</span><span class="p">,</span> <span class="nv">invert: </span><span class="kc">true</span><span class="p">}</span>
<span class="nx">o</span> <span class="s2">&quot;Expression UNLESS Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">IfNode</span> <span class="nx">$3</span><span class="p">,</span> <span class="nx">Expressions</span><span class="p">.</span><span class="nx">wrap</span><span class="p">([</span><span class="nx">$1</span><span class="p">]),</span> <span class="p">{</span><span class="nv">statement: </span><span class="kc">true</span><span class="p">,</span> <span class="nv">invert: </span><span class="kc">true</span><span class="p">}</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-64"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-64">#</a> </div> <p>Arithmetic and logical operators, working on one or more operands.
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-65"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-65">#</a> </div> <p>Arithmetic and logical operators, working on one or more operands.
Here they are grouped by order of precedence. The actual precedence rules
are defined at the bottom of the page. It would be shorter if we could
combine most of these rules into a single generic <em>Operand OpSymbol Operand</em>
@@ -341,7 +347,7 @@ rules are necessary.</p> </td> <td class="code">
<span class="nx">o</span> <span class="s2">&quot;Expression &amp;&amp; Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">OpNode</span> <span class="s1">&#39;&amp;&amp;&#39;</span><span class="p">,</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$3</span>
<span class="nx">o</span> <span class="s2">&quot;Expression || Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">OpNode</span> <span class="s1">&#39;||&#39;</span><span class="p">,</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$3</span>
<span class="nx">o</span> <span class="s2">&quot;Expression ? Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">OpNode</span> <span class="s1">&#39;?&#39;</span><span class="p">,</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$3</span>
<span class="nx">o</span> <span class="s2">&quot;Expression OP? Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">OpNode</span> <span class="s1">&#39;?&#39;</span><span class="p">,</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$3</span>
<span class="nx">o</span> <span class="s2">&quot;Expression -= Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">OpNode</span> <span class="s1">&#39;-=&#39;</span><span class="p">,</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$3</span>
<span class="nx">o</span> <span class="s2">&quot;Expression += Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">OpNode</span> <span class="s1">&#39;+=&#39;</span><span class="p">,</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$3</span>
@@ -359,7 +365,7 @@ rules are necessary.</p> </td> <td class="code">
<span class="nx">o</span> <span class="s2">&quot;Expression ! OF Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">OpNode</span> <span class="s1">&#39;!&#39;</span><span class="p">,</span> <span class="k">new</span> <span class="nx">ParentheticalNode</span> <span class="k">new</span> <span class="nx">OpNode</span> <span class="s1">&#39;in&#39;</span><span class="p">,</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$4</span>
<span class="p">]</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-65"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-65">#</a> </div> <h2>Precedence</h2> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-66"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-66">#</a> </div> <p>Operators at the top of this list have higher precedence than the ones lower
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-66"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-66">#</a> </div> <h2>Precedence</h2> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-67"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-67">#</a> </div> <p>Operators at the top of this list have higher precedence than the ones lower
down. Following these rules is what makes <code>2 + 3 * 4</code> parse as:</p>
<pre><code>2 + (3 * 4)
@@ -378,7 +384,7 @@ down. Following these rules is what makes <code>2 + 3 * 4</code> parse as:</p>
<span class="p">[</span><span class="s2">&quot;left&quot;</span><span class="p">,</span> <span class="s1">&#39;&lt;=&#39;</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="p">[</span><span class="s2">&quot;right&quot;</span><span class="p">,</span> <span class="s1">&#39;DELETE&#39;</span><span class="p">,</span> <span class="s1">&#39;INSTANCEOF&#39;</span><span class="p">,</span> <span class="s1">&#39;TYPEOF&#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;==&#39;</span><span class="p">,</span> <span class="s1">&#39;!=&#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;&amp;&amp;&#39;</span><span class="p">,</span> <span class="s1">&#39;||&#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;&amp;&amp;&#39;</span><span class="p">,</span> <span class="s1">&#39;||&#39;</span><span class="p">,</span> <span class="s1">&#39;OP?&#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;-=&#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;%=&#39;</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>
<span class="p">[</span><span class="s2">&quot;left&quot;</span><span class="p">,</span> <span class="s1">&#39;.&#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;INDENT&#39;</span><span class="p">]</span>
@@ -388,7 +394,7 @@ down. Following these rules is what makes <code>2 + 3 * 4</code> parse as:</p>
<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;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-67"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-67">#</a> </div> <h2>Wrapping Up</h2> </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>Finally, now what we have our <strong>grammar</strong> and our <strong>operators</strong>, we can create
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-68"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-68">#</a> </div> <h2>Wrapping Up</h2> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-69"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-69">#</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)
as "tokens".</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">tokens: </span><span class="p">[]</span>
@@ -397,7 +403,7 @@ as "tokens".</p> </td> <td class="code"> <
<span class="k">for</span> <span class="nx">token</span> <span class="k">in</span> <span class="nx">alt</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nx">split</span> <span class="s1">&#39; &#39;</span>
<span class="nx">tokens</span><span class="p">.</span><span class="nx">push</span> <span class="nx">token</span> <span class="nx">unless</span> <span class="nx">grammar</span><span class="p">[</span><span class="nx">token</span><span class="p">]</span>
<span class="nx">alt</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;return ${alt[1]}&quot;</span> <span class="k">if</span> <span class="nx">name</span> <span class="o">is</span> <span class="s1">&#39;Root&#39;</span>
<span class="nx">alt</span></pre></div> </td> </tr> <tr id="section-69"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-69">#</a> </div> <p>Initialize the <strong>Parser</strong> with our list of terminal <strong>tokens</strong>, our <strong>grammar</strong>
<span class="nx">alt</span></pre></div> </td> </tr> <tr id="section-70"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-70">#</a> </div> <p>Initialize the <strong>Parser</strong> with our list of terminal <strong>tokens</strong>, our <strong>grammar</strong>
rules, and the name of the root. Reverse the operators because Jison orders
precedence from low to high, and we have it high to low
(as in <a href="http://dinosaur.compilertools.net/yacc/index.html">Yacc</a>).</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.parser: </span><span class="k">new</span> <span class="nx">Parser</span> <span class="p">{</span>

View File

@@ -40,7 +40,7 @@ unless explicitly asked not to.</p> </td> <td class="cod
<span class="nx">@extractNextToken</span><span class="p">()</span>
<span class="nx">@closeIndentation</span><span class="p">()</span>
<span class="k">return</span> <span class="nx">@tokens</span> <span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">rewrite</span> <span class="o">is</span> <span class="kc">off</span>
<span class="p">(</span><span class="k">new</span> <span class="nx">Rewriter</span><span class="p">()).</span><span class="nx">rewrite</span> <span class="nx">@tokens</span></pre></div> </td> </tr> <tr id="section-7"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-7">#</a> </div> <p>At every position, run through this list of attempted matches,
<span class="p">(</span><span class="k">new</span> <span class="nx">Rewriter</span><span class="p">).</span><span class="nx">rewrite</span> <span class="nx">@tokens</span></pre></div> </td> </tr> <tr id="section-7"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-7">#</a> </div> <p>At every position, run through this list of attempted matches,
short-circuiting if any of them succeed. Their order determines precedence:
<code>@literalToken</code> is the fallback catch-all.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">extractNextToken: </span><span class="o">-&gt;</span>
<span class="k">return</span> <span class="k">if</span> <span class="nx">@identifierToken</span><span class="p">()</span>
@@ -75,8 +75,8 @@ though <code>is</code> means <code>===</code> otherwise.</p> </td>
<span class="k">else</span> <span class="k">if</span> <span class="nx">include</span><span class="p">(</span><span class="nx">RESERVED</span><span class="p">,</span> <span class="nx">id</span><span class="p">)</span>
<span class="nx">@identifierError</span> <span class="nx">id</span>
<span class="nx">unless</span> <span class="nx">forcedIdentifier</span>
<span class="nv">tag: id: </span><span class="nx">CONVERSIONS</span><span class="p">[</span><span class="nx">id</span><span class="p">]</span> <span class="k">if</span> <span class="nx">include</span> <span class="nx">COFFEE_ALIASES</span><span class="p">,</span> <span class="nx">id</span>
<span class="k">return</span> <span class="nx">@tagHalfAssignment</span> <span class="nx">tag</span> <span class="k">if</span> <span class="nx">@prev</span><span class="p">()</span> <span class="o">and</span> <span class="nx">@prev</span><span class="p">()[</span><span class="mi">0</span><span class="p">]</span> <span class="o">is</span> <span class="s1">&#39;ASSIGN&#39;</span> <span class="o">and</span> <span class="nx">include</span> <span class="nx">HALF_ASSIGNMENTS</span><span class="p">,</span> <span class="nx">tag</span>
<span class="nv">tag: id: </span><span class="nx">CONVERSIONS</span><span class="p">[</span><span class="nx">id</span><span class="p">]</span> <span class="k">if</span> <span class="nx">include</span> <span class="nx">COFFEE_ALIASES</span><span class="p">,</span> <span class="nx">id</span>
<span class="k">return</span> <span class="nx">@tagHalfAssignment</span> <span class="nx">tag</span> <span class="k">if</span> <span class="nx">@prev</span><span class="p">()</span> <span class="o">and</span> <span class="nx">@prev</span><span class="p">()[</span><span class="mi">0</span><span class="p">]</span> <span class="o">is</span> <span class="s1">&#39;ASSIGN&#39;</span> <span class="o">and</span> <span class="nx">include</span> <span class="nx">HALF_ASSIGNMENTS</span><span class="p">,</span> <span class="nx">tag</span>
<span class="nx">@token</span> <span class="nx">tag</span><span class="p">,</span> <span class="nx">id</span>
<span class="nx">@token</span> <span class="s1">&#39;]&#39;</span><span class="p">,</span> <span class="s1">&#39;]&#39;</span> <span class="k">if</span> <span class="nx">close_index</span>
<span class="kc">true</span></pre></div> </td> </tr> <tr id="section-10"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-10">#</a> </div> <p>Matches numbers, including decimals, hex, and exponential notation.
@@ -106,6 +106,10 @@ preserve whitespace, but ignore indentation to the left.</p> </td>
<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="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="k">if</span> <span class="nx">match</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span>
<span class="nv">comment: </span><span class="nx">@sanitizeHeredoc</span> <span class="nx">match</span><span class="p">[</span><span class="mi">2</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="nx">@token</span> <span class="s1">&#39;TERMINATOR&#39;</span><span class="p">,</span> <span class="s1">&#39;\n&#39;</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">jsToken: </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">@balancedToken</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>
@@ -199,6 +203,8 @@ parentheses that indicate a method call from regular parentheses, and so on.</p>
<span class="nx">@assignmentError</span><span class="p">()</span> <span class="k">if</span> <span class="nx">include</span> <span class="nx">JS_FORBIDDEN</span><span class="p">,</span> <span class="nx">@value</span>
<span class="k">else</span> <span class="k">if</span> <span class="nx">value</span> <span class="o">is</span> <span class="s1">&#39;;&#39;</span>
<span class="nv">tag: </span><span class="s1">&#39;TERMINATOR&#39;</span>
<span class="k">else</span> <span class="k">if</span> <span class="nx">value</span> <span class="o">is</span> <span class="s1">&#39;?&#39;</span> <span class="o">and</span> <span class="nx">prevSpaced</span>
<span class="nv">tag: </span><span class="s1">&#39;OP?&#39;</span>
<span class="k">else</span> <span class="k">if</span> <span class="nx">include</span><span class="p">(</span><span class="nx">CALLABLE</span><span class="p">,</span> <span class="nx">@tag</span><span class="p">())</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">prevSpaced</span>
<span class="k">if</span> <span class="nx">value</span> <span class="o">is</span> <span class="s1">&#39;(&#39;</span>
<span class="nv">tag: </span><span class="s1">&#39;CALL_START&#39;</span>
@@ -223,14 +229,16 @@ is the previous token.</p> </td> <td class="code">
<span class="nx">@tag</span> <span class="mi">1</span><span class="p">,</span> <span class="s1">&#39;PROPERTY_ACCESS&#39;</span>
<span class="k">else</span>
<span class="nx">prev</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">is</span> <span class="s1">&#39;@&#39;</span>
<span class="k">if</span> <span class="nx">accessor</span> <span class="k">then</span> <span class="s1">&#39;accessor&#39;</span> <span class="k">else</span> <span class="kc">false</span></pre></div> </td> </tr> <tr id="section-25"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-25">#</a> </div> <p>Sanitize a heredoc by escaping internal double quotes and
<span class="k">if</span> <span class="nx">accessor</span> <span class="k">then</span> <span class="s1">&#39;accessor&#39;</span> <span class="k">else</span> <span class="kc">false</span></pre></div> </td> </tr> <tr id="section-25"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-25">#</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">sanitizeHeredoc: </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="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="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="s2">&quot;\\$options.quote&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>Tag a half assignment.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">tagHalfAssignment: </span><span class="p">(</span><span class="nx">tag</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">tag: </span> <span class="s1">&#39;?&#39;</span> <span class="k">if</span> <span class="nx">tag</span> <span class="o">is</span> <span class="s1">&#39;OP?&#39;</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-27"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-27">#</a> </div> <p>A source of ambiguity in our grammar used to be parameter lists in function
@@ -293,7 +301,7 @@ token stream.</p> </td> <td class="code">
<span class="k">if</span> <span class="nx">str</span><span class="p">.</span><span class="nx">length</span> <span class="o">&lt;</span> <span class="mi">3</span> <span class="o">or</span> <span class="o">not</span> <span class="nx">starts</span> <span class="nx">str</span><span class="p">,</span> <span class="s1">&#39;&quot;&#39;</span>
<span class="nx">@token</span> <span class="s1">&#39;STRING&#39;</span><span class="p">,</span> <span class="nx">str</span>
<span class="k">else</span>
<span class="nv">lexer: </span> <span class="k">new</span> <span class="nx">Lexer</span><span class="p">()</span>
<span class="nv">lexer: </span> <span class="k">new</span> <span class="nx">Lexer</span>
<span class="nv">tokens: </span> <span class="p">[]</span>
<span class="nv">quote: </span> <span class="nx">str</span><span class="p">.</span><span class="nx">substring</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span>
<span class="p">[</span><span class="nx">i</span><span class="p">,</span> <span class="nx">pi</span><span class="p">]</span><span class="o">:</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">]</span>
@@ -311,6 +319,7 @@ token stream.</p> </td> <td class="code">
<span class="nx">tokens</span><span class="p">.</span><span class="nx">push</span> <span class="p">[</span><span class="s1">&#39;STRING&#39;</span><span class="p">,</span> <span class="s2">&quot;$quote${ str.substring(pi, i) }$quote&quot;</span><span class="p">]</span> <span class="k">if</span> <span class="nx">pi</span> <span class="o">&lt;</span> <span class="nx">i</span>
<span class="nv">inner: </span><span class="nx">expr</span><span class="p">.</span><span class="nx">substring</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="nx">expr</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">if</span> <span class="nx">inner</span><span class="p">.</span><span class="nx">length</span>
<span class="nv">inner: </span><span class="nx">inner</span><span class="p">.</span><span class="nx">replace</span> <span class="k">new</span> <span class="nb">RegExp</span><span class="p">(</span><span class="s1">&#39;\\\\&#39;</span> <span class="o">+</span> <span class="nx">quote</span><span class="p">,</span> <span class="s1">&#39;g&#39;</span><span class="p">),</span> <span class="nx">quote</span>
<span class="nv">nested: </span><span class="nx">lexer</span><span class="p">.</span><span class="nx">tokenize</span> <span class="s2">&quot;($inner)&quot;</span><span class="p">,</span> <span class="p">{</span><span class="nv">line: </span><span class="nx">@line</span><span class="p">}</span>
<span class="p">(</span><span class="nx">tok</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">:</span> <span class="s1">&#39;)&#39;</span><span class="p">)</span> <span class="k">for</span> <span class="nx">tok</span><span class="p">,</span> <span class="nx">idx</span> <span class="k">in</span> <span class="nx">nested</span> <span class="k">when</span> <span class="nx">tok</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">is</span> <span class="s1">&#39;CALL_END&#39;</span>
<span class="nx">nested</span><span class="p">.</span><span class="nx">pop</span><span class="p">()</span>
@@ -375,9 +384,9 @@ be used as identifiers or properties.</p> </td> <td clas
<span class="nv">NUMBER : </span><span class="sr">/^(((\b0(x|X)[0-9a-fA-F]+)|((\b[0-9]+(\.[0-9]+)?|\.[0-9]+)(e[+\-]?[0-9]+)?)))\b/i</span>
<span class="nv">HEREDOC : </span><span class="sr">/^(&quot;{6}|&#39;{6}|&quot;{3}\n?([\s\S]*?)\n?([ \t]*)&quot;{3}|&#39;{3}\n?([\s\S]*?)\n?([ \t]*)&#39;{3})/</span>
<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">OPERATOR : </span><span class="sr">/^(-[\-=&gt;]?|\+[+=]?|[*&amp;|\/%=&lt;&gt;:!?]+)([ \t]*)/</span>
<span class="nv">WHITESPACE : </span><span class="sr">/^([ \t]+)/</span>
<span class="nv">COMMENT : </span><span class="sr">/^(\s*#{3}(?!#)[ \t]*\n+([\s\S]*?)[ \t]*\n+[ \t]*#{3}|(\s*#[^\n]*)+)/</span>
<span class="nv">COMMENT : </span><span class="sr">/^(\s*#{3}(?!#)[ \t]*\n+([\s\S]*?)[ \t]*\n+[ \t]*#{3}|(\s*#(?!##[^#])[^\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>
@@ -390,7 +399,7 @@ be used as identifiers or properties.</p> </td> <td clas
<span class="nv">STRING_NEWLINES : </span><span class="sr">/\n[ \t]*/g</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">/(\n+([ \t]*)|^([ \t]+))/g</span>
<span class="nv">ASSIGNED : </span><span class="sr">/^([a-zA-Z\$_]\w*[ \t]*?[:=])/</span>
<span class="nv">ASSIGNED : </span><span class="sr">/^([a-zA-Z\$_]\w*[ \t]*?[:=][^=])/</span>
<span class="nv">NEXT_CHARACTER : </span><span class="sr">/^\s*(\S)/</span></pre></div> </td> </tr> <tr id="section-48"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-48">#</a> </div> <p>Tokens which a regular expression will never immediately follow, but which
a division operator might.</p>
@@ -402,7 +411,7 @@ a division operator might.</p>
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> <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-50"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-50">#</a> </div> <p>Tokens that, when immediately preceding a <code>WHEN</code>, indicate that the <code>WHEN</code>
occurs at the start of a line. We disambiguate these from trailing whens to
avoid an ambiguity in the grammar.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">LINE_BREAK: </span><span class="p">[</span><span class="s1">&#39;INDENT&#39;</span><span class="p">,</span> <span class="s1">&#39;OUTDENT&#39;</span><span class="p">,</span> <span class="s1">&#39;TERMINATOR&#39;</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-51"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-51">#</a> </div> <p>Half-assignments...</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">HALF_ASSIGNMENTS: </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;*&#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;&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-52"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-52">#</a> </div> <p>Conversions from CoffeeScript operators into JavaScript ones.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">CONVERSIONS: </span><span class="p">{</span>
avoid an ambiguity in the grammar.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">LINE_BREAK: </span><span class="p">[</span><span class="s1">&#39;INDENT&#39;</span><span class="p">,</span> <span class="s1">&#39;OUTDENT&#39;</span><span class="p">,</span> <span class="s1">&#39;TERMINATOR&#39;</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-51"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-51">#</a> </div> <p>Half-assignments...</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">HALF_ASSIGNMENTS: </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;*&#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;&amp;&amp;&#39;</span><span class="p">,</span> <span class="s1">&#39;?&#39;</span><span class="p">,</span> <span class="s1">&#39;OP?&#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>Conversions from CoffeeScript operators into JavaScript ones.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">CONVERSIONS: </span><span class="p">{</span>
<span class="s1">&#39;and&#39;</span><span class="o">:</span> <span class="s1">&#39;&amp;&amp;&#39;</span>
<span class="s1">&#39;or&#39;</span><span class="o">:</span> <span class="s1">&#39;||&#39;</span>
<span class="s1">&#39;is&#39;</span><span class="o">:</span> <span class="s1">&#39;==&#39;</span>

View File

@@ -33,7 +33,7 @@ top-level statement within the function body.</p> </td>
<span class="nx">del</span> <span class="nx">@options</span><span class="p">,</span> <span class="s1">&#39;chainRoot&#39;</span> <span class="nx">unless</span> <span class="k">this</span> <span class="k">instanceof</span> <span class="nx">AccessorNode</span> <span class="o">or</span> <span class="k">this</span> <span class="k">instanceof</span> <span class="nx">IndexNode</span>
<span class="nv">top: </span> <span class="k">if</span> <span class="nx">@topSensitive</span><span class="p">()</span> <span class="k">then</span> <span class="nx">@options</span><span class="p">.</span><span class="nx">top</span> <span class="k">else</span> <span class="nx">del</span> <span class="nx">@options</span><span class="p">,</span> <span class="s1">&#39;top&#39;</span>
<span class="nv">closure: </span> <span class="nx">@isStatement</span><span class="p">()</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">@isPureStatement</span><span class="p">()</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">top</span> <span class="o">and</span>
<span class="o">not</span> <span class="nx">@options</span><span class="p">.</span><span class="nx">asStatement</span> <span class="o">and</span>
<span class="o">not</span> <span class="nx">@options</span><span class="p">.</span><span class="nx">asStatement</span> <span class="o">and</span> <span class="o">not</span> <span class="p">(</span><span class="k">this</span> <span class="k">instanceof</span> <span class="nx">CommentNode</span><span class="p">)</span> <span class="o">and</span>
<span class="o">not</span> <span class="nx">@containsPureStatement</span><span class="p">()</span>
<span class="k">if</span> <span class="nx">closure</span> <span class="k">then</span> <span class="nx">@compileClosure</span><span class="p">(</span><span class="nx">@options</span><span class="p">)</span> <span class="k">else</span> <span class="nx">@compileNode</span><span class="p">(</span><span class="nx">@options</span><span class="p">)</span></pre></div> </td> </tr> <tr id="section-7"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-7">#</a> </div> <p>Statements converted into expressions via closure-wrapping share a scope
object with their parent closure, to preserve the expected lexical scope.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compileClosure: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
@@ -70,9 +70,10 @@ scope boundaries.</p> </td> <td class="code">
<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-13"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-13">#</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">containsPureStatement: </span><span class="o">-&gt;</span>
<span class="nx">@isPureStatement</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">isPureStatement</span><span class="p">()</span></pre></div> </td> </tr> <tr id="section-14"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-14">#</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">@traverseChildren</span> <span class="kc">true</span><span class="p">,</span> <span class="nx">block</span></pre></div> </td> </tr> <tr id="section-15"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-15">#</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>
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="nx">override</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">@class</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">@collectChildren</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="p">(</span><span class="nx">child</span><span class="p">.</span><span class="nx">toString</span> <span class="nx">idt</span> <span class="o">+</span> <span class="nx">TAB</span> <span class="k">for</span> <span class="nx">child</span> <span class="k">in</span> <span class="nx">@collectChildren</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="s1">&#39;\n&#39;</span> <span class="o">+</span> <span class="nx">idt</span> <span class="o">+</span> <span class="p">(</span><span class="nx">override</span> <span class="o">or</span> <span class="nx">@class</span><span class="p">)</span> <span class="o">+</span> <span class="nx">children</span>
<span class="nv">eachChild: </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</span>
@@ -92,9 +93,9 @@ This is what <code>coffee --nodes</code> prints out.</p> </td>
will override these with custom logic, if needed.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">class: </span> <span class="s1">&#39;BaseNode&#39;</span>
<span class="nv">children: </span><span class="p">[]</span>
<span class="nv">unwrap: </span> <span class="o">-&gt;</span> <span class="k">this</span>
<span class="nv">unwrap: </span> <span class="o">-&gt;</span> <span class="k">this</span>
<span class="nv">isStatement: </span> <span class="o">-&gt;</span> <span class="kc">no</span>
<span class="nv">isPureStatement: </span><span class="o">-&gt;</span> <span class="kc">no</span>
<span class="nv">isPureStatement: </span> <span class="o">-&gt;</span> <span class="kc">no</span>
<span class="nv">topSensitive: </span> <span class="o">-&gt;</span> <span class="kc">no</span></pre></div> </td> </tr> <tr id="section-17"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-17">#</a> </div> <h3>Expressions</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-18"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-18">#</a> </div> <p>The expressions body is the list of expressions that forms the body of an
indented block of code -- the implementation of a function, a clause in an
<code>if</code>, <code>switch</code>, or <code>try</code>, and so on...</p> </td> <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>
@@ -115,6 +116,7 @@ it back out.</p> </td> <td class="code"> <
ensures that the final expression is returned.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">makeReturn: </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">makeReturn</span><span class="p">()</span>
<span class="k">this</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 <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>
@@ -128,14 +130,14 @@ It would be better not to generate them in the first place, but for now,
clean up obvious double-parentheses.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compileRoot: </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">noWrap</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">@compileNode</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="k">else</span> <span class="nx">@compileWithDeclarations</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span>
<span class="nv">code: </span><span class="nx">@compileWithDeclarations</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="nv">code: </span><span class="nx">code</span><span class="p">.</span><span class="nx">replace</span><span class="p">(</span><span class="nx">DOUBLE_PARENS</span><span class="p">,</span> <span class="s1">&#39;($1)&#39;</span><span class="p">)</span>
<span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">noWrap</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-26"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-26">#</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">compileWithDeclarations: </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">@compileNode</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.compiledAssignments()};\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">hasAssignments</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.compiledDeclarations()};\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">hasDeclarations</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.compiledDeclarations()};\n$code&quot;</span> <span class="k">if</span> <span class="o">not</span> <span class="nx">o</span><span class="p">.</span><span class="nx">globals</span> <span class="o">and</span> <span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">hasDeclarations</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-27"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-27">#</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">compileExpression: </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>
@@ -173,16 +175,15 @@ make sense.</p> </td> <td class="code"> <d
<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">@expression: </span><span class="nx">expression</span>
<span class="nv">topSensitive: </span><span class="o">-&gt;</span>
<span class="kc">true</span>
<span class="nv">makeReturn: </span><span class="o">-&gt;</span>
<span class="k">this</span>
<span class="nv">compileNode: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<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">expr: </span><span class="nx">@expression</span><span class="p">.</span><span class="nx">makeReturn</span><span class="p">()</span>
<span class="k">return</span> <span class="nx">expr</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">unless</span> <span class="nx">expr</span> <span class="k">instanceof</span> <span class="nx">ReturnNode</span>
<span class="nx">del</span> <span class="nx">o</span><span class="p">,</span> <span class="s1">&#39;top&#39;</span>
<span class="k">return</span> <span class="nx">expr</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">o</span> <span class="nx">unless</span> <span class="nx">expr</span> <span class="k">instanceof</span> <span class="nx">ReturnNode</span>
<span class="k">super</span> <span class="nx">o</span>
<span class="nv">compileNode: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">o.asStatement: </span><span class="kc">true</span> <span class="k">if</span> <span class="nx">@expression</span><span class="p">.</span><span class="nx">isStatement</span><span class="p">()</span>
<span class="s2">&quot;${@tab}return ${@expression.compile(o)};&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>ValueNode</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 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>
@@ -217,14 +218,15 @@ properties.</p> </td> <td class="code"> <d
<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">chainRoot</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">chainRoot</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">chainRoot</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-42"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-42">#</a> </div> <p>We compile a value to JavaScript by compiling and joining each property.
<span class="nx">node</span> <span class="o">is</span> <span class="k">this</span></pre></div> </td> </tr> <tr id="section-42"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-42">#</a> </div> <p>Override compile to unwrap the value when possible.</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">if</span> <span class="o">not</span> <span class="nx">o</span><span class="p">.</span><span class="nx">top</span> <span class="o">or</span> <span class="nx">@properties</span><span class="p">.</span><span class="nx">length</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">@base</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-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">compileNode: </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;onlyFirst&#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">only: </span> <span class="nx">del</span> <span class="nx">o</span><span class="p">,</span> <span class="s1">&#39;onlyFirst&#39;</span>
<span class="nv">op: </span> <span class="nx">del</span> <span class="nx">o</span><span class="p">,</span> <span class="s1">&#39;operation&#39;</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.chainRoot: </span><span class="o">or</span> <span class="k">this</span>
<span class="nv">o.chainRoot: </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">@hasProperties</span><span class="p">()</span> <span class="o">and</span> <span class="p">(</span><span class="nx">@base</span> <span class="k">instanceof</span> <span class="nx">ObjectNode</span> <span class="o">or</span> <span class="nx">@isNumber</span><span class="p">())</span>
<span class="nv">complete: </span> <span class="vi">@last: </span><span class="nx">baseline</span>
@@ -243,7 +245,21 @@ evaluate a anything twice when building the soak chain.</p> </td>
<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-43"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-43">#</a> </div> <h3>CallNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-44"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-44">#</a> </div> <p>Node for a function invocation. Takes care of converting <code>super()</code> calls into
<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 block comments as JavaScript block 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">class: </span><span class="s1">&#39;CommentNode&#39;</span>
<span class="nv">isStatement: </span><span class="o">-&gt;</span> <span class="kc">yes</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="vi">@lines: </span><span class="nx">lines</span>
<span class="nv">makeReturn: </span><span class="o">-&gt;</span>
<span class="k">this</span>
<span class="nv">compileNode: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">sep: </span><span class="s2">&quot;\n$@tab&quot;</span>
<span class="s2">&quot;$@tab/*$sep${ @lines.join(sep) }\n$@tab*/&quot;</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>
<span class="nv">class: </span> <span class="s1">&#39;CallNode&#39;</span>
@@ -255,18 +271,18 @@ calls against the prototype's function of the same name.</p> </td>
<span class="vi">@variable: </span> <span class="k">if</span> <span class="nx">@isSuper</span> <span class="k">then</span> <span class="kc">null</span> <span class="k">else</span> <span class="nx">variable</span>
<span class="vi">@args: </span> <span class="p">(</span><span class="nx">args</span> <span class="o">or</span> <span class="p">[])</span>
<span class="vi">@compileSplatArguments: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nx">SplatNode</span><span class="p">.</span><span class="nx">compileMixedArray</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="nx">@args</span><span class="p">,</span> <span class="nx">o</span><span class="p">)</span></pre></div> </td> </tr> <tr id="section-45"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-45">#</a> </div> <p>Tag this invocation as creating a new instance.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">newInstance: </span><span class="o">-&gt;</span>
<span class="nx">SplatNode</span><span class="p">.</span><span class="nx">compileMixedArray</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="nx">@args</span><span class="p">,</span> <span class="nx">o</span><span class="p">)</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">newInstance: </span><span class="o">-&gt;</span>
<span class="vi">@isNew: </span><span class="kc">true</span>
<span class="k">this</span>
<span class="nv">prefix: </span><span class="o">-&gt;</span>
<span class="k">if</span> <span class="nx">@isNew</span> <span class="k">then</span> <span class="s1">&#39;new &#39;</span> <span class="k">else</span> <span class="s1">&#39;&#39;</span></pre></div> </td> </tr> <tr id="section-46"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-46">#</a> </div> <p>Grab the reference to the superclass' implementation of the current method.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">superReference: </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">@isNew</span> <span class="k">then</span> <span class="s1">&#39;new &#39;</span> <span class="k">else</span> <span class="s1">&#39;&#39;</span></pre></div> </td> </tr> <tr id="section-49"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-49">#</a> </div> <p>Grab the reference to the superclass' implementation of the current method.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">superReference: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">methname: </span><span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">method</span><span class="p">.</span><span class="nx">name</span>
<span class="nv">meth: </span><span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">method</span><span class="p">.</span><span class="nx">proto</span>
<span class="s2">&quot;${o.scope.method.proto}.__superClass__.$methname&quot;</span>
<span class="k">else</span> <span class="k">if</span> <span class="nx">methname</span>
<span class="s2">&quot;${methname}.__superClass__.constructor&quot;</span>
<span class="k">else</span> <span class="k">throw</span> <span class="k">new</span> <span class="nb">Error</span> <span class="s2">&quot;cannot call super on an anonymous function.&quot;</span></pre></div> </td> </tr> <tr id="section-47"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-47">#</a> </div> <p>Compile a vanilla function call.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compileNode: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="k">else</span> <span class="k">throw</span> <span class="k">new</span> <span class="nb">Error</span> <span class="s2">&quot;cannot call super on an anonymous function.&quot;</span></pre></div> </td> </tr> <tr id="section-50"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-50">#</a> </div> <p>Compile a vanilla function call.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compileNode: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">o.chainRoot: </span><span class="k">this</span> <span class="nx">unless</span> <span class="nx">o</span><span class="p">.</span><span class="nx">chainRoot</span>
<span class="k">for</span> <span class="nx">arg</span> <span class="k">in</span> <span class="nx">@args</span> <span class="k">when</span> <span class="nx">arg</span> <span class="k">instanceof</span> <span class="nx">SplatNode</span>
<span class="nv">compilation: </span><span class="nx">@compileSplat</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span>
@@ -274,9 +290,9 @@ calls against the prototype's function of the same name.</p> </td>
<span class="nv">args: </span><span class="p">(</span><span class="nx">arg</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">for</span> <span class="nx">arg</span> <span class="k">in</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>
<span class="nv">compilation: </span><span class="k">if</span> <span class="nx">@isSuper</span> <span class="k">then</span> <span class="nx">@compileSuper</span><span class="p">(</span><span class="nx">args</span><span class="p">,</span> <span class="nx">o</span><span class="p">)</span>
<span class="k">else</span> <span class="s2">&quot;${@prefix()}${@variable.compile(o)}($args)&quot;</span>
<span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">operation</span> <span class="o">and</span> <span class="nx">@wrapped</span> <span class="k">then</span> <span class="s2">&quot;($compilation)&quot;</span> <span class="k">else</span> <span class="nx">compilation</span></pre></div> </td> </tr> <tr id="section-48"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-48">#</a> </div> <p><code>super()</code> is converted into a call against the superclass's implementation
<span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">operation</span> <span class="o">and</span> <span class="nx">@wrapped</span> <span class="k">then</span> <span class="s2">&quot;($compilation)&quot;</span> <span class="k">else</span> <span class="nx">compilation</span></pre></div> </td> </tr> <tr id="section-51"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-51">#</a> </div> <p><code>super()</code> is converted into a call against the superclass's implementation
of the current function.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compileSuper: </span><span class="p">(</span><span class="nx">args</span><span class="p">,</span> <span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="s2">&quot;${@superReference(o)}.call(this${ if args.length then &#39;, &#39; else &#39;&#39; }$args)&quot;</span></pre></div> </td> </tr> <tr id="section-49"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-49">#</a> </div> <p>If you call a function with a splat, it's converted into a JavaScript
<span class="s2">&quot;${@superReference(o)}.call(this${ if args.length then &#39;, &#39; else &#39;&#39; }$args)&quot;</span></pre></div> </td> </tr> <tr id="section-52"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-52">#</a> </div> <p>If you call a function with a splat, it's converted into a JavaScript
<code>.apply()</code> call to allow an array of arguments to be passed.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compileSplat: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">meth: </span><span class="k">if</span> <span class="nx">@variable</span> <span class="k">then</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="nx">@superReference</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span>
<span class="nv">obj: </span> <span class="nx">@variable</span> <span class="o">and</span> <span class="nx">@variable</span><span class="p">.</span><span class="nx">source</span> <span class="o">or</span> <span class="s1">&#39;this&#39;</span>
@@ -284,7 +300,7 @@ 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">freeVariable</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, ${ @compileSplatArguments(o) })&quot;</span></pre></div> </td> </tr> <tr id="section-50"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-50">#</a> </div> <h3>ExtendsNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-51"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-51">#</a> </div> <p>Node to extend an object's prototype with an ancestor object.
<span class="s2">&quot;${@prefix()}${meth}.apply($obj, ${ @compileSplatArguments(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>ExtendsNode</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>Node to extend an object's prototype with an ancestor object.
After <code>goog.inherits</code> from the
<a href="http://closure-library.googlecode.com/svn/docs/closureGoogBase.js.html">Closure Library</a>.</p> </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>
@@ -293,9 +309,9 @@ After <code>goog.inherits</code> from the
<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">@child: </span><span class="nx">child</span>
<span class="vi">@parent: </span><span class="nx">parent</span></pre></div> </td> </tr> <tr id="section-52"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-52">#</a> </div> <p>Hooks one constructor into another's prototype chain.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compileNode: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="vi">@parent: </span><span class="nx">parent</span></pre></div> </td> </tr> <tr id="section-55"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-55">#</a> </div> <p>Hooks one constructor into another's prototype chain.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compileNode: </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-53"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-53">#</a> </div> <h3>AccessorNode</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>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></pre></div> </td> </tr> <tr id="section-56"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-56">#</a> </div> <h3>AccessorNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-57"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-57">#</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">class: </span> <span class="s1">&#39;AccessorNode&#39;</span>
@@ -310,7 +326,7 @@ an accessor into the object's prototype.</p> </td> <td c
<span class="nv">name: </span><span class="nx">@name</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">o</span>
<span class="nv">o.chainRoot.wrapped: </span><span class="o">or</span> <span class="nx">@soakNode</span>
<span class="nv">namePart: </span><span class="k">if</span> <span class="nx">name</span><span class="p">.</span><span class="nx">match</span><span class="p">(</span><span class="nx">IS_STRING</span><span class="p">)</span> <span class="k">then</span> <span class="s2">&quot;[$name]&quot;</span> <span class="k">else</span> <span class="s2">&quot;.$name&quot;</span>
<span class="nx">@prototype</span> <span class="o">+</span> <span class="nx">namePart</span></pre></div> </td> </tr> <tr id="section-55"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-55">#</a> </div> <h3>IndexNode</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>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="nx">@prototype</span> <span class="o">+</span> <span class="nx">namePart</span></pre></div> </td> </tr> <tr id="section-58"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-58">#</a> </div> <h3>IndexNode</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> 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">class: </span> <span class="s1">&#39;IndexNode&#39;</span>
<span class="nv">children: </span><span class="p">[</span><span class="s1">&#39;index&#39;</span><span class="p">]</span>
@@ -322,7 +338,7 @@ an accessor into the object's prototype.</p> </td> <td c
<span class="nv">o.chainRoot.wrapped: </span><span class="o">or</span> <span class="nx">@soakNode</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="nv">prefix: </span><span class="k">if</span> <span class="nx">@proto</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;$prefix[$idx]&quot;</span></pre></div> </td> </tr> <tr id="section-57"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-57">#</a> </div> <h3>RangeNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-58"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-58">#</a> </div> <p>A range literal. Ranges can be used to extract portions (slices) of arrays,
<span class="s2">&quot;$prefix[$idx]&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>RangeNode</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 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>
@@ -332,14 +348,14 @@ corresponding array of integers at runtime.</p> </td> <t
<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">@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-59"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-59">#</a> </div> <p>Compiles the range's source variables -- where it starts and where it ends.
<span class="vi">@exclusive: </span><span class="o">!!</span><span class="nx">exclusive</span></pre></div> </td> </tr> <tr id="section-62"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-62">#</a> </div> <p>Compiles the range's source variables -- where it starts and where it ends.
But only if they need to be cached to avoid double evaluation.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compileVariables: </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">@from</span><span class="p">,</span> <span class="nx">@fromVar</span><span class="p">]</span><span class="o">:</span> <span class="nx">@from</span><span class="p">.</span><span class="nx">compileReference</span> <span class="nx">o</span>
<span class="p">[</span><span class="nx">@to</span><span class="p">,</span> <span class="nx">@toVar</span><span class="p">]</span><span class="o">:</span> <span class="nx">@to</span><span class="p">.</span><span class="nx">compileReference</span> <span class="nx">o</span>
<span class="nv">parts: </span><span class="p">[]</span>
<span class="nx">parts</span><span class="p">.</span><span class="nx">push</span> <span class="nx">@from</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">o</span> <span class="k">if</span> <span class="nx">@from</span> <span class="o">isnt</span> <span class="nx">@fromVar</span>
<span class="nx">parts</span><span class="p">.</span><span class="nx">push</span> <span class="nx">@to</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">o</span> <span class="k">if</span> <span class="nx">@to</span> <span class="o">isnt</span> <span class="nx">@toVar</span>
<span class="k">if</span> <span class="nx">parts</span><span class="p">.</span><span class="nx">length</span> <span class="k">then</span> <span class="s2">&quot;${parts.join(&#39;; &#39;)};\n$o.indent&quot;</span> <span class="k">else</span> <span class="s1">&#39;&#39;</span></pre></div> </td> </tr> <tr id="section-60"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-60">#</a> </div> <p>When compiled normally, the range returns the contents of the <em>for loop</em>
<span class="k">if</span> <span class="nx">parts</span><span class="p">.</span><span class="nx">length</span> <span class="k">then</span> <span class="s2">&quot;${parts.join(&#39;; &#39;)};&quot;</span> <span class="k">else</span> <span class="s1">&#39;&#39;</span></pre></div> </td> </tr> <tr id="section-63"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-63">#</a> </div> <p>When compiled normally, the range returns the contents of the <em>for loop</em>
needed to iterate over the values in the range. Used by comprehensions.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compileNode: </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="nx">@compileArray</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="nx">unless</span> <span class="nx">o</span><span class="p">.</span><span class="nx">index</span>
<span class="nv">idx: </span> <span class="nx">del</span> <span class="nx">o</span><span class="p">,</span> <span class="s1">&#39;index&#39;</span>
@@ -348,17 +364,19 @@ needed to iterate over the values in the range. Used by comprehensions.</p>
<span class="nv">step: </span> <span class="k">if</span> <span class="nx">step</span> <span class="k">then</span> <span class="nx">step</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;1&#39;</span>
<span class="nv">equals: </span> <span class="k">if</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;=&#39;</span>
<span class="nv">op: </span> <span class="k">if</span> <span class="nx">starts</span><span class="p">(</span><span class="nx">step</span><span class="p">,</span> <span class="s1">&#39;-&#39;</span><span class="p">)</span> <span class="k">then</span> <span class="s2">&quot;&gt;$equals&quot;</span> <span class="k">else</span> <span class="s2">&quot;&lt;$equals&quot;</span>
<span class="s2">&quot;$vars; ${idx} $op ${@toVar.compile(o)}; $idx += $step&quot;</span></pre></div> </td> </tr> <tr id="section-61"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-61">#</a> </div> <p>When used as a value, expand the range into the equivalent array.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compileArray: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="s2">&quot;$vars; ${idx} $op ${@toVar.compile(o)}; $idx += $step&quot;</span></pre></div> </td> </tr> <tr id="section-64"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-64">#</a> </div> <p>When used as a value, expand the range into the equivalent array.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compileArray: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">idt: </span> <span class="nx">@idt</span> <span class="mi">1</span>
<span class="nv">vars: </span> <span class="nx">@compileVariables</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">equals: </span><span class="k">if</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;=&#39;</span>
<span class="nv">from: </span> <span class="nx">@fromVar</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">o</span>
<span class="nv">to: </span> <span class="nx">@toVar</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">o</span>
<span class="nv">result: </span><span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span><span class="p">()</span>
<span class="nv">i: </span> <span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span><span class="p">()</span>
<span class="nv">clause: </span><span class="s2">&quot;$from &lt;= $to ?&quot;</span>
<span class="nv">pre: </span> <span class="s2">&quot;\n${idt}a = [];${vars}&quot;</span>
<span class="nv">body: </span> <span class="s2">&quot;var i = $from; ($clause i &lt;$equals $to : i &gt;$equals $to); ($clause i += 1 : i -= 1)&quot;</span>
<span class="nv">post: </span> <span class="s2">&quot;a.push(i);\n${idt}return a;\n$o.indent&quot;</span>
<span class="s2">&quot;(function(){${pre}for ($body) $post}).call(this)&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>SliceNode</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>An array slice literal. Unlike JavaScript's <code>Array#slice</code>, the second parameter
<span class="nv">pre: </span> <span class="s2">&quot;\n${idt}${result} = []; ${vars}&quot;</span>
<span class="nv">body: </span> <span class="s2">&quot;var $i = $from; $clause $i &lt;$equals $to : $i &gt;$equals $to; $clause $i += 1 : $i -= 1&quot;</span>
<span class="nv">post: </span> <span class="s2">&quot;{ ${result}.push($i) };\n${idt}return $result;\n$o.indent&quot;</span>
<span class="s2">&quot;(function(){${pre}\n${idt}for ($body)$post}).call(this)&quot;</span></pre></div> </td> </tr> <tr id="section-65"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-65">#</a> </div> <h3>SliceNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-66"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-66">#</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>
@@ -372,7 +390,7 @@ is the index of the beginning.</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="nv">plusPart: </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$plusPart)&quot;</span></pre></div> </td> </tr> <tr id="section-64"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-64">#</a> </div> <h3>ObjectNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-65"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-65">#</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$plusPart)&quot;</span></pre></div> </td> </tr> <tr id="section-67"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-67">#</a> </div> <h3>ObjectNode</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 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">class: </span> <span class="s1">&#39;ObjectNode&#39;</span>
<span class="nv">children: </span><span class="p">[</span><span class="s1">&#39;properties&#39;</span><span class="p">]</span>
@@ -382,14 +400,18 @@ is the index of the beginning.</p> </td> <td class="code
<span class="nv">compileNode: </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">last: </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="nv">nonComments: </span><span class="nx">prop</span> <span class="k">for</span> <span class="nx">prop</span> <span class="k">in</span> <span class="nx">@properties</span> <span class="k">when</span> <span class="o">not</span> <span class="p">(</span><span class="nx">prop</span> <span class="k">instanceof</span> <span class="nx">CommentNode</span><span class="p">)</span>
<span class="nv">lastNoncom: </span> <span class="nx">nonComments</span><span class="p">[</span><span class="nx">nonComments</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="nv">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">@properties</span>
<span class="nv">join: </span> <span class="k">if</span> <span class="nx">i</span> <span class="o">is</span> <span class="nx">last</span> <span class="k">then</span> <span class="s1">&#39;&#39;</span> <span class="k">else</span> <span class="s1">&#39;,\n&#39;</span>
<span class="nv">prop: </span> <span class="k">new</span> <span class="nx">AssignNode</span> <span class="nx">prop</span><span class="p">,</span> <span class="nx">prop</span><span class="p">,</span> <span class="s1">&#39;object&#39;</span> <span class="nx">unless</span> <span class="nx">prop</span> <span class="k">instanceof</span> <span class="nx">AssignNode</span>
<span class="nx">@idt</span><span class="p">(</span><span class="mi">1</span><span class="p">)</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">join: </span> <span class="s2">&quot;,\n&quot;</span>
<span class="nv">join: </span> <span class="s2">&quot;\n&quot;</span> <span class="k">if</span> <span class="p">(</span><span class="nx">prop</span> <span class="o">is</span> <span class="nx">lastNoncom</span><span class="p">)</span> <span class="o">or</span> <span class="p">(</span><span class="nx">prop</span> <span class="k">instanceof</span> <span class="nx">CommentNode</span><span class="p">)</span>
<span class="nv">join: </span> <span class="s1">&#39;&#39;</span> <span class="k">if</span> <span class="nx">i</span> <span class="o">is</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="nv">indent: </span><span class="k">if</span> <span class="nx">prop</span> <span class="k">instanceof</span> <span class="nx">CommentNode</span> <span class="k">then</span> <span class="s1">&#39;&#39;</span> <span class="k">else</span> <span class="nx">@idt</span> <span class="mi">1</span>
<span class="nv">prop: </span> <span class="k">new</span> <span class="nx">AssignNode</span> <span class="nx">prop</span><span class="p">,</span> <span class="nx">prop</span><span class="p">,</span> <span class="s1">&#39;object&#39;</span> <span class="nx">unless</span> <span class="nx">prop</span> <span class="k">instanceof</span> <span class="nx">AssignNode</span> <span class="o">or</span> <span class="nx">prop</span> <span class="k">instanceof</span> <span class="nx">CommentNode</span>
<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-66"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-66">#</a> </div> <h3>ArrayNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-67"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-67">#</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></pre></div> </td> </tr> <tr id="section-69"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-69">#</a> </div> <h3>ArrayNode</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 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">class: </span> <span class="s1">&#39;ArrayNode&#39;</span>
<span class="nv">children: </span><span class="p">[</span><span class="s1">&#39;objects&#39;</span><span class="p">]</span>
@@ -406,6 +428,8 @@ is the index of the beginning.</p> </td> <td class="code
<span class="nv">code: </span><span class="nx">obj</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">obj</span> <span class="k">instanceof</span> <span class="nx">SplatNode</span>
<span class="k">return</span> <span class="nx">@compileSplatLiteral</span> <span class="nx">@objects</span><span class="p">,</span> <span class="nx">o</span>
<span class="k">else</span> <span class="k">if</span> <span class="nx">obj</span> <span class="k">instanceof</span> <span class="nx">CommentNode</span>
<span class="nx">objects</span><span class="p">.</span><span class="nx">push</span> <span class="s2">&quot;\n$code\n$o.indent&quot;</span>
<span class="k">else</span> <span class="k">if</span> <span class="nx">i</span> <span class="o">is</span> <span class="nx">@objects</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="mi">1</span>
<span class="nx">objects</span><span class="p">.</span><span class="nx">push</span> <span class="nx">code</span>
<span class="k">else</span>
@@ -414,11 +438,11 @@ is the index of the beginning.</p> </td> <td class="code
<span class="k">if</span> <span class="nx">indexOf</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-68"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-68">#</a> </div> <h3>ClassNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-69"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-69">#</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>
<span class="s2">&quot;[$objects]&quot;</span></pre></div> </td> </tr> <tr id="section-71"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-71">#</a> </div> <h3>ClassNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-72"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-72">#</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>
<span class="nv">class: </span> <span class="s1">&#39;ClassNode&#39;</span>
<span class="nv">children: </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><span class="p">]</span>
<span class="nv">isStatement: </span> <span class="o">-&gt;</span> <span class="kc">yes</span></pre></div> </td> </tr> <tr id="section-70"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-70">#</a> </div> <p>Initialize a <strong>ClassNode</strong> with its name, an optional superclass, and a
<span class="nv">isStatement: </span> <span class="o">-&gt;</span> <span class="kc">yes</span></pre></div> </td> </tr> <tr id="section-73"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-73">#</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">@variable: </span><span class="nx">variable</span>
<span class="vi">@parent: </span><span class="nx">parent</span>
@@ -427,11 +451,11 @@ list of prototype property assignments.</p> </td> <td cl
<span class="nv">makeReturn: </span><span class="o">-&gt;</span>
<span class="vi">@returns: </span><span class="kc">true</span>
<span class="k">this</span></pre></div> </td> </tr> <tr id="section-71"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-71">#</a> </div> <p>Instead of generating the JavaScript string directly, we build up the
<span class="k">this</span></pre></div> </td> </tr> <tr id="section-74"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-74">#</a> </div> <p>Instead of generating the JavaScript string directly, we build up the
equivalent syntax tree and compile that, in pieces. You can see the
constructor, property assignments, and inheritance getting built out below.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compileNode: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">extension: </span> <span class="nx">@parent</span> <span class="o">and</span> <span class="k">new</span> <span class="nx">ExtendsNode</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="nv">props: </span> <span class="k">new</span> <span class="nx">Expressions</span><span class="p">()</span>
<span class="nv">props: </span> <span class="k">new</span> <span class="nx">Expressions</span>
<span class="nv">o.top: </span> <span class="kc">true</span>
<span class="nv">me: </span> <span class="kc">null</span>
<span class="nv">className: </span> <span class="nx">@variable</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">o</span>
@@ -443,11 +467,12 @@ constructor, property assignments, and inheritance getting built out below.</p>
<span class="k">new</span> <span class="nx">CallNode</span><span class="p">(</span><span class="nx">applied</span><span class="p">,</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">literal</span><span class="p">(</span><span class="s1">&#39;arguments&#39;</span><span class="p">)])</span>
<span class="p">]))</span>
<span class="k">else</span>
<span class="nv">constructor: </span><span class="k">new</span> <span class="nx">CodeNode</span><span class="p">()</span>
<span class="nv">constructor: </span><span class="k">new</span> <span class="nx">CodeNode</span>
<span class="k">for</span> <span class="nx">prop</span> <span class="k">in</span> <span class="nx">@properties</span>
<span class="p">[</span><span class="nx">pvar</span><span class="p">,</span> <span class="nx">func</span><span class="p">]</span><span class="o">:</span> <span class="p">[</span><span class="nx">prop</span><span class="p">.</span><span class="nx">variable</span><span class="p">,</span> <span class="nx">prop</span><span class="p">.</span><span class="nx">value</span><span class="p">]</span>
<span class="k">if</span> <span class="nx">pvar</span> <span class="o">and</span> <span class="nx">pvar</span><span class="p">.</span><span class="nx">base</span><span class="p">.</span><span class="nx">value</span> <span class="o">is</span> <span class="s1">&#39;constructor&#39;</span> <span class="o">and</span> <span class="nx">func</span> <span class="k">instanceof</span> <span class="nx">CodeNode</span>
<span class="k">throw</span> <span class="k">new</span> <span class="nb">Error</span> <span class="s2">&quot;cannot define a constructor as a bound function.&quot;</span> <span class="k">if</span> <span class="nx">func</span><span class="p">.</span><span class="nx">bound</span>
<span class="nv">func.name: </span><span class="nx">className</span>
<span class="nx">func</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">push</span> <span class="k">new</span> <span class="nx">ReturnNode</span> <span class="nx">literal</span> <span class="s1">&#39;this&#39;</span>
<span class="vi">@variable: </span><span class="k">new</span> <span class="nx">ValueNode</span> <span class="nx">@variable</span>
@@ -472,8 +497,8 @@ constructor, property assignments, and inheritance getting built out below.</p>
<span class="nv">props: </span> <span class="k">if</span> <span class="nx">props</span><span class="p">.</span><span class="nx">empty</span><span class="p">()</span> <span class="k">then</span> <span class="s1">&#39;&#39;</span> <span class="k">else</span> <span class="nx">props</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;\n&#39;</span>
<span class="nv">extension: </span><span class="k">if</span> <span class="nx">extension</span> <span class="k">then</span> <span class="nx">@idt</span><span class="p">()</span> <span class="o">+</span> <span class="nx">extension</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;;\n&#39;</span> <span class="k">else</span> <span class="s1">&#39;&#39;</span>
<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></pre></div> </td> </tr> <tr id="section-72"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-72">#</a> </div> <h3>AssignNode</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>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-74"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-74">#</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="s2">&quot;$construct$extension$props$returns&quot;</span></pre></div> </td> </tr> <tr id="section-75"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-75">#</a> </div> <h3>AssignNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-76"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-76">#</a> </div> <p>The <strong>AssignNode</strong> is used to assign a local variable to value, or to set the
property of an object -- including within object literals.</p> </td> <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-77"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-77">#</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">class: </span> <span class="s1">&#39;AssignNode&#39;</span>
@@ -494,7 +519,7 @@ property of an object -- including within object literals.</p> </td>
<span class="k">return</span> <span class="k">new</span> <span class="nx">Expressions</span> <span class="p">[</span><span class="k">this</span><span class="p">,</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="nv">isStatement: </span><span class="o">-&gt;</span>
<span class="nx">@isValue</span><span class="p">()</span> <span class="o">and</span> <span class="p">(</span><span class="nx">@variable</span><span class="p">.</span><span class="nx">isArray</span><span class="p">()</span> <span class="o">or</span> <span class="nx">@variable</span><span class="p">.</span><span class="nx">isObject</span><span class="p">())</span></pre></div> </td> </tr> <tr id="section-75"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-75">#</a> </div> <p>Compile an assignment, delegating to <code>compilePatternMatch</code> or
<span class="nx">@isValue</span><span class="p">()</span> <span class="o">and</span> <span class="p">(</span><span class="nx">@variable</span><span class="p">.</span><span class="nx">isArray</span><span class="p">()</span> <span class="o">or</span> <span class="nx">@variable</span><span class="p">.</span><span class="nx">isObject</span><span class="p">())</span></pre></div> </td> </tr> <tr id="section-78"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-78">#</a> </div> <p>Compile an assignment, delegating to <code>compilePatternMatch</code> or
<code>compileSplice</code> if appropriate. Keep track of the name of the base object
we've been assigned to, for correct internal references. If the variable
has not been seen yet within the current scope, declare it.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compileNode: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
@@ -514,7 +539,7 @@ has not been seen yet within the current scope, declare it.</p> </td
<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="nx">unless</span> <span class="nx">@isValue</span><span class="p">()</span> <span class="o">and</span> <span class="p">(</span><span class="nx">@variable</span><span class="p">.</span><span class="nx">hasProperties</span><span class="p">()</span> <span class="o">or</span> <span class="nx">@variable</span><span class="p">.</span><span class="nx">namespaced</span><span class="p">)</span>
<span class="nv">val: </span><span class="s2">&quot;$name = $val&quot;</span>
<span class="k">return</span> <span class="s2">&quot;$@tab$val;&quot;</span> <span class="k">if</span> <span class="nx">stmt</span>
<span class="k">if</span> <span class="nx">top</span> <span class="k">then</span> <span class="nx">val</span> <span class="k">else</span> <span class="s2">&quot;($val)&quot;</span></pre></div> </td> </tr> <tr id="section-76"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-76">#</a> </div> <p>Brief implementation of recursive pattern matching, when assigning array or
<span class="k">if</span> <span class="nx">top</span> <span class="k">then</span> <span class="nx">val</span> <span class="k">else</span> <span class="s2">&quot;($val)&quot;</span></pre></div> </td> </tr> <tr id="section-79"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-79">#</a> </div> <p>Brief implementation of recursive pattern matching, when assigning array or
object literals to a value. Peeks at their properties to assign inner names.
See the <a href="http://wiki.ecmascript.org/doku.php?id=harmony:destructuring">ECMAScript Harmony Wiki</a>
for details.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compilePatternMatch: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
@@ -524,10 +549,10 @@ for details.</p> </td> <td class="code"> <
<span class="nv">o.top: </span><span class="kc">true</span>
<span class="nv">o.asStatement: </span><span class="kc">true</span>
<span class="nv">splat: </span><span class="kc">false</span>
<span class="k">for</span> <span class="nx">obj</span><span class="p">,</span> <span class="nx">i</span> <span class="k">in</span> <span class="nx">@variable</span><span class="p">.</span><span class="nx">base</span><span class="p">.</span><span class="nx">objects</span></pre></div> </td> </tr> <tr id="section-77"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-77">#</a> </div> <p>A regular array pattern-match.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">idx: </span><span class="nx">i</span>
<span class="k">for</span> <span class="nx">obj</span><span class="p">,</span> <span class="nx">i</span> <span class="k">in</span> <span class="nx">@variable</span><span class="p">.</span><span class="nx">base</span><span class="p">.</span><span class="nx">objects</span></pre></div> </td> </tr> <tr id="section-80"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-80">#</a> </div> <p>A regular array pattern-match.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">idx: </span><span class="nx">i</span>
<span class="k">if</span> <span class="nx">@variable</span><span class="p">.</span><span class="nx">isObject</span><span class="p">()</span>
<span class="k">if</span> <span class="nx">obj</span> <span class="k">instanceof</span> <span class="nx">AssignNode</span></pre></div> </td> </tr> <tr id="section-78"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-78">#</a> </div> <p>A regular object pattern-match.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="p">[</span><span class="nx">obj</span><span class="p">,</span> <span class="nx">idx</span><span class="p">]</span><span class="o">:</span> <span class="p">[</span><span class="nx">obj</span><span class="p">.</span><span class="nx">value</span><span class="p">,</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">variable</span><span class="p">.</span><span class="nx">base</span><span class="p">]</span>
<span class="k">else</span></pre></div> </td> </tr> <tr id="section-79"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-79">#</a> </div> <p>A shorthand <code>{a, b, c}: val</code> pattern-match.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">idx: </span><span class="nx">obj</span>
<span class="k">if</span> <span class="nx">obj</span> <span class="k">instanceof</span> <span class="nx">AssignNode</span></pre></div> </td> </tr> <tr id="section-81"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-81">#</a> </div> <p>A regular object pattern-match.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="p">[</span><span class="nx">obj</span><span class="p">,</span> <span class="nx">idx</span><span class="p">]</span><span class="o">:</span> <span class="p">[</span><span class="nx">obj</span><span class="p">.</span><span class="nx">value</span><span class="p">,</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">variable</span><span class="p">.</span><span class="nx">base</span><span class="p">]</span>
<span class="k">else</span></pre></div> </td> </tr> <tr id="section-82"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-82">#</a> </div> <p>A shorthand <code>{a, b, c}: val</code> pattern-match.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">idx: </span><span class="nx">obj</span>
<span class="k">if</span> <span class="o">not</span> <span class="p">(</span><span class="nx">obj</span> <span class="k">instanceof</span> <span class="nx">ValueNode</span> <span class="o">or</span> <span class="nx">obj</span> <span class="k">instanceof</span> <span class="nx">SplatNode</span><span class="p">)</span>
<span class="k">throw</span> <span class="k">new</span> <span class="nb">Error</span> <span class="s1">&#39;pattern matching must use only identifiers on the left-hand side.&#39;</span>
<span class="nv">isString: </span><span class="nx">idx</span><span class="p">.</span><span class="nx">value</span> <span class="o">and</span> <span class="nx">idx</span><span class="p">.</span><span class="nx">value</span><span class="p">.</span><span class="nx">match</span> <span class="nx">IS_STRING</span>
@@ -542,7 +567,7 @@ for details.</p> </td> <td class="code"> <
<span class="nv">val: </span><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">valVar</span><span class="p">),</span> <span class="p">[</span><span class="k">new</span> <span class="nx">accessClass</span><span class="p">(</span><span class="nx">idx</span><span class="p">)])</span>
<span class="nx">assigns</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="k">new</span> <span class="nx">AssignNode</span><span class="p">(</span><span class="nx">obj</span><span class="p">,</span> <span class="nx">val</span><span class="p">).</span><span class="nx">compile</span><span class="p">(</span><span class="nx">o</span><span class="p">))</span>
<span class="nv">code: </span><span class="nx">assigns</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>
<span class="nx">code</span></pre></div> </td> </tr> <tr id="section-80"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-80">#</a> </div> <p>Compile the assignment from an array splice literal, using JavaScript's
<span class="nx">code</span></pre></div> </td> </tr> <tr id="section-83"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-83">#</a> </div> <p>Compile the assignment from an array splice literal, using JavaScript's
<code>Array#splice</code> method.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compileSplice: </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">@variable</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">onlyFirst: </span><span class="kc">true</span><span class="p">}</span>
<span class="nv">l: </span> <span class="nx">@variable</span><span class="p">.</span><span class="nx">properties</span><span class="p">.</span><span class="nx">length</span>
@@ -551,7 +576,7 @@ 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-81"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-81">#</a> </div> <h3>CodeNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-82"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-82">#</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></pre></div> </td> </tr> <tr id="section-84"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-84">#</a> </div> <h3>CodeNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-85"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-85">#</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>
@@ -560,8 +585,8 @@ has no <em>children</em> -- they're within the inner scope.</p> </td
<span class="nv">constructor: </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">tag</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="vi">@params: </span> <span class="nx">params</span> <span class="o">or</span> <span class="p">[]</span>
<span class="vi">@body: </span> <span class="nx">body</span> <span class="o">or</span> <span class="k">new</span> <span class="nx">Expressions</span><span class="p">()</span>
<span class="vi">@bound: </span> <span class="nx">tag</span> <span class="o">is</span> <span class="s1">&#39;boundfunc&#39;</span></pre></div> </td> </tr> <tr id="section-83"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-83">#</a> </div> <p>Compilation creates a new scope unless explicitly asked to share with the
<span class="vi">@body: </span> <span class="nx">body</span> <span class="o">or</span> <span class="k">new</span> <span class="nx">Expressions</span>
<span class="vi">@bound: </span> <span class="nx">tag</span> <span class="o">is</span> <span class="s1">&#39;boundfunc&#39;</span></pre></div> </td> </tr> <tr id="section-86"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-86">#</a> </div> <p>Compilation creates a new scope unless explicitly asked to share with the
outer scope. Handles splat parameters in the parameter list by peeking at
the JavaScript <code>arguments</code> objects. If the function is bound with the <code>=&gt;</code>
arrow, generates a wrapper that saves the current value of <code>this</code> through
@@ -599,13 +624,13 @@ a closure.</p> </td> <td class="code"> <di
<span class="s2">&quot;(function(__this) {\n${@idt(1)}var __func = $func;\n${@idt(1)}return $inner\n$@tab})(this)&quot;</span>
<span class="nv">topSensitive: </span><span class="o">-&gt;</span>
<span class="kc">true</span></pre></div> </td> </tr> <tr id="section-84"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-84">#</a> </div> <p>Short-circuit traverseChildren method to prevent it from crossing scope boundaries
<span class="kc">true</span></pre></div> </td> </tr> <tr id="section-87"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-87">#</a> </div> <p>Short-circuit traverseChildren method to prevent it from crossing scope boundaries
unless crossScope is true</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">traverseChildren: </span><span class="p">(</span><span class="nx">crossScope</span><span class="p">,</span> <span class="nx">func</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="k">super</span><span class="p">(</span><span class="nx">crossScope</span><span class="p">,</span> <span class="nx">func</span><span class="p">)</span> <span class="k">if</span> <span class="nx">crossScope</span>
<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">@collectChildren</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-85"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-85">#</a> </div> <h3>SplatNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-86"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-86">#</a> </div> <p>A splat, either as a parameter to a function, an argument to a call,
<span class="s2">&quot;\n$idt$children&quot;</span></pre></div> </td> </tr> <tr id="section-88"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-88">#</a> </div> <h3>SplatNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-89"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-89">#</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">class: </span> <span class="s1">&#39;SplatNode&#39;</span>
@@ -616,7 +641,7 @@ or as part of a destructuring assignment.</p> </td> <td
<span class="vi">@name: </span><span class="nx">name</span>
<span class="nv">compileNode: </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">@compileParam</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-87"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-87">#</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">@compileParam</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-90"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-90">#</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">compileParam: </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>
@@ -627,10 +652,10 @@ the splat in the parameter list, by slicing the arguments object.</p>
<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-88"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-88">#</a> </div> <p>A compiling a splat as a destructuring assignment means slicing arguments
<span class="s2">&quot;$name = ${utility(&#39;slice&#39;)}.call(arguments, $@index, $len - ${@trailings.length})&quot;</span></pre></div> </td> </tr> <tr id="section-91"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-91">#</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">compileValue: </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-89"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-89">#</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-92"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-92">#</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">@compileMixedArray: </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>
@@ -648,7 +673,7 @@ 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-90"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-90">#</a> </div> <h3>WhileNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-91"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-91">#</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></pre></div> </td> </tr> <tr id="section-93"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-93">#</a> </div> <h3>WhileNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-94"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-94">#</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>
@@ -672,7 +697,7 @@ flexibility or more speed than a comprehension can provide.</p> </td
<span class="k">this</span>
<span class="nv">topSensitive: </span><span class="o">-&gt;</span>
<span class="kc">true</span></pre></div> </td> </tr> <tr id="section-92"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-92">#</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-95"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-95">#</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">compileNode: </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>
@@ -690,12 +715,12 @@ return an array containing the computed result of each iteration.</p>
<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}$post&quot;</span></pre></div> </td> </tr> <tr id="section-93"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-93">#</a> </div> <h3>OpNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-94"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-94">#</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-95"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-95">#</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="s2">&quot;$pre {\n${ @body.compile(o) }\n$@tab}$post&quot;</span></pre></div> </td> </tr> <tr id="section-96"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-96">#</a> </div> <h3>OpNode</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>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-98"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-98">#</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-96"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-96">#</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-97"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-97">#</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-98"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-98">#</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-99"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-99">#</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-100"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-100">#</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-101"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-101">#</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">class: </span> <span class="s1">&#39;OpNode&#39;</span>
<span class="nv">children: </span><span class="p">[</span><span class="s1">&#39;first&#39;</span><span class="p">,</span> <span class="s1">&#39;second&#39;</span><span class="p">]</span>
@@ -712,13 +737,16 @@ CoffeeScript operations into their JavaScript equivalents.</p> </td>
<span class="nv">isChainable: </span><span class="o">-&gt;</span>
<span class="nx">indexOf</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">toString: </span><span class="p">(</span><span class="nx">idt</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="k">super</span><span class="p">(</span><span class="nx">idt</span><span class="p">,</span> <span class="nx">@class</span> <span class="o">+</span> <span class="s1">&#39; &#39;</span> <span class="o">+</span> <span class="nx">@operator</span><span class="p">)</span>
<span class="nv">compileNode: </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">@compileChain</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="k">if</span> <span class="nx">@isChainable</span><span class="p">()</span> <span class="o">and</span> <span class="nx">@first</span><span class="p">.</span><span class="nx">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">isChainable</span><span class="p">()</span>
<span class="k">return</span> <span class="nx">@compileAssignment</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="k">if</span> <span class="nx">indexOf</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">@compileUnary</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="k">if</span> <span class="nx">@isUnary</span><span class="p">()</span>
<span class="k">return</span> <span class="nx">@compileExistence</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-99"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-99">#</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-102"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-102">#</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"
@@ -727,21 +755,21 @@ 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">compileReference</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">containsType</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-100"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-100">#</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-103"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-103">#</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">compileAssignment: </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.compileTest(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-101"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-101">#</a> </div> <p>If this is an existence operator, we delegate to <code>ExistenceNode.compileTest</code>
<span class="s2">&quot;$first = $first ${ @operator.substr(0, 2) } $second&quot;</span></pre></div> </td> </tr> <tr id="section-104"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-104">#</a> </div> <p>If this is an existence operator, we delegate to <code>ExistenceNode.compileTest</code>
to give us the safe references for the variables.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compileExistence: </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">compileTest</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-102"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-102">#</a> </div> <p>Compile a unary <strong>OpNode</strong>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compileUnary: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="s2">&quot;$test ? $first : $second&quot;</span></pre></div> </td> </tr> <tr id="section-105"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-105">#</a> </div> <p>Compile a unary <strong>OpNode</strong>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compileUnary: </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">indexOf</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-103"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-103">#</a> </div> <h3>InNode</h3> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.InNode: </span><span class="nx">class</span> <span class="nx">InNode</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></pre></div> </td> </tr> <tr id="section-106"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-106">#</a> </div> <h3>InNode</h3> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.InNode: </span><span class="nx">class</span> <span class="nx">InNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span>
<span class="nv">class: </span> <span class="s1">&#39;InNode&#39;</span>
<span class="nv">children: </span><span class="p">[</span><span class="s1">&#39;object&#39;</span><span class="p">,</span> <span class="s1">&#39;array&#39;</span><span class="p">]</span>
@@ -766,7 +794,7 @@ to give us the safe references for the variables.</p> </td>
<span class="p">[</span><span class="nx">@arr1</span><span class="p">,</span> <span class="nx">@arr2</span><span class="p">]</span><span class="o">:</span> <span class="nx">@array</span><span class="p">.</span><span class="nx">compileReference</span> <span class="nx">o</span><span class="p">,</span> <span class="p">{</span><span class="nv">precompile: </span><span class="kc">yes</span><span class="p">}</span>
<span class="p">[</span><span class="nx">i</span><span class="p">,</span> <span class="nx">l</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">freeVariable</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">freeVariable</span><span class="p">()]</span>
<span class="nv">prefix: </span><span class="k">if</span> <span class="nx">@obj1</span> <span class="o">isnt</span> <span class="nx">@obj2</span> <span class="k">then</span> <span class="nx">@obj1</span> <span class="o">+</span> <span class="s1">&#39;; &#39;</span> <span class="k">else</span> <span class="s1">&#39;&#39;</span>
<span class="s2">&quot;!!(function(){ ${prefix}for (var $i=0, $l=${@arr1}.length; $i&lt;$l; $i++) if (${@arr2}[$i] === $@obj2) return true; })()&quot;</span></pre></div> </td> </tr> <tr id="section-104"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-104">#</a> </div> <h3>TryNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-105"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-105">#</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="s2">&quot;!!(function(){ ${prefix}for (var $i=0, $l=${@arr1}.length; $i&lt;$l; $i++) if (${@arr2}[$i] === $@obj2) return true; }).call(this)&quot;</span></pre></div> </td> </tr> <tr id="section-107"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-107">#</a> </div> <h3>TryNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-108"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-108">#</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">class: </span> <span class="s1">&#39;TryNode&#39;</span>
<span class="nv">children: </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><span class="p">]</span>
@@ -781,7 +809,7 @@ to give us the safe references for the variables.</p> </td>
<span class="nv">makeReturn: </span><span class="o">-&gt;</span>
<span class="vi">@attempt: </span><span class="nx">@attempt</span><span class="p">.</span><span class="nx">makeReturn</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">makeReturn</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-106"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-106">#</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-109"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-109">#</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">compileNode: </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>
@@ -789,18 +817,18 @@ is optional, the <em>catch</em> is not.</p> </td> <td cl
<span class="nv">errorPart: </span> <span class="k">if</span> <span class="nx">@error</span> <span class="k">then</span> <span class="s2">&quot; (${ @error.compile(o) }) &quot;</span> <span class="k">else</span> <span class="s1">&#39; &#39;</span>
<span class="nv">catchPart: </span> <span class="k">if</span> <span class="nx">@recovery</span> <span class="k">then</span> <span class="s2">&quot; catch$errorPart{\n${ @recovery.compile(o) }\n$@tab}&quot;</span> <span class="k">else</span> <span class="s1">&#39;&#39;</span>
<span class="nv">finallyPart: </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$attemptPart\n$@tab}$catchPart$finallyPart&quot;</span></pre></div> </td> </tr> <tr id="section-107"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-107">#</a> </div> <h3>ThrowNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-108"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-108">#</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="s2">&quot;${@tab}try {\n$attemptPart\n$@tab}$catchPart$finallyPart&quot;</span></pre></div> </td> </tr> <tr id="section-110"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-110">#</a> </div> <h3>ThrowNode</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>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">class: </span> <span class="s1">&#39;ThrowNode&#39;</span>
<span class="nv">children: </span> <span class="p">[</span><span class="s1">&#39;expression&#39;</span><span class="p">]</span>
<span class="nv">isStatement: </span><span class="o">-&gt;</span> <span class="kc">yes</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">@expression: </span><span class="nx">expression</span></pre></div> </td> </tr> <tr id="section-109"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-109">#</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">makeReturn: </span><span class="o">-&gt;</span>
<span class="vi">@expression: </span><span class="nx">expression</span></pre></div> </td> </tr> <tr id="section-112"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-112">#</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">makeReturn: </span><span class="o">-&gt;</span>
<span class="k">return</span> <span class="k">this</span>
<span class="nv">compileNode: </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></pre></div> </td> </tr> <tr id="section-110"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-110">#</a> </div> <h3>ExistenceNode</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>Checks a variable for existence -- not <em>null</em> and not <em>undefined</em>. This is
<span class="s2">&quot;${@tab}throw ${@expression.compile(o)};&quot;</span></pre></div> </td> </tr> <tr id="section-113"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-113">#</a> </div> <h3>ExistenceNode</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>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>
@@ -811,11 +839,11 @@ table.</p> </td> <td class="code"> <div cl
<span class="vi">@expression: </span><span class="nx">expression</span>
<span class="nv">compileNode: </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">compileTest</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-112"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-112">#</a> </div> <p>The meat of the <strong>ExistenceNode</strong> is in this static <code>compileTest</code> method
<span class="nx">ExistenceNode</span><span class="p">.</span><span class="nx">compileTest</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-115"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-115">#</a> </div> <p>The meat of the <strong>ExistenceNode</strong> is in this static <code>compileTest</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">@compileTest: </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="nx">variable</span><span class="p">.</span><span class="nx">compileReference</span> <span class="nx">o</span>
<span class="s2">&quot;(typeof ${first.compile(o)} !== \&quot;undefined\&quot; &amp;&amp; ${second.compile(o)} !== null)&quot;</span></pre></div> </td> </tr> <tr id="section-113"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-113">#</a> </div> <h3>ParentheticalNode</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>An extra set of parentheses, specified explicitly in the source. At one time
<span class="s2">&quot;(typeof ${first.compile(o)} !== \&quot;undefined\&quot; &amp;&amp; ${second.compile(o)} !== null)&quot;</span></pre></div> </td> </tr> <tr id="section-116"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-116">#</a> </div> <h3>ParentheticalNode</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>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>
@@ -833,12 +861,17 @@ parentheses, but no longer -- you can put in as many as you please.</p>
<span class="nv">makeReturn: </span><span class="o">-&gt;</span>
<span class="nx">@expression</span><span class="p">.</span><span class="nx">makeReturn</span><span class="p">()</span>
<span class="nv">topSensitive: </span><span class="o">-&gt;</span>
<span class="kc">yes</span>
<span class="nv">compileNode: </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="nx">o</span><span class="p">,</span> <span class="s1">&#39;top&#39;</span>
<span class="nv">code: </span><span class="nx">@expression</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">return</span> <span class="nx">code</span> <span class="k">if</span> <span class="nx">@isStatement</span><span class="p">()</span>
<span class="k">if</span> <span class="nx">@isStatement</span><span class="p">()</span>
<span class="k">return</span> <span class="p">(</span><span class="k">if</span> <span class="nx">top</span> <span class="k">then</span> <span class="s2">&quot;$@tab$code;&quot;</span> <span class="k">else</span> <span class="nx">code</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-115"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-115">#</a> </div> <h3>ForNode</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>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></pre></div> </td> </tr> <tr id="section-118"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-118">#</a> </div> <h3>ForNode</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>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>
@@ -873,7 +906,7 @@ you can map and filter in a single pass.</p> </td> <td c
<span class="nv">compileReturnValue: </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="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-117"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-117">#</a> </div> <p>Welcome to the hairiest method in all of CoffeeScript. Handles the inner
<span class="s1">&#39;&#39;</span></pre></div> </td> </tr> <tr id="section-120"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-120">#</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">compileNode: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
@@ -891,13 +924,14 @@ some cannot.</p> </td> <td class="code"> <
<span class="nv">varPart: </span> <span class="s1">&#39;&#39;</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">@body</span><span class="p">])</span>
<span class="k">if</span> <span class="nx">range</span>
<span class="nv">sourcePart: </span> <span class="nx">source</span><span class="p">.</span><span class="nx">compileVariables</span> <span class="nx">o</span>
<span class="nv">sourcePart: </span> <span class="nx">source</span><span class="p">.</span><span class="nx">compileVariables</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span>
<span class="nv">sourcePart: </span> <span class="o">+</span> <span class="s2">&quot;\n$o.indent&quot;</span> <span class="k">if</span> <span class="nx">sourcePart</span>
<span class="nv">forPart: </span> <span class="nx">source</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">index: </span><span class="nx">ivar</span><span class="p">,</span> <span class="nv">step: </span><span class="nx">@step</span><span class="p">}</span>
<span class="k">else</span>
<span class="nv">svar: </span> <span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span><span class="p">()</span>
<span class="nv">sourcePart: </span> <span class="s2">&quot;$svar = ${ @source.compile(o) };&quot;</span>
<span class="k">if</span> <span class="nx">@pattern</span>
<span class="nv">namePart: </span> <span class="k">new</span> <span class="nx">AssignNode</span><span class="p">(</span><span class="nx">@name</span><span class="p">,</span> <span class="nx">literal</span><span class="p">(</span><span class="s2">&quot;$svar[$ivar]&quot;</span><span class="p">)).</span><span class="nx">compile</span><span class="p">(</span><span class="nx">merge</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="mi">1</span><span class="p">),</span> <span class="nv">top: </span><span class="kc">true</span><span class="p">})</span> <span class="o">+</span> <span class="s2">&quot;\n&quot;</span>
<span class="nv">namePart: </span> <span class="k">new</span> <span class="nx">AssignNode</span><span class="p">(</span><span class="nx">@name</span><span class="p">,</span> <span class="nx">literal</span><span class="p">(</span><span class="s2">&quot;$svar[$ivar]&quot;</span><span class="p">)).</span><span class="nx">compile</span><span class="p">(</span><span class="nx">merge</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="mi">1</span><span class="p">),</span> <span class="nv">top: </span><span class="kc">true</span><span class="p">})</span> <span class="o">+</span> <span class="s1">&#39;\n&#39;</span>
<span class="k">else</span>
<span class="nv">namePart: </span> <span class="s2">&quot;$name = $svar[$ivar]&quot;</span> <span class="k">if</span> <span class="nx">name</span>
<span class="nx">unless</span> <span class="nx">@object</span>
@@ -916,13 +950,13 @@ some cannot.</p> </td> <td class="code"> <
<span class="nx">body</span><span class="p">.</span><span class="nx">unshift</span> <span class="nx">literal</span> <span class="s2">&quot;var $index = $ivar&quot;</span> <span class="k">if</span> <span class="nx">index</span>
<span class="nv">body: </span> <span class="nx">ClosureNode</span><span class="p">.</span><span class="nx">wrap</span><span class="p">(</span><span class="nx">body</span><span class="p">,</span> <span class="kc">true</span><span class="p">)</span>
<span class="k">else</span>
<span class="nv">varPart: </span> <span class="s2">&quot;${@idt(1)}$namePart;\n&quot;</span> <span class="k">if</span> <span class="nx">namePart</span>
<span class="nv">varPart: </span> <span class="p">(</span><span class="nx">namePart</span> <span class="o">or</span> <span class="s1">&#39;&#39;</span><span class="p">)</span> <span class="o">and</span> <span class="p">(</span><span class="k">if</span> <span class="nx">@pattern</span> <span class="k">then</span> <span class="nx">namePart</span> <span class="k">else</span> <span class="s2">&quot;${@idt(1)}$namePart;\n&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="nx">@object</span>
<span class="nv">forPart: </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">@idt</span><span class="p">(</span><span class="mi">1</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;}}&#39;</span> <span class="k">else</span> <span class="s1">&#39;}&#39;</span>
<span class="s2">&quot;${sourcePart}for ($forPart) {\n$varPart$body\n$@tab$close$returnResult&quot;</span></pre></div> </td> </tr> <tr id="section-118"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-118">#</a> </div> <h3>IfNode</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><em>If/else</em> statements. Our <em>switch/when</em> will be compiled into this. Acts as an
<span class="s2">&quot;${sourcePart}for ($forPart) {\n$varPart$body\n$@tab$close$returnResult&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>IfNode</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><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,
@@ -934,20 +968,20 @@ because ternaries are already proper expressions, and don't need conversion.</p>
<span class="nv">constructor: </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">tags</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="vi">@condition: </span><span class="nx">condition</span>
<span class="vi">@body: </span> <span class="nx">body</span>
<span class="vi">@elseBody: </span><span class="kc">null</span>
<span class="vi">@elseBody: </span> <span class="kc">null</span>
<span class="vi">@tags: </span> <span class="nx">tags</span> <span class="o">or</span> <span class="p">{}</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">@isChain: </span> <span class="kc">false</span>
<span class="vi">@isChain: </span> <span class="kc">false</span>
<span class="nv">bodyNode: </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">elseBodyNode: </span><span class="o">-&gt;</span> <span class="nx">@elseBody</span><span class="o">?</span><span class="p">.</span><span class="nx">unwrap</span><span class="p">()</span>
<span class="nv">forceStatement: </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-120"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-120">#</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-123"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-123">#</a> </div> <p>Tag a chain of <strong>IfNodes</strong> with their object(s) to switch on for equality
tests. <code>rewriteSwitch</code> will perform the actual change at compile time.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">switchesOver: </span><span class="p">(</span><span class="nx">expression</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="vi">@switchSubject: </span><span class="nx">expression</span>
<span class="k">this</span></pre></div> </td> </tr> <tr id="section-121"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-121">#</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-124"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-124">#</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">rewriteSwitch: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="vi">@assigner: </span><span class="nx">@switchSubject</span>
<span class="nx">unless</span> <span class="p">(</span><span class="nx">@switchSubject</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>
@@ -957,14 +991,14 @@ Ensure that the switch expression isn't evaluated more than once.</p>
<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">@switchSubject</span><span class="p">),</span> <span class="nx">cond</span><span class="p">)</span>
<span class="nx">@elseBodyNode</span><span class="p">().</span><span class="nx">switchesOver</span><span class="p">(</span><span class="nx">@switchSubject</span><span class="p">)</span> <span class="k">if</span> <span class="nx">@isChain</span></pre></div> </td> </tr> <tr id="section-122"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-122">#</a> </div> <p>prevent this rewrite from happening again</p> </td> <td class="code"> <div class="highlight"><pre> <span class="vi">@switchSubject: </span><span class="kc">undefined</span>
<span class="k">this</span></pre></div> </td> </tr> <tr id="section-123"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-123">#</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">addElse: </span><span class="p">(</span><span class="nx">elseBody</span><span class="p">,</span> <span class="nx">statement</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nx">@elseBodyNode</span><span class="p">().</span><span class="nx">switchesOver</span><span class="p">(</span><span class="nx">@switchSubject</span><span class="p">)</span> <span class="k">if</span> <span class="nx">@isChain</span></pre></div> </td> </tr> <tr id="section-125"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-125">#</a> </div> <p>prevent this rewrite from happening again</p> </td> <td class="code"> <div class="highlight"><pre> <span class="vi">@switchSubject: </span><span class="kc">undefined</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>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">addElse: </span><span class="p">(</span><span class="nx">elseBody</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">@isChain</span>
<span class="nx">@elseBodyNode</span><span class="p">().</span><span class="nx">addElse</span> <span class="nx">elseBody</span><span class="p">,</span> <span class="nx">statement</span>
<span class="k">else</span>
<span class="vi">@isChain: </span><span class="nx">elseBody</span> <span class="k">instanceof</span> <span class="nx">IfNode</span>
<span class="vi">@elseBody: </span><span class="nx">@ensureExpressions</span> <span class="nx">elseBody</span>
<span class="k">this</span></pre></div> </td> </tr> <tr id="section-124"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-124">#</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-127"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-127">#</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">isStatement: </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">@tags</span><span class="p">.</span><span class="nx">statement</span> <span class="o">or</span> <span class="nx">@bodyNode</span><span class="p">().</span><span class="nx">isStatement</span><span class="p">()</span> <span class="o">or</span> <span class="p">(</span><span class="nx">@elseBody</span> <span class="o">and</span> <span class="nx">@elseBodyNode</span><span class="p">().</span><span class="nx">isStatement</span><span class="p">()))</span>
@@ -975,12 +1009,15 @@ to be a statement. Otherwise a ternary is safe.</p> </td>
<span class="k">if</span> <span class="nx">@isStatement</span><span class="p">()</span> <span class="k">then</span> <span class="nx">@compileStatement</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="k">else</span> <span class="nx">@compileTernary</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span>
<span class="nv">makeReturn: </span><span class="o">-&gt;</span>
<span class="vi">@body: </span> <span class="o">and</span> <span class="nx">@ensureExpressions</span><span class="p">(</span><span class="nx">@body</span><span class="p">.</span><span class="nx">makeReturn</span><span class="p">())</span>
<span class="vi">@elseBody: </span> <span class="o">and</span> <span class="nx">@ensureExpressions</span><span class="p">(</span><span class="nx">@elseBody</span><span class="p">.</span><span class="nx">makeReturn</span><span class="p">())</span>
<span class="k">this</span>
<span class="k">if</span> <span class="nx">@isStatement</span><span class="p">()</span>
<span class="vi">@body: </span> <span class="o">and</span> <span class="nx">@ensureExpressions</span><span class="p">(</span><span class="nx">@body</span><span class="p">.</span><span class="nx">makeReturn</span><span class="p">())</span>
<span class="vi">@elseBody: </span> <span class="o">and</span> <span class="nx">@ensureExpressions</span><span class="p">(</span><span class="nx">@elseBody</span><span class="p">.</span><span class="nx">makeReturn</span><span class="p">())</span>
<span class="k">this</span>
<span class="k">else</span>
<span class="k">new</span> <span class="nx">ReturnNode</span> <span class="k">this</span>
<span class="nv">ensureExpressions: </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">node</span> <span class="k">instanceof</span> <span class="nx">Expressions</span> <span class="k">then</span> <span class="nx">node</span> <span class="k">else</span> <span class="k">new</span> <span class="nx">Expressions</span> <span class="p">[</span><span class="nx">node</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-125"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-125">#</a> </div> <p>Compile the <strong>IfNode</strong> as a regular <em>if-else</em> statement. Flattened chains
<span class="k">if</span> <span class="nx">node</span> <span class="k">instanceof</span> <span class="nx">Expressions</span> <span class="k">then</span> <span class="nx">node</span> <span class="k">else</span> <span class="k">new</span> <span class="nx">Expressions</span> <span class="p">[</span><span class="nx">node</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-128"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-128">#</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">compileStatement: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nx">@rewriteSwitch</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="k">if</span> <span class="nx">@switchSubject</span>
<span class="nv">child: </span> <span class="nx">del</span> <span class="nx">o</span><span class="p">,</span> <span class="s1">&#39;chainChild&#39;</span>
@@ -996,10 +1033,10 @@ 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">@elseBodyNode</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">chainChild: </span><span class="kc">true</span><span class="p">}))</span>
<span class="k">else</span>
<span class="s2">&quot; else {\n${ @elseBody.compile(o) }\n$@tab}&quot;</span>
<span class="s2">&quot;$ifPart$elsePart&quot;</span></pre></div> </td> </tr> <tr id="section-126"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-126">#</a> </div> <p>Compile the IfNode as a ternary operator.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compileTernary: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="s2">&quot;$ifPart$elsePart&quot;</span></pre></div> </td> </tr> <tr id="section-129"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-129">#</a> </div> <p>Compile the IfNode as a ternary operator.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compileTernary: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">ifPart: </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">@bodyNode</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">elsePart: </span> <span class="k">if</span> <span class="nx">@elseBody</span> <span class="k">then</span> <span class="nx">@elseBodyNode</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;$ifPart : $elsePart&quot;</span></pre></div> </td> </tr> <tr id="section-127"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-127">#</a> </div> <h2>Faux-Nodes</h2> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-128"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-128">#</a> </div> <h3>PushNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-129"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-129">#</a> </div> <p>Faux-nodes are never created by the grammar, but are used during code
<span class="s2">&quot;$ifPart : $elsePart&quot;</span></pre></div> </td> </tr> <tr id="section-130"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-130">#</a> </div> <h2>Faux-Nodes</h2> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-131"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-131">#</a> </div> <h3>PushNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-132"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-132">#</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>
@@ -1011,14 +1048,17 @@ 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-130"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-130">#</a> </div> <h3>ClosureNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-131"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-131">#</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-132"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-132">#</a> </div> <p>Wrap the expressions body, unless it contains a pure statement,
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-133"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-133">#</a> </div> <h3>ClosureNode</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>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-135"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-135">#</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">containsPureStatement</span><span class="p">()</span>
<span class="nv">func: </span><span class="k">new</span> <span class="nx">ParentheticalNode</span><span class="p">(</span><span class="k">new</span> <span class="nx">CodeNode</span><span class="p">([],</span> <span class="nx">Expressions</span><span class="p">.</span><span class="nx">wrap</span><span class="p">([</span><span class="nx">expressions</span><span class="p">])))</span>
<span class="nv">args: </span><span class="p">[]</span>
<span class="nv">mentionsArgs: </span><span class="nx">expressions</span><span class="p">.</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="p">(</span><span class="nx">n</span> <span class="k">instanceof</span> <span class="nx">LiteralNode</span><span class="p">)</span> <span class="o">and</span> <span class="p">(</span><span class="nx">n</span><span class="p">.</span><span class="nx">value</span> <span class="o">is</span> <span class="s1">&#39;arguments&#39;</span><span class="p">)</span>
<span class="nv">mentionsThis: </span><span class="nx">expressions</span><span class="p">.</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="p">(</span><span class="nx">n</span> <span class="k">instanceof</span> <span class="nx">LiteralNode</span><span class="p">)</span> <span class="o">and</span> <span class="p">(</span><span class="nx">n</span><span class="p">.</span><span class="nx">value</span> <span class="o">is</span> <span class="s1">&#39;this&#39;</span><span class="p">)</span>
<span class="nv">mentionsArgs: </span><span class="nx">expressions</span><span class="p">.</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">LiteralNode</span> <span class="o">and</span> <span class="p">(</span><span class="nx">n</span><span class="p">.</span><span class="nx">value</span> <span class="o">is</span> <span class="s1">&#39;arguments&#39;</span><span class="p">)</span>
<span class="nv">mentionsThis: </span><span class="nx">expressions</span><span class="p">.</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="p">(</span><span class="nx">n</span> <span class="k">instanceof</span> <span class="nx">LiteralNode</span> <span class="o">and</span> <span class="p">(</span><span class="nx">n</span><span class="p">.</span><span class="nx">value</span> <span class="o">is</span> <span class="s1">&#39;this&#39;</span><span class="p">))</span> <span class="o">or</span>
<span class="p">(</span><span class="nx">n</span> <span class="k">instanceof</span> <span class="nx">CodeNode</span> <span class="o">and</span> <span class="nx">n</span><span class="p">.</span><span class="nx">bound</span><span class="p">)</span>
<span class="k">if</span> <span class="nx">mentionsArgs</span> <span class="o">or</span> <span class="nx">mentionsThis</span>
<span class="nv">meth: </span><span class="nx">literal</span><span class="p">(</span><span class="k">if</span> <span class="nx">mentionsArgs</span> <span class="k">then</span> <span class="s1">&#39;apply&#39;</span> <span class="k">else</span> <span class="s1">&#39;call&#39;</span><span class="p">)</span>
<span class="nv">args: </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>
@@ -1027,7 +1067,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-133"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-133">#</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-134"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-134">#</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-136"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-136">#</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-137"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-137">#</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/closureGoogBase.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>
@@ -1037,13 +1077,13 @@ 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-135"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-135">#</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-138"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-138">#</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-136"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-136">#</a> </div> <h2>Constants</h2> </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>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-138"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-138">#</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-139"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-139">#</a> </div> <p>Obvious redundant parentheses should be removed.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">DOUBLE_PARENS: </span><span class="sr">/\(\(([^\(\)\n]*)\)\)/g</span></pre></div> </td> </tr> <tr id="section-140"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-140">#</a> </div> <p>Keep these identifier regexes 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>
<span class="nv">NUMBER : </span><span class="sr">/^(((\b0(x|X)[0-9a-fA-F]+)|((\b[0-9]+(\.[0-9]+)?|\.[0-9]+)(e[+\-]?[0-9]+)?)))\b$/i</span></pre></div> </td> </tr> <tr id="section-141"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-141">#</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-142"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-142">#</a> </div> <h2>Utility Functions</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>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-144"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-144">#</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-139"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-139">#</a> </div> <h2>Constants</h2> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-140"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-140">#</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-141"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-141">#</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-142"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-142">#</a> </div> <p>Obvious redundant parentheses should be removed.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">DOUBLE_PARENS: </span><span class="sr">/\(\(([^\(\)\n]*)\)\)/g</span></pre></div> </td> </tr> <tr id="section-143"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-143">#</a> </div> <p>Keep these identifier regexes 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>
<span class="nv">NUMBER : </span><span class="sr">/^(((\b0(x|X)[0-9a-fA-F]+)|((\b[0-9]+(\.[0-9]+)?|\.[0-9]+)(e[+\-]?[0-9]+)?)))\b$/i</span></pre></div> </td> </tr> <tr id="section-144"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-144">#</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-145"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-145">#</a> </div> <h2>Utility Functions</h2> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-146"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-146">#</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-147"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-147">#</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

@@ -3,7 +3,10 @@ Use it like so:</p>
<pre><code>parser: new OptionParser switches, helpBanner
options: parser.parse process.argv
</code></pre> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.OptionParser: </span><span class="nx">class</span> <span class="nx">OptionParser</span></pre></div> </td> </tr> <tr id="section-2"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-2">#</a> </div> <p>Initialize with a list of valid options, in the form:</p>
</code></pre>
<p>The first non-option is considered to be the start of the file (and file
option) list, and all subsequent arguments are left unparsed.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.OptionParser: </span><span class="nx">class</span> <span class="nx">OptionParser</span></pre></div> </td> </tr> <tr id="section-2"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-2">#</a> </div> <p>Initialize with a list of valid options, in the form:</p>
<pre><code>[short-flag, long-flag, description]
</code></pre>
@@ -17,16 +20,18 @@ many option parsers that allow you to attach callback actions for every
flag. Instead, you're responsible for interpreting the options object.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">parse: </span><span class="p">(</span><span class="nx">args</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">options: </span><span class="p">{</span><span class="nv">arguments: </span><span class="p">[]}</span>
<span class="nv">args: </span><span class="nx">normalizeArguments</span> <span class="nx">args</span>
<span class="k">while</span> <span class="p">(</span><span class="nv">arg: </span><span class="nx">args</span><span class="p">.</span><span class="nx">shift</span><span class="p">())</span>
<span class="k">for</span> <span class="nx">arg</span><span class="p">,</span> <span class="nx">i</span> <span class="k">in</span> <span class="nx">args</span>
<span class="nv">isOption: </span><span class="o">!!</span><span class="p">(</span><span class="nx">arg</span><span class="p">.</span><span class="nx">match</span><span class="p">(</span><span class="nx">LONG_FLAG</span><span class="p">)</span> <span class="o">or</span> <span class="nx">arg</span><span class="p">.</span><span class="nx">match</span><span class="p">(</span><span class="nx">SHORT_FLAG</span><span class="p">))</span>
<span class="nv">matchedRule: </span><span class="kc">no</span>
<span class="k">for</span> <span class="nx">rule</span> <span class="k">in</span> <span class="nx">@rules</span>
<span class="k">if</span> <span class="nx">rule</span><span class="p">.</span><span class="nx">shortFlag</span> <span class="o">is</span> <span class="nx">arg</span> <span class="o">or</span> <span class="nx">rule</span><span class="p">.</span><span class="nx">longFlag</span> <span class="o">is</span> <span class="nx">arg</span>
<span class="nx">options</span><span class="p">[</span><span class="nx">rule</span><span class="p">.</span><span class="nx">name</span><span class="p">]</span><span class="o">:</span> <span class="k">if</span> <span class="nx">rule</span><span class="p">.</span><span class="nx">hasArgument</span> <span class="k">then</span> <span class="nx">args</span><span class="p">.</span><span class="nx">shift</span><span class="p">()</span> <span class="k">else</span> <span class="kc">true</span>
<span class="nx">options</span><span class="p">[</span><span class="nx">rule</span><span class="p">.</span><span class="nx">name</span><span class="p">]</span><span class="o">:</span> <span class="k">if</span> <span class="nx">rule</span><span class="p">.</span><span class="nx">hasArgument</span> <span class="k">then</span> <span class="nx">args</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="k">else</span> <span class="kc">true</span>
<span class="nv">matchedRule: </span><span class="kc">yes</span>
<span class="k">break</span>
<span class="k">throw</span> <span class="k">new</span> <span class="nb">Error</span> <span class="s2">&quot;unrecognized option: $arg&quot;</span> <span class="k">if</span> <span class="nx">isOption</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">matchedRule</span>
<span class="nx">options</span><span class="p">.</span><span class="nx">arguments</span><span class="p">.</span><span class="nx">push</span> <span class="nx">arg</span> <span class="nx">unless</span> <span class="nx">isOption</span>
<span class="k">if</span> <span class="o">not</span> <span class="nx">isOption</span>
<span class="nv">options.arguments: </span><span class="nx">args</span><span class="p">[</span><span class="nx">i</span><span class="p">...</span><span class="nx">args</span><span class="p">.</span><span class="nx">length</span><span class="p">]</span>
<span class="k">break</span>
<span class="nx">options</span></pre></div> </td> </tr> <tr id="section-4"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-4">#</a> </div> <p>Return the help text for this <strong>OptionParser</strong>, listing and describing all
of the valid options, for <code>--help</code> and such.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">help: </span><span class="o">-&gt;</span>
<span class="nv">lines: </span><span class="p">[</span><span class="s1">&#39;Available options:&#39;</span><span class="p">]</span>

View File

@@ -14,6 +14,7 @@ stream, with a big ol' efficient switch, but it's much nicer to work with
like this. The order of these passes matters -- indentation must be
corrected before implicit parentheses can be wrapped around blocks of code.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">rewrite: </span><span class="p">(</span><span class="nx">tokens</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="vi">@tokens: </span><span class="nx">tokens</span>
<span class="nx">@adjustComments</span><span class="p">()</span>
<span class="nx">@removeLeadingNewlines</span><span class="p">()</span>
<span class="nx">@removeMidExpressionNewlines</span><span class="p">()</span>
<span class="nx">@closeOpenCallsAndIndexes</span><span class="p">()</span>
@@ -31,14 +32,32 @@ our feet.</p> </td> <td class="code"> <div
<span class="k">break</span> <span class="nx">unless</span> <span class="nx">@tokens</span><span class="p">[</span><span class="nx">i</span><span class="p">]</span>
<span class="nv">move: </span><span class="nx">block</span> <span class="nx">@tokens</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="nx">@tokens</span><span class="p">[</span><span class="nx">i</span><span class="p">],</span> <span class="nx">@tokens</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="nx">i</span>
<span class="nv">i: </span><span class="o">+</span> <span class="nx">move</span>
<span class="kc">true</span></pre></div> </td> </tr> <tr id="section-7"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-7">#</a> </div> <p>Leading newlines would introduce an ambiguity in the grammar, so we
<span class="kc">true</span></pre></div> </td> </tr> <tr id="section-7"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-7">#</a> </div> <p>Massage newlines and indentations so that comments don't have to be
correctly indented, or appear on a line of their own.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">adjustComments: </span><span class="o">-&gt;</span>
<span class="nx">@scanTokens</span> <span class="p">(</span><span class="nx">prev</span><span class="p">,</span> <span class="nx">token</span><span class="p">,</span> <span class="nx">post</span><span class="p">,</span> <span class="nx">i</span><span class="p">)</span> <span class="o">=&gt;</span>
<span class="k">return</span> <span class="mi">1</span> <span class="nx">unless</span> <span class="nx">token</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">is</span> <span class="s1">&#39;HERECOMMENT&#39;</span>
<span class="p">[</span><span class="nx">before</span><span class="p">,</span> <span class="nx">after</span><span class="p">]</span><span class="o">:</span> <span class="p">[</span><span class="nx">@tokens</span><span class="p">[</span><span class="nx">i</span> <span class="o">-</span> <span class="mi">2</span><span class="p">],</span> <span class="nx">@tokens</span><span class="p">[</span><span class="nx">i</span> <span class="o">+</span> <span class="mi">2</span><span class="p">]]</span>
<span class="k">if</span> <span class="nx">after</span> <span class="o">and</span> <span class="nx">after</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">is</span> <span class="s1">&#39;INDENT&#39;</span>
<span class="nx">@tokens</span><span class="p">.</span><span class="nx">splice</span> <span class="nx">i</span> <span class="o">+</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">1</span>
<span class="k">if</span> <span class="nx">before</span> <span class="o">and</span> <span class="nx">before</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">is</span> <span class="s1">&#39;OUTDENT&#39;</span> <span class="o">and</span> <span class="nx">post</span> <span class="o">and</span> <span class="nx">prev</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">is</span> <span class="nx">post</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">is</span> <span class="s1">&#39;TERMINATOR&#39;</span>
<span class="nx">@tokens</span><span class="p">.</span><span class="nx">splice</span> <span class="nx">i</span> <span class="o">-</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">1</span>
<span class="k">else</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="nx">after</span>
<span class="k">else</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="mi">0</span><span class="p">]</span> <span class="o">not</span> <span class="k">in</span> <span class="p">[</span><span class="s1">&#39;TERMINATOR&#39;</span><span class="p">,</span> <span class="s1">&#39;INDENT&#39;</span><span class="p">,</span> <span class="s1">&#39;OUTDENT&#39;</span><span class="p">]</span>
<span class="k">if</span> <span class="nx">post</span> <span class="o">and</span> <span class="nx">post</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">is</span> <span class="s1">&#39;TERMINATOR&#39;</span> <span class="o">and</span> <span class="nx">after</span> <span class="o">and</span> <span class="nx">after</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">is</span> <span class="s1">&#39;OUTDENT&#39;</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">3</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="p">,</span> <span class="mi">2</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">3</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="p">[</span><span class="s1">&#39;TERMINATOR&#39;</span><span class="p">,</span> <span class="s2">&quot;\n&quot;</span><span class="p">,</span> <span class="nx">prev</span><span class="p">[</span><span class="mi">2</span><span class="p">]])</span>
<span class="k">else</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;TERMINATOR&#39;</span><span class="p">,</span> <span class="s2">&quot;\n&quot;</span><span class="p">,</span> <span class="nx">prev</span><span class="p">[</span><span class="mi">2</span><span class="p">]]</span>
<span class="k">return</span> <span class="mi">2</span>
<span class="k">return</span> <span class="mi">1</span></pre></div> </td> </tr> <tr id="section-8"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-8">#</a> </div> <p>Leading newlines would introduce an ambiguity in the grammar, so we
dispatch them here.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">removeLeadingNewlines: </span><span class="o">-&gt;</span>
<span class="nx">@tokens</span><span class="p">.</span><span class="nx">shift</span><span class="p">()</span> <span class="k">while</span> <span class="nx">@tokens</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">and</span> <span class="nx">@tokens</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span> <span class="o">is</span> <span class="s1">&#39;TERMINATOR&#39;</span></pre></div> </td> </tr> <tr id="section-8"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-8">#</a> </div> <p>Some blocks occur in the middle of expressions -- when we're expecting
<span class="nx">@tokens</span><span class="p">.</span><span class="nx">shift</span><span class="p">()</span> <span class="k">while</span> <span class="nx">@tokens</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">and</span> <span class="nx">@tokens</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span> <span class="o">is</span> <span class="s1">&#39;TERMINATOR&#39;</span></pre></div> </td> </tr> <tr id="section-9"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-9">#</a> </div> <p>Some blocks occur in the middle of expressions -- when we're expecting
this, remove their trailing newlines.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">removeMidExpressionNewlines: </span><span class="o">-&gt;</span>
<span class="nx">@scanTokens</span> <span class="p">(</span><span class="nx">prev</span><span class="p">,</span> <span class="nx">token</span><span class="p">,</span> <span class="nx">post</span><span class="p">,</span> <span class="nx">i</span><span class="p">)</span> <span class="o">=&gt;</span>
<span class="k">return</span> <span class="mi">1</span> <span class="nx">unless</span> <span class="nx">post</span> <span class="o">and</span> <span class="nx">include</span><span class="p">(</span><span class="nx">EXPRESSION_CLOSE</span><span class="p">,</span> <span class="nx">post</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span> <span class="o">and</span> <span class="nx">token</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">is</span> <span class="s1">&#39;TERMINATOR&#39;</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">1</span>
<span class="k">return</span> <span class="mi">0</span></pre></div> </td> </tr> <tr id="section-9"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-9">#</a> </div> <p>The lexer has tagged the opening parenthesis of a method call, and the
<span class="k">return</span> <span class="mi">0</span></pre></div> </td> </tr> <tr id="section-10"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-10">#</a> </div> <p>The lexer has tagged the opening parenthesis of a method call, and the
opening bracket of an indexing operation. Match them with their paired
close.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">closeOpenCallsAndIndexes: </span><span class="o">-&gt;</span>
<span class="nv">parens: </span> <span class="p">[</span><span class="mi">0</span><span class="p">]</span>
@@ -61,7 +80,7 @@ close.</p> </td> <td class="code"> <div cl
<span class="nx">token</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">:</span> <span class="s1">&#39;INDEX_END&#39;</span>
<span class="k">else</span>
<span class="nx">brackets</span><span class="p">[</span><span class="nx">brackets</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="k">return</span> <span class="mi">1</span></pre></div> </td> </tr> <tr id="section-10"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-10">#</a> </div> <p>Methods may be optionally called without parentheses, for simple cases.
<span class="k">return</span> <span class="mi">1</span></pre></div> </td> </tr> <tr id="section-11"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-11">#</a> </div> <p>Methods may be optionally called without parentheses, for simple cases.
Insert the implicit parentheses here, so that the parser doesn't have to
deal with them.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">addImplicitParentheses: </span><span class="o">-&gt;</span>
<span class="nv">stack: </span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
@@ -88,7 +107,7 @@ deal with them.</p> </td> <td class="code">
<span class="k">return</span> <span class="nx">size</span>
<span class="nx">stack</span><span class="p">.</span><span class="nx">push</span> <span class="mi">0</span>
<span class="k">return</span> <span class="mi">1</span>
<span class="k">if</span> <span class="nx">open</span> <span class="o">and</span> <span class="o">!</span><span class="nx">token</span><span class="p">.</span><span class="nx">generated</span> <span class="o">and</span> <span class="p">(</span><span class="o">!</span><span class="nx">post</span> <span class="o">or</span> <span class="nx">include</span><span class="p">(</span><span class="nx">IMPLICIT_END</span><span class="p">,</span> <span class="nx">tag</span><span class="p">))</span>
<span class="k">if</span> <span class="nx">open</span> <span class="o">and</span> <span class="o">!</span><span class="nx">token</span><span class="p">.</span><span class="nx">generated</span> <span class="o">and</span> <span class="nx">prev</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">isnt</span> <span class="s1">&#39;,&#39;</span> <span class="o">and</span> <span class="p">(</span><span class="o">!</span><span class="nx">post</span> <span class="o">or</span> <span class="nx">include</span><span class="p">(</span><span class="nx">IMPLICIT_END</span><span class="p">,</span> <span class="nx">tag</span><span class="p">))</span>
<span class="nv">j: </span><span class="mi">1</span><span class="p">;</span> <span class="nx">j</span><span class="o">++</span> <span class="k">while</span> <span class="p">(</span><span class="nv">nx: </span><span class="nx">@tokens</span><span class="p">[</span><span class="nx">i</span> <span class="o">+</span> <span class="nx">j</span><span class="p">])</span><span class="o">?</span> <span class="o">and</span> <span class="nx">include</span><span class="p">(</span><span class="nx">IMPLICIT_END</span><span class="p">,</span> <span class="nx">nx</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
<span class="k">if</span> <span class="nx">nx</span><span class="o">?</span> <span class="o">and</span> <span class="nx">nx</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">is</span> <span class="s1">&#39;,&#39;</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="p">,</span> <span class="mi">1</span><span class="p">)</span> <span class="k">if</span> <span class="nx">tag</span> <span class="o">is</span> <span class="s1">&#39;TERMINATOR&#39;</span>
@@ -99,20 +118,23 @@ deal with them.</p> </td> <td class="code">
<span class="k">if</span> <span class="nx">tag</span> <span class="o">isnt</span> <span class="s1">&#39;OUTDENT&#39;</span> <span class="o">and</span> <span class="nx">include</span> <span class="nx">EXPRESSION_END</span><span class="p">,</span> <span class="nx">tag</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">return</span> <span class="mi">1</span>
<span class="k">return</span> <span class="mi">1</span></pre></div> </td> </tr> <tr id="section-11"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-11">#</a> </div> <p>Because our grammar is LALR(1), it can't handle some single-line
<span class="k">return</span> <span class="mi">1</span></pre></div> </td> </tr> <tr id="section-12"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-12">#</a> </div> <p>Because our grammar is LALR(1), it can't handle some single-line
expressions that lack ending delimiters. The <strong>Rewriter</strong> adds the implicit
blocks, so it doesn't need to. ')' can close a single-line block,
but we need to make sure it's balanced.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">addImplicitIndentation: </span><span class="o">-&gt;</span>
<span class="nx">@scanTokens</span> <span class="p">(</span><span class="nx">prev</span><span class="p">,</span> <span class="nx">token</span><span class="p">,</span> <span class="nx">post</span><span class="p">,</span> <span class="nx">i</span><span class="p">)</span> <span class="o">=&gt;</span>
<span class="k">if</span> <span class="nx">token</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">is</span> <span class="s1">&#39;ELSE&#39;</span> <span class="o">and</span> <span class="nx">prev</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">isnt</span> <span class="s1">&#39;OUTDENT&#39;</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;INDENT&#39;</span><span class="p">,</span> <span class="mi">2</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="p">[</span><span class="s1">&#39;OUTDENT&#39;</span><span class="p">,</span> <span class="mi">2</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">@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="nx">@indentation</span><span class="p">(</span><span class="nx">token</span><span class="p">)...</span>
<span class="k">return</span> <span class="mi">2</span>
<span class="k">if</span> <span class="nx">token</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">is</span> <span class="s1">&#39;CATCH&#39;</span> <span class="o">and</span> <span class="nx">@tokens</span><span class="p">[</span><span class="nx">i</span> <span class="o">+</span> <span class="mi">2</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span> <span class="o">is</span> <span class="s1">&#39;TERMINATOR&#39;</span>
<span class="nx">@tokens</span><span class="p">.</span><span class="nx">splice</span> <span class="nx">i</span> <span class="o">+</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">@indentation</span><span class="p">(</span><span class="nx">token</span><span class="p">)...</span>
<span class="k">return</span> <span class="mi">4</span>
<span class="k">return</span> <span class="mi">1</span> <span class="nx">unless</span> <span class="nx">include</span><span class="p">(</span><span class="nx">SINGLE_LINERS</span><span class="p">,</span> <span class="nx">token</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span> <span class="o">and</span>
<span class="nx">post</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">isnt</span> <span class="s1">&#39;INDENT&#39;</span> <span class="o">and</span>
<span class="o">not</span> <span class="p">(</span><span class="nx">token</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">is</span> <span class="s1">&#39;ELSE&#39;</span> <span class="o">and</span> <span class="nx">post</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">is</span> <span class="s1">&#39;IF&#39;</span><span class="p">)</span>
<span class="nv">starter: </span><span class="nx">token</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="nv">indent: </span><span class="p">[</span><span class="s1">&#39;INDENT&#39;</span><span class="p">,</span> <span class="mi">2</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="nv">indent.generated: </span><span class="kc">true</span>
<span class="p">[</span><span class="nx">indent</span><span class="p">,</span> <span class="nx">outdent</span><span class="p">]</span><span class="o">:</span> <span class="nx">@indentation</span> <span class="nx">token</span>
<span class="nv">indent.generated: outdent.generated: </span><span class="kc">true</span>
<span class="nx">@tokens</span><span class="p">.</span><span class="nx">splice</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="nx">indent</span>
<span class="nv">idx: </span><span class="nx">i</span> <span class="o">+</span> <span class="mi">1</span>
<span class="nv">parens: </span><span class="mi">0</span>
@@ -125,15 +147,13 @@ but we need to make sure it's balanced.</p> </td> <td cl
<span class="p">(</span><span class="nx">tok</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">is</span> <span class="s1">&#39;)&#39;</span> <span class="o">and</span> <span class="nx">parens</span> <span class="o">is</span> <span class="mi">0</span><span class="p">))</span> <span class="o">and</span>
<span class="o">not</span> <span class="p">(</span><span class="nx">tok</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">is</span> <span class="s1">&#39;ELSE&#39;</span> <span class="o">and</span> <span class="nx">starter</span> <span class="o">not</span> <span class="k">in</span> <span class="p">[</span><span class="s1">&#39;IF&#39;</span><span class="p">,</span> <span class="s1">&#39;THEN&#39;</span><span class="p">])</span>
<span class="nv">insertion: </span><span class="k">if</span> <span class="nx">pre</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">is</span> <span class="s2">&quot;,&quot;</span> <span class="k">then</span> <span class="nx">idx</span> <span class="o">-</span> <span class="mi">1</span> <span class="k">else</span> <span class="nx">idx</span>
<span class="nv">outdent: </span><span class="p">[</span><span class="s1">&#39;OUTDENT&#39;</span><span class="p">,</span> <span class="mi">2</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="nv">outdent.generated: </span><span class="kc">true</span>
<span class="nx">@tokens</span><span class="p">.</span><span class="nx">splice</span> <span class="nx">insertion</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">outdent</span>
<span class="k">break</span>
<span class="nv">parens: </span><span class="o">+</span> <span class="mi">1</span> <span class="k">if</span> <span class="nx">tok</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">is</span> <span class="s1">&#39;(&#39;</span>
<span class="nv">parens: </span><span class="o">-</span> <span class="mi">1</span> <span class="k">if</span> <span class="nx">tok</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">is</span> <span class="s1">&#39;)&#39;</span>
<span class="k">return</span> <span class="mi">1</span> <span class="nx">unless</span> <span class="nx">token</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">is</span> <span class="s1">&#39;THEN&#39;</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">1</span>
<span class="k">return</span> <span class="mi">0</span></pre></div> </td> </tr> <tr id="section-12"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-12">#</a> </div> <p>Ensure that all listed pairs of tokens are correctly balanced throughout
<span class="k">return</span> <span class="mi">0</span></pre></div> </td> </tr> <tr id="section-13"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-13">#</a> </div> <p>Ensure that all listed pairs of tokens are correctly balanced throughout
the course of the token stream.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">ensureBalance: </span><span class="p">(</span><span class="nx">pairs</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">levels: </span><span class="p">{}</span>
<span class="nv">openLine: </span><span class="p">{}</span>
@@ -151,7 +171,7 @@ the course of the token stream.</p> </td> <td class="cod
<span class="k">if</span> <span class="nx">unclosed</span><span class="p">.</span><span class="nx">length</span>
<span class="nv">open: </span><span class="nx">unclosed</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="nv">line: </span><span class="nx">openLine</span><span class="p">[</span><span class="nx">open</span><span class="p">]</span> <span class="o">+</span> <span class="mi">1</span>
<span class="k">throw</span> <span class="k">new</span> <span class="nb">Error</span> <span class="s2">&quot;unclosed $open on line $line&quot;</span></pre></div> </td> </tr> <tr id="section-13"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-13">#</a> </div> <p>We'd like to support syntax like this:</p>
<span class="k">throw</span> <span class="k">new</span> <span class="nb">Error</span> <span class="s2">&quot;unclosed $open on line $line&quot;</span></pre></div> </td> </tr> <tr id="section-14"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-14">#</a> </div> <p>We'd like to support syntax like this:</p>
<pre><code>el.click((event) -&gt;
el.hide())
@@ -198,16 +218,17 @@ rewriting.</li>
<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="nx">val</span>
<span class="k">return</span> <span class="mi">1</span>
<span class="k">else</span>
<span class="k">return</span> <span class="mi">1</span></pre></div> </td> </tr> <tr id="section-14"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-14">#</a> </div> <h2>Constants</h2> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-15"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-15">#</a> </div> <p>List of the token pairs that must be balanced.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">BALANCED_PAIRS: </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="p">[</span><span class="s1">&#39;[&#39;</span><span class="p">,</span> <span class="s1">&#39;]&#39;</span><span class="p">],</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="p">[</span><span class="s1">&#39;INDENT&#39;</span><span class="p">,</span> <span class="s1">&#39;OUTDENT&#39;</span><span class="p">],</span>
<span class="p">[</span><span class="s1">&#39;PARAM_START&#39;</span><span class="p">,</span> <span class="s1">&#39;PARAM_END&#39;</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;CALL_END&#39;</span><span class="p">],</span> <span class="p">[</span><span class="s1">&#39;INDEX_START&#39;</span><span class="p">,</span> <span class="s1">&#39;INDEX_END&#39;</span><span class="p">]]</span></pre></div> </td> </tr> <tr id="section-16"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-16">#</a> </div> <p>The inverse mappings of <code>BALANCED_PAIRS</code> we're trying to fix up, so we can
<span class="k">return</span> <span class="mi">1</span></pre></div> </td> </tr> <tr id="section-15"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-15">#</a> </div> <p>Generate the indentation tokens, based on another token on the same line.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">indentation: </span><span class="p">(</span><span class="nx">token</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="p">[[</span><span class="s1">&#39;INDENT&#39;</span><span class="p">,</span> <span class="mi">2</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="p">[</span><span class="s1">&#39;OUTDENT&#39;</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="nx">token</span><span class="p">[</span><span class="mi">2</span><span class="p">]]]</span></pre></div> </td> </tr> <tr id="section-16"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-16">#</a> </div> <h2>Constants</h2> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-17"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-17">#</a> </div> <p>List of the token pairs that must be balanced.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">BALANCED_PAIRS: </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="p">[</span><span class="s1">&#39;[&#39;</span><span class="p">,</span> <span class="s1">&#39;]&#39;</span><span class="p">],</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="p">[</span><span class="s1">&#39;INDENT&#39;</span><span class="p">,</span> <span class="s1">&#39;OUTDENT&#39;</span><span class="p">],</span>
<span class="p">[</span><span class="s1">&#39;PARAM_START&#39;</span><span class="p">,</span> <span class="s1">&#39;PARAM_END&#39;</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;CALL_END&#39;</span><span class="p">],</span> <span class="p">[</span><span class="s1">&#39;INDEX_START&#39;</span><span class="p">,</span> <span class="s1">&#39;INDEX_END&#39;</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 inverse mappings of <code>BALANCED_PAIRS</code> we're trying to fix up, so we can
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-17"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-17">#</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-18"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-18">#</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-19"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-19">#</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-20"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-20">#</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;@&#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>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-19"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-19">#</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-20"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-20">#</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-21"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-21">#</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-22"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-22">#</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;@&#39;</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-23"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-23">#</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;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;THIS&#39;</span><span class="p">,</span> <span class="s1">&#39;NULL&#39;</span><span class="p">,</span>
<span class="s1">&#39;@&#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;[&#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-22"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-22">#</a> </div> <p>Tokens indicating that the implicit call must enclose a block of expressions.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">IMPLICIT_BLOCK: </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;{&#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-23"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-23">#</a> </div> <p>Tokens that always mark the end of an implicit call for single-liners.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">IMPLICIT_END: </span> <span class="p">[</span><span class="s1">&#39;IF&#39;</span><span class="p">,</span> <span class="s1">&#39;UNLESS&#39;</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;LOOP&#39;</span><span class="p">,</span> <span class="s1">&#39;TERMINATOR&#39;</span><span class="p">,</span> <span class="s1">&#39;INDENT&#39;</span><span class="p">].</span><span class="nx">concat</span> <span class="nx">EXPRESSION_END</span></pre></div> </td> </tr> <tr id="section-24"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-24">#</a> </div> <p>Single-line flavors of block expressions that have unclosed endings.
<span class="s1">&#39;@&#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;[&#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-24"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-24">#</a> </div> <p>Tokens indicating that the implicit call must enclose a block of expressions.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">IMPLICIT_BLOCK: </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;{&#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-25"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-25">#</a> </div> <p>Tokens that always mark the end of an implicit call for single-liners.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">IMPLICIT_END: </span> <span class="p">[</span><span class="s1">&#39;IF&#39;</span><span class="p">,</span> <span class="s1">&#39;UNLESS&#39;</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;LOOP&#39;</span><span class="p">,</span> <span class="s1">&#39;TERMINATOR&#39;</span><span class="p">,</span> <span class="s1">&#39;INDENT&#39;</span><span class="p">].</span><span class="nx">concat</span> <span class="nx">EXPRESSION_END</span></pre></div> </td> </tr> <tr id="section-26"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-26">#</a> </div> <p>Single-line flavors of block expressions that have unclosed endings.
The grammar can't disambiguate them, so we insert the implicit indentation.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">SINGLE_LINERS: </span><span class="p">[</span><span class="s1">&#39;ELSE&#39;</span><span class="p">,</span> <span class="s2">&quot;-&gt;&quot;</span><span class="p">,</span> <span class="s2">&quot;=&gt;&quot;</span><span class="p">,</span> <span class="s1">&#39;TRY&#39;</span><span class="p">,</span> <span class="s1">&#39;FINALLY&#39;</span><span class="p">,</span> <span class="s1">&#39;THEN&#39;</span><span class="p">]</span>
<span class="nv">SINGLE_CLOSERS: </span><span class="p">[</span><span class="s1">&#39;TERMINATOR&#39;</span><span class="p">,</span> <span class="s1">&#39;CATCH&#39;</span><span class="p">,</span> <span class="s1">&#39;FINALLY&#39;</span><span class="p">,</span> <span class="s1">&#39;ELSE&#39;</span><span class="p">,</span> <span class="s1">&#39;OUTDENT&#39;</span><span class="p">,</span> <span class="s1">&#39;LEADING_WHEN&#39;</span><span class="p">]</span>

View File

@@ -129,7 +129,7 @@ alert reverse '.eeffoC yrT'</textarea></div>
<p>
<b>Latest Version:</b>
<a href="http://github.com/jashkenas/coffee-script/tarball/0.7.0">0.7.0</a>
<a href="http://github.com/jashkenas/coffee-script/tarball/0.7.1">0.7.1</a>
</p>
<h2>
@@ -175,7 +175,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.7.0">0.7.0</a>.
release: <a href="http://github.com/jashkenas/coffee-script/tarball/0.7.1">0.7.1</a>.
To install the CoffeeScript compiler system-wide
under <tt>/usr/local</tt>, open the directory and run:
</p>
@@ -184,7 +184,16 @@ alert reverse '.eeffoC yrT'</textarea></div>
sudo bin/cake install</pre>
<p>
This provides the <tt>coffee</tt> command, which will execute CoffeeScripts
Alternatively, if you already have the
<a href="http://npmjs.org/">Node Package Manager</a> installed,
you can use that to grab the latest CoffeeScript:
</p>
<pre>
sudo npm install coffee-script</pre>
<p>
Both of these provide the <tt>coffee</tt> command, which will execute CoffeeScripts
under Node.js by default, but is also used to compile CoffeeScript
<tt>.coffee</tt> files into JavaScript, or to run an an interactive REPL.
When compiling to JavaScript, <tt>coffee</tt> writes the output
@@ -879,6 +888,10 @@ coffee --print app/scripts/*.coffee > concatenation.js</pre>
<b>kchmck</b>'s <a href="http://github.com/kchmck/vim-coffee-script">Vim CoffeeScript</a>
&mdash; which adds Vim syntax highlighting and indentation support.
</li>
<li>
<b>wavded</b>'s <a href="http://github.com/wavded/gedit-coffeescript">gedit-coffeescript</a>
&mdash; a CoffeeScript syntax highlighter for the gedit text editor.
</li>
<li>
<b>yeungda</b>'s <a href="http://yeungda.github.com/coffeescript-idea/">coffeescript-idea</a>
&mdash; a plugin for IntelliJ IDEA and RubyMine providing syntax highlighting.
@@ -893,6 +906,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>dsc</b>'s <a href="http://github.com/dsc/coffeecup">CoffeeCup</a>
&mdash; A Python WSGI middleware that compiles CoffeeScript to JavaScript
on-demand during development.
</li>
<li>
<b>sutto</b>'s <a href="http://github.com/Sutto/barista">Barista</a>
&mdash; a BistroCar alternative that integrates well with
@@ -930,6 +948,14 @@ coffee --print app/scripts/*.coffee > concatenation.js</pre>
Change Log
</h2>
<p>
<b class="header" style="margin-top: 20px;">0.7.1</b>
Block-style comments are now passed through and printed as JavaScript block
comments -- making them useful for licenses and copyright headers. Better
support for running coffee scripts standalone via hashbangs.
Improved syntax errors for tokens that are not in the grammar.
</p>
<p>
<b class="header" style="margin-top: 20px;">0.7.0</b>
Official CoffeeScript variable style is now camelCase, as in JavaScript.
@@ -937,7 +963,7 @@ coffee --print app/scripts/*.coffee > concatenation.js</pre>
Range comprehensions now generate cleaner code, but you have to specify <tt>by -1</tt>
if you'd like to iterate downward. Reporting of syntax errors is greatly
improved from the previous release. Running <tt>coffee</tt> with no arguments
now launches the REPL, with Readline support. The <tt>&amp;-</tt> bind operator
now launches the REPL, with Readline support. The <tt>&lt;-</tt> bind operator
has been removed from CoffeeScript. The <tt>loop</tt> keyword was added,
which is equivalent to a <tt>while true</tt> loop. Comprehensions that contain
closures will now close over their variables, like the semantics of a <tt>forEach</tt>.

View File

@@ -33,7 +33,7 @@ File.open: (path, mode, block) ->
# Write.
write: (location, data) ->
path = new Pathname location
path: new Pathname location
raise "Location does not exist" unless path.exists()
File.open path, 'w', (file) ->

View File

@@ -19,7 +19,7 @@ spaced_out_multiline_object: {
pi: 3.14159
list: [1, 2, 3, 4]
regex: /match[ing](every|thing|\/)/gi
three: new Idea()
three: new Idea
inner_obj: {
freedom: -> _.freedom()

View File

@@ -90,14 +90,14 @@ class LinkedList
# Tests.
list: new LinkedList()
list: new LinkedList
list.add("Hi")
puts(list.size() is 1)
puts(list.item(0) is "Hi")
puts(list.item(1) is null)
list: new LinkedList()
list: new LinkedList
list.add("zero").add("one").add("two")
puts(list.size() is 3)
puts(list.item(2) is "two")

View File

@@ -60,7 +60,7 @@ class Person
# p = Person ()
# p /name string print
p: new Person()
p: new Person
print p.name
@@ -188,9 +188,9 @@ HomePage::get: (url) ->
# b /right = BTree ()
BTree: ->
b: new BTree()
b.left: new BTree()
b.right: new BTree()
b: new BTree
b.left: new BTree
b.right: new BTree
# BTree = class: /left, /right.
@@ -200,6 +200,6 @@ b.right: new BTree()
# 'left path found!' print.
BTree: ->
b: new BTree()
b: new BTree
print('left path found!') if b.left?

File diff suppressed because one or more lines are too long

View File

@@ -115,7 +115,7 @@ alert reverse '.eeffoC yrT'</textarea></div>
<p>
<b>Latest Version:</b>
<a href="http://github.com/jashkenas/coffee-script/tarball/0.7.0">0.7.0</a>
<a href="http://github.com/jashkenas/coffee-script/tarball/0.7.1">0.7.1</a>
</p>
<h2>
@@ -260,7 +260,7 @@ cubes = (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.7.0">0.7.0</a>.
release: <a href="http://github.com/jashkenas/coffee-script/tarball/0.7.1">0.7.1</a>.
To install the CoffeeScript compiler system-wide
under <tt>/usr/local</tt>, open the directory and run:
</p>
@@ -269,7 +269,16 @@ cubes = (function() {
sudo bin/cake install</pre>
<p>
This provides the <tt>coffee</tt> command, which will execute CoffeeScripts
Alternatively, if you already have the
<a href="http://npmjs.org/">Node Package Manager</a> installed,
you can use that to grab the latest CoffeeScript:
</p>
<pre>
sudo npm install coffee-script</pre>
<p>
Both of these provide the <tt>coffee</tt> command, which will execute CoffeeScripts
under Node.js by default, but is also used to compile CoffeeScript
<tt>.coffee</tt> files into JavaScript, or to run an an interactive REPL.
When compiling to JavaScript, <tt>coffee</tt> writes the output
@@ -1795,6 +1804,10 @@ html <span class="Keyword">=</span> <span class="String"><span class="String">'<
<b>kchmck</b>'s <a href="http://github.com/kchmck/vim-coffee-script">Vim CoffeeScript</a>
&mdash; which adds Vim syntax highlighting and indentation support.
</li>
<li>
<b>wavded</b>'s <a href="http://github.com/wavded/gedit-coffeescript">gedit-coffeescript</a>
&mdash; a CoffeeScript syntax highlighter for the gedit text editor.
</li>
<li>
<b>yeungda</b>'s <a href="http://yeungda.github.com/coffeescript-idea/">coffeescript-idea</a>
&mdash; a plugin for IntelliJ IDEA and RubyMine providing syntax highlighting.
@@ -1809,6 +1822,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>dsc</b>'s <a href="http://github.com/dsc/coffeecup">CoffeeCup</a>
&mdash; A Python WSGI middleware that compiles CoffeeScript to JavaScript
on-demand during development.
</li>
<li>
<b>sutto</b>'s <a href="http://github.com/Sutto/barista">Barista</a>
&mdash; a BistroCar alternative that integrates well with
@@ -1846,6 +1864,14 @@ html <span class="Keyword">=</span> <span class="String"><span class="String">'<
Change Log
</h2>
<p>
<b class="header" style="margin-top: 20px;">0.7.1</b>
Block-style comments are now passed through and printed as JavaScript block
comments -- making them useful for licenses and copyright headers. Better
support for running coffee scripts standalone via hashbangs.
Improved syntax errors for tokens that are not in the grammar.
</p>
<p>
<b class="header" style="margin-top: 20px;">0.7.0</b>
Official CoffeeScript variable style is now camelCase, as in JavaScript.
@@ -1853,7 +1879,7 @@ html <span class="Keyword">=</span> <span class="String"><span class="String">'<
Range comprehensions now generate cleaner code, but you have to specify <tt>by -1</tt>
if you'd like to iterate downward. Reporting of syntax errors is greatly
improved from the previous release. Running <tt>coffee</tt> with no arguments
now launches the REPL, with Readline support. The <tt>&amp;-</tt> bind operator
now launches the REPL, with Readline support. The <tt>&lt;-</tt> bind operator
has been removed from CoffeeScript. The <tt>loop</tt> keyword was added,
which is equivalent to a <tt>while true</tt> loop. Comprehensions that contain
closures will now close over their variables, like the semantics of a <tt>forEach</tt>.

View File

@@ -15,7 +15,7 @@
parser = this.parser;
helpers = this.helpers;
}
exports.VERSION = '0.7.0';
exports.VERSION = '0.7.1';
lexer = new Lexer();
exports.compile = (compile = function(code, options) {
options = options || {};

View File

@@ -39,6 +39,10 @@
flags = sources.slice((separator + 1), sources.length);
sources = sources.slice(0, separator);
}
if (options.run) {
flags = sources.slice(1, sources.length + 1).concat(flags);
sources = [sources[0]];
}
process.ARGV = (process.argv = flags);
return compileScripts();
};
@@ -153,11 +157,7 @@
});
};
return path.exists(dir, function(exists) {
if (exists) {
return compile();
} else {
return exec(("mkdir -p " + dir), compile);
}
return exists ? compile() : exec(("mkdir -p " + dir), compile);
});
};
lint = function(js) {
@@ -191,10 +191,10 @@
parseOptions = function() {
var o;
optionParser = new optparse.OptionParser(SWITCHES, BANNER);
o = (options = optionParser.parse(process.argv));
o = (options = optionParser.parse(process.argv.slice(2, process.argv.length)));
options.run = !(o.compile || o.print || o.lint);
options.print = !!(o.print || (o.eval || o.stdio && o.compile));
sources = options.arguments.slice(2, options.arguments.length);
sources = options.arguments;
return sources;
};
compileOptions = function(source) {

View File

@@ -34,12 +34,14 @@
return new LiteralNode($1);
})
],
Expression: [o("Value"), o("Call"), o("Code"), o("Operation"), o("Assign"), o("If"), o("Try"), o("While"), o("For"), o("Switch"), o("Extends"), o("Class"), o("Splat"), o("Existence")],
Expression: [o("Value"), o("Call"), o("Code"), o("Operation"), o("Assign"), o("If"), o("Try"), o("While"), o("For"), o("Switch"), o("Extends"), o("Class"), o("Splat"), o("Existence"), o("Comment")],
Block: [
o("INDENT Body OUTDENT", function() {
return $2;
}), o("INDENT OUTDENT", function() {
return new Expressions();
}), o("TERMINATOR Comment", function() {
return Expressions.wrap([$2]);
})
],
Identifier: [
@@ -85,7 +87,7 @@
return new AssignNode(new ValueNode($1), $3, 'object');
}), o("AlphaNumeric ASSIGN Expression", function() {
return new AssignNode(new ValueNode($1), $3, 'object');
})
}), o("Comment")
],
Return: [
o("RETURN Expression", function() {
@@ -94,6 +96,11 @@
return new ReturnNode(new ValueNode(new LiteralNode('null')));
})
],
Comment: [
o("HERECOMMENT", function() {
return new CommentNode($1);
})
],
Existence: [
o("Expression ?", function() {
return new ExistenceNode($1);
@@ -232,9 +239,11 @@
})
],
Call: [
o("Invocation"), o("NEW Invocation", function() {
o("Invocation"), o("Super"), o("NEW Invocation", function() {
return $2.newInstance();
}), o("Super")
}), o("NEW Value", function() {
return (new CallNode($2, [])).newInstance();
})
],
Extends: [
o("SimpleAssignable EXTENDS Value", function() {
@@ -304,11 +313,7 @@
],
SimpleArgs: [
o("Expression"), o("SimpleArgs , Expression", function() {
if ($1 instanceof Array) {
return $1.concat([$3]);
} else {
return [$1].concat([$3]);
}
return $1 instanceof Array ? $1.concat([$3]) : [$1].concat([$3]);
})
],
Try: [
@@ -560,7 +565,7 @@
return new OpNode('&&', $1, $3);
}), o("Expression || Expression", function() {
return new OpNode('||', $1, $3);
}), o("Expression ? Expression", function() {
}), o("Expression OP? Expression", function() {
return new OpNode('?', $1, $3);
}), o("Expression -= Expression", function() {
return new OpNode('-=', $1, $3);
@@ -591,7 +596,7 @@
})
]
};
operators = [["left", '?'], ["nonassoc", 'UMINUS', 'UPLUS', '!', '!!', '~', '++', '--'], ["left", '*', '/', '%'], ["left", '+', '-'], ["left", '<<', '>>', '>>>'], ["left", '&', '|', '^'], ["left", '<=', '<', '>', '>='], ["right", 'DELETE', 'INSTANCEOF', 'TYPEOF'], ["left", '==', '!='], ["left", '&&', '||'], ["right", '-=', '+=', '/=', '*=', '%=', '||=', '&&=', '?='], ["left", '.'], ["right", 'INDENT'], ["left", 'OUTDENT'], ["right", 'WHEN', 'LEADING_WHEN', 'IN', 'OF', 'BY', 'THROW'], ["right", 'FOR', 'WHILE', 'UNTIL', 'LOOP', 'NEW', 'SUPER', 'CLASS'], ["left", 'EXTENDS'], ["right", 'ASSIGN', 'RETURN'], ["right", '->', '=>', 'UNLESS', 'IF', 'ELSE']];
operators = [["left", '?'], ["nonassoc", 'UMINUS', 'UPLUS', '!', '!!', '~', '++', '--'], ["left", '*', '/', '%'], ["left", '+', '-'], ["left", '<<', '>>', '>>>'], ["left", '&', '|', '^'], ["left", '<=', '<', '>', '>='], ["right", 'DELETE', 'INSTANCEOF', 'TYPEOF'], ["left", '==', '!='], ["left", '&&', '||', 'OP?'], ["right", '-=', '+=', '/=', '*=', '%=', '||=', '&&=', '?='], ["left", '.'], ["right", 'INDENT'], ["left", 'OUTDENT'], ["right", 'WHEN', 'LEADING_WHEN', 'IN', 'OF', 'BY', 'THROW'], ["right", 'FOR', 'WHILE', 'UNTIL', 'LOOP', 'NEW', 'SUPER', 'CLASS'], ["left", 'EXTENDS'], ["right", 'ASSIGN', 'RETURN'], ["right", '->', '=>', 'UNLESS', 'IF', 'ELSE']];
tokens = [];
_a = grammar;
for (name in _a) { if (__hasProp.call(_a, name)) {

View File

@@ -152,12 +152,19 @@
return true;
};
Lexer.prototype.commentToken = function() {
var match;
var comment, match;
if (!(match = this.chunk.match(COMMENT))) {
return false;
}
this.line += count(match[1], "\n");
this.i += match[1].length;
if (match[2]) {
comment = this.sanitizeHeredoc(match[2], {
herecomment: true
});
this.token('HERECOMMENT', comment.split(MULTILINER));
this.token('TERMINATOR', '\n');
}
return true;
};
Lexer.prototype.jsToken = function() {
@@ -299,6 +306,8 @@
}
} else if (value === ';') {
tag = 'TERMINATOR';
} else if (value === '?' && prevSpaced) {
tag = 'OP?';
} else if (include(CALLABLE, this.tag()) && !prevSpaced) {
if (value === '(') {
tag = 'CALL_START';
@@ -338,11 +347,7 @@
return prev[0] === '@';
}
}).call(this);
if (accessor) {
return 'accessor';
} else {
return false;
}
return accessor ? 'accessor' : false;
};
Lexer.prototype.sanitizeHeredoc = function(doc, options) {
var _d, attempt, indent, match;
@@ -352,10 +357,17 @@
indent = attempt;
}
}
return doc.replace(new RegExp("^" + indent, 'gm'), '').replace(MULTILINER, "\\n").replace(new RegExp(options.quote, 'g'), ("\\" + options.quote));
doc = doc.replace(new RegExp("^" + indent, 'gm'), '');
if (options.herecomment) {
return doc;
}
return doc.replace(MULTILINER, "\\n").replace(new RegExp(options.quote, 'g'), ("\\" + options.quote));
};
Lexer.prototype.tagHalfAssignment = function(tag) {
var last;
if (tag === 'OP?') {
tag = '?';
}
last = this.tokens.pop();
this.tokens.push([("" + tag + "="), ("" + tag + "="), last[2]]);
return true;
@@ -433,11 +445,7 @@
}
throw new Error(("SyntaxError: Unterminated " + (levels.pop()[0]) + " starting on line " + (this.line + 1)));
}
if (!i) {
return false;
} else {
return str.substring(0, i);
}
return !i ? false : str.substring(0, i);
};
Lexer.prototype.interpolateString = function(str, escapeQuotes) {
var _d, _e, _f, _g, _h, _i, _j, escaped, expr, group, i, idx, inner, interp, interpolated, lexer, match, nested, pi, quote, tag, tok, token, tokens, value;
@@ -472,6 +480,7 @@
}
inner = expr.substring(2, expr.length - 1);
if (inner.length) {
inner = inner.replace(new RegExp('\\\\' + quote, 'g'), quote);
nested = lexer.tokenize(("(" + inner + ")"), {
line: this.line
});
@@ -557,11 +566,7 @@
if (!(m = this.chunk.match(regex))) {
return false;
}
if (m) {
return m[index];
} else {
return false;
}
return m ? m[index] : false;
};
Lexer.prototype.unfinished = function() {
var prev;
@@ -579,9 +584,9 @@
NUMBER = /^(((\b0(x|X)[0-9a-fA-F]+)|((\b[0-9]+(\.[0-9]+)?|\.[0-9]+)(e[+\-]?[0-9]+)?)))\b/i;
HEREDOC = /^("{6}|'{6}|"{3}\n?([\s\S]*?)\n?([ \t]*)"{3}|'{3}\n?([\s\S]*?)\n?([ \t]*)'{3})/;
INTERPOLATION = /^\$([a-zA-Z_@]\w*(\.\w+)*)/;
OPERATOR = /^([+\*&|\/\-%=<>:!?]+)([ \t]*)/;
OPERATOR = /^(-[\-=>]?|\+[+=]?|[*&|\/%=<>:!?]+)([ \t]*)/;
WHITESPACE = /^([ \t]+)/;
COMMENT = /^(\s*#{3}(?!#)[ \t]*\n+([\s\S]*?)[ \t]*\n+[ \t]*#{3}|(\s*#[^\n]*)+)/;
COMMENT = /^(\s*#{3}(?!#)[ \t]*\n+([\s\S]*?)[ \t]*\n+[ \t]*#{3}|(\s*#(?!##[^#])[^\n]*)+)/;
CODE = /^((-|=)>)/;
MULTI_DENT = /^((\n([ \t]*))+)(\.)?/;
LAST_DENTS = /\n([ \t]*)/g;
@@ -596,12 +601,12 @@
STRING_NEWLINES = /\n[ \t]*/g;
NO_NEWLINE = /^([+\*&|\/\-%=<>:!.\\][<>=&|]*|and|or|is|isnt|not|delete|typeof|instanceof)$/;
HEREDOC_INDENT = /(\n+([ \t]*)|^([ \t]+))/g;
ASSIGNED = /^([a-zA-Z\$_]\w*[ \t]*?[:=])/;
ASSIGNED = /^([a-zA-Z\$_]\w*[ \t]*?[:=][^=])/;
NEXT_CHARACTER = /^\s*(\S)/;
NOT_REGEX = ['NUMBER', 'REGEX', '++', '--', 'FALSE', 'NULL', 'TRUE', ']'];
CALLABLE = ['IDENTIFIER', 'SUPER', ')', ']', '}', 'STRING', '@', 'THIS', '?', '::'];
LINE_BREAK = ['INDENT', 'OUTDENT', 'TERMINATOR'];
HALF_ASSIGNMENTS = ['-', '+', '/', '*', '%', '||', '&&', '?'];
HALF_ASSIGNMENTS = ['-', '+', '/', '*', '%', '||', '&&', '?', 'OP?'];
CONVERSIONS = {
'and': '&&',
'or': '||',

View File

@@ -1,5 +1,5 @@
(function(){
var AccessorNode, ArrayNode, AssignNode, BaseNode, CallNode, ClassNode, ClosureNode, CodeNode, DOUBLE_PARENS, ExistenceNode, Expressions, ExtendsNode, ForNode, IDENTIFIER, IS_STRING, IfNode, InNode, IndexNode, LiteralNode, NUMBER, ObjectNode, OpNode, ParentheticalNode, PushNode, RangeNode, ReturnNode, Scope, SliceNode, SplatNode, TAB, TRAILING_WHITESPACE, ThrowNode, TryNode, UTILITIES, ValueNode, WhileNode, _a, compact, del, flatten, helpers, include, indexOf, literal, merge, starts, utility;
var AccessorNode, ArrayNode, AssignNode, BaseNode, CallNode, ClassNode, ClosureNode, CodeNode, CommentNode, DOUBLE_PARENS, ExistenceNode, Expressions, ExtendsNode, ForNode, IDENTIFIER, IS_STRING, IfNode, InNode, IndexNode, LiteralNode, NUMBER, ObjectNode, OpNode, ParentheticalNode, PushNode, RangeNode, ReturnNode, Scope, SliceNode, SplatNode, TAB, TRAILING_WHITESPACE, ThrowNode, TryNode, UTILITIES, ValueNode, WhileNode, _a, compact, del, flatten, helpers, include, indexOf, literal, merge, starts, utility;
var __extends = function(child, parent) {
var ctor = function(){ };
ctor.prototype = parent.prototype;
@@ -36,12 +36,8 @@
}
}
top = this.topSensitive() ? this.options.top : del(this.options, 'top');
closure = this.isStatement() && !this.isPureStatement() && !top && !this.options.asStatement && !this.containsPureStatement();
if (closure) {
return this.compileClosure(this.options);
} else {
return this.compileNode(this.options);
}
closure = this.isStatement() && !this.isPureStatement() && !top && !this.options.asStatement && !(this instanceof CommentNode) && !this.containsPureStatement();
return closure ? this.compileClosure(this.options) : this.compileNode(this.options);
};
BaseNode.prototype.compileClosure = function(o) {
this.tab = o.indent;
@@ -100,10 +96,10 @@
BaseNode.prototype.traverse = function(block) {
return this.traverseChildren(true, block);
};
BaseNode.prototype.toString = function(idt) {
var _b, _c, _d, _e, child;
BaseNode.prototype.toString = function(idt, override) {
var _b, _c, _d, _e, child, children;
idt = idt || '';
return '\n' + idt + this['class'] + (function() {
children = (function() {
_b = []; _d = this.collectChildren();
for (_c = 0, _e = _d.length; _c < _e; _c++) {
child = _d[_c];
@@ -111,6 +107,7 @@
}
return _b;
}).call(this).join('');
return '\n' + idt + (override || this['class']) + children;
};
BaseNode.prototype.eachChild = function(func) {
var _b, _c, _d, _e, _f, _g, _h, attr, child;
@@ -184,11 +181,7 @@
return this;
};
Expressions.prototype.unwrap = function() {
if (this.expressions.length === 1) {
return this.expressions[0];
} else {
return this;
}
return this.expressions.length === 1 ? this.expressions[0] : this;
};
Expressions.prototype.empty = function() {
return this.expressions.length === 0;
@@ -197,6 +190,9 @@
var idx, last;
idx = this.expressions.length - 1;
last = this.expressions[idx];
if (last instanceof CommentNode) {
last = this.expressions[idx -= 1];
}
if (!last || last instanceof ReturnNode) {
return this;
}
@@ -205,11 +201,7 @@
};
Expressions.prototype.compile = function(o) {
o = o || {};
if (o.scope) {
return Expressions.__superClass__.compile.call(this, o);
} else {
return this.compileRoot(o);
}
return o.scope ? Expressions.__superClass__.compile.call(this, o) : this.compileRoot(o);
};
Expressions.prototype.compileNode = function(o) {
var _b, _c, _d, _e, node;
@@ -226,14 +218,10 @@
var code;
o.indent = (this.tab = o.noWrap ? '' : TAB);
o.scope = new Scope(null, this, null);
code = o.globals ? this.compileNode(o) : this.compileWithDeclarations(o);
code = this.compileWithDeclarations(o);
code = code.replace(TRAILING_WHITESPACE, '');
code = code.replace(DOUBLE_PARENS, '($1)');
if (o.noWrap) {
return code;
} else {
return "(function(){\n" + code + "\n})();\n";
}
return o.noWrap ? code : ("(function(){\n" + code + "\n})();\n");
};
Expressions.prototype.compileWithDeclarations = function(o) {
var code;
@@ -241,7 +229,7 @@
if (o.scope.hasAssignments(this)) {
code = ("" + (this.tab) + "var " + (o.scope.compiledAssignments()) + ";\n" + code);
}
if (o.scope.hasDeclarations(this)) {
if (!o.globals && o.scope.hasDeclarations(this)) {
code = ("" + (this.tab) + "var " + (o.scope.compiledDeclarations()) + ";\n" + code);
}
return code;
@@ -252,11 +240,7 @@
compiledNode = node.compile(merge(o, {
top: true
}));
if (node.isStatement()) {
return compiledNode;
} else {
return "" + (this.idt()) + compiledNode + ";";
}
return node.isStatement() ? compiledNode : ("" + (this.idt()) + compiledNode + ";");
};
return Expressions;
})();
@@ -302,19 +286,18 @@
return true;
};
ReturnNode.prototype.children = ['expression'];
ReturnNode.prototype.topSensitive = function() {
return true;
};
ReturnNode.prototype.makeReturn = function() {
return this;
};
ReturnNode.prototype.compileNode = function(o) {
ReturnNode.prototype.compile = function(o) {
var expr;
expr = this.expression.makeReturn();
if (!(expr instanceof ReturnNode)) {
return expr.compile(o);
}
del(o, 'top');
return ReturnNode.__superClass__.compile.call(this, o);
};
ReturnNode.prototype.compileNode = function(o) {
if (this.expression.isStatement()) {
o.asStatement = true;
}
@@ -349,18 +332,10 @@
return this.hasProperties() && this.properties[this.properties.length - 1] instanceof SliceNode;
};
ValueNode.prototype.makeReturn = function() {
if (this.hasProperties()) {
return ValueNode.__superClass__.makeReturn.call(this);
} else {
return this.base.makeReturn();
}
return this.hasProperties() ? ValueNode.__superClass__.makeReturn.call(this) : this.base.makeReturn();
};
ValueNode.prototype.unwrap = function() {
if (this.properties.length) {
return this;
} else {
return this.base;
}
return this.properties.length ? this : this.base;
};
ValueNode.prototype.isStatement = function() {
return this.base.isStatement && this.base.isStatement() && !this.hasProperties();
@@ -379,6 +354,9 @@
}
return node === this;
};
ValueNode.prototype.compile = function(o) {
return !o.top || this.properties.length ? ValueNode.__superClass__.compile.call(this, o) : this.base.compile(o);
};
ValueNode.prototype.compileNode = function(o) {
var _b, _c, baseline, complete, i, only, op, part, prop, props, temp;
only = del(o, 'onlyFirst');
@@ -410,14 +388,30 @@
this.last = part;
}
}
if (op && this.wrapped) {
return "(" + complete + ")";
} else {
return complete;
}
return op && this.wrapped ? ("(" + complete + ")") : complete;
};
return ValueNode;
})();
exports.CommentNode = (function() {
CommentNode = function(lines) {
this.lines = lines;
return this;
};
__extends(CommentNode, BaseNode);
CommentNode.prototype['class'] = 'CommentNode';
CommentNode.prototype.isStatement = function() {
return true;
};
CommentNode.prototype.makeReturn = function() {
return this;
};
CommentNode.prototype.compileNode = function(o) {
var sep;
sep = ("\n" + this.tab);
return "" + this.tab + "/*" + sep + (this.lines.join(sep)) + "\n" + this.tab + "*/";
};
return CommentNode;
})();
exports.CallNode = (function() {
CallNode = function(variable, args) {
this.isNew = false;
@@ -437,11 +431,7 @@
return this;
};
CallNode.prototype.prefix = function() {
if (this.isNew) {
return 'new ';
} else {
return '';
}
return this.isNew ? 'new ' : '';
};
CallNode.prototype.superReference = function(o) {
var meth, methname;
@@ -478,11 +468,7 @@
}).call(this).join(', ');
compilation = this.isSuper ? this.compileSuper(args, o) : ("" + (this.prefix()) + (this.variable.compile(o)) + "(" + args + ")");
}
if (o.operation && this.wrapped) {
return "(" + compilation + ")";
} else {
return compilation;
}
return o.operation && this.wrapped ? ("(" + compilation + ")") : compilation;
};
CallNode.prototype.compileSuper = function(args, o) {
return "" + (this.superReference(o)) + ".call(this" + (args.length ? ', ' : '') + args + ")";
@@ -577,11 +563,7 @@
if (this.to !== this.toVar) {
parts.push(this.to.compile(o));
}
if (parts.length) {
return "" + (parts.join('; ')) + ";\n" + o.indent;
} else {
return '';
}
return parts.length ? ("" + (parts.join('; ')) + ";") : '';
};
RangeNode.prototype.compileNode = function(o) {
var equals, idx, op, step, vars;
@@ -597,7 +579,7 @@
return "" + vars + "; " + (idx) + " " + op + " " + (this.toVar.compile(o)) + "; " + idx + " += " + step;
};
RangeNode.prototype.compileArray = function(o) {
var body, clause, equals, from, idt, post, pre, to, vars;
var body, clause, equals, from, i, idt, post, pre, result, to, vars;
idt = this.idt(1);
vars = this.compileVariables(merge(o, {
indent: idt
@@ -605,11 +587,13 @@
equals = this.exclusive ? '' : '=';
from = this.fromVar.compile(o);
to = this.toVar.compile(o);
result = o.scope.freeVariable();
i = o.scope.freeVariable();
clause = ("" + from + " <= " + to + " ?");
pre = ("\n" + (idt) + "a = [];" + (vars));
body = ("var i = " + from + "; (" + clause + " i <" + equals + " " + to + " : i >" + equals + " " + to + "); (" + clause + " i += 1 : i -= 1)");
post = ("a.push(i);\n" + (idt) + "return a;\n" + o.indent);
return "(function(){" + (pre) + "for (" + body + ") " + post + "}).call(this)";
pre = ("\n" + (idt) + (result) + " = []; " + (vars));
body = ("var " + i + " = " + from + "; " + clause + " " + i + " <" + equals + " " + to + " : " + i + " >" + equals + " " + to + "; " + clause + " " + i + " += 1 : " + i + " -= 1");
post = ("{ " + (result) + ".push(" + i + ") };\n" + (idt) + "return " + result + ";\n" + o.indent);
return "(function(){" + (pre) + "\n" + (idt) + "for (" + body + ")" + post + "}).call(this)";
};
return RangeNode;
})();
@@ -639,23 +623,38 @@
ObjectNode.prototype['class'] = 'ObjectNode';
ObjectNode.prototype.children = ['properties'];
ObjectNode.prototype.compileNode = function(o) {
var _b, _c, _d, i, inner, join, last, prop, props;
var _b, _c, _d, _e, _f, _g, _h, i, indent, inner, join, lastNoncom, nonComments, prop, props;
o.indent = this.idt(1);
last = this.properties.length - 1;
props = (function() {
_b = []; _c = this.properties;
for (i = 0, _d = _c.length; i < _d; i++) {
prop = _c[i];
_b.push((function() {
join = i === last ? '' : ',\n';
if (!(prop instanceof AssignNode)) {
prop = new AssignNode(prop, prop, 'object');
}
return this.idt(1) + prop.compile(o) + join;
}).call(this));
nonComments = (function() {
_b = []; _d = this.properties;
for (_c = 0, _e = _d.length; _c < _e; _c++) {
prop = _d[_c];
!(prop instanceof CommentNode) ? _b.push(prop) : null;
}
return _b;
}).call(this);
lastNoncom = nonComments[nonComments.length - 1];
props = (function() {
_f = []; _g = this.properties;
for (i = 0, _h = _g.length; i < _h; i++) {
prop = _g[i];
_f.push((function() {
join = ",\n";
if ((prop === lastNoncom) || (prop instanceof CommentNode)) {
join = "\n";
}
if (i === this.properties.length - 1) {
join = '';
}
indent = prop instanceof CommentNode ? '' : this.idt(1);
if (!(prop instanceof AssignNode || prop instanceof CommentNode)) {
prop = new AssignNode(prop, prop, 'object');
}
return indent + prop.compile(o) + join;
}).call(this));
}
return _f;
}).call(this);
props = props.join('');
inner = props ? '\n' + props + '\n' + this.idt() : '';
return "{" + inner + "}";
@@ -683,6 +682,8 @@
code = obj.compile(o);
if (obj instanceof SplatNode) {
return this.compileSplatLiteral(this.objects, o);
} else if (obj instanceof CommentNode) {
objects.push("\n" + code + "\n" + o.indent);
} else if (i === this.objects.length - 1) {
objects.push(code);
} else {
@@ -690,11 +691,7 @@
}
}
objects = objects.join('');
if (indexOf(objects, '\n') >= 0) {
return "[\n" + (this.idt(1)) + objects + "\n" + this.tab + "]";
} else {
return "[" + objects + "]";
}
return indexOf(objects, '\n') >= 0 ? ("[\n" + (this.idt(1)) + objects + "\n" + this.tab + "]") : ("[" + objects + "]");
};
return ArrayNode;
})();
@@ -737,6 +734,9 @@
pvar = _e[0];
func = _e[1];
if (pvar && pvar.base.value === 'constructor' && func instanceof CodeNode) {
if (func.bound) {
throw new Error("cannot define a constructor as a bound function.");
}
func.name = className;
func.body.push(new ReturnNode(literal('this')));
this.variable = new ValueNode(this.variable);
@@ -831,11 +831,7 @@
if (stmt) {
return ("" + this.tab + val + ";");
}
if (top) {
return val;
} else {
return "(" + val + ")";
}
return top ? val : ("(" + val + ")");
};
AssignNode.prototype.compilePatternMatch = function(o) {
var _b, _c, _d, accessClass, assigns, code, i, idx, isString, obj, oindex, olength, splat, val, valVar, value;
@@ -991,11 +987,7 @@
SplatNode.prototype.children = ['name'];
SplatNode.prototype.compileNode = function(o) {
var _b;
if ((typeof (_b = this.index) !== "undefined" && _b !== null)) {
return this.compileParam(o);
} else {
return this.name.compile(o);
}
return (typeof (_b = this.index) !== "undefined" && _b !== null) ? this.compileParam(o) : this.name.compile(o);
};
SplatNode.prototype.compileParam = function(o) {
var _b, _c, idx, len, name, pos, trailing, variadic;
@@ -1123,6 +1115,9 @@
OpNode.prototype.isChainable = function() {
return indexOf(this.CHAINABLE, this.operator) >= 0;
};
OpNode.prototype.toString = function(idt) {
return OpNode.__superClass__.toString.call(this, idt, this['class'] + ' ' + this.operator);
};
OpNode.prototype.compileNode = function(o) {
o.operation = true;
if (this.isChainable() && this.first.unwrap() instanceof OpNode && this.first.unwrap().isChainable()) {
@@ -1204,11 +1199,7 @@
});
this.obj1 = _b[0];
this.obj2 = _b[1];
if (this.isArray()) {
return this.compileOrTest(o);
} else {
return this.compileLoopTest(o);
}
return this.isArray() ? this.compileOrTest(o) : this.compileLoopTest(o);
};
InNode.prototype.compileOrTest = function(o) {
var _b, _c, _d, i, item, tests;
@@ -1233,7 +1224,7 @@
i = _c[0];
l = _c[1];
prefix = this.obj1 !== this.obj2 ? this.obj1 + '; ' : '';
return "!!(function(){ " + (prefix) + "for (var " + i + "=0, " + l + "=" + (this.arr1) + ".length; " + i + "<" + l + "; " + i + "++) if (" + (this.arr2) + "[" + i + "] === " + this.obj2 + ") return true; })()";
return "!!(function(){ " + (prefix) + "for (var " + i + "=0, " + l + "=" + (this.arr1) + ".length; " + i + "<" + l + "; " + i + "++) if (" + (this.arr2) + "[" + i + "] === " + this.obj2 + ") return true; }).call(this)";
};
return InNode;
})();
@@ -1325,21 +1316,21 @@
ParentheticalNode.prototype.makeReturn = function() {
return this.expression.makeReturn();
};
ParentheticalNode.prototype.topSensitive = function() {
return true;
};
ParentheticalNode.prototype.compileNode = function(o) {
var code, l;
var code, l, top;
top = del(o, 'top');
code = this.expression.compile(o);
if (this.isStatement()) {
return code;
return (top ? ("" + this.tab + code + ";") : code);
}
l = code.length;
if (code.substr(l - 1, 1) === ';') {
code = code.substr(o, l - 1);
}
if (this.expression instanceof AssignNode) {
return code;
} else {
return "(" + code + ")";
}
return this.expression instanceof AssignNode ? code : ("(" + code + ")");
};
return ParentheticalNode;
})();
@@ -1420,6 +1411,9 @@
body = Expressions.wrap([this.body]);
if (range) {
sourcePart = source.compileVariables(o);
if (sourcePart) {
sourcePart += ("\n" + o.indent);
}
forPart = source.compile(merge(o, {
index: ivar,
step: this.step
@@ -1431,7 +1425,7 @@
namePart = new AssignNode(this.name, literal("" + svar + "[" + ivar + "]")).compile(merge(o, {
indent: this.idt(1),
top: true
})) + "\n";
})) + '\n';
} else {
if (name) {
namePart = ("" + name + " = " + svar + "[" + ivar + "]");
@@ -1459,9 +1453,7 @@
}
body = ClosureNode.wrap(body, true);
} else {
if (namePart) {
varPart = ("" + (this.idt(1)) + namePart + ";\n");
}
varPart = (namePart || '') && (this.pattern ? namePart : ("" + (this.idt(1)) + namePart + ";\n"));
}
this.object ? (forPart = ("" + ivar + " in " + svar + ") { if (" + (utility('hasProp')) + ".call(" + svar + ", " + ivar + ")")) : null;
body = body.compile(merge(o, {
@@ -1554,23 +1546,19 @@
}).call(this).join(' || ');
};
IfNode.prototype.compileNode = function(o) {
if (this.isStatement()) {
return this.compileStatement(o);
} else {
return this.compileTernary(o);
}
return this.isStatement() ? this.compileStatement(o) : this.compileTernary(o);
};
IfNode.prototype.makeReturn = function() {
this.body = this.body && this.ensureExpressions(this.body.makeReturn());
this.elseBody = this.elseBody && this.ensureExpressions(this.elseBody.makeReturn());
return this;
if (this.isStatement()) {
this.body = this.body && this.ensureExpressions(this.body.makeReturn());
this.elseBody = this.elseBody && this.ensureExpressions(this.elseBody.makeReturn());
return this;
} else {
return new ReturnNode(this);
}
};
IfNode.prototype.ensureExpressions = function(node) {
if (node instanceof Expressions) {
return node;
} else {
return new Expressions([node]);
}
return node instanceof Expressions ? node : new Expressions([node]);
};
IfNode.prototype.compileStatement = function(o) {
var body, child, comDent, condO, elsePart, ifDent, ifPart;
@@ -1621,10 +1609,10 @@
func = new ParentheticalNode(new CodeNode([], Expressions.wrap([expressions])));
args = [];
mentionsArgs = expressions.contains(function(n) {
return (n instanceof LiteralNode) && (n.value === 'arguments');
return n instanceof LiteralNode && (n.value === 'arguments');
});
mentionsThis = expressions.contains(function(n) {
return (n instanceof LiteralNode) && (n.value === 'this');
return (n instanceof LiteralNode && (n.value === 'this')) || (n instanceof CodeNode && n.bound);
});
if (mentionsArgs || mentionsThis) {
meth = literal(mentionsArgs ? 'apply' : 'call');
@@ -1635,11 +1623,7 @@
func = new ValueNode(func, [new AccessorNode(meth)]);
}
call = new CallNode(func, args);
if (statement) {
return Expressions.wrap([call]);
} else {
return call;
}
return statement ? Expressions.wrap([call]) : call;
}
});
UTILITIES = {

View File

@@ -7,19 +7,21 @@
return this;
};
OptionParser.prototype.parse = function(args) {
var _a, _b, _c, arg, isOption, matchedRule, options, rule;
var _a, _b, _c, _d, _e, arg, i, isOption, matchedRule, options, rule;
options = {
arguments: []
};
args = normalizeArguments(args);
while ((arg = args.shift())) {
_a = args;
for (i = 0, _b = _a.length; i < _b; i++) {
arg = _a[i];
isOption = !!(arg.match(LONG_FLAG) || arg.match(SHORT_FLAG));
matchedRule = false;
_b = this.rules;
for (_a = 0, _c = _b.length; _a < _c; _a++) {
rule = _b[_a];
_d = this.rules;
for (_c = 0, _e = _d.length; _c < _e; _c++) {
rule = _d[_c];
if (rule.shortFlag === arg || rule.longFlag === arg) {
options[rule.name] = rule.hasArgument ? args.shift() : true;
options[rule.name] = rule.hasArgument ? args[i + 1] : true;
matchedRule = true;
break;
}
@@ -27,8 +29,9 @@
if (isOption && !matchedRule) {
throw new Error("unrecognized option: " + arg);
}
if (!(isOption)) {
options.arguments.push(arg);
if (!isOption) {
options.arguments = args.slice(i, args.length);
break;
}
}
return options;

File diff suppressed because one or more lines are too long

View File

@@ -14,6 +14,7 @@
Rewriter = function() { };
Rewriter.prototype.rewrite = function(tokens) {
this.tokens = tokens;
this.adjustComments();
this.removeLeadingNewlines();
this.removeMidExpressionNewlines();
this.closeOpenCallsAndIndexes();
@@ -35,6 +36,35 @@
}
return true;
};
Rewriter.prototype.adjustComments = function() {
return this.scanTokens((function(__this) {
var __func = function(prev, token, post, i) {
var _c, _d, after, before;
if (!(token[0] === 'HERECOMMENT')) {
return 1;
}
_c = [this.tokens[i - 2], this.tokens[i + 2]];
before = _c[0];
after = _c[1];
if (after && after[0] === 'INDENT') {
this.tokens.splice(i + 2, 1);
before && before[0] === 'OUTDENT' && post && (prev[0] === post[0]) && (post[0] === 'TERMINATOR') ? this.tokens.splice(i - 2, 1) : this.tokens.splice(i, 0, after);
} else if (prev && !('TERMINATOR' === (_d = prev[0]) || 'INDENT' === _d || 'OUTDENT' === _d)) {
if (post && post[0] === 'TERMINATOR' && after && after[0] === 'OUTDENT') {
this.tokens.splice.apply(this.tokens, [i + 3, 0].concat(this.tokens.splice(i, 2)));
this.tokens.splice(i + 3, 0, ['TERMINATOR', "\n", prev[2]]);
} else {
this.tokens.splice(i, 0, ['TERMINATOR', "\n", prev[2]]);
}
return 2;
}
return 1;
};
return (function() {
return __func.apply(__this, arguments);
});
})(this));
};
Rewriter.prototype.removeLeadingNewlines = function() {
var _c;
_c = [];
@@ -138,7 +168,7 @@
stack.push(0);
return 1;
}
if (open && !token.generated && (!post || include(IMPLICIT_END, tag))) {
if (open && !token.generated && prev[0] !== ',' && (!post || include(IMPLICIT_END, tag))) {
j = 1;
while ((typeof (_d = (nx = this.tokens[i + j])) !== "undefined" && _d !== null) && include(IMPLICIT_END, nx[0])) {
j++;
@@ -169,17 +199,23 @@
Rewriter.prototype.addImplicitIndentation = function() {
return this.scanTokens((function(__this) {
var __func = function(prev, token, post, i) {
var idx, indent, insertion, outdent, parens, pre, starter, tok;
var _c, idx, indent, insertion, outdent, parens, pre, starter, tok;
if (token[0] === 'ELSE' && prev[0] !== 'OUTDENT') {
this.tokens.splice(i, 0, ['INDENT', 2, token[2]], ['OUTDENT', 2, token[2]]);
this.tokens.splice.apply(this.tokens, [i, 0].concat(this.indentation(token)));
return 2;
}
if (token[0] === 'CATCH' && this.tokens[i + 2][0] === 'TERMINATOR') {
this.tokens.splice.apply(this.tokens, [i + 2, 0].concat(this.indentation(token)));
return 4;
}
if (!(include(SINGLE_LINERS, token[0]) && post[0] !== 'INDENT' && !(token[0] === 'ELSE' && post[0] === 'IF'))) {
return 1;
}
starter = token[0];
indent = ['INDENT', 2, token[2]];
indent.generated = true;
_c = this.indentation(token);
indent = _c[0];
outdent = _c[1];
indent.generated = (outdent.generated = true);
this.tokens.splice(i + 1, 0, indent);
idx = i + 1;
parens = 0;
@@ -189,8 +225,6 @@
pre = this.tokens[idx - 1];
if ((!tok || (include(SINGLE_CLOSERS, tok[0]) && tok[1] !== ';' && parens === 0) || (tok[0] === ')' && parens === 0)) && !(tok[0] === 'ELSE' && !('IF' === starter || 'THEN' === starter))) {
insertion = pre[0] === "," ? idx - 1 : idx;
outdent = ['OUTDENT', 2, token[2]];
outdent.generated = true;
this.tokens.splice(insertion, 0, outdent);
break;
}
@@ -307,6 +341,9 @@
});
})(this));
};
Rewriter.prototype.indentation = function(token) {
return [['INDENT', 2, token[2]], ['OUTDENT', 2, token[2]]];
};
return Rewriter;
})();
BALANCED_PAIRS = [['(', ')'], ['[', ']'], ['{', '}'], ['INDENT', 'OUTDENT'], ['PARAM_START', 'PARAM_END'], ['CALL_START', 'CALL_END'], ['INDEX_START', 'INDEX_END']];

View File

@@ -3,7 +3,7 @@
"description": "Unfancy JavaScript",
"keywords": ["javascript", "language"],
"author": "Jeremy Ashkenas",
"version": "0.7.0",
"version": "0.7.1",
"licenses": [{
"type": "MIT",
"url": "http://github.com/jashkenas/coffee-script/raw/master/LICENSE"

View File

@@ -22,10 +22,10 @@ else
helpers: this.helpers
# The current CoffeeScript version number.
exports.VERSION: '0.7.0'
exports.VERSION: '0.7.1'
# Instantiate a Lexer for our use here.
lexer: new Lexer()
lexer: new Lexer
# Compile a string of CoffeeScript code to JavaScript, using the Coffee/Jison
# compiler.

View File

@@ -49,14 +49,17 @@ exports.run: ->
return usage() if options.help
return version() if options.version
return require './repl' if options.interactive
return compileStdio() if options.stdio
return compileScript 'console', sources[0] if options.eval
return compileStdio() if options.stdio
return compileScript 'console', sources[0] if options.eval
return require './repl' unless sources.length
separator: sources.indexOf '--'
flags: []
if separator >= 0
flags: sources[(separator + 1)...sources.length]
flags: sources[(separator + 1)...sources.length]
sources: sources[0...separator]
if options.run
flags: sources[1..sources.length].concat flags
sources: [sources[0]]
process.ARGV: process.argv: flags
compileScripts()
@@ -151,11 +154,11 @@ printTokens: (tokens) ->
# Use the [OptionParser module](optparse.html) to extract all options from
# `process.argv` that are specified in `SWITCHES`.
parseOptions: ->
optionParser: new optparse.OptionParser SWITCHES, BANNER
o: options: optionParser.parse(process.argv)
optionParser: new optparse.OptionParser SWITCHES, BANNER
o: options: optionParser.parse(process.argv[2...process.argv.length])
options.run: not (o.compile or o.print or o.lint)
options.print: !! (o.print or (o.eval or o.stdio and o.compile))
sources: options.arguments[2...options.arguments.length]
sources: options.arguments
# The compile-time options to pass to the CoffeeScript compiler.
compileOptions: (source) ->

View File

@@ -53,8 +53,8 @@ grammar: {
# The **Root** is the top-level node in the syntax tree. Since we parse bottom-up,
# all parsing must end here.
Root: [
o "", -> new Expressions()
o "TERMINATOR", -> new Expressions()
o "", -> new Expressions
o "TERMINATOR", -> new Expressions
o "Body"
o "Block TERMINATOR"
]
@@ -99,6 +99,7 @@ grammar: {
o "Class"
o "Splat"
o "Existence"
o "Comment"
]
# A an indented block of expressions. Note that the [Rewriter](rewriter.html)
@@ -106,7 +107,8 @@ grammar: {
# token stream.
Block: [
o "INDENT Body OUTDENT", -> $2
o "INDENT OUTDENT", -> new Expressions()
o "INDENT OUTDENT", -> new Expressions
o "TERMINATOR Comment", -> Expressions.wrap [$2]
]
# A literal identifier, a variable name or property.
@@ -147,6 +149,7 @@ grammar: {
o "AlphaNumeric"
o "Identifier ASSIGN Expression", -> new AssignNode new ValueNode($1), $3, 'object'
o "AlphaNumeric ASSIGN Expression", -> new AssignNode new ValueNode($1), $3, 'object'
o "Comment"
]
# A return statement from a function body.
@@ -155,6 +158,11 @@ grammar: {
o "RETURN", -> new ReturnNode new ValueNode new LiteralNode 'null'
]
# A block comment.
Comment: [
o "HERECOMMENT", -> new CommentNode $1
]
# [The existential operator](http://jashkenas.github.com/coffee-script/#existence).
Existence: [
o "Expression ?", -> new ExistenceNode $1
@@ -285,8 +293,9 @@ grammar: {
# and calling `super()`
Call: [
o "Invocation"
o "NEW Invocation", -> $2.newInstance()
o "Super"
o "NEW Invocation", -> $2.newInstance()
o "NEW Value", -> (new CallNode($2, [])).newInstance()
]
# Extending an object by setting its prototype chain to reference a parent
@@ -529,7 +538,7 @@ grammar: {
o "Expression && Expression", -> new OpNode '&&', $1, $3
o "Expression || Expression", -> new OpNode '||', $1, $3
o "Expression ? Expression", -> new OpNode '?', $1, $3
o "Expression OP? Expression", -> new OpNode '?', $1, $3
o "Expression -= Expression", -> new OpNode '-=', $1, $3
o "Expression += Expression", -> new OpNode '+=', $1, $3
@@ -570,7 +579,7 @@ operators: [
["left", '<=', '<', '>', '>=']
["right", 'DELETE', 'INSTANCEOF', 'TYPEOF']
["left", '==', '!=']
["left", '&&', '||']
["left", '&&', '||', 'OP?']
["right", '-=', '+=', '/=', '*=', '%=', '||=', '&&=', '?=']
["left", '.']
["right", 'INDENT']

View File

@@ -54,7 +54,7 @@ exports.Lexer: class Lexer
@extractNextToken()
@closeIndentation()
return @tokens if o.rewrite is off
(new Rewriter()).rewrite @tokens
(new Rewriter).rewrite @tokens
# At every position, run through this list of attempted matches,
# short-circuiting if any of them succeed. Their order determines precedence:
@@ -98,8 +98,8 @@ exports.Lexer: class Lexer
else if include(RESERVED, id)
@identifierError id
unless forcedIdentifier
tag: id: CONVERSIONS[id] if include COFFEE_ALIASES, id
return @tagHalfAssignment tag if @prev() and @prev()[0] is 'ASSIGN' and include HALF_ASSIGNMENTS, tag
tag: id: CONVERSIONS[id] if include COFFEE_ALIASES, id
return @tagHalfAssignment tag if @prev() and @prev()[0] is 'ASSIGN' and include HALF_ASSIGNMENTS, tag
@token tag, id
@token ']', ']' if close_index
true
@@ -141,6 +141,10 @@ exports.Lexer: class Lexer
return false unless match: @chunk.match(COMMENT)
@line: + count match[1], "\n"
@i: + match[1].length
if match[2]
comment: @sanitizeHeredoc match[2], {herecomment: true}
@token 'HERECOMMENT', comment.split MULTILINER
@token 'TERMINATOR', '\n'
true
# Matches JavaScript interpolated directly into the source via backticks.
@@ -260,6 +264,8 @@ exports.Lexer: class Lexer
@assignmentError() if include JS_FORBIDDEN, @value
else if value is ';'
tag: 'TERMINATOR'
else if value is '?' and prevSpaced
tag: 'OP?'
else if include(CALLABLE, @tag()) and not prevSpaced
if value is '('
tag: 'CALL_START'
@@ -292,18 +298,20 @@ exports.Lexer: class Lexer
prev[0] is '@'
if accessor then 'accessor' else false
# Sanitize a heredoc by escaping internal double quotes and
# Sanitize a heredoc or herecomment by escaping internal double quotes and
# erasing all external indentation on the left-hand side.
sanitizeHeredoc: (doc, options) ->
while match: HEREDOC_INDENT.exec doc
attempt: if match[2]? then match[2] else match[3]
indent: attempt if not indent or attempt.length < indent.length
doc.replace(new RegExp("^" +indent, 'gm'), '')
.replace(MULTILINER, "\\n")
doc: doc.replace(new RegExp("^" +indent, 'gm'), '')
return doc if options.herecomment
doc.replace(MULTILINER, "\\n")
.replace(new RegExp(options.quote, 'g'), "\\$options.quote")
# Tag a half assignment.
tagHalfAssignment: (tag) ->
tag: '?' if tag is 'OP?'
last: @tokens.pop()
@tokens.push ["$tag=", "$tag=", last[2]]
true
@@ -383,7 +391,7 @@ exports.Lexer: class Lexer
if str.length < 3 or not starts str, '"'
@token 'STRING', str
else
lexer: new Lexer()
lexer: new Lexer
tokens: []
quote: str.substring 0, 1
[i, pi]: [1, 1]
@@ -401,6 +409,7 @@ exports.Lexer: class Lexer
tokens.push ['STRING', "$quote${ str.substring(pi, i) }$quote"] if pi < i
inner: expr.substring(2, expr.length - 1)
if inner.length
inner: inner.replace new RegExp('\\\\' + quote, 'g'), quote
nested: lexer.tokenize "($inner)", {line: @line}
(tok[0]: ')') for tok, idx in nested when tok[0] is 'CALL_END'
nested.pop()
@@ -504,9 +513,9 @@ IDENTIFIER : /^([a-zA-Z\$_](\w|\$)*)/
NUMBER : /^(((\b0(x|X)[0-9a-fA-F]+)|((\b[0-9]+(\.[0-9]+)?|\.[0-9]+)(e[+\-]?[0-9]+)?)))\b/i
HEREDOC : /^("{6}|'{6}|"{3}\n?([\s\S]*?)\n?([ \t]*)"{3}|'{3}\n?([\s\S]*?)\n?([ \t]*)'{3})/
INTERPOLATION : /^\$([a-zA-Z_@]\w*(\.\w+)*)/
OPERATOR : /^([+\*&|\/\-%=<>:!?]+)([ \t]*)/
OPERATOR : /^(-[\-=>]?|\+[+=]?|[*&|\/%=<>:!?]+)([ \t]*)/
WHITESPACE : /^([ \t]+)/
COMMENT : /^(\s*#{3}(?!#)[ \t]*\n+([\s\S]*?)[ \t]*\n+[ \t]*#{3}|(\s*#[^\n]*)+)/
COMMENT : /^(\s*#{3}(?!#)[ \t]*\n+([\s\S]*?)[ \t]*\n+[ \t]*#{3}|(\s*#(?!##[^#])[^\n]*)+)/
CODE : /^((-|=)>)/
MULTI_DENT : /^((\n([ \t]*))+)(\.)?/
LAST_DENTS : /\n([ \t]*)/g
@@ -525,7 +534,7 @@ MULTILINER : /\n/g
STRING_NEWLINES : /\n[ \t]*/g
NO_NEWLINE : /^([+\*&|\/\-%=<>:!.\\][<>=&|]*|and|or|is|isnt|not|delete|typeof|instanceof)$/
HEREDOC_INDENT : /(\n+([ \t]*)|^([ \t]+))/g
ASSIGNED : /^([a-zA-Z\$_]\w*[ \t]*?[:=])/
ASSIGNED : /^([a-zA-Z\$_]\w*[ \t]*?[:=][^=])/
NEXT_CHARACTER : /^\s*(\S)/
# Tokens which a regular expression will never immediately follow, but which
@@ -549,7 +558,7 @@ CALLABLE: ['IDENTIFIER', 'SUPER', ')', ']', '}', 'STRING', '@', 'THIS', '?', '::
LINE_BREAK: ['INDENT', 'OUTDENT', 'TERMINATOR']
# Half-assignments...
HALF_ASSIGNMENTS: ['-', '+', '/', '*', '%', '||', '&&', '?']
HALF_ASSIGNMENTS: ['-', '+', '/', '*', '%', '||', '&&', '?', 'OP?']
# Conversions from CoffeeScript operators into JavaScript ones.
CONVERSIONS: {

View File

@@ -47,7 +47,7 @@ exports.BaseNode: class BaseNode
del @options, 'chainRoot' unless this instanceof AccessorNode or this instanceof IndexNode
top: if @topSensitive() then @options.top else del @options, 'top'
closure: @isStatement() and not @isPureStatement() and not top and
not @options.asStatement and
not @options.asStatement and not (this instanceof CommentNode) and
not @containsPureStatement()
if closure then @compileClosure(@options) else @compileNode(@options)
@@ -111,9 +111,10 @@ exports.BaseNode: class BaseNode
# `toString` representation of the node, for inspecting the parse tree.
# This is what `coffee --nodes` prints out.
toString: (idt) ->
toString: (idt, override) ->
idt: or ''
'\n' + idt + @class + (child.toString(idt + TAB) for child in @collectChildren()).join('')
children: (child.toString idt + TAB for child in @collectChildren()).join('')
'\n' + idt + (override or @class) + children
eachChild: (func) ->
return unless @children
@@ -136,9 +137,9 @@ exports.BaseNode: class BaseNode
class: 'BaseNode'
children: []
unwrap: -> this
unwrap: -> this
isStatement: -> no
isPureStatement: -> no
isPureStatement: -> no
topSensitive: -> no
#### Expressions
@@ -179,6 +180,7 @@ exports.Expressions: class Expressions extends BaseNode
makeReturn: ->
idx: @expressions.length - 1
last: @expressions[idx]
last: @expressions[idx: - 1] if last instanceof CommentNode
return this if not last or last instanceof ReturnNode
@expressions[idx]: last.makeReturn()
this
@@ -198,7 +200,7 @@ exports.Expressions: class Expressions extends BaseNode
compileRoot: (o) ->
o.indent: @tab: if o.noWrap then '' else TAB
o.scope: new Scope(null, this, null)
code: if o.globals then @compileNode(o) else @compileWithDeclarations(o)
code: @compileWithDeclarations(o)
code: code.replace(TRAILING_WHITESPACE, '')
code: code.replace(DOUBLE_PARENS, '($1)')
if o.noWrap then code else "(function(){\n$code\n})();\n"
@@ -208,7 +210,7 @@ exports.Expressions: class Expressions extends BaseNode
compileWithDeclarations: (o) ->
code: @compileNode(o)
code: "${@tab}var ${o.scope.compiledAssignments()};\n$code" if o.scope.hasAssignments(this)
code: "${@tab}var ${o.scope.compiledDeclarations()};\n$code" if o.scope.hasDeclarations(this)
code: "${@tab}var ${o.scope.compiledDeclarations()};\n$code" if not o.globals and o.scope.hasDeclarations(this)
code
# Compiles a single expression within the expressions body. If we need to
@@ -265,16 +267,15 @@ exports.ReturnNode: class ReturnNode extends BaseNode
constructor: (expression) ->
@expression: expression
topSensitive: ->
true
makeReturn: ->
this
compileNode: (o) ->
compile: (o) ->
expr: @expression.makeReturn()
return expr.compile(o) unless expr instanceof ReturnNode
del o, 'top'
return expr.compile o unless expr instanceof ReturnNode
super o
compileNode: (o) ->
o.asStatement: true if @expression.isStatement()
"${@tab}return ${@expression.compile(o)};"
@@ -335,15 +336,19 @@ exports.ValueNode: class ValueNode extends BaseNode
while node instanceof CallNode then node: node.variable
node is this
# Override compile to unwrap the value when possible.
compile: (o) ->
if not o.top or @properties.length then super(o) else @base.compile(o)
# We compile a value to JavaScript by compiling and joining each property.
# Things get much more insteresting if the chain of properties has *soak*
# operators `?.` interspersed. Then we have to take care not to accidentally
# evaluate a anything twice when building the soak chain.
compileNode: (o) ->
only: del(o, 'onlyFirst')
op: del(o, 'operation')
only: del o, 'onlyFirst'
op: del o, 'operation'
props: if only then @properties[0...@properties.length - 1] else @properties
o.chainRoot: or this
o.chainRoot: or this
baseline: @base.compile o
baseline: "($baseline)" if @hasProperties() and (@base instanceof ObjectNode or @isNumber())
complete: @last: baseline
@@ -364,6 +369,25 @@ exports.ValueNode: class ValueNode extends BaseNode
if op and @wrapped then "($complete)" else complete
#### CommentNode
# CoffeeScript passes through block comments as JavaScript block comments
# at the same position.
exports.CommentNode: class CommentNode extends BaseNode
class: 'CommentNode'
isStatement: -> yes
constructor: (lines) ->
@lines: lines
makeReturn: ->
this
compileNode: (o) ->
sep: "\n$@tab"
"$@tab/*$sep${ @lines.join(sep) }\n$@tab*/"
#### CallNode
# Node for a function invocation. Takes care of converting `super()` calls into
@@ -504,7 +528,7 @@ exports.RangeNode: class RangeNode extends BaseNode
parts: []
parts.push @from.compile o if @from isnt @fromVar
parts.push @to.compile o if @to isnt @toVar
if parts.length then "${parts.join('; ')};\n$o.indent" else ''
if parts.length then "${parts.join('; ')};" else ''
# When compiled normally, the range returns the contents of the *for loop*
# needed to iterate over the values in the range. Used by comprehensions.
@@ -525,11 +549,13 @@ exports.RangeNode: class RangeNode extends BaseNode
equals: if @exclusive then '' else '='
from: @fromVar.compile o
to: @toVar.compile o
result: o.scope.freeVariable()
i: o.scope.freeVariable()
clause: "$from <= $to ?"
pre: "\n${idt}a = [];${vars}"
body: "var i = $from; ($clause i <$equals $to : i >$equals $to); ($clause i += 1 : i -= 1)"
post: "a.push(i);\n${idt}return a;\n$o.indent"
"(function(){${pre}for ($body) $post}).call(this)"
pre: "\n${idt}${result} = []; ${vars}"
body: "var $i = $from; $clause $i <$equals $to : $i >$equals $to; $clause $i += 1 : $i -= 1"
post: "{ ${result}.push($i) };\n${idt}return $result;\n$o.indent"
"(function(){${pre}\n${idt}for ($body)$post}).call(this)"
#### SliceNode
@@ -563,11 +589,15 @@ exports.ObjectNode: class ObjectNode extends BaseNode
compileNode: (o) ->
o.indent: @idt 1
last: @properties.length - 1
nonComments: prop for prop in @properties when not (prop instanceof CommentNode)
lastNoncom: nonComments[nonComments.length - 1]
props: for prop, i in @properties
join: if i is last then '' else ',\n'
prop: new AssignNode prop, prop, 'object' unless prop instanceof AssignNode
@idt(1) + prop.compile(o) + join
join: ",\n"
join: "\n" if (prop is lastNoncom) or (prop instanceof CommentNode)
join: '' if i is @properties.length - 1
indent: if prop instanceof CommentNode then '' else @idt 1
prop: new AssignNode prop, prop, 'object' unless prop instanceof AssignNode or prop instanceof CommentNode
indent + prop.compile(o) + join
props: props.join('')
inner: if props then '\n' + props + '\n' + @idt() else ''
"{$inner}"
@@ -592,6 +622,8 @@ exports.ArrayNode: class ArrayNode extends BaseNode
code: obj.compile(o)
if obj instanceof SplatNode
return @compileSplatLiteral @objects, o
else if obj instanceof CommentNode
objects.push "\n$code\n$o.indent"
else if i is @objects.length - 1
objects.push code
else
@@ -628,7 +660,7 @@ exports.ClassNode: class ClassNode extends BaseNode
# constructor, property assignments, and inheritance getting built out below.
compileNode: (o) ->
extension: @parent and new ExtendsNode(@variable, @parent)
props: new Expressions()
props: new Expressions
o.top: true
me: null
className: @variable.compile o
@@ -640,11 +672,12 @@ exports.ClassNode: class ClassNode extends BaseNode
new CallNode(applied, [literal('this'), literal('arguments')])
]))
else
constructor: new CodeNode()
constructor: new CodeNode
for prop in @properties
[pvar, func]: [prop.variable, prop.value]
if pvar and pvar.base.value is 'constructor' and func instanceof CodeNode
throw new Error "cannot define a constructor as a bound function." if func.bound
func.name: className
func.body.push new ReturnNode literal 'this'
@variable: new ValueNode @variable
@@ -785,7 +818,7 @@ exports.CodeNode: class CodeNode extends BaseNode
constructor: (params, body, tag) ->
@params: params or []
@body: body or new Expressions()
@body: body or new Expressions
@bound: tag is 'boundfunc'
# Compilation creates a new scope unless explicitly asked to share with the
@@ -982,6 +1015,9 @@ exports.OpNode: class OpNode extends BaseNode
isChainable: ->
indexOf(@CHAINABLE, @operator) >= 0
toString: (idt) ->
super(idt, @class + ' ' + @operator)
compileNode: (o) ->
o.operation: true
return @compileChain(o) if @isChainable() and @first.unwrap() instanceof OpNode and @first.unwrap().isChainable()
@@ -1050,7 +1086,7 @@ exports.InNode: class InNode extends BaseNode
[@arr1, @arr2]: @array.compileReference o, {precompile: yes}
[i, l]: [o.scope.freeVariable(), o.scope.freeVariable()]
prefix: if @obj1 isnt @obj2 then @obj1 + '; ' else ''
"!!(function(){ ${prefix}for (var $i=0, $l=${@arr1}.length; $i<$l; $i++) if (${@arr2}[$i] === $@obj2) return true; })()"
"!!(function(){ ${prefix}for (var $i=0, $l=${@arr1}.length; $i<$l; $i++) if (${@arr2}[$i] === $@obj2) return true; }).call(this)"
#### TryNode
@@ -1146,9 +1182,14 @@ exports.ParentheticalNode: class ParentheticalNode extends BaseNode
makeReturn: ->
@expression.makeReturn()
topSensitive: ->
yes
compileNode: (o) ->
top: del o, 'top'
code: @expression.compile(o)
return code if @isStatement()
if @isStatement()
return (if top then "$@tab$code;" else code)
l: code.length
code: code.substr(o, l-1) if code.substr(l-1, 1) is ';'
if @expression instanceof AssignNode then code else "($code)"
@@ -1212,13 +1253,14 @@ exports.ForNode: class ForNode extends BaseNode
varPart: ''
body: Expressions.wrap([@body])
if range
sourcePart: source.compileVariables o
sourcePart: source.compileVariables(o)
sourcePart: + "\n$o.indent" if sourcePart
forPart: source.compile merge o, {index: ivar, step: @step}
else
svar: scope.freeVariable()
sourcePart: "$svar = ${ @source.compile(o) };"
if @pattern
namePart: new AssignNode(@name, literal("$svar[$ivar]")).compile(merge o, {indent: @idt(1), top: true}) + "\n"
namePart: new AssignNode(@name, literal("$svar[$ivar]")).compile(merge o, {indent: @idt(1), top: true}) + '\n'
else
namePart: "$name = $svar[$ivar]" if name
unless @object
@@ -1237,7 +1279,7 @@ exports.ForNode: class ForNode extends BaseNode
body.unshift literal "var $index = $ivar" if index
body: ClosureNode.wrap(body, true)
else
varPart: "${@idt(1)}$namePart;\n" if namePart
varPart: (namePart or '') and (if @pattern then namePart else "${@idt(1)}$namePart;\n")
if @object
forPart: "$ivar in $svar) { if (${utility('hasProp')}.call($svar, $ivar)"
body: body.compile(merge(o, {indent: @idt(1), top: true}))
@@ -1260,10 +1302,10 @@ exports.IfNode: class IfNode extends BaseNode
constructor: (condition, body, tags) ->
@condition: condition
@body: body
@elseBody: null
@elseBody: null
@tags: tags or {}
@condition: new OpNode('!', new ParentheticalNode(@condition)) if @tags.invert
@isChain: false
@isChain: false
bodyNode: -> @body?.unwrap()
elseBodyNode: -> @elseBody?.unwrap()
@@ -1315,9 +1357,12 @@ exports.IfNode: class IfNode extends BaseNode
if @isStatement() then @compileStatement(o) else @compileTernary(o)
makeReturn: ->
@body: and @ensureExpressions(@body.makeReturn())
@elseBody: and @ensureExpressions(@elseBody.makeReturn())
this
if @isStatement()
@body: and @ensureExpressions(@body.makeReturn())
@elseBody: and @ensureExpressions(@elseBody.makeReturn())
this
else
new ReturnNode this
ensureExpressions: (node) ->
if node instanceof Expressions then node else new Expressions [node]
@@ -1379,8 +1424,11 @@ ClosureNode: exports.ClosureNode: {
return expressions if expressions.containsPureStatement()
func: new ParentheticalNode(new CodeNode([], Expressions.wrap([expressions])))
args: []
mentionsArgs: expressions.contains (n) -> (n instanceof LiteralNode) and (n.value is 'arguments')
mentionsThis: expressions.contains (n) -> (n instanceof LiteralNode) and (n.value is 'this')
mentionsArgs: expressions.contains (n) ->
n instanceof LiteralNode and (n.value is 'arguments')
mentionsThis: expressions.contains (n) ->
(n instanceof LiteralNode and (n.value is 'this')) or
(n instanceof CodeNode and n.bound)
if mentionsArgs or mentionsThis
meth: literal(if mentionsArgs then 'apply' else 'call')
args: [literal('this')]

View File

@@ -3,6 +3,9 @@
#
# parser: new OptionParser switches, helpBanner
# options: parser.parse process.argv
#
# The first non-option is considered to be the start of the file (and file
# option) list, and all subsequent arguments are left unparsed.
exports.OptionParser: class OptionParser
# Initialize with a list of valid options, in the form:
@@ -22,16 +25,18 @@ exports.OptionParser: class OptionParser
parse: (args) ->
options: {arguments: []}
args: normalizeArguments args
while (arg: args.shift())
for arg, i in args
isOption: !!(arg.match(LONG_FLAG) or arg.match(SHORT_FLAG))
matchedRule: no
for rule in @rules
if rule.shortFlag is arg or rule.longFlag is arg
options[rule.name]: if rule.hasArgument then args.shift() else true
options[rule.name]: if rule.hasArgument then args[i + 1] else true
matchedRule: yes
break
throw new Error "unrecognized option: $arg" if isOption and not matchedRule
options.arguments.push arg unless isOption
if not isOption
options.arguments: args[i...args.length]
break
options
# Return the help text for this **OptionParser**, listing and describing all

View File

@@ -26,6 +26,7 @@ exports.Rewriter: class Rewriter
# corrected before implicit parentheses can be wrapped around blocks of code.
rewrite: (tokens) ->
@tokens: tokens
@adjustComments()
@removeLeadingNewlines()
@removeMidExpressionNewlines()
@closeOpenCallsAndIndexes()
@@ -48,6 +49,27 @@ exports.Rewriter: class Rewriter
i: + move
true
# Massage newlines and indentations so that comments don't have to be
# correctly indented, or appear on a line of their own.
adjustComments: ->
@scanTokens (prev, token, post, i) =>
return 1 unless token[0] is 'HERECOMMENT'
[before, after]: [@tokens[i - 2], @tokens[i + 2]]
if after and after[0] is 'INDENT'
@tokens.splice i + 2, 1
if before and before[0] is 'OUTDENT' and post and prev[0] is post[0] is 'TERMINATOR'
@tokens.splice i - 2, 1
else
@tokens.splice i, 0, after
else if prev and prev[0] not in ['TERMINATOR', 'INDENT', 'OUTDENT']
if post and post[0] is 'TERMINATOR' and after and after[0] is 'OUTDENT'
@tokens.splice(i + 3, 0, @tokens.splice(i, 2)...)
@tokens.splice(i + 3, 0, ['TERMINATOR', "\n", prev[2]])
else
@tokens.splice i, 0, ['TERMINATOR', "\n", prev[2]]
return 2
return 1
# Leading newlines would introduce an ambiguity in the grammar, so we
# dispatch them here.
removeLeadingNewlines: ->
@@ -115,7 +137,7 @@ exports.Rewriter: class Rewriter
return size
stack.push 0
return 1
if open and !token.generated and (!post or include(IMPLICIT_END, tag))
if open and !token.generated and prev[0] isnt ',' and (!post or include(IMPLICIT_END, tag))
j: 1; j++ while (nx: @tokens[i + j])? and include(IMPLICIT_END, nx[0])
if nx? and nx[0] is ','
@tokens.splice(i, 1) if tag is 'TERMINATOR'
@@ -135,14 +157,17 @@ exports.Rewriter: class Rewriter
addImplicitIndentation: ->
@scanTokens (prev, token, post, i) =>
if token[0] is 'ELSE' and prev[0] isnt 'OUTDENT'
@tokens.splice i, 0, ['INDENT', 2, token[2]], ['OUTDENT', 2, token[2]]
@tokens.splice i, 0, @indentation(token)...
return 2
if token[0] is 'CATCH' and @tokens[i + 2][0] is 'TERMINATOR'
@tokens.splice i + 2, 0, @indentation(token)...
return 4
return 1 unless include(SINGLE_LINERS, token[0]) and
post[0] isnt 'INDENT' and
not (token[0] is 'ELSE' and post[0] is 'IF')
starter: token[0]
indent: ['INDENT', 2, token[2]]
indent.generated: true
[indent, outdent]: @indentation token
indent.generated: outdent.generated: true
@tokens.splice i + 1, 0, indent
idx: i + 1
parens: 0
@@ -155,8 +180,6 @@ exports.Rewriter: class Rewriter
(tok[0] is ')' and parens is 0)) and
not (tok[0] is 'ELSE' and starter not in ['IF', 'THEN'])
insertion: if pre[0] is "," then idx - 1 else idx
outdent: ['OUTDENT', 2, token[2]]
outdent.generated: true
@tokens.splice insertion, 0, outdent
break
parens: + 1 if tok[0] is '('
@@ -233,6 +256,10 @@ exports.Rewriter: class Rewriter
else
return 1
# Generate the indentation tokens, based on another token on the same line.
indentation: (token) ->
[['INDENT', 2, token[2]], ['OUTDENT', 2, token[2]]]
# Constants
# ---------

View File

@@ -22,7 +22,7 @@ class ThirdChild extends SecondChild
func: (string) ->
super('three/') + string
result: (new ThirdChild()).func 'four'
result: (new ThirdChild).func 'four'
ok result is 'zero/one/two/three/four'
ok Base.static('word') is 'static/word'
@@ -40,7 +40,7 @@ class SubClass extends SuperClass
constructor: ->
super 'sub'
ok (new SubClass()).prop is 'top-super-sub'
ok (new SubClass).prop is 'top-super-sub'
class OneClass
@@ -75,11 +75,11 @@ ThirdChild extends SecondChild
ThirdChild::func: (string) ->
super('three/') + string
result: (new ThirdChild()).func 'four'
result: (new ThirdChild).func 'four'
ok result is 'zero/one/two/three/four'
ok (new ThirdChild())['func-func']('thing') is 'dynamic-thing'
ok (new ThirdChild)['func-func']('thing') is 'dynamic-thing'
TopClass: (arg) ->
@@ -97,7 +97,7 @@ SubClass: ->
SuperClass extends TopClass
SubClass extends SuperClass
ok (new SubClass()).prop is 'top-super-sub'
ok (new SubClass).prop is 'top-super-sub'
# '@' referring to the current instance, and not being coerced into a call.
@@ -105,7 +105,7 @@ class ClassName
amI: ->
@ instanceof ClassName
obj: new ClassName()
obj: new ClassName
ok obj.amI()
@@ -125,7 +125,7 @@ class Class
class: 'class'
name: -> @class
instance: new Class()
instance: new Class
ok instance.class is 'class'
ok instance.name() is 'class'
@@ -144,3 +144,15 @@ fido: new Dog('Fido')
fido.bark: spark.bark
ok fido.bark() is 'Spark woofs!'
# Testing a bound function in a bound function.
class Mini
num: 10
generate: =>
for i in [1..3]
=>
@num
m: new Mini
ok (func() for func in m.generate()).join(' ') is '10 10 10'

View File

@@ -1,3 +1,10 @@
# comment before a ...
###
... block comment.
###
# comment
func: ->
# comment
@@ -66,6 +73,38 @@ func: ->
###
code
func: ->
one: ->
two: ->
three: ->
###
block.
###
four: ->
fn1: ->
oneLevel: null
###
This isn't fine.
###
ok ok
obj: {
a: 'b'
###
comment
###
c: 'd'
}
arr: [
1, 2, 3,
###
four
###
5, 6, 7
]
# Spaced comments in if / elses.
result: if false

View File

@@ -6,3 +6,9 @@ js: CoffeeScript.compile("one\r\ntwo", {noWrap: on})
ok js is "one;\ntwo;"
global.resultArray: []
CoffeeScript.run("resultArray.push i for i of global", {noWrap: on, globals: on, source: 'tests'})
ok 'setInterval' in global.resultArray

View File

@@ -1,19 +0,0 @@
# Basic exception throwing.
block: -> (throw 'up')
throws block, 'up'
# Basic try/catch.
result: try
10
finally
15
ok result is 10
result: try
throw 'up'
catch err
err.length
ok result is 2

View File

@@ -78,3 +78,8 @@ ok result
# Safely calls values off of non-existent variables.
result: nothing?.value
ok result is undefined
# Assign to the result of an exsitential operation with a minus.
x: null ? - 1
ok x is - 1

View File

@@ -157,6 +157,13 @@ result: sum ->
ok result is 20
# Implicit call with a trailing if statement as a param.
func: -> arguments[1]
result: func 'one', if false then 100 else 13
ok result is 13
# Test more function passing:
result: sum( ->
1 + 2

View File

@@ -60,3 +60,10 @@ else if true
else
ok result is undefined
# Return an if with no else.
func: ->
return (if false then callback())
ok func() is null

View File

@@ -114,3 +114,10 @@ obj: {class: 'höt'}
obj.function: 'dog'
ok obj.class + obj.function is 'hötdog'
# But keyword assignment should be smart enough not to stringify variables.
func: ->
this == 'this'
ok func() is false

View File

@@ -49,4 +49,19 @@ ok 1 not in array
list: [1, 2, 7]
result: if list[2] in [7, 10] then 100 else -1
ok result is 100
ok result is 100
# And with array presence on an instance variable.
obj: {
list: [1, 2, 3, 4, 5]
in_list: (value) -> value in @list
}
ok obj.in_list 4
ok not obj.in_list 0
# Non-spaced values still work.
x: 10
y: -5
ok x*-y is 50
ok x*+y is -50

View File

@@ -0,0 +1,20 @@
# Ensure that the OptionParser handles arguments correctly.
{OptionParser}: require './../lib/optparse'
opt: new OptionParser [
['-r', '--required [DIR]', 'desc required']
['-o', '--optional', 'desc optional']
]
result: opt.parse ['one', 'two', 'three', '-r', 'dir']
ok result.arguments.length is 5
ok result.arguments[3] is '-r'
result: opt.parse ['--optional', '-r', 'folder', 'one', 'two']
ok result.optional is true
ok result.required is 'folder'
ok result.arguments.join(' ') is 'folder one two'

View File

@@ -12,10 +12,19 @@ a: [0, 1, 2, 3, 4, 5, 6, 7]
deepEqual a[2...6], [2, 3, 4, 5]
# Range.
# Ranges.
countdown: [10..1].join(' ')
ok countdown is "10 9 8 7 6 5 4 3 2 1"
a: 1
b: 5
nums: [a...b]
ok nums.join(' ') is '1 2 3 4'
b: -5
nums: [a..b]
ok nums.join(' ') is '1 0 -1 -2 -3 -4 -5'
# Expression-based range.
array: [(1+5)..1+9]

View File

@@ -89,7 +89,7 @@ class Child extends Parent
nums: [3, 2, 1]
super nums...
ok (new Child()).meth().join(' ') is '3 2 1'
ok (new Child).meth().join(' ') is '3 2 1'
# Functions with splats being called with too few arguments.

View File

@@ -64,6 +64,11 @@ ok "Hello ${world ? "$hello"}" is 'Hello World'
ok "Hello ${"${"${obj["name"]}" + '!'}"}" is 'Hello Joe!'
a: """
Hello ${ "Joe" }
"""
ok a is "Hello Joe"
a: 1
b: 2
c: 3

View File

@@ -0,0 +1,38 @@
# Basic exception throwing.
block: -> (throw 'up')
throws block, 'up'
# Basic try/catch.
result: try
10
finally
15
ok result is 10
result: try
throw 'up'
catch err
err.length
ok result is 2
result: try throw 'error' catch err then err.length
ok result is 5
# try/catch with empty clauses still compiles.
try
# nothing
catch err
# nothing
try
# nothing
finally
# nothing
ok yes