Compare commits

..

46 Commits
0.9.3 ... 0.9.4

Author SHA1 Message Date
Jeremy Ashkenas
c50cf23b7b CoffeeScript 0.9.4 2010-09-21 23:58:05 -04:00
Jeremy Ashkenas
25c8b4b34f Using the Array spaces trick to generate padding and indentation. 2010-09-21 23:17:43 -04:00
Jeremy Ashkenas
c0a89a7988 Fixing issue #700, block comment after first line of class definition. 2010-09-21 23:13:46 -04:00
Jeremy Ashkenas
07d9e9b71e fixing up block comment indentation boondoggle. 2010-09-21 22:59:28 -04:00
Jeremy Ashkenas
269f4e8da8 Tweaks to browser.coffee 2010-09-21 22:31:59 -04:00
satyr
481c3d536b made browser.coffee override Node dependent exported methods 2010-09-22 01:05:00 +09:00
Jeremy Ashkenas
7e5db250d3 Merge branch 'master' of git://github.com/StanAngeloff/coffee-script 2010-09-21 08:06:12 -04:00
Jeremy Ashkenas
970bfbe151 Merge branch 'repl' of git://github.com/Tim-Smart/coffee-script 2010-09-21 08:05:03 -04:00
Jeremy Ashkenas
7d98bb216a merged in satyr's leakless branch. 2010-09-21 08:02:22 -04:00
satyr
e4b7d06f35 removed browser specific hacks from src/* by making "rake browser" provide fake require and exports 2010-09-21 18:37:44 +09:00
satyr
b19c004680 made wrapper function keep current this 2010-09-21 16:53:58 +09:00
satyr
7bc91bf6c6 removed global dependency from grammer 2010-09-21 16:50:32 +09:00
Tim-Smart
c49cd02365 Fix REPL. Add CoffeeScript.eval method as run doesn't return result. 2010-09-21 17:36:23 +12:00
Stan Angeloff
992f4192bf Re-compiling core with new temporary variable names, all tests pass. 2010-09-21 07:55:08 +03:00
Stan Angeloff
921ab3ce68 Using old temporary variable name generation for single-letter types
(e.g., i, j, k, and so on).
2010-09-21 07:53:52 +03:00
Jeremy Ashkenas
69942c9a81 commenting out the failing test for the time being, to be fixed later. 2010-09-21 00:14:22 -04:00
Jeremy Ashkenas
fb5158630a fixing herecomment newlines. 2010-09-21 00:06:03 -04:00
Tim-Smart
34c29b3406 Cleaner stack traces.
- Improves run() function
- Re-sets the module.filename to add (compiled)
2010-09-21 15:32:37 +12:00
Jeremy Ashkenas
c0796da7b9 hacking around Jison patch to remove module dependency. 2010-09-20 23:13:02 -04:00
Jeremy Ashkenas
83651a7d6a merging in Tim's registerExtension fix for the latest Node master. 2010-09-20 22:27:04 -04:00
Jeremy Ashkenas
10d57705a0 Merge branch 'registerExtension' of git://github.com/Tim-Smart/coffee-script 2010-09-20 22:24:19 -04:00
Jeremy Ashkenas
71998e06cf Merge branch 'master' of http://github.com/leobm/coffee-script 2010-09-20 22:14:41 -04:00
Jeremy Ashkenas
a16594ed7b Merging in Stan's temporary_junk improvements. 2010-09-20 22:13:08 -04:00
Jeremy Ashkenas
f7fce3cd68 tweaking compiled tempvar names to satisfaction. 2010-09-20 21:56:18 -04:00
Tim-Smart
ba850790ed Add require.extensions support. 2010-09-21 13:23:45 +12:00
Jan-Felix Wittmann
abc1e83319 fix invalid testcase 2010-09-20 12:02:16 +02:00
Stan Angeloff
99a06ce4ea Updating name for cached length temporary variables to '_length', 'length2', and
so on.
2010-09-20 08:42:31 +03:00
Stan Angeloff
31441868e0 Allowing temporary variables to be reused. 2010-09-19 19:34:27 +03:00
Jeremy Ashkenas
5d82dddfb1 merging in Stan's temporary variables. 2010-09-19 12:00:16 -04:00
Stan Angeloff
d568b56c5e First attempt at allowing temporary variables to be reused. 2010-09-19 17:47:26 +03:00
Stan Angeloff
3ab0c12bf1 Don't store tempVars as we can get the next available one from scope. 2010-09-19 17:03:45 +03:00
Stan Angeloff
ed74f42323 Refactoring temporary name generation in a separate method, no
functional changes.
2010-09-19 16:18:01 +03:00
Jeremy Ashkenas
15d84dbb4e Fixing issue #694. Destructuring assignment as first line of implicitly called block -- regression. 2010-09-19 09:04:38 -04:00
Stan Angeloff
65fa0411b4 Part of previous commit: updating how temporary variables are generated.
We no longer need to store the name of the last generated variable,
instead we store the index.
2010-09-19 15:50:17 +03:00
Stan Angeloff
408833daef Removing code added during the migration. freeVariable(..) is called with
a `type` at all times.
2010-09-19 15:37:26 +03:00
Stan Angeloff
bb35b3e3b2 Re-compiling core with new changes. All tests pass. 2010-09-19 15:29:15 +03:00
Stan Angeloff
4a3e1fb0cb Updating nodes.coffee to make use of new temporary variables code
generators.
2010-09-19 15:28:22 +03:00
Stan Angeloff
fe68261bc2 Added generator for custom free variable types, e.g., '_cache',
'_cache2', and so on.
2010-09-19 14:55:19 +03:00
Stan Angeloff
1f2c6c77fd s/tempVars/tempVars.general/ This should allow us to store more than one
category of temporary variables.
2010-09-19 14:36:37 +03:00
Jeremy Ashkenas
08e1101c1f fixing static class properties that are implicit objects. 2010-09-18 22:25:45 -04:00
Jeremy Ashkenas
72847b9b26 tweak to block indentation test. 2010-09-18 13:20:32 -04:00
Jeremy Ashkenas
4b2d40d3b5 Merging in Stephank's fix for #692. 2010-09-18 10:36:48 -04:00
Stéphan Kochen
72d7fe2f7a Function soaks should preserve this. Fixes issue #692. 2010-09-18 12:27:14 +02:00
Jeremy Ashkenas
43f7f6c355 documenting 'invoke' in Cakefiles a little bit. 2010-09-17 20:24:10 -04:00
Jeremy Ashkenas
a53c104db1 simpler default Try CoffeeScript scriptlet. 2010-09-16 00:41:13 -04:00
Jeremy Ashkenas
2a0bd1adc7 silencing another JavaScriptLint extraneous warning. 2010-09-16 00:36:46 -04:00
65 changed files with 2218 additions and 1595 deletions

View File

@@ -2,6 +2,7 @@ fs = require 'fs'
{helpers} = require './lib/helpers'
CoffeeScript = require './lib/coffee-script'
{spawn, exec} = require 'child_process'
path = require 'path'
# ANSI Terminal Colors.
red = '\033[0;31m'
@@ -57,8 +58,9 @@ task 'build:parser', 'rebuild the Jison parser (run build first)', ->
require 'jison'
parser = require('./lib/grammar').parser
js = parser.generate()
parserPath = 'lib/parser.js'
fs.writeFile parserPath, js
# TODO: Remove this when the Jison patch is released.
js = js.replace 'if (require.main === module)', 'if (typeof module !== "undefined" && require.main === module)'
fs.writeFile 'lib/parser.js', js
task 'build:ultraviolet', 'build and install the Ultraviolet syntax highlighter', ->

View File

@@ -2,11 +2,11 @@ require 'erb'
require 'fileutils'
require 'rake/testtask'
require 'rubygems'
require 'yui/compressor'
require 'closure-compiler'
HEADER = <<-EOS
/**
* CoffeeScript Compiler v0.9.3
* CoffeeScript Compiler v0.9.4
* http://coffeescript.org
*
* Copyright 2010, Jeremy Ashkenas
@@ -33,9 +33,21 @@ end
desc "Build the single concatenated and minified script for the browser"
task :browser do
sources = %w(helpers.js rewriter.js lexer.js parser.js scope.js nodes.js coffee-script.js browser.js)
code = sources.map {|s| File.read('lib/' + s) }.join('')
code = YUI::JavaScriptCompressor.new.compress(code)
File.open('extras/coffee-script.js', 'w+') {|f| f.write(HEADER + code) }
sources = %w(helpers rewriter lexer parser scope nodes coffee-script browser)
code = sources.inject '' do |js, name|
js << <<-"JS"
require['./#{name}'] = new function(){
var exports = this;
#{ File.read "lib/#{name}.js" }
}
JS
end
code = Closure::Compiler.new.compress(<<-"JS")
this.CoffeeScript = function(){
function require(path){ return require[path] }
#{ code }
return require['./coffee-script']
}()
JS
File.open('extras/coffee-script.js', 'wb+') {|f| f.write(HEADER + code) }
end

View File

@@ -1,4 +1,4 @@
###
CoffeeScript Compiler v0.9.3
CoffeeScript Compiler v0.9.4
Released under the MIT License
###

View File

@@ -1,26 +1,24 @@
<!DOCTYPE html> <html> <head> <title>browser.coffee</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <link rel="stylesheet" media="all" href="docco.css" /> </head> <body> <div id="container"> <div id="background"></div> <div id="jump_to"> Jump To &hellip; <div id="jump_wrapper"> <div id="jump_page"> <a class="source" href="browser.html"> browser.coffee </a> <a class="source" href="cake.html"> cake.coffee </a> <a class="source" href="coffee-script.html"> coffee-script.coffee </a> <a class="source" href="command.html"> command.coffee </a> <a class="source" href="grammar.html"> grammar.coffee </a> <a class="source" href="helpers.html"> helpers.coffee </a> <a class="source" href="index.html"> index.coffee </a> <a class="source" href="lexer.html"> lexer.coffee </a> <a class="source" href="nodes.html"> nodes.coffee </a> <a class="source" href="optparse.html"> optparse.coffee </a> <a class="source" href="repl.html"> repl.coffee </a> <a class="source" href="rewriter.html"> rewriter.coffee </a> <a class="source" href="scope.html"> scope.coffee </a> </div> </div> </div> <table cellpadding="0" cellspacing="0"> <thead> <tr> <th class="docs"> <h1> browser.coffee </h1> </th> <th class="code"> </th> </tr> </thead> <tbody> <tr id="section-1"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-1">#</a> </div> <p>Activate CoffeeScript in the browser by having it compile and evaluate
<!DOCTYPE html> <html> <head> <title>browser.coffee</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <link rel="stylesheet" media="all" href="docco.css" /> </head> <body> <div id="container"> <div id="background"></div> <div id="jump_to"> Jump To &hellip; <div id="jump_wrapper"> <div id="jump_page"> <a class="source" href="browser.html"> browser.coffee </a> <a class="source" href="cake.html"> cake.coffee </a> <a class="source" href="coffee-script.html"> coffee-script.coffee </a> <a class="source" href="command.html"> command.coffee </a> <a class="source" href="grammar.html"> grammar.coffee </a> <a class="source" href="helpers.html"> helpers.coffee </a> <a class="source" href="index.html"> index.coffee </a> <a class="source" href="lexer.html"> lexer.coffee </a> <a class="source" href="nodes.html"> nodes.coffee </a> <a class="source" href="optparse.html"> optparse.coffee </a> <a class="source" href="repl.html"> repl.coffee </a> <a class="source" href="rewriter.html"> rewriter.coffee </a> <a class="source" href="scope.html"> scope.coffee </a> </div> </div> </div> <table cellpadding="0" cellspacing="0"> <thead> <tr> <th class="docs"> <h1> browser.coffee </h1> </th> <th class="code"> </th> </tr> </thead> <tbody> <tr id="section-1"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-1">#</a> </div> <p>Override exported methods for non-Node.js engines.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">CoffeeScript = </span><span class="nx">require</span> <span class="s1">&#39;./coffee-script&#39;</span></pre></div> </td> </tr> <tr id="section-2"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-2">#</a> </div> <p>Use standard JavaScript <code>eval</code> to eval code.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">CoffeeScript.eval = </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="nb">eval</span> <span class="nx">CoffeeScript</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">code</span><span class="p">,</span> <span class="nx">options</span></pre></div> </td> </tr> <tr id="section-3"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-3">#</a> </div> <p>Running code does not provide access to this scope.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">CoffeeScript.run = </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="p">(</span><span class="nb">Function</span> <span class="nx">CoffeeScript</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">code</span><span class="p">,</span> <span class="nx">options</span><span class="p">)()</span></pre></div> </td> </tr> <tr id="section-4"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-4">#</a> </div> <p>If we're not in a browser environment, we're finished with the public API.</p> </td> <td class="code"> <div class="highlight"><pre><span class="k">return</span> <span class="nx">unless</span> <span class="nb">window</span><span class="o">?</span></pre></div> </td> </tr> <tr id="section-5"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-5">#</a> </div> <p>Load a remote script from the current domain via XHR.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">CoffeeScript.load = </span><span class="p">(</span><span class="nx">url</span><span class="p">,</span> <span class="nx">options</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">xhr = </span><span class="k">new</span> <span class="p">(</span><span class="nb">window</span><span class="p">.</span><span class="nx">ActiveXObject</span> <span class="o">or</span> <span class="nx">XMLHttpRequest</span><span class="p">)(</span><span class="s1">&#39;Microsoft.XMLHTTP&#39;</span><span class="p">)</span>
<span class="nx">xhr</span><span class="p">.</span><span class="nx">open</span> <span class="s1">&#39;GET&#39;</span><span class="p">,</span> <span class="nx">url</span><span class="p">,</span> <span class="kc">true</span>
<span class="nx">xhr</span><span class="p">.</span><span class="nx">overrideMimeType</span> <span class="s1">&#39;text/plain&#39;</span> <span class="k">if</span> <span class="s1">&#39;overrideMimeType&#39;</span> <span class="k">of</span> <span class="nx">xhr</span>
<span class="nv">xhr.onreadystatechange = </span><span class="o">-&gt;</span>
<span class="nx">CoffeeScript</span><span class="p">.</span><span class="nx">run</span> <span class="nx">xhr</span><span class="p">.</span><span class="nx">responseText</span><span class="p">,</span> <span class="nx">options</span> <span class="k">if</span> <span class="nx">xhr</span><span class="p">.</span><span class="nx">readyState</span> <span class="o">is</span> <span class="mi">4</span>
<span class="nx">xhr</span><span class="p">.</span><span class="nx">send</span> <span class="kc">null</span></pre></div> </td> </tr> <tr id="section-6"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-6">#</a> </div> <p>Activate CoffeeScript in the browser by having it compile and evaluate
all script tags with a content-type of <code>text/coffeescript</code>.
This happens on page load.</p> </td> <td class="code"> <div class="highlight"><pre><span class="k">if</span> <span class="nb">document</span><span class="o">?</span><span class="p">.</span><span class="nx">getElementsByTagName</span>
<span class="nv">grind = </span><span class="p">(</span><span class="nx">coffee</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nx">setTimeout</span> <span class="nx">exports</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">coffee</span>
<span class="nv">grindRemote = </span><span class="p">(</span><span class="nx">url</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">xhr = </span><span class="k">new</span> <span class="p">(</span><span class="nb">window</span><span class="p">.</span><span class="nx">ActiveXObject</span> <span class="o">or</span> <span class="nx">XMLHttpRequest</span><span class="p">)(</span><span class="s1">&#39;Microsoft.XMLHTTP&#39;</span><span class="p">)</span>
<span class="nx">xhr</span><span class="p">.</span><span class="nx">open</span> <span class="s1">&#39;GET&#39;</span><span class="p">,</span> <span class="nx">url</span><span class="p">,</span> <span class="kc">true</span>
<span class="nx">xhr</span><span class="p">.</span><span class="nx">overrideMimeType</span> <span class="s1">&#39;text/plain&#39;</span> <span class="k">if</span> <span class="s1">&#39;overrideMimeType&#39;</span> <span class="k">of</span> <span class="nx">xhr</span>
<span class="nv">xhr.onreadystatechange = </span><span class="o">-&gt;</span>
<span class="nx">grind</span> <span class="nx">xhr</span><span class="p">.</span><span class="nx">responseText</span> <span class="k">if</span> <span class="nx">xhr</span><span class="p">.</span><span class="nx">readyState</span> <span class="o">is</span> <span class="mi">4</span>
<span class="nx">xhr</span><span class="p">.</span><span class="nx">send</span> <span class="kc">null</span>
<span class="nv">processScripts = </span><span class="o">-&gt;</span>
<span class="k">for</span> <span class="nx">script</span> <span class="k">in</span> <span class="nb">document</span><span class="p">.</span><span class="nx">getElementsByTagName</span> <span class="s1">&#39;script&#39;</span>
<span class="k">if</span> <span class="nx">script</span><span class="p">.</span><span class="nx">type</span> <span class="o">is</span> <span class="s1">&#39;text/coffeescript&#39;</span>
<span class="k">if</span> <span class="nx">script</span><span class="p">.</span><span class="nx">src</span>
<span class="nx">grindRemote</span> <span class="nx">script</span><span class="p">.</span><span class="nx">src</span>
<span class="k">else</span>
<span class="nx">grind</span> <span class="nx">script</span><span class="p">.</span><span class="nx">innerHTML</span>
<span class="kc">null</span>
<span class="k">if</span> <span class="nb">window</span><span class="p">.</span><span class="nx">addEventListener</span>
<span class="nx">addEventListener</span> <span class="s1">&#39;DOMContentLoaded&#39;</span><span class="p">,</span> <span class="nx">processScripts</span><span class="p">,</span> <span class="kc">false</span>
<span class="k">else</span>
<span class="nx">attachEvent</span> <span class="s1">&#39;onload&#39;</span><span class="p">,</span> <span class="nx">processScripts</span>
This happens on page load.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">processScripts = </span><span class="o">-&gt;</span>
<span class="k">for</span> <span class="nx">script</span> <span class="k">in</span> <span class="nb">document</span><span class="p">.</span><span class="nx">getElementsByTagName</span> <span class="s1">&#39;script&#39;</span>
<span class="k">if</span> <span class="nx">script</span><span class="p">.</span><span class="nx">type</span> <span class="o">is</span> <span class="s1">&#39;text/coffeescript&#39;</span>
<span class="k">if</span> <span class="nx">script</span><span class="p">.</span><span class="nx">src</span>
<span class="nx">CoffeeScript</span><span class="p">.</span><span class="nx">load</span> <span class="nx">script</span><span class="p">.</span><span class="nx">src</span>
<span class="k">else</span>
<span class="nx">setTimeout</span> <span class="o">-&gt;</span> <span class="nx">CoffeeScript</span><span class="p">.</span><span class="nx">run</span> <span class="nx">script</span><span class="p">.</span><span class="nx">innerHTML</span>
<span class="kc">null</span>
<span class="k">if</span> <span class="nb">window</span><span class="p">.</span><span class="nx">addEventListener</span>
<span class="nx">addEventListener</span> <span class="s1">&#39;DOMContentLoaded&#39;</span><span class="p">,</span> <span class="nx">processScripts</span><span class="p">,</span> <span class="kc">false</span>
<span class="k">else</span>
<span class="nx">attachEvent</span> <span class="s1">&#39;onload&#39;</span><span class="p">,</span> <span class="nx">processScripts</span>
</pre></div> </td> </tr> </tbody> </table> </div> </body> </html>

View File

@@ -33,7 +33,7 @@ If no tasks are passed, print the help screen.</p> </td>
<span class="nx">puts</span> <span class="s1">&#39;&#39;</span>
<span class="k">for</span> <span class="nx">all</span> <span class="nx">name</span><span class="p">,</span> <span class="nx">task</span> <span class="k">of</span> <span class="nx">tasks</span>
<span class="nv">spaces = </span><span class="mi">20</span> <span class="o">-</span> <span class="nx">name</span><span class="p">.</span><span class="nx">length</span>
<span class="nv">spaces = </span><span class="k">if</span> <span class="nx">spaces</span> <span class="o">&gt;</span> <span class="mi">0</span> <span class="k">then</span> <span class="p">(</span><span class="s1">&#39; &#39;</span> <span class="k">for</span> <span class="nx">i</span> <span class="k">in</span> <span class="p">[</span><span class="mi">0</span><span class="p">..</span><span class="nx">spaces</span><span class="p">]).</span><span class="nx">join</span><span class="p">(</span><span class="s1">&#39;&#39;</span><span class="p">)</span> <span class="k">else</span> <span class="s1">&#39;&#39;</span>
<span class="nv">spaces = </span><span class="k">if</span> <span class="nx">spaces</span> <span class="o">&gt;</span> <span class="mi">0</span> <span class="k">then</span> <span class="nb">Array</span><span class="p">(</span><span class="nx">spaces</span> <span class="o">+</span> <span class="mi">1</span><span class="p">).</span><span class="nx">join</span><span class="p">(</span><span class="s1">&#39; &#39;</span><span class="p">)</span> <span class="k">else</span> <span class="s1">&#39;&#39;</span>
<span class="nv">desc = </span><span class="k">if</span> <span class="nx">task</span><span class="p">.</span><span class="nx">description</span> <span class="k">then</span> <span class="s2">&quot;# #{task.description}&quot;</span> <span class="k">else</span> <span class="s1">&#39;&#39;</span>
<span class="nx">puts</span> <span class="s2">&quot;cake #{name}#{spaces} #{desc}&quot;</span>
<span class="nx">puts</span> <span class="nx">oparse</span><span class="p">.</span><span class="nx">help</span><span class="p">()</span> <span class="k">if</span> <span class="nx">switches</span><span class="p">.</span><span class="nx">length</span></pre></div> </td> </tr> <tr id="section-10"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-10">#</a> </div> <p>Print an error and exit when attempting to all an undefined task.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">missingTask = </span><span class="p">(</span><span class="nx">task</span><span class="p">)</span> <span class="o">-&gt;</span>

View File

@@ -4,19 +4,16 @@ contains the main entry functions for tokenzing, parsing, and compiling source
CoffeeScript into JavaScript.</p>
<p>If included on a webpage, it will automatically sniff out, compile, and
execute all scripts present in <code>text/coffeescript</code> tags.</p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-2"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-2">#</a> </div> <p>Set up dependencies correctly for both the server and the browser.</p> </td> <td class="code"> <div class="highlight"><pre><span class="k">if</span> <span class="nx">process</span><span class="o">?</span>
<span class="nv">path = </span><span class="nx">require</span> <span class="s1">&#39;path&#39;</span>
<span class="nv">Lexer = </span><span class="nx">require</span><span class="p">(</span><span class="s1">&#39;./lexer&#39;</span><span class="p">).</span><span class="nx">Lexer</span>
<span class="nv">parser = </span><span class="nx">require</span><span class="p">(</span><span class="s1">&#39;./parser&#39;</span><span class="p">).</span><span class="nx">parser</span>
<span class="nv">helpers = </span><span class="nx">require</span><span class="p">(</span><span class="s1">&#39;./helpers&#39;</span><span class="p">).</span><span class="nx">helpers</span>
<span class="nx">helpers</span><span class="p">.</span><span class="nx">extend</span> <span class="nx">global</span><span class="p">,</span> <span class="nx">require</span> <span class="s1">&#39;./nodes&#39;</span>
<span class="k">if</span> <span class="nx">require</span><span class="p">.</span><span class="nx">registerExtension</span>
<span class="nx">require</span><span class="p">.</span><span class="nx">registerExtension</span> <span class="s1">&#39;.coffee&#39;</span><span class="p">,</span> <span class="p">(</span><span class="nx">content</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nx">compile</span> <span class="nx">content</span>
<span class="k">else</span>
<span class="k">this</span><span class="p">.</span><span class="nv">exports = </span><span class="k">this</span><span class="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.9.3&#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>Compile a string of CoffeeScript code to JavaScript, using the Coffee/Jison
execute all scripts present in <code>text/coffeescript</code> tags.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">path = </span><span class="nx">require</span> <span class="s1">&#39;path&#39;</span>
<span class="p">{</span><span class="nx">Lexer</span><span class="p">}</span> <span class="o">=</span> <span class="nx">require</span> <span class="s1">&#39;./lexer&#39;</span>
<span class="p">{</span><span class="nx">parser</span><span class="p">}</span> <span class="o">=</span> <span class="nx">require</span> <span class="s1">&#39;./parser&#39;</span></pre></div> </td> </tr> <tr id="section-2"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-2">#</a> </div> <p>TODO: Remove registerExtension when fully deprecated</p> </td> <td class="code"> <div class="highlight"><pre><span class="k">if</span> <span class="nx">require</span><span class="p">.</span><span class="nx">extensions</span>
<span class="nv">fs = </span><span class="nx">require</span> <span class="s1">&#39;fs&#39;</span>
<span class="nx">require</span><span class="p">.</span><span class="nx">extensions</span><span class="p">[</span><span class="s1">&#39;.coffee&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="p">(</span><span class="nx">module</span><span class="p">,</span> <span class="nx">filename</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">content = </span><span class="nx">compile</span> <span class="nx">fs</span><span class="p">.</span><span class="nx">readFileSync</span> <span class="nx">filename</span><span class="p">,</span> <span class="s1">&#39;utf8&#39;</span>
<span class="nv">module.filename = </span><span class="s2">&quot;#{filename} (compiled)&quot;</span>
<span class="nx">module</span><span class="p">.</span><span class="nx">_compile</span> <span class="nx">content</span><span class="p">,</span> <span class="nx">module</span><span class="p">.</span><span class="nx">filename</span>
<span class="k">else</span> <span class="k">if</span> <span class="nx">require</span><span class="p">.</span><span class="nx">registerExtension</span>
<span class="nx">require</span><span class="p">.</span><span class="nx">registerExtension</span> <span class="s1">&#39;.coffee&#39;</span><span class="p">,</span> <span class="p">(</span><span class="nx">content</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nx">compile</span> <span class="nx">content</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.9.4&#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>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="nx">options</span> <span class="o">or=</span> <span class="p">{}</span>
<span class="k">try</span>
@@ -28,10 +25,13 @@ compiler.</p> </td> <td class="code"> <div
then compile it by calling <code>.compile()</code> on the root, or traverse it by using
<code>.traverse()</code> with a callback.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.nodes = </span><span class="p">(</span><span class="nx">code</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nx">parser</span><span class="p">.</span><span class="nx">parse</span> <span class="nx">lexer</span><span class="p">.</span><span class="nx">tokenize</span> <span class="nx">code</span></pre></div> </td> </tr> <tr id="section-7"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-7">#</a> </div> <p>Compile and execute a string of CoffeeScript (on the server), correctly
setting <code>__filename</code>, <code>__dirname</code>, and relative <code>require()</code>.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.run = </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">module.filename = __filename = </span><span class="nx">options</span><span class="p">.</span><span class="nx">fileName</span>
<span class="nv">__dirname = </span><span class="nx">path</span><span class="p">.</span><span class="nx">dirname</span> <span class="nx">__filename</span>
<span class="nb">eval</span> <span class="nx">exports</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">code</span><span class="p">,</span> <span class="nx">options</span></pre></div> </td> </tr> <tr id="section-8"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-8">#</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-9"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-9">#</a> </div> <p>The real Lexer produces a generic stream of tokens. This object provides a
setting <code>__filename</code>, <code>__dirname</code>, and relative <code>require()</code>.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.run = </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></pre></div> </td> </tr> <tr id="section-8"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-8">#</a> </div> <p>We want the root module.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">root = </span><span class="nx">module</span>
<span class="k">while</span> <span class="nx">root</span><span class="p">.</span><span class="nx">parent</span>
<span class="nv">root = </span><span class="nx">root</span><span class="p">.</span><span class="nx">parent</span></pre></div> </td> </tr> <tr id="section-9"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-9">#</a> </div> <p>Set the filename</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">root.filename = __filename = </span><span class="s2">&quot;#{options.fileName} (compiled)&quot;</span></pre></div> </td> </tr> <tr id="section-10"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-10">#</a> </div> <p>Clear the module cache</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">root.moduleCache = </span><span class="p">{}</span> <span class="k">if</span> <span class="nx">root</span><span class="p">.</span><span class="nx">moduleCache</span></pre></div> </td> </tr> <tr id="section-11"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-11">#</a> </div> <p>Compile</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">root</span><span class="p">.</span><span class="nx">_compile</span> <span class="nx">exports</span><span class="p">.</span><span class="nx">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="nx">root</span><span class="p">.</span><span class="nx">filename</span></pre></div> </td> </tr> <tr id="section-12"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-12">#</a> </div> <p>Compile and evaluate a string of CoffeeScript (in a Node.js-like environment).
The CoffeeScript REPL uses this to run the input.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.eval = </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">__filename = </span><span class="nx">options</span><span class="p">.</span><span class="nx">fileName</span>
<span class="nv">__dirname = </span><span class="nx">path</span><span class="p">.</span><span class="nx">dirname</span> <span class="nx">__filename</span>
<span class="nb">eval</span> <span class="nx">exports</span><span class="p">.</span><span class="nx">compile</span><span class="p">(</span><span class="nx">code</span><span class="p">,</span> <span class="nx">options</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>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-14"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-14">#</a> </div> <p>The real Lexer produces a generic stream of tokens. This object provides a
thin wrapper around it, compatible with the Jison API. We can then pass it
directly as a "Jison lexer".</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">parser.lexer =</span>
<span class="nx">lex</span><span class="o">:</span> <span class="o">-&gt;</span>
@@ -45,4 +45,6 @@ directly as a "Jison lexer".</p> </td> <td class="code">
<span class="vi">@pos = </span><span class="mi">0</span>
<span class="nx">upcomingInput</span><span class="o">:</span> <span class="o">-&gt;</span> <span class="s2">&quot;&quot;</span>
<span class="nv">parser.yy = </span><span class="nx">require</span> <span class="s1">&#39;./nodes&#39;</span>
</pre></div> </td> </tr> </tbody> </table> </div> </body> </html>

View File

@@ -21,6 +21,7 @@ optionally. If no action is specified, we simply pass the value of the
previous nonterminal.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">o = </span><span class="p">(</span><span class="nx">patternString</span><span class="p">,</span> <span class="nx">action</span><span class="p">,</span> <span class="nx">options</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="k">return</span> <span class="p">[</span><span class="nx">patternString</span><span class="p">,</span> <span class="s1">&#39;$$ = $1;&#39;</span><span class="p">,</span> <span class="nx">options</span><span class="p">]</span> <span class="nx">unless</span> <span class="nx">action</span>
<span class="nv">action = </span><span class="k">if</span> <span class="nv">match = </span><span class="p">(</span><span class="nx">action</span> <span class="o">+</span> <span class="s1">&#39;&#39;</span><span class="p">).</span><span class="nx">match</span><span class="p">(</span><span class="nx">unwrap</span><span class="p">)</span> <span class="k">then</span> <span class="nx">match</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="k">else</span> <span class="s2">&quot;(#{action}())&quot;</span>
<span class="nv">action = </span><span class="nx">action</span><span class="p">.</span><span class="nx">replace</span> <span class="sr">/\b(?:[A-Z][a-z]+Node|Expressions)\b/g</span><span class="p">,</span> <span class="s1">&#39;yy.$&amp;&#39;</span>
<span class="p">[</span><span class="nx">patternString</span><span class="p">,</span> <span class="s2">&quot;$$ = #{action};&quot;</span><span class="p">,</span> <span class="nx">options</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-6"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-6">#</a> </div> <h2>Grammatical Rules</h2> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-7"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-7">#</a> </div> <p>In all of the rules that follow, you'll see the name of the nonterminal as
the key to a list of alternative matches. With each match's action, the
dollar-sign variables are provided by Jison as references to the value of
@@ -182,6 +183,7 @@ and optional references to the superclass.</p> </td> <td
<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="nx">ClassAssign</span><span class="o">:</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 : 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="nx">o</span> <span class="s2">&quot;ThisProperty : INDENT Expression OUTDENT&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">$4</span><span class="p">,</span> <span class="s1">&#39;this&#39;</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="nx">ClassBody</span><span class="o">:</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>

View File

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

File diff suppressed because one or more lines are too long

View File

@@ -1,14 +1,7 @@
<!DOCTYPE html> <html> <head> <title>nodes.coffee</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <link rel="stylesheet" media="all" href="docco.css" /> </head> <body> <div id="container"> <div id="background"></div> <div id="jump_to"> Jump To &hellip; <div id="jump_wrapper"> <div id="jump_page"> <a class="source" href="browser.html"> browser.coffee </a> <a class="source" href="cake.html"> cake.coffee </a> <a class="source" href="coffee-script.html"> coffee-script.coffee </a> <a class="source" href="command.html"> command.coffee </a> <a class="source" href="grammar.html"> grammar.coffee </a> <a class="source" href="helpers.html"> helpers.coffee </a> <a class="source" href="index.html"> index.coffee </a> <a class="source" href="lexer.html"> lexer.coffee </a> <a class="source" href="nodes.html"> nodes.coffee </a> <a class="source" href="optparse.html"> optparse.coffee </a> <a class="source" href="repl.html"> repl.coffee </a> <a class="source" href="rewriter.html"> rewriter.coffee </a> <a class="source" href="scope.html"> scope.coffee </a> </div> </div> </div> <table cellpadding="0" cellspacing="0"> <thead> <tr> <th class="docs"> <h1> nodes.coffee </h1> </th> <th class="code"> </th> </tr> </thead> <tbody> <tr id="section-1"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-1">#</a> </div> <p><code>nodes.coffee</code> contains all of the node classes for the syntax tree. Most
nodes are created as the result of actions in the <a href="grammar.html">grammar</a>,
but some are created by other nodes as a method of code generation. To convert
the syntax tree into a string of JavaScript code, call <code>compile()</code> on the root.</p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-2"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-2">#</a> </div> <p>Set up for both <strong>Node.js</strong> and the browser, by
including the <a href="scope.html">Scope</a> class and the <a href="helpers.html">helper</a> functions.</p> </td> <td class="code"> <div class="highlight"><pre><span class="k">if</span> <span class="nx">process</span><span class="o">?</span>
<span class="nv">Scope = </span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;./scope&#39;</span><span class="p">).</span><span class="nx">Scope</span>
<span class="nv">helpers = </span><span class="nx">require</span><span class="p">(</span><span class="s1">&#39;./helpers&#39;</span><span class="p">).</span><span class="nx">helpers</span>
<span class="k">else</span>
<span class="k">this</span><span class="p">.</span><span class="nv">exports = </span><span class="k">this</span>
<span class="nv">helpers = </span> <span class="k">this</span><span class="p">.</span><span class="nx">helpers</span>
<span class="nv">Scope = </span> <span class="k">this</span><span class="p">.</span><span class="nx">Scope</span></pre></div> </td> </tr> <tr id="section-3"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-3">#</a> </div> <p>Import the helpers we plan to use.</p> </td> <td class="code"> <div class="highlight"><pre><span class="p">{</span><span class="nx">compact</span><span class="p">,</span> <span class="nx">flatten</span><span class="p">,</span> <span class="nx">merge</span><span class="p">,</span> <span class="nx">del</span><span class="p">,</span> <span class="nx">include</span><span class="p">,</span> <span class="nx">indexOf</span><span class="p">,</span> <span class="nx">starts</span><span class="p">,</span> <span class="nx">ends</span><span class="p">}</span> <span class="o">=</span> <span class="nx">helpers</span></pre></div> </td> </tr> <tr id="section-4"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-4">#</a> </div> <h3>BaseNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-5"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-5">#</a> </div> <p>The <strong>BaseNode</strong> is the abstract base class for all nodes in the syntax tree.
the syntax tree into a string of JavaScript code, call <code>compile()</code> on the root.</p> </td> <td class="code"> <div class="highlight"><pre><span class="p">{</span><span class="nx">Scope</span><span class="p">}</span> <span class="o">=</span> <span class="nx">require</span> <span class="s1">&#39;./scope&#39;</span></pre></div> </td> </tr> <tr id="section-2"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-2">#</a> </div> <p>Import the helpers we plan to use.</p> </td> <td class="code"> <div class="highlight"><pre><span class="p">{</span><span class="nx">compact</span><span class="p">,</span> <span class="nx">flatten</span><span class="p">,</span> <span class="nx">merge</span><span class="p">,</span> <span class="nx">del</span><span class="p">,</span> <span class="nx">include</span><span class="p">,</span> <span class="nx">indexOf</span><span class="p">,</span> <span class="nx">starts</span><span class="p">,</span> <span class="nx">ends</span><span class="p">}</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;./helpers&#39;</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> <h3>BaseNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-4"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-4">#</a> </div> <p>The <strong>BaseNode</strong> is the abstract base class for all nodes in the syntax tree.
Each subclass implements the <code>compileNode</code> method, which performs the
code generation for that node. To compile a node to JavaScript,
call <code>compile</code> on it, which wraps <code>compileNode</code> in some generic extra smarts,
@@ -19,7 +12,7 @@ being requested by the surrounding function), information about the current
scope, and indentation level.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.BaseNode = </span><span class="nx">class</span> <span class="nx">BaseNode</span>
<span class="nx">constructor</span><span class="o">:</span> <span class="o">-&gt;</span>
<span class="vi">@tags = </span><span class="p">{}</span></pre></div> </td> </tr> <tr id="section-6"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-6">#</a> </div> <p>Common logic for determining whether to wrap this node in a closure before
<span class="vi">@tags = </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>Common logic for determining whether to wrap this node in a closure before
compiling it, or to compile directly. We need to wrap if this node is a
<em>statement</em>, and it's not a <em>pureStatement</em>, and we're not at
the top level of a block (which would be unnecessary), and we haven't
@@ -36,11 +29,14 @@ top-level statement within the function body.</p> </td>
<span class="nv">closure = </span><span class="nx">@isStatement</span><span class="p">(</span><span class="nx">o</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="k">this</span> <span class="o">not</span> <span class="k">instanceof</span> <span class="nx">CommentNode</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
<span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">startLevel</span><span class="p">()</span> <span class="k">if</span> <span class="o">not</span> <span class="nx">o</span><span class="p">.</span><span class="nx">keepLevel</span>
<span class="nv">code = </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>
<span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">endLevel</span><span class="p">()</span> <span class="k">if</span> <span class="o">not</span> <span class="nx">o</span><span class="p">.</span><span class="nx">keepLevel</span>
<span class="nx">code</span></pre></div> </td> </tr> <tr id="section-6"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-6">#</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="nx">compileClosure</span><span class="o">:</span> <span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="vi">@tab = </span><span class="nx">o</span><span class="p">.</span><span class="nx">indent</span>
<span class="nv">o.sharedScope = </span><span class="nx">o</span><span class="p">.</span><span class="nx">scope</span>
<span class="nx">ClosureNode</span><span class="p">.</span><span class="nx">wrap</span><span class="p">(</span><span class="k">this</span><span class="p">).</span><span class="nx">compile</span> <span class="nx">o</span></pre></div> </td> </tr> <tr id="section-8"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-8">#</a> </div> <p>If the code generation wishes to use the result of a complex expression
<span class="nx">ClosureNode</span><span class="p">.</span><span class="nx">wrap</span><span class="p">(</span><span class="k">this</span><span class="p">).</span><span class="nx">compile</span> <span class="nx">o</span></pre></div> </td> </tr> <tr id="section-7"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-7">#</a> </div> <p>If the code generation wishes to use the result of a complex expression
in multiple places, ensure that the expression is only ever evaluated once,
by assigning it to a temporary variable.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">compileReference</span><span class="o">:</span> <span class="p">(</span><span class="nx">o</span><span class="p">,</span> <span class="nx">options</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nx">options</span> <span class="o">or=</span> <span class="p">{}</span>
@@ -50,18 +46,18 @@ by assigning it to a temporary variable.</p> </td> <td c
<span class="k">else</span> <span class="k">if</span> <span class="k">this</span> <span class="k">instanceof</span> <span class="nx">ValueNode</span> <span class="o">and</span> <span class="nx">options</span><span class="p">.</span><span class="nx">assignment</span>
<span class="k">this</span><span class="p">.</span><span class="nx">cacheIndexes</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span>
<span class="k">else</span>
<span class="nv">reference = </span><span class="nx">literal</span> <span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span><span class="p">()</span>
<span class="nv">reference = </span><span class="nx">literal</span> <span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span> <span class="s1">&#39;ref&#39;</span>
<span class="nv">compiled = </span><span class="k">new</span> <span class="nx">AssignNode</span> <span class="nx">reference</span><span class="p">,</span> <span class="k">this</span>
<span class="p">[</span><span class="nx">compiled</span><span class="p">,</span> <span class="nx">reference</span><span class="p">]</span>
<span class="k">return</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="nx">compile</span><span class="p">(</span><span class="nx">o</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="nx">compile</span><span class="p">(</span><span class="nx">o</span><span class="p">)]</span> <span class="k">if</span> <span class="nx">options</span><span class="p">.</span><span class="nx">precompile</span>
<span class="nx">pair</span></pre></div> </td> </tr> <tr id="section-9"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-9">#</a> </div> <p>Convenience method to grab the current indentation level, plus tabbing in.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">idt</span><span class="o">:</span> <span class="p">(</span><span class="nx">tabs</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nx">pair</span></pre></div> </td> </tr> <tr id="section-8"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-8">#</a> </div> <p>Convenience method to grab the current indentation level, plus tabbing in.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">idt</span><span class="o">:</span> <span class="p">(</span><span class="nx">tabs</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">idt = </span><span class="nx">@tab</span> <span class="o">or</span> <span class="s1">&#39;&#39;</span>
<span class="nv">num = </span><span class="p">(</span><span class="nx">tabs</span> <span class="o">or</span> <span class="mi">0</span><span class="p">)</span> <span class="o">+</span> <span class="mi">1</span>
<span class="nx">idt</span> <span class="o">+=</span> <span class="nx">TAB</span> <span class="k">while</span> <span class="nx">num</span> <span class="o">-=</span> <span class="mi">1</span>
<span class="nx">idt</span></pre></div> </td> </tr> <tr id="section-10"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-10">#</a> </div> <p>Construct a node that returns the current node's result.
<span class="nx">idt</span></pre></div> </td> </tr> <tr id="section-9"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-9">#</a> </div> <p>Construct a node that returns the current node's result.
Note that this is overridden for smarter behavior for
many statement nodes (eg IfNode, ForNode)...</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">makeReturn</span><span class="o">:</span> <span class="o">-&gt;</span>
<span class="k">new</span> <span class="nx">ReturnNode</span> <span class="k">this</span></pre></div> </td> </tr> <tr id="section-11"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-11">#</a> </div> <p>Does this node, or any of its children, contain a node of a certain kind?
<span class="k">new</span> <span class="nx">ReturnNode</span> <span class="k">this</span></pre></div> </td> </tr> <tr id="section-10"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-10">#</a> </div> <p>Does this node, or any of its children, contain a node of a certain kind?
Recursively traverses down the <em>children</em> of the nodes, yielding to a block
and returning true when the block finds a match. <code>contains</code> does not cross
scope boundaries.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">contains</span><span class="o">:</span> <span class="p">(</span><span class="nx">block</span><span class="p">)</span> <span class="o">-&gt;</span>
@@ -70,10 +66,10 @@ scope boundaries.</p> </td> <td class="code">
<span class="k">if</span> <span class="nx">block</span><span class="p">(</span><span class="nx">node</span><span class="p">)</span>
<span class="nv">contains = </span><span class="kc">true</span>
<span class="k">return</span> <span class="kc">false</span>
<span class="nx">contains</span></pre></div> </td> </tr> <tr id="section-12"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-12">#</a> </div> <p>Is this node of a certain type, or does it contain the type?</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">containsType</span><span class="o">:</span> <span class="p">(</span><span class="nx">type</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="k">this</span> <span class="k">instanceof</span> <span class="nx">type</span> <span class="o">or</span> <span class="nx">@contains</span> <span class="p">(</span><span class="nx">n</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nx">n</span> <span class="k">instanceof</span> <span class="nx">type</span></pre></div> </td> </tr> <tr id="section-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
<span class="nx">contains</span></pre></div> </td> </tr> <tr id="section-11"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-11">#</a> </div> <p>Is this node of a certain type, or does it contain the type?</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">containsType</span><span class="o">:</span> <span class="p">(</span><span class="nx">type</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="k">this</span> <span class="k">instanceof</span> <span class="nx">type</span> <span class="o">or</span> <span class="nx">@contains</span> <span class="p">(</span><span class="nx">n</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nx">n</span> <span class="k">instanceof</span> <span class="nx">type</span></pre></div> </td> </tr> <tr id="section-12"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-12">#</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="nx">containsPureStatement</span><span class="o">:</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="o">and</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="nx">traverse</span><span class="o">:</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.
<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="o">and</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-13"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-13">#</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="nx">traverse</span><span class="o">:</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-14"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-14">#</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="nx">toString</span><span class="o">:</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="nx">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="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>
@@ -93,14 +89,14 @@ This is what <code>coffee --nodes</code> prints out.</p> </td>
<span class="nx">traverseChildren</span><span class="o">:</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="nx">@eachChild</span> <span class="p">(</span><span class="nx">child</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nx">func</span><span class="p">.</span><span class="nx">apply</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="nx">arguments</span><span class="p">)</span>
<span class="nx">child</span><span class="p">.</span><span class="nx">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="k">if</span> <span class="nx">child</span> <span class="k">instanceof</span> <span class="nx">BaseNode</span></pre></div> </td> </tr> <tr id="section-16"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-16">#</a> </div> <p>Default implementations of the common node properties and methods. Nodes
<span class="nx">child</span><span class="p">.</span><span class="nx">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="k">if</span> <span class="nx">child</span> <span class="k">instanceof</span> <span class="nx">BaseNode</span></pre></div> </td> </tr> <tr id="section-15"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-15">#</a> </div> <p>Default implementations of the common node properties and methods. Nodes
will override these with custom logic, if needed.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">class</span><span class="o">:</span> <span class="s1">&#39;BaseNode&#39;</span>
<span class="nx">children</span><span class="o">:</span> <span class="p">[]</span>
<span class="nx">unwrap</span> <span class="o">:</span> <span class="o">-&gt;</span> <span class="k">this</span>
<span class="nx">isStatement</span> <span class="o">:</span> <span class="o">-&gt;</span> <span class="kc">no</span>
<span class="nx">isPureStatement</span> <span class="o">:</span> <span class="o">-&gt;</span> <span class="kc">no</span>
<span class="nx">topSensitive</span> <span class="o">:</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
<span class="nx">topSensitive</span> <span class="o">:</span> <span class="o">-&gt;</span> <span class="kc">no</span></pre></div> </td> </tr> <tr id="section-16"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-16">#</a> </div> <h3>Expressions</h3> </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>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>
@@ -110,26 +106,26 @@ indented block of code -- the implementation of a function, a clause in an
<span class="nx">constructor</span><span class="o">:</span> <span class="p">(</span><span class="nx">nodes</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="k">super</span><span class="p">()</span>
<span class="vi">@expressions = </span><span class="nx">compact</span> <span class="nx">flatten</span> <span class="nx">nodes</span> <span class="o">or</span> <span class="p">[]</span></pre></div> </td> </tr> <tr id="section-19"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-19">#</a> </div> <p>Tack an expression on to the end of this expression list.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">push</span><span class="o">:</span> <span class="p">(</span><span class="nx">node</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="vi">@expressions = </span><span class="nx">compact</span> <span class="nx">flatten</span> <span class="nx">nodes</span> <span class="o">or</span> <span class="p">[]</span></pre></div> </td> </tr> <tr id="section-18"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-18">#</a> </div> <p>Tack an expression on to the end of this expression list.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">push</span><span class="o">:</span> <span class="p">(</span><span class="nx">node</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nx">@expressions</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">node</span><span class="p">)</span>
<span class="k">this</span></pre></div> </td> </tr> <tr id="section-20"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-20">#</a> </div> <p>Add an expression at the beginning of this expression list.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">unshift</span><span class="o">:</span> <span class="p">(</span><span class="nx">node</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="k">this</span></pre></div> </td> </tr> <tr id="section-19"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-19">#</a> </div> <p>Add an expression at the beginning of this expression list.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">unshift</span><span class="o">:</span> <span class="p">(</span><span class="nx">node</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nx">@expressions</span><span class="p">.</span><span class="nx">unshift</span><span class="p">(</span><span class="nx">node</span><span class="p">)</span>
<span class="k">this</span></pre></div> </td> </tr> <tr id="section-21"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-21">#</a> </div> <p>If this Expressions consists of just a single node, unwrap it by pulling
<span class="k">this</span></pre></div> </td> </tr> <tr id="section-20"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-20">#</a> </div> <p>If this Expressions consists of just a single node, unwrap it by pulling
it back out.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">unwrap</span><span class="o">:</span> <span class="o">-&gt;</span>
<span class="k">if</span> <span class="nx">@expressions</span><span class="p">.</span><span class="nx">length</span> <span class="o">is</span> <span class="mi">1</span> <span class="k">then</span> <span class="nx">@expressions</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">else</span> <span class="k">this</span></pre></div> </td> </tr> <tr id="section-22"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-22">#</a> </div> <p>Is this an empty block of code?</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">empty</span><span class="o">:</span> <span class="o">-&gt;</span>
<span class="nx">@expressions</span><span class="p">.</span><span class="nx">length</span> <span class="o">is</span> <span class="mi">0</span></pre></div> </td> </tr> <tr id="section-23"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-23">#</a> </div> <p>An Expressions node does not return its entire body, rather it
<span class="k">if</span> <span class="nx">@expressions</span><span class="p">.</span><span class="nx">length</span> <span class="o">is</span> <span class="mi">1</span> <span class="k">then</span> <span class="nx">@expressions</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">else</span> <span class="k">this</span></pre></div> </td> </tr> <tr id="section-21"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-21">#</a> </div> <p>Is this an empty block of code?</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">empty</span><span class="o">:</span> <span class="o">-&gt;</span>
<span class="nx">@expressions</span><span class="p">.</span><span class="nx">length</span> <span class="o">is</span> <span class="mi">0</span></pre></div> </td> </tr> <tr id="section-22"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-22">#</a> </div> <p>An Expressions node does not return its entire body, rather it
ensures that the final expression is returned.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">makeReturn</span><span class="o">:</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="nx">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="nx">compile</span><span class="o">:</span> <span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="k">this</span></pre></div> </td> </tr> <tr id="section-23"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-23">#</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="nx">compile</span><span class="o">:</span> <span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nx">o</span> <span class="o">or=</span> <span class="p">{}</span>
<span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">scope</span> <span class="k">then</span> <span class="k">super</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="k">else</span> <span class="nx">@compileRoot</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span>
<span class="nx">compileNode</span><span class="o">:</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">@compileExpression</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="nx">merge</span><span class="p">(</span><span class="nx">o</span><span class="p">))</span> <span class="k">for</span> <span class="nx">node</span> <span class="k">in</span> <span class="nx">@expressions</span><span class="p">).</span><span class="nx">join</span><span class="p">(</span><span class="s2">&quot;\n&quot;</span><span class="p">)</span></pre></div> </td> </tr> <tr id="section-25"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-25">#</a> </div> <p>If we happen to be the top-level <strong>Expressions</strong>, wrap everything in
<span class="p">(</span><span class="nx">@compileExpression</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="nx">merge</span><span class="p">(</span><span class="nx">o</span><span class="p">))</span> <span class="k">for</span> <span class="nx">node</span> <span class="k">in</span> <span class="nx">@expressions</span><span class="p">).</span><span class="nx">join</span><span class="p">(</span><span class="s2">&quot;\n&quot;</span><span class="p">)</span></pre></div> </td> </tr> <tr id="section-24"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-24">#</a> </div> <p>If we happen to be the top-level <strong>Expressions</strong>, wrap everything in
a safety closure, unless requested not to.
It would be better not to generate them in the first place, but for now,
clean up obvious double-parentheses.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">compileRoot</span><span class="o">:</span> <span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
@@ -137,20 +133,20 @@ clean up obvious double-parentheses.</p> </td> <td class
<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="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="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
<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}).call(this);\n&quot;</span></pre></div> </td> </tr> <tr id="section-25"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-25">#</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="nx">compileWithDeclarations</span><span class="o">:</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="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
<span class="nx">code</span></pre></div> </td> </tr> <tr id="section-26"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-26">#</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="nx">compileExpression</span><span class="o">:</span> <span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="vi">@tab = </span><span class="nx">o</span><span class="p">.</span><span class="nx">indent</span>
<span class="nv">compiledNode = </span><span class="nx">node</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">merge</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">top</span><span class="o">:</span> <span class="kc">true</span>
<span class="k">if</span> <span class="nx">node</span><span class="p">.</span><span class="nx">isStatement</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="k">then</span> <span class="nx">compiledNode</span> <span class="k">else</span> <span class="s2">&quot;#{@idt()}#{compiledNode};&quot;</span></pre></div> </td> </tr> <tr id="section-28"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-28">#</a> </div> <p>Wrap up the given nodes as an <strong>Expressions</strong>, unless it already happens
<span class="k">if</span> <span class="nx">node</span><span class="p">.</span><span class="nx">isStatement</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="k">then</span> <span class="nx">compiledNode</span> <span class="k">else</span> <span class="s2">&quot;#{@idt()}#{compiledNode};&quot;</span></pre></div> </td> </tr> <tr id="section-27"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-27">#</a> </div> <p>Wrap up the given nodes as an <strong>Expressions</strong>, unless it already happens
to be one.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">Expressions.wrap = </span><span class="p">(</span><span class="nx">nodes</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="k">return</span> <span class="nx">nodes</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">if</span> <span class="nx">nodes</span><span class="p">.</span><span class="nx">length</span> <span class="o">is</span> <span class="mi">1</span> <span class="o">and</span> <span class="nx">nodes</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">instanceof</span> <span class="nx">Expressions</span>
<span class="k">new</span> <span class="nx">Expressions</span><span class="p">(</span><span class="nx">nodes</span><span class="p">)</span></pre></div> </td> </tr> <tr id="section-29"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-29">#</a> </div> <h3>LiteralNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-30"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-30">#</a> </div> <p>Literals are static values that can be passed through directly into
<span class="k">new</span> <span class="nx">Expressions</span><span class="p">(</span><span class="nx">nodes</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> <h3>LiteralNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-29"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-29">#</a> </div> <p>Literals are static values that can be passed through directly into
JavaScript without translation, such as: strings, numbers,
<code>true</code>, <code>false</code>, <code>null</code>...</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.LiteralNode = </span><span class="nx">class</span> <span class="nx">LiteralNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span>
@@ -160,7 +156,7 @@ JavaScript without translation, such as: strings, numbers,
<span class="k">super</span><span class="p">()</span>
<span class="nx">makeReturn</span><span class="o">:</span> <span class="o">-&gt;</span>
<span class="k">if</span> <span class="nx">@isStatement</span><span class="p">()</span> <span class="k">then</span> <span class="k">this</span> <span class="k">else</span> <span class="k">super</span><span class="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>Break and continue must be treated as pure statements -- they lose their
<span class="k">if</span> <span class="nx">@isStatement</span><span class="p">()</span> <span class="k">then</span> <span class="k">this</span> <span class="k">else</span> <span class="k">super</span><span class="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>Break and continue must be treated as pure statements -- they lose their
meaning when wrapped in a closure.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">isStatement</span><span class="o">:</span> <span class="o">-&gt;</span>
<span class="nx">@value</span> <span class="o">is</span> <span class="s1">&#39;break&#39;</span> <span class="o">or</span> <span class="nx">@value</span> <span class="o">is</span> <span class="s1">&#39;continue&#39;</span> <span class="o">or</span> <span class="nx">@value</span> <span class="o">is</span> <span class="s1">&#39;debugger&#39;</span>
<span class="nx">isPureStatement</span><span class="o">:</span> <span class="nx">LiteralNode</span><span class="o">::</span><span class="nx">isStatement</span>
@@ -171,7 +167,7 @@ meaning when wrapped in a closure.</p> </td> <td class="
<span class="nx">idt</span> <span class="o">+</span> <span class="nx">@value</span> <span class="o">+</span> <span class="nx">end</span>
<span class="nx">toString</span><span class="o">:</span> <span class="p">(</span><span class="nx">idt</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="s1">&#39;&quot;&#39;</span> <span class="o">+</span> <span class="nx">@value</span> <span class="o">+</span> <span class="s1">&#39;&quot;&#39;</span></pre></div> </td> </tr> <tr id="section-32"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-32">#</a> </div> <h3>ReturnNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-33"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-33">#</a> </div> <p>A <code>return</code> is a <em>pureStatement</em> -- wrapping it in a closure wouldn't
<span class="s1">&#39;&quot;&#39;</span> <span class="o">+</span> <span class="nx">@value</span> <span class="o">+</span> <span class="s1">&#39;&quot;&#39;</span></pre></div> </td> </tr> <tr id="section-31"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-31">#</a> </div> <h3>ReturnNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-32"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-32">#</a> </div> <p>A <code>return</code> is a <em>pureStatement</em> -- wrapping it in a closure wouldn't
make sense.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.ReturnNode = </span><span class="nx">class</span> <span class="nx">ReturnNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span>
<span class="nx">class</span><span class="o">:</span> <span class="s1">&#39;ReturnNode&#39;</span>
@@ -192,18 +188,18 @@ make sense.</p> </td> <td class="code"> <d
<span class="nx">compileNode</span><span class="o">:</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="nx">o</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,
<span class="s2">&quot;#{@tab}return #{@expression.compile(o)};&quot;</span></pre></div> </td> </tr> <tr id="section-33"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-33">#</a> </div> <h3>ValueNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-34"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-34">#</a> </div> <p>A value, variable or literal or parenthesized, indexed or dotted into,
or vanilla.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.ValueNode = </span><span class="nx">class</span> <span class="nx">ValueNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span>
<span class="nx">class</span><span class="o">:</span> <span class="s1">&#39;ValueNode&#39;</span>
<span class="nx">children</span><span class="o">:</span> <span class="p">[</span><span class="s1">&#39;base&#39;</span><span class="p">,</span> <span class="s1">&#39;properties&#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 <strong>ValueNode</strong> has a base and a list of property accesses.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">constructor</span><span class="o">:</span> <span class="p">(</span><span class="nx">@base</span><span class="p">,</span> <span class="nx">@properties</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nx">children</span><span class="o">:</span> <span class="p">[</span><span class="s1">&#39;base&#39;</span><span class="p">,</span> <span class="s1">&#39;properties&#39;</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>A <strong>ValueNode</strong> has a base and a list of property accesses.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">constructor</span><span class="o">:</span> <span class="p">(</span><span class="nx">@base</span><span class="p">,</span> <span class="nx">@properties</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="k">super</span><span class="p">()</span>
<span class="nx">@properties</span> <span class="o">or=</span> <span class="p">[]</span></pre></div> </td> </tr> <tr id="section-37"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-37">#</a> </div> <p>Add a property access to the list.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">push</span><span class="o">:</span> <span class="p">(</span><span class="nx">prop</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nx">@properties</span> <span class="o">or=</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>Add a property access to the list.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">push</span><span class="o">:</span> <span class="p">(</span><span class="nx">prop</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nx">@properties</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">prop</span><span class="p">)</span>
<span class="k">this</span>
<span class="nx">hasProperties</span><span class="o">:</span> <span class="o">-&gt;</span>
<span class="o">!!</span><span class="nx">@properties</span><span class="p">.</span><span class="nx">length</span></pre></div> </td> </tr> <tr id="section-38"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-38">#</a> </div> <p>Some boolean checks for the benefit of other nodes.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">isArray</span><span class="o">:</span> <span class="o">-&gt;</span>
<span class="o">!!</span><span class="nx">@properties</span><span class="p">.</span><span class="nx">length</span></pre></div> </td> </tr> <tr id="section-37"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-37">#</a> </div> <p>Some boolean checks for the benefit of other nodes.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">isArray</span><span class="o">:</span> <span class="o">-&gt;</span>
<span class="nx">@base</span> <span class="k">instanceof</span> <span class="nx">ArrayNode</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">@hasProperties</span><span class="p">()</span>
<span class="nx">isObject</span><span class="o">:</span> <span class="o">-&gt;</span>
@@ -213,13 +209,13 @@ or vanilla.</p> </td> <td class="code"> <d
<span class="nx">@hasProperties</span><span class="p">()</span> <span class="o">and</span> <span class="nx">@properties</span><span class="p">[</span><span class="nx">@properties</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]</span> <span class="k">instanceof</span> <span class="nx">SliceNode</span>
<span class="nx">makeReturn</span><span class="o">:</span> <span class="o">-&gt;</span>
<span class="k">if</span> <span class="nx">@hasProperties</span><span class="p">()</span> <span class="k">then</span> <span class="k">super</span><span class="p">()</span> <span class="k">else</span> <span class="nx">@base</span><span class="p">.</span><span class="nx">makeReturn</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>The value can be unwrapped as its inner node, if there are no attached
<span class="k">if</span> <span class="nx">@hasProperties</span><span class="p">()</span> <span class="k">then</span> <span class="k">super</span><span class="p">()</span> <span class="k">else</span> <span class="nx">@base</span><span class="p">.</span><span class="nx">makeReturn</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>The value can be unwrapped as its inner node, if there are no attached
properties.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">unwrap</span><span class="o">:</span> <span class="o">-&gt;</span>
<span class="k">if</span> <span class="nx">@properties</span><span class="p">.</span><span class="nx">length</span> <span class="k">then</span> <span class="k">this</span> <span class="k">else</span> <span class="nx">@base</span></pre></div> </td> </tr> <tr id="section-40"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-40">#</a> </div> <p>Values are considered to be statements if their base is a statement.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">isStatement</span><span class="o">:</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">@properties</span><span class="p">.</span><span class="nx">length</span> <span class="k">then</span> <span class="k">this</span> <span class="k">else</span> <span class="nx">@base</span></pre></div> </td> </tr> <tr id="section-39"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-39">#</a> </div> <p>Values are considered to be statements if their base is a statement.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">isStatement</span><span class="o">:</span> <span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nx">@base</span><span class="p">.</span><span class="nx">isStatement</span> <span class="o">and</span> <span class="nx">@base</span><span class="p">.</span><span class="nx">isStatement</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">@hasProperties</span><span class="p">()</span>
<span class="nx">isNumber</span><span class="o">:</span> <span class="o">-&gt;</span>
<span class="nx">@base</span> <span class="k">instanceof</span> <span class="nx">LiteralNode</span> <span class="o">and</span> <span class="nx">@base</span><span class="p">.</span><span class="nx">value</span><span class="p">.</span><span class="nx">match</span> <span class="nx">NUMBER</span></pre></div> </td> </tr> <tr id="section-41"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-41">#</a> </div> <p>If the value node has indexes containing function calls, and the value node
<span class="nx">@base</span> <span class="k">instanceof</span> <span class="nx">LiteralNode</span> <span class="o">and</span> <span class="nx">@base</span><span class="p">.</span><span class="nx">value</span><span class="p">.</span><span class="nx">match</span> <span class="nx">NUMBER</span></pre></div> </td> </tr> <tr id="section-40"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-40">#</a> </div> <p>If the value node has indexes containing function calls, and the value node
needs to be used twice, in compound assignment ... then we need to cache
the value of the indexes.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">cacheIndexes</span><span class="o">:</span> <span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">copy = </span><span class="k">new</span> <span class="nx">ValueNode</span> <span class="nx">@base</span><span class="p">,</span> <span class="nx">@properties</span><span class="p">[</span><span class="mi">0</span><span class="p">..]</span>
@@ -230,8 +226,8 @@ the value of the indexes.</p> </td> <td class="code">
<span class="p">[</span><span class="nx">index</span><span class="p">,</span> <span class="nx">indexVar</span><span class="p">]</span> <span class="o">=</span> <span class="nx">prop</span><span class="p">.</span><span class="nx">index</span><span class="p">.</span><span class="nx">compileReference</span> <span class="nx">o</span>
<span class="k">this</span><span class="p">.</span><span class="nx">properties</span><span class="p">[</span><span class="nx">i</span><span class="p">]</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">IndexNode</span> <span class="nx">index</span>
<span class="nx">copy</span><span class="p">.</span><span class="nx">properties</span><span class="p">[</span><span class="nx">i</span><span class="p">]</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">IndexNode</span> <span class="nx">indexVar</span>
<span class="p">[</span><span class="k">this</span><span class="p">,</span> <span class="nx">copy</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>Override compile to unwrap the value when possible.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">compile</span><span class="o">:</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.
<span class="p">[</span><span class="k">this</span><span class="p">,</span> <span class="nx">copy</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>Override compile to unwrap the value when possible.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">compile</span><span class="o">:</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-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.
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="nx">compileNode</span><span class="o">:</span> <span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
@@ -252,7 +248,7 @@ evaluate a anything twice when building the soak chain.</p> </td>
<span class="vi">@source = </span><span class="nx">baseline</span>
<span class="k">if</span> <span class="nx">prop</span><span class="p">.</span><span class="nx">soakNode</span>
<span class="k">if</span> <span class="nx">@base</span><span class="p">.</span><span class="nx">containsType</span><span class="p">(</span><span class="nx">CallNode</span><span class="p">)</span> <span class="o">and</span> <span class="nx">i</span> <span class="o">is</span> <span class="mi">0</span>
<span class="nv">temp = </span><span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span><span class="p">()</span>
<span class="nv">temp = </span><span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span> <span class="s1">&#39;ref&#39;</span>
<span class="nv">complete = </span><span class="s2">&quot;(#{ baseline = temp } = (#{complete}))&quot;</span>
<span class="nv">complete = </span><span class="k">if</span> <span class="nx">i</span> <span class="o">is</span> <span class="mi">0</span>
<span class="s2">&quot;(typeof #{complete} === \&quot;undefined\&quot; || #{baseline} === null) ? undefined : &quot;</span>
@@ -268,7 +264,7 @@ evaluate a anything twice when building the soak chain.</p> </td>
<span class="nx">complete</span> <span class="o">+=</span> <span class="nx">part</span>
<span class="vi">@last = </span><span class="nx">part</span>
<span class="k">if</span> <span class="nx">op</span> <span class="o">and</span> <span class="nx">@wrapped</span> <span class="k">then</span> <span class="s2">&quot;(#{complete})&quot;</span> <span class="k">else</span> <span class="nx">complete</span></pre></div> </td> </tr> <tr id="section-44"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-44">#</a> </div> <h3>CommentNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-45"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-45">#</a> </div> <p>CoffeeScript passes through block comments as JavaScript block comments
<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>CommentNode</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>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="nx">class</span><span class="o">:</span> <span class="s1">&#39;CommentNode&#39;</span>
@@ -281,7 +277,7 @@ at the same position.</p> </td> <td class="code">
<span class="k">this</span>
<span class="nx">compileNode</span><span class="o">:</span> <span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nx">@tab</span> <span class="o">+</span> <span class="s1">&#39;/*&#39;</span> <span class="o">+</span> <span class="nx">@comment</span><span class="p">.</span><span class="nx">replace</span><span class="p">(</span><span class="sr">/\r?\n/g</span><span class="p">,</span> <span class="s1">&#39;\n&#39;</span> <span class="o">+</span> <span class="nx">@tab</span><span class="p">)</span> <span class="o">+</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> <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
<span class="nx">@tab</span> <span class="o">+</span> <span class="s1">&#39;/*&#39;</span> <span class="o">+</span> <span class="nx">@comment</span><span class="p">.</span><span class="nx">replace</span><span class="p">(</span><span class="sr">/\r?\n/g</span><span class="p">,</span> <span class="s1">&#39;\n&#39;</span> <span class="o">+</span> <span class="nx">@tab</span><span class="p">)</span> <span class="o">+</span> <span class="s1">&#39;*/&#39;</span></pre></div> </td> </tr> <tr id="section-45"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-45">#</a> </div> <h3>CallNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-46"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-46">#</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="nx">class</span><span class="o">:</span> <span class="s1">&#39;CallNode&#39;</span>
@@ -295,26 +291,33 @@ calls against the prototype's function of the same name.</p> </td>
<span class="nx">@args</span> <span class="o">or=</span> <span class="p">[]</span>
<span class="vi">@first = @last = </span><span class="s1">&#39;&#39;</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">compileSplattedArray</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="nx">newInstance</span><span class="o">:</span> <span class="o">-&gt;</span>
<span class="nx">SplatNode</span><span class="p">.</span><span class="nx">compileSplattedArray</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-47"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-47">#</a> </div> <p>Tag this invocation as creating a new instance.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">newInstance</span><span class="o">:</span> <span class="o">-&gt;</span>
<span class="vi">@isNew = </span><span class="kc">true</span>
<span class="k">this</span>
<span class="nx">prefix</span><span class="o">:</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="nx">superReference</span><span class="o">:</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-48"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-48">#</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="nx">superReference</span><span class="o">:</span> <span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="k">throw</span> <span class="k">new</span> <span class="nb">Error</span> <span class="s2">&quot;cannot call super outside of a function&quot;</span> <span class="nx">unless</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="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}.__super__.#{methname}&quot;</span>
<span class="k">else</span> <span class="k">if</span> <span class="nx">methname</span>
<span class="s2">&quot;#{methname}.__super__.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-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="nx">compileNode</span><span class="o">:</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-49"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-49">#</a> </div> <p>Compile a vanilla function call.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">compileNode</span><span class="o">:</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="nv">op = </span><span class="nx">@tags</span><span class="p">.</span><span class="nx">operation</span>
<span class="k">if</span> <span class="nx">@exist</span>
<span class="p">[</span><span class="nx">@first</span><span class="p">,</span> <span class="nx">@meth</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="p">,</span> <span class="nx">precompile</span><span class="o">:</span> <span class="kc">yes</span>
<span class="k">if</span> <span class="nx">@variable</span> <span class="k">instanceof</span> <span class="nx">ValueNode</span> <span class="o">and</span> <span class="nx">@variable</span><span class="p">.</span><span class="nx">properties</span><span class="p">[</span><span class="nx">@variable</span><span class="p">.</span><span class="nx">properties</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]</span> <span class="k">instanceof</span> <span class="nx">AccessorNode</span>
<span class="nv">methodAccessor = </span><span class="nx">@variable</span><span class="p">.</span><span class="nx">properties</span><span class="p">.</span><span class="nx">pop</span><span class="p">()</span>
<span class="p">[</span><span class="nx">first</span><span class="p">,</span> <span class="nx">meth</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="vi">@first = </span><span class="k">new</span> <span class="nx">ValueNode</span><span class="p">(</span><span class="nx">first</span><span class="p">,</span> <span class="p">[</span><span class="nx">methodAccessor</span><span class="p">]).</span><span class="nx">compile</span> <span class="nx">o</span>
<span class="vi">@meth = </span><span class="k">new</span> <span class="nx">ValueNode</span><span class="p">(</span><span class="nx">meth</span><span class="p">,</span> <span class="p">[</span><span class="nx">methodAccessor</span><span class="p">]).</span><span class="nx">compile</span> <span class="nx">o</span>
<span class="k">else</span>
<span class="p">[</span><span class="nx">@first</span><span class="p">,</span> <span class="nx">@meth</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="p">,</span> <span class="nx">precompile</span><span class="o">:</span> <span class="kc">yes</span>
<span class="vi">@first = </span><span class="s2">&quot;(typeof #{@first} === \&quot;function\&quot; ? &quot;</span>
<span class="vi">@last = </span><span class="s2">&quot; : undefined)&quot;</span>
<span class="k">else</span> <span class="k">if</span> <span class="nx">@variable</span> <span class="k">then</span> <span class="vi">@meth = </span><span class="nx">@variable</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">o</span>
<span class="k">else</span> <span class="k">if</span> <span class="nx">@variable</span>
<span class="vi">@meth = </span><span class="nx">@variable</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">o</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">code = </span><span class="nx">@compileSplat</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span>
<span class="k">if</span> <span class="o">not</span> <span class="nx">code</span>
@@ -325,16 +328,16 @@ calls against the prototype's function of the same name.</p> </td>
<span class="nx">@compileSuper</span><span class="p">(</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="nx">o</span><span class="p">)</span>
<span class="k">else</span>
<span class="s2">&quot;#{@first}#{@prefix()}#{@meth}(#{ args.join(&#39;, &#39;) })#{@last}&quot;</span>
<span class="k">if</span> <span class="nx">op</span> <span class="o">and</span> <span class="nx">@variable</span> <span class="o">and</span> <span class="nx">@variable</span><span class="p">.</span><span class="nx">wrapped</span> <span class="k">then</span> <span class="s2">&quot;(#{code})&quot;</span> <span class="k">else</span> <span class="nx">code</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
<span class="k">if</span> <span class="nx">op</span> <span class="o">and</span> <span class="nx">@variable</span> <span class="o">and</span> <span class="nx">@variable</span><span class="p">.</span><span class="nx">wrapped</span> <span class="k">then</span> <span class="s2">&quot;(#{code})&quot;</span> <span class="k">else</span> <span class="nx">code</span></pre></div> </td> </tr> <tr id="section-50"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-50">#</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="nx">compileSuper</span><span class="o">:</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-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
<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-51"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-51">#</a> </div> <p>If you call a function with a splat, it's converted into a JavaScript
<code>.apply()</code> call to allow an array of arguments to be passed.
If it's a constructor, then things get real tricky. We have to inject an
inner constructor in order to be able to pass the varargs.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">compileSplat</span><span class="o">:</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="nx">@meth</span> <span class="o">or</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>
<span class="k">if</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">match</span><span class="p">(</span><span class="sr">/\(/</span><span class="p">)</span>
<span class="nv">temp = </span><span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span><span class="p">()</span>
<span class="nv">temp = </span><span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span> <span class="s1">&#39;ref&#39;</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="k">if</span> <span class="nx">@isNew</span>
@@ -342,29 +345,29 @@ inner constructor in order to be able to pass the varargs.</p> </td>
<span class="k">for</span> <span class="nx">arg</span> <span class="k">in</span> <span class="nx">@args</span>
<span class="nx">arg</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">mentionsArgs</span> <span class="o">or=</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="nx">utility</span> <span class="s1">&#39;extends&#39;</span>
<span class="nv">a = </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">b = </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">c = </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">a = </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="s1">&#39;ctor&#39;</span>
<span class="nv">b = </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="s1">&#39;ref&#39;</span>
<span class="nv">c = </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="s1">&#39;result&#39;</span>
<span class="s2">&quot;&quot;&quot;</span>
<span class="s2">#DIVIDER</span>
<span class="s2"> &quot;&quot;&quot;</span>
<span class="k">else</span>
<span class="s2">&quot;#{@first}#{@prefix()}#{meth}.apply(#{obj}, #{ @compileSplatArguments(o) })#{@last}&quot;</span></pre></div> </td> </tr> <tr id="section-53"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-53">#</a> </div> <p>{@first}(function() {
<span class="s2">&quot;#{@first}#{@prefix()}#{meth}.apply(#{obj}, #{ @compileSplatArguments(o) })#{@last}&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>{@first}(function() {
{@idt(1)}var ctor = function(){};
{@idt(1)}__extends(ctor, #{a} = #{meth});
{@idt(1)}return typeof (#{b} = #{a}.apply(#{c} = new ctor, #{ @compileSplatArguments(o) })) === "object" ? #{b} : #{c};
{@tab}}).#{ if mentionsArgs then 'apply(this, arguments)' else 'call(this)'}#{@last}</p> </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> <h3>ExtendsNode</h3> </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>
{@idt(1)}return typeof (#{c} = #{a}.apply(#{b} = new ctor, #{ @compileSplatArguments(o) })) === "object" ? #{c} : #{b};
{@tab}}).#{ if mentionsArgs then 'apply(this, arguments)' else 'call(this)'}#{@last}</p> </td> <td class="code"> <div class="highlight"><pre></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><span class="nv">exports.ExtendsNode = </span><span class="nx">class</span> <span class="nx">ExtendsNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span>
<span class="nx">class</span><span class="o">:</span> <span class="s1">&#39;ExtendsNode&#39;</span>
<span class="nx">children</span><span class="o">:</span> <span class="p">[</span><span class="s1">&#39;child&#39;</span><span class="p">,</span> <span class="s1">&#39;parent&#39;</span><span class="p">]</span>
<span class="nx">constructor</span><span class="o">:</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="k">super</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>Node to extend an object's prototype with an ancestor object.
<span class="k">super</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>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="nx">compileNode</span><span class="o">:</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-56"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-56">#</a> </div> <p>Hooks one constructor into another's prototype chain.</p> </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> <h3>AccessorNode</h3> </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="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-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></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><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="nx">class</span><span class="o">:</span> <span class="s1">&#39;AccessorNode&#39;</span>
<span class="nx">children</span><span class="o">:</span> <span class="p">[</span><span class="s1">&#39;name&#39;</span><span class="p">]</span>
@@ -378,8 +381,8 @@ After <code>goog.inherits</code> from the
<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="nx">o</span><span class="p">.</span><span class="nx">chainRoot</span><span class="p">.</span><span class="nx">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-58"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-58">#</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></pre></div> </td> </tr> <tr id="section-59"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-59">#</a> </div> <h3>IndexNode</h3> </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-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></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><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">class</span><span class="o">:</span> <span class="s1">&#39;IndexNode&#39;</span>
<span class="nx">children</span><span class="o">:</span> <span class="p">[</span><span class="s1">&#39;index&#39;</span><span class="p">]</span>
@@ -391,7 +394,7 @@ an accessor into the object's prototype.</p> </td> <td c
<span class="nx">o</span><span class="p">.</span><span class="nx">chainRoot</span><span class="p">.</span><span class="nx">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-60"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-60">#</a> </div> <p>A <code>[ ... ]</code> indexed accessor into an array or object.</p> </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> <h3>RangeNode</h3> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.RangeNode = </span><span class="nx">class</span> <span class="nx">RangeNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span>
<span class="s2">&quot;#{prefix}[#{idx}]&quot;</span></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></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><span class="nv">exports.RangeNode = </span><span class="nx">class</span> <span class="nx">RangeNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span>
<span class="nx">class</span><span class="o">:</span> <span class="s1">&#39;RangeNode&#39;</span>
<span class="nx">children</span><span class="o">:</span> <span class="p">[</span><span class="s1">&#39;from&#39;</span><span class="p">,</span> <span class="s1">&#39;to&#39;</span><span class="p">]</span>
@@ -399,7 +402,7 @@ an accessor into the object's prototype.</p> </td> <td c
<span class="nx">constructor</span><span class="o">:</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">tag</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="k">super</span><span class="p">()</span>
<span class="vi">@exclusive = </span><span class="nx">tag</span> <span class="o">is</span> <span class="s1">&#39;exclusive&#39;</span>
<span class="vi">@equals = </span><span class="k">if</span> <span class="nx">@exclusive</span> <span class="k">then</span> <span class="s1">&#39;&#39;</span> <span class="k">else</span> <span class="s1">&#39;=&#39;</span></pre></div> </td> </tr> <tr id="section-62"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-62">#</a> </div> <p>A range literal. Ranges can be used to extract portions (slices) of arrays,
<span class="vi">@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></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="nx">compileVariables</span><span class="o">:</span> <span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">o = </span><span class="nx">merge</span><span class="p">(</span><span class="nx">o</span><span class="p">,</span> <span class="nx">top</span><span class="o">:</span> <span class="kc">true</span><span class="p">)</span>
@@ -409,7 +412,7 @@ corresponding array of integers at runtime.</p> </td> <t
<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="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="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;)}; &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>Compiles the range's source variables -- where it starts and where it ends.
<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-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="nx">compileNode</span><span class="o">:</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="k">return</span> <span class="nx">@compileSimple</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="k">if</span> <span class="nx">@fromNum</span> <span class="o">and</span> <span class="nx">@toNum</span>
@@ -420,7 +423,7 @@ But only if they need to be cached to avoid double evaluation.</p> <
<span class="nv">compare = </span><span class="s2">&quot;#{intro} &lt;#{@equals} #{@toVar} : #{idx} &gt;#{@equals} #{@toVar})&quot;</span>
<span class="nv">stepPart = </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">incr = </span><span class="k">if</span> <span class="nx">step</span> <span class="k">then</span> <span class="s2">&quot;#{idx} += #{stepPart}&quot;</span> <span class="k">else</span> <span class="s2">&quot;#{intro} += #{stepPart} : #{idx} -= #{stepPart})&quot;</span>
<span class="s2">&quot;#{vars}; #{compare}; #{incr}&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 compiled normally, the range returns the contents of the <em>for loop</em>
<span class="s2">&quot;#{vars}; #{compare}; #{incr}&quot;</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="nx">compileSimple</span><span class="o">:</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">to</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="nb">parseInt</span><span class="p">(</span><span class="nx">@fromNum</span><span class="p">,</span> <span class="mi">10</span><span class="p">),</span> <span class="nb">parseInt</span><span class="p">(</span><span class="nx">@toNum</span><span class="p">,</span> <span class="mi">10</span><span class="p">)]</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>
@@ -429,15 +432,15 @@ needed to iterate over the values in the range. Used by comprehensions.</p>
<span class="k">if</span> <span class="nx">from</span> <span class="o">&lt;=</span> <span class="nx">to</span>
<span class="s2">&quot;#{idx} = #{from}; #{idx} &lt;#{@equals} #{to}; #{step or &quot;</span><span class="c1">#{idx}++&quot;}&quot;</span>
<span class="k">else</span>
<span class="s2">&quot;#{idx} = #{from}; #{idx} &gt;#{@equals} #{to}; #{step or &quot;</span><span class="c1">#{idx}--&quot;}&quot;</span></pre></div> </td> </tr> <tr id="section-65"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-65">#</a> </div> <p>Compile a simple range comprehension, with integers.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">compileArray</span><span class="o">:</span> <span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="s2">&quot;#{idx} = #{from}; #{idx} &gt;#{@equals} #{to}; #{step or &quot;</span><span class="c1">#{idx}--&quot;}&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>Compile a simple range comprehension, with integers.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">compileArray</span><span class="o">:</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="nx">merge</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">indent</span><span class="o">:</span> <span class="nx">idt</span>
<span class="k">if</span> <span class="nx">@fromNum</span> <span class="o">and</span> <span class="nx">@toNum</span> <span class="o">and</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">abs</span><span class="p">(</span><span class="o">+</span><span class="nx">@fromNum</span> <span class="o">-</span> <span class="o">+</span><span class="nx">@toNum</span><span class="p">)</span> <span class="o">&lt;=</span> <span class="mi">20</span>
<span class="nv">range = </span><span class="p">[</span><span class="o">+</span><span class="nx">@fromNum</span><span class="p">..</span><span class="o">+</span><span class="nx">@toNum</span><span class="p">]</span>
<span class="nx">range</span><span class="p">.</span><span class="nx">pop</span><span class="p">()</span> <span class="k">if</span> <span class="nx">@exclusive</span>
<span class="k">return</span> <span class="s2">&quot;[#{ range.join(&#39;, &#39;) }]&quot;</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">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="s1">&#39;i&#39;</span>
<span class="nv">result = </span><span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span> <span class="s1">&#39;result&#39;</span>
<span class="nv">pre = </span><span class="s2">&quot;\n#{idt}#{result} = []; #{vars}&quot;</span>
<span class="k">if</span> <span class="nx">@fromNum</span> <span class="o">and</span> <span class="nx">@toNum</span>
<span class="nv">o.index = </span><span class="nx">i</span>
@@ -446,7 +449,7 @@ needed to iterate over the values in the range. Used by comprehensions.</p>
<span class="nv">clause = </span><span class="s2">&quot;#{@fromVar} &lt;= #{@toVar} ?&quot;</span>
<span class="nv">body = </span><span class="s2">&quot;var #{i} = #{@fromVar}; #{clause} #{i} &lt;#{@equals} #{@toVar} : #{i} &gt;#{@equals} #{@toVar}; #{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-66"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-66">#</a> </div> <p>When used as a value, expand the range into the equivalent array.</p> </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> <h3>SliceNode</h3> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.SliceNode = </span><span class="nx">class</span> <span class="nx">SliceNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span>
<span class="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> <p>When used as a value, expand the range into the equivalent array.</p> </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> <h3>SliceNode</h3> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.SliceNode = </span><span class="nx">class</span> <span class="nx">SliceNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span>
<span class="nx">class</span><span class="o">:</span> <span class="s1">&#39;SliceNode&#39;</span>
<span class="nx">children</span><span class="o">:</span> <span class="p">[</span><span class="s1">&#39;range&#39;</span><span class="p">]</span>
@@ -459,9 +462,9 @@ needed to iterate over the values in the range. Used by comprehensions.</p>
<span class="nv">to = </span> <span class="k">if</span> <span class="nx">@range</span><span class="p">.</span><span class="nx">to</span> <span class="k">then</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="k">else</span> <span class="s1">&#39;&#39;</span>
<span class="nx">to</span> <span class="o">+=</span> <span class="k">if</span> <span class="o">not</span> <span class="nx">to</span> <span class="o">or</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="nv">to = </span> <span class="s1">&#39;, &#39;</span> <span class="o">+</span> <span class="nx">to</span> <span class="k">if</span> <span class="nx">to</span>
<span class="s2">&quot;.slice(#{from}#{to})&quot;</span></pre></div> </td> </tr> <tr id="section-68"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-68">#</a> </div> <p>An array slice literal. Unlike JavaScript's <code>Array#slice</code>, the second parameter
<span class="s2">&quot;.slice(#{from}#{to})&quot;</span></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 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></pre></div> </td> </tr> <tr id="section-69"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-69">#</a> </div> <h3>ObjectNode</h3> </td> <td class="code"> <div class="highlight"><pre><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>
is the index of the beginning.</p> </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> <h3>ObjectNode</h3> </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="nx">class</span><span class="o">:</span> <span class="s1">&#39;ObjectNode&#39;</span>
<span class="nx">children</span><span class="o">:</span> <span class="p">[</span><span class="s1">&#39;properties&#39;</span><span class="p">]</span>
@@ -486,7 +489,7 @@ is the index of the beginning.</p> </td> <td class="code
<span class="nx">indent</span> <span class="o">+</span> <span class="nx">prop</span><span class="p">.</span><span class="nx">compile</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">+</span> <span class="nx">join</span>
<span class="nv">props = </span><span class="nx">props</span><span class="p">.</span><span class="nx">join</span><span class="p">(</span><span class="s1">&#39;&#39;</span><span class="p">)</span>
<span class="nv">obj = </span><span class="s1">&#39;{&#39;</span> <span class="o">+</span> <span class="p">(</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="p">)</span> <span class="o">+</span> <span class="s1">&#39;}&#39;</span>
<span class="k">if</span> <span class="nx">top</span> <span class="k">then</span> <span class="s2">&quot;(#{obj})&quot;</span> <span class="k">else</span> <span class="nx">obj</span></pre></div> </td> </tr> <tr id="section-70"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-70">#</a> </div> <p>An object literal, nothing fancy.</p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-71"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-71">#</a> </div> <h3>ArrayNode</h3> </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="k">if</span> <span class="nx">top</span> <span class="k">then</span> <span class="s2">&quot;(#{obj})&quot;</span> <span class="k">else</span> <span class="nx">obj</span></pre></div> </td> </tr> <tr id="section-69"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-69">#</a> </div> <p>An object literal, nothing fancy.</p> </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> <h3>ArrayNode</h3> </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="nx">class</span><span class="o">:</span> <span class="s1">&#39;ArrayNode&#39;</span>
<span class="nx">children</span><span class="o">:</span> <span class="p">[</span><span class="s1">&#39;objects&#39;</span><span class="p">]</span>
@@ -514,20 +517,20 @@ 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-72"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-72">#</a> </div> <p>An array literal.</p> </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> <h3>ClassNode</h3> </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> <p>An array literal.</p> </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> <h3>ClassNode</h3> </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="nx">class</span><span class="o">:</span> <span class="s1">&#39;ClassNode&#39;</span>
<span class="nx">children</span><span class="o">:</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="nx">isStatement</span><span class="o">:</span> <span class="o">-&gt;</span> <span class="kc">yes</span></pre></div> </td> </tr> <tr id="section-74"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-74">#</a> </div> <p>The CoffeeScript class definition.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">constructor</span><span class="o">:</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">@properties</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nx">isStatement</span><span class="o">:</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>The CoffeeScript class definition.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">constructor</span><span class="o">:</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">@properties</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="k">super</span><span class="p">()</span>
<span class="nx">@properties</span> <span class="o">or=</span> <span class="p">[]</span>
<span class="vi">@returns = </span><span class="kc">false</span>
<span class="nx">makeReturn</span><span class="o">:</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-75"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-75">#</a> </div> <p>Initialize a <strong>ClassNode</strong> with its name, an optional superclass, and a
<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>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="nx">compileNode</span><span class="o">:</span> <span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="vi">@variable = </span><span class="nx">literal</span> <span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span><span class="p">()</span> <span class="k">if</span> <span class="nx">@variable</span> <span class="o">is</span> <span class="s1">&#39;__temp__&#39;</span>
<span class="vi">@variable = </span><span class="nx">literal</span> <span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span> <span class="s1">&#39;ctor&#39;</span> <span class="k">if</span> <span class="nx">@variable</span> <span class="o">is</span> <span class="s1">&#39;__temp__&#39;</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="nv">o.top = </span><span class="kc">true</span>
@@ -559,7 +562,7 @@ list of prototype property assignments.</p> </td> <td cl
<span class="k">else</span>
<span class="nv">func.bound = </span><span class="kc">false</span>
<span class="nx">constScope</span> <span class="o">or=</span> <span class="k">new</span> <span class="nx">Scope</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">constructor</span><span class="p">.</span><span class="nx">body</span><span class="p">,</span> <span class="nx">constructor</span><span class="p">)</span>
<span class="nx">me</span> <span class="o">or=</span> <span class="nx">constScope</span><span class="p">.</span><span class="nx">freeVariable</span><span class="p">()</span>
<span class="nx">me</span> <span class="o">or=</span> <span class="nx">constScope</span><span class="p">.</span><span class="nx">freeVariable</span> <span class="s1">&#39;this&#39;</span>
<span class="nv">pname = </span><span class="nx">pvar</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">constructor</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="k">if</span> <span class="nx">constructor</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">empty</span><span class="p">()</span>
<span class="nx">constructor</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">unshift</span> <span class="nx">literal</span> <span class="s2">&quot;this.#{pname} = function(){ return #{className}.prototype.#{pname}.apply(#{me}, arguments); }&quot;</span>
@@ -574,9 +577,9 @@ list of prototype property assignments.</p> </td> <td cl
<span class="nv">props = </span><span class="k">if</span> <span class="o">!</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;\n&#39;</span> <span class="o">+</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="k">else</span> <span class="s1">&#39;&#39;</span>
<span class="nv">extension = </span><span class="k">if</span> <span class="nx">extension</span> <span class="k">then</span> <span class="s1">&#39;\n&#39;</span> <span class="o">+</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;;&#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="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">@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="nx">construct</span> <span class="o">+</span> <span class="nx">extension</span> <span class="o">+</span> <span class="nx">props</span> <span class="o">+</span> <span class="nx">returns</span></pre></div> </td> </tr> <tr id="section-76"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-76">#</a> </div> <p>Instead of generating the JavaScript string directly, we build up the
<span class="nx">construct</span> <span class="o">+</span> <span class="nx">extension</span> <span class="o">+</span> <span class="nx">props</span> <span class="o">+</span> <span class="nx">returns</span></pre></div> </td> </tr> <tr id="section-75"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-75">#</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></pre></div> </td> </tr> <tr id="section-77"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-77">#</a> </div> <h3>AssignNode</h3> </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-78"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-78">#</a> </div> <p>The <strong>AssignNode</strong> is used to assign a local variable to value, or to set the
constructor, property assignments, and inheritance getting built out below.</p> </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> <h3>AssignNode</h3> </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>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="nx">PROTO_ASSIGN</span><span class="o">:</span> <span class="sr">/^(\S+)\.prototype/</span>
<span class="nx">LEADING_DOT</span><span class="o">:</span> <span class="sr">/^\.(prototype\.)?/</span>
@@ -599,7 +602,7 @@ property of an object -- including within object literals.</p> </td>
<span class="k">super</span><span class="p">()</span>
<span class="nx">isStatement</span><span class="o">:</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-79"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-79">#</a> </div> <p>Matchers for detecting prototype assignments.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">compileNode</span><span class="o">:</span> <span class="p">(</span><span class="nx">o</span><span class="p">)</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-78"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-78">#</a> </div> <p>Matchers for detecting prototype assignments.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">compileNode</span><span class="o">:</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="k">return</span> <span class="nx">@compilePatternMatch</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="k">if</span> <span class="nx">@isStatement</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span>
<span class="k">return</span> <span class="nx">@compileSplice</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="k">if</span> <span class="nx">@isValue</span><span class="p">()</span> <span class="o">and</span> <span class="nx">@variable</span><span class="p">.</span><span class="nx">isSplice</span><span class="p">()</span>
@@ -616,23 +619,23 @@ property of an object -- including within object literals.</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="o">or</span> <span class="nx">@parenthetical</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-80"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-80">#</a> </div> <p>Compile an assignment, delegating to <code>compilePatternMatch</code> or
<span class="k">if</span> <span class="nx">top</span> <span class="o">or</span> <span class="nx">@parenthetical</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>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="nx">compilePatternMatch</span><span class="o">:</span> <span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">valVar = </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">valVar = </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="s1">&#39;ref&#39;</span>
<span class="nv">value = </span><span class="k">if</span> <span class="nx">@value</span><span class="p">.</span><span class="nx">isStatement</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="k">then</span> <span class="nx">ClosureNode</span><span class="p">.</span><span class="nx">wrap</span><span class="p">(</span><span class="nx">@value</span><span class="p">)</span> <span class="k">else</span> <span class="nx">@value</span>
<span class="nv">assigns = </span><span class="p">[</span><span class="s2">&quot;#{@tab}#{valVar} = #{ value.compile(o) };&quot;</span><span class="p">]</span>
<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-81"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-81">#</a> </div> <p>Brief implementation of recursive pattern matching, when assigning array or
<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>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">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-82"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-82">#</a> </div> <p>A regular array 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-83"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-83">#</a> </div> <p>A regular object 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 array 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 regular object 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>
@@ -647,7 +650,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-84"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-84">#</a> </div> <p>A shorthand <code>{a, b, c} = val</code> pattern-match.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">compileSplice</span><span class="o">:</span> <span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<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>A shorthand <code>{a, b, c} = val</code> pattern-match.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">compileSplice</span><span class="o">:</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="nx">onlyFirst</span><span class="o">:</span> <span class="kc">true</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>
<span class="nv">range = </span><span class="nx">@variable</span><span class="p">.</span><span class="nx">properties</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="nx">range</span>
@@ -655,8 +658,8 @@ for details.</p> </td> <td class="code"> <
<span class="nv">from = </span><span class="k">if</span> <span class="nx">range</span><span class="p">.</span><span class="nx">from</span> <span class="k">then</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="k">else</span> <span class="s1">&#39;0&#39;</span>
<span class="nv">to = </span><span class="k">if</span> <span class="nx">range</span><span class="p">.</span><span class="nx">to</span> <span class="k">then</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="k">else</span> <span class="s2">&quot;#{name}.length&quot;</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-85"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-85">#</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></pre></div> </td> </tr> <tr id="section-86"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-86">#</a> </div> <h3>CodeNode</h3> </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>
<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> <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></pre></div> </td> </tr> <tr id="section-85"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-85">#</a> </div> <h3>CodeNode</h3> </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>
<span class="nx">class</span><span class="o">:</span> <span class="s1">&#39;CodeNode&#39;</span>
<span class="nx">children</span><span class="o">:</span> <span class="p">[</span><span class="s1">&#39;params&#39;</span><span class="p">,</span> <span class="s1">&#39;body&#39;</span><span class="p">]</span>
@@ -666,7 +669,7 @@ for details.</p> </td> <td class="code"> <
<span class="nx">@params</span> <span class="o">or=</span> <span class="p">[]</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>
<span class="vi">@context = </span><span class="s1">&#39;this&#39;</span> <span class="k">if</span> <span class="nx">@bound</span></pre></div> </td> </tr> <tr id="section-87"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-87">#</a> </div> <p>A function definition. This is the only node that creates a new Scope.
<span class="vi">@context = </span><span class="s1">&#39;this&#39;</span> <span class="k">if</span> <span class="nx">@bound</span></pre></div> </td> </tr> <tr id="section-86"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-86">#</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="nx">compileNode</span><span class="o">:</span> <span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">sharedScope = </span><span class="nx">del</span> <span class="nx">o</span><span class="p">,</span> <span class="s1">&#39;sharedScope&#39;</span>
@@ -688,7 +691,7 @@ has no <em>children</em> -- they're within the inner scope.</p> </td
<span class="k">else</span>
<span class="k">if</span> <span class="nx">param</span><span class="p">.</span><span class="nx">attach</span>
<span class="p">{</span><span class="nx">value</span><span class="p">}</span> <span class="o">=</span> <span class="nx">param</span>
<span class="p">[</span><span class="nx">param</span><span class="p">,</span> <span class="nx">param</span><span class="p">.</span><span class="nx">splat</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="nx">literal</span><span class="p">(</span><span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span><span class="p">()),</span> <span class="nx">param</span><span class="p">.</span><span class="nx">splat</span><span class="p">]</span>
<span class="p">[</span><span class="nx">param</span><span class="p">,</span> <span class="nx">param</span><span class="p">.</span><span class="nx">splat</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="nx">literal</span><span class="p">(</span><span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span> <span class="s1">&#39;arg&#39;</span><span class="p">),</span> <span class="nx">param</span><span class="p">.</span><span class="nx">splat</span><span class="p">]</span>
<span class="nx">@body</span><span class="p">.</span><span class="nx">unshift</span> <span class="k">new</span> <span class="nx">AssignNode</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="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="nx">value</span><span class="p">]),</span> <span class="nx">param</span>
<span class="k">if</span> <span class="nx">param</span><span class="p">.</span><span class="nx">splat</span>
<span class="nv">splat = </span><span class="k">new</span> <span class="nx">SplatNode</span> <span class="nx">param</span><span class="p">.</span><span class="nx">value</span>
@@ -707,7 +710,7 @@ has no <em>children</em> -- they're within the inner scope.</p> </td
<span class="k">if</span> <span class="nx">top</span> <span class="k">then</span> <span class="s2">&quot;(#{func})&quot;</span> <span class="k">else</span> <span class="nx">func</span>
<span class="nx">topSensitive</span><span class="o">:</span> <span class="o">-&gt;</span>
<span class="kc">true</span></pre></div> </td> </tr> <tr id="section-88"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-88">#</a> </div> <p>Compilation creates a new scope unless explicitly asked to share with the
<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>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
@@ -716,8 +719,8 @@ a closure.</p> </td> <td class="code"> <di
<span class="nx">toString</span><span class="o">:</span> <span class="p">(</span><span class="nx">idt</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nx">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="s1">&#39;\n&#39;</span> <span class="o">+</span> <span class="nx">idt</span> <span class="o">+</span> <span class="nx">children</span></pre></div> </td> </tr> <tr id="section-89"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-89">#</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></pre></div> </td> </tr> <tr id="section-90"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-90">#</a> </div> <h3>ParamNode</h3> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.ParamNode = </span><span class="nx">class</span> <span class="nx">ParamNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span>
<span class="s1">&#39;\n&#39;</span> <span class="o">+</span> <span class="nx">idt</span> <span class="o">+</span> <span class="nx">children</span></pre></div> </td> </tr> <tr id="section-88"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-88">#</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></pre></div> </td> </tr> <tr id="section-89"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-89">#</a> </div> <h3>ParamNode</h3> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.ParamNode = </span><span class="nx">class</span> <span class="nx">ParamNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span>
<span class="nx">class</span><span class="o">:</span> <span class="s1">&#39;ParamNode&#39;</span>
<span class="nx">children</span><span class="o">:</span> <span class="p">[</span><span class="s1">&#39;name&#39;</span><span class="p">]</span>
@@ -730,9 +733,9 @@ unless crossScope is true</p> </td> <td class="code">
<span class="nx">@value</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">o</span>
<span class="nx">toString</span><span class="o">:</span> <span class="p">(</span><span class="nx">idt</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="k">if</span> <span class="nx">@attach</span> <span class="k">then</span> <span class="p">(</span><span class="nx">literal</span> <span class="s1">&#39;@&#39;</span> <span class="o">+</span> <span class="nx">@name</span><span class="p">).</span><span class="nx">toString</span> <span class="nx">idt</span> <span class="k">else</span> <span class="nx">@value</span><span class="p">.</span><span class="nx">toString</span> <span class="nx">idt</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 parameter in a function definition. Beyond a typical Javascript parameter,
<span class="k">if</span> <span class="nx">@attach</span> <span class="k">then</span> <span class="p">(</span><span class="nx">literal</span> <span class="s1">&#39;@&#39;</span> <span class="o">+</span> <span class="nx">@name</span><span class="p">).</span><span class="nx">toString</span> <span class="nx">idt</span> <span class="k">else</span> <span class="nx">@value</span><span class="p">.</span><span class="nx">toString</span> <span class="nx">idt</span></pre></div> </td> </tr> <tr id="section-90"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-90">#</a> </div> <p>A parameter in a function definition. Beyond a typical Javascript parameter,
these parameters can also attach themselves to the context of the function,
as well as be a splat, gathering up a group of parameters into an array.</p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-92"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-92">#</a> </div> <h3>SplatNode</h3> </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>
as well as be a splat, gathering up a group of parameters into an array.</p> </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> <h3>SplatNode</h3> </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="nx">class</span><span class="o">:</span> <span class="s1">&#39;SplatNode&#39;</span>
<span class="nx">children</span><span class="o">:</span> <span class="p">[</span><span class="s1">&#39;name&#39;</span><span class="p">]</span>
@@ -743,28 +746,28 @@ as well as be a splat, gathering up a group of parameters into an array.</p>
<span class="vi">@name = </span><span class="nx">name</span>
<span class="nx">compileNode</span><span class="o">:</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-93"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-93">#</a> </div> <p>A splat, either as a parameter to a function, an argument to a call,
<span class="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-92"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-92">#</a> </div> <p>A splat, either as a parameter to a function, an argument to a call,
or as part of a destructuring assignment.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">compileParam</span><span class="o">:</span> <span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">name = </span><span class="nx">@name</span><span class="p">.</span><span class="nx">compile</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span>
<span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">find</span> <span class="nx">name</span>
<span class="nv">end = </span><span class="s1">&#39;&#39;</span>
<span class="k">if</span> <span class="nx">@trailings</span><span class="p">.</span><span class="nx">length</span>
<span class="nv">len = </span><span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span><span class="p">()</span>
<span class="nv">len = </span><span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span> <span class="s1">&#39;len&#39;</span>
<span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">assign</span> <span class="nx">len</span><span class="p">,</span> <span class="s2">&quot;arguments.length&quot;</span>
<span class="nv">variadic = </span><span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span><span class="p">()</span>
<span class="nv">variadic = </span><span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span> <span class="s1">&#39;result&#39;</span>
<span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">assign</span> <span class="nx">variadic</span><span class="p">,</span> <span class="nx">len</span> <span class="o">+</span> <span class="s1">&#39; &gt;= &#39;</span> <span class="o">+</span> <span class="nx">@arglength</span>
<span class="nv">end = </span><span class="k">if</span> <span class="nx">@trailings</span><span class="p">.</span><span class="nx">length</span> <span class="k">then</span> <span class="s2">&quot;, #{len} - #{@trailings.length}&quot;</span>
<span class="k">for</span> <span class="nx">trailing</span><span class="p">,</span> <span class="nx">idx</span> <span class="k">in</span> <span class="nx">@trailings</span>
<span class="k">if</span> <span class="nx">trailing</span><span class="p">.</span><span class="nx">attach</span>
<span class="nv">assign = </span><span class="nx">trailing</span><span class="p">.</span><span class="nx">assign</span>
<span class="nv">trailing = </span><span class="nx">literal</span> <span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span><span class="p">()</span>
<span class="nv">trailing = </span><span class="nx">literal</span> <span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span> <span class="s1">&#39;arg&#39;</span>
<span class="nv">assign.value = </span><span class="nx">trailing</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}#{end})&quot;</span></pre></div> </td> </tr> <tr id="section-94"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-94">#</a> </div> <p>Compiling a parameter splat means recovering the parameters that succeed
<span class="s2">&quot;#{name} = #{utility(&#39;slice&#39;)}.call(arguments, #{@index}#{end})&quot;</span></pre></div> </td> </tr> <tr id="section-93"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-93">#</a> </div> <p>Compiling a parameter splat means recovering the parameters that succeed
the splat in the parameter list, by slicing the arguments object.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">compileValue</span><span class="o">:</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-95"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-95">#</a> </div> <p>A compiling a splat as a destructuring assignment means slicing arguments
<span class="s2">&quot;#{utility &#39;slice&#39;}.call(#{name}, #{index}#{trail})&quot;</span></pre></div> </td> </tr> <tr id="section-94"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-94">#</a> </div> <p>A compiling a splat as a destructuring assignment means slicing arguments
from the right-hand-side's corresponding array.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">@compileSplattedArray</span><span class="o">:</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="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">list</span>
@@ -780,8 +783,8 @@ from the right-hand-side's corresponding array.</p> </td>
<span class="k">else</span>
<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="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-96"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-96">#</a> </div> <p>Utility function that converts arbitrary number of elements, mixed with
splats, to a proper array</p> </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> <h3>WhileNode</h3> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.WhileNode = </span><span class="nx">class</span> <span class="nx">WhileNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span>
<span class="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-95"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-95">#</a> </div> <p>Utility function that converts arbitrary number of elements, mixed with
splats, to a proper array</p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-96"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-96">#</a> </div> <h3>WhileNode</h3> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.WhileNode = </span><span class="nx">class</span> <span class="nx">WhileNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span>
<span class="nx">class</span><span class="o">:</span> <span class="s1">&#39;WhileNode&#39;</span>
<span class="nx">children</span><span class="o">:</span> <span class="p">[</span><span class="s1">&#39;condition&#39;</span><span class="p">,</span> <span class="s1">&#39;guard&#39;</span><span class="p">,</span> <span class="s1">&#39;body&#39;</span><span class="p">]</span>
@@ -804,7 +807,7 @@ splats, to a proper array</p> </td> <td class="code">
<span class="k">this</span>
<span class="nx">topSensitive</span><span class="o">:</span> <span class="o">-&gt;</span>
<span class="kc">true</span></pre></div> </td> </tr> <tr id="section-98"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-98">#</a> </div> <p>A while loop, the only sort of low-level loop exposed by CoffeeScript. From
<span class="kc">true</span></pre></div> </td> </tr> <tr id="section-97"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-97">#</a> </div> <p>A while loop, the only sort of low-level loop exposed by CoffeeScript. From
it, all other loops can be manufactured. Useful in cases where you need more
flexibility or more speed than a comprehension can provide.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">compileNode</span><span class="o">:</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>
@@ -814,7 +817,7 @@ flexibility or more speed than a comprehension can provide.</p> </td
<span class="nv">cond = </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="nv">set = </span> <span class="s1">&#39;&#39;</span>
<span class="nx">unless</span> <span class="nx">top</span>
<span class="nv">rvar = </span><span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span><span class="p">()</span>
<span class="nv">rvar = </span><span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span> <span class="s1">&#39;result&#39;</span>
<span class="nv">set = </span><span class="s2">&quot;#{@tab}#{rvar} = [];\n&quot;</span>
<span class="vi">@body = </span><span class="nx">PushNode</span><span class="p">.</span><span class="nx">wrap</span><span class="p">(</span><span class="nx">rvar</span><span class="p">,</span> <span class="nx">@body</span><span class="p">)</span> <span class="k">if</span> <span class="nx">@body</span>
<span class="nv">pre = </span><span class="s2">&quot;#{set}#{@tab}while (#{cond})&quot;</span>
@@ -823,15 +826,15 @@ flexibility or more speed than a comprehension can provide.</p> </td
<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="nx">indent</span><span class="o">:</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-99"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-99">#</a> </div> <p>The main difference from a JavaScript <em>while</em> is that the CoffeeScript
<span class="s2">&quot;#{pre} {\n#{ @body.compile(o) }\n#{@tab}}#{post}&quot;</span></pre></div> </td> </tr> <tr id="section-98"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-98">#</a> </div> <p>The main difference from a JavaScript <em>while</em> is that the CoffeeScript
<em>while</em> can be used as a part of a larger expression -- while loops may
return an array containing the computed result of each iteration.</p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-100"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-100">#</a> </div> <h3>OpNode</h3> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.OpNode = </span><span class="nx">class</span> <span class="nx">OpNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span></pre></div> </td> </tr> <tr id="section-101"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-101">#</a> </div> <p>Simple Arithmetic and logical operations. Performs some conversion from
return an array containing the computed result of each iteration.</p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-99"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-99">#</a> </div> <h3>OpNode</h3> </td> <td class="code"> <div class="highlight"><pre><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-100"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-100">#</a> </div> <p>Simple Arithmetic and logical operations. Performs some conversion from
CoffeeScript operations into their JavaScript equivalents.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">CONVERSIONS</span><span class="o">:</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></pre></div> </td> </tr> <tr id="section-102"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-102">#</a> </div> <p>The map of conversions from CoffeeScript to JavaScript symbols.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">INVERSIONS</span><span class="o">:</span>
<span class="s1">&#39;!=&#39;</span><span class="o">:</span> <span class="s1">&#39;!==&#39;</span></pre></div> </td> </tr> <tr id="section-101"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-101">#</a> </div> <p>The map of conversions from CoffeeScript to JavaScript symbols.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">INVERSIONS</span><span class="o">:</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></pre></div> </td> </tr> <tr id="section-103"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-103">#</a> </div> <p>The map of invertible operators.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">CHAINABLE</span><span class="o">:</span> <span class="p">[</span><span class="s1">&#39;&lt;&#39;</span><span class="p">,</span> <span class="s1">&#39;&gt;&#39;</span><span class="p">,</span> <span class="s1">&#39;&gt;=&#39;</span><span class="p">,</span> <span class="s1">&#39;&lt;=&#39;</span><span class="p">,</span> <span class="s1">&#39;===&#39;</span><span class="p">,</span> <span class="s1">&#39;!==&#39;</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-104"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-104">#</a> </div> <p>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="nx">ASSIGNMENT</span><span class="o">:</span> <span class="p">[</span><span class="s1">&#39;||=&#39;</span><span class="p">,</span> <span class="s1">&#39;&amp;&amp;=&#39;</span><span class="p">,</span> <span class="s1">&#39;?=&#39;</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-105"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-105">#</a> </div> <p>Our assignment operators that have no JavaScript equivalent.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">PREFIX_OPERATORS</span><span class="o">:</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="s1">&#39;===&#39;</span><span class="o">:</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>The map of invertible operators.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">CHAINABLE</span><span class="o">:</span> <span class="p">[</span><span class="s1">&#39;&lt;&#39;</span><span class="p">,</span> <span class="s1">&#39;&gt;&#39;</span><span class="p">,</span> <span class="s1">&#39;&gt;=&#39;</span><span class="p">,</span> <span class="s1">&#39;&lt;=&#39;</span><span class="p">,</span> <span class="s1">&#39;===&#39;</span><span class="p">,</span> <span class="s1">&#39;!==&#39;</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-103"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-103">#</a> </div> <p>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="nx">ASSIGNMENT</span><span class="o">:</span> <span class="p">[</span><span class="s1">&#39;||=&#39;</span><span class="p">,</span> <span class="s1">&#39;&amp;&amp;=&#39;</span><span class="p">,</span> <span class="s1">&#39;?=&#39;</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-104"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-104">#</a> </div> <p>Our assignment operators that have no JavaScript equivalent.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">PREFIX_OPERATORS</span><span class="o">:</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="nx">class</span><span class="o">:</span> <span class="s1">&#39;OpNode&#39;</span>
<span class="nx">children</span><span class="o">:</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>
@@ -872,11 +875,11 @@ CoffeeScript operations into their JavaScript equivalents.</p> </td>
<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="vi">@first = </span><span class="k">new</span> <span class="nx">ParentheticalNode</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="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">isMutator</span><span class="p">()</span>
<span class="vi">@second = </span><span class="k">new</span> <span class="nx">ParentheticalNode</span><span class="p">(</span><span class="nx">@second</span><span class="p">)</span> <span class="k">if</span> <span class="nx">@second</span> <span class="k">instanceof</span> <span class="nx">OpNode</span> <span class="o">and</span> <span class="nx">@second</span><span class="p">.</span><span class="nx">isMutator</span><span class="p">()</span>
<span class="p">[</span><span class="nx">@first</span><span class="p">.</span><span class="nx">compile</span><span class="p">(</span><span class="nx">o</span><span class="p">),</span> <span class="nx">@operator</span><span class="p">,</span> <span class="nx">@second</span><span class="p">.</span><span class="nx">compile</span><span class="p">(</span><span class="nx">o</span><span class="p">)].</span><span class="nx">join</span> <span class="s1">&#39; &#39;</span></pre></div> </td> </tr> <tr id="section-106"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-106">#</a> </div> <p>Operators must come before their operands with a space.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">compileChain</span><span class="o">:</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">compile</span><span class="p">(</span><span class="nx">o</span><span class="p">),</span> <span class="nx">@operator</span><span class="p">,</span> <span class="nx">@second</span><span class="p">.</span><span class="nx">compile</span><span class="p">(</span><span class="nx">o</span><span class="p">)].</span><span class="nx">join</span> <span class="s1">&#39; &#39;</span></pre></div> </td> </tr> <tr id="section-105"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-105">#</a> </div> <p>Operators must come before their operands with a space.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">compileChain</span><span class="o">:</span> <span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<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-107"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-107">#</a> </div> <p>Mimic Python's chained comparisons when multiple comparison operators are
<span class="s2">&quot;(#{first}) &amp;&amp; (#{shared} #{@operator} #{second})&quot;</span></pre></div> </td> </tr> <tr id="section-106"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-106">#</a> </div> <p>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"
@@ -887,16 +890,16 @@ true
<span class="nv">second = </span><span class="s2">&quot;(#{second})&quot;</span> <span class="k">if</span> <span class="nx">@second</span> <span class="k">instanceof</span> <span class="nx">OpNode</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, literal(firstVar))[0] } ? #{firstVar} : #{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} #{ @operator.substr(0, 2) } (#{firstVar} = #{second})&quot;</span></pre></div> </td> </tr> <tr id="section-108"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-108">#</a> </div> <p>When compiling a conditional assignment, take care to ensure that the
<span class="s2">&quot;#{first} #{ @operator.substr(0, 2) } (#{firstVar} = #{second})&quot;</span></pre></div> </td> </tr> <tr id="section-107"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-107">#</a> </div> <p>When compiling a conditional assignment, take care to ensure that the
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="nx">compileExistence</span><span class="o">:</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">test</span><span class="p">,</span> <span class="nx">ref</span><span class="p">]</span> <span class="o">=</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} ? #{ref} : #{ @second.compile(o) }&quot;</span></pre></div> </td> </tr> <tr id="section-109"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-109">#</a> </div> <p>If this is an existence operator, we delegate to <code>ExistenceNode.compileTest</code>
<span class="s2">&quot;#{test} ? #{ref} : #{ @second.compile(o) }&quot;</span></pre></div> </td> </tr> <tr id="section-108"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-108">#</a> </div> <p>If this is an existence operator, we delegate to <code>ExistenceNode.compileTest</code>
to give us the safe references for the variables.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">compileUnary</span><span class="o">:</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-110"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-110">#</a> </div> <p>Compile a unary <strong>OpNode</strong>.</p> </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-109"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-109">#</a> </div> <p>Compile a unary <strong>OpNode</strong>.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">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">class</span><span class="o">:</span> <span class="s1">&#39;InNode&#39;</span>
<span class="nx">children</span><span class="o">:</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>
@@ -918,9 +921,9 @@ to give us the safe references for the variables.</p> </td>
<span class="nx">compileLoopTest</span><span class="o">:</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">@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="nx">precompile</span><span class="o">:</span> <span class="kc">yes</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="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="s1">&#39;i&#39;</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="s1">&#39;len&#39;</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; } return false; }).call(this)&quot;</span></pre></div> </td> </tr> <tr id="section-111"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-111">#</a> </div> <h3>InNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-112"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-112">#</a> </div> <h3>TryNode</h3> </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; } return false; }).call(this)&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>InNode</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> <h3>TryNode</h3> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.TryNode = </span><span class="nx">class</span> <span class="nx">TryNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span>
<span class="nx">class</span><span class="o">:</span> <span class="s1">&#39;TryNode&#39;</span>
<span class="nx">children</span><span class="o">:</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>
@@ -932,26 +935,26 @@ to give us the safe references for the variables.</p> </td>
<span class="nx">makeReturn</span><span class="o">:</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-113"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-113">#</a> </div> <p>A classic <em>try/catch/finally</em> block.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">compileNode</span><span class="o">:</span> <span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="k">this</span></pre></div> </td> </tr> <tr id="section-112"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-112">#</a> </div> <p>A classic <em>try/catch/finally</em> block.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">compileNode</span><span class="o">:</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>
<span class="nv">attemptPart = </span><span class="nx">@attempt</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">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-114"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-114">#</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></pre></div> </td> </tr> <tr id="section-115"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-115">#</a> </div> <h3>ThrowNode</h3> </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-113"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-113">#</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></pre></div> </td> </tr> <tr id="section-114"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-114">#</a> </div> <h3>ThrowNode</h3> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.ThrowNode = </span><span class="nx">class</span> <span class="nx">ThrowNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span>
<span class="nx">class</span><span class="o">:</span> <span class="s1">&#39;ThrowNode&#39;</span>
<span class="nx">children</span><span class="o">:</span> <span class="p">[</span><span class="s1">&#39;expression&#39;</span><span class="p">]</span>
<span class="nx">isStatement</span><span class="o">:</span> <span class="o">-&gt;</span> <span class="kc">yes</span>
<span class="nx">constructor</span><span class="o">:</span> <span class="p">(</span><span class="nx">@expression</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="k">super</span><span class="p">()</span></pre></div> </td> </tr> <tr id="section-116"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-116">#</a> </div> <p>Simple node to throw an exception.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">makeReturn</span><span class="o">:</span> <span class="o">-&gt;</span>
<span class="k">super</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>Simple node to throw an exception.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">makeReturn</span><span class="o">:</span> <span class="o">-&gt;</span>
<span class="k">return</span> <span class="k">this</span>
<span class="nx">compileNode</span><span class="o">:</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-117"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-117">#</a> </div> <p>A <strong>ThrowNode</strong> is already a return, of sorts...</p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-118"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-118">#</a> </div> <h3>ExistenceNode</h3> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.ExistenceNode = </span><span class="nx">class</span> <span class="nx">ExistenceNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span>
<span class="s2">&quot;#{@tab}throw #{@expression.compile(o)};&quot;</span></pre></div> </td> </tr> <tr id="section-116"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-116">#</a> </div> <p>A <strong>ThrowNode</strong> is already a return, of sorts...</p> </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> <h3>ExistenceNode</h3> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.ExistenceNode = </span><span class="nx">class</span> <span class="nx">ExistenceNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span>
<span class="nx">class</span><span class="o">:</span> <span class="s1">&#39;ExistenceNode&#39;</span>
<span class="nx">children</span><span class="o">:</span> <span class="p">[</span><span class="s1">&#39;expression&#39;</span><span class="p">]</span>
@@ -961,13 +964,13 @@ is optional, the <em>catch</em> is not.</p> </td> <td cl
<span class="nx">compileNode</span><span class="o">:</span> <span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</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">@expression</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>
<span class="k">if</span> <span class="nx">@parenthetical</span> <span class="k">then</span> <span class="nx">test</span><span class="p">.</span><span class="nx">substring</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="nx">test</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">test</span></pre></div> </td> </tr> <tr id="section-119"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-119">#</a> </div> <p>Checks a variable for existence -- not <em>null</em> and not <em>undefined</em>. This is
<span class="k">if</span> <span class="nx">@parenthetical</span> <span class="k">then</span> <span class="nx">test</span><span class="p">.</span><span class="nx">substring</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="nx">test</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">test</span></pre></div> </td> </tr> <tr id="section-118"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-118">#</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="nx">@compileTest</span><span class="o">:</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="p">,</span> <span class="nx">precompile</span><span class="o">:</span> <span class="kc">yes</span>
<span class="p">[</span><span class="s2">&quot;(typeof #{first} !== \&quot;undefined\&quot; &amp;&amp; #{second} !== null)&quot;</span><span class="p">,</span> <span class="nx">second</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-120"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-120">#</a> </div> <p>The meat of the <strong>ExistenceNode</strong> is in this static <code>compileTest</code> method
<span class="p">[</span><span class="s2">&quot;(typeof #{first} !== \&quot;undefined\&quot; &amp;&amp; #{second} !== null)&quot;</span><span class="p">,</span> <span class="nx">second</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-119"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-119">#</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></pre></div> </td> </tr> <tr id="section-121"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-121">#</a> </div> <h3>ParentheticalNode</h3> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.ParentheticalNode = </span><span class="nx">class</span> <span class="nx">ParentheticalNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span>
Be careful not to double-evaluate anything.</p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-120"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-120">#</a> </div> <h3>ParentheticalNode</h3> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.ParentheticalNode = </span><span class="nx">class</span> <span class="nx">ParentheticalNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span>
<span class="nx">class</span><span class="o">:</span> <span class="s1">&#39;ParentheticalNode&#39;</span>
<span class="nx">children</span><span class="o">:</span> <span class="p">[</span><span class="s1">&#39;expression&#39;</span><span class="p">]</span>
@@ -991,11 +994,11 @@ Be careful not to double-evaluate anything.</p> </td> <t
<span class="k">return</span> <span class="nx">code</span> <span class="k">if</span> <span class="nx">top</span> <span class="o">and</span> <span class="nx">@expression</span><span class="p">.</span><span class="nx">isPureStatement</span> <span class="nx">o</span>
<span class="k">if</span> <span class="nx">@parenthetical</span> <span class="o">or</span> <span class="nx">@isStatement</span> <span class="nx">o</span>
<span class="k">return</span> <span class="k">if</span> <span class="nx">top</span> <span class="k">then</span> <span class="nx">@tab</span> <span class="o">+</span> <span class="nx">code</span> <span class="o">+</span> <span class="s1">&#39;;&#39;</span> <span class="k">else</span> <span class="nx">code</span>
<span class="s2">&quot;(#{code})&quot;</span></pre></div> </td> </tr> <tr id="section-122"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-122">#</a> </div> <p>An extra set of parentheses, specified explicitly in the source. At one time
<span class="s2">&quot;(#{code})&quot;</span></pre></div> </td> </tr> <tr id="section-121"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-121">#</a> </div> <p>An extra set of parentheses, specified explicitly in the source. At one time
we tried to clean up the results by detecting and removing redundant
parentheses, but no longer -- you can put in as many as you please.</p>
<p>Parentheses are a good way to force any statement to become an expression.</p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-123"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-123">#</a> </div> <h3>ForNode</h3> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.ForNode = </span><span class="nx">class</span> <span class="nx">ForNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span>
<p>Parentheses are a good way to force any statement to become an expression.</p> </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> <h3>ForNode</h3> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.ForNode = </span><span class="nx">class</span> <span class="nx">ForNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span>
<span class="nx">class</span><span class="o">:</span> <span class="s1">&#39;ForNode&#39;</span>
<span class="nx">children</span><span class="o">:</span> <span class="p">[</span><span class="s1">&#39;body&#39;</span><span class="p">,</span> <span class="s1">&#39;source&#39;</span><span class="p">,</span> <span class="s1">&#39;guard&#39;</span><span class="p">]</span>
@@ -1024,7 +1027,7 @@ parentheses, but no longer -- you can put in as many as you please.</p>
<span class="nx">compileReturnValue</span><span class="o">:</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-124"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-124">#</a> </div> <p>CoffeeScript's replacement for the <em>for</em> loop is our array and object
<span class="s1">&#39;&#39;</span></pre></div> </td> </tr> <tr id="section-123"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-123">#</a> </div> <p>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>
@@ -1036,12 +1039,12 @@ you can map and filter in a single pass.</p> </td> <td c
<span class="nv">source = </span><span class="k">if</span> <span class="nx">range</span> <span class="k">then</span> <span class="nx">@source</span><span class="p">.</span><span class="nx">base</span> <span class="k">else</span> <span class="nx">@source</span>
<span class="nv">codeInBody = </span><span class="nx">@body</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">CodeNode</span>
<span class="nv">scope = </span><span class="nx">o</span><span class="p">.</span><span class="nx">scope</span>
<span class="nv">name = </span><span class="p">(</span><span class="nx">@name</span> <span class="o">and</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="o">or</span> <span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span><span class="p">()</span>
<span class="nv">name = </span><span class="p">(</span><span class="nx">@name</span> <span class="o">and</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="o">or</span> <span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span> <span class="s1">&#39;i&#39;</span>
<span class="nv">index = </span><span class="nx">@index</span> <span class="o">and</span> <span class="nx">@index</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">o</span>
<span class="nx">scope</span><span class="p">.</span><span class="nx">find</span><span class="p">(</span><span class="nx">name</span><span class="p">,</span> <span class="nx">immediate</span><span class="o">:</span> <span class="kc">yes</span><span class="p">)</span> <span class="k">if</span> <span class="nx">name</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">@pattern</span> <span class="o">and</span> <span class="p">(</span><span class="nx">range</span> <span class="o">or</span> <span class="o">not</span> <span class="nx">codeInBody</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">index</span><span class="p">,</span> <span class="nx">immediate</span><span class="o">:</span> <span class="kc">yes</span><span class="p">)</span> <span class="k">if</span> <span class="nx">index</span>
<span class="nv">rvar = </span><span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span><span class="p">()</span> <span class="nx">unless</span> <span class="nx">topLevel</span>
<span class="nv">ivar = </span><span class="k">if</span> <span class="nx">codeInBody</span> <span class="k">then</span> <span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span><span class="p">()</span> <span class="k">else</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="nx">index</span> <span class="o">or</span> <span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span><span class="p">()</span>
<span class="nv">rvar = </span><span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span> <span class="s1">&#39;result&#39;</span> <span class="nx">unless</span> <span class="nx">topLevel</span>
<span class="nv">ivar = </span><span class="k">if</span> <span class="nx">codeInBody</span> <span class="k">then</span> <span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span> <span class="s1">&#39;i&#39;</span> <span class="k">else</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="nx">index</span> <span class="o">or</span> <span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span> <span class="s1">&#39;i&#39;</span>
<span class="nv">varPart = </span><span class="s1">&#39;&#39;</span>
<span class="nv">guardPart = </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>
@@ -1049,14 +1052,14 @@ you can map and filter in a single pass.</p> </td> <td c
<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">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="nx">index</span><span class="o">:</span> <span class="nx">ivar</span><span class="p">,</span> <span class="nx">step</span><span class="o">:</span> <span class="nx">@step</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">svar = </span><span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span> <span class="s1">&#39;ref&#39;</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="nx">indent</span><span class="o">:</span> <span class="nx">@idt</span><span class="p">(</span><span class="mi">1</span><span class="p">),</span> <span class="nx">top</span><span class="o">:</span> <span class="kc">true</span><span class="p">})</span> <span class="o">+</span> <span class="s1">&#39;\n&#39;</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="nx">indent</span><span class="o">:</span> <span class="nx">@idt</span><span class="p">(</span><span class="mi">1</span><span class="p">),</span> <span class="nx">top</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span> <span class="nx">keepLevel</span><span class="o">:</span> <span class="kc">yes</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>
<span class="nv">lvar = </span><span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span><span class="p">()</span>
<span class="nv">lvar = </span><span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span> <span class="s1">&#39;len&#39;</span>
<span class="nv">stepPart = </span><span class="k">if</span> <span class="nx">@step</span> <span class="k">then</span> <span class="s2">&quot;#{ivar} += #{ @step.compile(o) }&quot;</span> <span class="k">else</span> <span class="s2">&quot;#{ivar}++&quot;</span>
<span class="nv">forPart = </span><span class="s2">&quot;#{ivar} = 0, #{lvar} = #{svar}.length; #{ivar} &lt; #{lvar}; #{stepPart}&quot;</span>
<span class="nv">sourcePart = </span><span class="p">(</span><span class="k">if</span> <span class="nx">rvar</span> <span class="k">then</span> <span class="s2">&quot;#{rvar} = []; &quot;</span> <span class="k">else</span> <span class="s1">&#39;&#39;</span><span class="p">)</span> <span class="o">+</span> <span class="nx">sourcePart</span>
@@ -1078,10 +1081,10 @@ you can map and filter in a single pass.</p> </td> <td c
<span class="nv">guardPart = </span><span class="s2">&quot;\n#{@idt(1)}if (!#{utility(&#39;hasProp&#39;)}.call(#{svar}, #{ivar})) continue;&quot;</span> <span class="nx">unless</span> <span class="nx">@raw</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="nx">indent</span><span class="o">:</span> <span class="nx">@idt</span><span class="p">(</span><span class="mi">1</span><span class="p">),</span> <span class="nx">top</span><span class="o">:</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="s2">&quot;#{sourcePart}for (#{forPart}) {#{guardPart}\n#{varPart}#{body}\n#{@tab}}#{returnResult}&quot;</span></pre></div> </td> </tr> <tr id="section-125"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-125">#</a> </div> <p>Welcome to the hairiest method in all of CoffeeScript. Handles the inner
<span class="s2">&quot;#{sourcePart}for (#{forPart}) {#{guardPart}\n#{varPart}#{body}\n#{@tab}}#{returnResult}&quot;</span></pre></div> </td> </tr> <tr id="section-124"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-124">#</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></pre></div> </td> </tr> <tr id="section-126"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-126">#</a> </div> <h3>SwitchNode</h3> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.SwitchNode = </span><span class="nx">class</span> <span class="nx">SwitchNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span>
some cannot.</p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-125"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-125">#</a> </div> <h3>SwitchNode</h3> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.SwitchNode = </span><span class="nx">class</span> <span class="nx">SwitchNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span>
<span class="nx">class</span><span class="o">:</span> <span class="s1">&#39;SwitchNode&#39;</span>
<span class="nx">children</span><span class="o">:</span> <span class="p">[</span><span class="s1">&#39;subject&#39;</span><span class="p">,</span> <span class="s1">&#39;cases&#39;</span><span class="p">,</span> <span class="s1">&#39;otherwise&#39;</span><span class="p">]</span>
@@ -1099,7 +1102,7 @@ some cannot.</p> </td> <td class="code"> <
<span class="k">this</span>
<span class="nx">compileNode</span><span class="o">:</span> <span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">idt = o.indent = </span><span class="nx">@idt</span> <span class="mi">1</span>
<span class="nv">idt = o.indent = </span><span class="nx">@idt</span> <span class="mi">2</span>
<span class="nv">o.top = </span><span class="kc">yes</span>
<span class="nv">code = </span><span class="s2">&quot;#{ @tab }switch (#{ @subject.compile o }) {&quot;</span>
<span class="k">for</span> <span class="nx">pair</span> <span class="k">in</span> <span class="nx">@cases</span>
@@ -1107,13 +1110,13 @@ some cannot.</p> </td> <td class="code"> <
<span class="nv">exprs = </span><span class="nx">block</span><span class="p">.</span><span class="nx">expressions</span>
<span class="k">for</span> <span class="nx">condition</span> <span class="k">in</span> <span class="nx">flatten</span> <span class="p">[</span><span class="nx">conditions</span><span class="p">]</span>
<span class="nv">condition = </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="nx">condition</span> <span class="k">if</span> <span class="nx">@tags</span><span class="p">.</span><span class="nx">subjectless</span>
<span class="nx">code</span> <span class="o">+=</span> <span class="s2">&quot;\n#{ @tab }case #{ condition.compile o }:&quot;</span>
<span class="nx">code</span> <span class="o">+=</span> <span class="s2">&quot;\n#{ @idt(1) }case #{ condition.compile o }:&quot;</span>
<span class="nx">code</span> <span class="o">+=</span> <span class="s2">&quot;\n#{ block.compile o }&quot;</span>
<span class="nx">code</span> <span class="o">+=</span> <span class="s2">&quot;\n#{ idt }break;&quot;</span> <span class="nx">unless</span> <span class="nx">exprs</span><span class="p">[</span><span class="nx">exprs</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]</span> <span class="k">instanceof</span> <span class="nx">ReturnNode</span>
<span class="k">if</span> <span class="nx">@otherwise</span>
<span class="nx">code</span> <span class="o">+=</span> <span class="s2">&quot;\n#{ @tab }default:\n#{ @otherwise.compile o }&quot;</span>
<span class="nx">code</span> <span class="o">+=</span> <span class="s2">&quot;\n#{ @idt(1) }default:\n#{ @otherwise.compile o }&quot;</span>
<span class="nx">code</span> <span class="o">+=</span> <span class="s2">&quot;\n#{ @tab }}&quot;</span>
<span class="nx">code</span></pre></div> </td> </tr> <tr id="section-127"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-127">#</a> </div> <p>A JavaScript <em>switch</em> statement. Converts into a returnable expression on-demand.</p> </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>IfNode</h3> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.IfNode = </span><span class="nx">class</span> <span class="nx">IfNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span>
<span class="nx">code</span></pre></div> </td> </tr> <tr id="section-126"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-126">#</a> </div> <p>A JavaScript <em>switch</em> statement. Converts into a returnable expression on-demand.</p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-127"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-127">#</a> </div> <h3>IfNode</h3> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.IfNode = </span><span class="nx">class</span> <span class="nx">IfNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span>
<span class="nx">class</span><span class="o">:</span> <span class="s1">&#39;IfNode&#39;</span>
<span class="nx">children</span><span class="o">:</span> <span class="p">[</span><span class="s1">&#39;condition&#39;</span><span class="p">,</span> <span class="s1">&#39;body&#39;</span><span class="p">,</span> <span class="s1">&#39;elseBody&#39;</span><span class="p">,</span> <span class="s1">&#39;assigner&#39;</span><span class="p">]</span>
@@ -1135,7 +1138,7 @@ some cannot.</p> </td> <td class="code"> <
<span class="nx">forceStatement</span><span class="o">:</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-129"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-129">#</a> </div> <p><em>If/else</em> statements. Acts as an expression by pushing down requested returns
<span class="k">this</span></pre></div> </td> </tr> <tr id="section-128"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-128">#</a> </div> <p><em>If/else</em> statements. Acts as an expression by pushing down requested returns
to the last line of each clause.</p>
<p>Single-expression <strong>IfNodes</strong> are compiled into ternary operators if possible,
@@ -1145,7 +1148,7 @@ because ternaries are already proper expressions, and don't need conversion.</p>
<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-130"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-130">#</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="nx">isStatement</span><span class="o">:</span> <span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="k">this</span></pre></div> </td> </tr> <tr id="section-129"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-129">#</a> </div> <p>Rewrite a chain of <strong>IfNodes</strong> to add a default case as the final <em>else</em>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">isStatement</span><span class="o">:</span> <span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nx">@statement</span> <span class="o">or=</span> <span class="o">!!</span><span class="p">((</span><span class="nx">o</span> <span class="o">and</span> <span class="nx">o</span><span class="p">.</span><span class="nx">top</span><span class="p">)</span> <span class="o">or</span> <span class="nx">@tags</span><span class="p">.</span><span class="nx">statement</span> <span class="o">or</span> <span class="nx">@bodyNode</span><span class="p">().</span><span class="nx">isStatement</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">or</span> <span class="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><span class="nx">o</span><span class="p">)))</span>
<span class="nx">compileCondition</span><span class="o">:</span> <span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
@@ -1165,7 +1168,7 @@ because ternaries are already proper expressions, and don't need conversion.</p>
<span class="k">new</span> <span class="nx">ReturnNode</span> <span class="k">this</span>
<span class="nx">ensureExpressions</span><span class="o">:</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-131"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-131">#</a> </div> <p>The <strong>IfNode</strong> only compiles into a statement if either of its bodies needs
<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-130"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-130">#</a> </div> <p>The <strong>IfNode</strong> only compiles into a statement if either of its bodies needs
to be a statement. Otherwise a ternary is safe.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">compileStatement</span><span class="o">:</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">child = </span><span class="nx">del</span> <span class="nx">o</span><span class="p">,</span> <span class="s1">&#39;chainChild&#39;</span>
@@ -1181,23 +1184,23 @@ to be a statement. Otherwise a ternary is safe.</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="nx">indent</span><span class="o">:</span> <span class="nx">@idt</span><span class="p">(),</span> <span class="nx">chainChild</span><span class="o">:</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-132"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-132">#</a> </div> <p>Compile the <strong>IfNode</strong> as a regular <em>if-else</em> statement. Flattened chains
<span class="s2">&quot;#{ifPart}#{elsePart}&quot;</span></pre></div> </td> </tr> <tr id="section-131"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-131">#</a> </div> <p>Compile the <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="nx">compileTernary</span><span class="o">:</span> <span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nx">@bodyNode</span><span class="p">().</span><span class="nv">tags.operation = </span><span class="vi">@condition.tags.operation = </span><span class="kc">yes</span>
<span class="nx">@elseBodyNode</span><span class="p">().</span><span class="nv">tags.operation = </span><span class="kc">yes</span> <span class="k">if</span> <span class="nx">@elseBody</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="nv">code = </span><span class="s2">&quot;#{ifPart} : #{elsePart}&quot;</span>
<span class="k">if</span> <span class="nx">@tags</span><span class="p">.</span><span class="nx">operation</span> <span class="k">then</span> <span class="s2">&quot;(#{code})&quot;</span> <span class="k">else</span> <span class="nx">code</span></pre></div> </td> </tr> <tr id="section-133"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-133">#</a> </div> <p>Compile the IfNode as a ternary operator.</p> </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> <h2>Faux-Nodes</h2> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-135"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-135">#</a> </div> <h3>PushNode</h3> </td> <td class="code"> <div class="highlight"><pre><span class="nv">PushNode = exports.PushNode =</span>
<span class="k">if</span> <span class="nx">@tags</span><span class="p">.</span><span class="nx">operation</span> <span class="k">then</span> <span class="s2">&quot;(#{code})&quot;</span> <span class="k">else</span> <span class="nx">code</span></pre></div> </td> </tr> <tr id="section-132"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-132">#</a> </div> <p>Compile the IfNode as a ternary operator.</p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-133"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-133">#</a> </div> <h2>Faux-Nodes</h2> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-134"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-134">#</a> </div> <h3>PushNode</h3> </td> <td class="code"> <div class="highlight"><pre><span class="nv">PushNode = exports.PushNode =</span>
<span class="nx">wrap</span><span class="o">:</span> <span class="p">(</span><span class="nx">array</span><span class="p">,</span> <span class="nx">expressions</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">expr = </span><span class="nx">expressions</span><span class="p">.</span><span class="nx">unwrap</span><span class="p">()</span>
<span class="k">return</span> <span class="nx">expressions</span> <span class="k">if</span> <span class="nx">expr</span><span class="p">.</span><span class="nx">isPureStatement</span><span class="p">()</span> <span class="o">or</span> <span class="nx">expr</span><span class="p">.</span><span class="nx">containsPureStatement</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="k">new</span> <span class="nx">CallNode</span><span class="p">(</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">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></pre></div> </td> </tr> <tr id="section-136"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-136">#</a> </div> <p>Faux-nodes are never created by the grammar, but are used during code
<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>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></pre></div> </td> </tr> <tr id="section-137"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-137">#</a> </div> <h3>ClosureNode</h3> </td> <td class="code"> <div class="highlight"><pre><span class="nv">ClosureNode = exports.ClosureNode =</span></pre></div> </td> </tr> <tr id="section-138"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-138">#</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="nx">wrap</span><span class="o">:</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>
arrays from comprehensions.</p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-136"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-136">#</a> </div> <h3>ClosureNode</h3> </td> <td class="code"> <div class="highlight"><pre><span class="nv">ClosureNode = exports.ClosureNode =</span></pre></div> </td> </tr> <tr id="section-137"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-137">#</a> </div> <p>A faux-node used to wrap an expressions body in a closure.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">wrap</span><span class="o">:</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>
@@ -1212,9 +1215,9 @@ arrays from comprehensions.</p> </td> <td class="code">
<span class="nx">args</span><span class="p">.</span><span class="nx">push</span> <span class="nx">literal</span> <span class="s1">&#39;arguments&#39;</span> <span class="k">if</span> <span class="nx">mentionsArgs</span>
<span class="nv">func = </span><span class="k">new</span> <span class="nx">ValueNode</span> <span class="nx">func</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">meth</span><span class="p">)]</span>
<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></pre></div> </td> </tr> <tr id="section-139"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-139">#</a> </div> <p>Wrap the expressions body, unless it contains a pure statement,
<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></pre></div> </td> </tr> <tr id="section-138"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-138">#</a> </div> <p>Wrap the expressions body, unless it contains a pure statement,
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">UTILITIES =</span></pre></div> </td> </tr> <tr id="section-140"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-140">#</a> </div> <h2>Utility Functions</h2> </td> <td class="code"> <div class="highlight"><pre> <span class="k">extends</span><span class="o">:</span> <span class="s2">&quot;&quot;&quot;</span>
then make sure that the closure wrapper preserves the original values.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">UTILITIES =</span></pre></div> </td> </tr> <tr id="section-139"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-139">#</a> </div> <h2>Utility Functions</h2> </td> <td class="code"> <div class="highlight"><pre> <span class="k">extends</span><span class="o">:</span> <span class="s2">&quot;&quot;&quot;</span>
<span class="s2"> function(child, parent) {</span>
<span class="s2"> var ctor = function(){};</span>
<span class="s2"> ctor.prototype = parent.prototype;</span>
@@ -1223,20 +1226,20 @@ then make sure that the closure wrapper preserves the original values.</p>
<span class="s2"> if (typeof parent.extended === &quot;</span><span class="nx">function</span><span class="s2">&quot;) parent.extended(child);</span>
<span class="s2"> child.__super__ = parent.prototype;</span>
<span class="s2"> }</span>
<span class="s2"> &quot;&quot;&quot;</span></pre></div> </td> </tr> <tr id="section-141"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-141">#</a> </div> <p>Correctly set up a prototype chain for inheritance, including a reference
<span class="s2"> &quot;&quot;&quot;</span></pre></div> </td> </tr> <tr id="section-140"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-140">#</a> </div> <p>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="nx">bind</span><span class="o">:</span> <span class="s2">&quot;&quot;&quot;</span>
<span class="s2"> function(func, context) {</span>
<span class="s2"> return function(){ return func.apply(context, arguments); };</span>
<span class="s2"> }</span>
<span class="s2"> &quot;&quot;&quot;</span></pre></div> </td> </tr> <tr id="section-142"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-142">#</a> </div> <p>Create a function bound to the current value of "this".</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">hasProp</span><span class="o">:</span> <span class="s1">&#39;Object.prototype.hasOwnProperty&#39;</span>
<span class="nx">slice</span><span class="o">:</span> <span class="s1">&#39;Array.prototype.slice&#39;</span></pre></div> </td> </tr> <tr id="section-143"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-143">#</a> </div> <p>Shortcuts to speed up the lookup time for native functions.</p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-144"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-144">#</a> </div> <h2>Constants</h2> </td> <td class="code"> <div class="highlight"><pre><span class="nv">TAB = </span><span class="s1">&#39; &#39;</span></pre></div> </td> </tr> <tr id="section-145"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-145">#</a> </div> <p>Tabs are two spaces for pretty printing.</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-146"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-146">#</a> </div> <p>Trim out all trailing whitespace, so that the generated code plays nice
<span class="s2"> &quot;&quot;&quot;</span></pre></div> </td> </tr> <tr id="section-141"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-141">#</a> </div> <p>Create a function bound to the current value of "this".</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">hasProp</span><span class="o">:</span> <span class="s1">&#39;Object.prototype.hasOwnProperty&#39;</span>
<span class="nx">slice</span><span class="o">:</span> <span class="s1">&#39;Array.prototype.slice&#39;</span></pre></div> </td> </tr> <tr id="section-142"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-142">#</a> </div> <p>Shortcuts to speed up the lookup time for native functions.</p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-143"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-143">#</a> </div> <h2>Constants</h2> </td> <td class="code"> <div class="highlight"><pre><span class="nv">TAB = </span><span class="s1">&#39; &#39;</span></pre></div> </td> </tr> <tr id="section-144"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-144">#</a> </div> <p>Tabs are two spaces for pretty printing.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">TRAILING_WHITESPACE = </span><span class="sr">/[ \t]+$/gm</span></pre></div> </td> </tr> <tr id="section-145"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-145">#</a> </div> <p>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">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>
<span class="nv">SIMPLENUM = </span><span class="sr">/^-?\d+$/</span></pre></div> </td> </tr> <tr id="section-147"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-147">#</a> </div> <p>Keep these identifier regexes in sync with the Lexer.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">IS_STRING = </span><span class="sr">/^[&#39;&quot;]/</span></pre></div> </td> </tr> <tr id="section-148"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-148">#</a> </div> <p>Is a literal value a string?</p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-149"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-149">#</a> </div> <h2>Utility Functions</h2> </td> <td class="code"> <div class="highlight"><pre><span class="nv">literal = </span><span class="p">(</span><span class="nx">name</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="k">new</span> <span class="nx">LiteralNode</span><span class="p">(</span><span class="nx">name</span><span class="p">)</span></pre></div> </td> </tr> <tr id="section-150"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-150">#</a> </div> <p>Handy helper for a generating LiteralNode.</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">SIMPLENUM = </span><span class="sr">/^-?\d+$/</span></pre></div> </td> </tr> <tr id="section-146"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-146">#</a> </div> <p>Keep these identifier regexes in sync with the Lexer.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">IS_STRING = </span><span class="sr">/^[&#39;&quot;]/</span></pre></div> </td> </tr> <tr id="section-147"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-147">#</a> </div> <p>Is a literal value a string?</p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-148"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-148">#</a> </div> <h2>Utility Functions</h2> </td> <td class="code"> <div class="highlight"><pre><span class="nv">literal = </span><span class="p">(</span><span class="nx">name</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="k">new</span> <span class="nx">LiteralNode</span><span class="p">(</span><span class="nx">name</span><span class="p">)</span></pre></div> </td> </tr> <tr id="section-149"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-149">#</a> </div> <p>Handy helper for a generating LiteralNode.</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">name</span><span class="p">]</span>
<span class="nx">ref</span>
</pre></div> </td> </tr> <tr id="section-151"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-151">#</a> </div> <p>Helper for ensuring that utility functions are assigned at the top level.</p> </td> <td class="code"> <div class="highlight"><pre>undefined</pre></div> </td> </tr> </tbody> </table> </div> </body> </html>
</pre></div> </td> </tr> <tr id="section-150"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-150">#</a> </div> <p>Helper for ensuring that utility functions are assigned at the top level.</p> </td> <td class="code"> <div class="highlight"><pre>undefined</pre></div> </td> </tr> </tbody> </table> </div> </body> </html>

View File

@@ -39,7 +39,7 @@ of the valid options, for <code>--help</code> and such.</p> </td>
<span class="nx">lines</span><span class="p">.</span><span class="nx">unshift</span> <span class="s2">&quot;#{@banner}\n&quot;</span> <span class="k">if</span> <span class="nx">@banner</span>
<span class="k">for</span> <span class="nx">rule</span> <span class="k">in</span> <span class="nx">@rules</span>
<span class="nv">spaces = </span><span class="mi">15</span> <span class="o">-</span> <span class="nx">rule</span><span class="p">.</span><span class="nx">longFlag</span><span class="p">.</span><span class="nx">length</span>
<span class="nv">spaces = </span><span class="k">if</span> <span class="nx">spaces</span> <span class="o">&gt;</span> <span class="mi">0</span> <span class="k">then</span> <span class="p">(</span><span class="s1">&#39; &#39;</span> <span class="k">for</span> <span class="nx">i</span> <span class="k">in</span> <span class="p">[</span><span class="mi">0</span><span class="p">..</span><span class="nx">spaces</span><span class="p">]).</span><span class="nx">join</span><span class="p">(</span><span class="s1">&#39;&#39;</span><span class="p">)</span> <span class="k">else</span> <span class="s1">&#39;&#39;</span>
<span class="nv">spaces = </span><span class="k">if</span> <span class="nx">spaces</span> <span class="o">&gt;</span> <span class="mi">0</span> <span class="k">then</span> <span class="nb">Array</span><span class="p">(</span><span class="nx">spaces</span> <span class="o">+</span> <span class="mi">1</span><span class="p">).</span><span class="nx">join</span><span class="p">(</span><span class="s1">&#39; &#39;</span><span class="p">)</span> <span class="k">else</span> <span class="s1">&#39;&#39;</span>
<span class="nv">letPart = </span><span class="k">if</span> <span class="nx">rule</span><span class="p">.</span><span class="nx">shortFlag</span> <span class="k">then</span> <span class="nx">rule</span><span class="p">.</span><span class="nx">shortFlag</span> <span class="o">+</span> <span class="s1">&#39;, &#39;</span> <span class="k">else</span> <span class="s1">&#39; &#39;</span>
<span class="nx">lines</span><span class="p">.</span><span class="nx">push</span> <span class="s1">&#39; &#39;</span> <span class="o">+</span> <span class="nx">letPart</span> <span class="o">+</span> <span class="nx">rule</span><span class="p">.</span><span class="nx">longFlag</span> <span class="o">+</span> <span class="nx">spaces</span> <span class="o">+</span> <span class="nx">rule</span><span class="p">.</span><span class="nx">description</span>
<span class="s2">&quot;\n#{ lines.join(&#39;\n&#39;) }\n&quot;</span></pre></div> </td> </tr> <tr id="section-5"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-5">#</a> </div> <h2>Helpers</h2> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-6"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-6">#</a> </div> <p>Regex matchers for option flags.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">LONG_FLAG = </span><span class="sr">/^(--\w[\w\-]+)/</span>

View File

@@ -9,7 +9,7 @@ Using it looks like this:</p>
Attempt to evaluate the command. If there's an exception, print it out instead
of exiting.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">run = </span><span class="p">(</span><span class="nx">buffer</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="k">try</span>
<span class="nv">val = </span><span class="nx">CoffeeScript</span><span class="p">.</span><span class="nx">run</span> <span class="nx">buffer</span><span class="p">.</span><span class="nx">toString</span><span class="p">(),</span> <span class="nx">noWrap</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span> <span class="nx">globals</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span> <span class="nx">fileName</span><span class="o">:</span> <span class="s1">&#39;repl&#39;</span>
<span class="nv">val = </span><span class="nx">CoffeeScript</span><span class="p">.</span><span class="nb">eval</span> <span class="nx">buffer</span><span class="p">.</span><span class="nx">toString</span><span class="p">(),</span> <span class="nx">noWrap</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span> <span class="nx">globals</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span> <span class="nx">fileName</span><span class="o">:</span> <span class="s1">&#39;repl&#39;</span>
<span class="nx">puts</span> <span class="nx">inspect</span> <span class="nx">val</span> <span class="k">if</span> <span class="nx">val</span> <span class="o">isnt</span> <span class="kc">undefined</span>
<span class="k">catch</span> <span class="nx">err</span>
<span class="nx">puts</span> <span class="nx">err</span><span class="p">.</span><span class="nx">stack</span> <span class="o">or</span> <span class="nx">err</span><span class="p">.</span><span class="nx">toString</span><span class="p">()</span>

View File

@@ -3,13 +3,9 @@ and shorthand syntax. This can greatly complicate a grammar and bloat
the resulting parse table. Instead of making the parser handle it all, we take
a series of passes over the token stream, using this <strong>Rewriter</strong> to convert
shorthand into the unambiguous long form, add implicit indentation and
parentheses, balance incorrect nestings, and generally clean things up.</p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-2"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-2">#</a> </div> <p>Set up exported variables for both Node.js and the browser.</p> </td> <td class="code"> <div class="highlight"><pre><span class="k">if</span> <span class="nx">process</span><span class="o">?</span>
<span class="p">{</span><span class="nx">helpers</span><span class="p">}</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;./helpers&#39;</span><span class="p">)</span>
<span class="k">else</span>
<span class="k">this</span><span class="p">.</span><span class="nv">exports = </span><span class="k">this</span>
<span class="nv">helpers = </span><span class="k">this</span><span class="p">.</span><span class="nx">helpers</span></pre></div> </td> </tr> <tr id="section-3"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-3">#</a> </div> <p>Import the helpers we need.</p> </td> <td class="code"> <div class="highlight"><pre><span class="p">{</span><span class="nx">include</span><span class="p">}</span> <span class="o">=</span> <span class="nx">helpers</span></pre></div> </td> </tr> <tr id="section-4"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-4">#</a> </div> <p>The <strong>Rewriter</strong> class is used by the <a href="lexer.html">Lexer</a>, directly against
its internal array of tokens.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.Rewriter = </span><span class="nx">class</span> <span class="nx">Rewriter</span></pre></div> </td> </tr> <tr id="section-5"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-5">#</a> </div> <p>Helpful snippet for debugging:
puts (t[0] + '/' + t[1] for t in @tokens).join ' '</p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-6"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-6">#</a> </div> <p>Rewrite the token stream in multiple passes, one logical filter at
parentheses, balance incorrect nestings, and generally clean things up.</p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-2"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-2">#</a> </div> <p>Import the helpers we need.</p> </td> <td class="code"> <div class="highlight"><pre><span class="p">{</span><span class="nx">include</span><span class="p">}</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;./helpers&#39;</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 <strong>Rewriter</strong> class is used by the <a href="lexer.html">Lexer</a>, directly against
its internal array of tokens.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.Rewriter = </span><span class="nx">class</span> <span class="nx">Rewriter</span></pre></div> </td> </tr> <tr id="section-4"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-4">#</a> </div> <p>Helpful snippet for debugging:
puts (t[0] + '/' + t[1] for t in @tokens).join ' '</p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-5"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-5">#</a> </div> <p>Rewrite the token stream in multiple passes, one logical filter at
a time. This could certainly be changed into a single pass through the
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
@@ -26,7 +22,7 @@ corrected before implicit parentheses can be wrapped around blocks of code.</p>
<span class="nx">@addImplicitParentheses</span><span class="p">()</span>
<span class="nx">@ensureBalance</span> <span class="nx">BALANCED_PAIRS</span>
<span class="nx">@rewriteClosingParens</span><span class="p">()</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>Rewrite the token stream, looking one token ahead and behind.
<span class="nx">@tokens</span></pre></div> </td> </tr> <tr id="section-6"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-6">#</a> </div> <p>Rewrite the token stream, looking one token ahead and behind.
Allow the return value of the block to tell us how many tokens to move
forwards (or backwards) in the stream, to make sure we don't miss anything
as tokens are inserted and removed, and the stream changes length under
@@ -47,7 +43,7 @@ our feet.</p> </td> <td class="code"> <div
<span class="nx">levels</span> <span class="o">+=</span> <span class="mi">1</span> <span class="k">if</span> <span class="nx">include</span> <span class="nx">EXPRESSION_START</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="nx">levels</span> <span class="o">-=</span> <span class="mi">1</span> <span class="k">if</span> <span class="nx">include</span> <span class="nx">EXPRESSION_END</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="nx">i</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="nx">i</span> <span class="o">-</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>Massage newlines and indentations so that comments don't have to be
<span class="nx">i</span> <span class="o">-</span> <span class="mi">1</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="nx">adjustComments</span><span class="o">:</span> <span class="o">-&gt;</span>
<span class="nx">@scanTokens</span> <span class="p">(</span><span class="nx">token</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>
@@ -66,14 +62,14 @@ correctly indented, or appear on a line of their own.</p> </td>
<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-9"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-9">#</a> </div> <p>Leading newlines would introduce an ambiguity in the grammar, so we
<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="nx">removeLeadingNewlines</span><span class="o">:</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-10"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-10">#</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="nx">removeMidExpressionNewlines</span><span class="o">:</span> <span class="o">-&gt;</span>
<span class="nx">@scanTokens</span> <span class="p">(</span><span class="nx">token</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">include</span><span class="p">(</span><span class="nx">EXPRESSION_CLOSE</span><span class="p">,</span> <span class="nx">@tag</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="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-11"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-11">#</a> </div> <p>The lexer has tagged the opening parenthesis of a method call. Match it with
<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. Match it with
its paired close. We have the mis-nested outdent case included here for
calls that close on the same line, just before their outdent.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">closeOpenCalls</span><span class="o">:</span> <span class="o">-&gt;</span>
<span class="nx">@scanTokens</span> <span class="p">(</span><span class="nx">token</span><span class="p">,</span> <span class="nx">i</span><span class="p">)</span> <span class="o">-&gt;</span>
@@ -84,14 +80,14 @@ calls that close on the same line, just before their outdent.</p> </
<span class="nv">idx = </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;OUTDENT&#39;</span> <span class="k">then</span> <span class="nx">i</span> <span class="o">-</span> <span class="mi">1</span> <span class="k">else</span> <span class="nx">i</span>
<span class="nx">@tokens</span><span class="p">[</span><span class="nx">idx</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="s1">&#39;CALL_END&#39;</span>
<span class="nx">@detectEnd</span> <span class="nx">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="nx">condition</span><span class="p">,</span> <span class="nx">action</span>
<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>The lexer has tagged the opening parenthesis of an indexing operation call.
<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>The lexer has tagged the opening parenthesis of an indexing operation call.
Match it with its paired close.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">closeOpenIndexes</span><span class="o">:</span> <span class="o">-&gt;</span>
<span class="nx">@scanTokens</span> <span class="p">(</span><span class="nx">token</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;INDEX_START&#39;</span>
<span class="nv">condition = </span><span class="p">(</span><span class="nx">token</span><span class="p">,</span> <span class="nx">i</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nx">token</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">in</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="nv">action = </span><span class="p">(</span><span class="nx">token</span><span class="p">,</span> <span class="nx">i</span><span class="p">)</span> <span class="o">-&gt;</span> <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="nx">@detectEnd</span> <span class="nx">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="nx">condition</span><span class="p">,</span> <span class="nx">action</span>
<span class="k">return</span> <span class="mi">1</span></pre></div> </td> </tr> <tr id="section-13"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-13">#</a> </div> <p>Object literals may be written with implicit braces, for simple cases.
<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>Object literals may be written with implicit braces, for simple cases.
Insert the missing braces here, so that the parser doesn't have to.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">addImplicitBraces</span><span class="o">:</span> <span class="o">-&gt;</span>
<span class="nv">stack = </span><span class="p">[]</span>
<span class="nx">@scanTokens</span> <span class="p">(</span><span class="nx">token</span><span class="p">,</span> <span class="nx">i</span><span class="p">)</span> <span class="o">-&gt;</span>
@@ -103,6 +99,7 @@ Insert the missing braces here, so that the parser doesn't have to.</p>
<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;:&#39;</span> <span class="o">and</span> <span class="p">(</span><span class="o">not</span> <span class="nx">last</span> <span class="o">or</span> <span class="nx">last</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="p">)</span>
<span class="nx">stack</span><span class="p">.</span><span class="nx">push</span> <span class="s1">&#39;{&#39;</span>
<span class="nv">idx = </span><span class="k">if</span> <span class="nx">@tag</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="o">is</span> <span class="s1">&#39;@&#39;</span> <span class="k">then</span> <span class="nx">i</span> <span class="o">-</span> <span class="mi">2</span> <span class="k">else</span> <span class="nx">i</span> <span class="o">-</span> <span class="mi">1</span>
<span class="nx">idx</span> <span class="o">-=</span> <span class="mi">2</span> <span class="k">if</span> <span class="nx">@tag</span><span class="p">(</span><span class="nx">idx</span> <span class="o">-</span> <span class="mi">2</span><span class="p">)</span> <span class="o">is</span> <span class="s1">&#39;HERECOMMENT&#39;</span>
<span class="nv">tok = </span><span class="p">[</span><span class="s1">&#39;{&#39;</span><span class="p">,</span> <span class="s1">&#39;{&#39;</span><span class="p">,</span> <span class="nx">token</span><span class="p">[</span><span class="mi">2</span><span class="p">]]</span>
<span class="nv">tok.generated = </span><span class="kc">yes</span>
<span class="nx">@tokens</span><span class="p">.</span><span class="nx">splice</span> <span class="nx">idx</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">tok</span>
@@ -115,7 +112,7 @@ Insert the missing braces here, so that the parser doesn't have to.</p>
<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;}&#39;</span><span class="p">,</span> <span class="s1">&#39;}&#39;</span><span class="p">,</span> <span class="nx">token</span><span class="p">[</span><span class="mi">2</span><span class="p">]]</span>
<span class="nx">@detectEnd</span> <span class="nx">i</span> <span class="o">+</span> <span class="mi">2</span><span class="p">,</span> <span class="nx">condition</span><span class="p">,</span> <span class="nx">action</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-14"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-14">#</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-13"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-13">#</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="nx">addImplicitParentheses</span><span class="o">:</span> <span class="o">-&gt;</span>
<span class="nv">classLine = </span><span class="kc">no</span>
@@ -135,8 +132,9 @@ deal with them.</p> </td> <td class="code">
<span class="nv">condition = </span><span class="p">(</span><span class="nx">token</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="kc">yes</span> <span class="k">if</span> <span class="o">not</span> <span class="nx">seenSingle</span> <span class="o">and</span> <span class="nx">token</span><span class="p">.</span><span class="nx">fromThen</span>
<span class="nv">seenSingle = </span><span class="kc">yes</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="k">in</span> <span class="p">[</span><span class="s1">&#39;IF&#39;</span><span class="p">,</span> <span class="s1">&#39;ELSE&#39;</span><span class="p">,</span> <span class="s1">&#39;UNLESS&#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="nv">post = </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="p">(</span><span class="o">not</span> <span class="nx">token</span><span class="p">.</span><span class="nx">generated</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">1</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="nx">include</span><span class="p">(</span><span class="nx">IMPLICIT_END</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="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;INDENT&#39;</span> <span class="o">and</span> <span class="p">(</span><span class="nx">include</span><span class="p">(</span><span class="nx">IMPLICIT_BLOCK</span><span class="p">,</span> <span class="nx">@tag</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="o">or</span> <span class="nx">@tag</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="o">is</span> <span class="s1">&#39;CLASS&#39;</span> <span class="o">or</span> <span class="nx">@tag</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="o">is</span> <span class="s1">&#39;{&#39;</span><span class="p">)))</span> <span class="o">or</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;INDENT&#39;</span> <span class="o">and</span> <span class="p">(</span><span class="nx">include</span><span class="p">(</span><span class="nx">IMPLICIT_BLOCK</span><span class="p">,</span> <span class="nx">@tag</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="o">or</span> <span class="nx">@tag</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="o">is</span> <span class="s1">&#39;CLASS&#39;</span> <span class="o">or</span> <span class="p">(</span><span class="nx">post</span> <span class="o">and</span> <span class="nx">post</span><span class="p">.</span><span class="nx">generated</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;{&#39;</span><span class="p">))))</span> <span class="o">or</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;PROPERTY_ACCESS&#39;</span> <span class="o">and</span> <span class="nx">@tag</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="o">is</span> <span class="s1">&#39;OUTDENT&#39;</span>
<span class="nv">action = </span><span class="p">(</span><span class="nx">token</span><span class="p">,</span> <span class="nx">i</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">idx = </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;OUTDENT&#39;</span> <span class="k">then</span> <span class="nx">i</span> <span class="o">+</span> <span class="mi">1</span> <span class="k">else</span> <span class="nx">i</span>
@@ -144,7 +142,7 @@ deal with them.</p> </td> <td class="code">
<span class="nx">@detectEnd</span> <span class="nx">i</span> <span class="o">+</span> <span class="nx">idx</span><span class="p">,</span> <span class="nx">condition</span><span class="p">,</span> <span class="nx">action</span>
<span class="nx">prev</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="s1">&#39;FUNC_EXIST&#39;</span> <span class="k">if</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">return</span> <span class="mi">2</span>
<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>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-14"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-14">#</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="nx">addImplicitIndentation</span><span class="o">:</span> <span class="o">-&gt;</span>
@@ -172,7 +170,7 @@ but we need to make sure it's balanced.</p> </td> <td cl
<span class="nx">@detectEnd</span> <span class="nx">i</span> <span class="o">+</span> <span class="mi">2</span><span class="p">,</span> <span class="nx">condition</span><span class="p">,</span> <span class="nx">action</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">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;THEN&#39;</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-16"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-16">#</a> </div> <p>Tag postfix conditionals as such, so that we can parse them with a
<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>Tag postfix conditionals as such, so that we can parse them with a
different precedence.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">tagPostfixConditionals</span><span class="o">:</span> <span class="o">-&gt;</span>
<span class="nx">@scanTokens</span> <span class="p">(</span><span class="nx">token</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="k">in</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>
@@ -183,7 +181,7 @@ different precedence.</p> </td> <td class="code">
<span class="nx">original</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="s1">&#39;POST_&#39;</span> <span class="o">+</span> <span class="nx">original</span><span class="p">[</span><span class="mi">0</span><span class="p">]</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">isnt</span> <span class="s1">&#39;INDENT&#39;</span>
<span class="nx">@detectEnd</span> <span class="nx">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="nx">condition</span><span class="p">,</span> <span class="nx">action</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-17"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-17">#</a> </div> <p>Ensure that all listed pairs of tokens are correctly balanced throughout
<span class="k">return</span> <span class="mi">1</span></pre></div> </td> </tr> <tr id="section-16"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-16">#</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="nx">ensureBalance</span><span class="o">:</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>
@@ -201,7 +199,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-18"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-18">#</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-17"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-17">#</a> </div> <p>We'd like to support syntax like this:</p>
<pre><code>el.click((event) -&gt;
el.hide())
@@ -248,20 +246,20 @@ 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-19"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-19">#</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="nx">indentation</span><span class="o">:</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-20"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-20">#</a> </div> <p>Look up a tag by token index.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">tag</span><span class="o">:</span> <span class="p">(</span><span class="nx">i</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nx">@tokens</span><span class="p">[</span><span class="nx">i</span><span class="p">]</span> <span class="o">and</span> <span class="nx">@tokens</span><span class="p">[</span><span class="nx">i</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-21"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-21">#</a> </div> <h2>Constants</h2> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-22"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-22">#</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-23"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-23">#</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-18"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-18">#</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="nx">indentation</span><span class="o">:</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-19"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-19">#</a> </div> <p>Look up a tag by token index.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">tag</span><span class="o">:</span> <span class="p">(</span><span class="nx">i</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nx">@tokens</span><span class="p">[</span><span class="nx">i</span><span class="p">]</span> <span class="o">and</span> <span class="nx">@tokens</span><span class="p">[</span><span class="nx">i</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-20"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-20">#</a> </div> <h2>Constants</h2> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-21"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-21">#</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-22"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-22">#</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-24"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-24">#</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-25"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-25">#</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-26"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-26">#</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-27"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-27">#</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> <span class="s1">&#39;THIS&#39;</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>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="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-23"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-23">#</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-24"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-24">#</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-25"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-25">#</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-26"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-26">#</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> <span class="s1">&#39;THIS&#39;</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-27"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-27">#</a> </div> <p>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;CLASS&#39;</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;TRY&#39;</span><span class="p">,</span> <span class="s1">&#39;SWITCH&#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;UNARY&#39;</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;-&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-29"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-29">#</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-30"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-30">#</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;POST_IF&#39;</span><span class="p">,</span> <span class="s1">&#39;POST_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></pre></div> </td> </tr> <tr id="section-31"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-31">#</a> </div> <p>Single-line flavors of block expressions that have unclosed endings.
<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>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-29"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-29">#</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;POST_IF&#39;</span><span class="p">,</span> <span class="s1">&#39;POST_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></pre></div> </td> </tr> <tr id="section-30"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-30">#</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></pre></div> </td> </tr> <tr id="section-32"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-32">#</a> </div> <p>Tokens that end a line.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">LINEBREAKS = </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="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></pre></div> </td> </tr> <tr id="section-31"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-31">#</a> </div> <p>Tokens that end a line.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">LINEBREAKS = </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>
</pre></div> </td> </tr> </tbody> </table> </div> </body> </html>

View File

@@ -3,7 +3,7 @@ generate code, you create a tree of scopes in the same shape as the nested
function bodies. Each scope knows about the variables declared within it,
and has a reference to its parent enclosing scope. In this way, we know which
variables are new and need to be declared with <code>var</code>, and which are shared
with the outside.</p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-2"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-2">#</a> </div> <p>Set up exported variables for both <strong>Node.js</strong> and the browser.</p> </td> <td class="code"> <div class="highlight"><pre><span class="k">this</span><span class="p">.</span><span class="nv">exports = </span><span class="k">this</span> <span class="nx">unless</span> <span class="nx">process</span><span class="o">?</span>
with the outside.</p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-2"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-2">#</a> </div> <p>Import the helpers we plan to use.</p> </td> <td class="code"> <div class="highlight"><pre><span class="p">{</span><span class="nx">extend</span><span class="p">}</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;./helpers&#39;</span><span class="p">).</span><span class="nx">helpers</span>
<span class="nv">exports.Scope = </span><span class="nx">class</span> <span class="nx">Scope</span></pre></div> </td> </tr> <tr id="section-3"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-3">#</a> </div> <p>The top-level <strong>Scope</strong> object.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">@root</span><span class="o">:</span> <span class="kc">null</span></pre></div> </td> </tr> <tr id="section-4"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-4">#</a> </div> <p>Initialize a scope with its parent, for lookups up the chain,
as well as a reference to the <strong>Expressions</strong> node is belongs to, which is
@@ -12,39 +12,46 @@ it wraps.</p> </td> <td class="code"> <div
<span class="p">[</span><span class="nx">@parent</span><span class="p">,</span> <span class="nx">@expressions</span><span class="p">,</span> <span class="nx">@method</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="nx">parent</span><span class="p">,</span> <span class="nx">expressions</span><span class="p">,</span> <span class="nx">method</span><span class="p">]</span>
<span class="vi">@variables = </span><span class="p">{}</span>
<span class="k">if</span> <span class="nx">@parent</span>
<span class="vi">@tempVar = </span><span class="nx">@parent</span><span class="p">.</span><span class="nx">tempVar</span>
<span class="vi">@garbage = </span><span class="nx">@parent</span><span class="p">.</span><span class="nx">garbage</span>
<span class="k">else</span>
<span class="nv">Scope.root = </span><span class="k">this</span>
<span class="vi">@tempVar = </span><span class="s1">&#39;_a&#39;</span></pre></div> </td> </tr> <tr id="section-5"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-5">#</a> </div> <p>Look up a variable name in lexical scope, and declare it if it does not
<span class="vi">@garbage = </span><span class="p">[]</span>
<span class="nv">Scope.root = </span><span class="k">this</span></pre></div> </td> </tr> <tr id="section-5"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-5">#</a> </div> <p>Create a new garbage level</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">startLevel</span><span class="o">:</span> <span class="o">-&gt;</span>
<span class="nx">@garbage</span><span class="p">.</span><span class="nx">push</span> <span class="p">[]</span></pre></div> </td> </tr> <tr id="section-6"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-6">#</a> </div> <p>Return to the previous garbage level and erase referenced temporary
variables in current level from scope.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">endLevel</span><span class="o">:</span> <span class="o">-&gt;</span>
<span class="p">(</span><span class="nx">@variables</span><span class="p">[</span><span class="nx">name</span><span class="p">]</span> <span class="o">=</span> <span class="s1">&#39;reuse&#39;</span><span class="p">)</span> <span class="k">for</span> <span class="nx">name</span> <span class="k">in</span> <span class="nx">@garbage</span><span class="p">.</span><span class="nx">pop</span><span class="p">()</span> <span class="k">when</span> <span class="nx">@variables</span><span class="p">[</span><span class="nx">name</span><span class="p">]</span> <span class="o">is</span> <span class="s1">&#39;var&#39;</span></pre></div> </td> </tr> <tr id="section-7"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-7">#</a> </div> <p>Look up a variable name in lexical scope, and declare it if it does not
already exist.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">find</span><span class="o">:</span> <span class="p">(</span><span class="nx">name</span><span class="p">,</span> <span class="nx">options</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="k">return</span> <span class="kc">true</span> <span class="k">if</span> <span class="nx">@check</span> <span class="nx">name</span><span class="p">,</span> <span class="nx">options</span>
<span class="nx">@variables</span><span class="p">[</span><span class="nx">name</span><span class="p">]</span> <span class="o">=</span> <span class="s1">&#39;var&#39;</span>
<span class="kc">false</span></pre></div> </td> </tr> <tr id="section-6"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-6">#</a> </div> <p>Test variables and return true the first time fn(v, k) returns true</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">any</span><span class="o">:</span> <span class="p">(</span><span class="nx">fn</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="kc">false</span></pre></div> </td> </tr> <tr id="section-8"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-8">#</a> </div> <p>Test variables and return true the first time fn(v, k) returns true</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">any</span><span class="o">:</span> <span class="p">(</span><span class="nx">fn</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="k">for</span> <span class="nx">v</span><span class="p">,</span> <span class="nx">k</span> <span class="k">of</span> <span class="nx">@variables</span> <span class="k">when</span> <span class="nx">fn</span><span class="p">(</span><span class="nx">v</span><span class="p">,</span> <span class="nx">k</span><span class="p">)</span>
<span class="k">return</span> <span class="kc">true</span>
<span class="k">return</span> <span class="kc">false</span></pre></div> </td> </tr> <tr id="section-7"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-7">#</a> </div> <p>Reserve a variable name as originating from a function parameter for this
<span class="k">return</span> <span class="kc">false</span></pre></div> </td> </tr> <tr id="section-9"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-9">#</a> </div> <p>Reserve a variable name as originating from a function parameter for this
scope. No <code>var</code> required for internal references.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">parameter</span><span class="o">:</span> <span class="p">(</span><span class="nx">name</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nx">@variables</span><span class="p">[</span><span class="nx">name</span><span class="p">]</span> <span class="o">=</span> <span class="s1">&#39;param&#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>Just check to see if a variable has already been declared, without reserving,
<span class="nx">@variables</span><span class="p">[</span><span class="nx">name</span><span class="p">]</span> <span class="o">=</span> <span class="s1">&#39;param&#39;</span></pre></div> </td> </tr> <tr id="section-10"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-10">#</a> </div> <p>Just check to see if a variable has already been declared, without reserving,
walks up to the root scope.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">check</span><span class="o">:</span> <span class="p">(</span><span class="nx">name</span><span class="p">,</span> <span class="nx">options</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">immediate = </span><span class="nb">Object</span><span class="o">::</span><span class="nx">hasOwnProperty</span><span class="p">.</span><span class="nx">call</span> <span class="nx">@variables</span><span class="p">,</span> <span class="nx">name</span>
<span class="k">return</span> <span class="nx">immediate</span> <span class="k">if</span> <span class="nx">immediate</span> <span class="o">or</span> <span class="p">(</span><span class="nx">options</span> <span class="o">and</span> <span class="nx">options</span><span class="p">.</span><span class="nx">immediate</span><span class="p">)</span>
<span class="o">!!</span><span class="p">(</span><span class="nx">@parent</span> <span class="o">and</span> <span class="nx">@parent</span><span class="p">.</span><span class="nx">check</span><span class="p">(</span><span class="nx">name</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>If we need to store an intermediate result, find an available name for a
compiler-generated variable. <code>_a</code>, <code>_b</code>, and so on...</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">freeVariable</span><span class="o">:</span> <span class="o">-&gt;</span>
<span class="k">while</span> <span class="nx">@check</span> <span class="nx">@tempVar</span>
<span class="nv">ordinal = </span><span class="mi">1</span> <span class="o">+</span> <span class="nb">parseInt</span> <span class="nx">@tempVar</span><span class="p">.</span><span class="nx">substr</span><span class="p">(</span><span class="mi">1</span><span class="p">),</span> <span class="mi">36</span>
<span class="vi">@tempVar = </span><span class="s1">&#39;_&#39;</span> <span class="o">+</span> <span class="nx">ordinal</span><span class="p">.</span><span class="nx">toString</span><span class="p">(</span><span class="mi">36</span><span class="p">).</span><span class="nx">replace</span><span class="p">(</span><span class="sr">/\d/g</span><span class="p">,</span> <span class="s1">&#39;a&#39;</span><span class="p">)</span>
<span class="nx">@variables</span><span class="p">[</span><span class="nx">@tempVar</span><span class="p">]</span> <span class="o">=</span> <span class="s1">&#39;var&#39;</span>
<span class="nx">@tempVar</span></pre></div> </td> </tr> <tr id="section-10"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-10">#</a> </div> <p>Ensure that an assignment is made at the top of this scope
<span class="o">!!</span><span class="p">(</span><span class="nx">@parent</span> <span class="o">and</span> <span class="nx">@parent</span><span class="p">.</span><span class="nx">check</span><span class="p">(</span><span class="nx">name</span><span class="p">))</span></pre></div> </td> </tr> <tr id="section-11"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-11">#</a> </div> <p>Generate a temporary variable name at the given index.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">temporary</span><span class="o">:</span> <span class="p">(</span><span class="nx">type</span><span class="p">,</span> <span class="nx">index</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="k">if</span> <span class="nx">type</span><span class="p">.</span><span class="nx">length</span> <span class="o">&gt;</span> <span class="mi">1</span>
<span class="s1">&#39;_&#39;</span> <span class="o">+</span> <span class="nx">type</span> <span class="o">+</span> <span class="k">if</span> <span class="nx">index</span> <span class="o">&gt;</span> <span class="mi">1</span> <span class="k">then</span> <span class="nx">index</span> <span class="k">else</span> <span class="s1">&#39;&#39;</span>
<span class="k">else</span>
<span class="s1">&#39;_&#39;</span> <span class="o">+</span> <span class="p">(</span><span class="nx">index</span> <span class="o">+</span> <span class="nb">parseInt</span> <span class="nx">type</span><span class="p">,</span> <span class="mi">36</span><span class="p">).</span><span class="nx">toString</span><span class="p">(</span><span class="mi">36</span><span class="p">).</span><span class="nx">replace</span> <span class="sr">/\d/g</span><span class="p">,</span> <span class="s1">&#39;a&#39;</span></pre></div> </td> </tr> <tr id="section-12"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-12">#</a> </div> <p>If we need to store an intermediate result, find an available name for a
compiler-generated variable. <code>_var</code>, <code>_var2</code>, and so on...</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">freeVariable</span><span class="o">:</span> <span class="p">(</span><span class="nx">type</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">index = </span><span class="mi">0</span>
<span class="nx">index</span><span class="o">++</span> <span class="k">while</span> <span class="nx">@check</span><span class="p">(</span><span class="nv">temp = </span><span class="nx">@temporary</span> <span class="nx">type</span><span class="p">,</span> <span class="nx">index</span><span class="p">)</span> <span class="o">and</span> <span class="nx">@variables</span><span class="p">[</span><span class="nx">temp</span><span class="p">]</span> <span class="o">isnt</span> <span class="s1">&#39;reuse&#39;</span>
<span class="nx">@variables</span><span class="p">[</span><span class="nx">temp</span><span class="p">]</span> <span class="o">=</span> <span class="s1">&#39;var&#39;</span>
<span class="nx">@garbage</span><span class="p">[</span><span class="nx">@garbage</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="nx">push</span> <span class="nx">temp</span> <span class="k">if</span> <span class="nx">@garbage</span><span class="p">.</span><span class="nx">length</span>
<span class="nx">temp</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 an assignment is made at the top of this scope
(or at the top-level scope, if requested).</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">assign</span><span class="o">:</span> <span class="p">(</span><span class="nx">name</span><span class="p">,</span> <span class="nx">value</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nx">@variables</span><span class="p">[</span><span class="nx">name</span><span class="p">]</span> <span class="o">=</span> <span class="nx">value</span><span class="o">:</span> <span class="nx">value</span><span class="p">,</span> <span class="nx">assigned</span><span class="o">:</span> <span class="kc">true</span></pre></div> </td> </tr> <tr id="section-11"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-11">#</a> </div> <p>Does this scope reference any variables that need to be declared in the
<span class="nx">@variables</span><span class="p">[</span><span class="nx">name</span><span class="p">]</span> <span class="o">=</span> <span class="nx">value</span><span class="o">:</span> <span class="nx">value</span><span class="p">,</span> <span class="nx">assigned</span><span class="o">:</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>Does this scope reference any variables that need to be declared in the
given function body?</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">hasDeclarations</span><span class="o">:</span> <span class="p">(</span><span class="nx">body</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nx">body</span> <span class="o">is</span> <span class="nx">@expressions</span> <span class="o">and</span> <span class="nx">@any</span> <span class="p">(</span><span class="nx">k</span><span class="p">,</span> <span class="nx">val</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nx">val</span> <span class="o">is</span> <span class="s1">&#39;var&#39;</span></pre></div> </td> </tr> <tr id="section-12"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-12">#</a> </div> <p>Does this scope reference any assignments that need to be declared at the
<span class="nx">body</span> <span class="o">is</span> <span class="nx">@expressions</span> <span class="o">and</span> <span class="nx">@any</span> <span class="p">(</span><span class="nx">k</span><span class="p">,</span> <span class="nx">val</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nx">val</span> <span class="o">is</span> <span class="s1">&#39;var&#39;</span> <span class="o">or</span> <span class="nx">val</span> <span class="o">is</span> <span class="s1">&#39;reuse&#39;</span></pre></div> </td> </tr> <tr id="section-15"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-15">#</a> </div> <p>Does this scope reference any assignments that need to be declared at the
top of the given function body?</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">hasAssignments</span><span class="o">:</span> <span class="p">(</span><span class="nx">body</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nx">body</span> <span class="o">is</span> <span class="nx">@expressions</span> <span class="o">and</span> <span class="nx">@any</span> <span class="p">(</span><span class="nx">k</span><span class="p">,</span> <span class="nx">val</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nx">val</span><span class="p">.</span><span class="nx">assigned</span></pre></div> </td> </tr> <tr id="section-13"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-13">#</a> </div> <p>Return the list of variables first declared in this scope.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">declaredVariables</span><span class="o">:</span> <span class="o">-&gt;</span>
<span class="p">(</span><span class="nx">key</span> <span class="k">for</span> <span class="nx">key</span><span class="p">,</span> <span class="nx">val</span> <span class="k">of</span> <span class="nx">@variables</span> <span class="k">when</span> <span class="nx">val</span> <span class="o">is</span> <span class="s1">&#39;var&#39;</span><span class="p">).</span><span class="nx">sort</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>Return the list of assignments that are supposed to be made at the top
<span class="nx">body</span> <span class="o">is</span> <span class="nx">@expressions</span> <span class="o">and</span> <span class="nx">@any</span> <span class="p">(</span><span class="nx">k</span><span class="p">,</span> <span class="nx">val</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nx">val</span><span class="p">.</span><span class="nx">assigned</span></pre></div> </td> </tr> <tr id="section-16"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-16">#</a> </div> <p>Return the list of variables first declared in this scope.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">declaredVariables</span><span class="o">:</span> <span class="o">-&gt;</span>
<span class="p">(</span><span class="nx">key</span> <span class="k">for</span> <span class="nx">key</span><span class="p">,</span> <span class="nx">val</span> <span class="k">of</span> <span class="nx">@variables</span> <span class="k">when</span> <span class="nx">val</span> <span class="o">is</span> <span class="s1">&#39;var&#39;</span> <span class="o">or</span> <span class="nx">val</span> <span class="o">is</span> <span class="s1">&#39;reuse&#39;</span><span class="p">).</span><span class="nx">sort</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>Return the list of assignments that are supposed to be made at the top
of this scope.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">assignedVariables</span><span class="o">:</span> <span class="o">-&gt;</span>
<span class="s2">&quot;#{key} = #{val.value}&quot;</span> <span class="k">for</span> <span class="nx">key</span><span class="p">,</span> <span class="nx">val</span> <span class="k">of</span> <span class="nx">@variables</span> <span class="k">when</span> <span class="nx">val</span><span class="p">.</span><span class="nx">assigned</span></pre></div> </td> </tr> <tr id="section-15"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-15">#</a> </div> <p>Compile the JavaScript for all of the variable declarations in this scope.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">compiledDeclarations</span><span class="o">:</span> <span class="o">-&gt;</span>
<span class="nx">@declaredVariables</span><span class="p">().</span><span class="nx">join</span> <span class="s1">&#39;, &#39;</span></pre></div> </td> </tr> <tr id="section-16"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-16">#</a> </div> <p>Compile the JavaScript for all of the variable assignments in this scope.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">compiledAssignments</span><span class="o">:</span> <span class="o">-&gt;</span>
<span class="s2">&quot;#{key} = #{val.value}&quot;</span> <span class="k">for</span> <span class="nx">key</span><span class="p">,</span> <span class="nx">val</span> <span class="k">of</span> <span class="nx">@variables</span> <span class="k">when</span> <span class="nx">val</span><span class="p">.</span><span class="nx">assigned</span></pre></div> </td> </tr> <tr id="section-18"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-18">#</a> </div> <p>Compile the JavaScript for all of the variable declarations in this scope.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">compiledDeclarations</span><span class="o">:</span> <span class="o">-&gt;</span>
<span class="nx">@declaredVariables</span><span class="p">().</span><span class="nx">join</span> <span class="s1">&#39;, &#39;</span></pre></div> </td> </tr> <tr id="section-19"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-19">#</a> </div> <p>Compile the JavaScript forall of the variable assignments in this scope.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">compiledAssignments</span><span class="o">:</span> <span class="o">-&gt;</span>
<span class="nx">@assignedVariables</span><span class="p">().</span><span class="nx">join</span> <span class="s1">&#39;, &#39;</span>
</pre></div> </td> </tr> </tbody> </table> </div> </body> </html>

View File

@@ -71,10 +71,7 @@
</div>
<div class="contents repl_wrapper">
<div class="code">
<div id="repl_source_wrap"><textarea id="repl_source">reverse = (string) ->
string.split('').reverse().join ''
alert reverse '.eeffoC yrT'</textarea></div>
<div id="repl_source_wrap"><textarea id="repl_source">alert "Hello CoffeeScript!"</textarea></div>
<pre id="repl_results"></pre>
<button class="full_screen">go full screen</button>
<button class="minimize">minimize</button>
@@ -127,7 +124,7 @@ alert reverse '.eeffoC yrT'</textarea></div>
<p>
<b>Latest Version:</b>
<a href="http://github.com/jashkenas/coffee-script/tarball/0.9.3">0.9.3</a>
<a href="http://github.com/jashkenas/coffee-script/tarball/0.9.4">0.9.4</a>
</p>
<h2>
@@ -172,7 +169,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.9.3">0.9.3</a>.
release: <a href="http://github.com/jashkenas/coffee-script/tarball/0.9.4">0.9.4</a>.
To install the CoffeeScript compiler system-wide
under <tt>/usr/local</tt>, open the directory and run:
</p>
@@ -809,6 +806,11 @@ coffee --print app/scripts/*.coffee > concatenation.js</pre>
the Node.js API to rebuild CoffeeScript's parser:
</p>
<%= code_for('cake_tasks') %>
<p>
If you need to invoke one task before another &mdash; for example, running
<tt>build</tt> before <tt>test</tt>, you can use the <tt>invoke</tt> function:
<tt>invoke 'build'</tt>
</p>
<h2>
<span id="scripts" class="bookmark"></span>
@@ -923,6 +925,11 @@ coffee --print app/scripts/*.coffee > concatenation.js</pre>
&mdash; a CoffeeScript compiler plug-in that allows you to include external
source files.
</li>
<li>
<b>mauricemach</b>'s <a href="http://github.com/mauricemach/coffeekup">CoffeeKup</a>
&mdash; Markup as CoffeeScript. After _why's
<a href="http://markaby.github.com/">Markaby</a>.
</li>
<li>
<b>jashkenas</b>'s <a href="http://jashkenas.github.com/docco/">Docco</a>
&mdash; a quick-and-dirty literate-programming-style documentation generator
@@ -950,6 +957,15 @@ coffee --print app/scripts/*.coffee > concatenation.js</pre>
Change Log
</h2>
<p>
<b class="header" style="margin-top: 20px;">0.9.4</b>
CoffeeScript now uses appropriately-named temporary variables, and recycles
their references after use. Added <tt>require.extensions</tt> support for
<b>Node.js 0.3</b>. Loading CoffeeScript in the browser now adds just a
single <tt>CoffeeScript</tt> object to global scope.
Fixes for implicit object and block comment edge cases.
</p>
<p>
<b class="header" style="margin-top: 20px;">0.9.3</b>
CoffeeScript <tt>switch</tt> statements now compile into JS <tt>switch</tt>

View File

@@ -1,18 +1,18 @@
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, food, lunch, roid, roid2;
var _i, _j, _len, _len2, _ref, _ref2, _result, food, lunch, roid, roid2;
lunch = (function() {
_a = []; _c = ['toast', 'cheese', 'wine'];
for (_b = 0, _d = _c.length; _b < _d; _b++) {
food = _c[_b];
_a.push(eat(food));
_result = []; _ref = ['toast', 'cheese', 'wine'];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
food = _ref[_i];
_result.push(eat(food));
}
return _a;
return _result;
})();
_f = asteroids;
for (_e = 0, _g = _f.length; _e < _g; _e++) {
roid = _f[_e];
_i = asteroids;
for (_h = 0, _j = _i.length; _h < _j; _h++) {
roid2 = _i[_h];
_ref = asteroids;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
roid = _ref[_i];
_ref2 = asteroids;
for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) {
roid2 = _ref2[_j];
if (roid !== roid2) {
if (roid.overlaps(roid2)) {
roid.explode();

View File

@@ -1,3 +1,4 @@
/*CoffeeScript Compiler v0.9.3
/*
CoffeeScript Compiler v0.9.4
Released under the MIT License
*/

View File

@@ -7,8 +7,8 @@ var __extends = function(child, parent) {
if (typeof parent.extended === "function") parent.extended(child);
child.__super__ = parent.prototype;
};
Animal = function(_a) {
this.name = _a;
Animal = function(_arg) {
this.name = _arg;
return this;
};
Animal.prototype.move = function(meters) {

View File

@@ -1,11 +1,11 @@
var _a, _b, _c, globals, name;
var _i, _ref, _result, globals, name;
var __hasProp = Object.prototype.hasOwnProperty;
globals = (function() {
_b = []; _c = window;
for (name in _c) {
if (!__hasProp.call(_c, name)) continue;
_a = _c[name];
_b.push(name);
_result = []; _ref = window;
for (name in _ref) {
if (!__hasProp.call(_ref, name)) continue;
_i = _ref[name];
_result.push(name);
}
return _b;
return _result;
})().slice(0, 10);

View File

@@ -1,8 +1,8 @@
var _a, city, forecast, temp, weatherReport;
var _ref, city, forecast, temp, weatherReport;
weatherReport = function(location) {
return [location, 72, "Mostly Sunny"];
};
_a = weatherReport("Berkeley, CA");
city = _a[0];
temp = _a[1];
forecast = _a[2];
_ref = weatherReport("Berkeley, CA");
city = _ref[0];
temp = _ref[1];
forecast = _ref[2];

View File

@@ -1,4 +1,4 @@
var _a, _b, age, ages, child, yearsOld;
var _ref, _result, age, ages, child, yearsOld;
var __hasProp = Object.prototype.hasOwnProperty;
yearsOld = {
max: 10,
@@ -6,11 +6,11 @@ yearsOld = {
tim: 11
};
ages = (function() {
_a = []; _b = yearsOld;
for (child in _b) {
if (!__hasProp.call(_b, child)) continue;
age = _b[child];
_a.push(child + " is " + age);
_result = []; _ref = yearsOld;
for (child in _ref) {
if (!__hasProp.call(_ref, child)) continue;
age = _ref[child];
_result.push(child + " is " + age);
}
return _a;
return _result;
})();

View File

@@ -1,4 +1,4 @@
var _a, _b, _c, city, futurists, name, street;
var _ref, _ref2, _ref3, city, futurists, name, street;
futurists = {
sculptor: "Umberto Boccioni",
painter: "Vladimir Burliuk",
@@ -7,9 +7,9 @@ futurists = {
address: ["Via Roma 42R", "Bellagio, Italy 22021"]
}
};
_a = futurists;
_b = _a.poet;
name = _b.name;
_c = _b.address;
street = _c[0];
city = _c[1];
_ref = futurists;
_ref2 = _ref.poet;
name = _ref2.name;
_ref3 = _ref2.address;
street = _ref3[0];
city = _ref3[1];

View File

@@ -1,4 +1,4 @@
var _a, _b, _c, _d, cubes, list, math, num, number, opposite, race, square;
var _i, _len, _ref, _result, cubes, list, math, num, number, opposite, race, square;
var __slice = Array.prototype.slice;
number = 42;
opposite = true;
@@ -25,10 +25,10 @@ if (typeof elvis !== "undefined" && elvis !== null) {
alert("I knew it!");
}
cubes = (function() {
_a = []; _c = list;
for (_b = 0, _d = _c.length; _b < _d; _b++) {
num = _c[_b];
_a.push(math.cube(num));
_result = []; _ref = list;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
num = _ref[_i];
_result.push(math.cube(num));
}
return _a;
return _result;
})();

View File

@@ -1,6 +1,6 @@
var _a, theBait, theSwitch;
var _ref, theBait, theSwitch;
theBait = 1000;
theSwitch = 0;
_a = [theSwitch, theBait];
theBait = _a[0];
theSwitch = _a[1];
_ref = [theSwitch, theBait];
theBait = _ref[0];
theSwitch = _ref[1];

View File

@@ -1,7 +1,7 @@
var _a, close, contents, open, tag;
var _ref, close, contents, open, tag;
var __slice = Array.prototype.slice;
tag = "<impossible>";
_a = tag.split("");
open = _a[0];
contents = __slice.call(_a, 1, _a.length - 1);
close = _a[_a.length - 1];
_ref = tag.split("");
open = _ref[0];
contents = __slice.call(_ref, 1, _ref.length - 1);
close = _ref[_ref.length - 1];

View File

@@ -1,19 +1,19 @@
var _a, countdown, deliverEggs, num;
var _result, countdown, deliverEggs, num;
countdown = (function() {
_a = [];
_result = [];
for (num = 10; num >= 1; num--) {
_a.push(num);
_result.push(num);
}
return _a;
return _result;
})();
deliverEggs = function() {
var _b, _c, dozen, i;
_b = []; _c = eggs.length;
for (i = 0; (0 <= _c ? i < _c : i > _c); i += 12) {
_b.push((function() {
var _ref, _result2, dozen, i;
_result2 = []; _ref = eggs.length;
for (i = 0; (0 <= _ref ? i < _ref : i > _ref); i += 12) {
_result2.push((function() {
dozen = eggs.slice(i, i + 12);
return deliver(new eggCarton(dozen));
})());
}
return _b;
return _result2;
};

View File

@@ -1,2 +1,2 @@
var _a, _b;
(typeof (_b = ((_a = lottery.drawWinner()))) === "undefined" || _b === null) ? undefined : _b.address == null ? undefined : _b.address.zipcode;
var _ref, _ref2;
(typeof (_ref2 = ((_ref = lottery.drawWinner()))) === "undefined" || _ref2 === null) ? undefined : _ref2.address == null ? undefined : _ref2.address.zipcode;

View File

@@ -1,23 +1,23 @@
switch (day) {
case "Mon":
go(work);
break;
case "Tue":
go(relax);
break;
case "Thu":
go(iceFishing);
break;
case "Fri":
case "Sat":
if (day === bingoDay) {
go(bingo);
go(dancing);
}
break;
case "Sun":
go(church);
break;
default:
go(work);
case "Mon":
go(work);
break;
case "Tue":
go(relax);
break;
case "Thu":
go(iceFishing);
break;
case "Fri":
case "Sat":
if (day === bingoDay) {
go(bingo);
go(dancing);
}
break;
case "Sun":
go(church);
break;
default:
go(work);
}

View File

@@ -1,4 +1,4 @@
var _a, lyrics, num;
var _result, lyrics, num;
if (this.studyingEconomics) {
while (supply > demand) {
buy();
@@ -9,10 +9,10 @@ if (this.studyingEconomics) {
}
num = 6;
lyrics = (function() {
_a = [];
_result = [];
while (num -= 1) {
_a.push(num + " little monkeys, jumping on the bed.\
_result.push(num + " little monkeys, jumping on the bed.\
One fell out and bumped his head.");
}
return _a;
return _result;
})();

File diff suppressed because one or more lines are too long

View File

@@ -31,7 +31,7 @@
+useless_assign # useless assignment
+ambiguous_nested_stmt # block statements containing block statements should use curly braces to resolve ambiguity
+ambiguous_else_stmt # the else statement could be matched with one of multiple if statements (use curly braces to indicate intent)
+missing_default_case # missing default case in switch statement
-missing_default_case # missing default case in switch statement
+duplicate_case_in_switch # duplicate case in switch statements
+default_not_at_end # the default case is not at the end of the switch statement
+legacy_cc_not_understood # couldn't understand control comment using /*@keyword@*/ syntax

View File

@@ -58,10 +58,7 @@
</div>
<div class="contents repl_wrapper">
<div class="code">
<div id="repl_source_wrap"><textarea id="repl_source">reverse = (string) ->
string.split('').reverse().join ''
alert reverse '.eeffoC yrT'</textarea></div>
<div id="repl_source_wrap"><textarea id="repl_source">alert "Hello CoffeeScript!"</textarea></div>
<pre id="repl_results"></pre>
<button class="full_screen">go full screen</button>
<button class="minimize">minimize</button>
@@ -114,7 +111,7 @@ alert reverse '.eeffoC yrT'</textarea></div>
<p>
<b>Latest Version:</b>
<a href="http://github.com/jashkenas/coffee-script/tarball/0.9.3">0.9.3</a>
<a href="http://github.com/jashkenas/coffee-script/tarball/0.9.4">0.9.4</a>
</p>
<h2>
@@ -139,8 +136,8 @@ list <span class="Keyword">=</span> [<span class="Number">1</span>, <span class=
<span class="Comment"><span class="Comment">#</span> Objects:</span>
math <span class="Keyword">=</span>
root<span class="Keyword">:</span> Math.sqrt
square<span class="Keyword">:</span> square
root: Math.sqrt
square: square
<span class="FunctionName">cube</span><span class="Keyword">:</span> <span class="FunctionArgument">(</span><span class="FunctionArgument">x</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span> x <span class="Keyword">*</span> square x
<span class="Comment"><span class="Comment">#</span> Splats:</span>
@@ -152,7 +149,7 @@ alert <span class="String"><span class="String">&quot;</span>I knew it!<span cla
<span class="Comment"><span class="Comment">#</span> Array comprehensions:</span>
cubes <span class="Keyword">=</span> math.cube num <span class="Keyword">for</span> num <span class="Keyword">in</span> list
</pre><pre class="idle"><span class="Storage">var</span> _a, _b, _c, _d, cubes, list, math, num, number, opposite, race, square;
</pre><pre class="idle"><span class="Storage">var</span> _i, _len, _ref, _result, cubes, list, math, num, number, opposite, race, square;
<span class="Storage">var</span> __slice <span class="Keyword">=</span> <span class="LibraryClassType">Array</span>.<span class="LibraryConstant">prototype</span>.slice;
number <span class="Keyword">=</span> <span class="Number">42</span>;
opposite <span class="Keyword">=</span> <span class="BuiltInConstant">true</span>;
@@ -179,14 +176,14 @@ math <span class="Keyword">=</span> {
<span class="LibraryFunction">alert</span>(<span class="String"><span class="String">&quot;</span>I knew it!<span class="String">&quot;</span></span>);
}
cubes <span class="Keyword">=</span> (<span class="Storage">function</span>() {
_a <span class="Keyword">=</span> []; _c <span class="Keyword">=</span> list;
<span class="Keyword">for</span> (_b <span class="Keyword">=</span> <span class="Number">0</span>, _d <span class="Keyword">=</span> _c.<span class="LibraryConstant">length</span>; _b <span class="Keyword">&lt;</span> _d; _b<span class="Keyword">++</span>) {
num <span class="Keyword">=</span> _c[_b];
_a.<span class="LibraryFunction">push</span>(math.cube(num));
_result <span class="Keyword">=</span> []; _ref <span class="Keyword">=</span> list;
<span class="Keyword">for</span> (_i <span class="Keyword">=</span> <span class="Number">0</span>, _len <span class="Keyword">=</span> _ref.<span class="LibraryConstant">length</span>; _i <span class="Keyword">&lt;</span> _len; _i<span class="Keyword">++</span>) {
num <span class="Keyword">=</span> _ref[_i];
_result.<span class="LibraryFunction">push</span>(math.cube(num));
}
<span class="Keyword">return</span> _a;
<span class="Keyword">return</span> _result;
})();
</pre><button onclick='javascript: var _a, _b, _c, _d, cubes, list, math, num, number, opposite, race, square;
</pre><button onclick='javascript: var _i, _len, _ref, _result, cubes, list, math, num, number, opposite, race, square;
var __slice = Array.prototype.slice;
number = 42;
opposite = true;
@@ -213,12 +210,12 @@ if (typeof elvis !== "undefined" && elvis !== null) {
alert("I knew it!");
}
cubes = (function() {
_a = []; _c = list;
for (_b = 0, _d = _c.length; _b < _d; _b++) {
num = _c[_b];
_a.push(math.cube(num));
_result = []; _ref = list;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
num = _ref[_i];
_result.push(math.cube(num));
}
return _a;
return _result;
})();;alert(cubes);'>run: cubes</button><br class='clear' /></div>
<p>
@@ -254,7 +251,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.9.3">0.9.3</a>.
release: <a href="http://github.com/jashkenas/coffee-script/tarball/0.9.4">0.9.4</a>.
To install the CoffeeScript compiler system-wide
under <tt>/usr/local</tt>, open the directory and run:
</p>
@@ -470,7 +467,7 @@ cube = function(x) {
</p>
<div class='code'><pre class="idle">song <span class="Keyword">=</span> [<span class="String"><span class="String">&quot;</span>do<span class="String">&quot;</span></span>, <span class="String"><span class="String">&quot;</span>re<span class="String">&quot;</span></span>, <span class="String"><span class="String">&quot;</span>mi<span class="String">&quot;</span></span>, <span class="String"><span class="String">&quot;</span>fa<span class="String">&quot;</span></span>, <span class="String"><span class="String">&quot;</span>so<span class="String">&quot;</span></span>]
singers <span class="Keyword">=</span> {Jagger<span class="Keyword">:</span> <span class="String"><span class="String">&quot;</span>Rock<span class="String">&quot;</span></span>, Elvis<span class="Keyword">:</span> <span class="String"><span class="String">&quot;</span>Roll<span class="String">&quot;</span></span>}
singers <span class="Keyword">=</span> {Jagger: <span class="String"><span class="String">&quot;</span>Rock<span class="String">&quot;</span></span>, Elvis: <span class="String"><span class="String">&quot;</span>Roll<span class="String">&quot;</span></span>}
matrix <span class="Keyword">=</span> [
<span class="Number">1</span>, <span class="Number">0</span>, <span class="Number">1</span>
@@ -479,12 +476,12 @@ matrix <span class="Keyword">=</span> [
]
kids <span class="Keyword">=</span>
brother<span class="Keyword">:</span>
name<span class="Keyword">:</span> <span class="String"><span class="String">&quot;</span>Max<span class="String">&quot;</span></span>
age<span class="Keyword">:</span> <span class="Number">11</span>
sister<span class="Keyword">:</span>
name<span class="Keyword">:</span> <span class="String"><span class="String">&quot;</span>Ida<span class="String">&quot;</span></span>
age<span class="Keyword">:</span> <span class="Number">9</span>
brother:
name: <span class="String"><span class="String">&quot;</span>Max<span class="String">&quot;</span></span>
age: <span class="Number">11</span>
sister:
name: <span class="String"><span class="String">&quot;</span>Ida<span class="String">&quot;</span></span>
age: <span class="Number">9</span>
</pre><pre class="idle"><span class="Storage">var</span> kids, matrix, singers, song;
song <span class="Keyword">=</span> [<span class="String"><span class="String">&quot;</span>do<span class="String">&quot;</span></span>, <span class="String"><span class="String">&quot;</span>re<span class="String">&quot;</span></span>, <span class="String"><span class="String">&quot;</span>mi<span class="String">&quot;</span></span>, <span class="String"><span class="String">&quot;</span>fa<span class="String">&quot;</span></span>, <span class="String"><span class="String">&quot;</span>so<span class="String">&quot;</span></span>];
singers <span class="Keyword">=</span> {
@@ -524,7 +521,7 @@ kids = {
of an object, without quoting them as strings. CoffeeScript notices and quotes
them for you, so you don't have to worry about it (say, when using jQuery).
</p>
<div class='code'><pre class="idle">$(<span class="String"><span class="String">'</span>.account<span class="String">'</span></span>).css class<span class="Keyword">:</span> <span class="String"><span class="String">'</span>active<span class="String">'</span></span>
<div class='code'><pre class="idle">$(<span class="String"><span class="String">'</span>.account<span class="String">'</span></span>).css class: <span class="String"><span class="String">'</span>active<span class="String">'</span></span>
</pre><pre class="idle"><span class="Keyword">$</span>(<span class="String"><span class="String">'</span>.account<span class="String">'</span></span>).css({
<span class="String"><span class="String">&quot;</span>class<span class="String">&quot;</span></span>: <span class="String"><span class="String">'</span>active<span class="String">'</span></span>
});
@@ -612,7 +609,7 @@ inner = changeNumbers();;alert(inner);'>run: inner</button><br class='clear' /><
date <span class="Keyword">=</span> <span class="Keyword">if</span> friday <span class="Keyword">then</span> sue <span class="Keyword">else</span> jill
options <span class="Keyword">or=</span> defaults
options or<span class="Keyword">=</span> defaults
</pre><pre class="idle"><span class="Storage">var</span> date, mood, options;
<span class="Keyword">if</span> (singing) {
mood <span class="Keyword">=</span> greatlyImproved;
@@ -775,7 +772,7 @@ num <span class="Keyword">=</span> <span class="Number">6</span>
lyrics <span class="Keyword">=</span> <span class="Keyword">while</span> num <span class="Keyword">-</span><span class="Keyword">=</span> <span class="Number">1</span>
num <span class="Keyword">+</span> <span class="String"><span class="String">&quot;</span> little monkeys, jumping on the bed.</span>
<span class="String"> One fell out and bumped his head.<span class="String">&quot;</span></span>
</pre><pre class="idle"><span class="Storage">var</span> _a, lyrics, num;
</pre><pre class="idle"><span class="Storage">var</span> _result, lyrics, num;
<span class="Keyword">if</span> (<span class="Variable">this</span>.studyingEconomics) {
<span class="Keyword">while</span> (supply <span class="Keyword">&gt;</span> demand) {
buy();
@@ -786,14 +783,14 @@ lyrics <span class="Keyword">=</span> <span class="Keyword">while</span> num <sp
}
num <span class="Keyword">=</span> <span class="Number">6</span>;
lyrics <span class="Keyword">=</span> (<span class="Storage">function</span>() {
_a <span class="Keyword">=</span> [];
_result <span class="Keyword">=</span> [];
<span class="Keyword">while</span> (num <span class="Keyword">-</span><span class="Keyword">=</span> <span class="Number">1</span>) {
_a.<span class="LibraryFunction">push</span>(num <span class="Keyword">+</span> <span class="String"><span class="String">&quot;</span> little monkeys, jumping on the bed.\</span>
_result.<span class="LibraryFunction">push</span>(num <span class="Keyword">+</span> <span class="String"><span class="String">&quot;</span> little monkeys, jumping on the bed.\</span>
<span class="String"> One fell out and bumped his head.<span class="String">&quot;</span></span>);
}
<span class="Keyword">return</span> _a;
<span class="Keyword">return</span> _result;
})();
</pre><button onclick='javascript: var _a, lyrics, num;
</pre><button onclick='javascript: var _result, lyrics, num;
if (this.studyingEconomics) {
while (supply > demand) {
buy();
@@ -804,12 +801,12 @@ if (this.studyingEconomics) {
}
num = 6;
lyrics = (function() {
_a = [];
_result = [];
while (num -= 1) {
_a.push(num + " little monkeys, jumping on the bed.\
_result.push(num + " little monkeys, jumping on the bed.\
One fell out and bumped his head.");
}
return _a;
return _result;
})();;alert(lyrics.join("\n"));'>run: lyrics.join("\n")</button><br class='clear' /></div>
<p>
For readability, the <b>until</b> keyword is equivalent to <tt>while not</tt>,
@@ -837,21 +834,21 @@ lunch <span class="Keyword">=</span> eat food <span class="Keyword">for</span> f
<span class="Keyword">for</span> roid <span class="Keyword">in</span> asteroids
<span class="Keyword">for</span> roid2 <span class="Keyword">in</span> asteroids <span class="Keyword">when</span> roid <span class="Keyword">isnt</span> roid2
roid.explode() <span class="Keyword">if</span> roid.overlaps roid2
</pre><pre class="idle"><span class="Storage">var</span> _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, food, lunch, roid, roid2;
</pre><pre class="idle"><span class="Storage">var</span> _i, _j, _len, _len2, _ref, _ref2, _result, food, lunch, roid, roid2;
lunch <span class="Keyword">=</span> (<span class="Storage">function</span>() {
_a <span class="Keyword">=</span> []; _c <span class="Keyword">=</span> [<span class="String"><span class="String">'</span>toast<span class="String">'</span></span>, <span class="String"><span class="String">'</span>cheese<span class="String">'</span></span>, <span class="String"><span class="String">'</span>wine<span class="String">'</span></span>];
<span class="Keyword">for</span> (_b <span class="Keyword">=</span> <span class="Number">0</span>, _d <span class="Keyword">=</span> _c.<span class="LibraryConstant">length</span>; _b <span class="Keyword">&lt;</span> _d; _b<span class="Keyword">++</span>) {
food <span class="Keyword">=</span> _c[_b];
_a.<span class="LibraryFunction">push</span>(eat(food));
_result <span class="Keyword">=</span> []; _ref <span class="Keyword">=</span> [<span class="String"><span class="String">'</span>toast<span class="String">'</span></span>, <span class="String"><span class="String">'</span>cheese<span class="String">'</span></span>, <span class="String"><span class="String">'</span>wine<span class="String">'</span></span>];
<span class="Keyword">for</span> (_i <span class="Keyword">=</span> <span class="Number">0</span>, _len <span class="Keyword">=</span> _ref.<span class="LibraryConstant">length</span>; _i <span class="Keyword">&lt;</span> _len; _i<span class="Keyword">++</span>) {
food <span class="Keyword">=</span> _ref[_i];
_result.<span class="LibraryFunction">push</span>(eat(food));
}
<span class="Keyword">return</span> _a;
<span class="Keyword">return</span> _result;
})();
_f <span class="Keyword">=</span> asteroids;
<span class="Keyword">for</span> (_e <span class="Keyword">=</span> <span class="Number">0</span>, _g <span class="Keyword">=</span> _f.<span class="LibraryConstant">length</span>; _e <span class="Keyword">&lt;</span> _g; _e<span class="Keyword">++</span>) {
roid <span class="Keyword">=</span> _f[_e];
_i <span class="Keyword">=</span> asteroids;
<span class="Keyword">for</span> (_h <span class="Keyword">=</span> <span class="Number">0</span>, _j <span class="Keyword">=</span> _i.<span class="LibraryConstant">length</span>; _h <span class="Keyword">&lt;</span> _j; _h<span class="Keyword">++</span>) {
roid2 <span class="Keyword">=</span> _i[_h];
_ref <span class="Keyword">=</span> asteroids;
<span class="Keyword">for</span> (_i <span class="Keyword">=</span> <span class="Number">0</span>, _len <span class="Keyword">=</span> _ref.<span class="LibraryConstant">length</span>; _i <span class="Keyword">&lt;</span> _len; _i<span class="Keyword">++</span>) {
roid <span class="Keyword">=</span> _ref[_i];
_ref2 <span class="Keyword">=</span> asteroids;
<span class="Keyword">for</span> (_j <span class="Keyword">=</span> <span class="Number">0</span>, _len2 <span class="Keyword">=</span> _ref2.<span class="LibraryConstant">length</span>; _j <span class="Keyword">&lt;</span> _len2; _j<span class="Keyword">++</span>) {
roid2 <span class="Keyword">=</span> _ref2[_j];
<span class="Keyword">if</span> (roid <span class="Keyword">!</span><span class="Keyword">==</span> roid2) {
<span class="Keyword">if</span> (roid.overlaps(roid2)) {
roid.explode();
@@ -871,54 +868,54 @@ _f <span class="Keyword">=</span> asteroids;
<span class="Keyword">for</span> i <span class="Keyword">in</span> [<span class="Number">0</span>...eggs.length] <span class="Keyword">by</span> <span class="Number">12</span>
dozen <span class="Keyword">=</span> eggs[i...i<span class="Keyword">+</span><span class="Number">12</span>]
deliver <span class="Keyword">new</span> <span class="TypeName">eggCarton</span> dozen
</pre><pre class="idle"><span class="Storage">var</span> _a, countdown, deliverEggs, num;
</pre><pre class="idle"><span class="Storage">var</span> _result, countdown, deliverEggs, num;
countdown <span class="Keyword">=</span> (<span class="Storage">function</span>() {
_a <span class="Keyword">=</span> [];
_result <span class="Keyword">=</span> [];
<span class="Keyword">for</span> (num <span class="Keyword">=</span> <span class="Number">10</span>; num <span class="Keyword">&gt;=</span> <span class="Number">1</span>; num<span class="Keyword">--</span>) {
_a.<span class="LibraryFunction">push</span>(num);
_result.<span class="LibraryFunction">push</span>(num);
}
<span class="Keyword">return</span> _a;
<span class="Keyword">return</span> _result;
})();
<span class="FunctionName">deliverEggs</span> = <span class="Storage">function</span>() {
<span class="Storage">var</span> _b, _c, dozen, i;
_b <span class="Keyword">=</span> []; _c <span class="Keyword">=</span> eggs.<span class="LibraryConstant">length</span>;
<span class="Keyword">for</span> (i <span class="Keyword">=</span> <span class="Number">0</span>; (<span class="Number">0</span> <span class="Keyword">&lt;=</span> _c ? i <span class="Keyword">&lt;</span> _c : i <span class="Keyword">&gt;</span> _c); i <span class="Keyword">+</span><span class="Keyword">=</span> <span class="Number">12</span>) {
_b.<span class="LibraryFunction">push</span>((<span class="Storage">function</span>() {
<span class="Storage">var</span> _ref, _result2, dozen, i;
_result2 <span class="Keyword">=</span> []; _ref <span class="Keyword">=</span> eggs.<span class="LibraryConstant">length</span>;
<span class="Keyword">for</span> (i <span class="Keyword">=</span> <span class="Number">0</span>; (<span class="Number">0</span> <span class="Keyword">&lt;=</span> _ref ? i <span class="Keyword">&lt;</span> _ref : i <span class="Keyword">&gt;</span> _ref); i <span class="Keyword">+</span><span class="Keyword">=</span> <span class="Number">12</span>) {
_result2.<span class="LibraryFunction">push</span>((<span class="Storage">function</span>() {
dozen <span class="Keyword">=</span> eggs.<span class="LibraryFunction">slice</span>(i, i <span class="Keyword">+</span> <span class="Number">12</span>);
<span class="Keyword">return</span> deliver(<span class="Keyword">new</span> <span class="TypeName">eggCarton</span>(dozen));
})());
}
<span class="Keyword">return</span> _b;
<span class="Keyword">return</span> _result2;
};
</pre><button onclick='javascript: var _a, countdown, deliverEggs, num;
</pre><button onclick='javascript: var _result, countdown, deliverEggs, num;
countdown = (function() {
_a = [];
_result = [];
for (num = 10; num >= 1; num--) {
_a.push(num);
_result.push(num);
}
return _a;
return _result;
})();
deliverEggs = function() {
var _b, _c, dozen, i;
_b = []; _c = eggs.length;
for (i = 0; (0 <= _c ? i < _c : i > _c); i += 12) {
_b.push((function() {
var _ref, _result2, dozen, i;
_result2 = []; _ref = eggs.length;
for (i = 0; (0 <= _ref ? i < _ref : i > _ref); i += 12) {
_result2.push((function() {
dozen = eggs.slice(i, i + 12);
return deliver(new eggCarton(dozen));
})());
}
return _b;
return _result2;
};;alert(countdown);'>run: countdown</button><br class='clear' /></div>
<p>
Comprehensions can also be used to iterate over the keys and values in
an object. Use <tt>of</tt> to signal comprehension over the properties of
an object instead of the values in an array.
</p>
<div class='code'><pre class="idle">yearsOld <span class="Keyword">=</span> max<span class="Keyword">:</span> <span class="Number">10</span>, ida<span class="Keyword">:</span> <span class="Number">9</span>, tim<span class="Keyword">:</span> <span class="Number">11</span>
<div class='code'><pre class="idle">yearsOld <span class="Keyword">=</span> max: <span class="Number">10</span>, ida: <span class="Number">9</span>, tim: <span class="Number">11</span>
ages <span class="Keyword">=</span> <span class="Keyword">for</span> child, age <span class="Keyword">of</span> yearsOld
child <span class="Keyword">+</span> <span class="String"><span class="String">&quot;</span> is <span class="String">&quot;</span></span> <span class="Keyword">+</span> age
</pre><pre class="idle"><span class="Storage">var</span> _a, _b, age, ages, child, yearsOld;
</pre><pre class="idle"><span class="Storage">var</span> _ref, _result, age, ages, child, yearsOld;
<span class="Storage">var</span> __hasProp <span class="Keyword">=</span> <span class="LibraryClassType">Object</span>.<span class="LibraryConstant">prototype</span>.hasOwnProperty;
yearsOld <span class="Keyword">=</span> {
max: <span class="Number">10</span>,
@@ -926,15 +923,15 @@ yearsOld <span class="Keyword">=</span> {
tim: <span class="Number">11</span>
};
ages <span class="Keyword">=</span> (<span class="Storage">function</span>() {
_a <span class="Keyword">=</span> []; _b <span class="Keyword">=</span> yearsOld;
<span class="Keyword">for</span> (child <span class="Keyword">in</span> _b) {
<span class="Keyword">if</span> (<span class="Keyword">!</span>__hasProp.<span class="LibraryFunction">call</span>(_b, child)) <span class="Keyword">continue</span>;
age <span class="Keyword">=</span> _b[child];
_a.<span class="LibraryFunction">push</span>(child <span class="Keyword">+</span> <span class="String"><span class="String">&quot;</span> is <span class="String">&quot;</span></span> <span class="Keyword">+</span> age);
_result <span class="Keyword">=</span> []; _ref <span class="Keyword">=</span> yearsOld;
<span class="Keyword">for</span> (child <span class="Keyword">in</span> _ref) {
<span class="Keyword">if</span> (<span class="Keyword">!</span>__hasProp.<span class="LibraryFunction">call</span>(_ref, child)) <span class="Keyword">continue</span>;
age <span class="Keyword">=</span> _ref[child];
_result.<span class="LibraryFunction">push</span>(child <span class="Keyword">+</span> <span class="String"><span class="String">&quot;</span> is <span class="String">&quot;</span></span> <span class="Keyword">+</span> age);
}
<span class="Keyword">return</span> _a;
<span class="Keyword">return</span> _result;
})();
</pre><button onclick='javascript: var _a, _b, age, ages, child, yearsOld;
</pre><button onclick='javascript: var _ref, _result, age, ages, child, yearsOld;
var __hasProp = Object.prototype.hasOwnProperty;
yearsOld = {
max: 10,
@@ -942,13 +939,13 @@ yearsOld = {
tim: 11
};
ages = (function() {
_a = []; _b = yearsOld;
for (child in _b) {
if (!__hasProp.call(_b, child)) continue;
age = _b[child];
_a.push(child + " is " + age);
_result = []; _ref = yearsOld;
for (child in _ref) {
if (!__hasProp.call(_ref, child)) continue;
age = _ref[child];
_result.push(child + " is " + age);
}
return _a;
return _result;
})();;alert(ages.join(", "));'>run: ages.join(", ")</button><br class='clear' /></div>
<p>
By default, object comprehensions are safe, and use a <tt>hasOwnProperty</tt>
@@ -1062,27 +1059,27 @@ six = (one = 1) + (two = 2) + (three = 3);;alert(six);'>run: six</button><br cla
<div class='code'><pre class="idle"><span class="Comment"><span class="Comment">#</span> The first ten global properties.</span>
globals <span class="Keyword">=</span> (name <span class="Keyword">for</span> name <span class="Keyword">of</span> window)[<span class="Number">0</span>...<span class="Number">10</span>]
</pre><pre class="idle"><span class="Storage">var</span> _a, _b, _c, globals, name;
</pre><pre class="idle"><span class="Storage">var</span> _i, _ref, _result, globals, name;
<span class="Storage">var</span> __hasProp <span class="Keyword">=</span> <span class="LibraryClassType">Object</span>.<span class="LibraryConstant">prototype</span>.hasOwnProperty;
globals <span class="Keyword">=</span> (<span class="Storage">function</span>() {
_b <span class="Keyword">=</span> []; _c <span class="Keyword">=</span> <span class="LibraryClassType">window</span>;
<span class="Keyword">for</span> (name <span class="Keyword">in</span> _c) {
<span class="Keyword">if</span> (<span class="Keyword">!</span>__hasProp.<span class="LibraryFunction">call</span>(_c, name)) <span class="Keyword">continue</span>;
_a <span class="Keyword">=</span> _c[name];
_b.<span class="LibraryFunction">push</span>(name);
_result <span class="Keyword">=</span> []; _ref <span class="Keyword">=</span> <span class="LibraryClassType">window</span>;
<span class="Keyword">for</span> (name <span class="Keyword">in</span> _ref) {
<span class="Keyword">if</span> (<span class="Keyword">!</span>__hasProp.<span class="LibraryFunction">call</span>(_ref, name)) <span class="Keyword">continue</span>;
_i <span class="Keyword">=</span> _ref[name];
_result.<span class="LibraryFunction">push</span>(name);
}
<span class="Keyword">return</span> _b;
<span class="Keyword">return</span> _result;
})().<span class="LibraryFunction">slice</span>(<span class="Number">0</span>, <span class="Number">10</span>);
</pre><button onclick='javascript: var _a, _b, _c, globals, name;
</pre><button onclick='javascript: var _i, _ref, _result, globals, name;
var __hasProp = Object.prototype.hasOwnProperty;
globals = (function() {
_b = []; _c = window;
for (name in _c) {
if (!__hasProp.call(_c, name)) continue;
_a = _c[name];
_b.push(name);
_result = []; _ref = window;
for (name in _ref) {
if (!__hasProp.call(_ref, name)) continue;
_i = _ref[name];
_result.push(name);
}
return _b;
return _result;
})().slice(0, 10);;alert(globals);'>run: globals</button><br class='clear' /></div>
<p>
As well as silly things, like passing a <b>try/catch</b> statement directly
@@ -1155,8 +1152,8 @@ speed = (typeof speed !== "undefined" && speed !== null) ? speed : 140;;alert(sp
the <b>TypeError</b> that would be raised otherwise.
</p>
<div class='code'><pre class="idle">lottery.drawWinner()<span class="Keyword">?</span>.address<span class="Keyword">?</span>.zipcode
</pre><pre class="idle"><span class="Storage">var</span> _a, _b;
(<span class="Keyword">typeof</span> (_b <span class="Keyword">=</span> ((_a <span class="Keyword">=</span> lottery.drawWinner()))) <span class="Keyword">===</span> <span class="String"><span class="String">&quot;</span>undefined<span class="String">&quot;</span></span> <span class="Keyword">||</span> _b <span class="Keyword">===</span> <span class="BuiltInConstant">null</span>) ? undefined : _b.address <span class="Keyword">==</span> <span class="BuiltInConstant">null</span> ? undefined : _b.address.zipcode;
</pre><pre class="idle"><span class="Storage">var</span> _ref, _ref2;
(<span class="Keyword">typeof</span> (_ref2 <span class="Keyword">=</span> ((_ref <span class="Keyword">=</span> lottery.drawWinner()))) <span class="Keyword">===</span> <span class="String"><span class="String">&quot;</span>undefined<span class="String">&quot;</span></span> <span class="Keyword">||</span> _ref2 <span class="Keyword">===</span> <span class="BuiltInConstant">null</span>) ? undefined : _ref2.address <span class="Keyword">==</span> <span class="BuiltInConstant">null</span> ? undefined : _ref2.address.zipcode;
</pre><br class='clear' /></div>
<p>
Soaking up nulls is similar to Ruby's
@@ -1220,8 +1217,8 @@ tom.move()
<span class="Keyword">if</span> (<span class="Keyword">typeof</span> parent.extended <span class="Keyword">===</span> <span class="String"><span class="String">&quot;</span>function<span class="String">&quot;</span></span>) parent.extended(child);
child.__super__ <span class="Keyword">=</span> parent.<span class="LibraryConstant">prototype</span>;
};
<span class="FunctionName">Animal</span> = <span class="Storage">function</span>(<span class="FunctionArgument">_a</span>) {
<span class="Variable">this</span>.<span class="LibraryConstant">name</span> <span class="Keyword">=</span> _a;
<span class="FunctionName">Animal</span> = <span class="Storage">function</span>(<span class="FunctionArgument">_arg</span>) {
<span class="Variable">this</span>.<span class="LibraryConstant">name</span> <span class="Keyword">=</span> _arg;
<span class="Keyword">return</span> <span class="Variable">this</span>;
};
<span class="LibraryClassType">Animal</span>.<span class="LibraryConstant">prototype</span>.<span class="FunctionName">move</span> = <span class="Storage">function</span>(<span class="FunctionArgument">meters</span>) {
@@ -1256,8 +1253,8 @@ var __extends = function(child, parent) {
if (typeof parent.extended === "function") parent.extended(child);
child.__super__ = parent.prototype;
};
Animal = function(_a) {
this.name = _a;
Animal = function(_arg) {
this.name = _arg;
return this;
};
Animal.prototype.move = function(meters) {
@@ -1318,18 +1315,18 @@ tom.move();;'>run</button><br class='clear' /></div>
theSwitch <span class="Keyword">=</span> <span class="Number">0</span>
<span class="Keyword">[</span>theBait, theSwitch<span class="Keyword">] =</span> [theSwitch, theBait]
</pre><pre class="idle"><span class="Storage">var</span> _a, theBait, theSwitch;
</pre><pre class="idle"><span class="Storage">var</span> _ref, theBait, theSwitch;
theBait <span class="Keyword">=</span> <span class="Number">1000</span>;
theSwitch <span class="Keyword">=</span> <span class="Number">0</span>;
_a <span class="Keyword">=</span> [theSwitch, theBait];
theBait <span class="Keyword">=</span> _a[<span class="Number">0</span>];
theSwitch <span class="Keyword">=</span> _a[<span class="Number">1</span>];
</pre><button onclick='javascript: var _a, theBait, theSwitch;
_ref <span class="Keyword">=</span> [theSwitch, theBait];
theBait <span class="Keyword">=</span> _ref[<span class="Number">0</span>];
theSwitch <span class="Keyword">=</span> _ref[<span class="Number">1</span>];
</pre><button onclick='javascript: var _ref, theBait, theSwitch;
theBait = 1000;
theSwitch = 0;
_a = [theSwitch, theBait];
theBait = _a[0];
theSwitch = _a[1];;alert(theBait);'>run: theBait</button><br class='clear' /></div>
_ref = [theSwitch, theBait];
theBait = _ref[0];
theSwitch = _ref[1];;alert(theBait);'>run: theBait</button><br class='clear' /></div>
<p>
But it's also helpful for dealing with functions that return multiple
values.
@@ -1339,38 +1336,38 @@ theSwitch = _a[1];;alert(theBait);'>run: theBait</button><br class='clear' /></d
[location, <span class="Number">72</span>, <span class="String"><span class="String">&quot;</span>Mostly Sunny<span class="String">&quot;</span></span>]
<span class="Keyword">[</span>city, temp, forecast<span class="Keyword">] =</span> weatherReport <span class="String"><span class="String">&quot;</span>Berkeley, CA<span class="String">&quot;</span></span>
</pre><pre class="idle"><span class="Storage">var</span> _a, city, forecast, temp, weatherReport;
</pre><pre class="idle"><span class="Storage">var</span> _ref, city, forecast, temp, weatherReport;
<span class="FunctionName">weatherReport</span> = <span class="Storage">function</span>(<span class="FunctionArgument">location</span>) {
<span class="Keyword">return</span> [location, <span class="Number">72</span>, <span class="String"><span class="String">&quot;</span>Mostly Sunny<span class="String">&quot;</span></span>];
};
_a <span class="Keyword">=</span> weatherReport(<span class="String"><span class="String">&quot;</span>Berkeley, CA<span class="String">&quot;</span></span>);
city <span class="Keyword">=</span> _a[<span class="Number">0</span>];
temp <span class="Keyword">=</span> _a[<span class="Number">1</span>];
forecast <span class="Keyword">=</span> _a[<span class="Number">2</span>];
</pre><button onclick='javascript: var _a, city, forecast, temp, weatherReport;
_ref <span class="Keyword">=</span> weatherReport(<span class="String"><span class="String">&quot;</span>Berkeley, CA<span class="String">&quot;</span></span>);
city <span class="Keyword">=</span> _ref[<span class="Number">0</span>];
temp <span class="Keyword">=</span> _ref[<span class="Number">1</span>];
forecast <span class="Keyword">=</span> _ref[<span class="Number">2</span>];
</pre><button onclick='javascript: var _ref, city, forecast, temp, weatherReport;
weatherReport = function(location) {
return [location, 72, "Mostly Sunny"];
};
_a = weatherReport("Berkeley, CA");
city = _a[0];
temp = _a[1];
forecast = _a[2];;alert(forecast);'>run: forecast</button><br class='clear' /></div>
_ref = weatherReport("Berkeley, CA");
city = _ref[0];
temp = _ref[1];
forecast = _ref[2];;alert(forecast);'>run: forecast</button><br class='clear' /></div>
<p>
Pattern matching can be used with any depth of array and object nesting,
to help pull out deeply nested properties.
</p>
<div class='code'><pre class="idle">futurists <span class="Keyword">=</span>
sculptor<span class="Keyword">:</span> <span class="String"><span class="String">&quot;</span>Umberto Boccioni<span class="String">&quot;</span></span>
painter<span class="Keyword">:</span> <span class="String"><span class="String">&quot;</span>Vladimir Burliuk<span class="String">&quot;</span></span>
poet<span class="Keyword">:</span>
name<span class="Keyword">:</span> <span class="String"><span class="String">&quot;</span>F.T. Marinetti<span class="String">&quot;</span></span>
address<span class="Keyword">:</span> [
sculptor: <span class="String"><span class="String">&quot;</span>Umberto Boccioni<span class="String">&quot;</span></span>
painter: <span class="String"><span class="String">&quot;</span>Vladimir Burliuk<span class="String">&quot;</span></span>
poet:
name: <span class="String"><span class="String">&quot;</span>F.T. Marinetti<span class="String">&quot;</span></span>
address: [
<span class="String"><span class="String">&quot;</span>Via Roma 42R<span class="String">&quot;</span></span>
<span class="String"><span class="String">&quot;</span>Bellagio, Italy 22021<span class="String">&quot;</span></span>
]
{poet<span class="Keyword">:</span> {name, address<span class="Keyword">:</span> [street, city]}} <span class="Keyword">=</span> futurists
</pre><pre class="idle"><span class="Storage">var</span> _a, _b, _c, city, futurists, name, street;
{poet: {name, address: [street, city]}} <span class="Keyword">=</span> futurists
</pre><pre class="idle"><span class="Storage">var</span> _ref, _ref2, _ref3, city, futurists, name, street;
futurists <span class="Keyword">=</span> {
sculptor: <span class="String"><span class="String">&quot;</span>Umberto Boccioni<span class="String">&quot;</span></span>,
painter: <span class="String"><span class="String">&quot;</span>Vladimir Burliuk<span class="String">&quot;</span></span>,
@@ -1379,13 +1376,13 @@ futurists <span class="Keyword">=</span> {
address: [<span class="String"><span class="String">&quot;</span>Via Roma 42R<span class="String">&quot;</span></span>, <span class="String"><span class="String">&quot;</span>Bellagio, Italy 22021<span class="String">&quot;</span></span>]
}
};
_a <span class="Keyword">=</span> futurists;
_b <span class="Keyword">=</span> _a.poet;
name <span class="Keyword">=</span> _b.<span class="LibraryConstant">name</span>;
_c <span class="Keyword">=</span> _b.address;
street <span class="Keyword">=</span> _c[<span class="Number">0</span>];
city <span class="Keyword">=</span> _c[<span class="Number">1</span>];
</pre><button onclick='javascript: var _a, _b, _c, city, futurists, name, street;
_ref <span class="Keyword">=</span> futurists;
_ref2 <span class="Keyword">=</span> _ref.poet;
name <span class="Keyword">=</span> _ref2.<span class="LibraryConstant">name</span>;
_ref3 <span class="Keyword">=</span> _ref2.address;
street <span class="Keyword">=</span> _ref3[<span class="Number">0</span>];
city <span class="Keyword">=</span> _ref3[<span class="Number">1</span>];
</pre><button onclick='javascript: var _ref, _ref2, _ref3, city, futurists, name, street;
futurists = {
sculptor: "Umberto Boccioni",
painter: "Vladimir Burliuk",
@@ -1394,12 +1391,12 @@ futurists = {
address: ["Via Roma 42R", "Bellagio, Italy 22021"]
}
};
_a = futurists;
_b = _a.poet;
name = _b.name;
_c = _b.address;
street = _c[0];
city = _c[1];;alert(name + " — " + street);'>run: name + " — " + street</button><br class='clear' /></div>
_ref = futurists;
_ref2 = _ref.poet;
name = _ref2.name;
_ref3 = _ref2.address;
street = _ref3[0];
city = _ref3[1];;alert(name + " — " + street);'>run: name + " — " + street</button><br class='clear' /></div>
<p>
Pattern matching can even be combined with splats.
</p>
@@ -1410,20 +1407,20 @@ city = _c[1];;alert(name + " — " + street);'>run: name + " — " + street</but
</pre><pre class="idle"><span class="Storage">var</span> _a, close, contents, open, tag;
</pre><pre class="idle"><span class="Storage">var</span> _ref, close, contents, open, tag;
<span class="Storage">var</span> __slice <span class="Keyword">=</span> <span class="LibraryClassType">Array</span>.<span class="LibraryConstant">prototype</span>.slice;
tag <span class="Keyword">=</span> <span class="String"><span class="String">&quot;</span>&lt;impossible&gt;<span class="String">&quot;</span></span>;
_a <span class="Keyword">=</span> tag.<span class="LibraryFunction">split</span>(<span class="String"><span class="String">&quot;</span><span class="String">&quot;</span></span>);
open <span class="Keyword">=</span> _a[<span class="Number">0</span>];
contents <span class="Keyword">=</span> __slice.<span class="LibraryFunction">call</span>(_a, <span class="Number">1</span>, _a.<span class="LibraryConstant">length</span> <span class="Keyword">-</span> <span class="Number">1</span>);
close <span class="Keyword">=</span> _a[_a.<span class="LibraryConstant">length</span> <span class="Keyword">-</span> <span class="Number">1</span>];
</pre><button onclick='javascript: var _a, close, contents, open, tag;
_ref <span class="Keyword">=</span> tag.<span class="LibraryFunction">split</span>(<span class="String"><span class="String">&quot;</span><span class="String">&quot;</span></span>);
open <span class="Keyword">=</span> _ref[<span class="Number">0</span>];
contents <span class="Keyword">=</span> __slice.<span class="LibraryFunction">call</span>(_ref, <span class="Number">1</span>, _ref.<span class="LibraryConstant">length</span> <span class="Keyword">-</span> <span class="Number">1</span>);
close <span class="Keyword">=</span> _ref[_ref.<span class="LibraryConstant">length</span> <span class="Keyword">-</span> <span class="Number">1</span>];
</pre><button onclick='javascript: var _ref, close, contents, open, tag;
var __slice = Array.prototype.slice;
tag = "<impossible>";
_a = tag.split("");
open = _a[0];
contents = __slice.call(_a, 1, _a.length - 1);
close = _a[_a.length - 1];;alert(contents.join(""));'>run: contents.join("")</button><br class='clear' /></div>
_ref = tag.split("");
open = _ref[0];
contents = __slice.call(_ref, 1, _ref.length - 1);
close = _ref[_ref.length - 1];;alert(contents.join(""));'>run: contents.join("")</button><br class='clear' /></div>
<p>
<span id="fat_arrow" class="bookmark"></span>
@@ -1514,27 +1511,27 @@ hi = function() {
<span class="Keyword">when</span> <span class="String"><span class="String">&quot;</span>Sun<span class="String">&quot;</span></span> <span class="Keyword">then</span> go church
<span class="Keyword">else</span> go work
</pre><pre class="idle"><span class="Keyword">switch</span> (day) {
<span class="Keyword">case</span> <span class="String"><span class="String">&quot;</span>Mon<span class="String">&quot;</span></span>:
<span class="LibraryFunction">go</span>(work);
<span class="Keyword">break</span>;
<span class="Keyword">case</span> <span class="String"><span class="String">&quot;</span>Tue<span class="String">&quot;</span></span>:
<span class="LibraryFunction">go</span>(relax);
<span class="Keyword">break</span>;
<span class="Keyword">case</span> <span class="String"><span class="String">&quot;</span>Thu<span class="String">&quot;</span></span>:
<span class="LibraryFunction">go</span>(iceFishing);
<span class="Keyword">break</span>;
<span class="Keyword">case</span> <span class="String"><span class="String">&quot;</span>Fri<span class="String">&quot;</span></span>:
<span class="Keyword">case</span> <span class="String"><span class="String">&quot;</span>Sat<span class="String">&quot;</span></span>:
<span class="Keyword">if</span> (day <span class="Keyword">===</span> bingoDay) {
<span class="LibraryFunction">go</span>(bingo);
<span class="LibraryFunction">go</span>(dancing);
}
<span class="Keyword">break</span>;
<span class="Keyword">case</span> <span class="String"><span class="String">&quot;</span>Sun<span class="String">&quot;</span></span>:
<span class="LibraryFunction">go</span>(church);
<span class="Keyword">break</span>;
<span class="Keyword">default</span>:
<span class="LibraryFunction">go</span>(work);
<span class="Keyword">case</span> <span class="String"><span class="String">&quot;</span>Mon<span class="String">&quot;</span></span>:
<span class="LibraryFunction">go</span>(work);
<span class="Keyword">break</span>;
<span class="Keyword">case</span> <span class="String"><span class="String">&quot;</span>Tue<span class="String">&quot;</span></span>:
<span class="LibraryFunction">go</span>(relax);
<span class="Keyword">break</span>;
<span class="Keyword">case</span> <span class="String"><span class="String">&quot;</span>Thu<span class="String">&quot;</span></span>:
<span class="LibraryFunction">go</span>(iceFishing);
<span class="Keyword">break</span>;
<span class="Keyword">case</span> <span class="String"><span class="String">&quot;</span>Fri<span class="String">&quot;</span></span>:
<span class="Keyword">case</span> <span class="String"><span class="String">&quot;</span>Sat<span class="String">&quot;</span></span>:
<span class="Keyword">if</span> (day <span class="Keyword">===</span> bingoDay) {
<span class="LibraryFunction">go</span>(bingo);
<span class="LibraryFunction">go</span>(dancing);
}
<span class="Keyword">break</span>;
<span class="Keyword">case</span> <span class="String"><span class="String">&quot;</span>Sun<span class="String">&quot;</span></span>:
<span class="LibraryFunction">go</span>(church);
<span class="Keyword">break</span>;
<span class="Keyword">default</span>:
<span class="LibraryFunction">go</span>(work);
}
</pre><br class='clear' /></div>
@@ -1665,10 +1662,11 @@ html <span class="Keyword">=</span> <span class="String"><span class="String">'<
are preserved in the generated code.
</p>
<div class='code'><pre class="idle"><span class="Comment"><span class="Comment">###</span></span>
<span class="Comment">CoffeeScript Compiler v0.9.3</span>
<span class="Comment">CoffeeScript Compiler v0.9.4</span>
<span class="Comment">Released under the MIT License</span>
<span class="Comment">###</span>
</pre><pre class="idle"><span class="Comment"><span class="Comment">/*</span>CoffeeScript Compiler v0.9.3</span>
</pre><pre class="idle"><span class="Comment"><span class="Comment">/*</span></span>
<span class="Comment">CoffeeScript Compiler v0.9.4</span>
<span class="Comment">Released under the MIT License</span>
<span class="Comment"><span class="Comment">*/</span></span>
</pre><br class='clear' /></div>
@@ -1716,6 +1714,11 @@ task(<span class="String"><span class="String">'</span>build:parser<span class="
<span class="Keyword">return</span> fs.writeFile(<span class="String"><span class="String">&quot;</span><span class="String">&quot;</span></span> <span class="Keyword">+</span> (dir) <span class="Keyword">+</span> <span class="String"><span class="String">&quot;</span>/parser.js<span class="String">&quot;</span></span>, code);
});
</pre><br class='clear' /></div>
<p>
If you need to invoke one task before another &mdash; for example, running
<tt>build</tt> before <tt>test</tt>, you can use the <tt>invoke</tt> function:
<tt>invoke 'build'</tt>
</p>
<h2>
<span id="scripts" class="bookmark"></span>
@@ -1830,6 +1833,11 @@ task(<span class="String"><span class="String">'</span>build:parser<span class="
&mdash; a CoffeeScript compiler plug-in that allows you to include external
source files.
</li>
<li>
<b>mauricemach</b>'s <a href="http://github.com/mauricemach/coffeekup">CoffeeKup</a>
&mdash; Markup as CoffeeScript. After _why's
<a href="http://markaby.github.com/">Markaby</a>.
</li>
<li>
<b>jashkenas</b>'s <a href="http://jashkenas.github.com/docco/">Docco</a>
&mdash; a quick-and-dirty literate-programming-style documentation generator
@@ -1857,6 +1865,15 @@ task(<span class="String"><span class="String">'</span>build:parser<span class="
Change Log
</h2>
<p>
<b class="header" style="margin-top: 20px;">0.9.4</b>
CoffeeScript now uses appropriately-named temporary variables, and recycles
their references after use. Added <tt>require.extensions</tt> support for
<b>Node.js 0.3</b>. Loading CoffeeScript in the browser now adds just a
single <tt>CoffeeScript</tt> object to global scope.
Fixes for implicit object and block comment edge cases.
</p>
<p>
<b class="header" style="margin-top: 20px;">0.9.3</b>
CoffeeScript <tt>switch</tt> statements now compile into JS <tt>switch</tt>

View File

@@ -1,42 +1,45 @@
(function() {
var grind, grindRemote, processScripts;
if ((typeof document === "undefined" || document === null) ? undefined : document.getElementsByTagName) {
grind = function(coffee) {
return setTimeout(exports.compile(coffee));
};
grindRemote = function(url) {
var xhr;
xhr = new (window.ActiveXObject || XMLHttpRequest)('Microsoft.XMLHTTP');
xhr.open('GET', url, true);
if ('overrideMimeType' in xhr) {
xhr.overrideMimeType('text/plain');
}
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
return grind(xhr.responseText);
}
};
return xhr.send(null);
};
processScripts = function() {
var _a, _b, _c, script;
_b = document.getElementsByTagName('script');
for (_a = 0, _c = _b.length; _a < _c; _a++) {
script = _b[_a];
if (script.type === 'text/coffeescript') {
if (script.src) {
grindRemote(script.src);
} else {
grind(script.innerHTML);
}
}
}
return null;
};
if (window.addEventListener) {
addEventListener('DOMContentLoaded', processScripts, false);
} else {
attachEvent('onload', processScripts);
}
var CoffeeScript, processScripts;
CoffeeScript = require('./coffee-script');
CoffeeScript.eval = function(code, options) {
return eval(CoffeeScript.compile(code, options));
};
CoffeeScript.run = function(code, options) {
return (Function(CoffeeScript.compile(code, options)))();
};
if (!(typeof window !== "undefined" && window !== null)) {
return null;
}
})();
CoffeeScript.load = function(url, options) {
var xhr;
xhr = new (window.ActiveXObject || XMLHttpRequest)('Microsoft.XMLHTTP');
xhr.open('GET', url, true);
if ('overrideMimeType' in xhr) {
xhr.overrideMimeType('text/plain');
}
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
return CoffeeScript.run(xhr.responseText, options);
}
};
return xhr.send(null);
};
processScripts = function() {
var _i, _len, _ref;
_ref = document.getElementsByTagName('script');
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
(function() {
var script = _ref[_i];
return script.type === 'text/coffeescript' ? (script.src ? CoffeeScript.load(script.src) : setTimeout(function() {
return CoffeeScript.run(script.innerHTML);
})) : null;
})();
}
return null;
};
if (window.addEventListener) {
addEventListener('DOMContentLoaded', processScripts, false);
} else {
attachEvent('onload', processScripts);
}
}).call(this);

View File

@@ -11,11 +11,11 @@
oparse = null;
helpers.extend(global, {
task: function(name, description, action) {
var _a;
var _ref;
if (!(action)) {
_a = [description, action];
action = _a[0];
description = _a[1];
_ref = [description, action];
action = _ref[0];
description = _ref[1];
}
return (tasks[name] = {
name: name,
@@ -35,7 +35,7 @@
});
exports.run = function() {
return path.exists('Cakefile', function(exists) {
var _a, _b, _c, _d, arg, args;
var _i, _len, _ref, _result, arg, args;
if (!(exists)) {
throw new Error("Cakefile not found in " + (process.cwd()));
}
@@ -48,28 +48,22 @@
return printTasks();
}
options = oparse.parse(args);
_a = []; _c = options.arguments;
for (_b = 0, _d = _c.length; _b < _d; _b++) {
arg = _c[_b];
_a.push(invoke(arg));
_result = []; _ref = options.arguments;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
arg = _ref[_i];
_result.push(invoke(arg));
}
return _a;
return _result;
});
};
printTasks = function() {
var _a, _b, desc, i, name, spaces, task;
var _ref, desc, name, spaces, task;
puts('');
_a = tasks;
for (name in _a) {
task = _a[name];
_ref = tasks;
for (name in _ref) {
task = _ref[name];
spaces = 20 - name.length;
spaces = spaces > 0 ? (function() {
_b = [];
for (i = 0; (0 <= spaces ? i <= spaces : i >= spaces); (0 <= spaces ? i += 1 : i -= 1)) {
_b.push(' ');
}
return _b;
})().join('') : '';
spaces = spaces > 0 ? Array(spaces + 1).join(' ') : '';
desc = task.description ? ("# " + (task.description)) : '';
puts("cake " + (name) + (spaces) + " " + (desc));
}
@@ -81,4 +75,4 @@
puts("No such task: \"" + (task) + "\"");
return process.exit(1);
};
})();
}).call(this);

View File

@@ -1,23 +1,24 @@
(function() {
var Lexer, compile, helpers, lexer, parser, path;
if (typeof process !== "undefined" && process !== null) {
path = require('path');
Lexer = require('./lexer').Lexer;
parser = require('./parser').parser;
helpers = require('./helpers').helpers;
helpers.extend(global, require('./nodes'));
if (require.registerExtension) {
require.registerExtension('.coffee', function(content) {
return compile(content);
});
}
} else {
this.exports = (this.CoffeeScript = {});
Lexer = this.Lexer;
parser = this.parser;
helpers = this.helpers;
var Lexer, _ref, compile, fs, lexer, parser, path;
path = require('path');
_ref = require('./lexer');
Lexer = _ref.Lexer;
_ref = require('./parser');
parser = _ref.parser;
if (require.extensions) {
fs = require('fs');
require.extensions['.coffee'] = function(module, filename) {
var content;
content = compile(fs.readFileSync(filename, 'utf8'));
module.filename = ("" + (filename) + " (compiled)");
return module._compile(content, module.filename);
};
} else if (require.registerExtension) {
require.registerExtension('.coffee', function(content) {
return compile(content);
});
}
exports.VERSION = '0.9.3';
exports.VERSION = '0.9.4';
exports.compile = (compile = function(code, options) {
options || (options = {});
try {
@@ -36,8 +37,20 @@
return parser.parse(lexer.tokenize(code));
};
exports.run = function(code, options) {
var __filename, root;
root = module;
while (root.parent) {
root = root.parent;
}
root.filename = (__filename = ("" + (options.fileName) + " (compiled)"));
if (root.moduleCache) {
root.moduleCache = {};
}
return root._compile(exports.compile(code, options), root.filename);
};
exports.eval = function(code, options) {
var __dirname, __filename;
module.filename = (__filename = options.fileName);
__filename = options.fileName;
__dirname = path.dirname(__filename);
return eval(exports.compile(code, options));
};
@@ -59,4 +72,5 @@
return "";
}
};
})();
parser.yy = require('./nodes');
}).call(this);

View File

@@ -1,16 +1,16 @@
(function() {
var BANNER, CoffeeScript, EventEmitter, SWITCHES, _a, _b, _c, compileOptions, compileScript, compileScripts, compileStdio, exec, fs, helpers, lint, optionParser, optparse, opts, parseOptions, path, printTokens, sources, spawn, usage, version, watch, writeJs;
var BANNER, CoffeeScript, EventEmitter, SWITCHES, _ref, compileOptions, compileScript, compileScripts, compileStdio, exec, fs, helpers, lint, optionParser, optparse, opts, parseOptions, path, printTokens, sources, spawn, usage, version, watch, writeJs;
fs = require('fs');
path = require('path');
optparse = require('./optparse');
CoffeeScript = require('./coffee-script');
_a = require('./helpers');
helpers = _a.helpers;
_b = require('child_process');
spawn = _b.spawn;
exec = _b.exec;
_c = require('events');
EventEmitter = _c.EventEmitter;
_ref = require('./helpers');
helpers = _ref.helpers;
_ref = require('child_process');
spawn = _ref.spawn;
exec = _ref.exec;
_ref = require('events');
EventEmitter = _ref.EventEmitter;
helpers.extend(CoffeeScript, new EventEmitter());
global.CoffeeScript = CoffeeScript;
BANNER = 'coffee compiles CoffeeScript source files into JavaScript.\n\nUsage:\n coffee path/to/script.coffee';
@@ -53,13 +53,13 @@
return compileScripts();
};
compileScripts = function() {
var _d, _e, _f, _g;
_d = []; _f = sources;
for (_e = 0, _g = _f.length; _e < _g; _e++) {
var _i, _len, _ref2, _result;
_result = []; _ref2 = sources;
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
(function() {
var base, compile;
var source = _f[_e];
return _d.push((function() {
var source = _ref2[_i];
return _result.push((function() {
base = source;
compile = function(source, topLevel) {
return path.exists(source, function(exists) {
@@ -69,13 +69,13 @@
return fs.stat(source, function(err, stats) {
if (stats.isDirectory()) {
return fs.readdir(source, function(err, files) {
var _h, _i, _j, _k, file;
_h = []; _j = files;
for (_i = 0, _k = _j.length; _i < _k; _i++) {
file = _j[_i];
_h.push(compile(path.join(source, file)));
var _j, _len2, _ref3, _result2, file;
_result2 = []; _ref3 = files;
for (_j = 0, _len2 = _ref3.length; _j < _len2; _j++) {
file = _ref3[_j];
_result2.push(compile(path.join(source, file)));
}
return _h;
return _result2;
});
} else if (topLevel || path.extname(source) === '.coffee') {
fs.readFile(source, function(err, code) {
@@ -92,16 +92,16 @@
})());
})();
}
return _d;
return _result;
};
compileScript = function(file, input, base) {
var _d, _e, _f, o, options, req, t, task;
var _i, _len, _ref2, o, options, req, t, task;
o = opts;
options = compileOptions(file);
if (o.require) {
_e = o.require;
for (_d = 0, _f = _e.length; _d < _f; _d++) {
req = _e[_d];
_ref2 = o.require;
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
req = _ref2[_i];
require(helpers.starts(req, '.') ? fs.realpathSync(req) : req);
}
}
@@ -204,19 +204,19 @@
return jsl.stdin.end();
};
printTokens = function(tokens) {
var _d, _e, _f, _g, _h, strings, tag, token, value;
var _i, _len, _ref2, _ref3, _result, strings, tag, token, value;
strings = (function() {
_d = []; _f = tokens;
for (_e = 0, _g = _f.length; _e < _g; _e++) {
token = _f[_e];
_d.push((function() {
_h = [token[0], token[1].toString().replace(/\n/, '\\n')];
tag = _h[0];
value = _h[1];
_result = []; _ref2 = tokens;
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
token = _ref2[_i];
_result.push((function() {
_ref3 = [token[0], token[1].toString().replace(/\n/, '\\n')];
tag = _ref3[0];
value = _ref3[1];
return "[" + (tag) + " " + (value) + "]";
})());
}
return _d;
return _result;
})();
return puts(strings.join(' '));
};
@@ -245,4 +245,4 @@
puts("CoffeeScript version " + (CoffeeScript.VERSION));
return process.exit(0);
};
})();
}).call(this);

View File

@@ -1,5 +1,5 @@
(function() {
var Parser, _a, _b, _c, _d, _e, _f, _g, _h, alt, alternatives, grammar, name, o, operators, token, tokens, unwrap;
var Parser, _i, _j, _len, _len2, _ref, _ref2, _ref3, _result, alt, alternatives, grammar, name, o, operators, token, tokens, unwrap;
var __hasProp = Object.prototype.hasOwnProperty;
Parser = require('jison').Parser;
unwrap = /function\s*\(\)\s*\{\s*return\s*([\s\S]*);\s*\}/;
@@ -9,6 +9,7 @@
return [patternString, '$$ = $1;', options];
}
action = (match = (action + '').match(unwrap)) ? match[1] : ("(" + (action) + "())");
action = action.replace(/\b(?:[A-Z][a-z]+Node|Expressions)\b/g, 'yy.$&');
return [patternString, ("$$ = " + (action) + ";"), options];
};
grammar = {
@@ -241,6 +242,8 @@
return $1;
}), o("ThisProperty : Expression", function() {
return new AssignNode(new ValueNode($1), $3, 'this');
}), o("ThisProperty : INDENT Expression OUTDENT", function() {
return new AssignNode(new ValueNode($1), $4, 'this');
})
],
ClassBody: [
@@ -610,18 +613,18 @@
};
operators = [["right", '?', 'NEW'], ["left", 'CALL_START', 'CALL_END'], ["nonassoc", '++', '--'], ["right", 'UNARY'], ["left", 'MATH'], ["left", '+', '-'], ["left", 'SHIFT'], ["left", 'COMPARE'], ["left", 'INSTANCEOF'], ["left", '==', '!='], ["left", 'LOGIC'], ["right", 'COMPOUND_ASSIGN'], ["left", '.'], ["nonassoc", 'INDENT', 'OUTDENT'], ["right", 'WHEN', 'LEADING_WHEN', 'IN', 'OF', 'BY', 'THROW'], ["right", 'IF', 'UNLESS', 'ELSE', 'FOR', 'WHILE', 'UNTIL', 'LOOP', 'SUPER', 'CLASS', 'EXTENDS'], ["right", '=', ':', 'RETURN'], ["right", '->', '=>', 'UNLESS', 'POST_IF', 'POST_UNLESS']];
tokens = [];
_a = grammar;
for (name in _a) {
if (!__hasProp.call(_a, name)) continue;
alternatives = _a[name];
_ref = grammar;
for (name in _ref) {
if (!__hasProp.call(_ref, name)) continue;
alternatives = _ref[name];
grammar[name] = (function() {
_b = []; _d = alternatives;
for (_c = 0, _e = _d.length; _c < _e; _c++) {
alt = _d[_c];
_b.push((function() {
_g = alt[0].split(' ');
for (_f = 0, _h = _g.length; _f < _h; _f++) {
token = _g[_f];
_result = []; _ref2 = alternatives;
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
alt = _ref2[_i];
_result.push((function() {
_ref3 = alt[0].split(' ');
for (_j = 0, _len2 = _ref3.length; _j < _len2; _j++) {
token = _ref3[_j];
if (!(grammar[token])) {
tokens.push(token);
}
@@ -632,7 +635,7 @@
return alt;
})());
}
return _b;
return _result;
})();
}
exports.parser = new Parser({
@@ -641,4 +644,4 @@
operators: operators.reverse(),
startSymbol: 'Root'
});
})();
}).call(this);

View File

@@ -1,17 +1,14 @@
(function() {
var compact, count, del, ends, extend, flatten, helpers, include, indexOf, merge, starts;
if (!(typeof process !== "undefined" && process !== null)) {
this.exports = this;
}
helpers = (exports.helpers = {});
helpers.indexOf = (indexOf = function(array, item, from) {
var _a, _b, index, other;
var _len, _ref, index, other;
if (array.indexOf) {
return array.indexOf(item, from);
}
_a = array;
for (index = 0, _b = _a.length; index < _b; index++) {
other = _a[index];
_ref = array;
for (index = 0, _len = _ref.length; index < _len; index++) {
other = _ref[index];
if (other === item && (!from || (from <= index))) {
return index;
}
@@ -30,15 +27,15 @@
return string.substring(start, start + literal.length) === literal;
});
helpers.compact = (compact = function(array) {
var _a, _b, _c, _d, item;
_a = []; _c = array;
for (_b = 0, _d = _c.length; _b < _d; _b++) {
item = _c[_b];
var _i, _len, _ref, _result, item;
_result = []; _ref = array;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
item = _ref[_i];
if (item) {
_a.push(item);
_result.push(item);
}
}
return _a;
return _result;
});
helpers.count = (count = function(string, letter) {
var num, pos;
@@ -51,37 +48,37 @@
return num;
});
helpers.merge = (merge = function(options, overrides) {
var _a, _b, fresh, key, val;
var _ref, fresh, key, val;
fresh = {};
_a = options;
for (key in _a) {
val = _a[key];
_ref = options;
for (key in _ref) {
val = _ref[key];
(fresh[key] = val);
}
if (overrides) {
_b = overrides;
for (key in _b) {
val = _b[key];
_ref = overrides;
for (key in _ref) {
val = _ref[key];
(fresh[key] = val);
}
}
return fresh;
});
helpers.extend = (extend = function(object, properties) {
var _a, _b, key, val;
_a = []; _b = properties;
for (key in _b) {
val = _b[key];
_a.push(object[key] = val);
var _ref, _result, key, val;
_result = []; _ref = properties;
for (key in _ref) {
val = _ref[key];
_result.push(object[key] = val);
}
return _a;
return _result;
});
helpers.flatten = (flatten = function(array) {
var _a, _b, _c, item, memo;
var _i, _len, _ref, item, memo;
memo = [];
_b = array;
for (_a = 0, _c = _b.length; _a < _c; _a++) {
item = _b[_a];
_ref = array;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
item = _ref[_i];
if (item instanceof Array) {
memo = memo.concat(item);
} else {
@@ -96,4 +93,4 @@
delete obj[key];
return val;
});
})();
}).call(this);

View File

@@ -1,10 +1,10 @@
(function() {
var _a, key, val;
var _ref, key, val;
var __hasProp = Object.prototype.hasOwnProperty;
_a = require('./coffee-script');
for (key in _a) {
if (!__hasProp.call(_a, key)) continue;
val = _a[key];
_ref = require('./coffee-script');
for (key in _ref) {
if (!__hasProp.call(_ref, key)) continue;
val = _ref[key];
(exports[key] = val);
}
})();
}).call(this);

View File

@@ -1,21 +1,13 @@
(function() {
var ASSIGNED, CALLABLE, CODE, COFFEE_ALIASES, COFFEE_KEYWORDS, COMMENT, COMPARE, COMPOUND_ASSIGN, CONVERSIONS, HEREDOC, HEREDOC_INDENT, IDENTIFIER, JS_CLEANER, JS_FORBIDDEN, JS_KEYWORDS, LAST_DENT, LAST_DENTS, LINE_BREAK, LOGIC, Lexer, MATH, MULTILINER, MULTI_DENT, NEXT_CHARACTER, NOT_REGEX, NO_NEWLINE, NUMBER, OPERATOR, REGEX_END, REGEX_ESCAPE, REGEX_INTERPOLATION, REGEX_START, RESERVED, Rewriter, SHIFT, UNARY, WHITESPACE, _a, _b, _c, compact, count, helpers, include, starts;
var ASSIGNED, CALLABLE, CODE, COFFEE_ALIASES, COFFEE_KEYWORDS, COMMENT, COMPARE, COMPOUND_ASSIGN, CONVERSIONS, HEREDOC, HEREDOC_INDENT, IDENTIFIER, JS_CLEANER, JS_FORBIDDEN, JS_KEYWORDS, LAST_DENT, LAST_DENTS, LINE_BREAK, LOGIC, Lexer, MATH, MULTILINER, MULTI_DENT, NEXT_CHARACTER, NOT_REGEX, NO_NEWLINE, NUMBER, OPERATOR, REGEX_END, REGEX_ESCAPE, REGEX_INTERPOLATION, REGEX_START, RESERVED, Rewriter, SHIFT, UNARY, WHITESPACE, _ref, compact, count, include, starts;
var __slice = Array.prototype.slice;
if (typeof process !== "undefined" && process !== null) {
_a = require('./rewriter');
Rewriter = _a.Rewriter;
_b = require('./helpers');
helpers = _b.helpers;
} else {
this.exports = this;
Rewriter = this.Rewriter;
helpers = this.helpers;
}
_c = helpers;
include = _c.include;
count = _c.count;
starts = _c.starts;
compact = _c.compact;
_ref = require('./rewriter');
Rewriter = _ref.Rewriter;
_ref = require('./helpers').helpers;
include = _ref.include;
count = _ref.count;
starts = _ref.starts;
compact = _ref.compact;
exports.Lexer = (function() {
Lexer = function() {};
Lexer.prototype.tokenize = function(code, options) {
@@ -170,10 +162,10 @@
}
this.line += count(match[1], "\n");
this.i += match[1].length;
if (match[4]) {
this.token('HERECOMMENT', this.sanitizeHeredoc(match[4], {
if (match[2]) {
this.token('HERECOMMENT', this.sanitizeHeredoc(match[2], {
herecomment: true,
indent: match[3]
indent: Array(this.indent + 1).join(' ')
}));
this.token('TERMINATOR', '\n');
}
@@ -192,11 +184,11 @@
return true;
};
Lexer.prototype.regexToken = function() {
var _d, end, first, flags, regex, str;
var _ref2, end, first, flags, regex, str;
if (!(first = this.chunk.match(REGEX_START))) {
return false;
}
if (first[1] === ' ' && !('CALL_START' === (_d = this.tag()) || '=' === _d)) {
if (first[1] === ' ' && !('CALL_START' === (_ref2 = this.tag()) || '=' === _ref2)) {
return false;
}
if (include(NOT_REGEX, this.tag())) {
@@ -320,7 +312,7 @@
return true;
};
Lexer.prototype.literalToken = function() {
var _d, match, prev, space, spaced, tag, value;
var _ref2, match, prev, space, spaced, tag, value;
match = this.chunk.match(OPERATOR);
value = match && match[1];
space = match && match[2];
@@ -335,7 +327,7 @@
if (include(JS_FORBIDDEN, this.value())) {
this.assignmentError();
}
if (('or' === (_d = this.value()) || 'and' === _d)) {
if (('or' === (_ref2 = this.value()) || 'and' === _ref2)) {
this.tokens.splice(this.tokens.length - 1, 1, ['COMPOUND_ASSIGN', CONVERSIONS[this.value()] + '=', prev[2]]);
return true;
}
@@ -395,24 +387,25 @@
return accessor ? 'accessor' : false;
};
Lexer.prototype.sanitizeHeredoc = function(doc, options) {
var _d, attempt, indent, match;
var _ref2, attempt, indent, match;
indent = options.indent;
if (options.herecomment && !include(doc, '\n')) {
return doc;
}
if (!(options.herecomment)) {
while ((match = HEREDOC_INDENT.exec(doc)) !== null) {
attempt = (typeof (_d = match[2]) !== "undefined" && _d !== null) ? match[2] : match[3];
attempt = (typeof (_ref2 = match[2]) !== "undefined" && _ref2 !== null) ? match[2] : match[3];
if (!(typeof indent !== "undefined" && indent !== null) || attempt.length < indent.length) {
indent = attempt;
}
}
}
indent || (indent = '');
doc = doc.replace(new RegExp("^" + indent, 'gm'), '').replace(/^\n/, '');
doc = doc.replace(new RegExp("^" + indent, 'gm'), '');
if (options.herecomment) {
return doc;
}
doc = doc.replace(/^\n/, '');
return doc.replace(MULTILINER, "\\n").replace(new RegExp(options.quote, 'g'), "\\" + (options.quote));
};
Lexer.prototype.tagParameters = function() {
@@ -428,15 +421,15 @@
return null;
}
switch (tok[0]) {
case 'IDENTIFIER':
tok[0] = 'PARAM';
break;
case ')':
tok[0] = 'PARAM_END';
break;
case '(':
case 'CALL_START':
return (tok[0] = 'PARAM_START');
case 'IDENTIFIER':
tok[0] = 'PARAM';
break;
case ')':
tok[0] = 'PARAM_END';
break;
case '(':
case 'CALL_START':
return (tok[0] = 'PARAM_START');
}
}
return true;
@@ -451,7 +444,7 @@
throw new Error("SyntaxError: Reserved word \"" + (this.value()) + "\" on line " + (this.line + 1) + " can't be assigned");
};
Lexer.prototype.balancedString = function(str, delimited, options) {
var _d, _e, _f, _g, close, i, levels, open, pair, slash;
var _i, _len, _ref2, _ref3, close, i, levels, open, pair, slash;
options || (options = {});
slash = delimited[0][0] === '/';
levels = [];
@@ -460,12 +453,12 @@
if (levels.length && starts(str, '\\', i)) {
i += 1;
} else {
_e = delimited;
for (_d = 0, _f = _e.length; _d < _f; _d++) {
pair = _e[_d];
_g = pair;
open = _g[0];
close = _g[1];
_ref2 = delimited;
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
pair = _ref2[_i];
_ref3 = pair;
open = _ref3[0];
close = _ref3[1];
if (levels.length && starts(str, close, i) && levels[levels.length - 1] === pair) {
levels.pop();
i += close.length - 1;
@@ -494,7 +487,7 @@
return !i ? false : str.substring(0, i);
};
Lexer.prototype.interpolateString = function(str, options) {
var _d, _e, _f, _g, _h, _i, escaped, expr, i, idx, inner, interpolated, lexer, nested, pi, quote, tag, tok, token, tokens, value;
var _len, _ref2, _ref3, escaped, expr, i, idx, inner, interpolated, lexer, nested, pi, quote, tag, tok, token, tokens, value;
options || (options = {});
if (str.length < 3 || !starts(str, '"')) {
return this.token('STRING', str);
@@ -502,9 +495,9 @@
lexer = new Lexer();
tokens = [];
quote = str.substring(0, 1);
_d = [1, 1];
i = _d[0];
pi = _d[1];
_ref2 = [1, 1];
i = _ref2[0];
pi = _ref2[1];
while (i < str.length - 1) {
if (starts(str, '\\', i)) {
i += 1;
@@ -520,9 +513,9 @@
nested = lexer.tokenize("(" + (inner) + ")", {
line: this.line
});
_e = nested;
for (idx = 0, _f = _e.length; idx < _f; idx++) {
tok = _e[idx];
_ref2 = nested;
for (idx = 0, _len = _ref2.length; idx < _len; idx++) {
tok = _ref2[idx];
if (tok[0] === 'CALL_END') {
(tok[0] = ')');
}
@@ -547,12 +540,12 @@
if (interpolated) {
this.token('(', '(');
}
_g = tokens;
for (i = 0, _h = _g.length; i < _h; i++) {
token = _g[i];
_i = token;
tag = _i[0];
value = _i[1];
_ref2 = tokens;
for (i = 0, _len = _ref2.length; i < _len; i++) {
token = _ref2[i];
_ref3 = token;
tag = _ref3[0];
value = _ref3[1];
if (tag === 'TOKENS') {
this.tokens = this.tokens.concat(value);
} else if (tag === 'STRING' && options.escapeQuotes) {
@@ -621,7 +614,7 @@
HEREDOC = /^("{6}|'{6}|"{3}([\s\S]*?)\n?([ \t]*)"{3}|'{3}([\s\S]*?)\n?([ \t]*)'{3})/;
OPERATOR = /^(-[\-=>]?|\+[+=]?|[*&|\/%=<>^:!?]+)([ \t]*)/;
WHITESPACE = /^([ \t]+)/;
COMMENT = /^(([ \t]*\n)*([ \t]*)###([^#][\s\S]*?)(###[ \t]*\n|(###)?$)|(\s*#(?!##[^#])[^\n]*)+)/;
COMMENT = /^(###([^#][\s\S]*?)(###[ \t]*\n|(###)?$)|(\s*#(?!##[^#])[^\n]*)+)/;
CODE = /^((-|=)>)/;
MULTI_DENT = /^((\n([ \t]*))+)(\.)?/;
LAST_DENTS = /\n([ \t]*)/g;
@@ -653,4 +646,4 @@
'not': '!',
'===': '=='
};
})();
}).call(this);

File diff suppressed because it is too large Load Diff

View File

@@ -7,19 +7,19 @@
return this;
};
OptionParser.prototype.parse = function(args) {
var _a, _b, _c, _d, _e, arg, i, isOption, matchedRule, options, rule, value;
var _i, _len, _len2, _ref, _ref2, arg, i, isOption, matchedRule, options, rule, value;
options = {
arguments: []
};
args = normalizeArguments(args);
_a = args;
for (i = 0, _b = _a.length; i < _b; i++) {
arg = _a[i];
_ref = args;
for (i = 0, _len = _ref.length; i < _len; i++) {
arg = _ref[i];
isOption = !!(arg.match(LONG_FLAG) || arg.match(SHORT_FLAG));
matchedRule = false;
_d = this.rules;
for (_c = 0, _e = _d.length; _c < _e; _c++) {
rule = _d[_c];
_ref2 = this.rules;
for (_i = 0, _len2 = _ref2.length; _i < _len2; _i++) {
rule = _ref2[_i];
if (rule.shortFlag === arg || rule.longFlag === arg) {
value = rule.hasArgument ? args[i += 1] : true;
options[rule.name] = rule.isList ? (options[rule.name] || []).concat(value) : value;
@@ -38,22 +38,16 @@
return options;
};
OptionParser.prototype.help = function() {
var _a, _b, _c, _d, i, letPart, lines, rule, spaces;
var _i, _len, _ref, letPart, lines, rule, spaces;
lines = ['Available options:'];
if (this.banner) {
lines.unshift("" + (this.banner) + "\n");
}
_b = this.rules;
for (_a = 0, _c = _b.length; _a < _c; _a++) {
rule = _b[_a];
_ref = this.rules;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
rule = _ref[_i];
spaces = 15 - rule.longFlag.length;
spaces = spaces > 0 ? (function() {
_d = [];
for (i = 0; (0 <= spaces ? i <= spaces : i >= spaces); (0 <= spaces ? i += 1 : i -= 1)) {
_d.push(' ');
}
return _d;
})().join('') : '';
spaces = spaces > 0 ? Array(spaces + 1).join(' ') : '';
letPart = rule.shortFlag ? rule.shortFlag + ', ' : ' ';
lines.push(' ' + letPart + rule.longFlag + spaces + rule.description);
}
@@ -66,18 +60,18 @@
MULTI_FLAG = /^-(\w{2,})/;
OPTIONAL = /\[(\w+(\*?))\]/;
buildRules = function(rules) {
var _a, _b, _c, _d, tuple;
_a = []; _c = rules;
for (_b = 0, _d = _c.length; _b < _d; _b++) {
tuple = _c[_b];
_a.push((function() {
var _i, _len, _ref, _result, tuple;
_result = []; _ref = rules;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
tuple = _ref[_i];
_result.push((function() {
if (tuple.length < 3) {
tuple.unshift(null);
}
return buildRule.apply(this, tuple);
})());
}
return _a;
return _result;
};
buildRule = function(shortFlag, longFlag, description, options) {
var match;
@@ -94,16 +88,16 @@
};
};
normalizeArguments = function(args) {
var _a, _b, _c, _d, _e, _f, arg, l, match, result;
var _i, _j, _len, _len2, _ref, _ref2, arg, l, match, result;
args = args.slice(0);
result = [];
_b = args;
for (_a = 0, _c = _b.length; _a < _c; _a++) {
arg = _b[_a];
_ref = args;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
arg = _ref[_i];
if (match = arg.match(MULTI_FLAG)) {
_e = match[1].split('');
for (_d = 0, _f = _e.length; _d < _f; _d++) {
l = _e[_d];
_ref2 = match[1].split('');
for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) {
l = _ref2[_j];
result.push('-' + l);
}
} else {
@@ -112,4 +106,4 @@
}
return result;
};
})();
}).call(this);

File diff suppressed because one or more lines are too long

View File

@@ -12,7 +12,7 @@
run = function(buffer) {
var val;
try {
val = CoffeeScript.run(buffer.toString(), {
val = CoffeeScript.eval(buffer.toString(), {
noWrap: true,
globals: true,
fileName: 'repl'
@@ -35,4 +35,4 @@
});
repl.on('line', run);
repl.prompt();
})();
}).call(this);

View File

@@ -1,15 +1,8 @@
(function() {
var BALANCED_PAIRS, EXPRESSION_CLOSE, EXPRESSION_END, EXPRESSION_START, IMPLICIT_BLOCK, IMPLICIT_CALL, IMPLICIT_END, IMPLICIT_FUNC, INVERSES, LINEBREAKS, Rewriter, SINGLE_CLOSERS, SINGLE_LINERS, _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, helpers, include, pair;
var BALANCED_PAIRS, EXPRESSION_CLOSE, EXPRESSION_END, EXPRESSION_START, IMPLICIT_BLOCK, IMPLICIT_CALL, IMPLICIT_END, IMPLICIT_FUNC, INVERSES, LINEBREAKS, Rewriter, SINGLE_CLOSERS, SINGLE_LINERS, _i, _len, _ref, _result, include, pair;
var __hasProp = Object.prototype.hasOwnProperty;
if (typeof process !== "undefined" && process !== null) {
_a = require('./helpers');
helpers = _a.helpers;
} else {
this.exports = this;
helpers = this.helpers;
}
_b = helpers;
include = _b.include;
_ref = require('./helpers').helpers;
include = _ref.include;
exports.Rewriter = (function() {
Rewriter = function() {};
Rewriter.prototype.rewrite = function(tokens) {
@@ -62,15 +55,15 @@
};
Rewriter.prototype.adjustComments = function() {
return this.scanTokens(function(token, i) {
var _c, _d, after, before, post, prev;
var _ref2, after, before, post, prev;
if (token[0] !== 'HERECOMMENT') {
return 1;
}
_c = [this.tokens[i - 2], this.tokens[i - 1], this.tokens[i + 1], this.tokens[i + 2]];
before = _c[0];
prev = _c[1];
post = _c[2];
after = _c[3];
_ref2 = [this.tokens[i - 2], this.tokens[i - 1], this.tokens[i + 1], this.tokens[i + 2]];
before = _ref2[0];
prev = _ref2[1];
post = _ref2[2];
after = _ref2[3];
if (after && after[0] === 'INDENT') {
this.tokens.splice(i + 2, 1);
if (before && before[0] === 'OUTDENT' && post && (prev[0] === post[0]) && (post[0] === 'TERMINATOR')) {
@@ -78,7 +71,7 @@
} else {
this.tokens.splice(i, 0, after);
}
} else if (prev && !('TERMINATOR' === (_d = prev[0]) || 'INDENT' === _d || 'OUTDENT' === _d)) {
} else if (prev && !('TERMINATOR' === (_ref2 = prev[0]) || 'INDENT' === _ref2 || 'OUTDENT' === _ref2)) {
if (post && post[0] === 'TERMINATOR' && after && after[0] === 'OUTDENT') {
this.tokens.splice.apply(this.tokens, [i + 2, 0].concat(this.tokens.splice(i, 2)));
if (this.tokens[i + 2][0] !== 'TERMINATOR') {
@@ -93,12 +86,12 @@
});
};
Rewriter.prototype.removeLeadingNewlines = function() {
var _c;
_c = [];
var _result;
_result = [];
while (this.tokens[0] && this.tokens[0][0] === 'TERMINATOR') {
_c.push(this.tokens.shift());
_result.push(this.tokens.shift());
}
return _c;
return _result;
};
Rewriter.prototype.removeMidExpressionNewlines = function() {
return this.scanTokens(function(token, i) {
@@ -114,8 +107,8 @@
var action, condition;
if (token[0] === 'CALL_START') {
condition = function(token, i) {
var _c;
return ((')' === (_c = token[0]) || 'CALL_END' === _c)) || (token[0] === 'OUTDENT' && this.tokens[i - 1][0] === ')');
var _ref2;
return ((')' === (_ref2 = token[0]) || 'CALL_END' === _ref2)) || (token[0] === 'OUTDENT' && this.tokens[i - 1][0] === ')');
};
action = function(token, i) {
var idx;
@@ -132,8 +125,8 @@
var action, condition;
if (token[0] === 'INDEX_START') {
condition = function(token, i) {
var _c;
return (']' === (_c = token[0]) || 'INDEX_END' === _c);
var _ref2;
return (']' === (_ref2 = token[0]) || 'INDEX_END' === _ref2);
};
action = function(token, i) {
return (token[0] = 'INDEX_END');
@@ -158,19 +151,22 @@
if (token[0] === ':' && (!last || last[0] !== '{')) {
stack.push('{');
idx = this.tag(i - 2) === '@' ? i - 2 : i - 1;
if (this.tag(idx - 2) === 'HERECOMMENT') {
idx -= 2;
}
tok = ['{', '{', token[2]];
tok.generated = true;
this.tokens.splice(idx, 0, tok);
condition = function(token, i) {
var _c, _d, _e, one, three, two;
_c = this.tokens.slice(i + 1, i + 4);
one = _c[0];
two = _c[1];
three = _c[2];
var _ref2, one, three, two;
_ref2 = this.tokens.slice(i + 1, i + 4);
one = _ref2[0];
two = _ref2[1];
three = _ref2[2];
if ((this.tag(i + 1) === 'HERECOMMENT' || this.tag(i - 1) === 'HERECOMMENT')) {
return false;
}
return ((('TERMINATOR' === (_d = token[0]) || 'OUTDENT' === _d)) && !((two && two[0] === ':') || (one && one[0] === '@' && three && three[0] === ':'))) || (token[0] === ',' && one && (!('IDENTIFIER' === (_e = one[0]) || 'STRING' === _e || '@' === _e || 'TERMINATOR' === _e || 'OUTDENT' === _e)));
return ((('TERMINATOR' === (_ref2 = token[0]) || 'OUTDENT' === _ref2)) && !((two && two[0] === ':') || (one && one[0] === '@' && three && three[0] === ':'))) || (token[0] === ',' && one && (!('IDENTIFIER' === (_ref2 = one[0]) || 'STRING' === _ref2 || '@' === _ref2 || 'TERMINATOR' === _ref2 || 'OUTDENT' === _ref2)));
};
action = function(token, i) {
return this.tokens.splice(i, 0, ['}', '}', token[2]]);
@@ -185,7 +181,7 @@
var classLine;
classLine = false;
return this.scanTokens(function(token, i) {
var _c, action, callObject, condition, idx, next, prev, seenSingle;
var _ref2, action, callObject, condition, idx, next, prev, seenSingle;
if (token[0] === 'CLASS') {
classLine = true;
}
@@ -203,17 +199,18 @@
if (prev && !prev.spaced && token[0] === '?') {
token.call = true;
}
if (prev && (prev.spaced && (include(IMPLICIT_FUNC, prev[0]) || prev.call) && include(IMPLICIT_CALL, token[0]) && !(token[0] === 'UNARY' && (('IN' === (_c = this.tag(i + 1)) || 'OF' === _c || 'INSTANCEOF' === _c)))) || callObject) {
if (prev && (prev.spaced && (include(IMPLICIT_FUNC, prev[0]) || prev.call) && include(IMPLICIT_CALL, token[0]) && !(token[0] === 'UNARY' && (('IN' === (_ref2 = this.tag(i + 1)) || 'OF' === _ref2 || 'INSTANCEOF' === _ref2)))) || callObject) {
this.tokens.splice(i, 0, ['CALL_START', '(', token[2]]);
condition = function(token, i) {
var _c;
var _ref2, post;
if (!seenSingle && token.fromThen) {
return true;
}
if (('IF' === (_c = token[0]) || 'ELSE' === _c || 'UNLESS' === _c || '->' === _c || '=>' === _c)) {
if (('IF' === (_ref2 = token[0]) || 'ELSE' === _ref2 || 'UNLESS' === _ref2 || '->' === _ref2 || '=>' === _ref2)) {
seenSingle = true;
}
return (!token.generated && this.tokens[i - 1][0] !== ',' && include(IMPLICIT_END, token[0]) && !(token[0] === 'INDENT' && (include(IMPLICIT_BLOCK, this.tag(i - 1)) || this.tag(i - 2) === 'CLASS' || this.tag(i + 1) === '{'))) || token[0] === 'PROPERTY_ACCESS' && this.tag(i - 1) === 'OUTDENT';
post = this.tokens[i + 1];
return (!token.generated && this.tokens[i - 1][0] !== ',' && include(IMPLICIT_END, token[0]) && !(token[0] === 'INDENT' && (include(IMPLICIT_BLOCK, this.tag(i - 1)) || this.tag(i - 2) === 'CLASS' || (post && post.generated && post[0] === '{')))) || token[0] === 'PROPERTY_ACCESS' && this.tag(i - 1) === 'OUTDENT';
};
action = function(token, i) {
idx = token[0] === 'OUTDENT' ? i + 1 : i;
@@ -230,7 +227,7 @@
};
Rewriter.prototype.addImplicitIndentation = function() {
return this.scanTokens(function(token, i) {
var _c, action, condition, indent, outdent, starter;
var _ref2, action, condition, indent, outdent, starter;
if (token[0] === 'ELSE' && this.tag(i - 1) !== 'OUTDENT') {
this.tokens.splice.apply(this.tokens, [i, 0].concat(this.indentation(token)));
return 2;
@@ -241,9 +238,9 @@
}
if (include(SINGLE_LINERS, token[0]) && this.tag(i + 1) !== 'INDENT' && !(token[0] === 'ELSE' && this.tag(i + 1) === 'IF')) {
starter = token[0];
_c = this.indentation(token);
indent = _c[0];
outdent = _c[1];
_ref2 = this.indentation(token);
indent = _ref2[0];
outdent = _ref2[1];
if (starter === 'THEN') {
indent.fromThen = true;
}
@@ -268,12 +265,12 @@
};
Rewriter.prototype.tagPostfixConditionals = function() {
return this.scanTokens(function(token, i) {
var _c, action, condition, original;
if (('IF' === (_c = token[0]) || 'UNLESS' === _c)) {
var _ref2, action, condition, original;
if (('IF' === (_ref2 = token[0]) || 'UNLESS' === _ref2)) {
original = token;
condition = function(token, i) {
var _c;
return ('TERMINATOR' === (_c = token[0]) || 'INDENT' === _c);
var _ref2;
return ('TERMINATOR' === (_ref2 = token[0]) || 'INDENT' === _ref2);
};
action = function(token, i) {
if (token[0] !== 'INDENT') {
@@ -287,17 +284,17 @@
});
};
Rewriter.prototype.ensureBalance = function(pairs) {
var _c, _d, key, levels, line, open, openLine, unclosed, value;
var _ref2, _result, key, levels, line, open, openLine, unclosed, value;
levels = {};
openLine = {};
this.scanTokens(function(token, i) {
var _c, _d, _e, _f, close, open, pair;
_d = pairs;
for (_c = 0, _e = _d.length; _c < _e; _c++) {
pair = _d[_c];
_f = pair;
open = _f[0];
close = _f[1];
var _i, _len, _ref2, _ref3, close, open, pair;
_ref2 = pairs;
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
pair = _ref2[_i];
_ref3 = pair;
open = _ref3[0];
close = _ref3[1];
levels[open] || (levels[open] = 0);
if (token[0] === open) {
if (levels[open] === 0) {
@@ -315,15 +312,15 @@
return 1;
});
unclosed = (function() {
_c = []; _d = levels;
for (key in _d) {
if (!__hasProp.call(_d, key)) continue;
value = _d[key];
_result = []; _ref2 = levels;
for (key in _ref2) {
if (!__hasProp.call(_ref2, key)) continue;
value = _ref2[key];
if (value > 0) {
_c.push(key);
_result.push(key);
}
}
return _c;
return _result;
})();
if (unclosed.length) {
open = unclosed[0];
@@ -332,13 +329,13 @@
}
};
Rewriter.prototype.rewriteClosingParens = function() {
var _c, debt, key, stack, val;
var _ref2, debt, key, stack, val;
stack = [];
debt = {};
_c = INVERSES;
for (key in _c) {
if (!__hasProp.call(_c, key)) continue;
val = _c[key];
_ref2 = INVERSES;
for (key in _ref2) {
if (!__hasProp.call(_ref2, key)) continue;
val = _ref2[key];
(debt[key] = 0);
}
return this.scanTokens(function(token, i) {
@@ -385,27 +382,27 @@
})();
BALANCED_PAIRS = [['(', ')'], ['[', ']'], ['{', '}'], ['INDENT', 'OUTDENT'], ['PARAM_START', 'PARAM_END'], ['CALL_START', 'CALL_END'], ['INDEX_START', 'INDEX_END']];
INVERSES = {};
_d = BALANCED_PAIRS;
for (_c = 0, _e = _d.length; _c < _e; _c++) {
pair = _d[_c];
_ref = BALANCED_PAIRS;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
pair = _ref[_i];
INVERSES[pair[0]] = pair[1];
INVERSES[pair[1]] = pair[0];
}
EXPRESSION_START = (function() {
_f = []; _h = BALANCED_PAIRS;
for (_g = 0, _i = _h.length; _g < _i; _g++) {
pair = _h[_g];
_f.push(pair[0]);
_result = []; _ref = BALANCED_PAIRS;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
pair = _ref[_i];
_result.push(pair[0]);
}
return _f;
return _result;
})();
EXPRESSION_END = (function() {
_j = []; _l = BALANCED_PAIRS;
for (_k = 0, _m = _l.length; _k < _m; _k++) {
pair = _l[_k];
_j.push(pair[1]);
_result = []; _ref = BALANCED_PAIRS;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
pair = _ref[_i];
_result.push(pair[1]);
}
return _j;
return _result;
})();
EXPRESSION_CLOSE = ['CATCH', 'WHEN', 'ELSE', 'FINALLY'].concat(EXPRESSION_END);
IMPLICIT_FUNC = ['IDENTIFIER', 'SUPER', ')', 'CALL_END', ']', 'INDEX_END', '@', 'THIS'];
@@ -415,4 +412,4 @@
SINGLE_LINERS = ['ELSE', "->", "=>", 'TRY', 'FINALLY', 'THEN'];
SINGLE_CLOSERS = ['TERMINATOR', 'CATCH', 'FINALLY', 'ELSE', 'OUTDENT', 'LEADING_WHEN'];
LINEBREAKS = ['TERMINATOR', 'INDENT', 'OUTDENT'];
})();
}).call(this);

View File

@@ -1,26 +1,39 @@
(function() {
var Scope;
var Scope, _ref, extend;
var __hasProp = Object.prototype.hasOwnProperty;
if (!(typeof process !== "undefined" && process !== null)) {
this.exports = this;
}
_ref = require('./helpers').helpers;
extend = _ref.extend;
exports.Scope = (function() {
Scope = function(parent, expressions, method) {
var _a;
_a = [parent, expressions, method];
this.parent = _a[0];
this.expressions = _a[1];
this.method = _a[2];
var _ref2;
_ref2 = [parent, expressions, method];
this.parent = _ref2[0];
this.expressions = _ref2[1];
this.method = _ref2[2];
this.variables = {};
if (this.parent) {
this.tempVar = this.parent.tempVar;
this.garbage = this.parent.garbage;
} else {
this.garbage = [];
Scope.root = this;
this.tempVar = '_a';
}
return this;
};
Scope.root = null;
Scope.prototype.startLevel = function() {
return this.garbage.push([]);
};
Scope.prototype.endLevel = function() {
var _i, _len, _ref2, _result, name;
_result = []; _ref2 = this.garbage.pop();
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
name = _ref2[_i];
if (this.variables[name] === 'var') {
_result.push(this.variables[name] = 'reuse');
}
}
return _result;
};
Scope.prototype.find = function(name, options) {
if (this.check(name, options)) {
return true;
@@ -29,11 +42,11 @@
return false;
};
Scope.prototype.any = function(fn) {
var _a, k, v;
_a = this.variables;
for (v in _a) {
if (!__hasProp.call(_a, v)) continue;
k = _a[v];
var _ref2, k, v;
_ref2 = this.variables;
for (v in _ref2) {
if (!__hasProp.call(_ref2, v)) continue;
k = _ref2[v];
if (fn(v, k)) {
return true;
}
@@ -51,14 +64,20 @@
}
return !!(this.parent && this.parent.check(name));
};
Scope.prototype.freeVariable = function() {
var ordinal;
while (this.check(this.tempVar)) {
ordinal = 1 + parseInt(this.tempVar.substr(1), 36);
this.tempVar = '_' + ordinal.toString(36).replace(/\d/g, 'a');
Scope.prototype.temporary = function(type, index) {
return type.length > 1 ? '_' + type + (index > 1 ? index : '') : '_' + (index + parseInt(type, 36)).toString(36).replace(/\d/g, 'a');
};
Scope.prototype.freeVariable = function(type) {
var index, temp;
index = 0;
while (this.check(temp = this.temporary(type, index)) && this.variables[temp] !== 'reuse') {
index++;
}
this.variables[this.tempVar] = 'var';
return this.tempVar;
this.variables[temp] = 'var';
if (this.garbage.length) {
this.garbage[this.garbage.length - 1].push(temp);
}
return temp;
};
Scope.prototype.assign = function(name, value) {
return (this.variables[name] = {
@@ -68,7 +87,7 @@
};
Scope.prototype.hasDeclarations = function(body) {
return body === this.expressions && this.any(function(k, val) {
return val === 'var';
return val === 'var' || val === 'reuse';
});
};
Scope.prototype.hasAssignments = function(body) {
@@ -77,30 +96,30 @@
});
};
Scope.prototype.declaredVariables = function() {
var _a, _b, key, val;
var _ref2, _result, key, val;
return (function() {
_a = []; _b = this.variables;
for (key in _b) {
if (!__hasProp.call(_b, key)) continue;
val = _b[key];
if (val === 'var') {
_a.push(key);
_result = []; _ref2 = this.variables;
for (key in _ref2) {
if (!__hasProp.call(_ref2, key)) continue;
val = _ref2[key];
if (val === 'var' || val === 'reuse') {
_result.push(key);
}
}
return _a;
return _result;
}).call(this).sort();
};
Scope.prototype.assignedVariables = function() {
var _a, _b, key, val;
_a = []; _b = this.variables;
for (key in _b) {
if (!__hasProp.call(_b, key)) continue;
val = _b[key];
var _ref2, _result, key, val;
_result = []; _ref2 = this.variables;
for (key in _ref2) {
if (!__hasProp.call(_ref2, key)) continue;
val = _ref2[key];
if (val.assigned) {
_a.push("" + (key) + " = " + (val.value));
_result.push("" + (key) + " = " + (val.value));
}
}
return _a;
return _result;
};
Scope.prototype.compiledDeclarations = function() {
return this.declaredVariables().join(', ');
@@ -110,4 +129,4 @@
};
return Scope;
}).call(this);
})();
}).call(this);

View File

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

View File

@@ -1,25 +1,39 @@
# Override exported methods for non-Node.js engines.
CoffeeScript = require './coffee-script'
# Use standard JavaScript `eval` to eval code.
CoffeeScript.eval = (code, options) ->
eval CoffeeScript.compile code, options
# Running code does not provide access to this scope.
CoffeeScript.run = (code, options) ->
(Function CoffeeScript.compile code, options)()
# If we're not in a browser environment, we're finished with the public API.
return unless window?
# Load a remote script from the current domain via XHR.
CoffeeScript.load = (url, options) ->
xhr = new (window.ActiveXObject or XMLHttpRequest)('Microsoft.XMLHTTP')
xhr.open 'GET', url, true
xhr.overrideMimeType 'text/plain' if 'overrideMimeType' of xhr
xhr.onreadystatechange = ->
CoffeeScript.run xhr.responseText, options if xhr.readyState is 4
xhr.send null
# Activate CoffeeScript in the browser by having it compile and evaluate
# all script tags with a content-type of `text/coffeescript`.
# This happens on page load.
if document?.getElementsByTagName
grind = (coffee) ->
setTimeout exports.compile coffee
grindRemote = (url) ->
xhr = new (window.ActiveXObject or XMLHttpRequest)('Microsoft.XMLHTTP')
xhr.open 'GET', url, true
xhr.overrideMimeType 'text/plain' if 'overrideMimeType' of xhr
xhr.onreadystatechange = ->
grind xhr.responseText if xhr.readyState is 4
xhr.send null
processScripts = ->
for script in document.getElementsByTagName 'script'
if script.type is 'text/coffeescript'
if script.src
grindRemote script.src
else
grind script.innerHTML
null
if window.addEventListener
addEventListener 'DOMContentLoaded', processScripts, false
else
attachEvent 'onload', processScripts
processScripts = ->
for script in document.getElementsByTagName 'script'
if script.type is 'text/coffeescript'
if script.src
CoffeeScript.load script.src
else
setTimeout -> CoffeeScript.run script.innerHTML
null
if window.addEventListener
addEventListener 'DOMContentLoaded', processScripts, false
else
attachEvent 'onload', processScripts

View File

@@ -58,7 +58,7 @@ printTasks = ->
puts ''
for all name, task of tasks
spaces = 20 - name.length
spaces = if spaces > 0 then (' ' for i in [0..spaces]).join('') else ''
spaces = if spaces > 0 then Array(spaces + 1).join(' ') else ''
desc = if task.description then "# #{task.description}" else ''
puts "cake #{name}#{spaces} #{desc}"
puts oparse.help() if switches.length

View File

@@ -6,23 +6,22 @@
# If included on a webpage, it will automatically sniff out, compile, and
# execute all scripts present in `text/coffeescript` tags.
# Set up dependencies correctly for both the server and the browser.
if process?
path = require 'path'
Lexer = require('./lexer').Lexer
parser = require('./parser').parser
helpers = require('./helpers').helpers
helpers.extend global, require './nodes'
if require.registerExtension
require.registerExtension '.coffee', (content) -> compile content
else
this.exports = this.CoffeeScript = {}
Lexer = this.Lexer
parser = this.parser
helpers = this.helpers
path = require 'path'
{Lexer} = require './lexer'
{parser} = require './parser'
# TODO: Remove registerExtension when fully deprecated
if require.extensions
fs = require 'fs'
require.extensions['.coffee'] = (module, filename) ->
content = compile fs.readFileSync filename, 'utf8'
module.filename = "#{filename} (compiled)"
module._compile content, module.filename
else if require.registerExtension
require.registerExtension '.coffee', (content) -> compile content
# The current CoffeeScript version number.
exports.VERSION = '0.9.3'
exports.VERSION = '0.9.4'
# Compile a string of CoffeeScript code to JavaScript, using the Coffee/Jison
# compiler.
@@ -47,9 +46,23 @@ exports.nodes = (code) ->
# Compile and execute a string of CoffeeScript (on the server), correctly
# setting `__filename`, `__dirname`, and relative `require()`.
exports.run = (code, options) ->
module.filename = __filename = options.fileName
__dirname = path.dirname __filename
eval exports.compile code, options
# We want the root module.
root = module
while root.parent
root = root.parent
# Set the filename
root.filename = __filename = "#{options.fileName} (compiled)"
# Clear the module cache
root.moduleCache = {} if root.moduleCache
# Compile
root._compile exports.compile(code, options), root.filename
# Compile and evaluate a string of CoffeeScript (in a Node.js-like environment).
# The CoffeeScript REPL uses this to run the input.
exports.eval = (code, options) ->
__filename = options.fileName
__dirname = path.dirname __filename
eval exports.compile(code, options)
# Instantiate a Lexer for our use here.
lexer = new Lexer
@@ -68,3 +81,5 @@ parser.lexer =
@tokens = tokens
@pos = 0
upcomingInput: -> ""
parser.yy = require './nodes'

View File

@@ -33,6 +33,7 @@ unwrap = /function\s*\(\)\s*\{\s*return\s*([\s\S]*);\s*\}/
o = (patternString, action, options) ->
return [patternString, '$$ = $1;', options] unless action
action = if match = (action + '').match(unwrap) then match[1] else "(#{action}())"
action = action.replace /\b(?:[A-Z][a-z]+Node|Expressions)\b/g, 'yy.$&'
[patternString, "$$ = #{action};", options]
# Grammatical Rules
@@ -286,6 +287,7 @@ grammar =
ClassAssign: [
o "AssignObj", -> $1
o "ThisProperty : Expression", -> new AssignNode new ValueNode($1), $3, 'this'
o "ThisProperty : INDENT Expression OUTDENT", -> new AssignNode new ValueNode($1), $4, 'this'
]
# A list of assignments to a class.

View File

@@ -2,8 +2,6 @@
# the **Lexer**, **Rewriter**, and the **Nodes**. Merge objects, flatten
# arrays, count characters, that sort of thing.
# Set up exported variables for both **Node.js** and the browser.
this.exports = this unless process?
helpers = exports.helpers = {}
# Cross-browser indexOf, so that IE can join the party.

View File

@@ -7,17 +7,10 @@
#
# Which is a format that can be fed directly into [Jison](http://github.com/zaach/jison).
# Set up the Lexer for both Node.js and the browser, depending on where we are.
if process?
{Rewriter} = require './rewriter'
{helpers} = require './helpers'
else
this.exports = this
Rewriter = this.Rewriter
helpers = this.helpers
{Rewriter} = require './rewriter'
# Import the helpers we need.
{include, count, starts, compact} = helpers
{include, count, starts, compact} = require('./helpers').helpers
# The Lexer Class
# ---------------
@@ -145,8 +138,9 @@ exports.Lexer = class Lexer
return false unless match = @chunk.match(COMMENT)
@line += count match[1], "\n"
@i += match[1].length
if match[4]
@token 'HERECOMMENT', @sanitizeHeredoc match[4], herecomment: true, indent: match[3]
if match[2]
@token 'HERECOMMENT', @sanitizeHeredoc match[2],
herecomment: true, indent: Array(@indent + 1).join(' ')
@token 'TERMINATOR', '\n'
true
@@ -331,8 +325,9 @@ exports.Lexer = class Lexer
attempt = if match[2]? then match[2] else match[3]
indent = attempt if not indent? or attempt.length < indent.length
indent or= ''
doc = doc.replace(new RegExp("^" + indent, 'gm'), '').replace(/^\n/, '')
doc = doc.replace(new RegExp("^" + indent, 'gm'), '')
return doc if options.herecomment
doc = doc.replace(/^\n/, '')
doc.replace(MULTILINER, "\\n")
.replace(new RegExp(options.quote, 'g'), "\\#{options.quote}")
@@ -529,7 +524,7 @@ NUMBER = /^(((\b0(x|X)[0-9a-fA-F]+)|((\b[0-9]+(\.[0-9]+)?|\.[0-9]+)(e[+\-
HEREDOC = /^("{6}|'{6}|"{3}([\s\S]*?)\n?([ \t]*)"{3}|'{3}([\s\S]*?)\n?([ \t]*)'{3})/
OPERATOR = /^(-[\-=>]?|\+[+=]?|[*&|\/%=<>^:!?]+)([ \t]*)/
WHITESPACE = /^([ \t]+)/
COMMENT = /^(([ \t]*\n)*([ \t]*)###([^#][\s\S]*?)(###[ \t]*\n|(###)?$)|(\s*#(?!##[^#])[^\n]*)+)/
COMMENT = /^(###([^#][\s\S]*?)(###[ \t]*\n|(###)?$)|(\s*#(?!##[^#])[^\n]*)+)/
CODE = /^((-|=)>)/
MULTI_DENT = /^((\n([ \t]*))+)(\.)?/
LAST_DENTS = /\n([ \t]*)/g

View File

@@ -3,18 +3,10 @@
# but some are created by other nodes as a method of code generation. To convert
# the syntax tree into a string of JavaScript code, call `compile()` on the root.
# Set up for both **Node.js** and the browser, by
# including the [Scope](scope.html) class and the [helper](helpers.html) functions.
if process?
Scope = require('./scope').Scope
helpers = require('./helpers').helpers
else
this.exports = this
helpers = this.helpers
Scope = this.Scope
{Scope} = require './scope'
# Import the helpers we plan to use.
{compact, flatten, merge, del, include, indexOf, starts, ends} = helpers
{compact, flatten, merge, del, include, indexOf, starts, ends} = require('./helpers').helpers
#### BaseNode
@@ -50,7 +42,10 @@ exports.BaseNode = class BaseNode
closure = @isStatement(o) and not @isPureStatement() and not top and
not @options.asStatement and this not instanceof CommentNode and
not @containsPureStatement()
if closure then @compileClosure(@options) else @compileNode(@options)
o.scope.startLevel() if not o.keepLevel
code = if closure then @compileClosure(@options) else @compileNode(@options)
o.scope.endLevel() if not o.keepLevel
code
# Statements converted into expressions via closure-wrapping share a scope
# object with their parent closure, to preserve the expected lexical scope.
@@ -70,7 +65,7 @@ exports.BaseNode = class BaseNode
else if this instanceof ValueNode and options.assignment
this.cacheIndexes(o)
else
reference = literal o.scope.freeVariable()
reference = literal o.scope.freeVariable 'ref'
compiled = new AssignNode reference, this
[compiled, reference]
return [pair[0].compile(o), pair[1].compile(o)] if options.precompile
@@ -207,7 +202,7 @@ exports.Expressions = class Expressions extends BaseNode
o.scope = new Scope(null, this, null)
code = @compileWithDeclarations(o)
code = code.replace(TRAILING_WHITESPACE, '')
if o.noWrap then code else "(function() {\n#{code}\n})();\n"
if o.noWrap then code else "(function() {\n#{code}\n}).call(this);\n"
# Compile the expressions body for the contents of a function, with
# declarations of all inner variables pushed up to the top.
@@ -374,7 +369,7 @@ exports.ValueNode = class ValueNode extends BaseNode
@source = baseline
if prop.soakNode
if @base.containsType(CallNode) and i is 0
temp = o.scope.freeVariable()
temp = o.scope.freeVariable 'ref'
complete = "(#{ baseline = temp } = (#{complete}))"
complete = if i is 0
"(typeof #{complete} === \"undefined\" || #{baseline} === null) ? undefined : "
@@ -452,10 +447,17 @@ exports.CallNode = class CallNode extends BaseNode
o.chainRoot = this unless o.chainRoot
op = @tags.operation
if @exist
[@first, @meth] = @variable.compileReference o, precompile: yes
if @variable instanceof ValueNode and @variable.properties[@variable.properties.length - 1] instanceof AccessorNode
methodAccessor = @variable.properties.pop()
[first, meth] = @variable.compileReference o
@first = new ValueNode(first, [methodAccessor]).compile o
@meth = new ValueNode(meth, [methodAccessor]).compile o
else
[@first, @meth] = @variable.compileReference o, precompile: yes
@first = "(typeof #{@first} === \"function\" ? "
@last = " : undefined)"
else if @variable then @meth = @variable.compile o
else if @variable
@meth = @variable.compile o
for arg in @args when arg instanceof SplatNode
code = @compileSplat(o)
if not code
@@ -481,7 +483,7 @@ exports.CallNode = class CallNode extends BaseNode
meth = @meth or @superReference(o)
obj = @variable and @variable.source or 'this'
if obj.match(/\(/)
temp = o.scope.freeVariable()
temp = o.scope.freeVariable 'ref'
obj = temp
meth = "(#{temp} = #{ @variable.source })#{ @variable.last }"
if @isNew
@@ -489,14 +491,14 @@ exports.CallNode = class CallNode extends BaseNode
for arg in @args
arg.contains (n) -> mentionsArgs or= n instanceof LiteralNode and (n.value is 'arguments')
utility 'extends'
a = o.scope.freeVariable()
b = o.scope.freeVariable()
c = o.scope.freeVariable()
a = o.scope.freeVariable 'ctor'
b = o.scope.freeVariable 'ref'
c = o.scope.freeVariable 'result'
"""
#{@first}(function() {
#{@idt(1)}var ctor = function(){};
#{@idt(1)}__extends(ctor, #{a} = #{meth});
#{@idt(1)}return typeof (#{b} = #{a}.apply(#{c} = new ctor, #{ @compileSplatArguments(o) })) === "object" ? #{b} : #{c};
#{@idt(1)}return typeof (#{c} = #{a}.apply(#{b} = new ctor, #{ @compileSplatArguments(o) })) === "object" ? #{c} : #{b};
#{@tab}}).#{ if mentionsArgs then 'apply(this, arguments)' else 'call(this)'}#{@last}
"""
else
@@ -617,8 +619,8 @@ exports.RangeNode = class RangeNode extends BaseNode
range = [+@fromNum..+@toNum]
range.pop() if @exclusive
return "[#{ range.join(', ') }]"
i = o.scope.freeVariable()
result = o.scope.freeVariable()
i = o.scope.freeVariable 'i'
result = o.scope.freeVariable 'result'
pre = "\n#{idt}#{result} = []; #{vars}"
if @fromNum and @toNum
o.index = i
@@ -736,7 +738,7 @@ exports.ClassNode = class ClassNode extends BaseNode
# equivalent syntax tree and compile that, in pieces. You can see the
# constructor, property assignments, and inheritance getting built out below.
compileNode: (o) ->
@variable = literal o.scope.freeVariable() if @variable is '__temp__'
@variable = literal o.scope.freeVariable 'ctor' if @variable is '__temp__'
extension = @parent and new ExtendsNode(@variable, @parent)
props = new Expressions
o.top = true
@@ -768,7 +770,7 @@ exports.ClassNode = class ClassNode extends BaseNode
else
func.bound = false
constScope or= new Scope(o.scope, constructor.body, constructor)
me or= constScope.freeVariable()
me or= constScope.freeVariable 'this'
pname = pvar.compile(o)
constructor.body.push new ReturnNode literal 'this' if constructor.body.empty()
constructor.body.unshift literal "this.#{pname} = function(){ return #{className}.prototype.#{pname}.apply(#{me}, arguments); }"
@@ -844,7 +846,7 @@ exports.AssignNode = class AssignNode extends BaseNode
# See the [ECMAScript Harmony Wiki](http://wiki.ecmascript.org/doku.php?id=harmony:destructuring)
# for details.
compilePatternMatch: (o) ->
valVar = o.scope.freeVariable()
valVar = o.scope.freeVariable 'ref'
value = if @value.isStatement(o) then ClosureNode.wrap(@value) else @value
assigns = ["#{@tab}#{valVar} = #{ value.compile(o) };"]
o.top = true
@@ -930,7 +932,7 @@ exports.CodeNode = class CodeNode extends BaseNode
else
if param.attach
{value} = param
[param, param.splat] = [literal(o.scope.freeVariable()), param.splat]
[param, param.splat] = [literal(o.scope.freeVariable 'arg'), param.splat]
@body.unshift new AssignNode new ValueNode(literal('this'), [new AccessorNode value]), param
if param.splat
splat = new SplatNode param.value
@@ -1004,15 +1006,15 @@ exports.SplatNode = class SplatNode extends BaseNode
o.scope.find name
end = ''
if @trailings.length
len = o.scope.freeVariable()
len = o.scope.freeVariable 'len'
o.scope.assign len, "arguments.length"
variadic = o.scope.freeVariable()
variadic = o.scope.freeVariable 'result'
o.scope.assign variadic, len + ' >= ' + @arglength
end = if @trailings.length then ", #{len} - #{@trailings.length}"
for trailing, idx in @trailings
if trailing.attach
assign = trailing.assign
trailing = literal o.scope.freeVariable()
trailing = literal o.scope.freeVariable 'arg'
assign.value = trailing
pos = @trailings.length - idx
o.scope.assign(trailing.compile(o), "arguments[#{variadic} ? #{len} - #{pos} : #{@index + idx}]")
@@ -1084,7 +1086,7 @@ exports.WhileNode = class WhileNode extends BaseNode
cond = @condition.compile(o)
set = ''
unless top
rvar = o.scope.freeVariable()
rvar = o.scope.freeVariable 'result'
set = "#{@tab}#{rvar} = [];\n"
@body = PushNode.wrap(rvar, @body) if @body
pre = "#{set}#{@tab}while (#{cond})"
@@ -1220,7 +1222,7 @@ exports.InNode = class InNode extends BaseNode
compileLoopTest: (o) ->
[@arr1, @arr2] = @array.compileReference o, precompile: yes
[i, l] = [o.scope.freeVariable(), o.scope.freeVariable()]
[i, l] = [o.scope.freeVariable('i'), o.scope.freeVariable('len')]
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; } return false; }).call(this)"
@@ -1378,12 +1380,12 @@ exports.ForNode = class ForNode extends BaseNode
source = if range then @source.base else @source
codeInBody = @body.contains (n) -> n instanceof CodeNode
scope = o.scope
name = (@name and @name.compile(o)) or scope.freeVariable()
name = (@name and @name.compile(o)) or scope.freeVariable 'i'
index = @index and @index.compile o
scope.find(name, immediate: yes) if name and not @pattern and (range or not codeInBody)
scope.find(index, immediate: yes) if index
rvar = scope.freeVariable() unless topLevel
ivar = if codeInBody then scope.freeVariable() else if range then name else index or scope.freeVariable()
rvar = scope.freeVariable 'result' unless topLevel
ivar = if codeInBody then scope.freeVariable 'i' else if range then name else index or scope.freeVariable 'i'
varPart = ''
guardPart = ''
body = Expressions.wrap([@body])
@@ -1391,14 +1393,14 @@ exports.ForNode = class ForNode extends BaseNode
sourcePart = source.compileVariables(o)
forPart = source.compile merge o, index: ivar, step: @step
else
svar = scope.freeVariable()
svar = scope.freeVariable 'ref'
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, keepLevel: yes}) + '\n'
else
namePart = "#{name} = #{svar}[#{ivar}]" if name
unless @object
lvar = scope.freeVariable()
lvar = scope.freeVariable 'len'
stepPart = if @step then "#{ivar} += #{ @step.compile(o) }" else "#{ivar}++"
forPart = "#{ivar} = 0, #{lvar} = #{svar}.length; #{ivar} < #{lvar}; #{stepPart}"
sourcePart = (if rvar then "#{rvar} = []; " else '') + sourcePart
@@ -1443,7 +1445,7 @@ exports.SwitchNode = class SwitchNode extends BaseNode
this
compileNode: (o) ->
idt = o.indent = @idt 1
idt = o.indent = @idt 2
o.top = yes
code = "#{ @tab }switch (#{ @subject.compile o }) {"
for pair in @cases
@@ -1451,11 +1453,11 @@ exports.SwitchNode = class SwitchNode extends BaseNode
exprs = block.expressions
for condition in flatten [conditions]
condition = new OpNode '!!', new ParentheticalNode condition if @tags.subjectless
code += "\n#{ @tab }case #{ condition.compile o }:"
code += "\n#{ @idt(1) }case #{ condition.compile o }:"
code += "\n#{ block.compile o }"
code += "\n#{ idt }break;" unless exprs[exprs.length - 1] instanceof ReturnNode
if @otherwise
code += "\n#{ @tab }default:\n#{ @otherwise.compile o }"
code += "\n#{ @idt(1) }default:\n#{ @otherwise.compile o }"
code += "\n#{ @tab }}"
code

View File

@@ -47,7 +47,7 @@ exports.OptionParser = class OptionParser
lines.unshift "#{@banner}\n" if @banner
for rule in @rules
spaces = 15 - rule.longFlag.length
spaces = if spaces > 0 then (' ' for i in [0..spaces]).join('') else ''
spaces = if spaces > 0 then Array(spaces + 1).join(' ') else ''
letPart = if rule.shortFlag then rule.shortFlag + ', ' else ' '
lines.push ' ' + letPart + rule.longFlag + spaces + rule.description
"\n#{ lines.join('\n') }\n"

View File

@@ -20,7 +20,7 @@ helpers.extend global, quit: -> process.exit(0)
# of exiting.
run = (buffer) ->
try
val = CoffeeScript.run buffer.toString(), noWrap: true, globals: true, fileName: 'repl'
val = CoffeeScript.eval buffer.toString(), noWrap: true, globals: true, fileName: 'repl'
puts inspect val if val isnt undefined
catch err
puts err.stack or err.toString()

View File

@@ -5,15 +5,8 @@
# shorthand into the unambiguous long form, add implicit indentation and
# parentheses, balance incorrect nestings, and generally clean things up.
# Set up exported variables for both Node.js and the browser.
if process?
{helpers} = require('./helpers')
else
this.exports = this
helpers = this.helpers
# Import the helpers we need.
{include} = helpers
{include} = require('./helpers').helpers
# The **Rewriter** class is used by the [Lexer](lexer.html), directly against
# its internal array of tokens.
@@ -138,6 +131,7 @@ exports.Rewriter = class Rewriter
if token[0] is ':' and (not last or last[0] isnt '{')
stack.push '{'
idx = if @tag(i - 2) is '@' then i - 2 else i - 1
idx -= 2 if @tag(idx - 2) is 'HERECOMMENT'
tok = ['{', '{', token[2]]
tok.generated = yes
@tokens.splice idx, 0, tok
@@ -173,8 +167,9 @@ exports.Rewriter = class Rewriter
condition = (token, i) ->
return yes if not seenSingle and token.fromThen
seenSingle = yes if token[0] in ['IF', 'ELSE', 'UNLESS', '->', '=>']
post = @tokens[i + 1]
(not token.generated and @tokens[i - 1][0] isnt ',' and include(IMPLICIT_END, token[0]) and
not (token[0] is 'INDENT' and (include(IMPLICIT_BLOCK, @tag(i - 1)) or @tag(i - 2) is 'CLASS' or @tag(i + 1) is '{'))) or
not (token[0] is 'INDENT' and (include(IMPLICIT_BLOCK, @tag(i - 1)) or @tag(i - 2) is 'CLASS' or (post and post.generated and post[0] is '{')))) or
token[0] is 'PROPERTY_ACCESS' and @tag(i - 1) is 'OUTDENT'
action = (token, i) ->
idx = if token[0] is 'OUTDENT' then i + 1 else i

View File

@@ -5,8 +5,8 @@
# variables are new and need to be declared with `var`, and which are shared
# with the outside.
# Set up exported variables for both **Node.js** and the browser.
this.exports = this unless process?
# Import the helpers we plan to use.
{extend} = require('./helpers').helpers
exports.Scope = class Scope
@@ -21,10 +21,19 @@ exports.Scope = class Scope
[@parent, @expressions, @method] = [parent, expressions, method]
@variables = {}
if @parent
@tempVar = @parent.tempVar
@garbage = @parent.garbage
else
@garbage = []
Scope.root = this
@tempVar = '_a'
# Create a new garbage level
startLevel: ->
@garbage.push []
# Return to the previous garbage level and erase referenced temporary
# variables in current level from scope.
endLevel: ->
(@variables[name] = 'reuse') for name in @garbage.pop() when @variables[name] is 'var'
# Look up a variable name in lexical scope, and declare it if it does not
# already exist.
@@ -51,14 +60,21 @@ exports.Scope = class Scope
return immediate if immediate or (options and options.immediate)
!!(@parent and @parent.check(name))
# Generate a temporary variable name at the given index.
temporary: (type, index) ->
if type.length > 1
'_' + type + if index > 1 then index else ''
else
'_' + (index + parseInt type, 36).toString(36).replace /\d/g, 'a'
# If we need to store an intermediate result, find an available name for a
# compiler-generated variable. `_a`, `_b`, and so on...
freeVariable: ->
while @check @tempVar
ordinal = 1 + parseInt @tempVar.substr(1), 36
@tempVar = '_' + ordinal.toString(36).replace(/\d/g, 'a')
@variables[@tempVar] = 'var'
@tempVar
# compiler-generated variable. `_var`, `_var2`, and so on...
freeVariable: (type) ->
index = 0
index++ while @check(temp = @temporary type, index) and @variables[temp] isnt 'reuse'
@variables[temp] = 'var'
@garbage[@garbage.length - 1].push temp if @garbage.length
temp
# Ensure that an assignment is made at the top of this scope
# (or at the top-level scope, if requested).
@@ -68,7 +84,7 @@ exports.Scope = class Scope
# Does this scope reference any variables that need to be declared in the
# given function body?
hasDeclarations: (body) ->
body is @expressions and @any (k, val) -> val is 'var'
body is @expressions and @any (k, val) -> val is 'var' or val is 'reuse'
# Does this scope reference any assignments that need to be declared at the
# top of the given function body?
@@ -77,7 +93,7 @@ exports.Scope = class Scope
# Return the list of variables first declared in this scope.
declaredVariables: ->
(key for key, val of @variables when val is 'var').sort()
(key for key, val of @variables when val is 'var' or val is 'reuse').sort()
# Return the list of assignments that are supposed to be made at the top
# of this scope.
@@ -88,6 +104,6 @@ exports.Scope = class Scope
compiledDeclarations: ->
@declaredVariables().join ', '
# Compile the JavaScript for all of the variable assignments in this scope.
# Compile the JavaScript forall of the variable assignments in this scope.
compiledAssignments: ->
@assignedVariables().join ', '

View File

@@ -27,8 +27,8 @@ ok results.join(' ') is '3 2 1'
# Make incorrect indentation safe.
func = ->
obj = {
key: 10
}
key: 10
}
obj.key - 5
ok func() is 5

View File

@@ -245,4 +245,14 @@ obj =
method: -> 'value'
instance = new obj.klass
ok instance.method() is 'value'
ok instance.method() is 'value'
# Implicit objects as static properties.
class Static
@static:
one: 1
two: 2
ok Static.static.one is 1
ok Static.static.two is 2

View File

@@ -154,4 +154,13 @@ class A
###
c: ->
ok A.prototype.c instanceof Function
ok A.prototype.c instanceof Function
class A
###
Comment
###
b: ->
c: ->
ok A.prototype.b instanceof Function

View File

@@ -12,3 +12,4 @@ CoffeeScript.run("resultArray.push i for i of global", {noWrap: on, globals: on,
ok 'setInterval' in global.resultArray
ok 'passed' is CoffeeScript.eval '"passed"', noWrap: on, globals: on, fileName: 'tests'

View File

@@ -124,13 +124,21 @@ duration = if options?.animated then 150 else 0
ok duration is 0
# function soak
# Function soaks.
plus1 = (x) -> x + 1
count = 0
obj = {
counter: -> count += 1; this
returnThis: -> this
}
ok plus1?(41) is 42
ok (plus1? 41) is 42
ok plus2?(41) is undefined
ok (plus2? 41) is undefined
ok obj.returnThis?() is obj
ok obj.counter().counter().returnThis?() is obj
ok count is 2
maybe_close = (f, arg) -> if typeof f is 'function' then () -> f(arg) else -1

View File

@@ -234,11 +234,18 @@ func.withThis()
# Ensure that constructors invoked with splats return a new object.
args = [1, 2, 3]
Type = (@args) ->
type = new Type args...
type = new Type args
ok type and type instanceof Type
ok type.args and type.args instanceof Array
ok v is args[i] for v, i in type.args
Type1 = (@a, @b, @c) ->
type1 = new Type1 args...
ok type1 and type1 instanceof Type1
ok type1.a is args[0] and type1.b is args[1] and type1.c is args[2]
# Ensure that constructors invoked with splats cache the function.
called = 0

View File

@@ -137,3 +137,13 @@ persons = [['Bob', ['George']], ['Alice', ['Bob']], ['Stan', ['Christopher']]]
join3 = "#{parent}: #{name}" for [name, [parent]] in persons
deepEqual join2, join3
# Pattern matching doesn't clash with implicit block objects.
obj = a: 101
func -> true
if func func
{a} = obj
ok a is 101