This commit is contained in:
Jeremy Ashkenas
2013-02-25 21:13:39 +13:00
86 changed files with 2139 additions and 1375 deletions

View File

@@ -5,12 +5,8 @@ CoffeeScript = require './lib/coffee-script'
{spawn, exec} = require 'child_process'
# ANSI Terminal Colors.
enableColors = no
unless process.platform is 'win32'
enableColors = not process.env.NODE_DISABLE_COLORS
bold = red = green = reset = ''
if enableColors
unless process.env.NODE_DISABLE_COLORS
bold = '\x1B[0;1m'
red = '\x1B[0;31m'
green = '\x1B[0;32m'
@@ -27,11 +23,6 @@ header = """
*/
"""
sources = [
'coffee-script', 'grammar', 'helpers'
'lexer', 'nodes', 'rewriter', 'scope'
].map (filename) -> "src/#{filename}.coffee"
# Run a CoffeeScript through our node/coffee interpreter.
run = (args, cb) ->
proc = spawn 'node', ['bin/coffee'].concat(args)
@@ -76,7 +67,11 @@ task 'build:full', 'rebuild the source twice, and run the tests', ->
build ->
build ->
csPath = './lib/coffee-script'
delete require.cache[require.resolve csPath]
csDir = path.dirname require.resolve csPath
for mod of require.cache when csDir is mod[0 ... csDir.length]
delete require.cache[mod]
unless runTests require csPath
process.exit 1
@@ -141,25 +136,25 @@ task 'doc:underscore', 'rebuild the Underscore.coffee documentation page', ->
task 'bench', 'quick benchmark of compilation time', ->
{Rewriter} = require './lib/coffee-script/rewriter'
co = sources.map((name) -> fs.readFileSync name).join '\n'
sources = ['coffee-script', 'grammar', 'helpers', 'lexer', 'nodes', 'rewriter']
coffee = sources.map((name) -> fs.readFileSync "src/#{name}.coffee").join '\n'
litcoffee = fs.readFileSync("src/scope.litcoffee").toString()
fmt = (ms) -> " #{bold}#{ " #{ms}".slice -4 }#{reset} ms"
total = 0
now = Date.now()
time = -> total += ms = -(now - now = Date.now()); fmt ms
tokens = CoffeeScript.tokens co, rewrite: false
tokens = CoffeeScript.tokens coffee, rewrite: no
littokens = CoffeeScript.tokens litcoffee, rewrite: no, literate: yes
tokens = tokens.concat(littokens)
console.log "Lex #{time()} (#{tokens.length} tokens)"
tokens = new Rewriter().rewrite tokens
console.log "Rewrite#{time()} (#{tokens.length} tokens)"
nodes = CoffeeScript.nodes tokens
console.log "Parse #{time()}"
js = nodes.compile bare: true
js = nodes.compile bare: yes
console.log "Compile#{time()} (#{js.length} chars)"
console.log "total #{ fmt total }"
task 'loc', 'count the lines of source code in the CoffeeScript compiler', ->
exec "cat #{ sources.join(' ') } | grep -v '^\\( *#\\|\\s*$\\)' | wc -l | tr -s ' '", (err, stdout) ->
console.log stdout.trim()
# Run the CoffeeScript test suite.
runTests = (CoffeeScript) ->
@@ -181,9 +176,11 @@ runTests = (CoffeeScript) ->
fn.call(fn)
++passedTests
catch e
e.description = description if description?
e.source = fn.toString() if fn.toString?
failures.push filename: currentFile, error: e
failures.push
filename: currentFile
error: e
description: description if description?
source: fn.toString() if fn.toString?
# See http://wiki.ecmascript.org/doku.php?id=harmony:egal
egal = (a, b) ->
@@ -211,16 +208,16 @@ runTests = (CoffeeScript) ->
return log(message, green) unless failures.length
log "failed #{failures.length} and #{message}", red
for fail in failures
{error, filename} = fail
{error, filename, description, source} = fail
jsFilename = filename.replace(/\.coffee$/,'.js')
match = error.stack?.match(new RegExp(fail.file+":(\\d+):(\\d+)"))
match = error.stack?.match(/on line (\d+):/) unless match
[match, line, col] = match if match
console.log ''
log " #{error.description}", red if error.description
log " #{description}", red if description
log " #{error.stack}", red
log " #{jsFilename}: line #{line ? 'unknown'}, column #{col ? 'unknown'}", red
console.log " #{error.source}" if error.source
console.log " #{source}" if source
return
# Run every test in the `test` folder, recording failures.

View File

@@ -49,6 +49,7 @@ task :gem do
s.authors = ['Jeremy Ashkenas']
s.email = 'jashkenas@gmail.com'
s.rubyforge_project = 'coffee-script-source'
s.license = "MIT"
end
file = File.open("coffee-script-source.gem", "w")

View File

@@ -1,5 +1,5 @@
###
CoffeeScript Compiler v1.4.0
CoffeeScript Compiler v1.5.0
Released under the MIT License
###

View File

@@ -1,4 +1,4 @@
<!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="pilwrap"> <a class="pilcrow" href="#section-1">&#182;</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="s">&#39;./coffee-script&#39;</span>
<!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> </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="pilwrap"> <a class="pilcrow" href="#section-1">&#182;</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="s">&#39;./coffee-script&#39;</span>
<span class="nv">CoffeeScript.require = </span><span class="nx">require</span></pre></div> </td> </tr> <tr id="section-2"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-2">&#182;</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="nf">(code, options = {}) -&gt;</span>
<span class="nx">options</span><span class="p">.</span><span class="nx">bare</span> <span class="o">?=</span> <span class="kc">on</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="pilwrap"> <a class="pilcrow" href="#section-3">&#182;</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="nf">(code, options = {}) -&gt;</span>

View File

@@ -1,4 +1,4 @@
<!DOCTYPE html> <html> <head> <title>cake.coffee</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <link rel="stylesheet" media="all" href="docco.css" /> </head> <body> <div id="container"> <div id="background"></div> <div id="jump_to"> Jump To &hellip; <div id="jump_wrapper"> <div id="jump_page"> <a class="source" href="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> cake.coffee </h1> </th> <th class="code"> </th> </tr> </thead> <tbody> <tr id="section-1"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-1">&#182;</a> </div> <p><code>cake</code> is a simplified version of <a href="http://www.gnu.org/software/make/">Make</a>
<!DOCTYPE html> <html> <head> <title>cake.coffee</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <link rel="stylesheet" media="all" href="docco.css" /> </head> <body> <div id="container"> <div id="background"></div> <div id="jump_to"> Jump To &hellip; <div id="jump_wrapper"> <div id="jump_page"> <a class="source" href="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> </div> </div> </div> <table cellpadding="0" cellspacing="0"> <thead> <tr> <th class="docs"> <h1> cake.coffee </h1> </th> <th class="code"> </th> </tr> </thead> <tbody> <tr id="section-1"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-1">&#182;</a> </div> <p><code>cake</code> is a simplified version of <a href="http://www.gnu.org/software/make/">Make</a>
(<a href="http://rake.rubyforge.org/">Rake</a>, <a href="http://github.com/280north/jake">Jake</a>)
for CoffeeScript. You define tasks with names and descriptions in a Cakefile,
and can call them from the command line, or invoke them from other tasks.</p>

View File

@@ -1,45 +1,44 @@
<!DOCTYPE html> <html> <head> <title>coffee-script.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> coffee-script.coffee </h1> </th> <th class="code"> </th> </tr> </thead> <tbody> <tr id="section-1"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-1">&#182;</a> </div> <p>CoffeeScript can be used both on the server, as a command-line compiler based
<!DOCTYPE html> <html> <head> <title>coffee-script.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> </div> </div> </div> <table cellpadding="0" cellspacing="0"> <thead> <tr> <th class="docs"> <h1> coffee-script.coffee </h1> </th> <th class="code"> </th> </tr> </thead> <tbody> <tr id="section-1"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-1">&#182;</a> </div> <p>CoffeeScript can be used both on the server, as a command-line compiler based
on Node.js/V8, or to run CoffeeScripts directly in the browser. This module
contains the main entry functions for tokenizing, 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><span class="nv">fs = </span><span class="nx">require</span> <span class="s">&#39;fs&#39;</span>
<span class="nv">path = </span><span class="nx">require</span> <span class="s">&#39;path&#39;</span>
<span class="p">{</span><span class="nx">Lexer</span><span class="p">,</span><span class="nx">RESERVED</span><span class="p">}</span> <span class="o">=</span> <span class="nx">require</span> <span class="s">&#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="s">&#39;./parser&#39;</span>
<span class="nv">vm = </span><span class="nx">require</span> <span class="s">&#39;vm&#39;</span>
<span class="nv">stripBOM = </span><span class="nf">(content) -&gt;</span>
<span class="k">if</span> <span class="nx">content</span><span class="p">.</span><span class="nx">charCodeAt</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span> <span class="o">is</span> <span class="mh">0xFEFF</span> <span class="k">then</span> <span class="nx">content</span><span class="p">.</span><span class="nx">substring</span> <span class="mi">1</span> <span class="k">else</span> <span class="nx">content</span>
execute all scripts present in <code>text/coffeescript</code> tags.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">fs = </span><span class="nx">require</span> <span class="s">&#39;fs&#39;</span>
<span class="nv">path = </span><span class="nx">require</span> <span class="s">&#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="s">&#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="s">&#39;./parser&#39;</span>
<span class="nv">vm = </span><span class="nx">require</span> <span class="s">&#39;vm&#39;</span></pre></div> </td> </tr> <tr id="section-2"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-2">&#182;</a> </div> <p>The file extensions that are considered to be CoffeeScript.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">extensions = </span><span class="p">[</span><span class="s">&#39;.coffee&#39;</span><span class="p">,</span> <span class="s">&#39;.litcoffee&#39;</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-3"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-3">&#182;</a> </div> <p>Load and run a CoffeeScript file for Node, stripping any <code>BOM</code>s.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">loadFile = </span><span class="nf">(module, filename) -&gt;</span>
<span class="nv">raw = </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="s">&#39;utf8&#39;</span>
<span class="nv">stripped = </span><span class="k">if</span> <span class="nx">raw</span><span class="p">.</span><span class="nx">charCodeAt</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span> <span class="o">is</span> <span class="mh">0xFEFF</span> <span class="k">then</span> <span class="nx">raw</span><span class="p">.</span><span class="nx">substring</span> <span class="mi">1</span> <span class="k">else</span> <span class="nx">raw</span>
<span class="nx">module</span><span class="p">.</span><span class="nx">_compile</span> <span class="nx">compile</span><span class="p">(</span><span class="nx">stripped</span><span class="p">,</span> <span class="p">{</span><span class="nx">filename</span><span class="p">}),</span> <span class="nx">filename</span>
<span class="k">if</span> <span class="nx">require</span><span class="p">.</span><span class="nx">extensions</span>
<span class="nx">require</span><span class="p">.</span><span class="nx">extensions</span><span class="p">[</span><span class="s">&#39;.coffee&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="nf">(module, filename) -&gt;</span>
<span class="nv">content = </span><span class="nx">compile</span> <span class="nx">stripBOM</span><span class="p">(</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="s">&#39;utf8&#39;</span><span class="p">),</span> <span class="p">{</span><span class="nx">filename</span><span class="p">}</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">filename</span></pre></div> </td> </tr> <tr id="section-2"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-2">&#182;</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="s">&#39;1.4.0&#39;</span></pre></div> </td> </tr> <tr id="section-3"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-3">&#182;</a> </div> <p>Words that cannot be used as identifiers in CoffeeScript code</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.RESERVED = </span><span class="nx">RESERVED</span></pre></div> </td> </tr> <tr id="section-4"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-4">&#182;</a> </div> <p>Expose helpers for testing.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.helpers = </span><span class="nx">require</span> <span class="s">&#39;./helpers&#39;</span></pre></div> </td> </tr> <tr id="section-5"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-5">&#182;</a> </div> <p>Compile a string of CoffeeScript code to JavaScript, using the Coffee/Jison
<span class="k">for</span> <span class="nx">ext</span> <span class="k">in</span> <span class="nx">extensions</span>
<span class="nx">require</span><span class="p">.</span><span class="nx">extensions</span><span class="p">[</span><span class="nx">ext</span><span class="p">]</span> <span class="o">=</span> <span class="nx">loadFile</span></pre></div> </td> </tr> <tr id="section-4"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-4">&#182;</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="s">&#39;1.5.0&#39;</span></pre></div> </td> </tr> <tr id="section-5"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-5">&#182;</a> </div> <p>Expose helpers for testing.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.helpers = </span><span class="nx">require</span> <span class="s">&#39;./helpers&#39;</span></pre></div> </td> </tr> <tr id="section-6"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-6">&#182;</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="nf">(code, options = {}) -&gt;</span>
<span class="p">{</span><span class="nx">merge</span><span class="p">}</span> <span class="o">=</span> <span class="nx">exports</span><span class="p">.</span><span class="nx">helpers</span>
<span class="k">try</span>
<span class="nv">js = </span><span class="p">(</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><span class="p">).</span><span class="nx">compile</span> <span class="nx">options</span>
<span class="nv">js = </span><span class="p">(</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="p">(</span><span class="nx">code</span><span class="p">,</span> <span class="nx">options</span><span class="p">)).</span><span class="nx">compile</span> <span class="nx">options</span>
<span class="k">return</span> <span class="nx">js</span> <span class="k">unless</span> <span class="nx">options</span><span class="p">.</span><span class="nx">header</span>
<span class="k">catch</span> <span class="nx">err</span>
<span class="nv">err.message = </span><span class="s">&quot;In </span><span class="si">#{</span><span class="nx">options</span><span class="p">.</span><span class="nx">filename</span><span class="si">}</span><span class="s">, </span><span class="si">#{</span><span class="nx">err</span><span class="p">.</span><span class="nx">message</span><span class="si">}</span><span class="s">&quot;</span> <span class="k">if</span> <span class="nx">options</span><span class="p">.</span><span class="nx">filename</span>
<span class="k">throw</span> <span class="nx">err</span>
<span class="nv">header = </span><span class="s">&quot;Generated by CoffeeScript </span><span class="si">#{</span><span class="nx">@VERSION</span><span class="si">}</span><span class="s">&quot;</span>
<span class="s">&quot;// </span><span class="si">#{</span><span class="nx">header</span><span class="si">}</span><span class="s">\n</span><span class="si">#{</span><span class="nx">js</span><span class="si">}</span><span class="s">&quot;</span></pre></div> </td> </tr> <tr id="section-6"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-6">&#182;</a> </div> <p>Tokenize a string of CoffeeScript code, and return the array of tokens.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.tokens = </span><span class="nf">(code, options) -&gt;</span>
<span class="nx">lexer</span><span class="p">.</span><span class="nx">tokenize</span> <span class="nx">code</span><span class="p">,</span> <span class="nx">options</span></pre></div> </td> </tr> <tr id="section-7"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-7">&#182;</a> </div> <p>Parse a string of CoffeeScript code or an array of lexed tokens, and
<span class="s">&quot;// </span><span class="si">#{</span><span class="nx">header</span><span class="si">}</span><span class="s">\n</span><span class="si">#{</span><span class="nx">js</span><span class="si">}</span><span class="s">&quot;</span></pre></div> </td> </tr> <tr id="section-7"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-7">&#182;</a> </div> <p>Tokenize a string of CoffeeScript code, and return the array of tokens.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.tokens = </span><span class="nf">(code, options) -&gt;</span>
<span class="nx">lexer</span><span class="p">.</span><span class="nx">tokenize</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="pilwrap"> <a class="pilcrow" href="#section-8">&#182;</a> </div> <p>Parse a string of CoffeeScript code or an array of lexed tokens, and
return the AST. You can then compile it by calling <code>.compile()</code> on the root,
or traverse it by using <code>.traverseChildren()</code> with a callback.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.nodes = </span><span class="nf">(source, options) -&gt;</span>
<span class="k">if</span> <span class="k">typeof</span> <span class="nx">source</span> <span class="o">is</span> <span class="s">&#39;string&#39;</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">source</span><span class="p">,</span> <span class="nx">options</span>
<span class="k">else</span>
<span class="nx">parser</span><span class="p">.</span><span class="nx">parse</span> <span class="nx">source</span></pre></div> </td> </tr> <tr id="section-8"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-8">&#182;</a> </div> <p>Compile and execute a string of CoffeeScript (on the server), correctly
<span class="nx">parser</span><span class="p">.</span><span class="nx">parse</span> <span class="nx">source</span></pre></div> </td> </tr> <tr id="section-9"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-9">&#182;</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="nf">(code, options = {}) -&gt;</span>
<span class="nv">mainModule = </span><span class="nx">require</span><span class="p">.</span><span class="nx">main</span></pre></div> </td> </tr> <tr id="section-9"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-9">&#182;</a> </div> <p>Set the filename.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">mainModule.filename = </span><span class="nx">process</span><span class="p">.</span><span class="nx">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span>
<span class="k">if</span> <span class="nx">options</span><span class="p">.</span><span class="nx">filename</span> <span class="k">then</span> <span class="nx">fs</span><span class="p">.</span><span class="nx">realpathSync</span><span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">filename</span><span class="p">)</span> <span class="k">else</span> <span class="s">&#39;.&#39;</span></pre></div> </td> </tr> <tr id="section-10"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-10">&#182;</a> </div> <p>Clear the module cache.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">mainModule</span><span class="p">.</span><span class="nx">moduleCache</span> <span class="o">and=</span> <span class="p">{}</span></pre></div> </td> </tr> <tr id="section-11"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-11">&#182;</a> </div> <p>Assign paths for node_modules loading</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">mainModule.paths = </span><span class="nx">require</span><span class="p">(</span><span class="s">&#39;module&#39;</span><span class="p">).</span><span class="nx">_nodeModulePaths</span> <span class="nx">path</span><span class="p">.</span><span class="nx">dirname</span> <span class="nx">fs</span><span class="p">.</span><span class="nx">realpathSync</span> <span class="nx">options</span><span class="p">.</span><span class="nx">filename</span></pre></div> </td> </tr> <tr id="section-12"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-12">&#182;</a> </div> <p>Compile.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span> <span class="nx">path</span><span class="p">.</span><span class="nx">extname</span><span class="p">(</span><span class="nx">mainModule</span><span class="p">.</span><span class="nx">filename</span><span class="p">)</span> <span class="o">isnt</span> <span class="s">&#39;.coffee&#39;</span> <span class="o">or</span> <span class="nx">require</span><span class="p">.</span><span class="nx">extensions</span>
<span class="nv">mainModule = </span><span class="nx">require</span><span class="p">.</span><span class="nx">main</span></pre></div> </td> </tr> <tr id="section-10"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-10">&#182;</a> </div> <p>Set the filename.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">mainModule.filename = </span><span class="nx">process</span><span class="p">.</span><span class="nx">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span>
<span class="k">if</span> <span class="nx">options</span><span class="p">.</span><span class="nx">filename</span> <span class="k">then</span> <span class="nx">fs</span><span class="p">.</span><span class="nx">realpathSync</span><span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">filename</span><span class="p">)</span> <span class="k">else</span> <span class="s">&#39;.&#39;</span></pre></div> </td> </tr> <tr id="section-11"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-11">&#182;</a> </div> <p>Clear the module cache.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">mainModule</span><span class="p">.</span><span class="nx">moduleCache</span> <span class="o">and=</span> <span class="p">{}</span></pre></div> </td> </tr> <tr id="section-12"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-12">&#182;</a> </div> <p>Assign paths for node_modules loading</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">mainModule.paths = </span><span class="nx">require</span><span class="p">(</span><span class="s">&#39;module&#39;</span><span class="p">).</span><span class="nx">_nodeModulePaths</span> <span class="nx">path</span><span class="p">.</span><span class="nx">dirname</span> <span class="nx">fs</span><span class="p">.</span><span class="nx">realpathSync</span> <span class="nx">options</span><span class="p">.</span><span class="nx">filename</span></pre></div> </td> </tr> <tr id="section-13"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-13">&#182;</a> </div> <p>Compile.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span> <span class="p">(</span><span class="nx">path</span><span class="p">.</span><span class="nx">extname</span><span class="p">(</span><span class="nx">mainModule</span><span class="p">.</span><span class="nx">filename</span><span class="p">)</span> <span class="o">not</span> <span class="k">in</span> <span class="nx">extensions</span><span class="p">)</span> <span class="o">or</span> <span class="nx">require</span><span class="p">.</span><span class="nx">extensions</span>
<span class="nx">mainModule</span><span class="p">.</span><span class="nx">_compile</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">mainModule</span><span class="p">.</span><span class="nx">filename</span>
<span class="k">else</span>
<span class="nx">mainModule</span><span class="p">.</span><span class="nx">_compile</span> <span class="nx">code</span><span class="p">,</span> <span class="nx">mainModule</span><span class="p">.</span><span class="nx">filename</span></pre></div> </td> </tr> <tr id="section-13"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-13">&#182;</a> </div> <p>Compile and evaluate a string of CoffeeScript (in a Node.js-like environment).
<span class="nx">mainModule</span><span class="p">.</span><span class="nx">_compile</span> <span class="nx">code</span><span class="p">,</span> <span class="nx">mainModule</span><span class="p">.</span><span class="nx">filename</span></pre></div> </td> </tr> <tr id="section-14"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-14">&#182;</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="nf">(code, options = {}) -&gt;</span>
<span class="k">return</span> <span class="k">unless</span> <span class="nv">code = </span><span class="nx">code</span><span class="p">.</span><span class="nx">trim</span><span class="p">()</span>
<span class="nv">Script = </span><span class="nx">vm</span><span class="p">.</span><span class="nx">Script</span>
@@ -54,12 +53,12 @@ The CoffeeScript REPL uses this to run the input.</p> </td>
<span class="k">else</span>
<span class="nv">sandbox = </span><span class="nx">global</span>
<span class="nv">sandbox.__filename = </span><span class="nx">options</span><span class="p">.</span><span class="nx">filename</span> <span class="o">||</span> <span class="s">&#39;eval&#39;</span>
<span class="nv">sandbox.__dirname = </span><span class="nx">path</span><span class="p">.</span><span class="nx">dirname</span> <span class="nx">sandbox</span><span class="p">.</span><span class="nx">__filename</span></pre></div> </td> </tr> <tr id="section-14"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-14">&#182;</a> </div> <p>define module/require only if they chose not to specify their own</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">unless</span> <span class="nx">sandbox</span> <span class="o">isnt</span> <span class="nx">global</span> <span class="o">or</span> <span class="nx">sandbox</span><span class="p">.</span><span class="nx">module</span> <span class="o">or</span> <span class="nx">sandbox</span><span class="p">.</span><span class="nx">require</span>
<span class="nv">sandbox.__dirname = </span><span class="nx">path</span><span class="p">.</span><span class="nx">dirname</span> <span class="nx">sandbox</span><span class="p">.</span><span class="nx">__filename</span></pre></div> </td> </tr> <tr id="section-15"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-15">&#182;</a> </div> <p>define module/require only if they chose not to specify their own</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">unless</span> <span class="nx">sandbox</span> <span class="o">isnt</span> <span class="nx">global</span> <span class="o">or</span> <span class="nx">sandbox</span><span class="p">.</span><span class="nx">module</span> <span class="o">or</span> <span class="nx">sandbox</span><span class="p">.</span><span class="nx">require</span>
<span class="nv">Module = </span><span class="nx">require</span> <span class="s">&#39;module&#39;</span>
<span class="nv">sandbox.module = _module = </span><span class="k">new</span> <span class="nx">Module</span><span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">modulename</span> <span class="o">||</span> <span class="s">&#39;eval&#39;</span><span class="p">)</span>
<span class="nv">sandbox.require = _require = </span><span class="nf">(path) -&gt;</span> <span class="nx">Module</span><span class="p">.</span><span class="nx">_load</span> <span class="nx">path</span><span class="p">,</span> <span class="nx">_module</span><span class="p">,</span> <span class="kc">true</span>
<span class="nv">_module.filename = </span><span class="nx">sandbox</span><span class="p">.</span><span class="nx">__filename</span>
<span class="nx">_require</span><span class="p">[</span><span class="nx">r</span><span class="p">]</span> <span class="o">=</span> <span class="nx">require</span><span class="p">[</span><span class="nx">r</span><span class="p">]</span> <span class="k">for</span> <span class="nx">r</span> <span class="k">in</span> <span class="nb">Object</span><span class="p">.</span><span class="nx">getOwnPropertyNames</span> <span class="nx">require</span> <span class="k">when</span> <span class="nx">r</span> <span class="o">isnt</span> <span class="s">&#39;paths&#39;</span></pre></div> </td> </tr> <tr id="section-15"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-15">&#182;</a> </div> <p>use the same hack node currently uses for their own REPL</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">_require.paths = _module.paths = </span><span class="nx">Module</span><span class="p">.</span><span class="nx">_nodeModulePaths</span> <span class="nx">process</span><span class="p">.</span><span class="nx">cwd</span><span class="p">()</span>
<span class="nx">_require</span><span class="p">[</span><span class="nx">r</span><span class="p">]</span> <span class="o">=</span> <span class="nx">require</span><span class="p">[</span><span class="nx">r</span><span class="p">]</span> <span class="k">for</span> <span class="nx">r</span> <span class="k">in</span> <span class="nb">Object</span><span class="p">.</span><span class="nx">getOwnPropertyNames</span> <span class="nx">require</span> <span class="k">when</span> <span class="nx">r</span> <span class="o">isnt</span> <span class="s">&#39;paths&#39;</span></pre></div> </td> </tr> <tr id="section-16"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-16">&#182;</a> </div> <p>use the same hack node currently uses for their own REPL</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">_require.paths = _module.paths = </span><span class="nx">Module</span><span class="p">.</span><span class="nx">_nodeModulePaths</span> <span class="nx">process</span><span class="p">.</span><span class="nx">cwd</span><span class="p">()</span>
<span class="nv">_require.resolve = </span><span class="nf">(request) -&gt;</span> <span class="nx">Module</span><span class="p">.</span><span class="nx">_resolveFilename</span> <span class="nx">request</span><span class="p">,</span> <span class="nx">_module</span>
<span class="nv">o = </span><span class="p">{}</span>
<span class="nx">o</span><span class="p">[</span><span class="nx">k</span><span class="p">]</span> <span class="o">=</span> <span class="nx">v</span> <span class="k">for</span> <span class="k">own</span> <span class="nx">k</span><span class="p">,</span> <span class="nx">v</span> <span class="k">of</span> <span class="nx">options</span>
@@ -68,11 +67,17 @@ The CoffeeScript REPL uses this to run the input.</p> </td>
<span class="k">if</span> <span class="nx">sandbox</span> <span class="o">is</span> <span class="nx">global</span>
<span class="nx">vm</span><span class="p">.</span><span class="nx">runInThisContext</span> <span class="nx">js</span>
<span class="k">else</span>
<span class="nx">vm</span><span class="p">.</span><span class="nx">runInContext</span> <span class="nx">js</span><span class="p">,</span> <span class="nx">sandbox</span></pre></div> </td> </tr> <tr id="section-16"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-16">&#182;</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-17"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-17">&#182;</a> </div> <p>The real Lexer produces a generic stream of tokens. This object provides a
<span class="nx">vm</span><span class="p">.</span><span class="nx">runInContext</span> <span class="nx">js</span><span class="p">,</span> <span class="nx">sandbox</span></pre></div> </td> </tr> <tr id="section-17"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-17">&#182;</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-18"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-18">&#182;</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="nv">lex: </span><span class="nf">-&gt;</span>
<span class="p">[</span><span class="nx">tag</span><span class="p">,</span> <span class="nx">@yytext</span><span class="p">,</span> <span class="nx">@yylineno</span><span class="p">]</span> <span class="o">=</span> <span class="nx">@tokens</span><span class="p">[</span><span class="nx">@pos</span><span class="o">++</span><span class="p">]</span> <span class="o">or</span> <span class="p">[</span><span class="s">&#39;&#39;</span><span class="p">]</span>
<span class="nv">token = </span><span class="nx">@tokens</span><span class="p">[</span><span class="nx">@pos</span><span class="o">++</span><span class="p">]</span>
<span class="k">if</span> <span class="nx">token</span>
<span class="p">[</span><span class="nx">tag</span><span class="p">,</span> <span class="nx">@yytext</span><span class="p">,</span> <span class="nx">@yylloc</span><span class="p">]</span> <span class="o">=</span> <span class="nx">token</span>
<span class="vi">@yylineno = </span><span class="nx">@yylloc</span><span class="p">.</span><span class="nx">first_line</span>
<span class="k">else</span>
<span class="nv">tag = </span><span class="s">&#39;&#39;</span>
<span class="nx">tag</span>
<span class="nv">setInput: </span><span class="nf">(@tokens) -&gt;</span>
<span class="vi">@pos = </span><span class="mi">0</span>

View File

@@ -1,4 +1,4 @@
<!DOCTYPE html> <html> <head> <title>command.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> command.coffee </h1> </th> <th class="code"> </th> </tr> </thead> <tbody> <tr id="section-1"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-1">&#182;</a> </div> <p>The <code>coffee</code> utility. Handles command-line compilation of CoffeeScript
<!DOCTYPE html> <html> <head> <title>command.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> </div> </div> </div> <table cellpadding="0" cellspacing="0"> <thead> <tr> <th class="docs"> <h1> command.coffee </h1> </th> <th class="code"> </th> </tr> </thead> <tbody> <tr id="section-1"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-1">&#182;</a> </div> <p>The <code>coffee</code> utility. Handles command-line compilation of CoffeeScript
into various forms: saved into <code>.js</code> files or printed to stdout, piped to
<a href="http://javascriptlint.com/">JavaScript Lint</a> or recompiled every time the source is
saved, printed as a token stream or as the syntax tree, or launch an
@@ -31,7 +31,6 @@ interactive REPL.</p> </td> <td class="code">
<span class="p">[</span> <span class="s">&#39;--nodejs [ARGS]&#39;</span><span class="p">,</span> <span class="s">&#39;pass options directly to the &quot;node&quot; binary&#39;</span><span class="p">]</span>
<span class="p">[</span><span class="s">&#39;-o&#39;</span><span class="p">,</span> <span class="s">&#39;--output [DIR]&#39;</span><span class="p">,</span> <span class="s">&#39;set the output directory for compiled JavaScript&#39;</span><span class="p">]</span>
<span class="p">[</span><span class="s">&#39;-p&#39;</span><span class="p">,</span> <span class="s">&#39;--print&#39;</span><span class="p">,</span> <span class="s">&#39;print out the compiled JavaScript&#39;</span><span class="p">]</span>
<span class="p">[</span><span class="s">&#39;-r&#39;</span><span class="p">,</span> <span class="s">&#39;--require [FILE*]&#39;</span><span class="p">,</span> <span class="s">&#39;require a library before executing your script&#39;</span><span class="p">]</span>
<span class="p">[</span><span class="s">&#39;-s&#39;</span><span class="p">,</span> <span class="s">&#39;--stdio&#39;</span><span class="p">,</span> <span class="s">&#39;listen for and compile scripts over stdio&#39;</span><span class="p">]</span>
<span class="p">[</span><span class="s">&#39;-t&#39;</span><span class="p">,</span> <span class="s">&#39;--tokens&#39;</span><span class="p">,</span> <span class="s">&#39;print out the tokens that the lexer/rewriter produce&#39;</span><span class="p">]</span>
<span class="p">[</span><span class="s">&#39;-v&#39;</span><span class="p">,</span> <span class="s">&#39;--version&#39;</span><span class="p">,</span> <span class="s">&#39;display the version number&#39;</span><span class="p">]</span>
@@ -41,39 +40,38 @@ interactive REPL.</p> </td> <td class="code">
<span class="nv">sourceCode = </span><span class="p">[]</span>
<span class="nv">notSources = </span><span class="p">{}</span>
<span class="nv">watchers = </span><span class="p">{}</span>
<span class="nv">optionParser = </span><span class="kc">null</span></pre></div> </td> </tr> <tr id="section-7"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-7">&#182;</a> </div> <p>Run <code>coffee</code> by parsing passed options and determining what action to take.
<span class="nv">optionParser = </span><span class="kc">null</span>
<span class="nv">coffee_exts = </span><span class="p">[</span><span class="s">&#39;.coffee&#39;</span><span class="p">,</span> <span class="s">&#39;.litcoffee&#39;</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-7"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-7">&#182;</a> </div> <p>Run <code>coffee</code> by parsing passed options and determining what action to take.
Many flags cause us to divert before compiling anything. Flags passed after
<code>--</code> will be passed verbatim to your script as arguments in <code>process.argv</code></p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.run = </span><span class="nf">-&gt;</span>
<span class="nx">parseOptions</span><span class="p">()</span>
<span class="k">return</span> <span class="nx">forkNode</span><span class="p">()</span> <span class="k">if</span> <span class="nx">opts</span><span class="p">.</span><span class="nx">nodejs</span>
<span class="k">return</span> <span class="nx">usage</span><span class="p">()</span> <span class="k">if</span> <span class="nx">opts</span><span class="p">.</span><span class="nx">help</span>
<span class="k">return</span> <span class="nx">version</span><span class="p">()</span> <span class="k">if</span> <span class="nx">opts</span><span class="p">.</span><span class="nx">version</span>
<span class="nx">loadRequires</span><span class="p">()</span> <span class="k">if</span> <span class="nx">opts</span><span class="p">.</span><span class="nx">require</span>
<span class="k">return</span> <span class="nx">require</span> <span class="s">&#39;./repl&#39;</span> <span class="k">if</span> <span class="nx">opts</span><span class="p">.</span><span class="nx">interactive</span>
<span class="k">return</span> <span class="nx">require</span><span class="p">(</span><span class="s">&#39;./repl&#39;</span><span class="p">).</span><span class="nx">start</span><span class="p">()</span> <span class="k">if</span> <span class="nx">opts</span><span class="p">.</span><span class="nx">interactive</span>
<span class="k">if</span> <span class="nx">opts</span><span class="p">.</span><span class="nx">watch</span> <span class="o">and</span> <span class="o">!</span><span class="nx">fs</span><span class="p">.</span><span class="nx">watch</span>
<span class="k">return</span> <span class="nx">printWarn</span> <span class="s">&quot;The --watch feature depends on Node v0.6.0+. You are running </span><span class="si">#{</span><span class="nx">process</span><span class="p">.</span><span class="nx">version</span><span class="si">}</span><span class="s">.&quot;</span>
<span class="k">return</span> <span class="nx">compileStdio</span><span class="p">()</span> <span class="k">if</span> <span class="nx">opts</span><span class="p">.</span><span class="nx">stdio</span>
<span class="k">return</span> <span class="nx">compileScript</span> <span class="kc">null</span><span class="p">,</span> <span class="nx">sources</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">if</span> <span class="nx">opts</span><span class="p">.</span><span class="nb">eval</span>
<span class="k">return</span> <span class="nx">require</span> <span class="s">&#39;./repl&#39;</span> <span class="k">unless</span> <span class="nx">sources</span><span class="p">.</span><span class="nx">length</span>
<span class="k">return</span> <span class="nx">require</span><span class="p">(</span><span class="s">&#39;./repl&#39;</span><span class="p">).</span><span class="nx">start</span><span class="p">()</span> <span class="k">unless</span> <span class="nx">sources</span><span class="p">.</span><span class="nx">length</span>
<span class="nv">literals = </span><span class="k">if</span> <span class="nx">opts</span><span class="p">.</span><span class="nx">run</span> <span class="k">then</span> <span class="nx">sources</span><span class="p">.</span><span class="nx">splice</span> <span class="mi">1</span> <span class="k">else</span> <span class="p">[]</span>
<span class="nv">process.argv = </span><span class="nx">process</span><span class="p">.</span><span class="nx">argv</span><span class="p">[</span><span class="mi">0</span><span class="p">..</span><span class="mi">1</span><span class="p">].</span><span class="nx">concat</span> <span class="nx">literals</span>
<span class="nx">process</span><span class="p">.</span><span class="nx">argv</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="s">&#39;coffee&#39;</span>
<span class="nv">process.execPath = </span><span class="nx">require</span><span class="p">.</span><span class="nx">main</span><span class="p">.</span><span class="nx">filename</span>
<span class="k">for</span> <span class="nx">source</span> <span class="k">in</span> <span class="nx">sources</span>
<span class="nx">compilePath</span> <span class="nx">source</span><span class="p">,</span> <span class="kc">yes</span><span class="p">,</span> <span class="nx">path</span><span class="p">.</span><span class="nx">normalize</span> <span class="nx">source</span></pre></div> </td> </tr> <tr id="section-8"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-8">&#182;</a> </div> <p>Compile a path, which could be a script or a directory. If a directory
is passed, recursively compile all '.coffee' extension source files in it
and all subdirectories.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">compilePath = </span><span class="nf">(source, topLevel, base) -&gt;</span>
is passed, recursively compile all '.coffee' and '.litcoffee' extension source
files in it and all subdirectories.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">compilePath = </span><span class="nf">(source, topLevel, base) -&gt;</span>
<span class="nx">fs</span><span class="p">.</span><span class="nx">stat</span> <span class="nx">source</span><span class="p">,</span> <span class="nf">(err, stats) -&gt;</span>
<span class="k">throw</span> <span class="nx">err</span> <span class="k">if</span> <span class="nx">err</span> <span class="o">and</span> <span class="nx">err</span><span class="p">.</span><span class="nx">code</span> <span class="o">isnt</span> <span class="s">&#39;ENOENT&#39;</span>
<span class="k">if</span> <span class="nx">err</span><span class="o">?</span><span class="p">.</span><span class="nx">code</span> <span class="o">is</span> <span class="s">&#39;ENOENT&#39;</span>
<span class="k">if</span> <span class="nx">topLevel</span> <span class="o">and</span> <span class="nx">source</span><span class="p">[</span><span class="o">-</span><span class="mi">7</span><span class="p">..]</span> <span class="o">isnt</span> <span class="s">&#39;.coffee&#39;</span>
<span class="k">if</span> <span class="nx">topLevel</span> <span class="o">and</span> <span class="nx">source</span> <span class="o">and</span> <span class="nx">path</span><span class="p">.</span><span class="nx">extname</span><span class="p">(</span><span class="nx">source</span><span class="p">)</span> <span class="o">not</span> <span class="k">in</span> <span class="nx">coffee_exts</span>
<span class="nv">source = </span><span class="nx">sources</span><span class="p">[</span><span class="nx">sources</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="nx">source</span><span class="p">)]</span> <span class="o">=</span> <span class="s">&quot;</span><span class="si">#{</span><span class="nx">source</span><span class="si">}</span><span class="s">.coffee&quot;</span>
<span class="k">return</span> <span class="nx">compilePath</span> <span class="nx">source</span><span class="p">,</span> <span class="nx">topLevel</span><span class="p">,</span> <span class="nx">base</span>
<span class="k">if</span> <span class="nx">topLevel</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">error</span> <span class="s">&quot;File not found: </span><span class="si">#{</span><span class="nx">source</span><span class="si">}</span><span class="s">&quot;</span>
<span class="nx">process</span><span class="p">.</span><span class="nx">exit</span> <span class="mi">1</span>
<span class="k">return</span>
<span class="k">if</span> <span class="nx">stats</span><span class="p">.</span><span class="nx">isDirectory</span><span class="p">()</span>
<span class="k">if</span> <span class="nx">stats</span><span class="p">.</span><span class="nx">isDirectory</span><span class="p">()</span> <span class="o">and</span> <span class="nx">path</span><span class="p">.</span><span class="nx">dirname</span><span class="p">(</span><span class="nx">source</span><span class="p">)</span> <span class="o">isnt</span> <span class="s">&#39;node_modules&#39;</span>
<span class="nx">watchDir</span> <span class="nx">source</span><span class="p">,</span> <span class="nx">base</span> <span class="k">if</span> <span class="nx">opts</span><span class="p">.</span><span class="nx">watch</span>
<span class="nx">fs</span><span class="p">.</span><span class="nx">readdir</span> <span class="nx">source</span><span class="p">,</span> <span class="nf">(err, files) -&gt;</span>
<span class="k">throw</span> <span class="nx">err</span> <span class="k">if</span> <span class="nx">err</span> <span class="o">and</span> <span class="nx">err</span><span class="p">.</span><span class="nx">code</span> <span class="o">isnt</span> <span class="s">&#39;ENOENT&#39;</span>
@@ -84,7 +82,7 @@ and all subdirectories.</p> </td> <td class="code">
<span class="nx">sourceCode</span><span class="p">[</span><span class="nx">index</span><span class="p">..</span><span class="nx">index</span><span class="p">]</span> <span class="o">=</span> <span class="nx">files</span><span class="p">.</span><span class="nx">map</span> <span class="nf">-&gt;</span> <span class="kc">null</span>
<span class="nx">files</span><span class="p">.</span><span class="nx">forEach</span> <span class="nf">(file) -&gt;</span>
<span class="nx">compilePath</span> <span class="p">(</span><span class="nx">path</span><span class="p">.</span><span class="nx">join</span> <span class="nx">source</span><span class="p">,</span> <span class="nx">file</span><span class="p">),</span> <span class="kc">no</span><span class="p">,</span> <span class="nx">base</span>
<span class="k">else</span> <span class="k">if</span> <span class="nx">topLevel</span> <span class="o">or</span> <span class="nx">path</span><span class="p">.</span><span class="nx">extname</span><span class="p">(</span><span class="nx">source</span><span class="p">)</span> <span class="o">is</span> <span class="s">&#39;.coffee&#39;</span>
<span class="k">else</span> <span class="k">if</span> <span class="nx">topLevel</span> <span class="o">or</span> <span class="nx">path</span><span class="p">.</span><span class="nx">extname</span><span class="p">(</span><span class="nx">source</span><span class="p">)</span> <span class="k">in</span> <span class="nx">coffee_exts</span>
<span class="nx">watch</span> <span class="nx">source</span><span class="p">,</span> <span class="nx">base</span> <span class="k">if</span> <span class="nx">opts</span><span class="p">.</span><span class="nx">watch</span>
<span class="nx">fs</span><span class="p">.</span><span class="nx">readFile</span> <span class="nx">source</span><span class="p">,</span> <span class="nf">(err, code) -&gt;</span>
<span class="k">throw</span> <span class="nx">err</span> <span class="k">if</span> <span class="nx">err</span> <span class="o">and</span> <span class="nx">err</span><span class="p">.</span><span class="nx">code</span> <span class="o">isnt</span> <span class="s">&#39;ENOENT&#39;</span>
@@ -100,8 +98,8 @@ requested options. If evaluating the script directly sets <code>__filename</code
<span class="k">try</span>
<span class="nv">t = task = </span><span class="p">{</span><span class="nx">file</span><span class="p">,</span> <span class="nx">input</span><span class="p">,</span> <span class="nx">options</span><span class="p">}</span>
<span class="nx">CoffeeScript</span><span class="p">.</span><span class="nx">emit</span> <span class="s">&#39;compile&#39;</span><span class="p">,</span> <span class="nx">task</span>
<span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">tokens</span> <span class="k">then</span> <span class="nx">printTokens</span> <span class="nx">CoffeeScript</span><span class="p">.</span><span class="nx">tokens</span> <span class="nx">t</span><span class="p">.</span><span class="nx">input</span>
<span class="k">else</span> <span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">nodes</span> <span class="k">then</span> <span class="nx">printLine</span> <span class="nx">CoffeeScript</span><span class="p">.</span><span class="nx">nodes</span><span class="p">(</span><span class="nx">t</span><span class="p">.</span><span class="nx">input</span><span class="p">).</span><span class="nx">toString</span><span class="p">().</span><span class="nx">trim</span><span class="p">()</span>
<span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">tokens</span> <span class="k">then</span> <span class="nx">printTokens</span> <span class="nx">CoffeeScript</span><span class="p">.</span><span class="nx">tokens</span> <span class="nx">t</span><span class="p">.</span><span class="nx">input</span><span class="p">,</span> <span class="nx">t</span><span class="p">.</span><span class="nx">options</span>
<span class="k">else</span> <span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">nodes</span> <span class="k">then</span> <span class="nx">printLine</span> <span class="nx">CoffeeScript</span><span class="p">.</span><span class="nx">nodes</span><span class="p">(</span><span class="nx">t</span><span class="p">.</span><span class="nx">input</span><span class="p">,</span> <span class="nx">t</span><span class="p">.</span><span class="nx">options</span><span class="p">).</span><span class="nx">toString</span><span class="p">().</span><span class="nx">trim</span><span class="p">()</span>
<span class="k">else</span> <span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">run</span> <span class="k">then</span> <span class="nx">CoffeeScript</span><span class="p">.</span><span class="nx">run</span> <span class="nx">t</span><span class="p">.</span><span class="nx">input</span><span class="p">,</span> <span class="nx">t</span><span class="p">.</span><span class="nx">options</span>
<span class="k">else</span> <span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">join</span> <span class="o">and</span> <span class="nx">t</span><span class="p">.</span><span class="nx">file</span> <span class="o">isnt</span> <span class="nx">o</span><span class="p">.</span><span class="nx">join</span>
<span class="nx">sourceCode</span><span class="p">[</span><span class="nx">sources</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="nx">t</span><span class="p">.</span><span class="nx">file</span><span class="p">)]</span> <span class="o">=</span> <span class="nx">t</span><span class="p">.</span><span class="nx">input</span>
@@ -131,11 +129,7 @@ them together.</p> </td> <td class="code">
<span class="k">unless</span> <span class="nx">sourceCode</span><span class="p">.</span><span class="nx">some</span><span class="p">(</span><span class="nf">(code) -&gt;</span> <span class="nx">code</span> <span class="o">is</span> <span class="kc">null</span><span class="p">)</span>
<span class="nx">clearTimeout</span> <span class="nx">joinTimeout</span>
<span class="nv">joinTimeout = </span><span class="nx">wait</span> <span class="mi">100</span><span class="p">,</span> <span class="nf">-&gt;</span>
<span class="nx">compileScript</span> <span class="nx">opts</span><span class="p">.</span><span class="nx">join</span><span class="p">,</span> <span class="nx">sourceCode</span><span class="p">.</span><span class="nx">join</span><span class="p">(</span><span class="s">&#39;\n&#39;</span><span class="p">),</span> <span class="nx">opts</span><span class="p">.</span><span class="nx">join</span></pre></div> </td> </tr> <tr id="section-12"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-12">&#182;</a> </div> <p>Load files that are to-be-required before compilation occurs.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">loadRequires = </span><span class="nf">-&gt;</span>
<span class="nv">realFilename = </span><span class="nx">module</span><span class="p">.</span><span class="nx">filename</span>
<span class="nv">module.filename = </span><span class="s">&#39;.&#39;</span>
<span class="nx">require</span> <span class="nx">req</span> <span class="k">for</span> <span class="nx">req</span> <span class="k">in</span> <span class="nx">opts</span><span class="p">.</span><span class="nx">require</span>
<span class="nv">module.filename = </span><span class="nx">realFilename</span></pre></div> </td> </tr> <tr id="section-13"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-13">&#182;</a> </div> <p>Watch a source CoffeeScript file using <code>fs.watch</code>, recompiling it every
<span class="nx">compileScript</span> <span class="nx">opts</span><span class="p">.</span><span class="nx">join</span><span class="p">,</span> <span class="nx">sourceCode</span><span class="p">.</span><span class="nx">join</span><span class="p">(</span><span class="s">&#39;\n&#39;</span><span class="p">),</span> <span class="nx">opts</span><span class="p">.</span><span class="nx">join</span></pre></div> </td> </tr> <tr id="section-12"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-12">&#182;</a> </div> <p>Watch a source CoffeeScript file using <code>fs.watch</code>, recompiling it every
time the file is updated. May be used in combination with other options,
such as <code>--lint</code> or <code>--print</code>.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">watch = </span><span class="nf">(source, base) -&gt;</span>
@@ -173,7 +167,7 @@ such as <code>--lint</code> or <code>--print</code>.</p> </td>
<span class="nv">rewatch = </span><span class="nf">-&gt;</span>
<span class="nx">watcher</span><span class="o">?</span><span class="p">.</span><span class="nx">close</span><span class="p">()</span>
<span class="nv">watcher = </span><span class="nx">fs</span><span class="p">.</span><span class="nx">watch</span> <span class="nx">source</span><span class="p">,</span> <span class="nx">compile</span></pre></div> </td> </tr> <tr id="section-14"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-14">&#182;</a> </div> <p>Watch a directory of files for new additions.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">watchDir = </span><span class="nf">(source, base) -&gt;</span>
<span class="nv">watcher = </span><span class="nx">fs</span><span class="p">.</span><span class="nx">watch</span> <span class="nx">source</span><span class="p">,</span> <span class="nx">compile</span></pre></div> </td> </tr> <tr id="section-13"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-13">&#182;</a> </div> <p>Watch a directory of files for new additions.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">watchDir = </span><span class="nf">(source, base) -&gt;</span>
<span class="nv">readdirTimeout = </span><span class="kc">null</span>
<span class="k">try</span>
<span class="nv">watcher = </span><span class="nx">fs</span><span class="p">.</span><span class="nx">watch</span> <span class="nx">source</span><span class="p">,</span> <span class="nf">-&gt;</span>
@@ -198,7 +192,7 @@ such as <code>--lint</code> or <code>--print</code>.</p> </td>
<span class="nv">toRemove = </span><span class="p">(</span><span class="nx">file</span> <span class="k">for</span> <span class="nx">file</span> <span class="k">in</span> <span class="nx">sources</span> <span class="k">when</span> <span class="nx">file</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="nx">source</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="mi">0</span><span class="p">)</span>
<span class="nx">removeSource</span> <span class="nx">file</span><span class="p">,</span> <span class="nx">base</span><span class="p">,</span> <span class="kc">yes</span> <span class="k">for</span> <span class="nx">file</span> <span class="k">in</span> <span class="nx">toRemove</span>
<span class="k">return</span> <span class="k">unless</span> <span class="nx">sources</span><span class="p">.</span><span class="nx">some</span> <span class="nf">(s, i) -&gt;</span> <span class="nx">prevSources</span><span class="p">[</span><span class="nx">i</span><span class="p">]</span> <span class="o">isnt</span> <span class="nx">s</span>
<span class="nx">compileJoin</span><span class="p">()</span></pre></div> </td> </tr> <tr id="section-15"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-15">&#182;</a> </div> <p>Remove a file from our source list, and source code cache. Optionally remove
<span class="nx">compileJoin</span><span class="p">()</span></pre></div> </td> </tr> <tr id="section-14"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-14">&#182;</a> </div> <p>Remove a file from our source list, and source code cache. Optionally remove
the compiled JS version as well.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">removeSource = </span><span class="nf">(source, base, removeJs) -&gt;</span>
<span class="nv">index = </span><span class="nx">sources</span><span class="p">.</span><span class="nx">indexOf</span> <span class="nx">source</span>
<span class="nx">sources</span><span class="p">.</span><span class="nx">splice</span> <span class="nx">index</span><span class="p">,</span> <span class="mi">1</span>
@@ -209,12 +203,12 @@ the compiled JS version as well.</p> </td> <td class="co
<span class="k">if</span> <span class="nx">itExists</span>
<span class="nx">fs</span><span class="p">.</span><span class="nx">unlink</span> <span class="nx">jsPath</span><span class="p">,</span> <span class="nf">(err) -&gt;</span>
<span class="k">throw</span> <span class="nx">err</span> <span class="k">if</span> <span class="nx">err</span> <span class="o">and</span> <span class="nx">err</span><span class="p">.</span><span class="nx">code</span> <span class="o">isnt</span> <span class="s">&#39;ENOENT&#39;</span>
<span class="nx">timeLog</span> <span class="s">&quot;removed </span><span class="si">#{</span><span class="nx">source</span><span class="si">}</span><span class="s">&quot;</span></pre></div> </td> </tr> <tr id="section-16"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-16">&#182;</a> </div> <p>Get the corresponding output JavaScript path for a source file.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">outputPath = </span><span class="nf">(source, base) -&gt;</span>
<span class="nx">timeLog</span> <span class="s">&quot;removed </span><span class="si">#{</span><span class="nx">source</span><span class="si">}</span><span class="s">&quot;</span></pre></div> </td> </tr> <tr id="section-15"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-15">&#182;</a> </div> <p>Get the corresponding output JavaScript path for a source file.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">outputPath = </span><span class="nf">(source, base) -&gt;</span>
<span class="nv">filename = </span><span class="nx">path</span><span class="p">.</span><span class="nx">basename</span><span class="p">(</span><span class="nx">source</span><span class="p">,</span> <span class="nx">path</span><span class="p">.</span><span class="nx">extname</span><span class="p">(</span><span class="nx">source</span><span class="p">))</span> <span class="o">+</span> <span class="s">&#39;.js&#39;</span>
<span class="nv">srcDir = </span><span class="nx">path</span><span class="p">.</span><span class="nx">dirname</span> <span class="nx">source</span>
<span class="nv">baseDir = </span><span class="k">if</span> <span class="nx">base</span> <span class="o">is</span> <span class="s">&#39;.&#39;</span> <span class="k">then</span> <span class="nx">srcDir</span> <span class="k">else</span> <span class="nx">srcDir</span><span class="p">.</span><span class="nx">substring</span> <span class="nx">base</span><span class="p">.</span><span class="nx">length</span>
<span class="nv">dir = </span><span class="k">if</span> <span class="nx">opts</span><span class="p">.</span><span class="nx">output</span> <span class="k">then</span> <span class="nx">path</span><span class="p">.</span><span class="nx">join</span> <span class="nx">opts</span><span class="p">.</span><span class="nx">output</span><span class="p">,</span> <span class="nx">baseDir</span> <span class="k">else</span> <span class="nx">srcDir</span>
<span class="nx">path</span><span class="p">.</span><span class="nx">join</span> <span class="nx">dir</span><span class="p">,</span> <span class="nx">filename</span></pre></div> </td> </tr> <tr id="section-17"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-17">&#182;</a> </div> <p>Write out a JavaScript source file with the compiled code. By default, files
<span class="nx">path</span><span class="p">.</span><span class="nx">join</span> <span class="nx">dir</span><span class="p">,</span> <span class="nx">filename</span></pre></div> </td> </tr> <tr id="section-16"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-16">&#182;</a> </div> <p>Write out a JavaScript source file with the compiled code. By default, files
are written out in <code>cwd</code> as <code>.js</code> files with the same name, but the output
directory can be customized with <code>--output</code>.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">writeJs = </span><span class="nf">(source, js, base) -&gt;</span>
<span class="nv">jsPath = </span><span class="nx">outputPath</span> <span class="nx">source</span><span class="p">,</span> <span class="nx">base</span>
@@ -227,8 +221,8 @@ directory can be customized with <code>--output</code>.</p> </td>
<span class="k">else</span> <span class="k">if</span> <span class="nx">opts</span><span class="p">.</span><span class="nx">compile</span> <span class="o">and</span> <span class="nx">opts</span><span class="p">.</span><span class="nx">watch</span>
<span class="nx">timeLog</span> <span class="s">&quot;compiled </span><span class="si">#{</span><span class="nx">source</span><span class="si">}</span><span class="s">&quot;</span>
<span class="nx">exists</span> <span class="nx">jsDir</span><span class="p">,</span> <span class="nf">(itExists) -&gt;</span>
<span class="k">if</span> <span class="nx">itExists</span> <span class="k">then</span> <span class="nx">compile</span><span class="p">()</span> <span class="k">else</span> <span class="nx">exec</span> <span class="s">&quot;mkdir -p </span><span class="si">#{</span><span class="nx">jsDir</span><span class="si">}</span><span class="s">&quot;</span><span class="p">,</span> <span class="nx">compile</span></pre></div> </td> </tr> <tr id="section-18"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-18">&#182;</a> </div> <p>Convenience for cleaner setTimeouts.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">wait = </span><span class="nf">(milliseconds, func) -&gt;</span> <span class="nx">setTimeout</span> <span class="nx">func</span><span class="p">,</span> <span class="nx">milliseconds</span></pre></div> </td> </tr> <tr id="section-19"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-19">&#182;</a> </div> <p>When watching scripts, it's useful to log changes with the timestamp.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">timeLog = </span><span class="nf">(message) -&gt;</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span> <span class="s">&quot;</span><span class="si">#{</span><span class="p">(</span><span class="k">new</span> <span class="nb">Date</span><span class="p">).</span><span class="nx">toLocaleTimeString</span><span class="p">()</span><span class="si">}</span><span class="s"> - </span><span class="si">#{</span><span class="nx">message</span><span class="si">}</span><span class="s">&quot;</span></pre></div> </td> </tr> <tr id="section-20"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-20">&#182;</a> </div> <p>Pipe compiled JS through JSLint (requires a working <code>jsl</code> command), printing
<span class="k">if</span> <span class="nx">itExists</span> <span class="k">then</span> <span class="nx">compile</span><span class="p">()</span> <span class="k">else</span> <span class="nx">exec</span> <span class="s">&quot;mkdir -p </span><span class="si">#{</span><span class="nx">jsDir</span><span class="si">}</span><span class="s">&quot;</span><span class="p">,</span> <span class="nx">compile</span></pre></div> </td> </tr> <tr id="section-17"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-17">&#182;</a> </div> <p>Convenience for cleaner setTimeouts.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">wait = </span><span class="nf">(milliseconds, func) -&gt;</span> <span class="nx">setTimeout</span> <span class="nx">func</span><span class="p">,</span> <span class="nx">milliseconds</span></pre></div> </td> </tr> <tr id="section-18"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-18">&#182;</a> </div> <p>When watching scripts, it's useful to log changes with the timestamp.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">timeLog = </span><span class="nf">(message) -&gt;</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span> <span class="s">&quot;</span><span class="si">#{</span><span class="p">(</span><span class="k">new</span> <span class="nb">Date</span><span class="p">).</span><span class="nx">toLocaleTimeString</span><span class="p">()</span><span class="si">}</span><span class="s"> - </span><span class="si">#{</span><span class="nx">message</span><span class="si">}</span><span class="s">&quot;</span></pre></div> </td> </tr> <tr id="section-19"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-19">&#182;</a> </div> <p>Pipe compiled JS through JSLint (requires a working <code>jsl</code> command), printing
any errors or warnings that arise.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">lint = </span><span class="nf">(file, js) -&gt;</span>
<span class="nv">printIt = </span><span class="nf">(buffer) -&gt;</span> <span class="nx">printLine</span> <span class="nx">file</span> <span class="o">+</span> <span class="s">&#39;:\t&#39;</span> <span class="o">+</span> <span class="nx">buffer</span><span class="p">.</span><span class="nx">toString</span><span class="p">().</span><span class="nx">trim</span><span class="p">()</span>
<span class="nv">conf = </span><span class="nx">__dirname</span> <span class="o">+</span> <span class="s">&#39;/../../extras/jsl.conf&#39;</span>
@@ -236,11 +230,13 @@ any errors or warnings that arise.</p> </td> <td class="
<span class="nx">jsl</span><span class="p">.</span><span class="nx">stdout</span><span class="p">.</span><span class="nx">on</span> <span class="s">&#39;data&#39;</span><span class="p">,</span> <span class="nx">printIt</span>
<span class="nx">jsl</span><span class="p">.</span><span class="nx">stderr</span><span class="p">.</span><span class="nx">on</span> <span class="s">&#39;data&#39;</span><span class="p">,</span> <span class="nx">printIt</span>
<span class="nx">jsl</span><span class="p">.</span><span class="nx">stdin</span><span class="p">.</span><span class="nx">write</span> <span class="nx">js</span>
<span class="nx">jsl</span><span class="p">.</span><span class="nx">stdin</span><span class="p">.</span><span class="nx">end</span><span class="p">()</span></pre></div> </td> </tr> <tr id="section-21"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-21">&#182;</a> </div> <p>Pretty-print a stream of tokens.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">printTokens = </span><span class="nf">(tokens) -&gt;</span>
<span class="nx">jsl</span><span class="p">.</span><span class="nx">stdin</span><span class="p">.</span><span class="nx">end</span><span class="p">()</span></pre></div> </td> </tr> <tr id="section-20"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-20">&#182;</a> </div> <p>Pretty-print a stream of tokens.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">printTokens = </span><span class="nf">(tokens) -&gt;</span>
<span class="nv">strings = </span><span class="k">for</span> <span class="nx">token</span> <span class="k">in</span> <span class="nx">tokens</span>
<span class="p">[</span><span class="nx">tag</span><span class="p">,</span> <span class="nx">value</span><span class="p">]</span> <span class="o">=</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">token</span><span class="p">[</span><span class="mi">1</span><span class="p">].</span><span class="nx">toString</span><span class="p">().</span><span class="nx">replace</span><span class="p">(</span><span class="sr">/\n/</span><span class="p">,</span> <span class="s">&#39;\\n&#39;</span><span class="p">)]</span>
<span class="s">&quot;[</span><span class="si">#{</span><span class="nx">tag</span><span class="si">}</span><span class="s"> </span><span class="si">#{</span><span class="nx">value</span><span class="si">}</span><span class="s">]&quot;</span>
<span class="nx">printLine</span> <span class="nx">strings</span><span class="p">.</span><span class="nx">join</span><span class="p">(</span><span class="s">&#39; &#39;</span><span class="p">)</span></pre></div> </td> </tr> <tr id="section-22"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-22">&#182;</a> </div> <p>Use the <a href="optparse.html">OptionParser module</a> to extract all options from
<span class="nv">tag = </span><span class="nx">token</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="nv">value = </span><span class="nx">token</span><span class="p">[</span><span class="mi">1</span><span class="p">].</span><span class="nx">toString</span><span class="p">().</span><span class="nx">replace</span><span class="p">(</span><span class="sr">/\n/</span><span class="p">,</span> <span class="s">&#39;\\n&#39;</span><span class="p">)</span>
<span class="nv">locationData = </span><span class="nx">helpers</span><span class="p">.</span><span class="nx">locationDataToString</span> <span class="nx">token</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span>
<span class="s">&quot;[</span><span class="si">#{</span><span class="nx">tag</span><span class="si">}</span><span class="s"> </span><span class="si">#{</span><span class="nx">value</span><span class="si">}</span><span class="s"> </span><span class="si">#{</span><span class="nx">locationData</span><span class="si">}</span><span class="s">]&quot;</span>
<span class="nx">printLine</span> <span class="nx">strings</span><span class="p">.</span><span class="nx">join</span><span class="p">(</span><span class="s">&#39; &#39;</span><span class="p">)</span></pre></div> </td> </tr> <tr id="section-21"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-21">&#182;</a> </div> <p>Use the <a href="optparse.html">OptionParser module</a> to extract all options from
<code>process.argv</code> that are specified in <code>SWITCHES</code>.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">parseOptions = </span><span class="nf">-&gt;</span>
<span class="nv">optionParser = </span><span class="k">new</span> <span class="nx">optparse</span><span class="p">.</span><span class="nx">OptionParser</span> <span class="nx">SWITCHES</span><span class="p">,</span> <span class="nx">BANNER</span>
<span class="nv">o = opts = </span><span class="nx">optionParser</span><span class="p">.</span><span class="nx">parse</span> <span class="nx">process</span><span class="p">.</span><span class="nx">argv</span><span class="p">[</span><span class="mi">2</span><span class="p">..]</span>
@@ -249,8 +245,9 @@ any errors or warnings that arise.</p> </td> <td class="
<span class="nv">o.print = </span><span class="o">!!</span> <span class="p">(</span><span class="nx">o</span><span class="p">.</span><span class="nx">print</span> <span class="o">or</span> <span class="p">(</span><span class="nx">o</span><span class="p">.</span><span class="nb">eval</span> <span class="o">or</span> <span class="nx">o</span><span class="p">.</span><span class="nx">stdio</span> <span class="o">and</span> <span class="nx">o</span><span class="p">.</span><span class="nx">compile</span><span class="p">))</span>
<span class="nv">sources = </span><span class="nx">o</span><span class="p">.</span><span class="nx">arguments</span>
<span class="nx">sourceCode</span><span class="p">[</span><span class="nx">i</span><span class="p">]</span> <span class="o">=</span> <span class="kc">null</span> <span class="k">for</span> <span class="nx">source</span><span class="p">,</span> <span class="nx">i</span> <span class="k">in</span> <span class="nx">sources</span>
<span class="k">return</span></pre></div> </td> </tr> <tr id="section-23"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-23">&#182;</a> </div> <p>The compile-time options to pass to the CoffeeScript compiler.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">compileOptions = </span><span class="nf">(filename) -&gt;</span>
<span class="p">{</span><span class="nx">filename</span><span class="p">,</span> <span class="nv">bare: </span><span class="nx">opts</span><span class="p">.</span><span class="nx">bare</span><span class="p">,</span> <span class="nv">header: </span><span class="nx">opts</span><span class="p">.</span><span class="nx">compile</span><span class="p">}</span></pre></div> </td> </tr> <tr id="section-24"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-24">&#182;</a> </div> <p>Start up a new Node.js instance with the arguments in <code>--nodejs</code> passed to
<span class="k">return</span></pre></div> </td> </tr> <tr id="section-22"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-22">&#182;</a> </div> <p>The compile-time options to pass to the CoffeeScript compiler.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">compileOptions = </span><span class="nf">(filename) -&gt;</span>
<span class="nv">literate = </span><span class="nx">path</span><span class="p">.</span><span class="nx">extname</span><span class="p">(</span><span class="nx">filename</span><span class="p">)</span> <span class="o">is</span> <span class="s">&#39;.litcoffee&#39;</span>
<span class="p">{</span><span class="nx">filename</span><span class="p">,</span> <span class="nx">literate</span><span class="p">,</span> <span class="nv">bare: </span><span class="nx">opts</span><span class="p">.</span><span class="nx">bare</span><span class="p">,</span> <span class="nv">header: </span><span class="nx">opts</span><span class="p">.</span><span class="nx">compile</span><span class="p">}</span></pre></div> </td> </tr> <tr id="section-23"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-23">&#182;</a> </div> <p>Start up a new Node.js instance with the arguments in <code>--nodejs</code> passed to
the <code>node</code> binary, preserving the other options.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">forkNode = </span><span class="nf">-&gt;</span>
<span class="nv">nodeArgs = </span><span class="nx">opts</span><span class="p">.</span><span class="nx">nodejs</span><span class="p">.</span><span class="nx">split</span> <span class="sr">/\s+/</span>
<span class="nv">args = </span><span class="nx">process</span><span class="p">.</span><span class="nx">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">..]</span>
@@ -258,9 +255,9 @@ the <code>node</code> binary, preserving the other options.</p> </td
<span class="nx">spawn</span> <span class="nx">process</span><span class="p">.</span><span class="nx">execPath</span><span class="p">,</span> <span class="nx">nodeArgs</span><span class="p">.</span><span class="nx">concat</span><span class="p">(</span><span class="nx">args</span><span class="p">),</span>
<span class="nv">cwd: </span> <span class="nx">process</span><span class="p">.</span><span class="nx">cwd</span><span class="p">()</span>
<span class="nv">env: </span> <span class="nx">process</span><span class="p">.</span><span class="nx">env</span>
<span class="nv">customFds: </span> <span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-25"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-25">&#182;</a> </div> <p>Print the <code>--help</code> usage message and exit. Deprecated switches are not
<span class="nv">customFds: </span> <span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-24"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-24">&#182;</a> </div> <p>Print the <code>--help</code> usage message and exit. Deprecated switches are not
shown.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">usage = </span><span class="nf">-&gt;</span>
<span class="nx">printLine</span> <span class="p">(</span><span class="k">new</span> <span class="nx">optparse</span><span class="p">.</span><span class="nx">OptionParser</span> <span class="nx">SWITCHES</span><span class="p">,</span> <span class="nx">BANNER</span><span class="p">).</span><span class="nx">help</span><span class="p">()</span></pre></div> </td> </tr> <tr id="section-26"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-26">&#182;</a> </div> <p>Print the <code>--version</code> message and exit.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">version = </span><span class="nf">-&gt;</span>
<span class="nx">printLine</span> <span class="p">(</span><span class="k">new</span> <span class="nx">optparse</span><span class="p">.</span><span class="nx">OptionParser</span> <span class="nx">SWITCHES</span><span class="p">,</span> <span class="nx">BANNER</span><span class="p">).</span><span class="nx">help</span><span class="p">()</span></pre></div> </td> </tr> <tr id="section-25"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-25">&#182;</a> </div> <p>Print the <code>--version</code> message and exit.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">version = </span><span class="nf">-&gt;</span>
<span class="nx">printLine</span> <span class="s">&quot;CoffeeScript version </span><span class="si">#{</span><span class="nx">CoffeeScript</span><span class="p">.</span><span class="nx">VERSION</span><span class="si">}</span><span class="s">&quot;</span>
</pre></div> </td> </tr> </tbody> </table> </div> </body> </html>

View File

@@ -1,4 +1,4 @@
<!DOCTYPE html> <html> <head> <title>grammar.coffee</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <link rel="stylesheet" media="all" href="docco.css" /> </head> <body> <div id="container"> <div id="background"></div> <div id="jump_to"> Jump To &hellip; <div id="jump_wrapper"> <div id="jump_page"> <a class="source" href="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> grammar.coffee </h1> </th> <th class="code"> </th> </tr> </thead> <tbody> <tr id="section-1"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-1">&#182;</a> </div> <p>The CoffeeScript parser is generated by <a href="http://github.com/zaach/jison">Jison</a>
<!DOCTYPE html> <html> <head> <title>grammar.coffee</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <link rel="stylesheet" media="all" href="docco.css" /> </head> <body> <div id="container"> <div id="background"></div> <div id="jump_to"> Jump To &hellip; <div id="jump_wrapper"> <div id="jump_page"> <a class="source" href="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> </div> </div> </div> <table cellpadding="0" cellspacing="0"> <thead> <tr> <th class="docs"> <h1> grammar.coffee </h1> </th> <th class="code"> </th> </tr> </thead> <tbody> <tr id="section-1"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-1">&#182;</a> </div> <p>The CoffeeScript parser is generated by <a href="http://github.com/zaach/jison">Jison</a>
from this grammar file. Jison is a bottom-up parser generator, similar in
style to <a href="http://www.gnu.org/software/bison">Bison</a>, implemented in JavaScript.
It can recognize <a href="http://en.wikipedia.org/wiki/LR_grammar">LALR(1), LR(0), SLR(1), and LR(1)</a>
@@ -20,11 +20,22 @@ we pass the pattern-defining string, the action to run, and extra options,
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="nf">(patternString, action, options) -&gt;</span>
<span class="nv">patternString = </span><span class="nx">patternString</span><span class="p">.</span><span class="nx">replace</span> <span class="sr">/\s{2,}/g</span><span class="p">,</span> <span class="s">&#39; &#39;</span>
<span class="nv">patternCount = </span><span class="nx">patternString</span><span class="p">.</span><span class="nx">split</span><span class="p">(</span><span class="s">&#39; &#39;</span><span class="p">).</span><span class="nx">length</span>
<span class="k">return</span> <span class="p">[</span><span class="nx">patternString</span><span class="p">,</span> <span class="s">&#39;$$ = $1;&#39;</span><span class="p">,</span> <span class="nx">options</span><span class="p">]</span> <span class="k">unless</span> <span class="nx">action</span>
<span class="nv">action = </span><span class="k">if</span> <span class="nv">match = </span><span class="nx">unwrap</span><span class="p">.</span><span class="nx">exec</span> <span class="nx">action</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="s">&quot;(</span><span class="si">#{</span><span class="nx">action</span><span class="si">}</span><span class="s">())&quot;</span>
<span class="nv">action = </span><span class="nx">action</span><span class="p">.</span><span class="nx">replace</span> <span class="sr">/\bnew /g</span><span class="p">,</span> <span class="s">&#39;$&amp;yy.&#39;</span>
<span class="nv">action = </span><span class="k">if</span> <span class="nv">match = </span><span class="nx">unwrap</span><span class="p">.</span><span class="nx">exec</span> <span class="nx">action</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="s">&quot;(</span><span class="si">#{</span><span class="nx">action</span><span class="si">}</span><span class="s">())&quot;</span></pre></div> </td> </tr> <tr id="section-6"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-6">&#182;</a> </div> <p>All runtime functions we need are defined on "yy"</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">action = </span><span class="nx">action</span><span class="p">.</span><span class="nx">replace</span> <span class="sr">/\bnew /g</span><span class="p">,</span> <span class="s">&#39;$&amp;yy.&#39;</span>
<span class="nv">action = </span><span class="nx">action</span><span class="p">.</span><span class="nx">replace</span> <span class="sr">/\b(?:Block\.wrap|extend)\b/g</span><span class="p">,</span> <span class="s">&#39;yy.$&amp;&#39;</span>
<span class="p">[</span><span class="nx">patternString</span><span class="p">,</span> <span class="s">&quot;$$ = </span><span class="si">#{</span><span class="nx">action</span><span class="si">}</span><span class="s">;&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="pilwrap"> <a class="pilcrow" href="#section-6">&#182;</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="pilwrap"> <a class="pilcrow" href="#section-7">&#182;</a> </div> <p>In all of the rules that follow, you'll see the name of the nonterminal as
<span class="nv">action = </span><span class="nx">action</span><span class="p">.</span><span class="nx">replace</span> <span class="sr">/\b(Op|Value\.(create|wrap))\b/g</span><span class="p">,</span> <span class="s">&#39;yy.$&amp;&#39;</span></pre></div> </td> </tr> <tr id="section-7"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-7">&#182;</a> </div> <p>Returns a function which adds location data to the first parameter passed
in, and returns the parameter. If the parameter is not a node, it will
just be passed through unaffected.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">addLocationDataFn = </span><span class="nf">(first, last) -&gt;</span>
<span class="k">if</span> <span class="o">not</span> <span class="nx">last</span>
<span class="s">&quot;yy.addLocationDataFn(@</span><span class="si">#{</span><span class="nx">first</span><span class="si">}</span><span class="s">)&quot;</span>
<span class="k">else</span>
<span class="s">&quot;yy.addLocationDataFn(@</span><span class="si">#{</span><span class="nx">first</span><span class="si">}</span><span class="s">, @</span><span class="si">#{</span><span class="nx">last</span><span class="si">}</span><span class="s">)&quot;</span>
<span class="nv">action = </span><span class="nx">action</span><span class="p">.</span><span class="nx">replace</span> <span class="sr">/LOC\(([0-9]*)\)/g</span><span class="p">,</span> <span class="nx">addLocationDataFn</span><span class="p">(</span><span class="s">&#39;$1&#39;</span><span class="p">)</span>
<span class="nv">action = </span><span class="nx">action</span><span class="p">.</span><span class="nx">replace</span> <span class="sr">/LOC\(([0-9]*),\s*([0-9]*)\)/g</span><span class="p">,</span> <span class="nx">addLocationDataFn</span><span class="p">(</span><span class="s">&#39;$1&#39;</span><span class="p">,</span> <span class="s">&#39;$2&#39;</span><span class="p">)</span>
<span class="p">[</span><span class="nx">patternString</span><span class="p">,</span> <span class="s">&quot;$$ = </span><span class="si">#{</span><span class="nx">addLocationDataFn</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="nx">patternCount</span><span class="p">)</span><span class="si">}</span><span class="s">(</span><span class="si">#{</span><span class="nx">action</span><span class="si">}</span><span class="s">);&quot;</span><span class="p">,</span> <span class="nx">options</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-8"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-8">&#182;</a> </div> <h2>Grammatical Rules</h2> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-9"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-9">&#182;</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
their numeric position, so in this rule:</p>
@@ -34,23 +45,23 @@ their numeric position, so in this rule:</p>
<p><code>$1</code> would be the value of the first <code>Expression</code>, <code>$2</code> would be the token
for the <code>UNLESS</code> terminal, and <code>$3</code> would be the value of the second
<code>Expression</code>.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">grammar =</span></pre></div> </td> </tr> <tr id="section-8"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-8">&#182;</a> </div> <p>The <strong>Root</strong> is the top-level node in the syntax tree. Since we parse bottom-up,
<code>Expression</code>.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">grammar =</span></pre></div> </td> </tr> <tr id="section-10"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-10">&#182;</a> </div> <p>The <strong>Root</strong> is the top-level node in the syntax tree. Since we parse bottom-up,
all parsing must end here.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Root: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s">&#39;&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Block</span>
<span class="nx">o</span> <span class="s">&#39;Body&#39;</span>
<span class="nx">o</span> <span class="s">&#39;Block TERMINATOR&#39;</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-9"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-9">&#182;</a> </div> <p>Any list of statements and expressions, separated by line breaks or semicolons.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Body: </span><span class="p">[</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-11"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-11">&#182;</a> </div> <p>Any list of statements and expressions, separated by line breaks or semicolons.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Body: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s">&#39;Line&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="nx">Block</span><span class="p">.</span><span class="nx">wrap</span> <span class="p">[</span><span class="nx">$1</span><span class="p">]</span>
<span class="nx">o</span> <span class="s">&#39;Body TERMINATOR Line&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="nx">$1</span><span class="p">.</span><span class="nx">push</span> <span class="nx">$3</span>
<span class="nx">o</span> <span class="s">&#39;Body TERMINATOR&#39;</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-10"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-10">&#182;</a> </div> <p>Block and statements, which make up a line in a body.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Line: </span><span class="p">[</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-12"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-12">&#182;</a> </div> <p>Block and statements, which make up a line in a body.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Line: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s">&#39;Expression&#39;</span>
<span class="nx">o</span> <span class="s">&#39;Statement&#39;</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-11"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-11">&#182;</a> </div> <p>Pure statements which cannot be expressions.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Statement: </span><span class="p">[</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-13"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-13">&#182;</a> </div> <p>Pure statements which cannot be expressions.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Statement: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s">&#39;Return&#39;</span>
<span class="nx">o</span> <span class="s">&#39;Comment&#39;</span>
<span class="nx">o</span> <span class="s">&#39;STATEMENT&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Literal</span> <span class="nx">$1</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-12"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-12">&#182;</a> </div> <p>All the different types of expressions in our language. The basic unit of
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-14"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-14">&#182;</a> </div> <p>All the different types of expressions in our language. The basic unit of
CoffeeScript is the <strong>Expression</strong> -- everything that can be an expression
is one. Blocks serve as the building blocks of many other rules, making
them somewhat circular.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Expression: </span><span class="p">[</span>
@@ -66,18 +77,18 @@ them somewhat circular.</p> </td> <td class="code">
<span class="nx">o</span> <span class="s">&#39;Switch&#39;</span>
<span class="nx">o</span> <span class="s">&#39;Class&#39;</span>
<span class="nx">o</span> <span class="s">&#39;Throw&#39;</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-13"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-13">&#182;</a> </div> <p>An indented block of expressions. Note that the <a href="rewriter.html">Rewriter</a>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-15"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-15">&#182;</a> </div> <p>An indented block of expressions. Note that the <a href="rewriter.html">Rewriter</a>
will convert some postfix forms into blocks for us, by adjusting the
token stream.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Block: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s">&#39;INDENT OUTDENT&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Block</span>
<span class="nx">o</span> <span class="s">&#39;INDENT Body OUTDENT&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="nx">$2</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-14"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-14">&#182;</a> </div> <p>A literal identifier, a variable name or property.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Identifier: </span><span class="p">[</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-16"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-16">&#182;</a> </div> <p>A literal identifier, a variable name or property.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Identifier: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s">&#39;IDENTIFIER&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Literal</span> <span class="nx">$1</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-15"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-15">&#182;</a> </div> <p>Alphanumerics are separated from the other <strong>Literal</strong> matchers because
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-17"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-17">&#182;</a> </div> <p>Alphanumerics are separated from the other <strong>Literal</strong> matchers because
they can also serve as keys in object literals.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">AlphaNumeric: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s">&#39;NUMBER&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Literal</span> <span class="nx">$1</span>
<span class="nx">o</span> <span class="s">&#39;STRING&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Literal</span> <span class="nx">$1</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-16"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-16">&#182;</a> </div> <p>All of our immediate values. Generally these can be passed straight
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-18"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-18">&#182;</a> </div> <p>All of our immediate values. Generally these can be passed straight
through and printed to JavaScript.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Literal: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s">&#39;AlphaNumeric&#39;</span>
<span class="nx">o</span> <span class="s">&#39;JS&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Literal</span> <span class="nx">$1</span>
@@ -86,16 +97,16 @@ through and printed to JavaScript.</p> </td> <td class="
<span class="nx">o</span> <span class="s">&#39;UNDEFINED&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Undefined</span>
<span class="nx">o</span> <span class="s">&#39;NULL&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Null</span>
<span class="nx">o</span> <span class="s">&#39;BOOL&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Bool</span> <span class="nx">$1</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-17"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-17">&#182;</a> </div> <p>Assignment of a variable, property, or index to a value.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Assign: </span><span class="p">[</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-19"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-19">&#182;</a> </div> <p>Assignment of a variable, property, or index to a value.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Assign: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s">&#39;Assignable = Expression&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Assign</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$3</span>
<span class="nx">o</span> <span class="s">&#39;Assignable = TERMINATOR Expression&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Assign</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$4</span>
<span class="nx">o</span> <span class="s">&#39;Assignable = INDENT Expression OUTDENT&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Assign</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$4</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-18"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-18">&#182;</a> </div> <p>Assignment when it happens within an object literal. The difference from
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-20"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-20">&#182;</a> </div> <p>Assignment when it happens within an object literal. The difference from
the ordinary <strong>Assign</strong> is that these allow numbers and strings as keys.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">AssignObj: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s">&#39;ObjAssignable&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Value</span> <span class="nx">$1</span>
<span class="nx">o</span> <span class="s">&#39;ObjAssignable : Expression&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Assign</span> <span class="k">new</span> <span class="nx">Value</span><span class="p">(</span><span class="nx">$1</span><span class="p">),</span> <span class="nx">$3</span><span class="p">,</span> <span class="s">&#39;object&#39;</span>
<span class="nx">o</span> <span class="s">&#39;ObjAssignable&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="nx">Value</span><span class="p">.</span><span class="nx">wrap</span> <span class="nx">$1</span>
<span class="nx">o</span> <span class="s">&#39;ObjAssignable : Expression&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Assign</span> <span class="nx">LOC</span><span class="p">(</span><span class="mi">1</span><span class="p">)(</span><span class="nx">Value</span><span class="p">.</span><span class="nx">wrap</span><span class="p">(</span><span class="nx">$1</span><span class="p">)),</span> <span class="nx">$3</span><span class="p">,</span> <span class="s">&#39;object&#39;</span>
<span class="nx">o</span> <span class="s">&#39;ObjAssignable :</span>
<span class="s"> INDENT Expression OUTDENT&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Assign</span> <span class="k">new</span> <span class="nx">Value</span><span class="p">(</span><span class="nx">$1</span><span class="p">),</span> <span class="nx">$4</span><span class="p">,</span> <span class="s">&#39;object&#39;</span>
<span class="s"> INDENT Expression OUTDENT&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Assign</span> <span class="nx">LOC</span><span class="p">(</span><span class="mi">1</span><span class="p">)(</span><span class="nx">Value</span><span class="p">.</span><span class="nx">wrap</span><span class="p">(</span><span class="nx">$1</span><span class="p">)),</span> <span class="nx">$4</span><span class="p">,</span> <span class="s">&#39;object&#39;</span>
<span class="nx">o</span> <span class="s">&#39;Comment&#39;</span>
<span class="p">]</span>
@@ -103,65 +114,65 @@ the ordinary <strong>Assign</strong> is that these allow numbers and strings as
<span class="nx">o</span> <span class="s">&#39;Identifier&#39;</span>
<span class="nx">o</span> <span class="s">&#39;AlphaNumeric&#39;</span>
<span class="nx">o</span> <span class="s">&#39;ThisProperty&#39;</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-19"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-19">&#182;</a> </div> <p>A return statement from a function body.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Return: </span><span class="p">[</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-21"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-21">&#182;</a> </div> <p>A return statement from a function body.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Return: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s">&#39;RETURN Expression&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Return</span> <span class="nx">$2</span>
<span class="nx">o</span> <span class="s">&#39;RETURN&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Return</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-20"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-20">&#182;</a> </div> <p>A block comment.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Comment: </span><span class="p">[</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-22"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-22">&#182;</a> </div> <p>A block comment.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Comment: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s">&#39;HERECOMMENT&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Comment</span> <span class="nx">$1</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-21"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-21">&#182;</a> </div> <p>The <strong>Code</strong> node is the function literal. It's defined by an indented block
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-23"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-23">&#182;</a> </div> <p>The <strong>Code</strong> node is the function literal. It's defined by an indented block
of <strong>Block</strong> preceded by a function arrow, with an optional parameter
list.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Code: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s">&#39;PARAM_START ParamList PARAM_END FuncGlyph Block&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Code</span> <span class="nx">$2</span><span class="p">,</span> <span class="nx">$5</span><span class="p">,</span> <span class="nx">$4</span>
<span class="nx">o</span> <span class="s">&#39;FuncGlyph Block&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Code</span> <span class="p">[],</span> <span class="nx">$2</span><span class="p">,</span> <span class="nx">$1</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-22"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-22">&#182;</a> </div> <p>CoffeeScript has two different symbols for functions. <code>-&gt;</code> is for ordinary
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-24"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-24">&#182;</a> </div> <p>CoffeeScript has two different symbols for functions. <code>-&gt;</code> is for ordinary
functions, and <code>=&gt;</code> is for functions bound to the current value of <em>this</em>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">FuncGlyph: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s">&#39;-&gt;&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="s">&#39;func&#39;</span>
<span class="nx">o</span> <span class="s">&#39;=&gt;&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="s">&#39;boundfunc&#39;</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-23"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-23">&#182;</a> </div> <p>An optional, trailing comma.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">OptComma: </span><span class="p">[</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-25"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-25">&#182;</a> </div> <p>An optional, trailing comma.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">OptComma: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s">&#39;&#39;</span>
<span class="nx">o</span> <span class="s">&#39;,&#39;</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-24"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-24">&#182;</a> </div> <p>The list of parameters that a function accepts can be of any length.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">ParamList: </span><span class="p">[</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-26"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-26">&#182;</a> </div> <p>The list of parameters that a function accepts can be of any length.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">ParamList: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s">&#39;&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="p">[]</span>
<span class="nx">o</span> <span class="s">&#39;Param&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="p">[</span><span class="nx">$1</span><span class="p">]</span>
<span class="nx">o</span> <span class="s">&#39;ParamList , Param&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="nx">$1</span><span class="p">.</span><span class="nx">concat</span> <span class="nx">$3</span>
<span class="nx">o</span> <span class="s">&#39;ParamList OptComma TERMINATOR Param&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="nx">$1</span><span class="p">.</span><span class="nx">concat</span> <span class="nx">$4</span>
<span class="nx">o</span> <span class="s">&#39;ParamList OptComma INDENT ParamList OptComma OUTDENT&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="nx">$1</span><span class="p">.</span><span class="nx">concat</span> <span class="nx">$4</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-25"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-25">&#182;</a> </div> <p>A single parameter in a function definition can be ordinary, or a splat
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-27"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-27">&#182;</a> </div> <p>A single parameter in a function definition can be ordinary, or a splat
that hoovers up the remaining arguments.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Param: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s">&#39;ParamVar&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Param</span> <span class="nx">$1</span>
<span class="nx">o</span> <span class="s">&#39;ParamVar ...&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Param</span> <span class="nx">$1</span><span class="p">,</span> <span class="kc">null</span><span class="p">,</span> <span class="kc">on</span>
<span class="nx">o</span> <span class="s">&#39;ParamVar = Expression&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Param</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$3</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-26"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-26">&#182;</a> </div> <p>Function Parameters</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">ParamVar: </span><span class="p">[</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-28"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-28">&#182;</a> </div> <p>Function Parameters</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">ParamVar: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s">&#39;Identifier&#39;</span>
<span class="nx">o</span> <span class="s">&#39;ThisProperty&#39;</span>
<span class="nx">o</span> <span class="s">&#39;Array&#39;</span>
<span class="nx">o</span> <span class="s">&#39;Object&#39;</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-27"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-27">&#182;</a> </div> <p>A splat that occurs outside of a parameter list.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Splat: </span><span class="p">[</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-29"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-29">&#182;</a> </div> <p>A splat that occurs outside of a parameter list.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Splat: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s">&#39;Expression ...&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Splat</span> <span class="nx">$1</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-28"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-28">&#182;</a> </div> <p>Variables and properties that can be assigned to.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">SimpleAssignable: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s">&#39;Identifier&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Value</span> <span class="nx">$1</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-30"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-30">&#182;</a> </div> <p>Variables and properties that can be assigned to.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">SimpleAssignable: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s">&#39;Identifier&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="nx">Value</span><span class="p">.</span><span class="nx">wrap</span> <span class="nx">$1</span>
<span class="nx">o</span> <span class="s">&#39;Value Accessor&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="nx">$1</span><span class="p">.</span><span class="nx">add</span> <span class="nx">$2</span>
<span class="nx">o</span> <span class="s">&#39;Invocation Accessor&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Value</span> <span class="nx">$1</span><span class="p">,</span> <span class="p">[].</span><span class="nx">concat</span> <span class="nx">$2</span>
<span class="nx">o</span> <span class="s">&#39;Invocation Accessor&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="nx">Value</span><span class="p">.</span><span class="nx">wrap</span> <span class="nx">$1</span><span class="p">,</span> <span class="p">[].</span><span class="nx">concat</span> <span class="nx">$2</span>
<span class="nx">o</span> <span class="s">&#39;ThisProperty&#39;</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-29"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-29">&#182;</a> </div> <p>Everything that can be assigned to.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Assignable: </span><span class="p">[</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-31"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-31">&#182;</a> </div> <p>Everything that can be assigned to.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Assignable: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s">&#39;SimpleAssignable&#39;</span>
<span class="nx">o</span> <span class="s">&#39;Array&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Value</span> <span class="nx">$1</span>
<span class="nx">o</span> <span class="s">&#39;Object&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Value</span> <span class="nx">$1</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-30"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-30">&#182;</a> </div> <p>The types of things that can be treated as values -- assigned to, invoked
<span class="nx">o</span> <span class="s">&#39;Array&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="nx">Value</span><span class="p">.</span><span class="nx">wrap</span> <span class="nx">$1</span>
<span class="nx">o</span> <span class="s">&#39;Object&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="nx">Value</span><span class="p">.</span><span class="nx">wrap</span> <span class="nx">$1</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-32"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-32">&#182;</a> </div> <p>The types of things that can be treated as values -- assigned to, invoked
as functions, indexed into, named as a class, etc.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Value: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s">&#39;Assignable&#39;</span>
<span class="nx">o</span> <span class="s">&#39;Literal&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Value</span> <span class="nx">$1</span>
<span class="nx">o</span> <span class="s">&#39;Parenthetical&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Value</span> <span class="nx">$1</span>
<span class="nx">o</span> <span class="s">&#39;Range&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Value</span> <span class="nx">$1</span>
<span class="nx">o</span> <span class="s">&#39;Literal&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="nx">Value</span><span class="p">.</span><span class="nx">wrap</span> <span class="nx">$1</span>
<span class="nx">o</span> <span class="s">&#39;Parenthetical&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="nx">Value</span><span class="p">.</span><span class="nx">wrap</span> <span class="nx">$1</span>
<span class="nx">o</span> <span class="s">&#39;Range&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="nx">Value</span><span class="p">.</span><span class="nx">wrap</span> <span class="nx">$1</span>
<span class="nx">o</span> <span class="s">&#39;This&#39;</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-31"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-31">&#182;</a> </div> <p>The general group of accessors into an object, by property, by prototype
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-33"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-33">&#182;</a> </div> <p>The general group of accessors into an object, by property, by prototype
or by array index or slice.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Accessor: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s">&#39;. Identifier&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Access</span> <span class="nx">$2</span>
<span class="nx">o</span> <span class="s">&#39;?. Identifier&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Access</span> <span class="nx">$2</span><span class="p">,</span> <span class="s">&#39;soak&#39;</span>
<span class="nx">o</span> <span class="s">&#39;:: Identifier&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="p">[(</span><span class="k">new</span> <span class="nx">Access</span> <span class="k">new</span> <span class="nx">Literal</span> <span class="s">&#39;prototype&#39;</span><span class="p">),</span> <span class="k">new</span> <span class="nx">Access</span> <span class="nx">$2</span><span class="p">]</span>
<span class="nx">o</span> <span class="s">&#39;:: Identifier&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="p">[</span><span class="nx">LOC</span><span class="p">(</span><span class="mi">1</span><span class="p">)(</span><span class="k">new</span> <span class="nx">Access</span> <span class="k">new</span> <span class="nx">Literal</span> <span class="s">&#39;prototype&#39;</span><span class="p">),</span> <span class="nx">LOC</span><span class="p">(</span><span class="mi">2</span><span class="p">)(</span><span class="k">new</span> <span class="nx">Access</span> <span class="nx">$2</span><span class="p">)]</span>
<span class="nx">o</span> <span class="s">&#39;::&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Access</span> <span class="k">new</span> <span class="nx">Literal</span> <span class="s">&#39;prototype&#39;</span>
<span class="nx">o</span> <span class="s">&#39;Index&#39;</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-32"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-32">&#182;</a> </div> <p>Indexing into an object or array using bracket notation.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Index: </span><span class="p">[</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-34"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-34">&#182;</a> </div> <p>Indexing into an object or array using bracket notation.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Index: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s">&#39;INDEX_START IndexValue INDEX_END&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="nx">$2</span>
<span class="nx">o</span> <span class="s">&#39;INDEX_SOAK Index&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="nx">extend</span> <span class="nx">$2</span><span class="p">,</span> <span class="nv">soak : </span><span class="kc">yes</span>
<span class="p">]</span>
@@ -169,16 +180,16 @@ or by array index or slice.</p> </td> <td class="code">
<span class="nv">IndexValue: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s">&#39;Expression&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Index</span> <span class="nx">$1</span>
<span class="nx">o</span> <span class="s">&#39;Slice&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Slice</span> <span class="nx">$1</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-33"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-33">&#182;</a> </div> <p>In CoffeeScript, an object literal is simply a list of assignments.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nb">Object</span><span class="o">:</span> <span class="p">[</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-35"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-35">&#182;</a> </div> <p>In CoffeeScript, an object literal is simply a list of assignments.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nb">Object</span><span class="o">:</span> <span class="p">[</span>
<span class="nx">o</span> <span class="s">&#39;{ AssignList OptComma }&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Obj</span> <span class="nx">$2</span><span class="p">,</span> <span class="nx">$1</span><span class="p">.</span><span class="nx">generated</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-34"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-34">&#182;</a> </div> <p>Assignment of properties within an object literal can be separated by
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-36"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-36">&#182;</a> </div> <p>Assignment of properties within an object literal can be separated by
comma, as in JavaScript, or simply by newline.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">AssignList: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s">&#39;&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="p">[]</span>
<span class="nx">o</span> <span class="s">&#39;AssignObj&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="p">[</span><span class="nx">$1</span><span class="p">]</span>
<span class="nx">o</span> <span class="s">&#39;AssignList , AssignObj&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="nx">$1</span><span class="p">.</span><span class="nx">concat</span> <span class="nx">$3</span>
<span class="nx">o</span> <span class="s">&#39;AssignList OptComma TERMINATOR AssignObj&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="nx">$1</span><span class="p">.</span><span class="nx">concat</span> <span class="nx">$4</span>
<span class="nx">o</span> <span class="s">&#39;AssignList OptComma INDENT AssignList OptComma OUTDENT&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="nx">$1</span><span class="p">.</span><span class="nx">concat</span> <span class="nx">$4</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-35"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-35">&#182;</a> </div> <p>Class definitions have optional bodies of prototype property assignments,
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-37"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-37">&#182;</a> </div> <p>Class definitions have optional bodies of prototype property assignments,
and optional references to the superclass.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Class: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s">&#39;CLASS&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Class</span>
<span class="nx">o</span> <span class="s">&#39;CLASS Block&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Class</span> <span class="kc">null</span><span class="p">,</span> <span class="kc">null</span><span class="p">,</span> <span class="nx">$2</span>
@@ -188,36 +199,36 @@ and optional references to the superclass.</p> </td> <td
<span class="nx">o</span> <span class="s">&#39;CLASS SimpleAssignable Block&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Class</span> <span class="nx">$2</span><span class="p">,</span> <span class="kc">null</span><span class="p">,</span> <span class="nx">$3</span>
<span class="nx">o</span> <span class="s">&#39;CLASS SimpleAssignable EXTENDS Expression&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Class</span> <span class="nx">$2</span><span class="p">,</span> <span class="nx">$4</span>
<span class="nx">o</span> <span class="s">&#39;CLASS SimpleAssignable EXTENDS Expression Block&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Class</span> <span class="nx">$2</span><span class="p">,</span> <span class="nx">$4</span><span class="p">,</span> <span class="nx">$5</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-36"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-36">&#182;</a> </div> <p>Ordinary function invocation, or a chained series of calls.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Invocation: </span><span class="p">[</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-38"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-38">&#182;</a> </div> <p>Ordinary function invocation, or a chained series of calls.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Invocation: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s">&#39;Value OptFuncExist Arguments&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Call</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$3</span><span class="p">,</span> <span class="nx">$2</span>
<span class="nx">o</span> <span class="s">&#39;Invocation OptFuncExist Arguments&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Call</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$3</span><span class="p">,</span> <span class="nx">$2</span>
<span class="nx">o</span> <span class="s">&#39;SUPER&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Call</span> <span class="s">&#39;super&#39;</span><span class="p">,</span> <span class="p">[</span><span class="k">new</span> <span class="nx">Splat</span> <span class="k">new</span> <span class="nx">Literal</span> <span class="s">&#39;arguments&#39;</span><span class="p">]</span>
<span class="nx">o</span> <span class="s">&#39;SUPER Arguments&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Call</span> <span class="s">&#39;super&#39;</span><span class="p">,</span> <span class="nx">$2</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-37"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-37">&#182;</a> </div> <p>An optional existence check on a function.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">OptFuncExist: </span><span class="p">[</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-39"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-39">&#182;</a> </div> <p>An optional existence check on a function.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">OptFuncExist: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s">&#39;&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="kc">no</span>
<span class="nx">o</span> <span class="s">&#39;FUNC_EXIST&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="kc">yes</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-38"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-38">&#182;</a> </div> <p>The list of arguments to a function call.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Arguments: </span><span class="p">[</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-40"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-40">&#182;</a> </div> <p>The list of arguments to a function call.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Arguments: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s">&#39;CALL_START CALL_END&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="p">[]</span>
<span class="nx">o</span> <span class="s">&#39;CALL_START ArgList OptComma CALL_END&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="nx">$2</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-39"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-39">&#182;</a> </div> <p>A reference to the <em>this</em> current object.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">This: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s">&#39;THIS&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Value</span> <span class="k">new</span> <span class="nx">Literal</span> <span class="s">&#39;this&#39;</span>
<span class="nx">o</span> <span class="s">&#39;@&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Value</span> <span class="k">new</span> <span class="nx">Literal</span> <span class="s">&#39;this&#39;</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-40"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-40">&#182;</a> </div> <p>A reference to a property on <em>this</em>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">ThisProperty: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s">&#39;@ Identifier&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Value</span> <span class="k">new</span> <span class="nx">Literal</span><span class="p">(</span><span class="s">&#39;this&#39;</span><span class="p">),</span> <span class="p">[</span><span class="k">new</span> <span class="nx">Access</span><span class="p">(</span><span class="nx">$2</span><span class="p">)],</span> <span class="s">&#39;this&#39;</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-41"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-41">&#182;</a> </div> <p>The array literal.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nb">Array</span><span class="o">:</span> <span class="p">[</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-41"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-41">&#182;</a> </div> <p>A reference to the <em>this</em> current object.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">This: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s">&#39;THIS&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="nx">Value</span><span class="p">.</span><span class="nx">wrap</span> <span class="k">new</span> <span class="nx">Literal</span> <span class="s">&#39;this&#39;</span>
<span class="nx">o</span> <span class="s">&#39;@&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="nx">Value</span><span class="p">.</span><span class="nx">wrap</span> <span class="k">new</span> <span class="nx">Literal</span> <span class="s">&#39;this&#39;</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-42"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-42">&#182;</a> </div> <p>A reference to a property on <em>this</em>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">ThisProperty: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s">&#39;@ Identifier&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="nx">Value</span><span class="p">.</span><span class="nx">wrap</span> <span class="nx">LOC</span><span class="p">(</span><span class="mi">1</span><span class="p">)(</span><span class="k">new</span> <span class="nx">Literal</span><span class="p">(</span><span class="s">&#39;this&#39;</span><span class="p">)),</span> <span class="p">[</span><span class="nx">LOC</span><span class="p">(</span><span class="mi">2</span><span class="p">)(</span><span class="k">new</span> <span class="nx">Access</span><span class="p">(</span><span class="nx">$2</span><span class="p">))],</span> <span class="s">&#39;this&#39;</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-43"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-43">&#182;</a> </div> <p>The array literal.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nb">Array</span><span class="o">:</span> <span class="p">[</span>
<span class="nx">o</span> <span class="s">&#39;[ ]&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Arr</span> <span class="p">[]</span>
<span class="nx">o</span> <span class="s">&#39;[ ArgList OptComma ]&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Arr</span> <span class="nx">$2</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-42"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-42">&#182;</a> </div> <p>Inclusive and exclusive range dots.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">RangeDots: </span><span class="p">[</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-44"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-44">&#182;</a> </div> <p>Inclusive and exclusive range dots.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">RangeDots: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s">&#39;..&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="s">&#39;inclusive&#39;</span>
<span class="nx">o</span> <span class="s">&#39;...&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="s">&#39;exclusive&#39;</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-43"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-43">&#182;</a> </div> <p>The CoffeeScript range literal.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Range: </span><span class="p">[</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-45"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-45">&#182;</a> </div> <p>The CoffeeScript range literal.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Range: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s">&#39;[ Expression RangeDots Expression ]&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Range</span> <span class="nx">$2</span><span class="p">,</span> <span class="nx">$4</span><span class="p">,</span> <span class="nx">$3</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-44"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-44">&#182;</a> </div> <p>Array slice literals.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Slice: </span><span class="p">[</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-46"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-46">&#182;</a> </div> <p>Array slice literals.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Slice: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s">&#39;Expression RangeDots Expression&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Range</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$3</span><span class="p">,</span> <span class="nx">$2</span>
<span class="nx">o</span> <span class="s">&#39;Expression RangeDots&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Range</span> <span class="nx">$1</span><span class="p">,</span> <span class="kc">null</span><span class="p">,</span> <span class="nx">$2</span>
<span class="nx">o</span> <span class="s">&#39;RangeDots Expression&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Range</span> <span class="kc">null</span><span class="p">,</span> <span class="nx">$2</span><span class="p">,</span> <span class="nx">$1</span>
<span class="nx">o</span> <span class="s">&#39;RangeDots&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Range</span> <span class="kc">null</span><span class="p">,</span> <span class="kc">null</span><span class="p">,</span> <span class="nx">$1</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-45"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-45">&#182;</a> </div> <p>The <strong>ArgList</strong> is both the list of objects passed into a function call,
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-47"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-47">&#182;</a> </div> <p>The <strong>ArgList</strong> is both the list of objects passed into a function call,
as well as the contents of an array literal
(i.e. comma-separated expressions). Newlines work as well.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">ArgList: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s">&#39;Arg&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="p">[</span><span class="nx">$1</span><span class="p">]</span>
@@ -225,46 +236,47 @@ as well as the contents of an array literal
<span class="nx">o</span> <span class="s">&#39;ArgList OptComma TERMINATOR Arg&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="nx">$1</span><span class="p">.</span><span class="nx">concat</span> <span class="nx">$4</span>
<span class="nx">o</span> <span class="s">&#39;INDENT ArgList OptComma OUTDENT&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="nx">$2</span>
<span class="nx">o</span> <span class="s">&#39;ArgList OptComma INDENT ArgList OptComma OUTDENT&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="nx">$1</span><span class="p">.</span><span class="nx">concat</span> <span class="nx">$4</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-46"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-46">&#182;</a> </div> <p>Valid arguments are Blocks or Splats.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Arg: </span><span class="p">[</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-48"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-48">&#182;</a> </div> <p>Valid arguments are Blocks or Splats.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Arg: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s">&#39;Expression&#39;</span>
<span class="nx">o</span> <span class="s">&#39;Splat&#39;</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-47"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-47">&#182;</a> </div> <p>Just simple, comma-separated, required arguments (no fancy syntax). We need
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-49"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-49">&#182;</a> </div> <p>Just simple, comma-separated, required arguments (no fancy syntax). We need
this to be separate from the <strong>ArgList</strong> for use in <strong>Switch</strong> blocks, where
having the newlines wouldn't make sense.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">SimpleArgs: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s">&#39;Expression&#39;</span>
<span class="nx">o</span> <span class="s">&#39;SimpleArgs , Expression&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="p">[].</span><span class="nx">concat</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$3</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-48"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-48">&#182;</a> </div> <p>The variants of <em>try/catch/finally</em> exception handling blocks.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Try: </span><span class="p">[</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-50"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-50">&#182;</a> </div> <p>The variants of <em>try/catch/finally</em> exception handling blocks.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Try: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s">&#39;TRY Block&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Try</span> <span class="nx">$2</span>
<span class="nx">o</span> <span class="s">&#39;TRY Block Catch&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Try</span> <span class="nx">$2</span><span class="p">,</span> <span class="nx">$3</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="nx">$3</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
<span class="nx">o</span> <span class="s">&#39;TRY Block FINALLY Block&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Try</span> <span class="nx">$2</span><span class="p">,</span> <span class="kc">null</span><span class="p">,</span> <span class="kc">null</span><span class="p">,</span> <span class="nx">$4</span>
<span class="nx">o</span> <span class="s">&#39;TRY Block Catch FINALLY Block&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Try</span> <span class="nx">$2</span><span class="p">,</span> <span class="nx">$3</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="nx">$3</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="nx">$5</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-49"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-49">&#182;</a> </div> <p>A catch clause names its error and runs a block of code.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Catch: </span><span class="p">[</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-51"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-51">&#182;</a> </div> <p>A catch clause names its error and runs a block of code.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Catch: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s">&#39;CATCH Identifier Block&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="p">[</span><span class="nx">$2</span><span class="p">,</span> <span class="nx">$3</span><span class="p">]</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-50"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-50">&#182;</a> </div> <p>Throw an exception object.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Throw: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s">&#39;CATCH Object Block&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="p">[</span><span class="nx">LOC</span><span class="p">(</span><span class="mi">2</span><span class="p">)(</span><span class="nx">Value</span><span class="p">.</span><span class="nx">wrap</span><span class="p">(</span><span class="nx">$2</span><span class="p">)),</span> <span class="nx">$3</span><span class="p">]</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-52"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-52">&#182;</a> </div> <p>Throw an exception object.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Throw: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s">&#39;THROW Expression&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Throw</span> <span class="nx">$2</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-51"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-51">&#182;</a> </div> <p>Parenthetical expressions. Note that the <strong>Parenthetical</strong> is a <strong>Value</strong>,
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-53"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-53">&#182;</a> </div> <p>Parenthetical expressions. Note that the <strong>Parenthetical</strong> is a <strong>Value</strong>,
not an <strong>Expression</strong>, so if you need to use an expression in a place
where only values are accepted, wrapping it in parentheses will always do
the trick.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Parenthetical: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s">&#39;( Body )&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Parens</span> <span class="nx">$2</span>
<span class="nx">o</span> <span class="s">&#39;( INDENT Body OUTDENT )&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Parens</span> <span class="nx">$3</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-52"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-52">&#182;</a> </div> <p>The condition portion of a while loop.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">WhileSource: </span><span class="p">[</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-54"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-54">&#182;</a> </div> <p>The condition portion of a while loop.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">WhileSource: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s">&#39;WHILE Expression&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">While</span> <span class="nx">$2</span>
<span class="nx">o</span> <span class="s">&#39;WHILE Expression WHEN Expression&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">While</span> <span class="nx">$2</span><span class="p">,</span> <span class="nv">guard: </span><span class="nx">$4</span>
<span class="nx">o</span> <span class="s">&#39;UNTIL Expression&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">While</span> <span class="nx">$2</span><span class="p">,</span> <span class="nv">invert: </span><span class="kc">true</span>
<span class="nx">o</span> <span class="s">&#39;UNTIL Expression WHEN Expression&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">While</span> <span class="nx">$2</span><span class="p">,</span> <span class="nv">invert: </span><span class="kc">true</span><span class="p">,</span> <span class="nv">guard: </span><span class="nx">$4</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-53"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-53">&#182;</a> </div> <p>The while loop can either be normal, with a block of expressions to execute,
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-55"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-55">&#182;</a> </div> <p>The while loop can either be normal, with a block of expressions to execute,
or postfix, with a single expression. There is no do..while.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">While: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s">&#39;WhileSource Block&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="nx">$1</span><span class="p">.</span><span class="nx">addBody</span> <span class="nx">$2</span>
<span class="nx">o</span> <span class="s">&#39;Statement WhileSource&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="nx">$2</span><span class="p">.</span><span class="nx">addBody</span> <span class="nx">Block</span><span class="p">.</span><span class="nx">wrap</span> <span class="p">[</span><span class="nx">$1</span><span class="p">]</span>
<span class="nx">o</span> <span class="s">&#39;Expression WhileSource&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="nx">$2</span><span class="p">.</span><span class="nx">addBody</span> <span class="nx">Block</span><span class="p">.</span><span class="nx">wrap</span> <span class="p">[</span><span class="nx">$1</span><span class="p">]</span>
<span class="nx">o</span> <span class="s">&#39;Statement WhileSource&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="nx">$2</span><span class="p">.</span><span class="nx">addBody</span> <span class="nx">LOC</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="nx">Block</span><span class="p">.</span><span class="nx">wrap</span><span class="p">([</span><span class="nx">$1</span><span class="p">])</span>
<span class="nx">o</span> <span class="s">&#39;Expression WhileSource&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="nx">$2</span><span class="p">.</span><span class="nx">addBody</span> <span class="nx">LOC</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="nx">Block</span><span class="p">.</span><span class="nx">wrap</span><span class="p">([</span><span class="nx">$1</span><span class="p">])</span>
<span class="nx">o</span> <span class="s">&#39;Loop&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="nx">$1</span>
<span class="p">]</span>
<span class="nv">Loop: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s">&#39;LOOP Block&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">While</span><span class="p">(</span><span class="k">new</span> <span class="nx">Literal</span> <span class="s">&#39;true&#39;</span><span class="p">).</span><span class="nx">addBody</span> <span class="nx">$2</span>
<span class="nx">o</span> <span class="s">&#39;LOOP Expression&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">While</span><span class="p">(</span><span class="k">new</span> <span class="nx">Literal</span> <span class="s">&#39;true&#39;</span><span class="p">).</span><span class="nx">addBody</span> <span class="nx">Block</span><span class="p">.</span><span class="nx">wrap</span> <span class="p">[</span><span class="nx">$2</span><span class="p">]</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-54"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-54">&#182;</a> </div> <p>Array, object, and range comprehensions, at the most generic level.
<span class="nx">o</span> <span class="s">&#39;LOOP Block&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">While</span><span class="p">(</span><span class="nx">LOC</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="k">new</span> <span class="nx">Literal</span> <span class="s">&#39;true&#39;</span><span class="p">).</span><span class="nx">addBody</span> <span class="nx">$2</span>
<span class="nx">o</span> <span class="s">&#39;LOOP Expression&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">While</span><span class="p">(</span><span class="nx">LOC</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="k">new</span> <span class="nx">Literal</span> <span class="s">&#39;true&#39;</span><span class="p">).</span><span class="nx">addBody</span> <span class="nx">LOC</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span> <span class="nx">Block</span><span class="p">.</span><span class="nx">wrap</span> <span class="p">[</span><span class="nx">$2</span><span class="p">]</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-56"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-56">&#182;</a> </div> <p>Array, object, and range comprehensions, at the most generic level.
Comprehensions can either be normal, with a block of expressions to execute,
or postfix, with a single expression.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">For: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s">&#39;Statement ForBody&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">For</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$2</span>
@@ -273,25 +285,25 @@ or postfix, with a single expression.</p> </td> <td clas
<span class="p">]</span>
<span class="nv">ForBody: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s">&#39;FOR Range&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="nv">source: </span><span class="k">new</span> <span class="nx">Value</span><span class="p">(</span><span class="nx">$2</span><span class="p">)</span>
<span class="nx">o</span> <span class="s">&#39;FOR Range&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="nv">source: </span><span class="nx">LOC</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span> <span class="nx">Value</span><span class="p">.</span><span class="nx">wrap</span><span class="p">(</span><span class="nx">$2</span><span class="p">)</span>
<span class="nx">o</span> <span class="s">&#39;ForStart ForSource&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="nv">$2.own = </span><span class="nx">$1</span><span class="p">.</span><span class="nx">own</span><span class="p">;</span> <span class="nv">$2.name = </span><span class="nx">$1</span><span class="p">[</span><span class="mi">0</span><span class="p">];</span> <span class="nv">$2.index = </span><span class="nx">$1</span><span class="p">[</span><span class="mi">1</span><span class="p">];</span> <span class="nx">$2</span>
<span class="p">]</span>
<span class="nv">ForStart: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s">&#39;FOR ForVariables&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="nx">$2</span>
<span class="nx">o</span> <span class="s">&#39;FOR OWN ForVariables&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="nv">$3.own = </span><span class="kc">yes</span><span class="p">;</span> <span class="nx">$3</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-55"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-55">&#182;</a> </div> <p>An array of all accepted values for a variable inside the loop.
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-57"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-57">&#182;</a> </div> <p>An array of all accepted values for a variable inside the loop.
This enables support for pattern matching.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">ForValue: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s">&#39;Identifier&#39;</span>
<span class="nx">o</span> <span class="s">&#39;ThisProperty&#39;</span>
<span class="nx">o</span> <span class="s">&#39;Array&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Value</span> <span class="nx">$1</span>
<span class="nx">o</span> <span class="s">&#39;Object&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Value</span> <span class="nx">$1</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-56"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-56">&#182;</a> </div> <p>An array or range comprehension has variables for the current element
<span class="nx">o</span> <span class="s">&#39;Array&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="nx">Value</span><span class="p">.</span><span class="nx">wrap</span> <span class="nx">$1</span>
<span class="nx">o</span> <span class="s">&#39;Object&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="nx">Value</span><span class="p">.</span><span class="nx">wrap</span> <span class="nx">$1</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-58"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-58">&#182;</a> </div> <p>An array or range comprehension has variables for the current element
and (optional) reference to the current index. Or, <em>key, value</em>, in the case
of object comprehensions.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">ForVariables: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s">&#39;ForValue&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="p">[</span><span class="nx">$1</span><span class="p">]</span>
<span class="nx">o</span> <span class="s">&#39;ForValue , ForValue&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="p">[</span><span class="nx">$1</span><span class="p">,</span> <span class="nx">$3</span><span class="p">]</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-57"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-57">&#182;</a> </div> <p>The source of a comprehension is an array or object with an optional guard
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-59"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-59">&#182;</a> </div> <p>The source of a comprehension is an array or object with an optional guard
clause. If it's an array comprehension, you can also choose to step through
in fixed-size increments.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">ForSource: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s">&#39;FORIN Expression&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="nv">source: </span><span class="nx">$2</span>
@@ -313,54 +325,56 @@ in fixed-size increments.</p> </td> <td class="code">
<span class="nv">Whens: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s">&#39;When&#39;</span>
<span class="nx">o</span> <span class="s">&#39;Whens When&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="nx">$1</span><span class="p">.</span><span class="nx">concat</span> <span class="nx">$2</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-58"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-58">&#182;</a> </div> <p>An individual <strong>When</strong> clause, with action.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">When: </span><span class="p">[</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-60"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-60">&#182;</a> </div> <p>An individual <strong>When</strong> clause, with action.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">When: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s">&#39;LEADING_WHEN SimpleArgs Block&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="p">[[</span><span class="nx">$2</span><span class="p">,</span> <span class="nx">$3</span><span class="p">]]</span>
<span class="nx">o</span> <span class="s">&#39;LEADING_WHEN SimpleArgs Block TERMINATOR&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="p">[[</span><span class="nx">$2</span><span class="p">,</span> <span class="nx">$3</span><span class="p">]]</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-59"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-59">&#182;</a> </div> <p>The most basic form of <em>if</em> is a condition and an action. The following
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-61"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-61">&#182;</a> </div> <p>The most basic form of <em>if</em> is a condition and an action. The following
if-related rules are broken up along these lines in order to avoid
ambiguity.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">IfBlock: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s">&#39;IF Expression Block&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">If</span> <span class="nx">$2</span><span class="p">,</span> <span class="nx">$3</span><span class="p">,</span> <span class="nv">type: </span><span class="nx">$1</span>
<span class="nx">o</span> <span class="s">&#39;IfBlock ELSE IF Expression Block&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="nx">$1</span><span class="p">.</span><span class="nx">addElse</span> <span class="k">new</span> <span class="nx">If</span> <span class="nx">$4</span><span class="p">,</span> <span class="nx">$5</span><span class="p">,</span> <span class="nv">type: </span><span class="nx">$3</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-60"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-60">&#182;</a> </div> <p>The full complement of <em>if</em> expressions, including postfix one-liner
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-62"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-62">&#182;</a> </div> <p>The full complement of <em>if</em> expressions, including postfix one-liner
<em>if</em> and <em>unless</em>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">If: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s">&#39;IfBlock&#39;</span>
<span class="nx">o</span> <span class="s">&#39;IfBlock ELSE Block&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="nx">$1</span><span class="p">.</span><span class="nx">addElse</span> <span class="nx">$3</span>
<span class="nx">o</span> <span class="s">&#39;Statement POST_IF Expression&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">If</span> <span class="nx">$3</span><span class="p">,</span> <span class="nx">Block</span><span class="p">.</span><span class="nx">wrap</span><span class="p">([</span><span class="nx">$1</span><span class="p">]),</span> <span class="nv">type: </span><span class="nx">$2</span><span class="p">,</span> <span class="nv">statement: </span><span class="kc">true</span>
<span class="nx">o</span> <span class="s">&#39;Expression POST_IF Expression&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">If</span> <span class="nx">$3</span><span class="p">,</span> <span class="nx">Block</span><span class="p">.</span><span class="nx">wrap</span><span class="p">([</span><span class="nx">$1</span><span class="p">]),</span> <span class="nv">type: </span><span class="nx">$2</span><span class="p">,</span> <span class="nv">statement: </span><span class="kc">true</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-61"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-61">&#182;</a> </div> <p>Arithmetic and logical operators, working on one or more operands.
<span class="nx">o</span> <span class="s">&#39;Statement POST_IF Expression&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">If</span> <span class="nx">$3</span><span class="p">,</span> <span class="nx">LOC</span><span class="p">(</span><span class="mi">1</span><span class="p">)(</span><span class="nx">Block</span><span class="p">.</span><span class="nx">wrap</span> <span class="p">[</span><span class="nx">$1</span><span class="p">]),</span> <span class="nv">type: </span><span class="nx">$2</span><span class="p">,</span> <span class="nv">statement: </span><span class="kc">true</span>
<span class="nx">o</span> <span class="s">&#39;Expression POST_IF Expression&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">If</span> <span class="nx">$3</span><span class="p">,</span> <span class="nx">LOC</span><span class="p">(</span><span class="mi">1</span><span class="p">)(</span><span class="nx">Block</span><span class="p">.</span><span class="nx">wrap</span> <span class="p">[</span><span class="nx">$1</span><span class="p">]),</span> <span class="nv">type: </span><span class="nx">$2</span><span class="p">,</span> <span class="nv">statement: </span><span class="kc">true</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-63"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-63">&#182;</a> </div> <p>Arithmetic and logical operators, working on one or more operands.
Here they are grouped by order of precedence. The actual precedence rules
are defined at the bottom of the page. It would be shorter if we could
combine most of these rules into a single generic <em>Operand OpSymbol Operand</em>
-type rule, but in order to make the precedence binding possible, separate
rules are necessary.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Operation: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s">&#39;UNARY Expression&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Op</span> <span class="nx">$1</span> <span class="p">,</span> <span class="nx">$2</span>
<span class="nx">o</span> <span class="s">&#39;- Expression&#39;</span><span class="p">,</span> <span class="p">(</span><span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Op</span> <span class="s">&#39;-&#39;</span><span class="p">,</span> <span class="nx">$2</span><span class="p">),</span> <span class="nv">prec: </span><span class="s">&#39;UNARY&#39;</span>
<span class="nx">o</span> <span class="s">&#39;+ Expression&#39;</span><span class="p">,</span> <span class="p">(</span><span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Op</span> <span class="s">&#39;+&#39;</span><span class="p">,</span> <span class="nx">$2</span><span class="p">),</span> <span class="nv">prec: </span><span class="s">&#39;UNARY&#39;</span>
<span class="nx">o</span> <span class="s">&#39;UNARY Expression&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="nx">Op</span><span class="p">.</span><span class="nx">create</span> <span class="nx">$1</span> <span class="p">,</span> <span class="nx">$2</span>
<span class="nx">o</span> <span class="s">&#39;- Expression&#39;</span><span class="p">,</span> <span class="p">(</span><span class="nf">-&gt;</span> <span class="nx">Op</span><span class="p">.</span><span class="nx">create</span> <span class="s">&#39;-&#39;</span><span class="p">,</span> <span class="nx">$2</span><span class="p">),</span> <span class="nv">prec: </span><span class="s">&#39;UNARY&#39;</span>
<span class="nx">o</span> <span class="s">&#39;+ Expression&#39;</span><span class="p">,</span> <span class="p">(</span><span class="nf">-&gt;</span> <span class="nx">Op</span><span class="p">.</span><span class="nx">create</span> <span class="s">&#39;+&#39;</span><span class="p">,</span> <span class="nx">$2</span><span class="p">),</span> <span class="nv">prec: </span><span class="s">&#39;UNARY&#39;</span>
<span class="nx">o</span> <span class="s">&#39;-- SimpleAssignable&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Op</span> <span class="s">&#39;--&#39;</span><span class="p">,</span> <span class="nx">$2</span>
<span class="nx">o</span> <span class="s">&#39;++ SimpleAssignable&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Op</span> <span class="s">&#39;++&#39;</span><span class="p">,</span> <span class="nx">$2</span>
<span class="nx">o</span> <span class="s">&#39;SimpleAssignable --&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Op</span> <span class="s">&#39;--&#39;</span><span class="p">,</span> <span class="nx">$1</span><span class="p">,</span> <span class="kc">null</span><span class="p">,</span> <span class="kc">true</span>
<span class="nx">o</span> <span class="s">&#39;SimpleAssignable ++&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Op</span> <span class="s">&#39;++&#39;</span><span class="p">,</span> <span class="nx">$1</span><span class="p">,</span> <span class="kc">null</span><span class="p">,</span> <span class="kc">true</span></pre></div> </td> </tr> <tr id="section-62"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-62">&#182;</a> </div> <p><a href="http://jashkenas.github.com/coffee-script/#existence">The existential operator</a>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">o</span> <span class="s">&#39;Expression ?&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Existence</span> <span class="nx">$1</span>
<span class="nx">o</span> <span class="s">&#39;-- SimpleAssignable&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="nx">Op</span><span class="p">.</span><span class="nx">create</span> <span class="s">&#39;--&#39;</span><span class="p">,</span> <span class="nx">$2</span>
<span class="nx">o</span> <span class="s">&#39;++ SimpleAssignable&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="nx">Op</span><span class="p">.</span><span class="nx">create</span> <span class="s">&#39;++&#39;</span><span class="p">,</span> <span class="nx">$2</span>
<span class="nx">o</span> <span class="s">&#39;SimpleAssignable --&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="nx">Op</span><span class="p">.</span><span class="nx">create</span> <span class="s">&#39;--&#39;</span><span class="p">,</span> <span class="nx">$1</span><span class="p">,</span> <span class="kc">null</span><span class="p">,</span> <span class="kc">true</span>
<span class="nx">o</span> <span class="s">&#39;SimpleAssignable ++&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="nx">Op</span><span class="p">.</span><span class="nx">create</span> <span class="s">&#39;++&#39;</span><span class="p">,</span> <span class="nx">$1</span><span class="p">,</span> <span class="kc">null</span><span class="p">,</span> <span class="kc">true</span></pre></div> </td> </tr> <tr id="section-64"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-64">&#182;</a> </div> <p><a href="http://jashkenas.github.com/coffee-script/#existence">The existential operator</a>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">o</span> <span class="s">&#39;Expression ?&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Existence</span> <span class="nx">$1</span>
<span class="nx">o</span> <span class="s">&#39;Expression + Expression&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Op</span> <span class="s">&#39;+&#39;</span> <span class="p">,</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$3</span>
<span class="nx">o</span> <span class="s">&#39;Expression - Expression&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Op</span> <span class="s">&#39;-&#39;</span> <span class="p">,</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$3</span>
<span class="nx">o</span> <span class="s">&#39;Expression + Expression&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="nx">Op</span><span class="p">.</span><span class="nx">create</span> <span class="s">&#39;+&#39;</span> <span class="p">,</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$3</span>
<span class="nx">o</span> <span class="s">&#39;Expression - Expression&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="nx">Op</span><span class="p">.</span><span class="nx">create</span> <span class="s">&#39;-&#39;</span> <span class="p">,</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$3</span>
<span class="nx">o</span> <span class="s">&#39;Expression MATH Expression&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Op</span> <span class="nx">$2</span><span class="p">,</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$3</span>
<span class="nx">o</span> <span class="s">&#39;Expression SHIFT Expression&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Op</span> <span class="nx">$2</span><span class="p">,</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$3</span>
<span class="nx">o</span> <span class="s">&#39;Expression COMPARE Expression&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Op</span> <span class="nx">$2</span><span class="p">,</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$3</span>
<span class="nx">o</span> <span class="s">&#39;Expression LOGIC Expression&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Op</span> <span class="nx">$2</span><span class="p">,</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$3</span>
<span class="nx">o</span> <span class="s">&#39;Expression MATH Expression&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="nx">Op</span><span class="p">.</span><span class="nx">create</span> <span class="nx">$2</span><span class="p">,</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$3</span>
<span class="nx">o</span> <span class="s">&#39;Expression SHIFT Expression&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="nx">Op</span><span class="p">.</span><span class="nx">create</span> <span class="nx">$2</span><span class="p">,</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$3</span>
<span class="nx">o</span> <span class="s">&#39;Expression COMPARE Expression&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="nx">Op</span><span class="p">.</span><span class="nx">create</span> <span class="nx">$2</span><span class="p">,</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$3</span>
<span class="nx">o</span> <span class="s">&#39;Expression LOGIC Expression&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="nx">Op</span><span class="p">.</span><span class="nx">create</span> <span class="nx">$2</span><span class="p">,</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$3</span>
<span class="nx">o</span> <span class="s">&#39;Expression RELATION Expression&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span>
<span class="k">if</span> <span class="nx">$2</span><span class="p">.</span><span class="nx">charAt</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span> <span class="o">is</span> <span class="s">&#39;!&#39;</span>
<span class="k">new</span> <span class="nx">Op</span><span class="p">(</span><span class="nx">$2</span><span class="p">[</span><span class="mi">1</span><span class="p">..],</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$3</span><span class="p">).</span><span class="nx">invert</span><span class="p">()</span>
<span class="nx">Op</span><span class="p">.</span><span class="nx">create</span><span class="p">(</span><span class="nx">$2</span><span class="p">[</span><span class="mi">1</span><span class="p">..],</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$3</span><span class="p">).</span><span class="nx">invert</span><span class="p">()</span>
<span class="k">else</span>
<span class="k">new</span> <span class="nx">Op</span> <span class="nx">$2</span><span class="p">,</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$3</span>
<span class="nx">Op</span><span class="p">.</span><span class="nx">create</span> <span class="nx">$2</span><span class="p">,</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$3</span>
<span class="nx">o</span> <span class="s">&#39;SimpleAssignable COMPOUND_ASSIGN</span>
<span class="s"> Expression&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Assign</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$3</span><span class="p">,</span> <span class="nx">$2</span>
<span class="nx">o</span> <span class="s">&#39;SimpleAssignable COMPOUND_ASSIGN</span>
<span class="s"> INDENT Expression OUTDENT&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Assign</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$4</span><span class="p">,</span> <span class="nx">$2</span>
<span class="nx">o</span> <span class="s">&#39;SimpleAssignable COMPOUND_ASSIGN TERMINATOR</span>
<span class="s"> Expression&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Assign</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$4</span><span class="p">,</span> <span class="nx">$2</span>
<span class="nx">o</span> <span class="s">&#39;SimpleAssignable EXTENDS Expression&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="k">new</span> <span class="nx">Extends</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$3</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-63"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-63">&#182;</a> </div> <h2>Precedence</h2> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-64"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-64">&#182;</a> </div> <p>Operators at the top of this list have higher precedence than the ones lower
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-65"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-65">&#182;</a> </div> <h2>Precedence</h2> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-66"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-66">&#182;</a> </div> <p>Operators at the top of this list have higher precedence than the ones lower
down. Following these rules is what makes <code>2 + 3 * 4</code> parse as:</p>
<pre><code>2 + (3 * 4)
@@ -386,7 +400,7 @@ down. Following these rules is what makes <code>2 + 3 * 4</code> parse as:</p>
<span class="p">[</span><span class="s">&#39;right&#39;</span><span class="p">,</span> <span class="s">&#39;FORIN&#39;</span><span class="p">,</span> <span class="s">&#39;FOROF&#39;</span><span class="p">,</span> <span class="s">&#39;BY&#39;</span><span class="p">,</span> <span class="s">&#39;WHEN&#39;</span><span class="p">]</span>
<span class="p">[</span><span class="s">&#39;right&#39;</span><span class="p">,</span> <span class="s">&#39;IF&#39;</span><span class="p">,</span> <span class="s">&#39;ELSE&#39;</span><span class="p">,</span> <span class="s">&#39;FOR&#39;</span><span class="p">,</span> <span class="s">&#39;WHILE&#39;</span><span class="p">,</span> <span class="s">&#39;UNTIL&#39;</span><span class="p">,</span> <span class="s">&#39;LOOP&#39;</span><span class="p">,</span> <span class="s">&#39;SUPER&#39;</span><span class="p">,</span> <span class="s">&#39;CLASS&#39;</span><span class="p">]</span>
<span class="p">[</span><span class="s">&#39;right&#39;</span><span class="p">,</span> <span class="s">&#39;POST_IF&#39;</span><span class="p">]</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-65"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-65">&#182;</a> </div> <h2>Wrapping Up</h2> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-66"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-66">&#182;</a> </div> <p>Finally, now that we have our <strong>grammar</strong> and our <strong>operators</strong>, we can create
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-67"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-67">&#182;</a> </div> <h2>Wrapping Up</h2> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-68"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-68">&#182;</a> </div> <p>Finally, now that we have our <strong>grammar</strong> and our <strong>operators</strong>, we can create
our <strong>Jison.Parser</strong>. We do this by processing all of our rules, recording all
terminals (every symbol which does not appear as the name of a rule above)
as "tokens".</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">tokens = </span><span class="p">[]</span>
@@ -395,7 +409,7 @@ as "tokens".</p> </td> <td class="code"> <
<span class="k">for</span> <span class="nx">token</span> <span class="k">in</span> <span class="nx">alt</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nx">split</span> <span class="s">&#39; &#39;</span>
<span class="nx">tokens</span><span class="p">.</span><span class="nx">push</span> <span class="nx">token</span> <span class="k">unless</span> <span class="nx">grammar</span><span class="p">[</span><span class="nx">token</span><span class="p">]</span>
<span class="nx">alt</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="s">&quot;return </span><span class="si">#{</span><span class="nx">alt</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span><span class="si">}</span><span class="s">&quot;</span> <span class="k">if</span> <span class="nx">name</span> <span class="o">is</span> <span class="s">&#39;Root&#39;</span>
<span class="nx">alt</span></pre></div> </td> </tr> <tr id="section-67"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-67">&#182;</a> </div> <p>Initialize the <strong>Parser</strong> with our list of terminal <strong>tokens</strong>, our <strong>grammar</strong>
<span class="nx">alt</span></pre></div> </td> </tr> <tr id="section-69"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-69">&#182;</a> </div> <p>Initialize the <strong>Parser</strong> with our list of terminal <strong>tokens</strong>, our <strong>grammar</strong>
rules, and the name of the root. Reverse the operators because Jison orders
precedence from low to high, and we have it high to low
(as in <a href="http://dinosaur.compilertools.net/yacc/index.html">Yacc</a>).</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.parser = </span><span class="k">new</span> <span class="nx">Parser</span>

View File

@@ -1,4 +1,4 @@
<!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="pilwrap"> <a class="pilcrow" href="#section-1">&#182;</a> </div> <p>This file contains the common helper functions that we'd like to share among
<!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> </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="pilwrap"> <a class="pilcrow" href="#section-1">&#182;</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="pilwrap"> <a class="pilcrow" href="#section-2">&#182;</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">exports.starts = </span><span class="nf">(string, literal, start) -&gt;</span>
<span class="nx">literal</span> <span class="o">is</span> <span class="nx">string</span><span class="p">.</span><span class="nx">substr</span> <span class="nx">start</span><span class="p">,</span> <span class="nx">literal</span><span class="p">.</span><span class="nx">length</span></pre></div> </td> </tr> <tr id="section-3"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-3">&#182;</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">exports.ends = </span><span class="nf">(string, literal, back) -&gt;</span>
@@ -28,6 +28,29 @@ looking for a particular method in an options hash.</p> </td>
<span class="k">delete</span> <span class="nx">obj</span><span class="p">[</span><span class="nx">key</span><span class="p">]</span>
<span class="nx">val</span></pre></div> </td> </tr> <tr id="section-10"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-10">&#182;</a> </div> <p>Gets the last item of an array(-like) object.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.last = </span><span class="nf">(array, back) -&gt;</span> <span class="nx">array</span><span class="p">[</span><span class="nx">array</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">or</span> <span class="mi">0</span><span class="p">)</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-11"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-11">&#182;</a> </div> <p>Typical Array::some</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.some = </span><span class="nb">Array</span><span class="o">::</span><span class="nx">some</span> <span class="o">?</span> <span class="nf">(fn) -&gt;</span>
<span class="k">return</span> <span class="kc">true</span> <span class="k">for</span> <span class="nx">e</span> <span class="k">in</span> <span class="k">this</span> <span class="k">when</span> <span class="nx">fn</span> <span class="nx">e</span>
<span class="kc">false</span>
<span class="kc">false</span></pre></div> </td> </tr> <tr id="section-12"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-12">&#182;</a> </div> <p>Merge two jison-style location data objects together.
If <code>last</code> is not provided, this will simply return <code>first</code>.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">buildLocationData = </span><span class="nf">(first, last) -&gt;</span>
<span class="k">if</span> <span class="o">not</span> <span class="nx">last</span>
<span class="nx">first</span>
<span class="k">else</span>
<span class="nv">first_line: </span><span class="nx">first</span><span class="p">.</span><span class="nx">first_line</span>
<span class="nv">first_column: </span><span class="nx">first</span><span class="p">.</span><span class="nx">first_column</span>
<span class="nv">last_line: </span><span class="nx">last</span><span class="p">.</span><span class="nx">last_line</span>
<span class="nv">last_column: </span><span class="nx">last</span><span class="p">.</span><span class="nx">last_column</span></pre></div> </td> </tr> <tr id="section-13"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-13">&#182;</a> </div> <p>This returns a function which takes an object as a parameter, and if that object is an AST node,
updates that object's locationData. The object is returned either way.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.addLocationDataFn = </span><span class="nf">(first, last) -&gt;</span>
<span class="nf">(obj) -&gt;</span>
<span class="k">if</span> <span class="p">((</span><span class="k">typeof</span> <span class="nx">obj</span><span class="p">)</span> <span class="o">is</span> <span class="s">&#39;object&#39;</span><span class="p">)</span> <span class="o">and</span> <span class="p">(</span><span class="o">!!</span><span class="nx">obj</span><span class="p">[</span><span class="s">&#39;updateLocationDataIfMissing&#39;</span><span class="p">])</span>
<span class="nx">obj</span><span class="p">.</span><span class="nx">updateLocationDataIfMissing</span> <span class="nx">buildLocationData</span><span class="p">(</span><span class="nx">first</span><span class="p">,</span> <span class="nx">last</span><span class="p">)</span>
<span class="k">return</span> <span class="nx">obj</span></pre></div> </td> </tr> <tr id="section-14"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-14">&#182;</a> </div> <p>Convert jison location data to a string.
<code>obj</code> can be a token, or a locationData.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.locationDataToString = </span><span class="nf">(obj) -&gt;</span>
<span class="k">if</span> <span class="p">(</span><span class="s">&quot;2&quot;</span> <span class="k">of</span> <span class="nx">obj</span><span class="p">)</span> <span class="o">and</span> <span class="p">(</span><span class="s">&quot;first_line&quot;</span> <span class="k">of</span> <span class="nx">obj</span><span class="p">[</span><span class="mi">2</span><span class="p">])</span> <span class="k">then</span> <span class="nv">locationData = </span><span class="nx">obj</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span>
<span class="k">else</span> <span class="k">if</span> <span class="s">&quot;first_line&quot;</span> <span class="k">of</span> <span class="nx">obj</span> <span class="k">then</span> <span class="nv">locationData = </span><span class="nx">obj</span>
<span class="k">if</span> <span class="nx">locationData</span>
<span class="s">&quot;</span><span class="si">#{</span><span class="nx">locationData</span><span class="p">.</span><span class="nx">first_line</span> <span class="o">+</span> <span class="mi">1</span><span class="si">}</span><span class="s">:</span><span class="si">#{</span><span class="nx">locationData</span><span class="p">.</span><span class="nx">first_column</span> <span class="o">+</span> <span class="mi">1</span><span class="si">}</span><span class="s">-&quot;</span> <span class="o">+</span>
<span class="s">&quot;</span><span class="si">#{</span><span class="nx">locationData</span><span class="p">.</span><span class="nx">last_line</span> <span class="o">+</span> <span class="mi">1</span><span class="si">}</span><span class="s">:</span><span class="si">#{</span><span class="nx">locationData</span><span class="p">.</span><span class="nx">last_column</span> <span class="o">+</span> <span class="mi">1</span><span class="si">}</span><span class="s">&quot;</span>
<span class="k">else</span>
<span class="s">&quot;No location data&quot;</span>
</pre></div> </td> </tr> </tbody> </table> </div> </body> </html>

View File

@@ -1,3 +1,3 @@
<!DOCTYPE html> <html> <head> <title>index.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> index.coffee </h1> </th> <th class="code"> </th> </tr> </thead> <tbody> <tr id="section-1"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-1">&#182;</a> </div> <p>Loader for CoffeeScript as a Node.js library.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nx">exports</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="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">require</span> <span class="s">&#39;./coffee-script&#39;</span>
<!DOCTYPE html> <html> <head> <title>index.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> </div> </div> </div> <table cellpadding="0" cellspacing="0"> <thead> <tr> <th class="docs"> <h1> index.coffee </h1> </th> <th class="code"> </th> </tr> </thead> <tbody> <tr id="section-1"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-1">&#182;</a> </div> <p>Loader for CoffeeScript as a Node.js library.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nx">exports</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="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">require</span> <span class="s">&#39;./coffee-script&#39;</span>
</pre></div> </td> </tr> </tbody> </table> </div> </body> </html>

File diff suppressed because one or more lines are too long

View File

@@ -1,13 +1,12 @@
<!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="pilwrap"> <a class="pilcrow" href="#section-1">&#182;</a> </div> <p><code>nodes.coffee</code> contains all of the node classes for the syntax tree. Most
<!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> </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="pilwrap"> <a class="pilcrow" href="#section-1">&#182;</a> </div> <p><code>nodes.coffee</code> contains all of the node classes for the syntax tree. Most
nodes are created as the result of actions in the <a href="grammar.html">grammar</a>,
but some are created by other nodes as a method of code generation. To convert
the syntax tree into a string of JavaScript code, call <code>compile()</code> on the root.</p> </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="s">&#39;./scope&#39;</span>
<span class="p">{</span><span class="nx">RESERVED</span><span class="p">,</span> <span class="nx">STRICT_PROSCRIBED</span><span class="p">}</span> <span class="o">=</span> <span class="nx">require</span> <span class="s">&#39;./lexer&#39;</span></pre></div> </td> </tr> <tr id="section-2"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-2">&#182;</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">extend</span><span class="p">,</span> <span class="nx">merge</span><span class="p">,</span> <span class="nx">del</span><span class="p">,</span> <span class="nx">starts</span><span class="p">,</span> <span class="nx">ends</span><span class="p">,</span> <span class="nx">last</span><span class="p">,</span> <span class="nx">some</span><span class="p">}</span> <span class="o">=</span> <span class="nx">require</span> <span class="s">&#39;./helpers&#39;</span>
<span class="nv">exports.extend = </span><span class="nx">extend</span> <span class="c1"># for parser</span></pre></div> </td> </tr> <tr id="section-3"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-3">&#182;</a> </div> <p>Constant functions for nodes that don't need customization.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">YES = </span><span class="nf">-&gt;</span> <span class="kc">yes</span>
<span class="p">{</span><span class="nx">RESERVED</span><span class="p">,</span> <span class="nx">STRICT_PROSCRIBED</span><span class="p">}</span> <span class="o">=</span> <span class="nx">require</span> <span class="s">&#39;./lexer&#39;</span></pre></div> </td> </tr> <tr id="section-2"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-2">&#182;</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">extend</span><span class="p">,</span> <span class="nx">merge</span><span class="p">,</span> <span class="nx">del</span><span class="p">,</span> <span class="nx">starts</span><span class="p">,</span> <span class="nx">ends</span><span class="p">,</span> <span class="nx">last</span><span class="p">,</span> <span class="nx">some</span><span class="p">,</span> <span class="nx">addLocationDataFn</span><span class="p">,</span> <span class="nx">locationDataToString</span><span class="p">}</span> <span class="o">=</span> <span class="nx">require</span> <span class="s">&#39;./helpers&#39;</span></pre></div> </td> </tr> <tr id="section-3"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-3">&#182;</a> </div> <p>Functions required by parser</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.extend = </span><span class="nx">extend</span>
<span class="nv">exports.addLocationDataFn = </span><span class="nx">addLocationDataFn</span></pre></div> </td> </tr> <tr id="section-4"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-4">&#182;</a> </div> <p>Constant functions for nodes that don't need customization.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">YES = </span><span class="nf">-&gt;</span> <span class="kc">yes</span>
<span class="nv">NO = </span><span class="nf">-&gt;</span> <span class="kc">no</span>
<span class="nv">THIS = </span><span class="nf">-&gt;</span> <span class="k">this</span>
<span class="nv">NEGATE = </span><span class="nf">-&gt;</span> <span class="vi">@negated = </span><span class="o">not</span> <span class="nx">@negated</span><span class="p">;</span> <span class="k">this</span></pre></div> </td> </tr> <tr id="section-4"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-4">&#182;</a> </div> <h3>Base</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-5"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-5">&#182;</a> </div> <p>The <strong>Base</strong> is the abstract base class for all nodes in the syntax tree.
<span class="nv">NEGATE = </span><span class="nf">-&gt;</span> <span class="vi">@negated = </span><span class="o">not</span> <span class="nx">@negated</span><span class="p">;</span> <span class="k">this</span></pre></div> </td> </tr> <tr id="section-5"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-5">&#182;</a> </div> <h3>Base</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-6"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-6">&#182;</a> </div> <p>The <strong>Base</strong> is the abstract base class for all nodes in the syntax tree.
Each subclass implements the <code>compileNode</code> method, which performs the
code generation for that node. To compile a node to JavaScript,
call <code>compile</code> on it, which wraps <code>compileNode</code> in some generic extra smarts,
@@ -15,7 +14,7 @@ to know when the generated code needs to be wrapped up in a closure.
An options hash is passed and cloned throughout, containing information about
the environment from higher in the tree (such as if a returned value is
being requested by the surrounding function), information about the current
scope, and indentation level.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.Base = </span><span class="k">class</span> <span class="nx">Base</span></pre></div> </td> </tr> <tr id="section-6"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-6">&#182;</a> </div> <p>Common logic for determining whether to wrap this node in a closure before
scope, and indentation level.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.Base = </span><span class="k">class</span> <span class="nx">Base</span></pre></div> </td> </tr> <tr id="section-7"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-7">&#182;</a> </div> <p>Common logic for determining whether to wrap this node in a closure before
compiling it, or to compile directly. We need to wrap if this node is a
<em>statement</em>, and it'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
@@ -28,12 +27,12 @@ return results).</p> </td> <td class="code">
<span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">level</span> <span class="o">is</span> <span class="nx">LEVEL_TOP</span> <span class="o">or</span> <span class="o">not</span> <span class="nx">node</span><span class="p">.</span><span class="nx">isStatement</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">compileNode</span> <span class="nx">o</span>
<span class="k">else</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">compileClosure</span> <span class="nx">o</span></pre></div> </td> </tr> <tr id="section-7"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-7">&#182;</a> </div> <p>Statements converted into expressions via closure-wrapping share a scope
<span class="nx">node</span><span class="p">.</span><span class="nx">compileClosure</span> <span class="nx">o</span></pre></div> </td> </tr> <tr id="section-8"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-8">&#182;</a> </div> <p>Statements converted into expressions via closure-wrapping share a scope
object with their parent closure, to preserve the expected lexical scope.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compileClosure: </span><span class="nf">(o) -&gt;</span>
<span class="k">if</span> <span class="nx">@jumps</span><span class="p">()</span>
<span class="k">throw</span> <span class="nx">SyntaxError</span> <span class="s">&#39;cannot use a pure statement in an expression.&#39;</span>
<span class="nv">o.sharedScope = </span><span class="kc">yes</span>
<span class="nx">Closure</span><span class="p">.</span><span class="nx">wrap</span><span class="p">(</span><span class="k">this</span><span class="p">).</span><span class="nx">compileNode</span> <span class="nx">o</span></pre></div> </td> </tr> <tr id="section-8"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-8">&#182;</a> </div> <p>If the code generation wishes to use the result of a complex expression
<span class="nx">Closure</span><span class="p">.</span><span class="nx">wrap</span><span class="p">(</span><span class="k">this</span><span class="p">).</span><span class="nx">compileNode</span> <span class="nx">o</span></pre></div> </td> </tr> <tr id="section-9"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-9">&#182;</a> </div> <p>If the code generation wishes to use the result of a complex expression
in multiple places, ensure that the expression is only ever evaluated once,
by assigning it to a temporary variable. Pass a level to precompile.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">cache: </span><span class="nf">(o, level, reused) -&gt;</span>
<span class="k">unless</span> <span class="nx">@isComplex</span><span class="p">()</span>
@@ -42,11 +41,7 @@ by assigning it to a temporary variable. Pass a level to precompile.</p>
<span class="k">else</span>
<span class="nv">ref = </span><span class="k">new</span> <span class="nx">Literal</span> <span class="nx">reused</span> <span class="o">or</span> <span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span> <span class="s">&#39;ref&#39;</span>
<span class="nv">sub = </span><span class="k">new</span> <span class="nx">Assign</span> <span class="nx">ref</span><span class="p">,</span> <span class="k">this</span>
<span class="k">if</span> <span class="nx">level</span> <span class="k">then</span> <span class="p">[</span><span class="nx">sub</span><span class="p">.</span><span class="nx">compile</span><span class="p">(</span><span class="nx">o</span><span class="p">,</span> <span class="nx">level</span><span class="p">),</span> <span class="nx">ref</span><span class="p">.</span><span class="nx">value</span><span class="p">]</span> <span class="k">else</span> <span class="p">[</span><span class="nx">sub</span><span class="p">,</span> <span class="nx">ref</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-9"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-9">&#182;</a> </div> <p>Compile to a source/variable pair suitable for looping.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compileLoopReference: </span><span class="nf">(o, name) -&gt;</span>
<span class="nv">src = tmp = </span><span class="nx">@compile</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_LIST</span>
<span class="k">unless</span> <span class="o">-</span><span class="kc">Infinity</span> <span class="o">&lt;</span> <span class="o">+</span><span class="nx">src</span> <span class="o">&lt;</span> <span class="kc">Infinity</span> <span class="o">or</span> <span class="nx">IDENTIFIER</span><span class="p">.</span><span class="nx">test</span><span class="p">(</span><span class="nx">src</span><span class="p">)</span> <span class="o">and</span> <span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">check</span><span class="p">(</span><span class="nx">src</span><span class="p">,</span> <span class="kc">yes</span><span class="p">)</span>
<span class="nv">src = </span><span class="s">&quot;</span><span class="si">#{</span> <span class="nv">tmp = </span><span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span> <span class="nx">name</span> <span class="si">}</span><span class="s"> = </span><span class="si">#{</span><span class="nx">src</span><span class="si">}</span><span class="s">&quot;</span>
<span class="p">[</span><span class="nx">src</span><span class="p">,</span> <span class="nx">tmp</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-10"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-10">&#182;</a> </div> <p>Construct a node that returns the current node's result.
<span class="k">if</span> <span class="nx">level</span> <span class="k">then</span> <span class="p">[</span><span class="nx">sub</span><span class="p">.</span><span class="nx">compile</span><span class="p">(</span><span class="nx">o</span><span class="p">,</span> <span class="nx">level</span><span class="p">),</span> <span class="nx">ref</span><span class="p">.</span><span class="nx">value</span><span class="p">]</span> <span class="k">else</span> <span class="p">[</span><span class="nx">sub</span><span class="p">,</span> <span class="nx">ref</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-10"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-10">&#182;</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 (e.g. If, For)...</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">makeReturn: </span><span class="nf">(res) -&gt;</span>
<span class="nv">me = </span><span class="nx">@unwrapAll</span><span class="p">()</span>
@@ -68,7 +63,8 @@ scope boundaries.</p> </td> <td class="code">
<span class="k">return</span> <span class="nx">list</span><span class="p">[</span><span class="nx">i</span><span class="p">]</span> <span class="k">while</span> <span class="nx">i</span><span class="o">--</span> <span class="k">when</span> <span class="nx">list</span><span class="p">[</span><span class="nx">i</span><span class="p">]</span> <span class="o">not</span> <span class="k">instanceof</span> <span class="nx">Comment</span>
<span class="kc">null</span></pre></div> </td> </tr> <tr id="section-14"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-14">&#182;</a> </div> <p><code>toString</code> representation of the node, for inspecting the parse tree.
This is what <code>coffee --nodes</code> prints out.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">toString: </span><span class="nf">(idt = &#39;&#39;, name = @constructor.name) -&gt;</span>
<span class="nv">tree = </span><span class="s">&#39;\n&#39;</span> <span class="o">+</span> <span class="nx">idt</span> <span class="o">+</span> <span class="nx">name</span>
<span class="nv">location = </span><span class="k">if</span> <span class="nx">@locationData</span> <span class="k">then</span> <span class="nx">locationDataToString</span> <span class="nx">@locationData</span> <span class="k">else</span> <span class="s">&quot;??&quot;</span>
<span class="nv">tree = </span><span class="s">&#39;\n&#39;</span> <span class="o">+</span> <span class="nx">idt</span> <span class="o">+</span> <span class="nx">location</span> <span class="o">+</span> <span class="s">&quot;: &quot;</span> <span class="o">+</span> <span class="nx">name</span>
<span class="nx">tree</span> <span class="o">+=</span> <span class="s">&#39;?&#39;</span> <span class="k">if</span> <span class="nx">@soak</span>
<span class="nx">@eachChild</span> <span class="nf">(node) -&gt;</span> <span class="nx">tree</span> <span class="o">+=</span> <span class="nx">node</span><span class="p">.</span><span class="nx">toString</span> <span class="nx">idt</span> <span class="o">+</span> <span class="nx">TAB</span>
<span class="nx">tree</span></pre></div> </td> </tr> <tr id="section-15"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-15">&#182;</a> </div> <p>Passes each child to a function, breaking when the function returns <code>false</code>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">eachChild: </span><span class="nf">(func) -&gt;</span>
@@ -84,7 +80,7 @@ This is what <code>coffee --nodes</code> prints out.</p> </td>
<span class="nx">child</span><span class="p">.</span><span class="nx">traverseChildren</span> <span class="nx">crossScope</span><span class="p">,</span> <span class="nx">func</span>
<span class="nv">invert: </span><span class="nf">-&gt;</span>
<span class="k">new</span> <span class="nx">Op</span> <span class="s">&#39;!&#39;</span><span class="p">,</span> <span class="k">this</span>
<span class="nx">Op</span><span class="p">.</span><span class="nx">create</span> <span class="s">&#39;!&#39;</span><span class="p">,</span> <span class="k">this</span>
<span class="nv">unwrapAll: </span><span class="nf">-&gt;</span>
<span class="nv">node = </span><span class="k">this</span>
@@ -99,20 +95,27 @@ will override these with custom logic, if needed.</p> </td>
<span class="nv">isAssignable : </span><span class="nx">NO</span>
<span class="nv">unwrap : </span><span class="nx">THIS</span>
<span class="nv">unfoldSoak : </span><span class="nx">NO</span></pre></div> </td> </tr> <tr id="section-17"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-17">&#182;</a> </div> <p>Is this node used to assign a certain variable?</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">assigns: </span><span class="nx">NO</span></pre></div> </td> </tr> <tr id="section-18"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-18">&#182;</a> </div> <h3>Block</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-19"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-19">&#182;</a> </div> <p>The block is the list of expressions that forms the body of an
<span class="nv">unfoldSoak : </span><span class="nx">NO</span></pre></div> </td> </tr> <tr id="section-17"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-17">&#182;</a> </div> <p>Is this node used to assign a certain variable?</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">assigns: </span><span class="nx">NO</span></pre></div> </td> </tr> <tr id="section-18"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-18">&#182;</a> </div> <p>For this node and all descendents, set the location data to <code>locationData</code> if the location
data is not already set.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">updateLocationDataIfMissing: </span><span class="nf">(locationData) -&gt;</span>
<span class="k">if</span> <span class="o">not</span> <span class="nx">@locationData</span>
<span class="vi">@locationData = </span><span class="p">{}</span>
<span class="nx">extend</span> <span class="nx">@locationData</span><span class="p">,</span> <span class="nx">locationData</span>
<span class="nx">@eachChild</span> <span class="nf">(child) -&gt;</span>
<span class="nx">child</span><span class="p">.</span><span class="nx">updateLocationDataIfMissing</span> <span class="nx">locationData</span></pre></div> </td> </tr> <tr id="section-19"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-19">&#182;</a> </div> <h3>Block</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-20"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-20">&#182;</a> </div> <p>The block is the list of expressions that forms the body of an
indented block of code -- the implementation of a function, a clause in an
<code>if</code>, <code>switch</code>, or <code>try</code>, and so on...</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.Block = </span><span class="k">class</span> <span class="nx">Block</span> <span class="k">extends</span> <span class="nx">Base</span>
<span class="nv">constructor: </span><span class="nf">(nodes) -&gt;</span>
<span class="vi">@expressions = </span><span class="nx">compact</span> <span class="nx">flatten</span> <span class="nx">nodes</span> <span class="o">or</span> <span class="p">[]</span>
<span class="nv">children: </span><span class="p">[</span><span class="s">&#39;expressions&#39;</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-20"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-20">&#182;</a> </div> <p>Tack an expression on to the end of this expression list.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">push: </span><span class="nf">(node) -&gt;</span>
<span class="nv">children: </span><span class="p">[</span><span class="s">&#39;expressions&#39;</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-21"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-21">&#182;</a> </div> <p>Tack an expression on to the end of this expression list.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">push: </span><span class="nf">(node) -&gt;</span>
<span class="nx">@expressions</span><span class="p">.</span><span class="nx">push</span> <span class="nx">node</span>
<span class="k">this</span></pre></div> </td> </tr> <tr id="section-21"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-21">&#182;</a> </div> <p>Remove and return the last expression of this expression list.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">pop: </span><span class="nf">-&gt;</span>
<span class="nx">@expressions</span><span class="p">.</span><span class="nx">pop</span><span class="p">()</span></pre></div> </td> </tr> <tr id="section-22"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-22">&#182;</a> </div> <p>Add an expression at the beginning of this expression list.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">unshift: </span><span class="nf">(node) -&gt;</span>
<span class="k">this</span></pre></div> </td> </tr> <tr id="section-22"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-22">&#182;</a> </div> <p>Remove and return the last expression of this expression list.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">pop: </span><span class="nf">-&gt;</span>
<span class="nx">@expressions</span><span class="p">.</span><span class="nx">pop</span><span class="p">()</span></pre></div> </td> </tr> <tr id="section-23"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-23">&#182;</a> </div> <p>Add an expression at the beginning of this expression list.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">unshift: </span><span class="nf">(node) -&gt;</span>
<span class="nx">@expressions</span><span class="p">.</span><span class="nx">unshift</span> <span class="nx">node</span>
<span class="k">this</span></pre></div> </td> </tr> <tr id="section-23"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-23">&#182;</a> </div> <p>If this Block consists of just a single node, unwrap it by pulling
<span class="k">this</span></pre></div> </td> </tr> <tr id="section-24"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-24">&#182;</a> </div> <p>If this Block consists of just a single node, unwrap it by pulling
it back out.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">unwrap: </span><span class="nf">-&gt;</span>
<span class="k">if</span> <span class="nx">@expressions</span><span class="p">.</span><span class="nx">length</span> <span class="o">is</span> <span class="mi">1</span> <span class="k">then</span> <span class="nx">@expressions</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">else</span> <span class="k">this</span></pre></div> </td> </tr> <tr id="section-24"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-24">&#182;</a> </div> <p>Is this an empty block of code?</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">isEmpty: </span><span class="nf">-&gt;</span>
<span class="k">if</span> <span class="nx">@expressions</span><span class="p">.</span><span class="nx">length</span> <span class="o">is</span> <span class="mi">1</span> <span class="k">then</span> <span class="nx">@expressions</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">else</span> <span class="k">this</span></pre></div> </td> </tr> <tr id="section-25"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-25">&#182;</a> </div> <p>Is this an empty block of code?</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">isEmpty: </span><span class="nf">-&gt;</span>
<span class="o">not</span> <span class="nx">@expressions</span><span class="p">.</span><span class="nx">length</span>
<span class="nv">isStatement: </span><span class="nf">(o) -&gt;</span>
@@ -122,7 +125,7 @@ it back out.</p> </td> <td class="code"> <
<span class="nv">jumps: </span><span class="nf">(o) -&gt;</span>
<span class="k">for</span> <span class="nx">exp</span> <span class="k">in</span> <span class="nx">@expressions</span>
<span class="k">return</span> <span class="nx">exp</span> <span class="k">if</span> <span class="nx">exp</span><span class="p">.</span><span class="nx">jumps</span> <span class="nx">o</span></pre></div> </td> </tr> <tr id="section-25"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-25">&#182;</a> </div> <p>A Block node does not return its entire body, rather it
<span class="k">return</span> <span class="nx">exp</span> <span class="k">if</span> <span class="nx">exp</span><span class="p">.</span><span class="nx">jumps</span> <span class="nx">o</span></pre></div> </td> </tr> <tr id="section-26"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-26">&#182;</a> </div> <p>A Block node does not return its entire body, rather it
ensures that the final expression is returned.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">makeReturn: </span><span class="nf">(res) -&gt;</span>
<span class="nv">len = </span><span class="nx">@expressions</span><span class="p">.</span><span class="nx">length</span>
<span class="k">while</span> <span class="nx">len</span><span class="o">--</span>
@@ -131,8 +134,8 @@ ensures that the final expression is returned.</p> </td>
<span class="nx">@expressions</span><span class="p">[</span><span class="nx">len</span><span class="p">]</span> <span class="o">=</span> <span class="nx">expr</span><span class="p">.</span><span class="nx">makeReturn</span> <span class="nx">res</span>
<span class="nx">@expressions</span><span class="p">.</span><span class="nx">splice</span><span class="p">(</span><span class="nx">len</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span> <span class="k">if</span> <span class="nx">expr</span> <span class="k">instanceof</span> <span class="nx">Return</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">expr</span><span class="p">.</span><span class="nx">expression</span>
<span class="k">break</span>
<span class="k">this</span></pre></div> </td> </tr> <tr id="section-26"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-26">&#182;</a> </div> <p>A <strong>Block</strong> is the only node that can serve as the root.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compile: </span><span class="nf">(o = {}, level) -&gt;</span>
<span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">scope</span> <span class="k">then</span> <span class="k">super</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">level</span> <span class="k">else</span> <span class="nx">@compileRoot</span> <span class="nx">o</span></pre></div> </td> </tr> <tr id="section-27"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-27">&#182;</a> </div> <p>Compile all expressions within the <strong>Block</strong> body. If we need to
<span class="k">this</span></pre></div> </td> </tr> <tr id="section-27"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-27">&#182;</a> </div> <p>A <strong>Block</strong> is the only node that can serve as the root.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compile: </span><span class="nf">(o = {}, level) -&gt;</span>
<span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">scope</span> <span class="k">then</span> <span class="k">super</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">level</span> <span class="k">else</span> <span class="nx">@compileRoot</span> <span class="nx">o</span></pre></div> </td> </tr> <tr id="section-28"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-28">&#182;</a> </div> <p>Compile all expressions within the <strong>Block</strong> body. If we need to
return the result, and it's an expression, simply return it. If it's a
statement, ask the statement to do so.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compileNode: </span><span class="nf">(o) -&gt;</span>
<span class="vi">@tab = </span><span class="nx">o</span><span class="p">.</span><span class="nx">indent</span>
@@ -141,7 +144,7 @@ statement, ask the statement to do so.</p> </td> <td cla
<span class="k">for</span> <span class="nx">node</span> <span class="k">in</span> <span class="nx">@expressions</span>
<span class="nv">node = </span><span class="nx">node</span><span class="p">.</span><span class="nx">unwrapAll</span><span class="p">()</span>
<span class="nv">node = </span><span class="p">(</span><span class="nx">node</span><span class="p">.</span><span class="nx">unfoldSoak</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">or</span> <span class="nx">node</span><span class="p">)</span>
<span class="k">if</span> <span class="nx">node</span> <span class="k">instanceof</span> <span class="nx">Block</span></pre></div> </td> </tr> <tr id="section-28"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-28">&#182;</a> </div> <p>This is a nested block. We don't do anything special here like enclose
<span class="k">if</span> <span class="nx">node</span> <span class="k">instanceof</span> <span class="nx">Block</span></pre></div> </td> </tr> <tr id="section-29"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-29">&#182;</a> </div> <p>This is a nested block. We don't do anything special here like enclose
it in a new scope; we just compile the statements in this block along with
our own</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">codes</span><span class="p">.</span><span class="nx">push</span> <span class="nx">node</span><span class="p">.</span><span class="nx">compileNode</span> <span class="nx">o</span>
<span class="k">else</span> <span class="k">if</span> <span class="nx">top</span>
@@ -149,7 +152,6 @@ our own</p> </td> <td class="code"> <div c
<span class="nv">code = </span><span class="nx">node</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">o</span>
<span class="k">unless</span> <span class="nx">node</span><span class="p">.</span><span class="nx">isStatement</span> <span class="nx">o</span>
<span class="nv">code = </span><span class="s">&quot;</span><span class="si">#{</span><span class="nx">@tab</span><span class="si">}#{</span><span class="nx">code</span><span class="si">}</span><span class="s">;&quot;</span>
<span class="nv">code = </span><span class="s">&quot;</span><span class="si">#{</span><span class="nx">code</span><span class="si">}</span><span class="s">\n&quot;</span> <span class="k">if</span> <span class="nx">node</span> <span class="k">instanceof</span> <span class="nx">Literal</span>
<span class="nx">codes</span><span class="p">.</span><span class="nx">push</span> <span class="nx">code</span>
<span class="k">else</span>
<span class="nx">codes</span><span class="p">.</span><span class="nx">push</span> <span class="nx">node</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_LIST</span>
@@ -159,7 +161,7 @@ our own</p> </td> <td class="code"> <div c
<span class="k">else</span>
<span class="k">return</span> <span class="nx">codes</span><span class="p">.</span><span class="nx">join</span> <span class="s">&#39;\n&#39;</span>
<span class="nv">code = </span><span class="nx">codes</span><span class="p">.</span><span class="nx">join</span><span class="p">(</span><span class="s">&#39;, &#39;</span><span class="p">)</span> <span class="o">or</span> <span class="s">&#39;void 0&#39;</span>
<span class="k">if</span> <span class="nx">codes</span><span class="p">.</span><span class="nx">length</span> <span class="o">&gt;</span> <span class="mi">1</span> <span class="o">and</span> <span class="nx">o</span><span class="p">.</span><span class="nx">level</span> <span class="o">&gt;=</span> <span class="nx">LEVEL_LIST</span> <span class="k">then</span> <span class="s">&quot;(</span><span class="si">#{</span><span class="nx">code</span><span class="si">}</span><span class="s">)&quot;</span> <span class="k">else</span> <span class="nx">code</span></pre></div> </td> </tr> <tr id="section-29"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-29">&#182;</a> </div> <p>If we happen to be the top-level <strong>Block</strong>, wrap everything in
<span class="k">if</span> <span class="nx">codes</span><span class="p">.</span><span class="nx">length</span> <span class="o">&gt;</span> <span class="mi">1</span> <span class="o">and</span> <span class="nx">o</span><span class="p">.</span><span class="nx">level</span> <span class="o">&gt;=</span> <span class="nx">LEVEL_LIST</span> <span class="k">then</span> <span class="s">&quot;(</span><span class="si">#{</span><span class="nx">code</span><span class="si">}</span><span class="s">)&quot;</span> <span class="k">else</span> <span class="nx">code</span></pre></div> </td> </tr> <tr id="section-30"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-30">&#182;</a> </div> <p>If we happen to be the top-level <strong>Block</strong>, wrap everything in
a safety closure, unless requested not to.
It would be better not to generate them in the first place, but for now,
clean up obvious double-parentheses.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compileRoot: </span><span class="nf">(o) -&gt;</span>
@@ -178,7 +180,7 @@ clean up obvious double-parentheses.</p> </td> <td class
<span class="vi">@expressions = </span><span class="nx">rest</span>
<span class="nv">code = </span><span class="nx">@compileWithDeclarations</span> <span class="nx">o</span>
<span class="k">return</span> <span class="nx">code</span> <span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">bare</span>
<span class="s">&quot;</span><span class="si">#{</span><span class="nx">prelude</span><span class="si">}</span><span class="s">(function() {\n</span><span class="si">#{</span><span class="nx">code</span><span class="si">}</span><span class="s">\n}).call(this);\n&quot;</span></pre></div> </td> </tr> <tr id="section-30"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-30">&#182;</a> </div> <p>Compile the expressions body for the contents of a function, with
<span class="s">&quot;</span><span class="si">#{</span><span class="nx">prelude</span><span class="si">}</span><span class="s">(function() {\n</span><span class="si">#{</span><span class="nx">code</span><span class="si">}</span><span class="s">\n}).call(this);\n&quot;</span></pre></div> </td> </tr> <tr id="section-31"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-31">&#182;</a> </div> <p>Compile the expressions body for the contents of a function, with
declarations of all inner variables pushed up to the top.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compileWithDeclarations: </span><span class="nf">(o) -&gt;</span>
<span class="nv">code = post = </span><span class="s">&#39;&#39;</span>
<span class="k">for</span> <span class="nx">exp</span><span class="p">,</span> <span class="nx">i</span> <span class="k">in</span> <span class="nx">@expressions</span>
@@ -204,10 +206,10 @@ declarations of all inner variables pushed up to the top.</p> </td>
<span class="nx">code</span> <span class="o">+=</span> <span class="s">&quot;,\n</span><span class="si">#{</span><span class="nx">@tab</span> <span class="o">+</span> <span class="nx">TAB</span><span class="si">}</span><span class="s">&quot;</span> <span class="k">if</span> <span class="nx">declars</span>
<span class="nx">code</span> <span class="o">+=</span> <span class="nx">scope</span><span class="p">.</span><span class="nx">assignedVariables</span><span class="p">().</span><span class="nx">join</span> <span class="s">&quot;,\n</span><span class="si">#{</span><span class="nx">@tab</span> <span class="o">+</span> <span class="nx">TAB</span><span class="si">}</span><span class="s">&quot;</span>
<span class="nx">code</span> <span class="o">+=</span> <span class="s">&#39;;\n&#39;</span>
<span class="nx">code</span> <span class="o">+</span> <span class="nx">post</span></pre></div> </td> </tr> <tr id="section-31"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-31">&#182;</a> </div> <p>Wrap up the given nodes as a <strong>Block</strong>, unless it already happens
<span class="nx">code</span> <span class="o">+</span> <span class="nx">post</span></pre></div> </td> </tr> <tr id="section-32"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-32">&#182;</a> </div> <p>Wrap up the given nodes as a <strong>Block</strong>, unless it already happens
to be one.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="vi">@wrap: </span><span class="nf">(nodes) -&gt;</span>
<span class="k">return</span> <span class="nx">nodes</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">if</span> <span class="nx">nodes</span><span class="p">.</span><span class="nx">length</span> <span class="o">is</span> <span class="mi">1</span> <span class="o">and</span> <span class="nx">nodes</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">instanceof</span> <span class="nx">Block</span>
<span class="k">new</span> <span class="nx">Block</span> <span class="nx">nodes</span></pre></div> </td> </tr> <tr id="section-32"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-32">&#182;</a> </div> <h3>Literal</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-33"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-33">&#182;</a> </div> <p>Literals are static values that can be passed through directly into
<span class="k">new</span> <span class="nx">Block</span> <span class="nx">nodes</span></pre></div> </td> </tr> <tr id="section-33"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-33">&#182;</a> </div> <h3>Literal</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-34"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-34">&#182;</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.Literal = </span><span class="k">class</span> <span class="nx">Literal</span> <span class="k">extends</span> <span class="nx">Base</span>
<span class="nv">constructor: </span><span class="nf">(@value) -&gt;</span>
@@ -257,7 +259,7 @@ JavaScript without translation, such as: strings, numbers,
<span class="nv">isAssignable: </span><span class="nx">NO</span>
<span class="nv">isComplex: </span><span class="nx">NO</span>
<span class="nv">compileNode: </span><span class="nf">-&gt;</span> <span class="nx">@val</span>
<span class="nv">constructor: </span><span class="nf">(@val) -&gt;</span></pre></div> </td> </tr> <tr id="section-34"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-34">&#182;</a> </div> <h3>Return</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-35"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-35">&#182;</a> </div> <p>A <code>return</code> is a <em>pureStatement</em> -- wrapping it in a closure wouldn't
<span class="nv">constructor: </span><span class="nf">(@val) -&gt;</span></pre></div> </td> </tr> <tr id="section-35"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-35">&#182;</a> </div> <h3>Return</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-36"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-36">&#182;</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.Return = </span><span class="k">class</span> <span class="nx">Return</span> <span class="k">extends</span> <span class="nx">Base</span>
<span class="nv">constructor: </span><span class="nf">(expr) -&gt;</span>
<span class="vi">@expression = </span><span class="nx">expr</span> <span class="k">if</span> <span class="nx">expr</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">expr</span><span class="p">.</span><span class="nx">unwrap</span><span class="p">().</span><span class="nx">isUndefined</span>
@@ -273,21 +275,24 @@ make sense.</p> </td> <td class="code"> <d
<span class="k">if</span> <span class="nx">expr</span> <span class="o">and</span> <span class="nx">expr</span> <span class="o">not</span> <span class="k">instanceof</span> <span class="nx">Return</span> <span class="k">then</span> <span class="nx">expr</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">level</span> <span class="k">else</span> <span class="k">super</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">level</span>
<span class="nv">compileNode: </span><span class="nf">(o) -&gt;</span>
<span class="nx">@tab</span> <span class="o">+</span> <span class="s">&quot;return</span><span class="si">#{</span><span class="p">[</span><span class="s">&quot; </span><span class="si">#{</span><span class="nx">@expression</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_PAREN</span><span class="si">}</span><span class="s">&quot;</span> <span class="k">if</span> <span class="nx">@expression</span><span class="p">]</span><span class="si">}</span><span class="s">;&quot;</span></pre></div> </td> </tr> <tr id="section-36"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-36">&#182;</a> </div> <h3>Value</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-37"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-37">&#182;</a> </div> <p>A value, variable or literal or parenthesized, indexed or dotted into,
<span class="nx">@tab</span> <span class="o">+</span> <span class="s">&quot;return</span><span class="si">#{</span><span class="p">[</span><span class="s">&quot; </span><span class="si">#{</span><span class="nx">@expression</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_PAREN</span><span class="si">}</span><span class="s">&quot;</span> <span class="k">if</span> <span class="nx">@expression</span><span class="p">]</span><span class="si">}</span><span class="s">;&quot;</span></pre></div> </td> </tr> <tr id="section-37"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-37">&#182;</a> </div> <h3>Value</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-38"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-38">&#182;</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.Value = </span><span class="k">class</span> <span class="nx">Value</span> <span class="k">extends</span> <span class="nx">Base</span>
<span class="nv">constructor: </span><span class="nf">(base, props, tag) -&gt;</span>
<span class="k">return</span> <span class="nx">base</span> <span class="k">if</span> <span class="o">not</span> <span class="nx">props</span> <span class="o">and</span> <span class="nx">base</span> <span class="k">instanceof</span> <span class="nx">Value</span>
<span class="vi">@base = </span><span class="nx">base</span>
<span class="vi">@properties = </span><span class="nx">props</span> <span class="o">or</span> <span class="p">[]</span>
<span class="nx">@</span><span class="p">[</span><span class="nx">tag</span><span class="p">]</span> <span class="o">=</span> <span class="kc">true</span> <span class="k">if</span> <span class="nx">tag</span>
<span class="k">return</span> <span class="k">this</span>
<span class="vi">@wrap: </span><span class="nf">(base, props, tag) -&gt;</span>
<span class="k">if</span> <span class="o">not</span> <span class="nx">props</span> <span class="o">and</span> <span class="nx">base</span> <span class="k">instanceof</span> <span class="nx">Value</span>
<span class="nx">base</span>
<span class="k">else</span>
<span class="k">new</span> <span class="nx">Value</span> <span class="nx">base</span><span class="p">,</span> <span class="nx">props</span><span class="p">,</span> <span class="nx">tag</span>
<span class="nv">children: </span><span class="p">[</span><span class="s">&#39;base&#39;</span><span class="p">,</span> <span class="s">&#39;properties&#39;</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-38"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-38">&#182;</a> </div> <p>Add a property (or <em>properties</em> ) <code>Access</code> to the list.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">add: </span><span class="nf">(props) -&gt;</span>
<span class="nv">constructor: </span><span class="nf">(@base, @properties, tag) -&gt;</span>
<span class="nx">@properties</span> <span class="o">or=</span> <span class="p">[]</span>
<span class="vi">@this = </span><span class="kc">true</span> <span class="k">if</span> <span class="nx">tag</span> <span class="o">is</span> <span class="s">&#39;this&#39;</span>
<span class="nv">children: </span><span class="p">[</span><span class="s">&#39;base&#39;</span><span class="p">,</span> <span class="s">&#39;properties&#39;</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-39"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-39">&#182;</a> </div> <p>Add a property (or <em>properties</em> ) <code>Access</code> to the list.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">add: </span><span class="nf">(props) -&gt;</span>
<span class="vi">@properties = </span><span class="nx">@properties</span><span class="p">.</span><span class="nx">concat</span> <span class="nx">props</span>
<span class="k">this</span>
<span class="nv">hasProperties: </span><span class="nf">-&gt;</span>
<span class="o">!!</span><span class="nx">@properties</span><span class="p">.</span><span class="nx">length</span></pre></div> </td> </tr> <tr id="section-39"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-39">&#182;</a> </div> <p>Some boolean checks for the benefit of other nodes.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">isArray : </span><span class="nf">-&gt;</span> <span class="o">not</span> <span class="nx">@properties</span><span class="p">.</span><span class="nx">length</span> <span class="o">and</span> <span class="nx">@base</span> <span class="k">instanceof</span> <span class="nx">Arr</span>
<span class="o">!!</span><span class="nx">@properties</span><span class="p">.</span><span class="nx">length</span></pre></div> </td> </tr> <tr id="section-40"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-40">&#182;</a> </div> <p>Some boolean checks for the benefit of other nodes.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">isArray : </span><span class="nf">-&gt;</span> <span class="o">not</span> <span class="nx">@properties</span><span class="p">.</span><span class="nx">length</span> <span class="o">and</span> <span class="nx">@base</span> <span class="k">instanceof</span> <span class="nx">Arr</span>
<span class="nv">isComplex : </span><span class="nf">-&gt;</span> <span class="nx">@hasProperties</span><span class="p">()</span> <span class="o">or</span> <span class="nx">@base</span><span class="p">.</span><span class="nx">isComplex</span><span class="p">()</span>
<span class="nv">isAssignable : </span><span class="nf">-&gt;</span> <span class="nx">@hasProperties</span><span class="p">()</span> <span class="o">or</span> <span class="nx">@base</span><span class="p">.</span><span class="nx">isAssignable</span><span class="p">()</span>
<span class="nv">isSimpleNumber : </span><span class="nf">-&gt;</span> <span class="nx">@base</span> <span class="k">instanceof</span> <span class="nx">Literal</span> <span class="o">and</span> <span class="nx">SIMPLENUM</span><span class="p">.</span><span class="nx">test</span> <span class="nx">@base</span><span class="p">.</span><span class="nx">value</span>
@@ -306,24 +311,24 @@ or vanilla.</p> </td> <td class="code"> <d
<span class="p">(</span><span class="nx">@base</span> <span class="k">instanceof</span> <span class="nx">Obj</span><span class="p">)</span> <span class="o">and</span> <span class="p">(</span><span class="o">not</span> <span class="nx">onlyGenerated</span> <span class="o">or</span> <span class="nx">@base</span><span class="p">.</span><span class="nx">generated</span><span class="p">)</span>
<span class="nv">isSplice: </span><span class="nf">-&gt;</span>
<span class="nx">last</span><span class="p">(</span><span class="nx">@properties</span><span class="p">)</span> <span class="k">instanceof</span> <span class="nx">Slice</span></pre></div> </td> </tr> <tr id="section-40"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-40">&#182;</a> </div> <p>The value can be unwrapped as its inner node, if there are no attached
<span class="nx">last</span><span class="p">(</span><span class="nx">@properties</span><span class="p">)</span> <span class="k">instanceof</span> <span class="nx">Slice</span></pre></div> </td> </tr> <tr id="section-41"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-41">&#182;</a> </div> <p>The value can be unwrapped as its inner node, if there are no attached
properties.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">unwrap: </span><span class="nf">-&gt;</span>
<span class="k">if</span> <span class="nx">@properties</span><span class="p">.</span><span class="nx">length</span> <span class="k">then</span> <span class="k">this</span> <span class="k">else</span> <span class="nx">@base</span></pre></div> </td> </tr> <tr id="section-41"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-41">&#182;</a> </div> <p>A reference has base part (<code>this</code> value) and name part.
<span class="k">if</span> <span class="nx">@properties</span><span class="p">.</span><span class="nx">length</span> <span class="k">then</span> <span class="k">this</span> <span class="k">else</span> <span class="nx">@base</span></pre></div> </td> </tr> <tr id="section-42"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-42">&#182;</a> </div> <p>A reference has base part (<code>this</code> value) and name part.
We cache them separately for compiling complex expressions.
<code>a()[b()] ?= c</code> -> <code>(_base = a())[_name = b()] ? _base[_name] = c</code></p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">cacheReference: </span><span class="nf">(o) -&gt;</span>
<span class="nv">name = </span><span class="nx">last</span> <span class="nx">@properties</span>
<span class="k">if</span> <span class="nx">@properties</span><span class="p">.</span><span class="nx">length</span> <span class="o">&lt;</span> <span class="mi">2</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">@base</span><span class="p">.</span><span class="nx">isComplex</span><span class="p">()</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">name</span><span class="o">?</span><span class="p">.</span><span class="nx">isComplex</span><span class="p">()</span>
<span class="k">return</span> <span class="p">[</span><span class="k">this</span><span class="p">,</span> <span class="k">this</span><span class="p">]</span> <span class="c1"># `a` `a.b`</span>
<span class="nv">base = </span><span class="k">new</span> <span class="nx">Value</span> <span class="nx">@base</span><span class="p">,</span> <span class="nx">@properties</span><span class="p">[...</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
<span class="nv">base = </span><span class="nx">Value</span><span class="p">.</span><span class="nx">wrap</span> <span class="nx">@base</span><span class="p">,</span> <span class="nx">@properties</span><span class="p">[...</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
<span class="k">if</span> <span class="nx">base</span><span class="p">.</span><span class="nx">isComplex</span><span class="p">()</span> <span class="c1"># `a().b`</span>
<span class="nv">bref = </span><span class="k">new</span> <span class="nx">Literal</span> <span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span> <span class="s">&#39;base&#39;</span>
<span class="nv">base = </span><span class="k">new</span> <span class="nx">Value</span> <span class="k">new</span> <span class="nx">Parens</span> <span class="k">new</span> <span class="nx">Assign</span> <span class="nx">bref</span><span class="p">,</span> <span class="nx">base</span>
<span class="nv">base = </span><span class="nx">Value</span><span class="p">.</span><span class="nx">wrap</span> <span class="k">new</span> <span class="nx">Parens</span> <span class="k">new</span> <span class="nx">Assign</span> <span class="nx">bref</span><span class="p">,</span> <span class="nx">base</span>
<span class="k">return</span> <span class="p">[</span><span class="nx">base</span><span class="p">,</span> <span class="nx">bref</span><span class="p">]</span> <span class="k">unless</span> <span class="nx">name</span> <span class="c1"># `a()`</span>
<span class="k">if</span> <span class="nx">name</span><span class="p">.</span><span class="nx">isComplex</span><span class="p">()</span> <span class="c1"># `a[b()]`</span>
<span class="nv">nref = </span><span class="k">new</span> <span class="nx">Literal</span> <span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span> <span class="s">&#39;name&#39;</span>
<span class="nv">name = </span><span class="k">new</span> <span class="nx">Index</span> <span class="k">new</span> <span class="nx">Assign</span> <span class="nx">nref</span><span class="p">,</span> <span class="nx">name</span><span class="p">.</span><span class="nx">index</span>
<span class="nv">nref = </span><span class="k">new</span> <span class="nx">Index</span> <span class="nx">nref</span>
<span class="p">[</span><span class="nx">base</span><span class="p">.</span><span class="nx">add</span><span class="p">(</span><span class="nx">name</span><span class="p">),</span> <span class="k">new</span> <span class="nx">Value</span><span class="p">(</span><span class="nx">bref</span> <span class="o">or</span> <span class="nx">base</span><span class="p">.</span><span class="nx">base</span><span class="p">,</span> <span class="p">[</span><span class="nx">nref</span> <span class="o">or</span> <span class="nx">name</span><span class="p">])]</span></pre></div> </td> </tr> <tr id="section-42"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-42">&#182;</a> </div> <p>We compile a value to JavaScript by compiling and joining each property.
<span class="p">[</span><span class="nx">base</span><span class="p">.</span><span class="nx">add</span><span class="p">(</span><span class="nx">name</span><span class="p">),</span> <span class="nx">Value</span><span class="p">.</span><span class="nx">wrap</span><span class="p">(</span><span class="nx">bref</span> <span class="o">or</span> <span class="nx">base</span><span class="p">.</span><span class="nx">base</span><span class="p">,</span> <span class="p">[</span><span class="nx">nref</span> <span class="o">or</span> <span class="nx">name</span><span class="p">])]</span></pre></div> </td> </tr> <tr id="section-43"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-43">&#182;</a> </div> <p>We compile a value to JavaScript by compiling and joining each property.
Things get much more interesting if the chain of properties has <em>soak</em>
operators <code>?.</code> interspersed. Then we have to take care not to accidentally
evaluate anything twice when building the soak chain.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compileNode: </span><span class="nf">(o) -&gt;</span>
@@ -332,23 +337,21 @@ evaluate anything twice when building the soak chain.</p> </td>
<span class="nv">code = </span><span class="nx">@base</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">o</span><span class="p">,</span> <span class="k">if</span> <span class="nx">props</span><span class="p">.</span><span class="nx">length</span> <span class="k">then</span> <span class="nx">LEVEL_ACCESS</span> <span class="k">else</span> <span class="kc">null</span>
<span class="nv">code = </span><span class="s">&quot;</span><span class="si">#{</span><span class="nx">code</span><span class="si">}</span><span class="s">.&quot;</span> <span class="k">if</span> <span class="p">(</span><span class="nx">@base</span> <span class="k">instanceof</span> <span class="nx">Parens</span> <span class="o">or</span> <span class="nx">props</span><span class="p">.</span><span class="nx">length</span><span class="p">)</span> <span class="o">and</span> <span class="nx">SIMPLENUM</span><span class="p">.</span><span class="nx">test</span> <span class="nx">code</span>
<span class="nx">code</span> <span class="o">+=</span> <span class="nx">prop</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">o</span> <span class="k">for</span> <span class="nx">prop</span> <span class="k">in</span> <span class="nx">props</span>
<span class="nx">code</span></pre></div> </td> </tr> <tr id="section-43"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-43">&#182;</a> </div> <p>Unfold a soak into an <code>If</code>: <code>a?.b</code> -> <code>a.b if a?</code></p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">unfoldSoak: </span><span class="nf">(o) -&gt;</span>
<span class="k">return</span> <span class="nx">@unfoldedSoak</span> <span class="k">if</span> <span class="nx">@unfoldedSoak</span><span class="o">?</span>
<span class="nv">result = </span><span class="nx">do</span> <span class="o">=&gt;</span>
<span class="nx">code</span></pre></div> </td> </tr> <tr id="section-44"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-44">&#182;</a> </div> <p>Unfold a soak into an <code>If</code>: <code>a?.b</code> -> <code>a.b if a?</code></p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">unfoldSoak: </span><span class="nf">(o) -&gt;</span>
<span class="nx">@unfoldedSoak</span> <span class="o">?=</span> <span class="nx">do</span> <span class="o">=&gt;</span>
<span class="k">if</span> <span class="nv">ifn = </span><span class="nx">@base</span><span class="p">.</span><span class="nx">unfoldSoak</span> <span class="nx">o</span>
<span class="nb">Array</span><span class="o">::</span><span class="nx">push</span><span class="p">.</span><span class="nx">apply</span> <span class="nx">ifn</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">properties</span><span class="p">,</span> <span class="nx">@properties</span>
<span class="nx">ifn</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">properties</span><span class="p">.</span><span class="nx">push</span> <span class="nx">@properties</span><span class="p">...</span>
<span class="k">return</span> <span class="nx">ifn</span>
<span class="k">for</span> <span class="nx">prop</span><span class="p">,</span> <span class="nx">i</span> <span class="k">in</span> <span class="nx">@properties</span> <span class="k">when</span> <span class="nx">prop</span><span class="p">.</span><span class="nx">soak</span>
<span class="nv">prop.soak = </span><span class="kc">off</span>
<span class="nv">fst = </span><span class="k">new</span> <span class="nx">Value</span> <span class="nx">@base</span><span class="p">,</span> <span class="nx">@properties</span><span class="p">[...</span><span class="nx">i</span><span class="p">]</span>
<span class="nv">snd = </span><span class="k">new</span> <span class="nx">Value</span> <span class="nx">@base</span><span class="p">,</span> <span class="nx">@properties</span><span class="p">[</span><span class="nx">i</span><span class="p">..]</span>
<span class="nv">fst = </span><span class="nx">Value</span><span class="p">.</span><span class="nx">wrap</span> <span class="nx">@base</span><span class="p">,</span> <span class="nx">@properties</span><span class="p">[...</span><span class="nx">i</span><span class="p">]</span>
<span class="nv">snd = </span><span class="nx">Value</span><span class="p">.</span><span class="nx">wrap</span> <span class="nx">@base</span><span class="p">,</span> <span class="nx">@properties</span><span class="p">[</span><span class="nx">i</span><span class="p">..]</span>
<span class="k">if</span> <span class="nx">fst</span><span class="p">.</span><span class="nx">isComplex</span><span class="p">()</span>
<span class="nv">ref = </span><span class="k">new</span> <span class="nx">Literal</span> <span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span> <span class="s">&#39;ref&#39;</span>
<span class="nv">fst = </span><span class="k">new</span> <span class="nx">Parens</span> <span class="k">new</span> <span class="nx">Assign</span> <span class="nx">ref</span><span class="p">,</span> <span class="nx">fst</span>
<span class="nv">snd.base = </span><span class="nx">ref</span>
<span class="k">return</span> <span class="k">new</span> <span class="nx">If</span> <span class="k">new</span> <span class="nx">Existence</span><span class="p">(</span><span class="nx">fst</span><span class="p">),</span> <span class="nx">snd</span><span class="p">,</span> <span class="nv">soak: </span><span class="kc">on</span>
<span class="kc">null</span>
<span class="vi">@unfoldedSoak = </span><span class="nx">result</span> <span class="o">or</span> <span class="kc">no</span></pre></div> </td> </tr> <tr id="section-44"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-44">&#182;</a> </div> <h3>Comment</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-45"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-45">&#182;</a> </div> <p>CoffeeScript passes through block comments as JavaScript block comments
<span class="kc">no</span></pre></div> </td> </tr> <tr id="section-45"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-45">&#182;</a> </div> <h3>Comment</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-46"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-46">&#182;</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.Comment = </span><span class="k">class</span> <span class="nx">Comment</span> <span class="k">extends</span> <span class="nx">Base</span>
<span class="nv">constructor: </span><span class="nf">(@comment) -&gt;</span>
@@ -358,20 +361,20 @@ at the same position.</p> </td> <td class="code">
<span class="nv">compileNode: </span><span class="nf">(o, level) -&gt;</span>
<span class="nv">code = </span><span class="s">&#39;/*&#39;</span> <span class="o">+</span> <span class="nx">multident</span><span class="p">(</span><span class="nx">@comment</span><span class="p">,</span> <span class="nx">@tab</span><span class="p">)</span> <span class="o">+</span> <span class="s">&quot;\n</span><span class="si">#{</span><span class="nx">@tab</span><span class="si">}</span><span class="s">*/\n&quot;</span>
<span class="nv">code = </span><span class="nx">o</span><span class="p">.</span><span class="nx">indent</span> <span class="o">+</span> <span class="nx">code</span> <span class="k">if</span> <span class="p">(</span><span class="nx">level</span> <span class="o">or</span> <span class="nx">o</span><span class="p">.</span><span class="nx">level</span><span class="p">)</span> <span class="o">is</span> <span class="nx">LEVEL_TOP</span>
<span class="nx">code</span></pre></div> </td> </tr> <tr id="section-46"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-46">&#182;</a> </div> <h3>Call</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-47"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-47">&#182;</a> </div> <p>Node for a function invocation. Takes care of converting <code>super()</code> calls into
<span class="nx">code</span></pre></div> </td> </tr> <tr id="section-47"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-47">&#182;</a> </div> <h3>Call</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-48"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-48">&#182;</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.Call = </span><span class="k">class</span> <span class="nx">Call</span> <span class="k">extends</span> <span class="nx">Base</span>
<span class="nv">constructor: </span><span class="nf">(variable, @args = [], @soak) -&gt;</span>
<span class="vi">@isNew = </span><span class="kc">false</span>
<span class="vi">@isSuper = </span><span class="nx">variable</span> <span class="o">is</span> <span class="s">&#39;super&#39;</span>
<span class="vi">@variable = </span><span class="k">if</span> <span class="nx">@isSuper</span> <span class="k">then</span> <span class="kc">null</span> <span class="k">else</span> <span class="nx">variable</span>
<span class="nv">children: </span><span class="p">[</span><span class="s">&#39;variable&#39;</span><span class="p">,</span> <span class="s">&#39;args&#39;</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-48"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-48">&#182;</a> </div> <p>Tag this invocation as creating a new instance.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">newInstance: </span><span class="nf">-&gt;</span>
<span class="nv">children: </span><span class="p">[</span><span class="s">&#39;variable&#39;</span><span class="p">,</span> <span class="s">&#39;args&#39;</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-49"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-49">&#182;</a> </div> <p>Tag this invocation as creating a new instance.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">newInstance: </span><span class="nf">-&gt;</span>
<span class="nv">base = </span><span class="nx">@variable</span><span class="o">?</span><span class="p">.</span><span class="nx">base</span> <span class="o">or</span> <span class="nx">@variable</span>
<span class="k">if</span> <span class="nx">base</span> <span class="k">instanceof</span> <span class="nx">Call</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">base</span><span class="p">.</span><span class="nx">isNew</span>
<span class="nx">base</span><span class="p">.</span><span class="nx">newInstance</span><span class="p">()</span>
<span class="k">else</span>
<span class="vi">@isNew = </span><span class="kc">true</span>
<span class="k">this</span></pre></div> </td> </tr> <tr id="section-49"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-49">&#182;</a> </div> <p>Grab the reference to the superclass's implementation of the current
<span class="k">this</span></pre></div> </td> </tr> <tr id="section-50"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-50">&#182;</a> </div> <p>Grab the reference to the superclass's implementation of the current
method.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">superReference: </span><span class="nf">(o) -&gt;</span>
<span class="nv">method = </span><span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">namedMethod</span><span class="p">()</span>
<span class="k">throw</span> <span class="nx">SyntaxError</span> <span class="s">&#39;cannot call super outside of a function.&#39;</span> <span class="k">unless</span> <span class="nx">method</span>
@@ -381,22 +384,22 @@ method.</p> </td> <td class="code"> <div c
<span class="nv">accesses = </span><span class="p">[</span><span class="k">new</span> <span class="nx">Access</span><span class="p">(</span><span class="k">new</span> <span class="nx">Literal</span> <span class="s">&#39;__super__&#39;</span><span class="p">)]</span>
<span class="nx">accesses</span><span class="p">.</span><span class="nx">push</span> <span class="k">new</span> <span class="nx">Access</span> <span class="k">new</span> <span class="nx">Literal</span> <span class="s">&#39;constructor&#39;</span> <span class="k">if</span> <span class="nx">method</span><span class="p">.</span><span class="nx">static</span>
<span class="nx">accesses</span><span class="p">.</span><span class="nx">push</span> <span class="k">new</span> <span class="nx">Access</span> <span class="k">new</span> <span class="nx">Literal</span> <span class="nx">name</span>
<span class="p">(</span><span class="k">new</span> <span class="nx">Value</span> <span class="p">(</span><span class="k">new</span> <span class="nx">Literal</span> <span class="nx">method</span><span class="p">.</span><span class="nx">klass</span><span class="p">),</span> <span class="nx">accesses</span><span class="p">).</span><span class="nx">compile</span> <span class="nx">o</span>
<span class="p">(</span><span class="nx">Value</span><span class="p">.</span><span class="nx">wrap</span> <span class="p">(</span><span class="k">new</span> <span class="nx">Literal</span> <span class="nx">method</span><span class="p">.</span><span class="nx">klass</span><span class="p">),</span> <span class="nx">accesses</span><span class="p">).</span><span class="nx">compile</span> <span class="nx">o</span>
<span class="k">else</span>
<span class="s">&quot;</span><span class="si">#{</span><span class="nx">name</span><span class="si">}</span><span class="s">.__super__.constructor&quot;</span></pre></div> </td> </tr> <tr id="section-50"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-50">&#182;</a> </div> <p>The appropriate <code>this</code> value for a <code>super</code> call.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">superThis : </span><span class="nf">(o) -&gt;</span>
<span class="s">&quot;</span><span class="si">#{</span><span class="nx">name</span><span class="si">}</span><span class="s">.__super__.constructor&quot;</span></pre></div> </td> </tr> <tr id="section-51"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-51">&#182;</a> </div> <p>The appropriate <code>this</code> value for a <code>super</code> call.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">superThis : </span><span class="nf">(o) -&gt;</span>
<span class="nv">method = </span><span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">method</span>
<span class="p">(</span><span class="nx">method</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">method</span><span class="p">.</span><span class="nx">klass</span> <span class="o">and</span> <span class="nx">method</span><span class="p">.</span><span class="nx">context</span><span class="p">)</span> <span class="o">or</span> <span class="s">&quot;this&quot;</span></pre></div> </td> </tr> <tr id="section-51"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-51">&#182;</a> </div> <p>Soaked chained invocations unfold into if/else ternary structures.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">unfoldSoak: </span><span class="nf">(o) -&gt;</span>
<span class="p">(</span><span class="nx">method</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">method</span><span class="p">.</span><span class="nx">klass</span> <span class="o">and</span> <span class="nx">method</span><span class="p">.</span><span class="nx">context</span><span class="p">)</span> <span class="o">or</span> <span class="s">&quot;this&quot;</span></pre></div> </td> </tr> <tr id="section-52"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-52">&#182;</a> </div> <p>Soaked chained invocations unfold into if/else ternary structures.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">unfoldSoak: </span><span class="nf">(o) -&gt;</span>
<span class="k">if</span> <span class="nx">@soak</span>
<span class="k">if</span> <span class="nx">@variable</span>
<span class="k">return</span> <span class="nx">ifn</span> <span class="k">if</span> <span class="nv">ifn = </span><span class="nx">unfoldSoak</span> <span class="nx">o</span><span class="p">,</span> <span class="k">this</span><span class="p">,</span> <span class="s">&#39;variable&#39;</span>
<span class="p">[</span><span class="nx">left</span><span class="p">,</span> <span class="nx">rite</span><span class="p">]</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Value</span><span class="p">(</span><span class="nx">@variable</span><span class="p">).</span><span class="nx">cacheReference</span> <span class="nx">o</span>
<span class="p">[</span><span class="nx">left</span><span class="p">,</span> <span class="nx">rite</span><span class="p">]</span> <span class="o">=</span> <span class="nx">Value</span><span class="p">.</span><span class="nx">wrap</span><span class="p">(</span><span class="nx">@variable</span><span class="p">).</span><span class="nx">cacheReference</span> <span class="nx">o</span>
<span class="k">else</span>
<span class="nv">left = </span><span class="k">new</span> <span class="nx">Literal</span> <span class="nx">@superReference</span> <span class="nx">o</span>
<span class="nv">rite = </span><span class="k">new</span> <span class="nx">Value</span> <span class="nx">left</span>
<span class="nv">rite = </span><span class="nx">Value</span><span class="p">.</span><span class="nx">wrap</span> <span class="nx">left</span>
<span class="nv">rite = </span><span class="k">new</span> <span class="nx">Call</span> <span class="nx">rite</span><span class="p">,</span> <span class="nx">@args</span>
<span class="nv">rite.isNew = </span><span class="nx">@isNew</span>
<span class="nv">left = </span><span class="k">new</span> <span class="nx">Literal</span> <span class="s">&quot;typeof </span><span class="si">#{</span> <span class="nx">left</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">o</span> <span class="si">}</span><span class="s"> === \&quot;function\&quot;&quot;</span>
<span class="k">return</span> <span class="k">new</span> <span class="nx">If</span> <span class="nx">left</span><span class="p">,</span> <span class="k">new</span> <span class="nx">Value</span><span class="p">(</span><span class="nx">rite</span><span class="p">),</span> <span class="nv">soak: </span><span class="kc">yes</span>
<span class="k">return</span> <span class="k">new</span> <span class="nx">If</span> <span class="nx">left</span><span class="p">,</span> <span class="nx">Value</span><span class="p">.</span><span class="nx">wrap</span><span class="p">(</span><span class="nx">rite</span><span class="p">),</span> <span class="nv">soak: </span><span class="kc">yes</span>
<span class="nv">call = </span><span class="k">this</span>
<span class="nv">list = </span><span class="p">[]</span>
<span class="k">loop</span>
@@ -414,7 +417,7 @@ method.</p> </td> <td class="code"> <div c
<span class="k">else</span>
<span class="nv">call.variable.base = </span><span class="nx">ifn</span>
<span class="nv">ifn = </span><span class="nx">unfoldSoak</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">call</span><span class="p">,</span> <span class="s">&#39;variable&#39;</span>
<span class="nx">ifn</span></pre></div> </td> </tr> <tr id="section-52"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-52">&#182;</a> </div> <p>Walk through the objects in the arguments, moving over simple values.
<span class="nx">ifn</span></pre></div> </td> </tr> <tr id="section-53"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-53">&#182;</a> </div> <p>Walk through the objects in the arguments, moving over simple values.
This allows syntax like <code>call a: b, c</code> into <code>call({a: b}, c);</code></p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">filterImplicitObjects: </span><span class="nf">(list) -&gt;</span>
<span class="nv">nodes = </span><span class="p">[]</span>
<span class="k">for</span> <span class="nx">node</span> <span class="k">in</span> <span class="nx">list</span>
@@ -429,7 +432,7 @@ This allows syntax like <code>call a: b, c</code> into <code>call({a: b}, c);</c
<span class="k">else</span>
<span class="nx">nodes</span><span class="p">.</span><span class="nx">push</span> <span class="nx">prop</span>
<span class="nv">obj = </span><span class="kc">null</span>
<span class="nx">nodes</span></pre></div> </td> </tr> <tr id="section-53"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-53">&#182;</a> </div> <p>Compile a vanilla function call.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compileNode: </span><span class="nf">(o) -&gt;</span>
<span class="nx">nodes</span></pre></div> </td> </tr> <tr id="section-54"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-54">&#182;</a> </div> <p>Compile a vanilla function call.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compileNode: </span><span class="nf">(o) -&gt;</span>
<span class="nx">@variable</span><span class="o">?</span><span class="p">.</span><span class="nv">front = </span><span class="nx">@front</span>
<span class="k">if</span> <span class="nv">code = </span><span class="nx">Splat</span><span class="p">.</span><span class="nx">compileSplattedArray</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">@args</span><span class="p">,</span> <span class="kc">true</span>
<span class="k">return</span> <span class="nx">@compileSplat</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">code</span>
@@ -438,9 +441,7 @@ This allows syntax like <code>call a: b, c</code> into <code>call({a: b}, c);</c
<span class="k">if</span> <span class="nx">@isSuper</span>
<span class="nx">@superReference</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">+</span> <span class="s">&quot;.call(</span><span class="si">#{</span><span class="nx">@superThis</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span><span class="si">}#{</span> <span class="nx">args</span> <span class="o">and</span> <span class="s">&#39;, &#39;</span> <span class="o">+</span> <span class="nx">args</span> <span class="si">}</span><span class="s">)&quot;</span>
<span class="k">else</span>
<span class="p">(</span><span class="k">if</span> <span class="nx">@isNew</span> <span class="k">then</span> <span class="s">&#39;new &#39;</span> <span class="k">else</span> <span class="s">&#39;&#39;</span><span class="p">)</span> <span class="o">+</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="nx">LEVEL_ACCESS</span><span class="p">)</span> <span class="o">+</span> <span class="s">&quot;(</span><span class="si">#{</span><span class="nx">args</span><span class="si">}</span><span class="s">)&quot;</span></pre></div> </td> </tr> <tr id="section-54"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-54">&#182;</a> </div> <p><code>super()</code> is converted into a call against the superclass's implementation
of the current function.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compileSuper: </span><span class="nf">(args, o) -&gt;</span>
<span class="s">&quot;</span><span class="si">#{</span><span class="nx">@superReference</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span><span class="si">}</span><span class="s">.call(</span><span class="si">#{</span><span class="nx">@superThis</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span><span class="si">}#{</span> <span class="k">if</span> <span class="nx">args</span><span class="p">.</span><span class="nx">length</span> <span class="k">then</span> <span class="s">&#39;, &#39;</span> <span class="k">else</span> <span class="s">&#39;&#39;</span> <span class="si">}#{</span><span class="nx">args</span><span class="si">}</span><span class="s">)&quot;</span></pre></div> </td> </tr> <tr id="section-55"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-55">&#182;</a> </div> <p>If you call a function with a splat, it's converted into a JavaScript
<span class="p">(</span><span class="k">if</span> <span class="nx">@isNew</span> <span class="k">then</span> <span class="s">&#39;new &#39;</span> <span class="k">else</span> <span class="s">&#39;&#39;</span><span class="p">)</span> <span class="o">+</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="nx">LEVEL_ACCESS</span><span class="p">)</span> <span class="o">+</span> <span class="s">&quot;(</span><span class="si">#{</span><span class="nx">args</span><span class="si">}</span><span class="s">)&quot;</span></pre></div> </td> </tr> <tr id="section-55"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-55">&#182;</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="nv">compileSplat: </span><span class="nf">(o, splatArgs) -&gt;</span>
@@ -454,7 +455,7 @@ inner constructor in order to be able to pass the varargs.</p> </td>
<span class="s"> </span><span class="si">#{</span><span class="nx">idt</span><span class="si">}</span><span class="s">return Object(result) === result ? result : child;</span>
<span class="s"> </span><span class="si">#{</span><span class="nx">@tab</span><span class="si">}</span><span class="s">})(</span><span class="si">#{</span> <span class="nx">@variable</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_LIST</span> <span class="si">}</span><span class="s">, </span><span class="si">#{</span><span class="nx">splatArgs</span><span class="si">}</span><span class="s">, function(){})</span>
<span class="s"> &quot;&quot;&quot;</span>
<span class="nv">base = </span><span class="k">new</span> <span class="nx">Value</span> <span class="nx">@variable</span>
<span class="nv">base = </span><span class="nx">Value</span><span class="p">.</span><span class="nx">wrap</span> <span class="nx">@variable</span>
<span class="k">if</span> <span class="p">(</span><span class="nv">name = </span><span class="nx">base</span><span class="p">.</span><span class="nx">properties</span><span class="p">.</span><span class="nx">pop</span><span class="p">())</span> <span class="o">and</span> <span class="nx">base</span><span class="p">.</span><span class="nx">isComplex</span><span class="p">()</span>
<span class="nv">ref = </span><span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span> <span class="s">&#39;ref&#39;</span>
<span class="nv">fun = </span><span class="s">&quot;(</span><span class="si">#{</span><span class="nx">ref</span><span class="si">}</span><span class="s"> = </span><span class="si">#{</span> <span class="nx">base</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_LIST</span> <span class="si">}</span><span class="s">)</span><span class="si">#{</span> <span class="nx">name</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">o</span> <span class="si">}</span><span class="s">&quot;</span>
@@ -472,7 +473,7 @@ After <code>goog.inherits</code> from the
<span class="nv">constructor: </span><span class="nf">(@child, @parent) -&gt;</span>
<span class="nv">children: </span><span class="p">[</span><span class="s">&#39;child&#39;</span><span class="p">,</span> <span class="s">&#39;parent&#39;</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-58"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-58">&#182;</a> </div> <p>Hooks one constructor into another's prototype chain.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compile: </span><span class="nf">(o) -&gt;</span>
<span class="k">new</span> <span class="nx">Call</span><span class="p">(</span><span class="k">new</span> <span class="nx">Value</span><span class="p">(</span><span class="k">new</span> <span class="nx">Literal</span> <span class="nx">utility</span> <span class="s">&#39;extends&#39;</span><span class="p">),</span> <span class="p">[</span><span class="nx">@child</span><span class="p">,</span> <span class="nx">@parent</span><span class="p">]).</span><span class="nx">compile</span> <span class="nx">o</span></pre></div> </td> </tr> <tr id="section-59"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-59">&#182;</a> </div> <h3>Access</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-60"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-60">&#182;</a> </div> <p>A <code>.</code> access into a property of a value, or the <code>::</code> shorthand for
<span class="k">new</span> <span class="nx">Call</span><span class="p">(</span><span class="nx">Value</span><span class="p">.</span><span class="nx">wrap</span><span class="p">(</span><span class="k">new</span> <span class="nx">Literal</span> <span class="nx">utility</span> <span class="s">&#39;extends&#39;</span><span class="p">),</span> <span class="p">[</span><span class="nx">@child</span><span class="p">,</span> <span class="nx">@parent</span><span class="p">]).</span><span class="nx">compile</span> <span class="nx">o</span></pre></div> </td> </tr> <tr id="section-59"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-59">&#182;</a> </div> <h3>Access</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-60"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-60">&#182;</a> </div> <p>A <code>.</code> access into a property of a value, or the <code>::</code> shorthand for
an access into the object's prototype.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.Access = </span><span class="k">class</span> <span class="nx">Access</span> <span class="k">extends</span> <span class="nx">Base</span>
<span class="nv">constructor: </span><span class="nf">(@name, tag) -&gt;</span>
<span class="vi">@name.asKey = </span><span class="kc">yes</span>
@@ -524,7 +525,7 @@ needed to iterate over the values in the range. Used by comprehensions.</p>
<span class="p">[</span><span class="nx">from</span><span class="p">,</span> <span class="nx">to</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="o">+</span><span class="nx">@fromNum</span><span class="p">,</span> <span class="o">+</span><span class="nx">@toNum</span><span class="p">]</span>
<span class="k">if</span> <span class="nx">from</span> <span class="o">&lt;=</span> <span class="nx">to</span> <span class="k">then</span> <span class="s">&quot;</span><span class="si">#{</span><span class="nx">lt</span><span class="si">}</span><span class="s"> </span><span class="si">#{</span><span class="nx">to</span><span class="si">}</span><span class="s">&quot;</span> <span class="k">else</span> <span class="s">&quot;</span><span class="si">#{</span><span class="nx">gt</span><span class="si">}</span><span class="s"> </span><span class="si">#{</span><span class="nx">to</span><span class="si">}</span><span class="s">&quot;</span>
<span class="k">else</span>
<span class="nv">cond = </span><span class="s">&quot;</span><span class="si">#{</span><span class="nx">@fromVar</span><span class="si">}</span><span class="s"> &lt;= </span><span class="si">#{</span><span class="nx">@toVar</span><span class="si">}</span><span class="s">&quot;</span>
<span class="nv">cond = </span><span class="k">if</span> <span class="nx">@stepVar</span> <span class="k">then</span> <span class="s">&quot;</span><span class="si">#{</span><span class="nx">@stepVar</span><span class="si">}</span><span class="s"> &gt; 0&quot;</span> <span class="k">else</span> <span class="s">&quot;</span><span class="si">#{</span><span class="nx">@fromVar</span><span class="si">}</span><span class="s"> &lt;= </span><span class="si">#{</span><span class="nx">@toVar</span><span class="si">}</span><span class="s">&quot;</span>
<span class="s">&quot;</span><span class="si">#{</span><span class="nx">cond</span><span class="si">}</span><span class="s"> ? </span><span class="si">#{</span><span class="nx">lt</span><span class="si">}</span><span class="s"> </span><span class="si">#{</span><span class="nx">@toVar</span><span class="si">}</span><span class="s"> : </span><span class="si">#{</span><span class="nx">gt</span><span class="si">}</span><span class="s"> </span><span class="si">#{</span><span class="nx">@toVar</span><span class="si">}</span><span class="s">&quot;</span></pre></div> </td> </tr> <tr id="section-69"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-69">&#182;</a> </div> <p>Generate the step.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">stepPart = </span><span class="k">if</span> <span class="nx">@stepVar</span>
<span class="s">&quot;</span><span class="si">#{</span><span class="nx">idx</span><span class="si">}</span><span class="s"> += </span><span class="si">#{</span><span class="nx">@stepVar</span><span class="si">}</span><span class="s">&quot;</span>
<span class="k">else</span> <span class="k">if</span> <span class="nx">known</span>
@@ -660,10 +661,10 @@ list of prototype property assignments.</p> </td> <td cl
<span class="nv">node.klass = </span><span class="nx">name</span>
<span class="nv">node.context = </span><span class="nx">name</span> <span class="k">if</span> <span class="nx">node</span><span class="p">.</span><span class="nx">bound</span></pre></div> </td> </tr> <tr id="section-83"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-83">&#182;</a> </div> <p>Ensure that all functions bound to the instance are proxied in the
constructor.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">addBoundFunctions: </span><span class="nf">(o) -&gt;</span>
<span class="k">if</span> <span class="nx">@boundFuncs</span><span class="p">.</span><span class="nx">length</span>
<span class="k">for</span> <span class="nx">bvar</span> <span class="k">in</span> <span class="nx">@boundFuncs</span>
<span class="nv">lhs = </span><span class="p">(</span><span class="k">new</span> <span class="nx">Value</span> <span class="p">(</span><span class="k">new</span> <span class="nx">Literal</span> <span class="s">&quot;this&quot;</span><span class="p">),</span> <span class="p">[</span><span class="k">new</span> <span class="nx">Access</span> <span class="nx">bvar</span><span class="p">]).</span><span class="nx">compile</span> <span class="nx">o</span>
<span class="nx">@ctor</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">unshift</span> <span class="k">new</span> <span class="nx">Literal</span> <span class="s">&quot;</span><span class="si">#{</span><span class="nx">lhs</span><span class="si">}</span><span class="s"> = </span><span class="si">#{</span><span class="nx">utility</span> <span class="s">&#39;bind&#39;</span><span class="si">}</span><span class="s">(</span><span class="si">#{</span><span class="nx">lhs</span><span class="si">}</span><span class="s">, this)&quot;</span></pre></div> </td> </tr> <tr id="section-84"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-84">&#182;</a> </div> <p>Merge the properties from a top-level object as prototypal properties
<span class="k">for</span> <span class="nx">bvar</span> <span class="k">in</span> <span class="nx">@boundFuncs</span>
<span class="nv">lhs = </span><span class="p">(</span><span class="nx">Value</span><span class="p">.</span><span class="nx">wrap</span> <span class="p">(</span><span class="k">new</span> <span class="nx">Literal</span> <span class="s">&quot;this&quot;</span><span class="p">),</span> <span class="p">[</span><span class="k">new</span> <span class="nx">Access</span> <span class="nx">bvar</span><span class="p">]).</span><span class="nx">compile</span> <span class="nx">o</span>
<span class="nx">@ctor</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">unshift</span> <span class="k">new</span> <span class="nx">Literal</span> <span class="s">&quot;</span><span class="si">#{</span><span class="nx">lhs</span><span class="si">}</span><span class="s"> = </span><span class="si">#{</span><span class="nx">utility</span> <span class="s">&#39;bind&#39;</span><span class="si">}</span><span class="s">(</span><span class="si">#{</span><span class="nx">lhs</span><span class="si">}</span><span class="s">, this)&quot;</span>
<span class="k">return</span></pre></div> </td> </tr> <tr id="section-84"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-84">&#182;</a> </div> <p>Merge the properties from a top-level object as prototypal properties
on the class.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">addProperties: </span><span class="nf">(node, name, o) -&gt;</span>
<span class="nv">props = </span><span class="nx">node</span><span class="p">.</span><span class="nx">base</span><span class="p">.</span><span class="nx">properties</span><span class="p">[..]</span>
<span class="nv">exprs = </span><span class="k">while</span> <span class="nv">assign = </span><span class="nx">props</span><span class="p">.</span><span class="nx">shift</span><span class="p">()</span>
@@ -687,7 +688,7 @@ on the class.</p> </td> <td class="code">
<span class="k">if</span> <span class="nx">func</span><span class="p">.</span><span class="nx">bound</span>
<span class="nv">func.context = </span><span class="nx">name</span>
<span class="k">else</span>
<span class="nv">assign.variable = </span><span class="k">new</span> <span class="nx">Value</span><span class="p">(</span><span class="k">new</span> <span class="nx">Literal</span><span class="p">(</span><span class="nx">name</span><span class="p">),</span> <span class="p">[(</span><span class="k">new</span> <span class="nx">Access</span> <span class="k">new</span> <span class="nx">Literal</span> <span class="s">&#39;prototype&#39;</span><span class="p">),</span> <span class="k">new</span> <span class="nx">Access</span> <span class="nx">base</span> <span class="p">])</span>
<span class="nv">assign.variable = </span><span class="nx">Value</span><span class="p">.</span><span class="nx">wrap</span><span class="p">(</span><span class="k">new</span> <span class="nx">Literal</span><span class="p">(</span><span class="nx">name</span><span class="p">),</span> <span class="p">[(</span><span class="k">new</span> <span class="nx">Access</span> <span class="k">new</span> <span class="nx">Literal</span> <span class="s">&#39;prototype&#39;</span><span class="p">),</span> <span class="k">new</span> <span class="nx">Access</span> <span class="nx">base</span> <span class="p">])</span>
<span class="k">if</span> <span class="nx">func</span> <span class="k">instanceof</span> <span class="nx">Code</span> <span class="o">and</span> <span class="nx">func</span><span class="p">.</span><span class="nx">bound</span>
<span class="nx">@boundFuncs</span><span class="p">.</span><span class="nx">push</span> <span class="nx">base</span>
<span class="nv">func.bound = </span><span class="kc">no</span>
@@ -707,16 +708,19 @@ above the <code>constructor</code>.</p> </td> <td class=
<span class="o">++</span><span class="nx">index</span> <span class="k">while</span> <span class="p">(</span><span class="nv">node = </span><span class="nx">expressions</span><span class="p">[</span><span class="nx">index</span><span class="p">])</span> <span class="o">and</span> <span class="nx">node</span> <span class="k">instanceof</span> <span class="nx">Comment</span> <span class="o">or</span>
<span class="nx">node</span> <span class="k">instanceof</span> <span class="nx">Value</span> <span class="o">and</span> <span class="nx">node</span><span class="p">.</span><span class="nx">isString</span><span class="p">()</span>
<span class="vi">@directives = </span><span class="nx">expressions</span><span class="p">.</span><span class="nx">splice</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">index</span></pre></div> </td> </tr> <tr id="section-87"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-87">&#182;</a> </div> <p>Make sure that a constructor is defined for the class, and properly
configured.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">ensureConstructor: </span><span class="nf">(name) -&gt;</span>
configured.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">ensureConstructor: </span><span class="nf">(name, o) -&gt;</span>
<span class="k">if</span> <span class="o">not</span> <span class="nx">@ctor</span>
<span class="vi">@ctor = </span><span class="k">new</span> <span class="nx">Code</span>
<span class="nx">@ctor</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">push</span> <span class="k">new</span> <span class="nx">Literal</span> <span class="s">&quot;</span><span class="si">#{</span><span class="nx">name</span><span class="si">}</span><span class="s">.__super__.constructor.apply(this, arguments)&quot;</span> <span class="k">if</span> <span class="nx">@parent</span>
<span class="nx">@ctor</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">Literal</span> <span class="s">&quot;</span><span class="si">#{</span><span class="nx">@externalCtor</span><span class="si">}</span><span class="s">.apply(this, arguments)&quot;</span> <span class="k">if</span> <span class="nx">@externalCtor</span>
<span class="nx">@ctor</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">makeReturn</span><span class="p">()</span>
<span class="nx">@body</span><span class="p">.</span><span class="nx">expressions</span><span class="p">.</span><span class="nx">unshift</span> <span class="nx">@ctor</span>
<span class="vi">@ctor.ctor = @ctor.name = </span><span class="nx">name</span>
<span class="vi">@ctor.klass = </span><span class="kc">null</span>
<span class="vi">@ctor.noReturn = </span><span class="kc">yes</span></pre></div> </td> </tr> <tr id="section-88"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-88">&#182;</a> </div> <p>Instead of generating the JavaScript string directly, we build up the
<span class="vi">@ctor.noReturn = </span><span class="kc">yes</span></pre></div> </td> </tr> <tr id="section-88"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-88">&#182;</a> </div> <p>Prevent constructor from returning a value.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">returnExpr = </span><span class="kc">null</span>
<span class="nx">@ctor</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">traverseChildren</span> <span class="kc">no</span><span class="p">,</span> <span class="nf">(node) -&gt;</span>
<span class="k">return</span> <span class="kc">no</span> <span class="k">if</span> <span class="nx">node</span> <span class="k">instanceof</span> <span class="nx">Return</span> <span class="o">and</span> <span class="p">(</span><span class="nv">returnExpr = </span><span class="nx">node</span><span class="p">.</span><span class="nx">expression</span><span class="p">)</span>
<span class="k">if</span> <span class="nx">returnExpr</span>
<span class="k">throw</span> <span class="nx">SyntaxError</span> <span class="s">&quot;cannot return a value from a constructor: \&quot;</span><span class="si">#{</span><span class="nx">returnExpr</span><span class="p">.</span><span class="nx">compileNode</span> <span class="nx">o</span><span class="si">}</span><span class="s">\&quot; in class </span><span class="si">#{</span><span class="nx">name</span><span class="si">}</span><span class="s">&quot;</span></pre></div> </td> </tr> <tr id="section-89"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-89">&#182;</a> </div> <p>Instead of generating the JavaScript string directly, we build up the
equivalent syntax tree and compile that, in pieces. You can see the
constructor, property assignments, and inheritance getting built out below.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compileNode: </span><span class="nf">(o) -&gt;</span>
<span class="nv">decl = </span><span class="nx">@determineName</span><span class="p">()</span>
@@ -727,7 +731,7 @@ constructor, property assignments, and inheritance getting built out below.</p>
<span class="nx">@hoistDirectivePrologue</span><span class="p">()</span>
<span class="nx">@setContext</span> <span class="nx">name</span>
<span class="nx">@walkBody</span> <span class="nx">name</span><span class="p">,</span> <span class="nx">o</span>
<span class="nx">@ensureConstructor</span> <span class="nx">name</span>
<span class="nx">@ensureConstructor</span> <span class="nx">name</span><span class="p">,</span> <span class="nx">o</span>
<span class="vi">@body.spaced = </span><span class="kc">yes</span>
<span class="nx">@body</span><span class="p">.</span><span class="nx">expressions</span><span class="p">.</span><span class="nx">unshift</span> <span class="nx">@ctor</span> <span class="k">unless</span> <span class="nx">@ctor</span> <span class="k">instanceof</span> <span class="nx">Code</span>
<span class="nx">@body</span><span class="p">.</span><span class="nx">expressions</span><span class="p">.</span><span class="nx">push</span> <span class="nx">lname</span>
@@ -745,7 +749,7 @@ constructor, property assignments, and inheritance getting built out below.</p>
<span class="nv">klass = </span><span class="k">new</span> <span class="nx">Parens</span> <span class="nx">call</span><span class="p">,</span> <span class="kc">yes</span>
<span class="nv">klass = </span><span class="k">new</span> <span class="nx">Assign</span> <span class="nx">@variable</span><span class="p">,</span> <span class="nx">klass</span> <span class="k">if</span> <span class="nx">@variable</span>
<span class="nx">klass</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">o</span></pre></div> </td> </tr> <tr id="section-89"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-89">&#182;</a> </div> <h3>Assign</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-90"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-90">&#182;</a> </div> <p>The <strong>Assign</strong> is used to assign a local variable to value, or to set the
<span class="nx">klass</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">o</span></pre></div> </td> </tr> <tr id="section-90"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-90">&#182;</a> </div> <h3>Assign</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-91"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-91">&#182;</a> </div> <p>The <strong>Assign</strong> is used to assign a local variable to value, or to set the
property of an object -- including within object literals.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.Assign = </span><span class="k">class</span> <span class="nx">Assign</span> <span class="k">extends</span> <span class="nx">Base</span>
<span class="nv">constructor: </span><span class="nf">(@variable, @value, @context, options) -&gt;</span>
<span class="vi">@param = </span><span class="nx">options</span> <span class="o">and</span> <span class="nx">options</span><span class="p">.</span><span class="nx">param</span>
@@ -763,7 +767,7 @@ property of an object -- including within object literals.</p> </td>
<span class="nx">@</span><span class="p">[</span><span class="k">if</span> <span class="nx">@context</span> <span class="o">is</span> <span class="s">&#39;object&#39;</span> <span class="k">then</span> <span class="s">&#39;value&#39;</span> <span class="k">else</span> <span class="s">&#39;variable&#39;</span><span class="p">].</span><span class="nx">assigns</span> <span class="nx">name</span>
<span class="nv">unfoldSoak: </span><span class="nf">(o) -&gt;</span>
<span class="nx">unfoldSoak</span> <span class="nx">o</span><span class="p">,</span> <span class="k">this</span><span class="p">,</span> <span class="s">&#39;variable&#39;</span></pre></div> </td> </tr> <tr id="section-91"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-91">&#182;</a> </div> <p>Compile an assignment, delegating to <code>compilePatternMatch</code> or
<span class="nx">unfoldSoak</span> <span class="nx">o</span><span class="p">,</span> <span class="k">this</span><span class="p">,</span> <span class="s">&#39;variable&#39;</span></pre></div> </td> </tr> <tr id="section-92"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-92">&#182;</a> </div> <p>Compile an assignment, delegating to <code>compilePatternMatch</code> or
<code>compileSplice</code> if appropriate. Keep track of the name of the base object
we've been assigned to, for correct internal references. If the variable
has not been seen yet within the current scope, declare it.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compileNode: </span><span class="nf">(o) -&gt;</span>
@@ -786,7 +790,7 @@ has not been seen yet within the current scope, declare it.</p> </td
<span class="nv">val = </span><span class="nx">@value</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_LIST</span>
<span class="k">return</span> <span class="s">&quot;</span><span class="si">#{</span><span class="nx">name</span><span class="si">}</span><span class="s">: </span><span class="si">#{</span><span class="nx">val</span><span class="si">}</span><span class="s">&quot;</span> <span class="k">if</span> <span class="nx">@context</span> <span class="o">is</span> <span class="s">&#39;object&#39;</span>
<span class="nv">val = </span><span class="nx">name</span> <span class="o">+</span> <span class="s">&quot; </span><span class="si">#{</span> <span class="nx">@context</span> <span class="o">or</span> <span class="s">&#39;=&#39;</span> <span class="si">}</span><span class="s"> &quot;</span> <span class="o">+</span> <span class="nx">val</span>
<span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">level</span> <span class="o">&lt;=</span> <span class="nx">LEVEL_LIST</span> <span class="k">then</span> <span class="nx">val</span> <span class="k">else</span> <span class="s">&quot;(</span><span class="si">#{</span><span class="nx">val</span><span class="si">}</span><span class="s">)&quot;</span></pre></div> </td> </tr> <tr id="section-92"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-92">&#182;</a> </div> <p>Brief implementation of recursive pattern matching, when assigning array or
<span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">level</span> <span class="o">&lt;=</span> <span class="nx">LEVEL_LIST</span> <span class="k">then</span> <span class="nx">val</span> <span class="k">else</span> <span class="s">&quot;(</span><span class="si">#{</span><span class="nx">val</span><span class="si">}</span><span class="s">)&quot;</span></pre></div> </td> </tr> <tr id="section-93"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-93">&#182;</a> </div> <p>Brief implementation of recursive pattern matching, when assigning array or
object literals to a value. Peeks at their properties to assign inner names.
See the <a href="http://wiki.ecmascript.org/doku.php?id=harmony:destructuring">ECMAScript Harmony Wiki</a>
for details.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compilePatternMatch: </span><span class="nf">(o) -&gt;</span>
@@ -797,18 +801,15 @@ for details.</p> </td> <td class="code"> <
<span class="nv">code = </span><span class="nx">value</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">o</span>
<span class="k">return</span> <span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">level</span> <span class="o">&gt;=</span> <span class="nx">LEVEL_OP</span> <span class="k">then</span> <span class="s">&quot;(</span><span class="si">#{</span><span class="nx">code</span><span class="si">}</span><span class="s">)&quot;</span> <span class="k">else</span> <span class="nx">code</span>
<span class="nv">isObject = </span><span class="nx">@variable</span><span class="p">.</span><span class="nx">isObject</span><span class="p">()</span>
<span class="k">if</span> <span class="nx">top</span> <span class="o">and</span> <span class="nx">olen</span> <span class="o">is</span> <span class="mi">1</span> <span class="o">and</span> <span class="p">(</span><span class="nv">obj = </span><span class="nx">objects</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span> <span class="o">not</span> <span class="k">instanceof</span> <span class="nx">Splat</span></pre></div> </td> </tr> <tr id="section-93"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-93">&#182;</a> </div> <p>Unroll simplest cases: <code>{v} = x</code> -> <code>v = x.v</code></p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span> <span class="nx">obj</span> <span class="k">instanceof</span> <span class="nx">Assign</span>
<span class="k">if</span> <span class="nx">top</span> <span class="o">and</span> <span class="nx">olen</span> <span class="o">is</span> <span class="mi">1</span> <span class="o">and</span> <span class="p">(</span><span class="nv">obj = </span><span class="nx">objects</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span> <span class="o">not</span> <span class="k">instanceof</span> <span class="nx">Splat</span></pre></div> </td> </tr> <tr id="section-94"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-94">&#182;</a> </div> <p>Unroll simplest cases: <code>{v} = x</code> -> <code>v = x.v</code></p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span> <span class="nx">obj</span> <span class="k">instanceof</span> <span class="nx">Assign</span>
<span class="p">{</span><span class="nv">variable: </span><span class="p">{</span><span class="nv">base: </span><span class="nx">idx</span><span class="p">},</span> <span class="nv">value: </span><span class="nx">obj</span><span class="p">}</span> <span class="o">=</span> <span class="nx">obj</span>
<span class="k">else</span>
<span class="k">if</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">base</span> <span class="k">instanceof</span> <span class="nx">Parens</span>
<span class="p">[</span><span class="nx">obj</span><span class="p">,</span> <span class="nx">idx</span><span class="p">]</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Value</span><span class="p">(</span><span class="nx">obj</span><span class="p">.</span><span class="nx">unwrapAll</span><span class="p">()).</span><span class="nx">cacheReference</span> <span class="nx">o</span>
<span class="nv">idx = </span><span class="k">if</span> <span class="nx">isObject</span>
<span class="k">if</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">this</span> <span class="k">then</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">properties</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nx">name</span> <span class="k">else</span> <span class="nx">obj</span>
<span class="k">else</span>
<span class="nv">idx = </span><span class="k">if</span> <span class="nx">isObject</span>
<span class="k">if</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">this</span> <span class="k">then</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">properties</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nx">name</span> <span class="k">else</span> <span class="nx">obj</span>
<span class="k">else</span>
<span class="k">new</span> <span class="nx">Literal</span> <span class="mi">0</span>
<span class="k">new</span> <span class="nx">Literal</span> <span class="mi">0</span>
<span class="nv">acc = </span><span class="nx">IDENTIFIER</span><span class="p">.</span><span class="nx">test</span> <span class="nx">idx</span><span class="p">.</span><span class="nx">unwrap</span><span class="p">().</span><span class="nx">value</span> <span class="o">or</span> <span class="mi">0</span>
<span class="nv">value = </span><span class="k">new</span> <span class="nx">Value</span> <span class="nx">value</span>
<span class="nv">value = </span><span class="nx">Value</span><span class="p">.</span><span class="nx">wrap</span> <span class="nx">value</span>
<span class="nx">value</span><span class="p">.</span><span class="nx">properties</span><span class="p">.</span><span class="nx">push</span> <span class="k">new</span> <span class="p">(</span><span class="k">if</span> <span class="nx">acc</span> <span class="k">then</span> <span class="nx">Access</span> <span class="k">else</span> <span class="nx">Index</span><span class="p">)</span> <span class="nx">idx</span>
<span class="k">if</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">unwrap</span><span class="p">().</span><span class="nx">value</span> <span class="k">in</span> <span class="nx">RESERVED</span>
<span class="k">throw</span> <span class="k">new</span> <span class="nx">SyntaxError</span> <span class="s">&quot;assignment to a reserved word: </span><span class="si">#{</span><span class="nx">obj</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">o</span><span class="si">}</span><span class="s"> = </span><span class="si">#{</span><span class="nx">value</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">o</span><span class="si">}</span><span class="s">&quot;</span>
@@ -819,11 +820,11 @@ for details.</p> </td> <td class="code"> <
<span class="k">if</span> <span class="o">not</span> <span class="nx">IDENTIFIER</span><span class="p">.</span><span class="nx">test</span><span class="p">(</span><span class="nx">vvar</span><span class="p">)</span> <span class="o">or</span> <span class="nx">@variable</span><span class="p">.</span><span class="nx">assigns</span><span class="p">(</span><span class="nx">vvar</span><span class="p">)</span>
<span class="nx">assigns</span><span class="p">.</span><span class="nx">push</span> <span class="s">&quot;</span><span class="si">#{</span> <span class="nv">ref = </span><span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span> <span class="s">&#39;ref&#39;</span> <span class="si">}</span><span class="s"> = </span><span class="si">#{</span><span class="nx">vvar</span><span class="si">}</span><span class="s">&quot;</span>
<span class="nv">vvar = </span><span class="nx">ref</span>
<span class="k">for</span> <span class="nx">obj</span><span class="p">,</span> <span class="nx">i</span> <span class="k">in</span> <span class="nx">objects</span></pre></div> </td> </tr> <tr id="section-94"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-94">&#182;</a> </div> <p>A regular array pattern-match.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">idx = </span><span class="nx">i</span>
<span class="k">for</span> <span class="nx">obj</span><span class="p">,</span> <span class="nx">i</span> <span class="k">in</span> <span class="nx">objects</span></pre></div> </td> </tr> <tr id="section-95"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-95">&#182;</a> </div> <p>A regular array pattern-match.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">idx = </span><span class="nx">i</span>
<span class="k">if</span> <span class="nx">isObject</span>
<span class="k">if</span> <span class="nx">obj</span> <span class="k">instanceof</span> <span class="nx">Assign</span></pre></div> </td> </tr> <tr id="section-95"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-95">&#182;</a> </div> <p>A regular object pattern-match.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="p">{</span><span class="nv">variable: </span><span class="p">{</span><span class="nv">base: </span><span class="nx">idx</span><span class="p">},</span> <span class="nv">value: </span><span class="nx">obj</span><span class="p">}</span> <span class="o">=</span> <span class="nx">obj</span>
<span class="k">else</span></pre></div> </td> </tr> <tr id="section-96"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-96">&#182;</a> </div> <p>A shorthand <code>{a, b, @c} = val</code> pattern-match.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">base</span> <span class="k">instanceof</span> <span class="nx">Parens</span>
<span class="p">[</span><span class="nx">obj</span><span class="p">,</span> <span class="nx">idx</span><span class="p">]</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Value</span><span class="p">(</span><span class="nx">obj</span><span class="p">.</span><span class="nx">unwrapAll</span><span class="p">()).</span><span class="nx">cacheReference</span> <span class="nx">o</span>
<span class="k">if</span> <span class="nx">obj</span> <span class="k">instanceof</span> <span class="nx">Assign</span></pre></div> </td> </tr> <tr id="section-96"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-96">&#182;</a> </div> <p>A regular object pattern-match.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="p">{</span><span class="nv">variable: </span><span class="p">{</span><span class="nv">base: </span><span class="nx">idx</span><span class="p">},</span> <span class="nv">value: </span><span class="nx">obj</span><span class="p">}</span> <span class="o">=</span> <span class="nx">obj</span>
<span class="k">else</span></pre></div> </td> </tr> <tr id="section-97"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-97">&#182;</a> </div> <p>A shorthand <code>{a, b, @c} = val</code> pattern-match.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">base</span> <span class="k">instanceof</span> <span class="nx">Parens</span>
<span class="p">[</span><span class="nx">obj</span><span class="p">,</span> <span class="nx">idx</span><span class="p">]</span> <span class="o">=</span> <span class="nx">Value</span><span class="p">.</span><span class="nx">wrap</span><span class="p">(</span><span class="nx">obj</span><span class="p">.</span><span class="nx">unwrapAll</span><span class="p">()).</span><span class="nx">cacheReference</span> <span class="nx">o</span>
<span class="k">else</span>
<span class="nv">idx = </span><span class="k">if</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">this</span> <span class="k">then</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">properties</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nx">name</span> <span class="k">else</span> <span class="nx">obj</span>
<span class="k">if</span> <span class="o">not</span> <span class="nx">splat</span> <span class="o">and</span> <span class="nx">obj</span> <span class="k">instanceof</span> <span class="nx">Splat</span>
@@ -848,20 +849,20 @@ for details.</p> </td> <td class="code"> <
<span class="nv">acc = </span><span class="kc">no</span>
<span class="k">else</span>
<span class="nv">acc = </span><span class="nx">isObject</span> <span class="o">and</span> <span class="nx">IDENTIFIER</span><span class="p">.</span><span class="nx">test</span> <span class="nx">idx</span><span class="p">.</span><span class="nx">unwrap</span><span class="p">().</span><span class="nx">value</span> <span class="o">or</span> <span class="mi">0</span>
<span class="nv">val = </span><span class="k">new</span> <span class="nx">Value</span> <span class="k">new</span> <span class="nx">Literal</span><span class="p">(</span><span class="nx">vvar</span><span class="p">),</span> <span class="p">[</span><span class="k">new</span> <span class="p">(</span><span class="k">if</span> <span class="nx">acc</span> <span class="k">then</span> <span class="nx">Access</span> <span class="k">else</span> <span class="nx">Index</span><span class="p">)</span> <span class="nx">idx</span><span class="p">]</span>
<span class="nv">val = </span><span class="nx">Value</span><span class="p">.</span><span class="nx">wrap</span> <span class="k">new</span> <span class="nx">Literal</span><span class="p">(</span><span class="nx">vvar</span><span class="p">),</span> <span class="p">[</span><span class="k">new</span> <span class="p">(</span><span class="k">if</span> <span class="nx">acc</span> <span class="k">then</span> <span class="nx">Access</span> <span class="k">else</span> <span class="nx">Index</span><span class="p">)</span> <span class="nx">idx</span><span class="p">]</span>
<span class="k">if</span> <span class="nx">name</span><span class="o">?</span> <span class="o">and</span> <span class="nx">name</span> <span class="k">in</span> <span class="nx">RESERVED</span>
<span class="k">throw</span> <span class="k">new</span> <span class="nx">SyntaxError</span> <span class="s">&quot;assignment to a reserved word: </span><span class="si">#{</span><span class="nx">obj</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">o</span><span class="si">}</span><span class="s"> = </span><span class="si">#{</span><span class="nx">val</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">o</span><span class="si">}</span><span class="s">&quot;</span>
<span class="nx">assigns</span><span class="p">.</span><span class="nx">push</span> <span class="k">new</span> <span class="nx">Assign</span><span class="p">(</span><span class="nx">obj</span><span class="p">,</span> <span class="nx">val</span><span class="p">,</span> <span class="kc">null</span><span class="p">,</span> <span class="nv">param: </span><span class="nx">@param</span><span class="p">,</span> <span class="nv">subpattern: </span><span class="kc">yes</span><span class="p">).</span><span class="nx">compile</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_LIST</span>
<span class="nx">assigns</span><span class="p">.</span><span class="nx">push</span> <span class="nx">vvar</span> <span class="k">unless</span> <span class="nx">top</span> <span class="o">or</span> <span class="nx">@subpattern</span>
<span class="nv">code = </span><span class="nx">assigns</span><span class="p">.</span><span class="nx">join</span> <span class="s">&#39;, &#39;</span>
<span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">level</span> <span class="o">&lt;</span> <span class="nx">LEVEL_LIST</span> <span class="k">then</span> <span class="nx">code</span> <span class="k">else</span> <span class="s">&quot;(</span><span class="si">#{</span><span class="nx">code</span><span class="si">}</span><span class="s">)&quot;</span></pre></div> </td> </tr> <tr id="section-97"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-97">&#182;</a> </div> <p>When compiling a conditional assignment, take care to ensure that the
<span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">level</span> <span class="o">&lt;</span> <span class="nx">LEVEL_LIST</span> <span class="k">then</span> <span class="nx">code</span> <span class="k">else</span> <span class="s">&quot;(</span><span class="si">#{</span><span class="nx">code</span><span class="si">}</span><span class="s">)&quot;</span></pre></div> </td> </tr> <tr id="section-98"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-98">&#182;</a> </div> <p>When compiling a conditional assignment, take care to ensure that the
operands are only evaluated once, even though we have to reference them
more than once.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compileConditional: </span><span class="nf">(o) -&gt;</span>
<span class="p">[</span><span class="nx">left</span><span class="p">,</span> <span class="nx">right</span><span class="p">]</span> <span class="o">=</span> <span class="nx">@variable</span><span class="p">.</span><span class="nx">cacheReference</span> <span class="nx">o</span></pre></div> </td> </tr> <tr id="section-98"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-98">&#182;</a> </div> <p>Disallow conditional assignment of undefined variables.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span> <span class="o">not</span> <span class="nx">left</span><span class="p">.</span><span class="nx">properties</span><span class="p">.</span><span class="nx">length</span> <span class="o">and</span> <span class="nx">left</span><span class="p">.</span><span class="nx">base</span> <span class="k">instanceof</span> <span class="nx">Literal</span> <span class="o">and</span>
<span class="p">[</span><span class="nx">left</span><span class="p">,</span> <span class="nx">right</span><span class="p">]</span> <span class="o">=</span> <span class="nx">@variable</span><span class="p">.</span><span class="nx">cacheReference</span> <span class="nx">o</span></pre></div> </td> </tr> <tr id="section-99"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-99">&#182;</a> </div> <p>Disallow conditional assignment of undefined variables.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span> <span class="o">not</span> <span class="nx">left</span><span class="p">.</span><span class="nx">properties</span><span class="p">.</span><span class="nx">length</span> <span class="o">and</span> <span class="nx">left</span><span class="p">.</span><span class="nx">base</span> <span class="k">instanceof</span> <span class="nx">Literal</span> <span class="o">and</span>
<span class="nx">left</span><span class="p">.</span><span class="nx">base</span><span class="p">.</span><span class="nx">value</span> <span class="o">!=</span> <span class="s">&quot;this&quot;</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">check</span> <span class="nx">left</span><span class="p">.</span><span class="nx">base</span><span class="p">.</span><span class="nx">value</span>
<span class="k">throw</span> <span class="k">new</span> <span class="nb">Error</span> <span class="s">&quot;the variable \&quot;</span><span class="si">#{</span><span class="nx">left</span><span class="p">.</span><span class="nx">base</span><span class="p">.</span><span class="nx">value</span><span class="si">}</span><span class="s">\&quot; can&#39;t be assigned with </span><span class="si">#{</span><span class="nx">@context</span><span class="si">}</span><span class="s"> because it has not been defined.&quot;</span>
<span class="k">if</span> <span class="s">&quot;?&quot;</span> <span class="k">in</span> <span class="nx">@context</span> <span class="k">then</span> <span class="nv">o.isExistentialEquals = </span><span class="kc">true</span>
<span class="k">new</span> <span class="nx">Op</span><span class="p">(</span><span class="nx">@context</span><span class="p">[...</span><span class="o">-</span><span class="mi">1</span><span class="p">],</span> <span class="nx">left</span><span class="p">,</span> <span class="k">new</span> <span class="nx">Assign</span><span class="p">(</span><span class="nx">right</span><span class="p">,</span> <span class="nx">@value</span><span class="p">,</span> <span class="s">&#39;=&#39;</span><span class="p">)</span> <span class="p">).</span><span class="nx">compile</span> <span class="nx">o</span></pre></div> </td> </tr> <tr id="section-99"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-99">&#182;</a> </div> <p>Compile the assignment from an array splice literal, using JavaScript's
<span class="nx">Op</span><span class="p">.</span><span class="nx">create</span><span class="p">(</span><span class="nx">@context</span><span class="p">[...</span><span class="o">-</span><span class="mi">1</span><span class="p">],</span> <span class="nx">left</span><span class="p">,</span> <span class="k">new</span> <span class="nx">Assign</span><span class="p">(</span><span class="nx">right</span><span class="p">,</span> <span class="nx">@value</span><span class="p">,</span> <span class="s">&#39;=&#39;</span><span class="p">)</span> <span class="p">).</span><span class="nx">compile</span> <span class="nx">o</span></pre></div> </td> </tr> <tr id="section-100"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-100">&#182;</a> </div> <p>Compile the assignment from an array splice literal, using JavaScript's
<code>Array#splice</code> method.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compileSplice: </span><span class="nf">(o) -&gt;</span>
<span class="p">{</span><span class="nv">range: </span><span class="p">{</span><span class="nx">from</span><span class="p">,</span> <span class="nx">to</span><span class="p">,</span> <span class="nx">exclusive</span><span class="p">}}</span> <span class="o">=</span> <span class="nx">@variable</span><span class="p">.</span><span class="nx">properties</span><span class="p">.</span><span class="nx">pop</span><span class="p">()</span>
<span class="nv">name = </span><span class="nx">@variable</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">o</span>
@@ -877,7 +878,7 @@ more than once.</p> </td> <td class="code">
<span class="nv">to = </span><span class="s">&quot;9e9&quot;</span>
<span class="p">[</span><span class="nx">valDef</span><span class="p">,</span> <span class="nx">valRef</span><span class="p">]</span> <span class="o">=</span> <span class="nx">@value</span><span class="p">.</span><span class="nx">cache</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_LIST</span>
<span class="nv">code = </span><span class="s">&quot;[].splice.apply(</span><span class="si">#{</span><span class="nx">name</span><span class="si">}</span><span class="s">, [</span><span class="si">#{</span><span class="nx">fromDecl</span><span class="si">}</span><span class="s">, </span><span class="si">#{</span><span class="nx">to</span><span class="si">}</span><span class="s">].concat(</span><span class="si">#{</span><span class="nx">valDef</span><span class="si">}</span><span class="s">)), </span><span class="si">#{</span><span class="nx">valRef</span><span class="si">}</span><span class="s">&quot;</span>
<span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">level</span> <span class="o">&gt;</span> <span class="nx">LEVEL_TOP</span> <span class="k">then</span> <span class="s">&quot;(</span><span class="si">#{</span><span class="nx">code</span><span class="si">}</span><span class="s">)&quot;</span> <span class="k">else</span> <span class="nx">code</span></pre></div> </td> </tr> <tr id="section-100"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-100">&#182;</a> </div> <h3>Code</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-101"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-101">&#182;</a> </div> <p>A function definition. This is the only node that creates a new Scope.
<span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">level</span> <span class="o">&gt;</span> <span class="nx">LEVEL_TOP</span> <span class="k">then</span> <span class="s">&quot;(</span><span class="si">#{</span><span class="nx">code</span><span class="si">}</span><span class="s">)&quot;</span> <span class="k">else</span> <span class="nx">code</span></pre></div> </td> </tr> <tr id="section-101"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-101">&#182;</a> </div> <h3>Code</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-102"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-102">&#182;</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 Code
has no <em>children</em> -- they're within the inner scope.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.Code = </span><span class="k">class</span> <span class="nx">Code</span> <span class="k">extends</span> <span class="nx">Base</span>
<span class="nv">constructor: </span><span class="nf">(params, body, tag) -&gt;</span>
@@ -890,7 +891,7 @@ has no <em>children</em> -- they're within the inner scope.</p> </td
<span class="nv">isStatement: </span><span class="nf">-&gt;</span> <span class="o">!!</span><span class="nx">@ctor</span>
<span class="nv">jumps: </span><span class="nx">NO</span></pre></div> </td> </tr> <tr id="section-102"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-102">&#182;</a> </div> <p>Compilation creates a new scope unless explicitly asked to share with the
<span class="nv">jumps: </span><span class="nx">NO</span></pre></div> </td> </tr> <tr id="section-103"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-103">&#182;</a> </div> <p>Compilation creates a new scope unless explicitly asked to share with the
outer scope. Handles splat parameters in the parameter list by peeking at
the JavaScript <code>arguments</code> object. If the function is bound with the <code>=&gt;</code>
arrow, generates a wrapper that saves the current value of <code>this</code> through
@@ -908,19 +909,19 @@ a closure.</p> </td> <td class="code"> <di
<span class="k">for</span> <span class="p">{</span><span class="nv">name: </span><span class="nx">p</span><span class="p">}</span> <span class="k">in</span> <span class="nx">@params</span>
<span class="k">if</span> <span class="nx">p</span><span class="p">.</span><span class="nx">this</span> <span class="k">then</span> <span class="nv">p = </span><span class="nx">p</span><span class="p">.</span><span class="nx">properties</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nx">name</span>
<span class="k">if</span> <span class="nx">p</span><span class="p">.</span><span class="nx">value</span> <span class="k">then</span> <span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">add</span> <span class="nx">p</span><span class="p">.</span><span class="nx">value</span><span class="p">,</span> <span class="s">&#39;var&#39;</span><span class="p">,</span> <span class="kc">yes</span>
<span class="nv">splats = </span><span class="k">new</span> <span class="nx">Assign</span> <span class="k">new</span> <span class="nx">Value</span><span class="p">(</span><span class="k">new</span> <span class="nx">Arr</span><span class="p">(</span><span class="nx">p</span><span class="p">.</span><span class="nx">asReference</span> <span class="nx">o</span> <span class="k">for</span> <span class="nx">p</span> <span class="k">in</span> <span class="nx">@params</span><span class="p">)),</span>
<span class="k">new</span> <span class="nx">Value</span> <span class="k">new</span> <span class="nx">Literal</span> <span class="s">&#39;arguments&#39;</span>
<span class="nv">splats = </span><span class="k">new</span> <span class="nx">Assign</span> <span class="nx">Value</span><span class="p">.</span><span class="nx">wrap</span><span class="p">(</span><span class="k">new</span> <span class="nx">Arr</span><span class="p">(</span><span class="nx">p</span><span class="p">.</span><span class="nx">asReference</span> <span class="nx">o</span> <span class="k">for</span> <span class="nx">p</span> <span class="k">in</span> <span class="nx">@params</span><span class="p">)),</span>
<span class="nx">Value</span><span class="p">.</span><span class="nx">wrap</span> <span class="k">new</span> <span class="nx">Literal</span> <span class="s">&#39;arguments&#39;</span>
<span class="k">break</span>
<span class="k">for</span> <span class="nx">param</span> <span class="k">in</span> <span class="nx">@params</span>
<span class="k">if</span> <span class="nx">param</span><span class="p">.</span><span class="nx">isComplex</span><span class="p">()</span>
<span class="nv">val = ref = </span><span class="nx">param</span><span class="p">.</span><span class="nx">asReference</span> <span class="nx">o</span>
<span class="nv">val = </span><span class="k">new</span> <span class="nx">Op</span> <span class="s">&#39;?&#39;</span><span class="p">,</span> <span class="nx">ref</span><span class="p">,</span> <span class="nx">param</span><span class="p">.</span><span class="nx">value</span> <span class="k">if</span> <span class="nx">param</span><span class="p">.</span><span class="nx">value</span>
<span class="nx">exprs</span><span class="p">.</span><span class="nx">push</span> <span class="k">new</span> <span class="nx">Assign</span> <span class="k">new</span> <span class="nx">Value</span><span class="p">(</span><span class="nx">param</span><span class="p">.</span><span class="nx">name</span><span class="p">),</span> <span class="nx">val</span><span class="p">,</span> <span class="s">&#39;=&#39;</span><span class="p">,</span> <span class="nv">param: </span><span class="kc">yes</span>
<span class="nv">val = </span><span class="nx">Op</span><span class="p">.</span><span class="nx">create</span> <span class="s">&#39;?&#39;</span><span class="p">,</span> <span class="nx">ref</span><span class="p">,</span> <span class="nx">param</span><span class="p">.</span><span class="nx">value</span> <span class="k">if</span> <span class="nx">param</span><span class="p">.</span><span class="nx">value</span>
<span class="nx">exprs</span><span class="p">.</span><span class="nx">push</span> <span class="k">new</span> <span class="nx">Assign</span> <span class="nx">Value</span><span class="p">.</span><span class="nx">wrap</span><span class="p">(</span><span class="nx">param</span><span class="p">.</span><span class="nx">name</span><span class="p">),</span> <span class="nx">val</span><span class="p">,</span> <span class="s">&#39;=&#39;</span><span class="p">,</span> <span class="nv">param: </span><span class="kc">yes</span>
<span class="k">else</span>
<span class="nv">ref = </span><span class="nx">param</span>
<span class="k">if</span> <span class="nx">param</span><span class="p">.</span><span class="nx">value</span>
<span class="nv">lit = </span><span class="k">new</span> <span class="nx">Literal</span> <span class="nx">ref</span><span class="p">.</span><span class="nx">name</span><span class="p">.</span><span class="nx">value</span> <span class="o">+</span> <span class="s">&#39; == null&#39;</span>
<span class="nv">val = </span><span class="k">new</span> <span class="nx">Assign</span> <span class="k">new</span> <span class="nx">Value</span><span class="p">(</span><span class="nx">param</span><span class="p">.</span><span class="nx">name</span><span class="p">),</span> <span class="nx">param</span><span class="p">.</span><span class="nx">value</span><span class="p">,</span> <span class="s">&#39;=&#39;</span>
<span class="nv">val = </span><span class="k">new</span> <span class="nx">Assign</span> <span class="nx">Value</span><span class="p">.</span><span class="nx">wrap</span><span class="p">(</span><span class="nx">param</span><span class="p">.</span><span class="nx">name</span><span class="p">),</span> <span class="nx">param</span><span class="p">.</span><span class="nx">value</span><span class="p">,</span> <span class="s">&#39;=&#39;</span>
<span class="nx">exprs</span><span class="p">.</span><span class="nx">push</span> <span class="k">new</span> <span class="nx">If</span> <span class="nx">lit</span><span class="p">,</span> <span class="nx">val</span>
<span class="nx">params</span><span class="p">.</span><span class="nx">push</span> <span class="nx">ref</span> <span class="k">unless</span> <span class="nx">splats</span>
<span class="nv">wasEmpty = </span><span class="nx">@body</span><span class="p">.</span><span class="nx">isEmpty</span><span class="p">()</span>
@@ -944,12 +945,12 @@ a closure.</p> </td> <td class="code"> <di
<span class="nx">code</span> <span class="o">+=</span> <span class="s">&quot;\n</span><span class="si">#{</span> <span class="nx">@body</span><span class="p">.</span><span class="nx">compileWithDeclarations</span> <span class="nx">o</span> <span class="si">}</span><span class="s">\n</span><span class="si">#{</span><span class="nx">@tab</span><span class="si">}</span><span class="s">&quot;</span> <span class="k">unless</span> <span class="nx">@body</span><span class="p">.</span><span class="nx">isEmpty</span><span class="p">()</span>
<span class="nx">code</span> <span class="o">+=</span> <span class="s">&#39;}&#39;</span>
<span class="k">return</span> <span class="nx">@tab</span> <span class="o">+</span> <span class="nx">code</span> <span class="k">if</span> <span class="nx">@ctor</span>
<span class="k">if</span> <span class="nx">@front</span> <span class="o">or</span> <span class="p">(</span><span class="nx">o</span><span class="p">.</span><span class="nx">level</span> <span class="o">&gt;=</span> <span class="nx">LEVEL_ACCESS</span><span class="p">)</span> <span class="k">then</span> <span class="s">&quot;(</span><span class="si">#{</span><span class="nx">code</span><span class="si">}</span><span class="s">)&quot;</span> <span class="k">else</span> <span class="nx">code</span></pre></div> </td> </tr> <tr id="section-103"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-103">&#182;</a> </div> <p>A list of parameter names, excluding those generated by the compiler.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">paramNames: </span><span class="nf">-&gt;</span>
<span class="k">if</span> <span class="nx">@front</span> <span class="o">or</span> <span class="p">(</span><span class="nx">o</span><span class="p">.</span><span class="nx">level</span> <span class="o">&gt;=</span> <span class="nx">LEVEL_ACCESS</span><span class="p">)</span> <span class="k">then</span> <span class="s">&quot;(</span><span class="si">#{</span><span class="nx">code</span><span class="si">}</span><span class="s">)&quot;</span> <span class="k">else</span> <span class="nx">code</span></pre></div> </td> </tr> <tr id="section-104"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-104">&#182;</a> </div> <p>A list of parameter names, excluding those generated by the compiler.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">paramNames: </span><span class="nf">-&gt;</span>
<span class="nv">names = </span><span class="p">[]</span>
<span class="nx">names</span><span class="p">.</span><span class="nx">push</span> <span class="nx">param</span><span class="p">.</span><span class="nx">names</span><span class="p">()...</span> <span class="k">for</span> <span class="nx">param</span> <span class="k">in</span> <span class="nx">@params</span>
<span class="nx">names</span></pre></div> </td> </tr> <tr id="section-104"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-104">&#182;</a> </div> <p>Short-circuit <code>traverseChildren</code> method to prevent it from crossing scope boundaries
<span class="nx">names</span></pre></div> </td> </tr> <tr id="section-105"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-105">&#182;</a> </div> <p>Short-circuit <code>traverseChildren</code> method to prevent it from crossing scope boundaries
unless <code>crossScope</code> is <code>true</code>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">traverseChildren: </span><span class="nf">(crossScope, func) -&gt;</span>
<span class="k">super</span><span class="p">(</span><span class="nx">crossScope</span><span class="p">,</span> <span class="nx">func</span><span class="p">)</span> <span class="k">if</span> <span class="nx">crossScope</span></pre></div> </td> </tr> <tr id="section-105"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-105">&#182;</a> </div> <h3>Param</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-106"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-106">&#182;</a> </div> <p>A parameter in a function definition. Beyond a typical Javascript parameter,
<span class="k">super</span><span class="p">(</span><span class="nx">crossScope</span><span class="p">,</span> <span class="nx">func</span><span class="p">)</span> <span class="k">if</span> <span class="nx">crossScope</span></pre></div> </td> </tr> <tr id="section-106"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-106">&#182;</a> </div> <h3>Param</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-107"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-107">&#182;</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><span class="nv">exports.Param = </span><span class="k">class</span> <span class="nx">Param</span> <span class="k">extends</span> <span class="nx">Base</span>
<span class="nv">constructor: </span><span class="nf">(@name, @value, @splat) -&gt;</span>
@@ -970,12 +971,12 @@ as well as be a splat, gathering up a group of parameters into an array.</p>
<span class="nv">node = </span><span class="k">new</span> <span class="nx">Literal</span> <span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span> <span class="nx">node</span><span class="p">.</span><span class="nx">value</span>
<span class="k">else</span> <span class="k">if</span> <span class="nx">node</span><span class="p">.</span><span class="nx">isComplex</span><span class="p">()</span>
<span class="nv">node = </span><span class="k">new</span> <span class="nx">Literal</span> <span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span> <span class="s">&#39;arg&#39;</span>
<span class="nv">node = </span><span class="k">new</span> <span class="nx">Value</span> <span class="nx">node</span>
<span class="nv">node = </span><span class="nx">Value</span><span class="p">.</span><span class="nx">wrap</span> <span class="nx">node</span>
<span class="nv">node = </span><span class="k">new</span> <span class="nx">Splat</span> <span class="nx">node</span> <span class="k">if</span> <span class="nx">@splat</span>
<span class="vi">@reference = </span><span class="nx">node</span>
<span class="nv">isComplex: </span><span class="nf">-&gt;</span>
<span class="nx">@name</span><span class="p">.</span><span class="nx">isComplex</span><span class="p">()</span></pre></div> </td> </tr> <tr id="section-107"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-107">&#182;</a> </div> <p>Finds the name or names of a <code>Param</code>; useful for detecting duplicates.
<span class="nx">@name</span><span class="p">.</span><span class="nx">isComplex</span><span class="p">()</span></pre></div> </td> </tr> <tr id="section-108"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-108">&#182;</a> </div> <p>Finds the name or names of a <code>Param</code>; useful for detecting duplicates.
In a sense, a destructured parameter represents multiple JS parameters,
thus this method returns an <code>Array</code> of names.
Reserved words used as param names, as well as the Object and Array
@@ -984,31 +985,31 @@ during the <code>Code</code> compilation step, so this is necessarily an incompl
list of a parameter's names.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">names: </span><span class="nf">(name = @name)-&gt;</span>
<span class="nv">atParam = </span><span class="nf">(obj) -&gt;</span>
<span class="p">{</span><span class="nx">value</span><span class="p">}</span> <span class="o">=</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">properties</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nx">name</span>
<span class="k">return</span> <span class="k">if</span> <span class="nx">value</span><span class="p">.</span><span class="nx">reserved</span> <span class="k">then</span> <span class="p">[]</span> <span class="k">else</span> <span class="p">[</span><span class="nx">value</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-108"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-108">&#182;</a> </div> <ul>
<span class="k">return</span> <span class="k">if</span> <span class="nx">value</span><span class="p">.</span><span class="nx">reserved</span> <span class="k">then</span> <span class="p">[]</span> <span class="k">else</span> <span class="p">[</span><span class="nx">value</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-109"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-109">&#182;</a> </div> <ul>
<li>simple literals <code>foo</code></li>
</ul> </td> <td class="code"> <div class="highlight"><pre> <span class="k">return</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="k">if</span> <span class="nx">name</span> <span class="k">instanceof</span> <span class="nx">Literal</span></pre></div> </td> </tr> <tr id="section-109"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-109">&#182;</a> </div> <ul>
</ul> </td> <td class="code"> <div class="highlight"><pre> <span class="k">return</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="k">if</span> <span class="nx">name</span> <span class="k">instanceof</span> <span class="nx">Literal</span></pre></div> </td> </tr> <tr id="section-110"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-110">&#182;</a> </div> <ul>
<li>at-params <code>@foo</code></li>
</ul> </td> <td class="code"> <div class="highlight"><pre> <span class="k">return</span> <span class="nx">atParam</span><span class="p">(</span><span class="nx">name</span><span class="p">)</span> <span class="k">if</span> <span class="nx">name</span> <span class="k">instanceof</span> <span class="nx">Value</span>
<span class="nv">names = </span><span class="p">[]</span>
<span class="k">for</span> <span class="nx">obj</span> <span class="k">in</span> <span class="nx">name</span><span class="p">.</span><span class="nx">objects</span></pre></div> </td> </tr> <tr id="section-110"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-110">&#182;</a> </div> <ul>
<span class="k">for</span> <span class="nx">obj</span> <span class="k">in</span> <span class="nx">name</span><span class="p">.</span><span class="nx">objects</span></pre></div> </td> </tr> <tr id="section-111"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-111">&#182;</a> </div> <ul>
<li>assignments within destructured parameters <code>{foo:bar}</code></li>
</ul> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span> <span class="nx">obj</span> <span class="k">instanceof</span> <span class="nx">Assign</span>
<span class="nx">names</span><span class="p">.</span><span class="nx">push</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">value</span><span class="p">.</span><span class="nx">unwrap</span><span class="p">().</span><span class="nx">value</span></pre></div> </td> </tr> <tr id="section-111"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-111">&#182;</a> </div> <ul>
<span class="nx">names</span><span class="p">.</span><span class="nx">push</span> <span class="nx">@names</span><span class="p">(</span><span class="nx">obj</span><span class="p">.</span><span class="nx">value</span><span class="p">.</span><span class="nx">unwrap</span><span class="p">())...</span></pre></div> </td> </tr> <tr id="section-112"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-112">&#182;</a> </div> <ul>
<li>splats within destructured parameters <code>[xs...]</code></li>
</ul> </td> <td class="code"> <div class="highlight"><pre> <span class="k">else</span> <span class="k">if</span> <span class="nx">obj</span> <span class="k">instanceof</span> <span class="nx">Splat</span>
<span class="nx">names</span><span class="p">.</span><span class="nx">push</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">name</span><span class="p">.</span><span class="nx">unwrap</span><span class="p">().</span><span class="nx">value</span>
<span class="k">else</span> <span class="k">if</span> <span class="nx">obj</span> <span class="k">instanceof</span> <span class="nx">Value</span></pre></div> </td> </tr> <tr id="section-112"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-112">&#182;</a> </div> <ul>
<span class="k">else</span> <span class="k">if</span> <span class="nx">obj</span> <span class="k">instanceof</span> <span class="nx">Value</span></pre></div> </td> </tr> <tr id="section-113"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-113">&#182;</a> </div> <ul>
<li>destructured parameters within destructured parameters <code>[{a}]</code></li>
</ul> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">isArray</span><span class="p">()</span> <span class="o">or</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">isObject</span><span class="p">()</span>
<span class="nx">names</span><span class="p">.</span><span class="nx">push</span> <span class="nx">@names</span><span class="p">(</span><span class="nx">obj</span><span class="p">.</span><span class="nx">base</span><span class="p">)...</span></pre></div> </td> </tr> <tr id="section-113"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-113">&#182;</a> </div> <ul>
<span class="nx">names</span><span class="p">.</span><span class="nx">push</span> <span class="nx">@names</span><span class="p">(</span><span class="nx">obj</span><span class="p">.</span><span class="nx">base</span><span class="p">)...</span></pre></div> </td> </tr> <tr id="section-114"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-114">&#182;</a> </div> <ul>
<li>at-params within destructured parameters <code>{@foo}</code></li>
</ul> </td> <td class="code"> <div class="highlight"><pre> <span class="k">else</span> <span class="k">if</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">this</span>
<span class="nx">names</span><span class="p">.</span><span class="nx">push</span> <span class="nx">atParam</span><span class="p">(</span><span class="nx">obj</span><span class="p">)...</span></pre></div> </td> </tr> <tr id="section-114"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-114">&#182;</a> </div> <ul>
<span class="nx">names</span><span class="p">.</span><span class="nx">push</span> <span class="nx">atParam</span><span class="p">(</span><span class="nx">obj</span><span class="p">)...</span></pre></div> </td> </tr> <tr id="section-115"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-115">&#182;</a> </div> <ul>
<li>simple destructured parameters {foo}</li>
</ul> </td> <td class="code"> <div class="highlight"><pre> <span class="k">else</span> <span class="nx">names</span><span class="p">.</span><span class="nx">push</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">base</span><span class="p">.</span><span class="nx">value</span>
<span class="k">else</span>
<span class="k">throw</span> <span class="nx">SyntaxError</span> <span class="s">&quot;illegal parameter </span><span class="si">#{</span><span class="nx">obj</span><span class="p">.</span><span class="nx">compile</span><span class="p">()</span><span class="si">}</span><span class="s">&quot;</span>
<span class="nx">names</span></pre></div> </td> </tr> <tr id="section-115"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-115">&#182;</a> </div> <h3>Splat</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-116"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-116">&#182;</a> </div> <p>A splat, either as a parameter to a function, an argument to a call,
<span class="nx">names</span></pre></div> </td> </tr> <tr id="section-116"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-116">&#182;</a> </div> <h3>Splat</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-117"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-117">&#182;</a> </div> <p>A splat, either as a parameter to a function, an argument to a call,
or as part of a destructuring assignment.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.Splat = </span><span class="k">class</span> <span class="nx">Splat</span> <span class="k">extends</span> <span class="nx">Base</span>
<span class="nv">children: </span><span class="p">[</span><span class="s">&#39;name&#39;</span><span class="p">]</span>
@@ -1022,9 +1023,9 @@ or as part of a destructuring assignment.</p> </td> <td
<span class="nx">@name</span><span class="p">.</span><span class="nx">assigns</span> <span class="nx">name</span>
<span class="nv">compile: </span><span class="nf">(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="nx">o</span> <span class="k">else</span> <span class="nx">@name</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">o</span>
<span class="nx">@name</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">o</span>
<span class="nv">unwrap: </span><span class="nf">-&gt;</span> <span class="nx">@name</span></pre></div> </td> </tr> <tr id="section-117"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-117">&#182;</a> </div> <p>Utility function that converts an arbitrary number of elements, mixed with
<span class="nv">unwrap: </span><span class="nf">-&gt;</span> <span class="nx">@name</span></pre></div> </td> </tr> <tr id="section-118"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-118">&#182;</a> </div> <p>Utility function that converts an arbitrary number of elements, mixed with
splats, to a proper array.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="vi">@compileSplattedArray: </span><span class="nf">(o, list, apply) -&gt;</span>
<span class="nv">index = </span><span class="o">-</span><span class="mi">1</span>
<span class="k">continue</span> <span class="k">while</span> <span class="p">(</span><span class="nv">node = </span><span class="nx">list</span><span class="p">[</span><span class="o">++</span><span class="nx">index</span><span class="p">])</span> <span class="o">and</span> <span class="nx">node</span> <span class="o">not</span> <span class="k">instanceof</span> <span class="nx">Splat</span>
@@ -1041,7 +1042,7 @@ splats, to a proper array.</p> </td> <td class="code">
<span class="k">else</span> <span class="s">&quot;[</span><span class="si">#{</span><span class="nx">code</span><span class="si">}</span><span class="s">]&quot;</span>
<span class="k">return</span> <span class="nx">args</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">+</span> <span class="s">&quot;.concat(</span><span class="si">#{</span> <span class="nx">args</span><span class="p">[</span><span class="mi">1</span><span class="p">..].</span><span class="nx">join</span> <span class="s">&#39;, &#39;</span> <span class="si">}</span><span class="s">)&quot;</span> <span class="k">if</span> <span class="nx">index</span> <span class="o">is</span> <span class="mi">0</span>
<span class="nv">base = </span><span class="p">(</span><span class="nx">node</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_LIST</span> <span class="k">for</span> <span class="nx">node</span> <span class="k">in</span> <span class="nx">list</span><span class="p">[...</span><span class="nx">index</span><span class="p">])</span>
<span class="s">&quot;[</span><span class="si">#{</span> <span class="nx">base</span><span class="p">.</span><span class="nx">join</span> <span class="s">&#39;, &#39;</span> <span class="si">}</span><span class="s">].concat(</span><span class="si">#{</span> <span class="nx">args</span><span class="p">.</span><span class="nx">join</span> <span class="s">&#39;, &#39;</span> <span class="si">}</span><span class="s">)&quot;</span></pre></div> </td> </tr> <tr id="section-118"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-118">&#182;</a> </div> <h3>While</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-119"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-119">&#182;</a> </div> <p>A while loop, the only sort of low-level loop exposed by CoffeeScript. From
<span class="s">&quot;[</span><span class="si">#{</span> <span class="nx">base</span><span class="p">.</span><span class="nx">join</span> <span class="s">&#39;, &#39;</span> <span class="si">}</span><span class="s">].concat(</span><span class="si">#{</span> <span class="nx">args</span><span class="p">.</span><span class="nx">join</span> <span class="s">&#39;, &#39;</span> <span class="si">}</span><span class="s">)&quot;</span></pre></div> </td> </tr> <tr id="section-119"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-119">&#182;</a> </div> <h3>While</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-120"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-120">&#182;</a> </div> <p>A while loop, the only sort of low-level loop exposed by CoffeeScript. From
it, all other loops can be manufactured. Useful in cases where you need more
flexibility or more speed than a comprehension can provide.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.While = </span><span class="k">class</span> <span class="nx">While</span> <span class="k">extends</span> <span class="nx">Base</span>
<span class="nv">constructor: </span><span class="nf">(condition, options) -&gt;</span>
@@ -1067,7 +1068,7 @@ flexibility or more speed than a comprehension can provide.</p> </td
<span class="k">return</span> <span class="kc">no</span> <span class="k">unless</span> <span class="nx">expressions</span><span class="p">.</span><span class="nx">length</span>
<span class="k">for</span> <span class="nx">node</span> <span class="k">in</span> <span class="nx">expressions</span>
<span class="k">return</span> <span class="nx">node</span> <span class="k">if</span> <span class="nx">node</span><span class="p">.</span><span class="nx">jumps</span> <span class="k">loop</span><span class="o">:</span> <span class="kc">yes</span>
<span class="kc">no</span></pre></div> </td> </tr> <tr id="section-120"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-120">&#182;</a> </div> <p>The main difference from a JavaScript <em>while</em> is that the CoffeeScript
<span class="kc">no</span></pre></div> </td> </tr> <tr id="section-121"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-121">&#182;</a> </div> <p>The main difference from a JavaScript <em>while</em> is that the CoffeeScript
<em>while</em> can be used as a part of a larger expression -- while loops may
return an array containing the computed result of each iteration.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compileNode: </span><span class="nf">(o) -&gt;</span>
<span class="nx">o</span><span class="p">.</span><span class="nx">indent</span> <span class="o">+=</span> <span class="nx">TAB</span>
@@ -1088,23 +1089,24 @@ return an array containing the computed result of each iteration.</p>
<span class="nv">code = </span><span class="nx">set</span> <span class="o">+</span> <span class="nx">@tab</span> <span class="o">+</span> <span class="s">&quot;while (</span><span class="si">#{</span> <span class="nx">@condition</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_PAREN</span> <span class="si">}</span><span class="s">) {</span><span class="si">#{</span><span class="nx">body</span><span class="si">}</span><span class="s">}&quot;</span>
<span class="k">if</span> <span class="nx">@returns</span>
<span class="nx">code</span> <span class="o">+=</span> <span class="s">&quot;\n</span><span class="si">#{</span><span class="nx">@tab</span><span class="si">}</span><span class="s">return </span><span class="si">#{</span><span class="nx">rvar</span><span class="si">}</span><span class="s">;&quot;</span>
<span class="nx">code</span></pre></div> </td> </tr> <tr id="section-121"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-121">&#182;</a> </div> <h3>Op</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-122"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-122">&#182;</a> </div> <p>Simple Arithmetic and logical operations. Performs some conversion from
<span class="nx">code</span></pre></div> </td> </tr> <tr id="section-122"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-122">&#182;</a> </div> <h3>Op</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-123"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-123">&#182;</a> </div> <p>Simple Arithmetic and logical operations. Performs some conversion from
CoffeeScript operations into their JavaScript equivalents.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.Op = </span><span class="k">class</span> <span class="nx">Op</span> <span class="k">extends</span> <span class="nx">Base</span>
<span class="nv">constructor: </span><span class="nf">(op, first, second, flip ) -&gt;</span>
<span class="k">return</span> <span class="k">new</span> <span class="nx">In</span> <span class="nx">first</span><span class="p">,</span> <span class="nx">second</span> <span class="k">if</span> <span class="nx">op</span> <span class="o">is</span> <span class="s">&#39;in&#39;</span>
<span class="vi">@create: </span><span class="nf">(op, first, second, flip) -&gt;</span>
<span class="k">if</span> <span class="nx">op</span> <span class="o">is</span> <span class="s">&#39;in&#39;</span>
<span class="k">return</span> <span class="k">new</span> <span class="nx">In</span> <span class="nx">first</span><span class="p">,</span> <span class="nx">second</span>
<span class="k">if</span> <span class="nx">op</span> <span class="o">is</span> <span class="s">&#39;do&#39;</span>
<span class="k">return</span> <span class="nx">@generateDo</span> <span class="nx">first</span>
<span class="k">if</span> <span class="nx">op</span> <span class="o">is</span> <span class="s">&#39;new&#39;</span>
<span class="k">return</span> <span class="nx">first</span><span class="p">.</span><span class="nx">newInstance</span><span class="p">()</span> <span class="k">if</span> <span class="nx">first</span> <span class="k">instanceof</span> <span class="nx">Call</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">first</span><span class="p">.</span><span class="nx">do</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">first</span><span class="p">.</span><span class="nx">isNew</span>
<span class="nv">first = </span><span class="k">new</span> <span class="nx">Parens</span> <span class="nx">first</span> <span class="k">if</span> <span class="nx">first</span> <span class="k">instanceof</span> <span class="nx">Code</span> <span class="o">and</span> <span class="nx">first</span><span class="p">.</span><span class="nx">bound</span> <span class="o">or</span> <span class="nx">first</span><span class="p">.</span><span class="nx">do</span>
<span class="k">return</span> <span class="k">new</span> <span class="nx">Op</span> <span class="nx">op</span><span class="p">,</span> <span class="nx">first</span><span class="p">,</span> <span class="nx">second</span><span class="p">,</span> <span class="nx">flip</span>
<span class="nv">constructor: </span><span class="nf">(op, @first, @second, flip ) -&gt;</span>
<span class="vi">@operator = </span><span class="nx">CONVERSIONS</span><span class="p">[</span><span class="nx">op</span><span class="p">]</span> <span class="o">or</span> <span class="nx">op</span>
<span class="vi">@first = </span><span class="nx">first</span>
<span class="vi">@second = </span><span class="nx">second</span>
<span class="vi">@flip = </span><span class="o">!!</span><span class="nx">flip</span>
<span class="k">return</span> <span class="k">this</span></pre></div> </td> </tr> <tr id="section-123"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-123">&#182;</a> </div> <p>The map of conversions from CoffeeScript to JavaScript symbols.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">CONVERSIONS =</span>
<span class="vi">@flip = </span><span class="o">!!</span><span class="nx">flip</span></pre></div> </td> </tr> <tr id="section-124"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-124">&#182;</a> </div> <p>The map of conversions from CoffeeScript to JavaScript symbols.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">CONVERSIONS =</span>
<span class="s">&#39;==&#39;</span><span class="o">:</span> <span class="s">&#39;===&#39;</span>
<span class="s">&#39;!=&#39;</span><span class="o">:</span> <span class="s">&#39;!==&#39;</span>
<span class="s">&#39;of&#39;</span><span class="o">:</span> <span class="s">&#39;in&#39;</span></pre></div> </td> </tr> <tr id="section-124"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-124">&#182;</a> </div> <p>The map of invertible operators.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">INVERSIONS =</span>
<span class="s">&#39;of&#39;</span><span class="o">:</span> <span class="s">&#39;in&#39;</span></pre></div> </td> </tr> <tr id="section-125"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-125">&#182;</a> </div> <p>The map of invertible operators.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">INVERSIONS =</span>
<span class="s">&#39;!==&#39;</span><span class="o">:</span> <span class="s">&#39;===&#39;</span>
<span class="s">&#39;===&#39;</span><span class="o">:</span> <span class="s">&#39;!==&#39;</span>
@@ -1116,7 +1118,7 @@ CoffeeScript operations into their JavaScript equivalents.</p> </td>
<span class="o">not</span> <span class="nx">@second</span>
<span class="nv">isComplex: </span><span class="nf">-&gt;</span>
<span class="o">not</span> <span class="p">(</span><span class="nx">@isUnary</span><span class="p">()</span> <span class="o">and</span> <span class="p">(</span><span class="nx">@operator</span> <span class="k">in</span> <span class="p">[</span><span class="s">&#39;+&#39;</span><span class="p">,</span> <span class="s">&#39;-&#39;</span><span class="p">]))</span> <span class="o">or</span> <span class="nx">@first</span><span class="p">.</span><span class="nx">isComplex</span><span class="p">()</span></pre></div> </td> </tr> <tr id="section-125"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-125">&#182;</a> </div> <p>Am I capable of
<span class="o">not</span> <span class="p">(</span><span class="nx">@isUnary</span><span class="p">()</span> <span class="o">and</span> <span class="p">(</span><span class="nx">@operator</span> <span class="k">in</span> <span class="p">[</span><span class="s">&#39;+&#39;</span><span class="p">,</span> <span class="s">&#39;-&#39;</span><span class="p">]))</span> <span class="o">or</span> <span class="nx">@first</span><span class="p">.</span><span class="nx">isComplex</span><span class="p">()</span></pre></div> </td> </tr> <tr id="section-126"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-126">&#182;</a> </div> <p>Am I capable of
<a href="http://docs.python.org/reference/expressions.html#notin">Python-style comparison chaining</a>?</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">isChainable: </span><span class="nf">-&gt;</span>
<span class="nx">@operator</span> <span class="k">in</span> <span class="p">[</span><span class="s">&#39;&lt;&#39;</span><span class="p">,</span> <span class="s">&#39;&gt;&#39;</span><span class="p">,</span> <span class="s">&#39;&gt;=&#39;</span><span class="p">,</span> <span class="s">&#39;&lt;=&#39;</span><span class="p">,</span> <span class="s">&#39;===&#39;</span><span class="p">,</span> <span class="s">&#39;!==&#39;</span><span class="p">]</span>
@@ -1145,12 +1147,12 @@ CoffeeScript operations into their JavaScript equivalents.</p> </td>
<span class="nx">fst</span><span class="p">.</span><span class="nx">operator</span> <span class="k">in</span> <span class="p">[</span><span class="s">&#39;!&#39;</span><span class="p">,</span> <span class="s">&#39;in&#39;</span><span class="p">,</span> <span class="s">&#39;instanceof&#39;</span><span class="p">]</span>
<span class="nx">fst</span>
<span class="k">else</span>
<span class="k">new</span> <span class="nx">Op</span> <span class="s">&#39;!&#39;</span><span class="p">,</span> <span class="k">this</span>
<span class="nx">Op</span><span class="p">.</span><span class="nx">create</span> <span class="s">&#39;!&#39;</span><span class="p">,</span> <span class="k">this</span>
<span class="nv">unfoldSoak: </span><span class="nf">(o) -&gt;</span>
<span class="nx">@operator</span> <span class="k">in</span> <span class="p">[</span><span class="s">&#39;++&#39;</span><span class="p">,</span> <span class="s">&#39;--&#39;</span><span class="p">,</span> <span class="s">&#39;delete&#39;</span><span class="p">]</span> <span class="o">and</span> <span class="nx">unfoldSoak</span> <span class="nx">o</span><span class="p">,</span> <span class="k">this</span><span class="p">,</span> <span class="s">&#39;first&#39;</span>
<span class="nv">generateDo: </span><span class="nf">(exp) -&gt;</span>
<span class="vi">@generateDo: </span><span class="nf">(exp) -&gt;</span>
<span class="nv">passedParams = </span><span class="p">[]</span>
<span class="nv">func = </span><span class="k">if</span> <span class="nx">exp</span> <span class="k">instanceof</span> <span class="nx">Assign</span> <span class="o">and</span> <span class="p">(</span><span class="nv">ref = </span><span class="nx">exp</span><span class="p">.</span><span class="nx">value</span><span class="p">.</span><span class="nx">unwrap</span><span class="p">())</span> <span class="k">instanceof</span> <span class="nx">Code</span>
<span class="nx">ref</span>
@@ -1167,7 +1169,7 @@ CoffeeScript operations into their JavaScript equivalents.</p> </td>
<span class="nx">call</span>
<span class="nv">compileNode: </span><span class="nf">(o) -&gt;</span>
<span class="nv">isChain = </span><span class="nx">@isChainable</span><span class="p">()</span> <span class="o">and</span> <span class="nx">@first</span><span class="p">.</span><span class="nx">isChainable</span><span class="p">()</span></pre></div> </td> </tr> <tr id="section-126"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-126">&#182;</a> </div> <p>In chains, there's no need to wrap bare obj literals in parens,
<span class="nv">isChain = </span><span class="nx">@isChainable</span><span class="p">()</span> <span class="o">and</span> <span class="nx">@first</span><span class="p">.</span><span class="nx">isChainable</span><span class="p">()</span></pre></div> </td> </tr> <tr id="section-127"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-127">&#182;</a> </div> <p>In chains, there's no need to wrap bare obj literals in parens,
as the chained expression is wrapped.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="vi">@first.front = </span><span class="nx">@front</span> <span class="k">unless</span> <span class="nx">isChain</span>
<span class="k">if</span> <span class="nx">@operator</span> <span class="o">is</span> <span class="s">&#39;delete&#39;</span> <span class="o">and</span> <span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">check</span><span class="p">(</span><span class="nx">@first</span><span class="p">.</span><span class="nx">unwrapAll</span><span class="p">().</span><span class="nx">value</span><span class="p">)</span>
<span class="k">throw</span> <span class="nx">SyntaxError</span> <span class="s">&#39;delete operand may not be argument or var&#39;</span>
@@ -1178,7 +1180,7 @@ as the chained expression is wrapped.</p> </td> <td clas
<span class="k">return</span> <span class="nx">@compileExistence</span> <span class="nx">o</span> <span class="k">if</span> <span class="nx">@operator</span> <span class="o">is</span> <span class="s">&#39;?&#39;</span>
<span class="nv">code = </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">LEVEL_OP</span><span class="p">)</span> <span class="o">+</span> <span class="s">&#39; &#39;</span> <span class="o">+</span> <span class="nx">@operator</span> <span class="o">+</span> <span class="s">&#39; &#39;</span> <span class="o">+</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">LEVEL_OP</span><span class="p">)</span>
<span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">level</span> <span class="o">&lt;=</span> <span class="nx">LEVEL_OP</span> <span class="k">then</span> <span class="nx">code</span> <span class="k">else</span> <span class="s">&quot;(</span><span class="si">#{</span><span class="nx">code</span><span class="si">}</span><span class="s">)&quot;</span></pre></div> </td> </tr> <tr id="section-127"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-127">&#182;</a> </div> <p>Mimic Python's chained comparisons when multiple comparison operators are
<span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">level</span> <span class="o">&lt;=</span> <span class="nx">LEVEL_OP</span> <span class="k">then</span> <span class="nx">code</span> <span class="k">else</span> <span class="s">&quot;(</span><span class="si">#{</span><span class="nx">code</span><span class="si">}</span><span class="s">)&quot;</span></pre></div> </td> </tr> <tr id="section-128"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-128">&#182;</a> </div> <p>Mimic Python's chained comparisons when multiple comparison operators are
used sequentially. For example:</p>
<pre><code>bin/coffee -e 'console.log 50 &lt; 65 &gt; 10'
@@ -1196,10 +1198,13 @@ true
<span class="k">else</span>
<span class="nv">fst = </span><span class="nx">@first</span>
<span class="nv">ref = </span><span class="nx">fst</span>
<span class="k">new</span> <span class="nx">If</span><span class="p">(</span><span class="k">new</span> <span class="nx">Existence</span><span class="p">(</span><span class="nx">fst</span><span class="p">),</span> <span class="nx">ref</span><span class="p">,</span> <span class="nv">type: </span><span class="s">&#39;if&#39;</span><span class="p">).</span><span class="nx">addElse</span><span class="p">(</span><span class="nx">@second</span><span class="p">).</span><span class="nx">compile</span> <span class="nx">o</span></pre></div> </td> </tr> <tr id="section-128"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-128">&#182;</a> </div> <p>Compile a unary <strong>Op</strong>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compileUnary: </span><span class="nf">(o) -&gt;</span>
<span class="k">new</span> <span class="nx">If</span><span class="p">(</span><span class="k">new</span> <span class="nx">Existence</span><span class="p">(</span><span class="nx">fst</span><span class="p">),</span> <span class="nx">ref</span><span class="p">,</span> <span class="nv">type: </span><span class="s">&#39;if&#39;</span><span class="p">).</span><span class="nx">addElse</span><span class="p">(</span><span class="nx">@second</span><span class="p">).</span><span class="nx">compile</span> <span class="nx">o</span></pre></div> </td> </tr> <tr id="section-129"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-129">&#182;</a> </div> <p>Compile a unary <strong>Op</strong>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compileUnary: </span><span class="nf">(o) -&gt;</span>
<span class="nv">parts = </span><span class="p">[</span><span class="nv">op = </span><span class="nx">@operator</span><span class="p">]</span>
<span class="k">if</span> <span class="nx">op</span> <span class="o">is</span> <span class="s">&#39;!&#39;</span> <span class="o">and</span> <span class="nx">@first</span> <span class="k">instanceof</span> <span class="nx">Existence</span>
<span class="vi">@first.negated = </span><span class="o">not</span> <span class="nx">@first</span><span class="p">.</span><span class="nx">negated</span>
<span class="k">return</span> <span class="nx">@first</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">o</span>
<span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">level</span> <span class="o">&gt;=</span> <span class="nx">LEVEL_ACCESS</span>
<span class="k">return</span> <span class="p">(</span><span class="k">new</span> <span class="nx">Parens</span> <span class="k">this</span><span class="p">).</span><span class="nx">compile</span> <span class="nx">o</span>
<span class="nv">parts = </span><span class="p">[</span><span class="nv">op = </span><span class="nx">@operator</span><span class="p">]</span>
<span class="nv">plusMinus = </span><span class="nx">op</span> <span class="k">in</span> <span class="p">[</span><span class="s">&#39;+&#39;</span><span class="p">,</span> <span class="s">&#39;-&#39;</span><span class="p">]</span>
<span class="nx">parts</span><span class="p">.</span><span class="nx">push</span> <span class="s">&#39; &#39;</span> <span class="k">if</span> <span class="nx">op</span> <span class="k">in</span> <span class="p">[</span><span class="s">&#39;new&#39;</span><span class="p">,</span> <span class="s">&#39;typeof&#39;</span><span class="p">,</span> <span class="s">&#39;delete&#39;</span><span class="p">]</span> <span class="o">or</span>
<span class="nx">plusMinus</span> <span class="o">and</span> <span class="nx">@first</span> <span class="k">instanceof</span> <span class="nx">Op</span> <span class="o">and</span> <span class="nx">@first</span><span class="p">.</span><span class="nx">operator</span> <span class="o">is</span> <span class="nx">op</span>
@@ -1210,7 +1215,7 @@ true
<span class="nx">parts</span><span class="p">.</span><span class="nx">join</span> <span class="s">&#39;&#39;</span>
<span class="nv">toString: </span><span class="nf">(idt) -&gt;</span>
<span class="k">super</span> <span class="nx">idt</span><span class="p">,</span> <span class="nx">@constructor</span><span class="p">.</span><span class="nx">name</span> <span class="o">+</span> <span class="s">&#39; &#39;</span> <span class="o">+</span> <span class="nx">@operator</span></pre></div> </td> </tr> <tr id="section-129"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-129">&#182;</a> </div> <h3>In</h3> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.In = </span><span class="k">class</span> <span class="nx">In</span> <span class="k">extends</span> <span class="nx">Base</span>
<span class="k">super</span> <span class="nx">idt</span><span class="p">,</span> <span class="nx">@constructor</span><span class="p">.</span><span class="nx">name</span> <span class="o">+</span> <span class="s">&#39; &#39;</span> <span class="o">+</span> <span class="nx">@operator</span></pre></div> </td> </tr> <tr id="section-130"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-130">&#182;</a> </div> <h3>In</h3> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.In = </span><span class="k">class</span> <span class="nx">In</span> <span class="k">extends</span> <span class="nx">Base</span>
<span class="nv">constructor: </span><span class="nf">(@object, @array) -&gt;</span>
<span class="nv">children: </span><span class="p">[</span><span class="s">&#39;object&#39;</span><span class="p">,</span> <span class="s">&#39;array&#39;</span><span class="p">]</span>
@@ -1221,7 +1226,7 @@ true
<span class="k">if</span> <span class="nx">@array</span> <span class="k">instanceof</span> <span class="nx">Value</span> <span class="o">and</span> <span class="nx">@array</span><span class="p">.</span><span class="nx">isArray</span><span class="p">()</span>
<span class="k">for</span> <span class="nx">obj</span> <span class="k">in</span> <span class="nx">@array</span><span class="p">.</span><span class="nx">base</span><span class="p">.</span><span class="nx">objects</span> <span class="k">when</span> <span class="nx">obj</span> <span class="k">instanceof</span> <span class="nx">Splat</span>
<span class="nv">hasSplat = </span><span class="kc">yes</span>
<span class="k">break</span></pre></div> </td> </tr> <tr id="section-130"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-130">&#182;</a> </div> <p><code>compileOrTest</code> only if we have an array literal with no splats</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">return</span> <span class="nx">@compileOrTest</span> <span class="nx">o</span> <span class="k">unless</span> <span class="nx">hasSplat</span>
<span class="k">break</span></pre></div> </td> </tr> <tr id="section-131"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-131">&#182;</a> </div> <p><code>compileOrTest</code> only if we have an array literal with no splats</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">return</span> <span class="nx">@compileOrTest</span> <span class="nx">o</span> <span class="k">unless</span> <span class="nx">hasSplat</span>
<span class="nx">@compileLoopTest</span> <span class="nx">o</span>
<span class="nv">compileOrTest: </span><span class="nf">(o) -&gt;</span>
@@ -1242,7 +1247,7 @@ true
<span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">level</span> <span class="o">&lt;</span> <span class="nx">LEVEL_LIST</span> <span class="k">then</span> <span class="nx">code</span> <span class="k">else</span> <span class="s">&quot;(</span><span class="si">#{</span><span class="nx">code</span><span class="si">}</span><span class="s">)&quot;</span>
<span class="nv">toString: </span><span class="nf">(idt) -&gt;</span>
<span class="k">super</span> <span class="nx">idt</span><span class="p">,</span> <span class="nx">@constructor</span><span class="p">.</span><span class="nx">name</span> <span class="o">+</span> <span class="k">if</span> <span class="nx">@negated</span> <span class="k">then</span> <span class="s">&#39;!&#39;</span> <span class="k">else</span> <span class="s">&#39;&#39;</span></pre></div> </td> </tr> <tr id="section-131"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-131">&#182;</a> </div> <h3>Try</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-132"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-132">&#182;</a> </div> <p>A classic <em>try/catch/finally</em> block.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.Try = </span><span class="k">class</span> <span class="nx">Try</span> <span class="k">extends</span> <span class="nx">Base</span>
<span class="k">super</span> <span class="nx">idt</span><span class="p">,</span> <span class="nx">@constructor</span><span class="p">.</span><span class="nx">name</span> <span class="o">+</span> <span class="k">if</span> <span class="nx">@negated</span> <span class="k">then</span> <span class="s">&#39;!&#39;</span> <span class="k">else</span> <span class="s">&#39;&#39;</span></pre></div> </td> </tr> <tr id="section-132"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-132">&#182;</a> </div> <h3>Try</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-133"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-133">&#182;</a> </div> <p>A classic <em>try/catch/finally</em> block.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.Try = </span><span class="k">class</span> <span class="nx">Try</span> <span class="k">extends</span> <span class="nx">Base</span>
<span class="nv">constructor: </span><span class="nf">(@attempt, @error, @recovery, @ensure) -&gt;</span>
<span class="nv">children: </span><span class="p">[</span><span class="s">&#39;attempt&#39;</span><span class="p">,</span> <span class="s">&#39;recovery&#39;</span><span class="p">,</span> <span class="s">&#39;ensure&#39;</span><span class="p">]</span>
@@ -1254,17 +1259,20 @@ true
<span class="nv">makeReturn: </span><span class="nf">(res) -&gt;</span>
<span class="vi">@attempt = </span><span class="nx">@attempt</span> <span class="p">.</span><span class="nx">makeReturn</span> <span class="nx">res</span> <span class="k">if</span> <span class="nx">@attempt</span>
<span class="vi">@recovery = </span><span class="nx">@recovery</span><span class="p">.</span><span class="nx">makeReturn</span> <span class="nx">res</span> <span class="k">if</span> <span class="nx">@recovery</span>
<span class="k">this</span></pre></div> </td> </tr> <tr id="section-133"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-133">&#182;</a> </div> <p>Compilation is more or less as you would expect -- the <em>finally</em> clause
<span class="k">this</span></pre></div> </td> </tr> <tr id="section-134"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-134">&#182;</a> </div> <p>Compilation is more or less as you would expect -- the <em>finally</em> clause
is optional, the <em>catch</em> is not.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compileNode: </span><span class="nf">(o) -&gt;</span>
<span class="nx">o</span><span class="p">.</span><span class="nx">indent</span> <span class="o">+=</span> <span class="nx">TAB</span>
<span class="nv">errorPart = </span><span class="k">if</span> <span class="nx">@error</span> <span class="k">then</span> <span class="s">&quot; (</span><span class="si">#{</span> <span class="nx">@error</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">o</span> <span class="si">}</span><span class="s">) &quot;</span> <span class="k">else</span> <span class="s">&#39; &#39;</span>
<span class="nv">tryPart = </span><span class="nx">@attempt</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_TOP</span>
<span class="nv">catchPart = </span><span class="k">if</span> <span class="nx">@recovery</span>
<span class="k">if</span> <span class="nx">@error</span><span class="p">.</span><span class="nx">isObject</span><span class="o">?</span><span class="p">()</span>
<span class="nv">placeholder = </span><span class="k">new</span> <span class="nx">Literal</span> <span class="s">&#39;_error&#39;</span>
<span class="nx">@recovery</span><span class="p">.</span><span class="nx">unshift</span> <span class="k">new</span> <span class="nx">Assign</span> <span class="nx">@error</span><span class="p">,</span> <span class="nx">placeholder</span>
<span class="vi">@error = </span><span class="nx">placeholder</span>
<span class="k">if</span> <span class="nx">@error</span><span class="p">.</span><span class="nx">value</span> <span class="k">in</span> <span class="nx">STRICT_PROSCRIBED</span>
<span class="k">throw</span> <span class="nx">SyntaxError</span> <span class="s">&quot;catch variable may not be \&quot;</span><span class="si">#{</span><span class="nx">@error</span><span class="p">.</span><span class="nx">value</span><span class="si">}</span><span class="s">\&quot;&quot;</span>
<span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">add</span> <span class="nx">@error</span><span class="p">.</span><span class="nx">value</span><span class="p">,</span> <span class="s">&#39;param&#39;</span> <span class="k">unless</span> <span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">check</span> <span class="nx">@error</span><span class="p">.</span><span class="nx">value</span>
<span class="s">&quot; catch</span><span class="si">#{</span><span class="nx">errorPart</span><span class="si">}</span><span class="s">{\n</span><span class="si">#{</span> <span class="nx">@recovery</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_TOP</span> <span class="si">}</span><span class="s">\n</span><span class="si">#{</span><span class="nx">@tab</span><span class="si">}</span><span class="s">}&quot;</span>
<span class="s">&quot; catch (</span><span class="si">#{</span> <span class="nx">@error</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">o</span> <span class="si">}</span><span class="s">) {\n</span><span class="si">#{</span> <span class="nx">@recovery</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_TOP</span> <span class="si">}</span><span class="s">\n</span><span class="si">#{</span><span class="nx">@tab</span><span class="si">}</span><span class="s">}&quot;</span>
<span class="k">else</span> <span class="k">unless</span> <span class="nx">@ensure</span> <span class="o">or</span> <span class="nx">@recovery</span>
<span class="s">&#39; catch (_error) {}&#39;</span>
@@ -1272,16 +1280,16 @@ is optional, the <em>catch</em> is not.</p> </td> <td cl
<span class="s">&quot;&quot;&quot;</span><span class="si">#{</span><span class="nx">@tab</span><span class="si">}</span><span class="s">try {</span>
<span class="s"> </span><span class="si">#{</span><span class="nx">tryPart</span><span class="si">}</span><span class="s"></span>
<span class="s"> </span><span class="si">#{</span><span class="nx">@tab</span><span class="si">}</span><span class="s">}</span><span class="si">#{</span> <span class="nx">catchPart</span> <span class="o">or</span> <span class="s">&#39;&#39;</span> <span class="si">}#{</span><span class="nx">ensurePart</span><span class="si">}</span><span class="s">&quot;&quot;&quot;</span></pre></div> </td> </tr> <tr id="section-134"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-134">&#182;</a> </div> <h3>Throw</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-135"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-135">&#182;</a> </div> <p>Simple node to throw an exception.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.Throw = </span><span class="k">class</span> <span class="nx">Throw</span> <span class="k">extends</span> <span class="nx">Base</span>
<span class="s"> </span><span class="si">#{</span><span class="nx">@tab</span><span class="si">}</span><span class="s">}</span><span class="si">#{</span> <span class="nx">catchPart</span> <span class="o">or</span> <span class="s">&#39;&#39;</span> <span class="si">}#{</span><span class="nx">ensurePart</span><span class="si">}</span><span class="s">&quot;&quot;&quot;</span></pre></div> </td> </tr> <tr id="section-135"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-135">&#182;</a> </div> <h3>Throw</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-136"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-136">&#182;</a> </div> <p>Simple node to throw an exception.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.Throw = </span><span class="k">class</span> <span class="nx">Throw</span> <span class="k">extends</span> <span class="nx">Base</span>
<span class="nv">constructor: </span><span class="nf">(@expression) -&gt;</span>
<span class="nv">children: </span><span class="p">[</span><span class="s">&#39;expression&#39;</span><span class="p">]</span>
<span class="nv">isStatement: </span><span class="nx">YES</span>
<span class="nv">jumps: </span> <span class="nx">NO</span></pre></div> </td> </tr> <tr id="section-136"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-136">&#182;</a> </div> <p>A <strong>Throw</strong> is already a return, of sorts...</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">makeReturn: </span><span class="nx">THIS</span>
<span class="nv">jumps: </span> <span class="nx">NO</span></pre></div> </td> </tr> <tr id="section-137"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-137">&#182;</a> </div> <p>A <strong>Throw</strong> is already a return, of sorts...</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">makeReturn: </span><span class="nx">THIS</span>
<span class="nv">compileNode: </span><span class="nf">(o) -&gt;</span>
<span class="nx">@tab</span> <span class="o">+</span> <span class="s">&quot;throw </span><span class="si">#{</span> <span class="nx">@expression</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">o</span> <span class="si">}</span><span class="s">;&quot;</span></pre></div> </td> </tr> <tr id="section-137"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-137">&#182;</a> </div> <h3>Existence</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-138"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-138">&#182;</a> </div> <p>Checks a variable for existence -- not <em>null</em> and not <em>undefined</em>. This is
<span class="nx">@tab</span> <span class="o">+</span> <span class="s">&quot;throw </span><span class="si">#{</span> <span class="nx">@expression</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">o</span> <span class="si">}</span><span class="s">;&quot;</span></pre></div> </td> </tr> <tr id="section-138"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-138">&#182;</a> </div> <h3>Existence</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-139"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-139">&#182;</a> </div> <p>Checks a variable for existence -- not <em>null</em> and not <em>undefined</em>. This is
similar to <code>.nil?</code> in Ruby, and avoids having to consult a JavaScript truth
table.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.Existence = </span><span class="k">class</span> <span class="nx">Existence</span> <span class="k">extends</span> <span class="nx">Base</span>
<span class="nv">constructor: </span><span class="nf">(@expression) -&gt;</span>
@@ -1296,8 +1304,8 @@ table.</p> </td> <td class="code"> <div cl
<span class="k">if</span> <span class="nx">IDENTIFIER</span><span class="p">.</span><span class="nx">test</span><span class="p">(</span><span class="nx">code</span><span class="p">)</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">check</span> <span class="nx">code</span>
<span class="p">[</span><span class="nx">cmp</span><span class="p">,</span> <span class="nx">cnj</span><span class="p">]</span> <span class="o">=</span> <span class="k">if</span> <span class="nx">@negated</span> <span class="k">then</span> <span class="p">[</span><span class="s">&#39;===&#39;</span><span class="p">,</span> <span class="s">&#39;||&#39;</span><span class="p">]</span> <span class="k">else</span> <span class="p">[</span><span class="s">&#39;!==&#39;</span><span class="p">,</span> <span class="s">&#39;&amp;&amp;&#39;</span><span class="p">]</span>
<span class="nv">code = </span><span class="s">&quot;typeof </span><span class="si">#{</span><span class="nx">code</span><span class="si">}</span><span class="s"> </span><span class="si">#{</span><span class="nx">cmp</span><span class="si">}</span><span class="s"> \&quot;undefined\&quot; </span><span class="si">#{</span><span class="nx">cnj</span><span class="si">}</span><span class="s"> </span><span class="si">#{</span><span class="nx">code</span><span class="si">}</span><span class="s"> </span><span class="si">#{</span><span class="nx">cmp</span><span class="si">}</span><span class="s"> null&quot;</span>
<span class="k">else</span></pre></div> </td> </tr> <tr id="section-139"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-139">&#182;</a> </div> <p>do not use strict equality here; it will break existing code</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">code = </span><span class="s">&quot;</span><span class="si">#{</span><span class="nx">code</span><span class="si">}</span><span class="s"> </span><span class="si">#{</span><span class="k">if</span> <span class="nx">@negated</span> <span class="k">then</span> <span class="s">&#39;==&#39;</span> <span class="k">else</span> <span class="s">&#39;!=&#39;</span><span class="si">}</span><span class="s"> null&quot;</span>
<span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">level</span> <span class="o">&lt;=</span> <span class="nx">LEVEL_COND</span> <span class="k">then</span> <span class="nx">code</span> <span class="k">else</span> <span class="s">&quot;(</span><span class="si">#{</span><span class="nx">code</span><span class="si">}</span><span class="s">)&quot;</span></pre></div> </td> </tr> <tr id="section-140"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-140">&#182;</a> </div> <h3>Parens</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-141"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-141">&#182;</a> </div> <p>An extra set of parentheses, specified explicitly in the source. At one time
<span class="k">else</span></pre></div> </td> </tr> <tr id="section-140"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-140">&#182;</a> </div> <p>do not use strict equality here; it will break existing code</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">code = </span><span class="s">&quot;</span><span class="si">#{</span><span class="nx">code</span><span class="si">}</span><span class="s"> </span><span class="si">#{</span><span class="k">if</span> <span class="nx">@negated</span> <span class="k">then</span> <span class="s">&#39;==&#39;</span> <span class="k">else</span> <span class="s">&#39;!=&#39;</span><span class="si">}</span><span class="s"> null&quot;</span>
<span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">level</span> <span class="o">&lt;=</span> <span class="nx">LEVEL_COND</span> <span class="k">then</span> <span class="nx">code</span> <span class="k">else</span> <span class="s">&quot;(</span><span class="si">#{</span><span class="nx">code</span><span class="si">}</span><span class="s">)&quot;</span></pre></div> </td> </tr> <tr id="section-141"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-141">&#182;</a> </div> <h3>Parens</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-142"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-142">&#182;</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>
@@ -1317,7 +1325,7 @@ parentheses, but no longer -- you can put in as many as you please.</p>
<span class="nv">code = </span><span class="nx">expr</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_PAREN</span>
<span class="nv">bare = </span><span class="nx">o</span><span class="p">.</span><span class="nx">level</span> <span class="o">&lt;</span> <span class="nx">LEVEL_OP</span> <span class="o">and</span> <span class="p">(</span><span class="nx">expr</span> <span class="k">instanceof</span> <span class="nx">Op</span> <span class="o">or</span> <span class="nx">expr</span> <span class="k">instanceof</span> <span class="nx">Call</span> <span class="o">or</span>
<span class="p">(</span><span class="nx">expr</span> <span class="k">instanceof</span> <span class="nx">For</span> <span class="o">and</span> <span class="nx">expr</span><span class="p">.</span><span class="nx">returns</span><span class="p">))</span>
<span class="k">if</span> <span class="nx">bare</span> <span class="k">then</span> <span class="nx">code</span> <span class="k">else</span> <span class="s">&quot;(</span><span class="si">#{</span><span class="nx">code</span><span class="si">}</span><span class="s">)&quot;</span></pre></div> </td> </tr> <tr id="section-142"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-142">&#182;</a> </div> <h3>For</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-143"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-143">&#182;</a> </div> <p>CoffeeScript's replacement for the <em>for</em> loop is our array and object
<span class="k">if</span> <span class="nx">bare</span> <span class="k">then</span> <span class="nx">code</span> <span class="k">else</span> <span class="s">&quot;(</span><span class="si">#{</span><span class="nx">code</span><span class="si">}</span><span class="s">)&quot;</span></pre></div> </td> </tr> <tr id="section-143"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-143">&#182;</a> </div> <h3>For</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-144"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-144">&#182;</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>
@@ -1337,7 +1345,7 @@ you can map and filter in a single pass.</p> </td> <td c
<span class="k">throw</span> <span class="nx">SyntaxError</span> <span class="s">&#39;cannot pattern match over range loops&#39;</span> <span class="k">if</span> <span class="nx">@range</span> <span class="o">and</span> <span class="nx">@pattern</span>
<span class="vi">@returns = </span><span class="kc">false</span>
<span class="nv">children: </span><span class="p">[</span><span class="s">&#39;body&#39;</span><span class="p">,</span> <span class="s">&#39;source&#39;</span><span class="p">,</span> <span class="s">&#39;guard&#39;</span><span class="p">,</span> <span class="s">&#39;step&#39;</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-144"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-144">&#182;</a> </div> <p>Welcome to the hairiest method in all of CoffeeScript. Handles the inner
<span class="nv">children: </span><span class="p">[</span><span class="s">&#39;body&#39;</span><span class="p">,</span> <span class="s">&#39;source&#39;</span><span class="p">,</span> <span class="s">&#39;guard&#39;</span><span class="p">,</span> <span class="s">&#39;step&#39;</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-145"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-145">&#182;</a> </div> <p>Welcome to the hairiest method in all of CoffeeScript. Handles the inner
loop, filtering, stepping, and result saving for array, object, and range
comprehensions. Some of the generated code can be shared in common, and
some cannot.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compileNode: </span><span class="nf">(o) -&gt;</span>
@@ -1353,7 +1361,10 @@ some cannot.</p> </td> <td class="code"> <
<span class="nv">rvar = </span><span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span> <span class="s">&#39;results&#39;</span> <span class="k">if</span> <span class="nx">@returns</span>
<span class="nv">ivar = </span><span class="p">(</span><span class="nx">@object</span> <span class="o">and</span> <span class="nx">index</span><span class="p">)</span> <span class="o">or</span> <span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span> <span class="s">&#39;i&#39;</span>
<span class="nv">kvar = </span><span class="p">(</span><span class="nx">@range</span> <span class="o">and</span> <span class="nx">name</span><span class="p">)</span> <span class="o">or</span> <span class="nx">index</span> <span class="o">or</span> <span class="nx">ivar</span>
<span class="nv">kvarAssign = </span><span class="k">if</span> <span class="nx">kvar</span> <span class="o">isnt</span> <span class="nx">ivar</span> <span class="k">then</span> <span class="s">&quot;</span><span class="si">#{</span><span class="nx">kvar</span><span class="si">}</span><span class="s"> = &quot;</span> <span class="k">else</span> <span class="s">&quot;&quot;</span></pre></div> </td> </tr> <tr id="section-145"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-145">&#182;</a> </div> <p>the <code>_by</code> variable is created twice in <code>Range</code>s if we don't prevent it from being declared here</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">stepvar = </span><span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span> <span class="s">&quot;step&quot;</span> <span class="k">if</span> <span class="nx">@step</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">@range</span>
<span class="nv">kvarAssign = </span><span class="k">if</span> <span class="nx">kvar</span> <span class="o">isnt</span> <span class="nx">ivar</span> <span class="k">then</span> <span class="s">&quot;</span><span class="si">#{</span><span class="nx">kvar</span><span class="si">}</span><span class="s"> = &quot;</span> <span class="k">else</span> <span class="s">&quot;&quot;</span>
<span class="k">if</span> <span class="nx">@step</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">@range</span>
<span class="p">[</span><span class="nx">step</span><span class="p">,</span> <span class="nx">stepVar</span><span class="p">]</span> <span class="o">=</span> <span class="nx">@step</span><span class="p">.</span><span class="nx">cache</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_LIST</span>
<span class="nv">stepNum = </span><span class="nx">stepVar</span><span class="p">.</span><span class="nx">match</span> <span class="nx">SIMPLENUM</span>
<span class="nv">name = </span><span class="nx">ivar</span> <span class="k">if</span> <span class="nx">@pattern</span>
<span class="nv">varPart = </span><span class="s">&#39;&#39;</span>
<span class="nv">guardPart = </span><span class="s">&#39;&#39;</span>
@@ -1364,16 +1375,29 @@ some cannot.</p> </td> <td class="code"> <
<span class="k">else</span>
<span class="nv">svar = </span><span class="nx">@source</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_LIST</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">name</span> <span class="o">or</span> <span class="nx">@</span><span class="k">own</span><span class="p">)</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">IDENTIFIER</span><span class="p">.</span><span class="nx">test</span> <span class="nx">svar</span>
<span class="nv">defPart = </span><span class="s">&quot;</span><span class="si">#{</span><span class="nx">@tab</span><span class="si">}#{</span><span class="nv">ref = </span><span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span> <span class="s">&#39;ref&#39;</span><span class="si">}</span><span class="s"> = </span><span class="si">#{</span><span class="nx">svar</span><span class="si">}</span><span class="s">;\n&quot;</span>
<span class="nx">defPart</span> <span class="o">+=</span> <span class="s">&quot;</span><span class="si">#{</span><span class="nx">@tab</span><span class="si">}#{</span><span class="nv">ref = </span><span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span> <span class="s">&#39;ref&#39;</span><span class="si">}</span><span class="s"> = </span><span class="si">#{</span><span class="nx">svar</span><span class="si">}</span><span class="s">;\n&quot;</span>
<span class="nv">svar = </span><span class="nx">ref</span>
<span class="k">if</span> <span class="nx">name</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">@pattern</span>
<span class="nv">namePart = </span><span class="s">&quot;</span><span class="si">#{</span><span class="nx">name</span><span class="si">}</span><span class="s"> = </span><span class="si">#{</span><span class="nx">svar</span><span class="si">}</span><span class="s">[</span><span class="si">#{</span><span class="nx">kvar</span><span class="si">}</span><span class="s">]&quot;</span>
<span class="k">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="s">&#39;len&#39;</span>
<span class="nv">forVarPart = </span><span class="s">&quot;</span><span class="si">#{</span><span class="nx">kvarAssign</span><span class="si">}#{</span><span class="nx">ivar</span><span class="si">}</span><span class="s"> = 0, </span><span class="si">#{</span><span class="nx">lvar</span><span class="si">}</span><span class="s"> = </span><span class="si">#{</span><span class="nx">svar</span><span class="si">}</span><span class="s">.length&quot;</span>
<span class="nx">forVarPart</span> <span class="o">+=</span> <span class="s">&quot;, </span><span class="si">#{</span><span class="nx">stepvar</span><span class="si">}</span><span class="s"> = </span><span class="si">#{</span><span class="nx">@step</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_OP</span><span class="si">}</span><span class="s">&quot;</span> <span class="k">if</span> <span class="nx">@step</span>
<span class="nv">stepPart = </span><span class="s">&quot;</span><span class="si">#{</span><span class="nx">kvarAssign</span><span class="si">}#{</span><span class="k">if</span> <span class="nx">@step</span> <span class="k">then</span> <span class="s">&quot;</span><span class="si">#{</span><span class="nx">ivar</span><span class="si">}</span><span class="s"> += </span><span class="si">#{</span><span class="nx">stepvar</span><span class="si">}</span><span class="s">&quot;</span> <span class="k">else</span> <span class="p">(</span><span class="k">if</span> <span class="nx">kvar</span> <span class="o">isnt</span> <span class="nx">ivar</span> <span class="k">then</span> <span class="s">&quot;++</span><span class="si">#{</span><span class="nx">ivar</span><span class="si">}</span><span class="s">&quot;</span> <span class="k">else</span> <span class="s">&quot;</span><span class="si">#{</span><span class="nx">ivar</span><span class="si">}</span><span class="s">++&quot;</span><span class="p">)</span><span class="si">}</span><span class="s">&quot;</span>
<span class="nv">forPart = </span><span class="s">&quot;</span><span class="si">#{</span><span class="nx">forVarPart</span><span class="si">}</span><span class="s">; </span><span class="si">#{</span><span class="nx">ivar</span><span class="si">}</span><span class="s"> &lt; </span><span class="si">#{</span><span class="nx">lvar</span><span class="si">}</span><span class="s">; </span><span class="si">#{</span><span class="nx">stepPart</span><span class="si">}</span><span class="s">&quot;</span>
<span class="k">if</span> <span class="o">not</span> <span class="nx">@object</span>
<span class="nx">defPart</span> <span class="o">+=</span> <span class="s">&quot;</span><span class="si">#{</span><span class="nx">@tab</span><span class="si">}#{</span><span class="nx">step</span><span class="si">}</span><span class="s">;\n&quot;</span> <span class="k">if</span> <span class="nx">step</span> <span class="o">isnt</span> <span class="nx">stepVar</span>
<span class="nv">lvar = </span><span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span> <span class="s">&#39;len&#39;</span> <span class="k">unless</span> <span class="nx">@step</span> <span class="o">and</span> <span class="nx">stepNum</span> <span class="o">and</span> <span class="nv">down = </span><span class="p">(</span><span class="o">+</span><span class="nx">stepNum</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">)</span>
<span class="nv">declare = </span><span class="s">&quot;</span><span class="si">#{</span><span class="nx">kvarAssign</span><span class="si">}#{</span><span class="nx">ivar</span><span class="si">}</span><span class="s"> = 0, </span><span class="si">#{</span><span class="nx">lvar</span><span class="si">}</span><span class="s"> = </span><span class="si">#{</span><span class="nx">svar</span><span class="si">}</span><span class="s">.length&quot;</span>
<span class="nv">declareDown = </span><span class="s">&quot;</span><span class="si">#{</span><span class="nx">kvarAssign</span><span class="si">}#{</span><span class="nx">ivar</span><span class="si">}</span><span class="s"> = </span><span class="si">#{</span><span class="nx">svar</span><span class="si">}</span><span class="s">.length - 1&quot;</span>
<span class="nv">compare = </span><span class="s">&quot;</span><span class="si">#{</span><span class="nx">ivar</span><span class="si">}</span><span class="s"> &lt; </span><span class="si">#{</span><span class="nx">lvar</span><span class="si">}</span><span class="s">&quot;</span>
<span class="nv">compareDown = </span><span class="s">&quot;</span><span class="si">#{</span><span class="nx">ivar</span><span class="si">}</span><span class="s"> &gt;= 0&quot;</span>
<span class="k">if</span> <span class="nx">@step</span>
<span class="k">if</span> <span class="nx">stepNum</span>
<span class="k">if</span> <span class="nx">down</span>
<span class="nv">compare = </span><span class="nx">compareDown</span>
<span class="nv">declare = </span><span class="nx">declareDown</span>
<span class="k">else</span>
<span class="nv">compare = </span><span class="s">&quot;</span><span class="si">#{</span><span class="nx">stepVar</span><span class="si">}</span><span class="s"> &gt; 0 ? </span><span class="si">#{</span><span class="nx">compare</span><span class="si">}</span><span class="s"> : </span><span class="si">#{</span><span class="nx">compareDown</span><span class="si">}</span><span class="s">&quot;</span>
<span class="nv">declare = </span><span class="s">&quot;(</span><span class="si">#{</span><span class="nx">stepVar</span><span class="si">}</span><span class="s"> &gt; 0 ? (</span><span class="si">#{</span><span class="nx">declare</span><span class="si">}</span><span class="s">) : </span><span class="si">#{</span><span class="nx">declareDown</span><span class="si">}</span><span class="s">)&quot;</span>
<span class="nv">increment = </span><span class="s">&quot;</span><span class="si">#{</span><span class="nx">ivar</span><span class="si">}</span><span class="s"> += </span><span class="si">#{</span><span class="nx">stepVar</span><span class="si">}</span><span class="s">&quot;</span>
<span class="k">else</span>
<span class="nv">increment = </span><span class="s">&quot;</span><span class="si">#{</span><span class="k">if</span> <span class="nx">kvar</span> <span class="o">isnt</span> <span class="nx">ivar</span> <span class="k">then</span> <span class="s">&quot;++</span><span class="si">#{</span><span class="nx">ivar</span><span class="si">}</span><span class="s">&quot;</span> <span class="k">else</span> <span class="s">&quot;</span><span class="si">#{</span><span class="nx">ivar</span><span class="si">}</span><span class="s">++&quot;</span><span class="si">}</span><span class="s">&quot;</span>
<span class="nv">forPart = </span><span class="s">&quot;</span><span class="si">#{</span><span class="nx">declare</span><span class="si">}</span><span class="s">; </span><span class="si">#{</span><span class="nx">compare</span><span class="si">}</span><span class="s">; </span><span class="si">#{</span><span class="nx">kvarAssign</span><span class="si">}#{</span><span class="nx">increment</span><span class="si">}</span><span class="s">&quot;</span>
<span class="k">if</span> <span class="nx">@returns</span>
<span class="nv">resultPart = </span><span class="s">&quot;</span><span class="si">#{</span><span class="nx">@tab</span><span class="si">}#{</span><span class="nx">rvar</span><span class="si">}</span><span class="s"> = [];\n&quot;</span>
<span class="nv">returnResult = </span><span class="s">&quot;\n</span><span class="si">#{</span><span class="nx">@tab</span><span class="si">}</span><span class="s">return </span><span class="si">#{</span><span class="nx">rvar</span><span class="si">}</span><span class="s">;&quot;</span>
@@ -1409,7 +1433,7 @@ some cannot.</p> </td> <td class="code"> <
<span class="nx">val</span><span class="p">.</span><span class="nx">properties</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nx">name</span><span class="o">?</span><span class="p">.</span><span class="nx">value</span> <span class="k">in</span> <span class="p">[</span><span class="s">&#39;call&#39;</span><span class="p">,</span> <span class="s">&#39;apply&#39;</span><span class="p">])</span>
<span class="nv">fn = </span><span class="nx">val</span><span class="p">.</span><span class="nx">base</span><span class="o">?</span><span class="p">.</span><span class="nx">unwrapAll</span><span class="p">()</span> <span class="o">or</span> <span class="nx">val</span>
<span class="nv">ref = </span><span class="k">new</span> <span class="nx">Literal</span> <span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span> <span class="s">&#39;fn&#39;</span>
<span class="nv">base = </span><span class="k">new</span> <span class="nx">Value</span> <span class="nx">ref</span>
<span class="nv">base = </span><span class="nx">Value</span><span class="p">.</span><span class="nx">wrap</span> <span class="nx">ref</span>
<span class="k">if</span> <span class="nx">val</span><span class="p">.</span><span class="nx">base</span>
<span class="p">[</span><span class="nx">val</span><span class="p">.</span><span class="nx">base</span><span class="p">,</span> <span class="nx">base</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="nx">base</span><span class="p">,</span> <span class="nx">val</span><span class="p">]</span>
<span class="nx">body</span><span class="p">.</span><span class="nx">expressions</span><span class="p">[</span><span class="nx">idx</span><span class="p">]</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Call</span> <span class="nx">base</span><span class="p">,</span> <span class="nx">expr</span><span class="p">.</span><span class="nx">args</span>
@@ -1520,10 +1544,12 @@ then make sure that the closure wrapper preserves the original values.</p>
<span class="nv">func = </span><span class="k">new</span> <span class="nx">Code</span> <span class="p">[],</span> <span class="nx">Block</span><span class="p">.</span><span class="nx">wrap</span> <span class="p">[</span><span class="nx">expressions</span><span class="p">]</span>
<span class="nv">args = </span><span class="p">[]</span>
<span class="k">if</span> <span class="p">(</span><span class="nv">mentionsArgs = </span><span class="nx">expressions</span><span class="p">.</span><span class="nx">contains</span> <span class="nx">@literalArgs</span><span class="p">)</span> <span class="o">or</span> <span class="nx">expressions</span><span class="p">.</span><span class="nx">contains</span> <span class="nx">@literalThis</span>
<span class="k">if</span> <span class="nx">mentionsArgs</span> <span class="o">and</span> <span class="nx">expressions</span><span class="p">.</span><span class="nx">classBody</span>
<span class="k">throw</span> <span class="nx">SyntaxError</span> <span class="s">&quot;Class bodies shouldn&#39;t reference arguments&quot;</span>
<span class="nv">meth = </span><span class="k">new</span> <span class="nx">Literal</span> <span class="k">if</span> <span class="nx">mentionsArgs</span> <span class="k">then</span> <span class="s">&#39;apply&#39;</span> <span class="k">else</span> <span class="s">&#39;call&#39;</span>
<span class="nv">args = </span><span class="p">[</span><span class="k">new</span> <span class="nx">Literal</span> <span class="s">&#39;this&#39;</span><span class="p">]</span>
<span class="nx">args</span><span class="p">.</span><span class="nx">push</span> <span class="k">new</span> <span class="nx">Literal</span> <span class="s">&#39;arguments&#39;</span> <span class="k">if</span> <span class="nx">mentionsArgs</span>
<span class="nv">func = </span><span class="k">new</span> <span class="nx">Value</span> <span class="nx">func</span><span class="p">,</span> <span class="p">[</span><span class="k">new</span> <span class="nx">Access</span> <span class="nx">meth</span><span class="p">]</span>
<span class="nv">func = </span><span class="nx">Value</span><span class="p">.</span><span class="nx">wrap</span> <span class="nx">func</span><span class="p">,</span> <span class="p">[</span><span class="k">new</span> <span class="nx">Access</span> <span class="nx">meth</span><span class="p">]</span>
<span class="nv">func.noReturn = </span><span class="nx">noReturn</span>
<span class="nv">call = </span><span class="k">new</span> <span class="nx">Call</span> <span class="nx">func</span><span class="p">,</span> <span class="nx">args</span>
<span class="k">if</span> <span class="nx">statement</span> <span class="k">then</span> <span class="nx">Block</span><span class="p">.</span><span class="nx">wrap</span> <span class="p">[</span><span class="nx">call</span><span class="p">]</span> <span class="k">else</span> <span class="nx">call</span>
@@ -1537,7 +1563,7 @@ then make sure that the closure wrapper preserves the original values.</p>
<span class="p">(</span><span class="nx">node</span> <span class="k">instanceof</span> <span class="nx">Call</span> <span class="o">and</span> <span class="nx">node</span><span class="p">.</span><span class="nx">isSuper</span><span class="p">)</span></pre></div> </td> </tr> <tr id="section-158"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-158">&#182;</a> </div> <p>Unfold a node's child if soak, then tuck the node under created <code>If</code></p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">unfoldSoak = </span><span class="nf">(o, parent, name) -&gt;</span>
<span class="k">return</span> <span class="k">unless</span> <span class="nv">ifn = </span><span class="nx">parent</span><span class="p">[</span><span class="nx">name</span><span class="p">].</span><span class="nx">unfoldSoak</span> <span class="nx">o</span>
<span class="nx">parent</span><span class="p">[</span><span class="nx">name</span><span class="p">]</span> <span class="o">=</span> <span class="nx">ifn</span><span class="p">.</span><span class="nx">body</span>
<span class="nv">ifn.body = </span><span class="k">new</span> <span class="nx">Value</span> <span class="nx">parent</span>
<span class="nv">ifn.body = </span><span class="nx">Value</span><span class="p">.</span><span class="nx">wrap</span> <span class="nx">parent</span>
<span class="nx">ifn</span></pre></div> </td> </tr> <tr id="section-159"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-159">&#182;</a> </div> <h2>Constants</h2> </td> <td class="code"> <div class="highlight"><pre><span class="nv">UTILITIES =</span></pre></div> </td> </tr> <tr id="section-160"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-160">&#182;</a> </div> <p>Correctly set up a prototype chain for inheritance, including a reference
to the superclass for <code>super()</code> calls, and copies of any static properties.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">extends</span><span class="o">:</span> <span class="nf">-&gt;</span> <span class="s">&quot;&quot;&quot;</span>
<span class="s"> function(child, parent) { for (var key in parent) { if (</span><span class="si">#{</span><span class="nx">utility</span> <span class="s">&#39;hasProp&#39;</span><span class="si">}</span><span class="s">.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }</span>

View File

@@ -1,4 +1,4 @@
<!DOCTYPE html> <html> <head> <title>optparse.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> optparse.coffee </h1> </th> <th class="code"> </th> </tr> </thead> <tbody> <tr id="section-1"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-1">&#182;</a> </div> <p>A simple <strong>OptionParser</strong> class to parse option flags from the command-line.
<!DOCTYPE html> <html> <head> <title>optparse.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> </div> </div> </div> <table cellpadding="0" cellspacing="0"> <thead> <tr> <th class="docs"> <h1> optparse.coffee </h1> </th> <th class="code"> </th> </tr> </thead> <tbody> <tr id="section-1"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-1">&#182;</a> </div> <p>A simple <strong>OptionParser</strong> class to parse option flags from the command-line.
Use it like so:</p>
<pre><code>parser = new OptionParser switches, helpBanner

View File

@@ -1,142 +1,57 @@
<!DOCTYPE html> <html> <head> <title>repl.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> repl.coffee </h1> </th> <th class="code"> </th> </tr> </thead> <tbody> <tr id="section-1"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-1">&#182;</a> </div> <p>A very simple Read-Eval-Print-Loop. Compiles one line at a time to JavaScript
and evaluates it. Good for simple tests, or poking around the <strong>Node.js</strong> API.
Using it looks like this:</p>
<!DOCTYPE html> <html> <head> <title>repl.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> </div> </div> </div> <table cellpadding="0" cellspacing="0"> <thead> <tr> <th class="docs"> <h1> repl.coffee </h1> </th> <th class="code"> </th> </tr> </thead> <tbody> <tr id="section-1"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-1">&#182;</a> </div> </td> <td class="code"> <div class="highlight"><pre><span class="nv">vm = </span><span class="nx">require</span> <span class="s">&#39;vm&#39;</span>
<span class="nv">nodeREPL = </span><span class="nx">require</span> <span class="s">&#39;repl&#39;</span>
<span class="nv">CoffeeScript = </span><span class="nx">require</span> <span class="s">&#39;./coffee-script&#39;</span>
<span class="p">{</span><span class="nx">merge</span><span class="p">}</span> <span class="o">=</span> <span class="nx">require</span> <span class="s">&#39;./helpers&#39;</span>
<pre><code>coffee&gt; console.log "#{num} bottles of beer" for num in [99..1]
</code></pre> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-2"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-2">&#182;</a> </div> <p>Start by opening up <code>stdin</code> and <code>stdout</code>.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">stdin = </span><span class="nx">process</span><span class="p">.</span><span class="nx">openStdin</span><span class="p">()</span>
<span class="nv">stdout = </span><span class="nx">process</span><span class="p">.</span><span class="nx">stdout</span></pre></div> </td> </tr> <tr id="section-3"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-3">&#182;</a> </div> <p>Require the <strong>coffee-script</strong> module to get access to the compiler.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">CoffeeScript = </span><span class="nx">require</span> <span class="s">&#39;./coffee-script&#39;</span>
<span class="nv">readline = </span><span class="nx">require</span> <span class="s">&#39;readline&#39;</span>
<span class="p">{</span><span class="nx">inspect</span><span class="p">}</span> <span class="o">=</span> <span class="nx">require</span> <span class="s">&#39;util&#39;</span>
<span class="p">{</span><span class="nx">Script</span><span class="p">}</span> <span class="o">=</span> <span class="nx">require</span> <span class="s">&#39;vm&#39;</span>
<span class="nv">Module = </span><span class="nx">require</span> <span class="s">&#39;module&#39;</span></pre></div> </td> </tr> <tr id="section-4"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-4">&#182;</a> </div> <p>REPL Setup</p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-5"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-5">&#182;</a> </div> <p>Config</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">REPL_PROMPT = </span><span class="s">&#39;coffee&gt; &#39;</span>
<span class="nv">REPL_PROMPT_MULTILINE = </span><span class="s">&#39;------&gt; &#39;</span>
<span class="nv">REPL_PROMPT_CONTINUATION = </span><span class="s">&#39;......&gt; &#39;</span>
<span class="nv">enableColours = </span><span class="kc">no</span>
<span class="k">unless</span> <span class="nx">process</span><span class="p">.</span><span class="nx">platform</span> <span class="o">is</span> <span class="s">&#39;win32&#39;</span>
<span class="nv">enableColours = </span><span class="o">not</span> <span class="nx">process</span><span class="p">.</span><span class="nx">env</span><span class="p">.</span><span class="nx">NODE_DISABLE_COLORS</span></pre></div> </td> </tr> <tr id="section-6"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-6">&#182;</a> </div> <p>Log an error.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">error = </span><span class="nf">(err) -&gt;</span>
<span class="nx">stdout</span><span class="p">.</span><span class="nx">write</span> <span class="p">(</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> <span class="o">+</span> <span class="s">&#39;\n&#39;</span></pre></div> </td> </tr> <tr id="section-7"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-7">&#182;</a> </div> <h1>Autocompletion</h1> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-8"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-8">&#182;</a> </div> <p>Regexes to match complete-able bits of text.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">ACCESSOR = </span><span class="sr">/\s*([\w\.]+)(?:\.(\w*))$/</span>
<span class="nv">SIMPLEVAR = </span><span class="sr">/(\w+)$/i</span></pre></div> </td> </tr> <tr id="section-9"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-9">&#182;</a> </div> <p>Returns a list of completions, and the completed text.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">autocomplete = </span><span class="nf">(text) -&gt;</span>
<span class="nx">completeAttribute</span><span class="p">(</span><span class="nx">text</span><span class="p">)</span> <span class="o">or</span> <span class="nx">completeVariable</span><span class="p">(</span><span class="nx">text</span><span class="p">)</span> <span class="o">or</span> <span class="p">[[],</span> <span class="nx">text</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-10"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-10">&#182;</a> </div> <p>Attempt to autocomplete a chained dotted attribute: <code>one.two.three</code>.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">completeAttribute = </span><span class="nf">(text) -&gt;</span>
<span class="k">if</span> <span class="nv">match = </span><span class="nx">text</span><span class="p">.</span><span class="nx">match</span> <span class="nx">ACCESSOR</span>
<span class="p">[</span><span class="nx">all</span><span class="p">,</span> <span class="nx">obj</span><span class="p">,</span> <span class="nx">prefix</span><span class="p">]</span> <span class="o">=</span> <span class="nx">match</span>
<span class="k">try</span> <span class="nv">obj = </span><span class="nx">Script</span><span class="p">.</span><span class="nx">runInThisContext</span> <span class="nx">obj</span>
<span class="k">catch</span> <span class="nx">e</span>
<span class="k">return</span>
<span class="k">return</span> <span class="k">unless</span> <span class="nx">obj</span><span class="o">?</span>
<span class="nv">obj = </span><span class="nb">Object</span> <span class="nx">obj</span>
<span class="nv">candidates = </span><span class="nb">Object</span><span class="p">.</span><span class="nx">getOwnPropertyNames</span> <span class="nx">obj</span>
<span class="k">while</span> <span class="nv">obj = </span><span class="nb">Object</span><span class="p">.</span><span class="nx">getPrototypeOf</span> <span class="nx">obj</span>
<span class="k">for</span> <span class="nx">key</span> <span class="k">in</span> <span class="nb">Object</span><span class="p">.</span><span class="nx">getOwnPropertyNames</span> <span class="nx">obj</span> <span class="k">when</span> <span class="nx">key</span> <span class="o">not</span> <span class="k">in</span> <span class="nx">candidates</span>
<span class="nx">candidates</span><span class="p">.</span><span class="nx">push</span> <span class="nx">key</span>
<span class="nv">completions = </span><span class="nx">getCompletions</span> <span class="nx">prefix</span><span class="p">,</span> <span class="nx">candidates</span>
<span class="p">[</span><span class="nx">completions</span><span class="p">,</span> <span class="nx">prefix</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-11"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-11">&#182;</a> </div> <p>Attempt to autocomplete an in-scope free variable: <code>one</code>.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">completeVariable = </span><span class="nf">(text) -&gt;</span>
<span class="nv">free = </span><span class="nx">text</span><span class="p">.</span><span class="nx">match</span><span class="p">(</span><span class="nx">SIMPLEVAR</span><span class="p">)</span><span class="o">?</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
<span class="nv">free = </span><span class="s">&quot;&quot;</span> <span class="k">if</span> <span class="nx">text</span> <span class="o">is</span> <span class="s">&quot;&quot;</span>
<span class="k">if</span> <span class="nx">free</span><span class="o">?</span>
<span class="nv">vars = </span><span class="nx">Script</span><span class="p">.</span><span class="nx">runInThisContext</span> <span class="s">&#39;Object.getOwnPropertyNames(Object(this))&#39;</span>
<span class="nv">keywords = </span><span class="p">(</span><span class="nx">r</span> <span class="k">for</span> <span class="nx">r</span> <span class="k">in</span> <span class="nx">CoffeeScript</span><span class="p">.</span><span class="nx">RESERVED</span> <span class="k">when</span> <span class="nx">r</span><span class="p">[..</span><span class="mi">1</span><span class="p">]</span> <span class="o">isnt</span> <span class="s">&#39;__&#39;</span><span class="p">)</span>
<span class="nv">candidates = </span><span class="nx">vars</span>
<span class="k">for</span> <span class="nx">key</span> <span class="k">in</span> <span class="nx">keywords</span> <span class="k">when</span> <span class="nx">key</span> <span class="o">not</span> <span class="k">in</span> <span class="nx">candidates</span>
<span class="nx">candidates</span><span class="p">.</span><span class="nx">push</span> <span class="nx">key</span>
<span class="nv">completions = </span><span class="nx">getCompletions</span> <span class="nx">free</span><span class="p">,</span> <span class="nx">candidates</span>
<span class="p">[</span><span class="nx">completions</span><span class="p">,</span> <span class="nx">free</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-12"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-12">&#182;</a> </div> <p>Return elements of candidates for which <code>prefix</code> is a prefix.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">getCompletions = </span><span class="nf">(prefix, candidates) -&gt;</span>
<span class="nx">el</span> <span class="k">for</span> <span class="nx">el</span> <span class="k">in</span> <span class="nx">candidates</span> <span class="k">when</span> <span class="mi">0</span> <span class="o">is</span> <span class="nx">el</span><span class="p">.</span><span class="nx">indexOf</span> <span class="nx">prefix</span></pre></div> </td> </tr> <tr id="section-13"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-13">&#182;</a> </div> <p>Make sure that uncaught exceptions don't kill the REPL.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nx">process</span><span class="p">.</span><span class="nx">on</span> <span class="s">&#39;uncaughtException&#39;</span><span class="p">,</span> <span class="nx">error</span></pre></div> </td> </tr> <tr id="section-14"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-14">&#182;</a> </div> <p>The current backlog of multi-line code.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">backlog = </span><span class="s">&#39;&#39;</span></pre></div> </td> </tr> <tr id="section-15"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-15">&#182;</a> </div> <p>The main REPL function. <strong>run</strong> is called every time a line of code is entered.
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="nf">(buffer) -&gt;</span></pre></div> </td> </tr> <tr id="section-16"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-16">&#182;</a> </div> <p>remove single-line comments</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">buffer = </span><span class="nx">buffer</span><span class="p">.</span><span class="nx">replace</span> <span class="sr">/(^|[\r\n]+)(\s*)##?(?:[^#\r\n][^\r\n]*|)($|[\r\n])/</span><span class="p">,</span> <span class="s">&quot;$1$2$3&quot;</span></pre></div> </td> </tr> <tr id="section-17"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-17">&#182;</a> </div> <p>remove trailing newlines</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">buffer = </span><span class="nx">buffer</span><span class="p">.</span><span class="nx">replace</span> <span class="sr">/[\r\n]+$/</span><span class="p">,</span> <span class="s">&quot;&quot;</span>
<span class="k">if</span> <span class="nx">multilineMode</span>
<span class="nx">backlog</span> <span class="o">+=</span> <span class="s">&quot;</span><span class="si">#{</span><span class="nx">buffer</span><span class="si">}</span><span class="s">\n&quot;</span>
<span class="nx">repl</span><span class="p">.</span><span class="nx">setPrompt</span> <span class="nx">REPL_PROMPT_CONTINUATION</span>
<span class="nx">repl</span><span class="p">.</span><span class="nx">prompt</span><span class="p">()</span>
<span class="nv">replDefaults =</span>
<span class="nv">prompt: </span><span class="s">&#39;coffee&gt; &#39;</span><span class="p">,</span>
<span class="nb">eval</span><span class="o">:</span> <span class="nf">(input, context, filename, cb) -&gt;</span></pre></div> </td> </tr> <tr id="section-2"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-2">&#182;</a> </div> <p>XXX: multiline hack</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">input = </span><span class="nx">input</span><span class="p">.</span><span class="nx">replace</span> <span class="sr">/\uFF00/g</span><span class="p">,</span> <span class="s">&#39;\n&#39;</span></pre></div> </td> </tr> <tr id="section-3"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-3">&#182;</a> </div> <p>strip single-line comments</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">input = </span><span class="nx">input</span><span class="p">.</span><span class="nx">replace</span> <span class="sr">/(^|[\r\n]+)(\s*)##?(?:[^#\r\n][^\r\n]*|)($|[\r\n])/</span><span class="p">,</span> <span class="s">&#39;$1$2$3&#39;</span></pre></div> </td> </tr> <tr id="section-4"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-4">&#182;</a> </div> <p>empty command</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">return</span> <span class="nx">cb</span> <span class="kc">null</span> <span class="k">if</span> <span class="sr">/^\s*$/</span><span class="p">.</span><span class="nx">test</span> <span class="nx">input</span></pre></div> </td> </tr> <tr id="section-5"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-5">&#182;</a> </div> <p>TODO: fix #1829: pass in-scope vars and avoid accidentally shadowing them by omitting those declarations</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">try</span>
<span class="nv">js = </span><span class="nx">CoffeeScript</span><span class="p">.</span><span class="nx">compile</span> <span class="s">&quot;_=(</span><span class="si">#{</span><span class="nx">input</span><span class="si">}</span><span class="s">\n)&quot;</span><span class="p">,</span> <span class="p">{</span><span class="nx">filename</span><span class="p">,</span> <span class="nv">bare: </span><span class="kc">yes</span><span class="p">}</span>
<span class="k">catch</span> <span class="nx">err</span>
<span class="nx">cb</span> <span class="nx">err</span>
<span class="nx">cb</span> <span class="kc">null</span><span class="p">,</span> <span class="nx">vm</span><span class="p">.</span><span class="nx">runInContext</span><span class="p">(</span><span class="nx">js</span><span class="p">,</span> <span class="nx">context</span><span class="p">,</span> <span class="nx">filename</span><span class="p">)</span>
<span class="nv">addMultilineHandler = </span><span class="nf">(repl) -&gt;</span>
<span class="p">{</span><span class="nx">rli</span><span class="p">,</span> <span class="nx">inputStream</span><span class="p">,</span> <span class="nx">outputStream</span><span class="p">}</span> <span class="o">=</span> <span class="nx">repl</span>
<span class="nv">multiline =</span>
<span class="nv">enabled: </span><span class="kc">off</span>
<span class="nv">initialPrompt: </span><span class="nx">repl</span><span class="p">.</span><span class="nx">prompt</span><span class="p">.</span><span class="nx">replace</span><span class="p">(</span><span class="sr">/^[^&gt; ]*/</span><span class="p">,</span> <span class="nf">(x) -&gt;</span> <span class="nx">x</span><span class="p">.</span><span class="nx">replace</span> <span class="sr">/./g</span><span class="p">,</span> <span class="s">&#39;-&#39;</span><span class="p">)</span>
<span class="nv">prompt: </span><span class="nx">repl</span><span class="p">.</span><span class="nx">prompt</span><span class="p">.</span><span class="nx">replace</span><span class="p">(</span><span class="sr">/^[^&gt; ]*&gt;?/</span><span class="p">,</span> <span class="nf">(x) -&gt;</span> <span class="nx">x</span><span class="p">.</span><span class="nx">replace</span> <span class="sr">/./g</span><span class="p">,</span> <span class="s">&#39;.&#39;</span><span class="p">)</span>
<span class="nv">buffer: </span><span class="s">&#39;&#39;</span></pre></div> </td> </tr> <tr id="section-6"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-6">&#182;</a> </div> <p>Proxy node's line listener</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">nodeLineListener = </span><span class="nx">rli</span><span class="p">.</span><span class="nx">listeners</span><span class="p">(</span><span class="s">&#39;line&#39;</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>
<span class="nx">rli</span><span class="p">.</span><span class="nx">removeListener</span> <span class="s">&#39;line&#39;</span><span class="p">,</span> <span class="nx">nodeLineListener</span>
<span class="nx">rli</span><span class="p">.</span><span class="nx">on</span> <span class="s">&#39;line&#39;</span><span class="p">,</span> <span class="nf">(cmd) -&gt;</span>
<span class="k">if</span> <span class="nx">multiline</span><span class="p">.</span><span class="nx">enabled</span>
<span class="nx">multiline</span><span class="p">.</span><span class="nx">buffer</span> <span class="o">+=</span> <span class="s">&quot;</span><span class="si">#{</span><span class="nx">cmd</span><span class="si">}</span><span class="s">\n&quot;</span>
<span class="nx">rli</span><span class="p">.</span><span class="nx">setPrompt</span> <span class="nx">multiline</span><span class="p">.</span><span class="nx">prompt</span>
<span class="nx">rli</span><span class="p">.</span><span class="nx">prompt</span> <span class="kc">true</span>
<span class="k">else</span>
<span class="nx">nodeLineListener</span> <span class="nx">cmd</span>
<span class="k">return</span></pre></div> </td> </tr> <tr id="section-7"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-7">&#182;</a> </div> <p>Handle Ctrl-v</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">inputStream</span><span class="p">.</span><span class="nx">on</span> <span class="s">&#39;keypress&#39;</span><span class="p">,</span> <span class="nf">(char, key) -&gt;</span>
<span class="k">return</span> <span class="k">unless</span> <span class="nx">key</span> <span class="o">and</span> <span class="nx">key</span><span class="p">.</span><span class="nx">ctrl</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">key</span><span class="p">.</span><span class="nx">meta</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">key</span><span class="p">.</span><span class="nx">shift</span> <span class="o">and</span> <span class="nx">key</span><span class="p">.</span><span class="nx">name</span> <span class="o">is</span> <span class="s">&#39;v&#39;</span>
<span class="k">if</span> <span class="nx">multiline</span><span class="p">.</span><span class="nx">enabled</span></pre></div> </td> </tr> <tr id="section-8"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-8">&#182;</a> </div> <p>allow arbitrarily switching between modes any time before multiple lines are entered</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">unless</span> <span class="nx">multiline</span><span class="p">.</span><span class="nx">buffer</span><span class="p">.</span><span class="nx">match</span> <span class="sr">/\n/</span>
<span class="nv">multiline.enabled = </span><span class="o">not</span> <span class="nx">multiline</span><span class="p">.</span><span class="nx">enabled</span>
<span class="nx">rli</span><span class="p">.</span><span class="nx">setPrompt</span> <span class="nx">repl</span><span class="p">.</span><span class="nx">prompt</span>
<span class="nx">rli</span><span class="p">.</span><span class="nx">prompt</span> <span class="kc">true</span>
<span class="k">return</span></pre></div> </td> </tr> <tr id="section-9"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-9">&#182;</a> </div> <p>no-op unless the current line is empty</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">return</span> <span class="k">if</span> <span class="nx">rli</span><span class="p">.</span><span class="nx">line</span><span class="o">?</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">rli</span><span class="p">.</span><span class="nx">line</span><span class="p">.</span><span class="nx">match</span> <span class="sr">/^\s*$/</span></pre></div> </td> </tr> <tr id="section-10"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-10">&#182;</a> </div> <p>eval, print, loop</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">multiline.enabled = </span><span class="o">not</span> <span class="nx">multiline</span><span class="p">.</span><span class="nx">enabled</span>
<span class="nv">rli.line = </span><span class="s">&#39;&#39;</span>
<span class="nv">rli.cursor = </span><span class="mi">0</span>
<span class="nx">rli</span><span class="p">.</span><span class="nx">output</span><span class="p">.</span><span class="nx">cursorTo</span> <span class="mi">0</span>
<span class="nx">rli</span><span class="p">.</span><span class="nx">output</span><span class="p">.</span><span class="nx">clearLine</span> <span class="mi">1</span></pre></div> </td> </tr> <tr id="section-11"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-11">&#182;</a> </div> <p>XXX: multiline hack</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">multiline.buffer = </span><span class="nx">multiline</span><span class="p">.</span><span class="nx">buffer</span><span class="p">.</span><span class="nx">replace</span> <span class="sr">/\n/g</span><span class="p">,</span> <span class="s">&#39;\uFF00&#39;</span>
<span class="nx">rli</span><span class="p">.</span><span class="nx">emit</span> <span class="s">&#39;line&#39;</span><span class="p">,</span> <span class="nx">multiline</span><span class="p">.</span><span class="nx">buffer</span>
<span class="nv">multiline.buffer = </span><span class="s">&#39;&#39;</span>
<span class="k">else</span>
<span class="nv">multiline.enabled = </span><span class="o">not</span> <span class="nx">multiline</span><span class="p">.</span><span class="nx">enabled</span>
<span class="nx">rli</span><span class="p">.</span><span class="nx">setPrompt</span> <span class="nx">multiline</span><span class="p">.</span><span class="nx">initialPrompt</span>
<span class="nx">rli</span><span class="p">.</span><span class="nx">prompt</span> <span class="kc">true</span>
<span class="k">return</span>
<span class="k">if</span> <span class="o">!</span><span class="nx">buffer</span><span class="p">.</span><span class="nx">toString</span><span class="p">().</span><span class="nx">trim</span><span class="p">()</span> <span class="o">and</span> <span class="o">!</span><span class="nx">backlog</span>
<span class="nx">repl</span><span class="p">.</span><span class="nx">prompt</span><span class="p">()</span>
<span class="k">return</span>
<span class="nv">code = </span><span class="nx">backlog</span> <span class="o">+=</span> <span class="nx">buffer</span>
<span class="k">if</span> <span class="nx">code</span><span class="p">[</span><span class="nx">code</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]</span> <span class="o">is</span> <span class="s">&#39;\\&#39;</span>
<span class="nv">backlog = </span><span class="s">&quot;</span><span class="si">#{</span><span class="nx">backlog</span><span class="p">[...</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span><span class="si">}</span><span class="s">\n&quot;</span>
<span class="nx">repl</span><span class="p">.</span><span class="nx">setPrompt</span> <span class="nx">REPL_PROMPT_CONTINUATION</span>
<span class="nx">repl</span><span class="p">.</span><span class="nx">prompt</span><span class="p">()</span>
<span class="k">return</span>
<span class="nx">repl</span><span class="p">.</span><span class="nx">setPrompt</span> <span class="nx">REPL_PROMPT</span>
<span class="nv">backlog = </span><span class="s">&#39;&#39;</span>
<span class="k">try</span>
<span class="nv">_ = </span><span class="nx">global</span><span class="p">.</span><span class="nx">_</span>
<span class="nv">returnValue = </span><span class="nx">CoffeeScript</span><span class="p">.</span><span class="nb">eval</span> <span class="s">&quot;_=(</span><span class="si">#{</span><span class="nx">code</span><span class="si">}</span><span class="s">\n)&quot;</span><span class="p">,</span> <span class="p">{</span>
<span class="nv">filename: </span><span class="s">&#39;repl&#39;</span>
<span class="nv">modulename: </span><span class="s">&#39;repl&#39;</span>
<span class="p">}</span>
<span class="k">if</span> <span class="nx">returnValue</span> <span class="o">is</span> <span class="kc">undefined</span>
<span class="nv">global._ = </span><span class="nx">_</span>
<span class="nx">repl</span><span class="p">.</span><span class="nx">output</span><span class="p">.</span><span class="nx">write</span> <span class="s">&quot;</span><span class="si">#{</span><span class="nx">inspect</span> <span class="nx">returnValue</span><span class="p">,</span> <span class="kc">no</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="nx">enableColours</span><span class="si">}</span><span class="s">\n&quot;</span>
<span class="k">catch</span> <span class="nx">err</span>
<span class="nx">error</span> <span class="nx">err</span>
<span class="nx">repl</span><span class="p">.</span><span class="nx">prompt</span><span class="p">()</span>
<span class="k">if</span> <span class="nx">stdin</span><span class="p">.</span><span class="nx">readable</span> <span class="o">and</span> <span class="nx">stdin</span><span class="p">.</span><span class="nx">isRaw</span></pre></div> </td> </tr> <tr id="section-18"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-18">&#182;</a> </div> <p>handle piped input</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">pipedInput = </span><span class="s">&#39;&#39;</span>
<span class="nv">repl =</span>
<span class="nv">prompt: </span><span class="nf">-&gt;</span> <span class="nx">stdout</span><span class="p">.</span><span class="nx">write</span> <span class="nx">@_prompt</span>
<span class="nv">setPrompt: </span><span class="nf">(p) -&gt;</span> <span class="vi">@_prompt = </span><span class="nx">p</span>
<span class="nv">input: </span><span class="nx">stdin</span>
<span class="nv">output: </span><span class="nx">stdout</span>
<span class="kc">on</span><span class="o">:</span> <span class="nf">-&gt;</span>
<span class="nx">stdin</span><span class="p">.</span><span class="nx">on</span> <span class="s">&#39;data&#39;</span><span class="p">,</span> <span class="nf">(chunk) -&gt;</span>
<span class="nx">pipedInput</span> <span class="o">+=</span> <span class="nx">chunk</span>
<span class="k">return</span> <span class="k">unless</span> <span class="sr">/\n/</span><span class="p">.</span><span class="nx">test</span> <span class="nx">pipedInput</span>
<span class="nv">lines = </span><span class="nx">pipedInput</span><span class="p">.</span><span class="nx">split</span> <span class="s">&quot;\n&quot;</span>
<span class="nv">pipedInput = </span><span class="nx">lines</span><span class="p">[</span><span class="nx">lines</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">for</span> <span class="nx">line</span> <span class="k">in</span> <span class="nx">lines</span><span class="p">[...</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="k">when</span> <span class="nx">line</span>
<span class="nx">stdout</span><span class="p">.</span><span class="nx">write</span> <span class="s">&quot;</span><span class="si">#{</span><span class="nx">line</span><span class="si">}</span><span class="s">\n&quot;</span>
<span class="nx">run</span> <span class="nx">line</span>
<span class="k">return</span>
<span class="nx">stdin</span><span class="p">.</span><span class="nx">on</span> <span class="s">&#39;end&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span>
<span class="k">for</span> <span class="nx">line</span> <span class="k">in</span> <span class="nx">pipedInput</span><span class="p">.</span><span class="nx">trim</span><span class="p">().</span><span class="nx">split</span> <span class="s">&quot;\n&quot;</span> <span class="k">when</span> <span class="nx">line</span>
<span class="nx">stdout</span><span class="p">.</span><span class="nx">write</span> <span class="s">&quot;</span><span class="si">#{</span><span class="nx">line</span><span class="si">}</span><span class="s">\n&quot;</span>
<span class="nx">run</span> <span class="nx">line</span>
<span class="nx">stdout</span><span class="p">.</span><span class="nx">write</span> <span class="s">&#39;\n&#39;</span>
<span class="nx">process</span><span class="p">.</span><span class="nx">exit</span> <span class="mi">0</span>
<span class="k">else</span></pre></div> </td> </tr> <tr id="section-19"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-19">&#182;</a> </div> <p>Create the REPL by listening to <strong>stdin</strong>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span> <span class="nx">readline</span><span class="p">.</span><span class="nx">createInterface</span><span class="p">.</span><span class="nx">length</span> <span class="o">&lt;</span> <span class="mi">3</span>
<span class="nv">repl = </span><span class="nx">readline</span><span class="p">.</span><span class="nx">createInterface</span> <span class="nx">stdin</span><span class="p">,</span> <span class="nx">autocomplete</span>
<span class="nx">stdin</span><span class="p">.</span><span class="nx">on</span> <span class="s">&#39;data&#39;</span><span class="p">,</span> <span class="nf">(buffer) -&gt;</span> <span class="nx">repl</span><span class="p">.</span><span class="nx">write</span> <span class="nx">buffer</span>
<span class="k">else</span>
<span class="nv">repl = </span><span class="nx">readline</span><span class="p">.</span><span class="nx">createInterface</span> <span class="nx">stdin</span><span class="p">,</span> <span class="nx">stdout</span><span class="p">,</span> <span class="nx">autocomplete</span>
<span class="nv">multilineMode = </span><span class="kc">off</span></pre></div> </td> </tr> <tr id="section-20"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-20">&#182;</a> </div> <p>Handle multi-line mode switch</p> </td> <td class="code"> <div class="highlight"><pre><span class="nx">repl</span><span class="p">.</span><span class="nx">input</span><span class="p">.</span><span class="nx">on</span> <span class="s">&#39;keypress&#39;</span><span class="p">,</span> <span class="nf">(char, key) -&gt;</span></pre></div> </td> </tr> <tr id="section-21"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-21">&#182;</a> </div> <p>test for Ctrl-v</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">return</span> <span class="k">unless</span> <span class="nx">key</span> <span class="o">and</span> <span class="nx">key</span><span class="p">.</span><span class="nx">ctrl</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">key</span><span class="p">.</span><span class="nx">meta</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">key</span><span class="p">.</span><span class="nx">shift</span> <span class="o">and</span> <span class="nx">key</span><span class="p">.</span><span class="nx">name</span> <span class="o">is</span> <span class="s">&#39;v&#39;</span>
<span class="nv">cursorPos = </span><span class="nx">repl</span><span class="p">.</span><span class="nx">cursor</span>
<span class="nx">repl</span><span class="p">.</span><span class="nx">output</span><span class="p">.</span><span class="nx">cursorTo</span> <span class="mi">0</span>
<span class="nx">repl</span><span class="p">.</span><span class="nx">output</span><span class="p">.</span><span class="nx">clearLine</span> <span class="mi">1</span>
<span class="nv">multilineMode = </span><span class="o">not</span> <span class="nx">multilineMode</span>
<span class="nx">repl</span><span class="p">.</span><span class="nx">_line</span><span class="p">()</span> <span class="k">if</span> <span class="o">not</span> <span class="nx">multilineMode</span> <span class="o">and</span> <span class="nx">backlog</span>
<span class="nv">backlog = </span><span class="s">&#39;&#39;</span>
<span class="nx">repl</span><span class="p">.</span><span class="nx">setPrompt</span> <span class="p">(</span><span class="nv">newPrompt = </span><span class="k">if</span> <span class="nx">multilineMode</span> <span class="k">then</span> <span class="nx">REPL_PROMPT_MULTILINE</span> <span class="k">else</span> <span class="nx">REPL_PROMPT</span><span class="p">)</span>
<span class="nx">repl</span><span class="p">.</span><span class="nx">prompt</span><span class="p">()</span>
<span class="nx">repl</span><span class="p">.</span><span class="nx">output</span><span class="p">.</span><span class="nx">cursorTo</span> <span class="nx">newPrompt</span><span class="p">.</span><span class="nx">length</span> <span class="o">+</span> <span class="p">(</span><span class="nv">repl.cursor = </span><span class="nx">cursorPos</span><span class="p">)</span></pre></div> </td> </tr> <tr id="section-22"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-22">&#182;</a> </div> <p>Handle Ctrl-d press at end of last line in multiline mode</p> </td> <td class="code"> <div class="highlight"><pre><span class="nx">repl</span><span class="p">.</span><span class="nx">input</span><span class="p">.</span><span class="nx">on</span> <span class="s">&#39;keypress&#39;</span><span class="p">,</span> <span class="nf">(char, key) -&gt;</span>
<span class="k">return</span> <span class="k">unless</span> <span class="nx">multilineMode</span> <span class="o">and</span> <span class="nx">repl</span><span class="p">.</span><span class="nx">line</span></pre></div> </td> </tr> <tr id="section-23"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-23">&#182;</a> </div> <p>test for Ctrl-d</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">return</span> <span class="k">unless</span> <span class="nx">key</span> <span class="o">and</span> <span class="nx">key</span><span class="p">.</span><span class="nx">ctrl</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">key</span><span class="p">.</span><span class="nx">meta</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">key</span><span class="p">.</span><span class="nx">shift</span> <span class="o">and</span> <span class="nx">key</span><span class="p">.</span><span class="nx">name</span> <span class="o">is</span> <span class="s">&#39;d&#39;</span>
<span class="nv">multilineMode = </span><span class="kc">off</span>
<span class="nx">repl</span><span class="p">.</span><span class="nx">_line</span><span class="p">()</span>
<span class="nx">repl</span><span class="p">.</span><span class="nx">on</span> <span class="s">&#39;attemptClose&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span>
<span class="k">if</span> <span class="nx">multilineMode</span>
<span class="nv">multilineMode = </span><span class="kc">off</span>
<span class="nx">repl</span><span class="p">.</span><span class="nx">output</span><span class="p">.</span><span class="nx">cursorTo</span> <span class="mi">0</span>
<span class="nx">repl</span><span class="p">.</span><span class="nx">output</span><span class="p">.</span><span class="nx">clearLine</span> <span class="mi">1</span>
<span class="nx">repl</span><span class="p">.</span><span class="nx">_onLine</span> <span class="nx">repl</span><span class="p">.</span><span class="nx">line</span>
<span class="k">return</span>
<span class="k">if</span> <span class="nx">backlog</span> <span class="o">or</span> <span class="nx">repl</span><span class="p">.</span><span class="nx">line</span>
<span class="nv">backlog = </span><span class="s">&#39;&#39;</span>
<span class="nv">repl.historyIndex = </span><span class="o">-</span><span class="mi">1</span>
<span class="nx">repl</span><span class="p">.</span><span class="nx">setPrompt</span> <span class="nx">REPL_PROMPT</span>
<span class="nx">repl</span><span class="p">.</span><span class="nx">output</span><span class="p">.</span><span class="nx">write</span> <span class="s">&#39;\n(^C again to quit)&#39;</span>
<span class="nx">repl</span><span class="p">.</span><span class="nx">_line</span> <span class="p">(</span><span class="nv">repl.line = </span><span class="s">&#39;&#39;</span><span class="p">)</span>
<span class="k">else</span>
<span class="nx">repl</span><span class="p">.</span><span class="nx">close</span><span class="p">()</span>
<span class="nx">repl</span><span class="p">.</span><span class="nx">on</span> <span class="s">&#39;close&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span>
<span class="nx">repl</span><span class="p">.</span><span class="nx">output</span><span class="p">.</span><span class="nx">write</span> <span class="s">&#39;\n&#39;</span>
<span class="nx">repl</span><span class="p">.</span><span class="nx">input</span><span class="p">.</span><span class="nx">destroy</span><span class="p">()</span>
<span class="nx">repl</span><span class="p">.</span><span class="nx">on</span> <span class="s">&#39;line&#39;</span><span class="p">,</span> <span class="nx">run</span>
<span class="nx">repl</span><span class="p">.</span><span class="nx">setPrompt</span> <span class="nx">REPL_PROMPT</span>
<span class="nx">repl</span><span class="p">.</span><span class="nx">prompt</span><span class="p">()</span>
<span class="nv">module.exports =</span>
<span class="nv">start: </span><span class="nf">(opts = {}) -&gt;</span>
<span class="nv">opts = </span><span class="nx">merge</span> <span class="nx">replDefaults</span><span class="p">,</span> <span class="nx">opts</span>
<span class="nv">repl = </span><span class="nx">nodeREPL</span><span class="p">.</span><span class="nx">start</span> <span class="nx">opts</span>
<span class="nx">repl</span><span class="p">.</span><span class="nx">on</span> <span class="s">&#39;exit&#39;</span><span class="p">,</span> <span class="nf">-&gt;</span> <span class="nx">repl</span><span class="p">.</span><span class="nx">outputStream</span><span class="p">.</span><span class="nx">write</span> <span class="s">&#39;\n&#39;</span>
<span class="nx">addMultilineHandler</span> <span class="nx">repl</span>
<span class="nx">repl</span>
</pre></div> </td> </tr> </tbody> </table> </div> </body> </html>

View File

@@ -1,4 +1,4 @@
<!DOCTYPE html> <html> <head> <title>rewriter.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> rewriter.coffee </h1> </th> <th class="code"> </th> </tr> </thead> <tbody> <tr id="section-1"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-1">&#182;</a> </div> <p>The CoffeeScript language has a good deal of optional syntax, implicit syntax,
<!DOCTYPE html> <html> <head> <title>rewriter.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> </div> </div> </div> <table cellpadding="0" cellspacing="0"> <thead> <tr> <th class="docs"> <h1> rewriter.coffee </h1> </th> <th class="code"> </th> </tr> </thead> <tbody> <tr id="section-1"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-1">&#182;</a> </div> <p>The CoffeeScript language has a good deal of optional syntax, implicit syntax,
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
@@ -18,6 +18,7 @@ corrected before implicit parentheses can be wrapped around blocks of code.</p>
<span class="nx">@tagPostfixConditionals</span><span class="p">()</span>
<span class="nx">@addImplicitBraces</span><span class="p">()</span>
<span class="nx">@addImplicitParentheses</span><span class="p">()</span>
<span class="nx">@addLocationDataToGeneratedTokens</span><span class="p">()</span>
<span class="nx">@tokens</span></pre></div> </td> </tr> <tr id="section-5"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-5">&#182;</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
@@ -87,7 +88,7 @@ Insert the missing braces here, so that the parser doesn't have to.</p>
<span class="p">[</span><span class="nx">tag</span><span class="p">]</span> <span class="o">=</span> <span class="nx">token</span>
<span class="nv">sameLine = </span><span class="kc">no</span> <span class="k">if</span> <span class="nx">tag</span> <span class="k">in</span> <span class="nx">LINEBREAKS</span>
<span class="k">return</span> <span class="p">(</span>
<span class="p">(</span><span class="nx">tag</span> <span class="k">in</span> <span class="p">[</span><span class="s">&#39;TERMINATOR&#39;</span><span class="p">,</span> <span class="s">&#39;OUTDENT&#39;</span><span class="p">]</span> <span class="o">or</span>
<span class="p">(</span><span class="nx">tag</span> <span class="k">in</span> <span class="p">[</span><span class="s">&#39;TERMINATOR&#39;</span><span class="p">,</span> <span class="s">&#39;OUTDENT&#39;</span><span class="p">]</span> <span class="o">or</span>
<span class="p">(</span><span class="nx">tag</span> <span class="k">in</span> <span class="nx">IMPLICIT_END</span> <span class="o">and</span> <span class="nx">sameLine</span> <span class="o">and</span> <span class="o">not</span> <span class="p">(</span><span class="nx">i</span> <span class="o">-</span> <span class="nx">startIndex</span> <span class="o">is</span> <span class="mi">1</span><span class="p">)))</span> <span class="o">and</span>
<span class="p">((</span><span class="o">!</span><span class="nx">startsLine</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">isnt</span> <span class="s">&#39;,&#39;</span><span class="p">)</span> <span class="o">or</span>
<span class="o">not</span> <span class="p">(</span><span class="nx">two</span><span class="o">?</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">is</span> <span class="s">&#39;:&#39;</span> <span class="o">or</span> <span class="nx">one</span><span class="o">?</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">is</span> <span class="s">&#39;@&#39;</span> <span class="o">and</span> <span class="nx">three</span><span class="o">?</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">is</span> <span class="s">&#39;:&#39;</span><span class="p">)))</span> <span class="o">or</span>
@@ -96,7 +97,7 @@ Insert the missing braces here, so that the parser doesn't have to.</p>
<span class="p">)</span>
<span class="nv">action = </span><span class="nf">(token, i) -&gt;</span>
<span class="nv">tok = </span><span class="nx">@generate</span> <span class="s">&#39;}&#39;</span><span class="p">,</span> <span class="s">&#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 = </span><span class="nx">@generate</span> <span class="s">&#39;}&#39;</span><span class="p">,</span> <span class="s">&#39;}&#39;</span>
<span class="nx">@tokens</span><span class="p">.</span><span class="nx">splice</span> <span class="nx">i</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">tok</span>
<span class="nx">@scanTokens</span> <span class="nf">(token, i, tokens) -&gt;</span>
@@ -117,7 +118,7 @@ Insert the missing braces here, so that the parser doesn't have to.</p>
<span class="nv">startsLine = </span><span class="o">not</span> <span class="nx">prevTag</span> <span class="o">or</span> <span class="p">(</span><span class="nx">prevTag</span> <span class="k">in</span> <span class="nx">LINEBREAKS</span><span class="p">)</span>
<span class="nv">value = </span><span class="k">new</span> <span class="nb">String</span><span class="p">(</span><span class="s">&#39;{&#39;</span><span class="p">)</span>
<span class="nv">value.generated = </span><span class="kc">yes</span>
<span class="nv">tok = </span><span class="nx">@generate</span> <span class="s">&#39;{&#39;</span><span class="p">,</span> <span class="nx">value</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 = </span><span class="nx">@generate</span> <span class="s">&#39;{&#39;</span><span class="p">,</span> <span class="nx">value</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>
<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="mi">2</span></pre></div> </td> </tr> <tr id="section-11"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-11">&#182;</a> </div> <p>Methods may be optionally called without parentheses, for simple cases.
@@ -125,6 +126,7 @@ Insert the implicit parentheses here, so that the parser doesn't have to
deal with them.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">addImplicitParentheses: </span><span class="nf">-&gt;</span>
<span class="nv">noCall = seenSingle = seenControl = </span><span class="kc">no</span>
<span class="nv">callIndex = </span><span class="kc">null</span>
<span class="nv">condition = </span><span class="nf">(token, i) -&gt;</span>
<span class="p">[</span><span class="nx">tag</span><span class="p">]</span> <span class="o">=</span> <span class="nx">token</span>
@@ -136,10 +138,10 @@ deal with them.</p> </td> <td class="code">
<span class="p">(</span><span class="nx">tag</span> <span class="o">is</span> <span class="s">&#39;INDENT&#39;</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">seenControl</span><span class="p">))</span> <span class="o">and</span>
<span class="p">(</span><span class="nx">tag</span> <span class="o">isnt</span> <span class="s">&#39;INDENT&#39;</span> <span class="o">or</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">2</span><span class="p">)</span> <span class="o">not</span> <span class="k">in</span> <span class="p">[</span><span class="s">&#39;CLASS&#39;</span><span class="p">,</span> <span class="s">&#39;EXTENDS&#39;</span><span class="p">]</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">not</span> <span class="k">in</span> <span class="nx">IMPLICIT_BLOCK</span> <span class="o">and</span>
<span class="o">not</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="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="s">&#39;{&#39;</span><span class="p">)))</span>
<span class="o">not</span> <span class="p">(</span><span class="nx">callIndex</span> <span class="o">is</span> <span class="nx">i</span> <span class="o">-</span> <span class="mi">1</span> <span class="o">and</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="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="s">&#39;{&#39;</span><span class="p">)))</span>
<span class="nv">action = </span><span class="nf">(token, i) -&gt;</span>
<span class="nx">@tokens</span><span class="p">.</span><span class="nx">splice</span> <span class="nx">i</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">@generate</span> <span class="s">&#39;CALL_END&#39;</span><span class="p">,</span> <span class="s">&#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">@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">@generate</span> <span class="s">&#39;CALL_END&#39;</span><span class="p">,</span> <span class="s">&#39;)&#39;</span>
<span class="nx">@scanTokens</span> <span class="nf">(token, i, tokens) -&gt;</span>
<span class="nv">tag = </span><span class="nx">token</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
@@ -156,14 +158,31 @@ deal with them.</p> </td> <td class="code">
<span class="k">return</span> <span class="mi">1</span> <span class="k">unless</span> <span class="nx">callObject</span> <span class="o">or</span>
<span class="nx">prev</span><span class="o">?</span><span class="p">.</span><span class="nx">spaced</span> <span class="o">and</span> <span class="p">(</span><span class="nx">prev</span><span class="p">.</span><span class="nx">call</span> <span class="o">or</span> <span class="nx">prev</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">in</span> <span class="nx">IMPLICIT_FUNC</span><span class="p">)</span> <span class="o">and</span>
<span class="p">(</span><span class="nx">tag</span> <span class="k">in</span> <span class="nx">IMPLICIT_CALL</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="nx">spaced</span> <span class="o">or</span> <span class="nx">token</span><span class="p">.</span><span class="nx">newLine</span><span class="p">)</span> <span class="o">and</span> <span class="nx">tag</span> <span class="k">in</span> <span class="nx">IMPLICIT_UNSPACED_CALL</span><span class="p">)</span>
<span class="nv">callIndex = </span><span class="nx">i</span>
<span class="nx">tokens</span><span class="p">.</span><span class="nx">splice</span> <span class="nx">i</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">@generate</span> <span class="s">&#39;CALL_START&#39;</span><span class="p">,</span> <span class="s">&#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">1</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="s">&#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="s">&#39;?&#39;</span>
<span class="mi">2</span></pre></div> </td> </tr> <tr id="section-12"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-12">&#182;</a> </div> <p>Because our grammar is LALR(1), it can't handle some single-line
<span class="mi">2</span></pre></div> </td> </tr> <tr id="section-12"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-12">&#182;</a> </div> <p>Add location data to all tokens generated by the rewriter.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">addLocationDataToGeneratedTokens: </span><span class="nf">-&gt;</span>
<span class="nx">@scanTokens</span> <span class="nf">(token, i, tokens) -&gt;</span>
<span class="nv">tag = </span><span class="nx">token</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">token</span><span class="p">.</span><span class="nx">generated</span> <span class="o">or</span> <span class="nx">token</span><span class="p">.</span><span class="nx">explicit</span><span class="p">)</span> <span class="o">and</span> <span class="p">(</span><span class="o">not</span> <span class="nx">token</span><span class="p">[</span><span class="mi">2</span><span class="p">])</span>
<span class="k">if</span> <span class="nx">i</span> <span class="o">&gt;</span> <span class="mi">0</span>
<span class="nv">prevToken = </span><span class="nx">tokens</span><span class="p">[</span><span class="nx">i</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
<span class="nx">token</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="o">=</span>
<span class="nv">first_line: </span><span class="nx">prevToken</span><span class="p">[</span><span class="mi">2</span><span class="p">].</span><span class="nx">last_line</span>
<span class="nv">first_column: </span><span class="nx">prevToken</span><span class="p">[</span><span class="mi">2</span><span class="p">].</span><span class="nx">last_column</span>
<span class="nv">last_line: </span><span class="nx">prevToken</span><span class="p">[</span><span class="mi">2</span><span class="p">].</span><span class="nx">last_line</span>
<span class="nv">last_column: </span><span class="nx">prevToken</span><span class="p">[</span><span class="mi">2</span><span class="p">].</span><span class="nx">last_column</span>
<span class="k">else</span>
<span class="nx">token</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="o">=</span>
<span class="nv">first_line: </span><span class="mi">0</span>
<span class="nv">first_column: </span><span class="mi">0</span>
<span class="nv">last_line: </span><span class="mi">0</span>
<span class="nv">last_column: </span><span class="mi">0</span>
<span class="k">return</span> <span class="mi">1</span></pre></div> </td> </tr> <tr id="section-13"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-13">&#182;</a> </div> <p>Because our grammar is LALR(1), it can't handle some single-line
expressions that lack ending delimiters. The <strong>Rewriter</strong> adds the implicit
blocks, so it doesn't need to. ')' can close a single-line block,
but we need to make sure it's balanced.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">addImplicitIndentation: </span><span class="nf">-&gt;</span>
<span class="nv">starter = indent = outdent = </span><span class="kc">null</span>
<span class="nv">condition = </span><span class="nf">(token, i) -&gt;</span>
@@ -193,7 +212,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">tag</span> <span class="o">is</span> <span class="s">&#39;THEN&#39;</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-13"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-13">&#182;</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-14"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-14">&#182;</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="nv">tagPostfixConditionals: </span><span class="nf">-&gt;</span>
<span class="nv">original = </span><span class="kc">null</span>
@@ -209,14 +228,15 @@ different precedence.</p> </td> <td class="code">
<span class="k">return</span> <span class="mi">1</span> <span class="k">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="s">&#39;IF&#39;</span>
<span class="nv">original = </span><span class="nx">token</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="mi">1</span></pre></div> </td> </tr> <tr id="section-14"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-14">&#182;</a> </div> <p>Generate the indentation tokens, based on another token on the same line.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">indentation: </span><span class="nf">(token, implicit = no) -&gt;</span>
<span class="nv">indent = </span><span class="p">[</span><span class="s">&#39;INDENT&#39;</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="nx">token</span><span class="p">[</span><span class="mi">2</span><span class="p">]]</span>
<span class="nv">outdent = </span><span class="p">[</span><span class="s">&#39;OUTDENT&#39;</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="nx">token</span><span class="p">[</span><span class="mi">2</span><span class="p">]]</span>
<span class="mi">1</span></pre></div> </td> </tr> <tr id="section-15"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-15">&#182;</a> </div> <p>Generate the indentation tokens, based on another token on the same line.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">indentation: </span><span class="nf">(token, implicit = no) -&gt;</span>
<span class="nv">indent = </span><span class="p">[</span><span class="s">&#39;INDENT&#39;</span><span class="p">,</span> <span class="mi">2</span><span class="p">]</span>
<span class="nv">outdent = </span><span class="p">[</span><span class="s">&#39;OUTDENT&#39;</span><span class="p">,</span> <span class="mi">2</span><span class="p">]</span>
<span class="nv">indent.generated = outdent.generated = </span><span class="kc">yes</span> <span class="k">if</span> <span class="nx">implicit</span>
<span class="p">[</span><span class="nx">indent</span><span class="p">,</span> <span class="nx">outdent</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-15"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-15">&#182;</a> </div> <p>Create a generated token: one that exists due to a use of implicit syntax.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">generate: </span><span class="nf">(tag, value, line) -&gt;</span>
<span class="nv">tok = </span><span class="p">[</span><span class="nx">tag</span><span class="p">,</span> <span class="nx">value</span><span class="p">,</span> <span class="nx">line</span><span class="p">]</span>
<span class="nv">indent.explicit = outdent.explicit = </span><span class="kc">yes</span> <span class="k">if</span> <span class="o">not</span> <span class="nx">implicit</span>
<span class="p">[</span><span class="nx">indent</span><span class="p">,</span> <span class="nx">outdent</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-16"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-16">&#182;</a> </div> <p>Create a generated token: one that exists due to a use of implicit syntax.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">generate: </span><span class="nf">(tag, value) -&gt;</span>
<span class="nv">tok = </span><span class="p">[</span><span class="nx">tag</span><span class="p">,</span> <span class="nx">value</span><span class="p">]</span>
<span class="nv">tok.generated = </span><span class="kc">yes</span>
<span class="nx">tok</span></pre></div> </td> </tr> <tr id="section-16"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-16">&#182;</a> </div> <p>Look up a tag by token index.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">tag: </span><span class="nf">(i) -&gt;</span> <span class="nx">@tokens</span><span class="p">[</span><span class="nx">i</span><span class="p">]</span><span class="o">?</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-17"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-17">&#182;</a> </div> <h2>Constants</h2> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-18"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-18">&#182;</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="nx">tok</span></pre></div> </td> </tr> <tr id="section-17"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-17">&#182;</a> </div> <p>Look up a tag by token index.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">tag: </span><span class="nf">(i) -&gt;</span> <span class="nx">@tokens</span><span class="p">[</span><span class="nx">i</span><span class="p">]</span><span class="o">?</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-18"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-18">&#182;</a> </div> <h2>Constants</h2> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-19"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-19">&#182;</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="p">[</span><span class="s">&#39;(&#39;</span><span class="p">,</span> <span class="s">&#39;)&#39;</span><span class="p">]</span>
<span class="p">[</span><span class="s">&#39;[&#39;</span><span class="p">,</span> <span class="s">&#39;]&#39;</span><span class="p">]</span>
<span class="p">[</span><span class="s">&#39;{&#39;</span><span class="p">,</span> <span class="s">&#39;}&#39;</span><span class="p">]</span>
@@ -224,20 +244,20 @@ different precedence.</p> </td> <td class="code">
<span class="p">[</span><span class="s">&#39;CALL_START&#39;</span><span class="p">,</span> <span class="s">&#39;CALL_END&#39;</span><span class="p">]</span>
<span class="p">[</span><span class="s">&#39;PARAM_START&#39;</span><span class="p">,</span> <span class="s">&#39;PARAM_END&#39;</span><span class="p">]</span>
<span class="p">[</span><span class="s">&#39;INDEX_START&#39;</span><span class="p">,</span> <span class="s">&#39;INDEX_END&#39;</span><span class="p">]</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-19"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-19">&#182;</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">exports.INVERSES = INVERSES = </span><span class="p">{}</span></pre></div> </td> </tr> <tr id="section-20"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-20">&#182;</a> </div> <p>The tokens that signal the start/end of a balanced pair.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">EXPRESSION_START = </span><span class="p">[]</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-20"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-20">&#182;</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">exports.INVERSES = INVERSES = </span><span class="p">{}</span></pre></div> </td> </tr> <tr id="section-21"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-21">&#182;</a> </div> <p>The tokens that signal the start/end of a balanced pair.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">EXPRESSION_START = </span><span class="p">[]</span>
<span class="nv">EXPRESSION_END = </span><span class="p">[]</span>
<span class="k">for</span> <span class="p">[</span><span class="nx">left</span><span class="p">,</span> <span class="nx">rite</span><span class="p">]</span> <span class="k">in</span> <span class="nx">BALANCED_PAIRS</span>
<span class="nx">EXPRESSION_START</span><span class="p">.</span><span class="nx">push</span> <span class="nx">INVERSES</span><span class="p">[</span><span class="nx">rite</span><span class="p">]</span> <span class="o">=</span> <span class="nx">left</span>
<span class="nx">EXPRESSION_END</span> <span class="p">.</span><span class="nx">push</span> <span class="nx">INVERSES</span><span class="p">[</span><span class="nx">left</span><span class="p">]</span> <span class="o">=</span> <span class="nx">rite</span></pre></div> </td> </tr> <tr id="section-21"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-21">&#182;</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="s">&#39;CATCH&#39;</span><span class="p">,</span> <span class="s">&#39;WHEN&#39;</span><span class="p">,</span> <span class="s">&#39;ELSE&#39;</span><span class="p">,</span> <span class="s">&#39;FINALLY&#39;</span><span class="p">].</span><span class="nx">concat</span> <span class="nx">EXPRESSION_END</span></pre></div> </td> </tr> <tr id="section-22"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-22">&#182;</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="s">&#39;IDENTIFIER&#39;</span><span class="p">,</span> <span class="s">&#39;SUPER&#39;</span><span class="p">,</span> <span class="s">&#39;)&#39;</span><span class="p">,</span> <span class="s">&#39;CALL_END&#39;</span><span class="p">,</span> <span class="s">&#39;]&#39;</span><span class="p">,</span> <span class="s">&#39;INDEX_END&#39;</span><span class="p">,</span> <span class="s">&#39;@&#39;</span><span class="p">,</span> <span class="s">&#39;THIS&#39;</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-23"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-23">&#182;</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">EXPRESSION_END</span> <span class="p">.</span><span class="nx">push</span> <span class="nx">INVERSES</span><span class="p">[</span><span class="nx">left</span><span class="p">]</span> <span class="o">=</span> <span class="nx">rite</span></pre></div> </td> </tr> <tr id="section-22"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-22">&#182;</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="s">&#39;CATCH&#39;</span><span class="p">,</span> <span class="s">&#39;WHEN&#39;</span><span class="p">,</span> <span class="s">&#39;ELSE&#39;</span><span class="p">,</span> <span class="s">&#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-23"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-23">&#182;</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="s">&#39;IDENTIFIER&#39;</span><span class="p">,</span> <span class="s">&#39;SUPER&#39;</span><span class="p">,</span> <span class="s">&#39;)&#39;</span><span class="p">,</span> <span class="s">&#39;CALL_END&#39;</span><span class="p">,</span> <span class="s">&#39;]&#39;</span><span class="p">,</span> <span class="s">&#39;INDEX_END&#39;</span><span class="p">,</span> <span class="s">&#39;@&#39;</span><span class="p">,</span> <span class="s">&#39;THIS&#39;</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-24"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-24">&#182;</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="s">&#39;IDENTIFIER&#39;</span><span class="p">,</span> <span class="s">&#39;NUMBER&#39;</span><span class="p">,</span> <span class="s">&#39;STRING&#39;</span><span class="p">,</span> <span class="s">&#39;JS&#39;</span><span class="p">,</span> <span class="s">&#39;REGEX&#39;</span><span class="p">,</span> <span class="s">&#39;NEW&#39;</span><span class="p">,</span> <span class="s">&#39;PARAM_START&#39;</span><span class="p">,</span> <span class="s">&#39;CLASS&#39;</span>
<span class="s">&#39;IF&#39;</span><span class="p">,</span> <span class="s">&#39;TRY&#39;</span><span class="p">,</span> <span class="s">&#39;SWITCH&#39;</span><span class="p">,</span> <span class="s">&#39;THIS&#39;</span><span class="p">,</span> <span class="s">&#39;BOOL&#39;</span><span class="p">,</span> <span class="s">&#39;NULL&#39;</span><span class="p">,</span> <span class="s">&#39;UNDEFINED&#39;</span><span class="p">,</span> <span class="s">&#39;UNARY&#39;</span><span class="p">,</span> <span class="s">&#39;SUPER&#39;</span>
<span class="s">&#39;@&#39;</span><span class="p">,</span> <span class="s">&#39;-&gt;&#39;</span><span class="p">,</span> <span class="s">&#39;=&gt;&#39;</span><span class="p">,</span> <span class="s">&#39;[&#39;</span><span class="p">,</span> <span class="s">&#39;(&#39;</span><span class="p">,</span> <span class="s">&#39;{&#39;</span><span class="p">,</span> <span class="s">&#39;--&#39;</span><span class="p">,</span> <span class="s">&#39;++&#39;</span>
<span class="p">]</span>
<span class="nv">IMPLICIT_UNSPACED_CALL = </span><span class="p">[</span><span class="s">&#39;+&#39;</span><span class="p">,</span> <span class="s">&#39;-&#39;</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-24"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-24">&#182;</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="s">&#39;-&gt;&#39;</span><span class="p">,</span> <span class="s">&#39;=&gt;&#39;</span><span class="p">,</span> <span class="s">&#39;{&#39;</span><span class="p">,</span> <span class="s">&#39;[&#39;</span><span class="p">,</span> <span class="s">&#39;,&#39;</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-25"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-25">&#182;</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="s">&#39;POST_IF&#39;</span><span class="p">,</span> <span class="s">&#39;FOR&#39;</span><span class="p">,</span> <span class="s">&#39;WHILE&#39;</span><span class="p">,</span> <span class="s">&#39;UNTIL&#39;</span><span class="p">,</span> <span class="s">&#39;WHEN&#39;</span><span class="p">,</span> <span class="s">&#39;BY&#39;</span><span class="p">,</span> <span class="s">&#39;LOOP&#39;</span><span class="p">,</span> <span class="s">&#39;TERMINATOR&#39;</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-26"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-26">&#182;</a> </div> <p>Single-line flavors of block expressions that have unclosed endings.
<span class="nv">IMPLICIT_UNSPACED_CALL = </span><span class="p">[</span><span class="s">&#39;+&#39;</span><span class="p">,</span> <span class="s">&#39;-&#39;</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-25"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-25">&#182;</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="s">&#39;-&gt;&#39;</span><span class="p">,</span> <span class="s">&#39;=&gt;&#39;</span><span class="p">,</span> <span class="s">&#39;{&#39;</span><span class="p">,</span> <span class="s">&#39;[&#39;</span><span class="p">,</span> <span class="s">&#39;,&#39;</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-26"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-26">&#182;</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="s">&#39;POST_IF&#39;</span><span class="p">,</span> <span class="s">&#39;FOR&#39;</span><span class="p">,</span> <span class="s">&#39;WHILE&#39;</span><span class="p">,</span> <span class="s">&#39;UNTIL&#39;</span><span class="p">,</span> <span class="s">&#39;WHEN&#39;</span><span class="p">,</span> <span class="s">&#39;BY&#39;</span><span class="p">,</span> <span class="s">&#39;LOOP&#39;</span><span class="p">,</span> <span class="s">&#39;TERMINATOR&#39;</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-27"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-27">&#182;</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="s">&#39;ELSE&#39;</span><span class="p">,</span> <span class="s">&#39;-&gt;&#39;</span><span class="p">,</span> <span class="s">&#39;=&gt;&#39;</span><span class="p">,</span> <span class="s">&#39;TRY&#39;</span><span class="p">,</span> <span class="s">&#39;FINALLY&#39;</span><span class="p">,</span> <span class="s">&#39;THEN&#39;</span><span class="p">]</span>
<span class="nv">SINGLE_CLOSERS = </span><span class="p">[</span><span class="s">&#39;TERMINATOR&#39;</span><span class="p">,</span> <span class="s">&#39;CATCH&#39;</span><span class="p">,</span> <span class="s">&#39;FINALLY&#39;</span><span class="p">,</span> <span class="s">&#39;ELSE&#39;</span><span class="p">,</span> <span class="s">&#39;OUTDENT&#39;</span><span class="p">,</span> <span class="s">&#39;LEADING_WHEN&#39;</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-27"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-27">&#182;</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="s">&#39;TERMINATOR&#39;</span><span class="p">,</span> <span class="s">&#39;INDENT&#39;</span><span class="p">,</span> <span class="s">&#39;OUTDENT&#39;</span><span class="p">]</span>
<span class="nv">SINGLE_CLOSERS = </span><span class="p">[</span><span class="s">&#39;TERMINATOR&#39;</span><span class="p">,</span> <span class="s">&#39;CATCH&#39;</span><span class="p">,</span> <span class="s">&#39;FINALLY&#39;</span><span class="p">,</span> <span class="s">&#39;ELSE&#39;</span><span class="p">,</span> <span class="s">&#39;OUTDENT&#39;</span><span class="p">,</span> <span class="s">&#39;LEADING_WHEN&#39;</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-28"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-28">&#182;</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="s">&#39;TERMINATOR&#39;</span><span class="p">,</span> <span class="s">&#39;INDENT&#39;</span><span class="p">,</span> <span class="s">&#39;OUTDENT&#39;</span><span class="p">]</span>
</pre></div> </td> </tr> </tbody> </table> </div> </body> </html>

View File

@@ -48,6 +48,7 @@
<a href="#overview">Overview</a>
<a href="#installation">Installation</a>
<a href="#usage">Usage</a>
<a href="#literate">Literate CoffeeScript</a>
<a href="#language">Language Reference</a>
<a href="#literals">Literals: Functions, Objects and Arrays</a>
<a href="#lexical_scope">Lexical Scoping and Variable Safety</a>
@@ -117,9 +118,9 @@
<span class="bookmark" id="top"></span>
<p>
<b>CoffeeScript is a little language that compiles into JavaScript.</b> Underneath
all those awkward braces and semicolons, JavaScript has always had
a gorgeous object model at its heart. CoffeeScript is an attempt to expose
<b>CoffeeScript is a little language that compiles into JavaScript.</b>
Underneath that awkward Java-esque patina, JavaScript has always had
a gorgeous heart. CoffeeScript is an attempt to expose
the good parts of JavaScript in a simple way.
</p>
@@ -136,7 +137,7 @@
<p>
<b>Latest Version:</b>
<a href="http://github.com/jashkenas/coffee-script/tarball/1.4.0">1.4.0</a>
<a href="http://github.com/jashkenas/coffee-script/tarball/1.5.0">1.5.0</a>
</p>
<h2>
@@ -357,6 +358,33 @@ Expressions
</li>
</ul>
<h2>
<span id="literate" class="bookmark"></span>
Literate CoffeeScript
</h2>
<p>
Besides being used as an ordinary programming language, CoffeeScript may
also be written in "literate" mode. If you name your file with a
<tt>.litcoffee</tt> extension, you can write it as a Markdown document &mdash;
a document that also happens to be executable CoffeeScript code.
</p>
<p>
Just for kicks, a little bit of the compiler is currently implemented in this fashion:
See it
<a href="https://gist.github.com/jashkenas/3fc3c1a8b1009c00d9df">as a document</a>,
<a href="https://raw.github.com/jashkenas/coffee-script/master/src/scope.litcoffee">raw</a>,
and <a href="http://cl.ly/LxEu">properly highlighted in a text editor</a>.
</p>
<p>
I'm fairly excited about this direction for the language, and am looking
forward to writing (and more importantly, reading) more programs in this style.
As <b>1.5.0</b> is the first version of CoffeeScript that supports it, let us know
if you have any ideas for improving the feature.
</p>
<h2>
<span id="language" class="bookmark"></span>
Language Reference
@@ -970,7 +998,7 @@ Expressions
is a reimagination of the excellent book
<a href="http://eloquentjavascript.net/">Eloquent JavaScript</a>, as if
it had been written in CoffeeScript instead. Covers language features
as well a the functional and object oriented programming styles. By
as well as the functional and object oriented programming styles. By
<a href="https://github.com/autotelicum">E. Hoigaard</a>.
</li>
<li>
@@ -986,6 +1014,17 @@ Expressions
towards real-world usage both in the browser (jQuery) and on the server
size (Rails, Node).
</li>
<li>
<a href="http://ristrettolo.gy">CoffeeScript Ristretto</a>
is a deep dive into CoffeeScript's semantics from simple functions up through
closures, higher-order functions, objects, classes, combinators, and decorators.
By <a href="http://braythwayt.com/">Reg Braithwaite</a>.
</li>
<li>
<a href="https://efendibooks.com/minibooks/testing-with-coffeescript">Testing with CoffeeScript</a>
is a succinct and freely downloadable guide to building testable
applications with CoffeeScript and Jasmine.
</li>
</ul>
<h2>
@@ -1030,11 +1069,6 @@ Expressions
<b>sstephenson</b>'s <a href="http://pow.cx/">Pow</a>,
a zero-configuration Rack server, with comprehensive annotated source.
</li>
<li>
<b>frank06</b>'s <a href="http://riakjs.org/">riak-js</a>, a Node.js client for
<a href="http://www.basho.com/Riak.html">Riak</a>, with support for HTTP
and Protocol Buffers.
</li>
<li>
<b>technoweenie</b>'s <a href="https://github.com/technoweenie/coffee-resque">Coffee-Resque</a>,
a port of <a href="https://github.com/defunkt/resque">Resque</a> for Node.js.
@@ -1123,6 +1157,34 @@ Expressions
Change Log
</h2>
<p>
<b class="header" style="margin-top: 20px;">
<a href="https://github.com/jashkenas/coffee-script/compare/1.4.0...1.5.0">1.5.0</a>
<span class="timestamp"> &ndash; <small>Feb 25, 2013</small></span>
</b>
<ul>
<li>
First release of <a href="#literate">Literate CoffeeScript</a>.
</li>
<li>
The CoffeeScript REPL is now based on the Node.js REPL, and should work
better and more familiarly.
</li>
<li>
Returning explicit values from constructors is now forbidden. If you want
to return an arbitrary value, use a function, not a constructor.
</li>
<li>
You can now loop over an array backwards, without having to manually
deal with the indexes.
</li>
<li>
Source locations are now preserved in the CoffeeScript AST, although
source maps are not yet being emitted.
</li>
</ul>
</p>
<p>
<b class="header" style="margin-top: 20px;">
<a href="https://github.com/jashkenas/coffee-script/compare/1.3.3...1.4.0">1.4.0</a>

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.4.0
// Generated by CoffeeScript 1.5.0
var volume, winner;
if (ignition === true) {

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.4.0
// Generated by CoffeeScript 1.5.0
var courses, dish, food, foods, i, _i, _j, _k, _len, _len1, _len2, _ref;
_ref = ['toast', 'cheese', 'wine'];

View File

@@ -1,6 +1,6 @@
// Generated by CoffeeScript 1.4.0
// Generated by CoffeeScript 1.5.0
/*
CoffeeScript Compiler v1.4.0
CoffeeScript Compiler v1.5.0
Released under the MIT License
*/

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.4.0
// Generated by CoffeeScript 1.5.0
var fs;
fs = require('fs');

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.4.0
// Generated by CoffeeScript 1.5.0
var Animal, Horse, Snake, sam, tom,
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
@@ -22,7 +22,7 @@ Snake = (function(_super) {
__extends(Snake, _super);
function Snake() {
return Snake.__super__.constructor.apply(this, arguments);
Snake.__super__.constructor.apply(this, arguments);
}
Snake.prototype.move = function() {
@@ -39,7 +39,7 @@ Horse = (function(_super) {
__extends(Horse, _super);
function Horse() {
return Horse.__super__.constructor.apply(this, arguments);
Horse.__super__.constructor.apply(this, arguments);
}
Horse.prototype.move = function() {

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.4.0
// Generated by CoffeeScript 1.5.0
var cholesterol, healthy;
cholesterol = 127;

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.4.0
// Generated by CoffeeScript 1.5.0
var date, mood;
if (singing) {

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.4.0
// Generated by CoffeeScript 1.5.0
var fill;
fill = function(container, liquid) {

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.4.0
// Generated by CoffeeScript 1.5.0
var filename, _fn, _i, _len;
_fn = function(filename) {

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.4.0
// Generated by CoffeeScript 1.5.0
var hi;
hi = function() {

View File

@@ -1,7 +1,7 @@
// Generated by CoffeeScript 1.4.0
// Generated by CoffeeScript 1.5.0
var footprints, solipsism, speed;
if ((typeof mind !== "undefined" && mind !== null) && !(typeof world !== "undefined" && world !== null)) {
if ((typeof mind !== "undefined" && mind !== null) && (typeof world === "undefined" || world === null)) {
solipsism = true;
}

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.4.0
// Generated by CoffeeScript 1.5.0
var eldest, grade;
grade = function(student) {

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.4.0
// Generated by CoffeeScript 1.5.0
var one, six, three, two;
six = (one = 1) + (two = 2) + (three = 3);

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.4.0
// Generated by CoffeeScript 1.5.0
var globals, name;
globals = ((function() {

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.4.0
// Generated by CoffeeScript 1.5.0
alert((function() {
try {

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.4.0
// Generated by CoffeeScript 1.5.0
var Account;
Account = function(customer, cart) {

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.4.0
// Generated by CoffeeScript 1.5.0
var cube, square;
square = function(x) {

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.4.0
// Generated by CoffeeScript 1.5.0
var html;
html = "<strong>\n cup of coffeescript\n</strong>";

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.4.0
// Generated by CoffeeScript 1.5.0
var OPERATOR;
OPERATOR = /^(?:[-=]>|[-+*\/%<>&|^!?=]=|>>>=?|([-+:])\1|([&|<>])\2=?|\?\.|\.{2,3})/;

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.4.0
// Generated by CoffeeScript 1.5.0
var author, quote, sentence;
author = "Wittgenstein";

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.4.0
// Generated by CoffeeScript 1.5.0
var city, forecast, temp, weatherReport, _ref;
weatherReport = function(location) {

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.4.0
// Generated by CoffeeScript 1.5.0
var age, ages, child, yearsOld;
yearsOld = {

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.4.0
// Generated by CoffeeScript 1.5.0
var city, futurists, name, street, _ref, _ref1;
futurists = {

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.4.0
// Generated by CoffeeScript 1.5.0
var bitlist, kids, singers, song;
song = ["do", "re", "mi", "fa", "so"];

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.4.0
// Generated by CoffeeScript 1.5.0
$('.account').attr({
"class": 'active'

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.4.0
// Generated by CoffeeScript 1.5.0
var cubes, list, math, num, number, opposite, race, square,
__slice = [].slice;

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.4.0
// Generated by CoffeeScript 1.5.0
var theBait, theSwitch, _ref;
theBait = 1000;

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.4.0
// Generated by CoffeeScript 1.5.0
var close, contents, open, tag, _i, _ref,
__slice = [].slice;

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.4.0
// Generated by CoffeeScript 1.5.0
String.prototype.dasherize = function() {
return this.replace(/_/g, "-");

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.4.0
// Generated by CoffeeScript 1.5.0
var countdown, num;
countdown = (function() {

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.4.0
// Generated by CoffeeScript 1.5.0
var changeNumbers, inner, outer;
outer = 1;

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.4.0
// Generated by CoffeeScript 1.5.0
var copy, end, middle, numbers, start;
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9];

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.4.0
// Generated by CoffeeScript 1.5.0
var zip, _ref;
zip = typeof lottery.drawWinner === "function" ? (_ref = lottery.drawWinner().address) != null ? _ref.zipcode : void 0 : void 0;

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.4.0
// Generated by CoffeeScript 1.5.0
var awardMedals, contenders, gold, rest, silver,
__slice = [].slice;

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.4.0
// Generated by CoffeeScript 1.5.0
var numbers, _ref;
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.4.0
// Generated by CoffeeScript 1.5.0
var mobyDick;
mobyDick = "Call me Ishmael. Some years ago -- never mind how long precisely -- having little or no money in my purse, and nothing particular to interest me on shore, I thought I would sail about a little and see the watery part of the world...";

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.4.0
// Generated by CoffeeScript 1.5.0
switch (day) {
case "Mon":

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.4.0
// Generated by CoffeeScript 1.5.0
try {
allHellBreaksLoose();

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.4.0
// Generated by CoffeeScript 1.5.0
var lyrics, num;
if (this.studyingEconomics) {

File diff suppressed because one or more lines are too long

View File

@@ -25,6 +25,7 @@
<a href="#overview">Overview</a>
<a href="#installation">Installation</a>
<a href="#usage">Usage</a>
<a href="#literate">Literate CoffeeScript</a>
<a href="#language">Language Reference</a>
<a href="#literals">Literals: Functions, Objects and Arrays</a>
<a href="#lexical_scope">Lexical Scoping and Variable Safety</a>
@@ -94,9 +95,9 @@
<span class="bookmark" id="top"></span>
<p>
<b>CoffeeScript is a little language that compiles into JavaScript.</b> Underneath
all those awkward braces and semicolons, JavaScript has always had
a gorgeous object model at its heart. CoffeeScript is an attempt to expose
<b>CoffeeScript is a little language that compiles into JavaScript.</b>
Underneath that awkward Java-esque patina, JavaScript has always had
a gorgeous heart. CoffeeScript is an attempt to expose
the good parts of JavaScript in a simple way.
</p>
@@ -113,7 +114,7 @@
<p>
<b>Latest Version:</b>
<a href="http://github.com/jashkenas/coffee-script/tarball/1.4.0">1.4.0</a>
<a href="http://github.com/jashkenas/coffee-script/tarball/1.5.0">1.5.0</a>
</p>
<h2>
@@ -411,8 +412,9 @@ Expressions
<td><code>--nodejs</code></td>
<td>
The <tt>node</tt> executable has some useful options you can set,
such as<br /> <tt>--debug</tt>, <tt>--debug-brk</tt> and <tt>--max-stack-size</tt>. Use this
flag to forward options directly to Node.js.
such as<br /> <tt>--debug</tt>, <tt>--debug-brk</tt>, <tt>--max-stack-size</tt>,
and <tt>--expose-gc</tt>. Use this flag to forward options directly to Node.js.
To pass multiple flags, use <tt>--nodejs</tt> multiple times.
</td>
</tr>
</table>
@@ -449,6 +451,33 @@ Expressions
</li>
</ul>
<h2>
<span id="literate" class="bookmark"></span>
Literate CoffeeScript
</h2>
<p>
Besides being used as an ordinary programming language, CoffeeScript may
also be written in "literate" mode. If you name your file with a
<tt>.litcoffee</tt> extension, you can write it as a Markdown document &mdash;
a document that also happens to be executable CoffeeScript code.
</p>
<p>
Just for kicks, a little bit of the compiler is currently implemented in this fashion:
See it
<a href="https://gist.github.com/jashkenas/3fc3c1a8b1009c00d9df">as a document</a>,
<a href="https://raw.github.com/jashkenas/coffee-script/master/src/scope.litcoffee">raw</a>,
and <a href="http://cl.ly/LxEu">properly highlighted in a text editor</a>.
</p>
<p>
I'm fairly excited about this direction for the language, and am looking
forward to writing (and more importantly, reading) more programs in this style.
As <b>1.5.0</b> is the first version of CoffeeScript that supports it, let us know
if you have any ideas for improving the feature.
</p>
<h2>
<span id="language" class="bookmark"></span>
Language Reference
@@ -1370,7 +1399,7 @@ footprints <span class="Keyword">=</span> yeti <span class="Keyword">?</span> <s
</pre><pre class="idle"><span class="Storage">var</span> footprints, solipsism, speed;
<span class="Keyword">if</span> ((<span class="Keyword">typeof</span> mind <span class="Keyword">!</span><span class="Keyword">==</span> <span class="String"><span class="String">&quot;</span>undefined<span class="String">&quot;</span></span> <span class="Keyword">&amp;</span><span class="Keyword">&amp;</span> mind <span class="Keyword">!</span><span class="Keyword">==</span> <span class="BuiltInConstant">null</span>) <span class="Keyword">&amp;</span><span class="Keyword">&amp;</span> <span class="Keyword">!</span>(<span class="Keyword">typeof</span> world <span class="Keyword">!</span><span class="Keyword">==</span> <span class="String"><span class="String">&quot;</span>undefined<span class="String">&quot;</span></span> <span class="Keyword">&amp;</span><span class="Keyword">&amp;</span> world <span class="Keyword">!</span><span class="Keyword">==</span> <span class="BuiltInConstant">null</span>)) {
<span class="Keyword">if</span> ((<span class="Keyword">typeof</span> mind <span class="Keyword">!</span><span class="Keyword">==</span> <span class="String"><span class="String">&quot;</span>undefined<span class="String">&quot;</span></span> <span class="Keyword">&amp;</span><span class="Keyword">&amp;</span> mind <span class="Keyword">!</span><span class="Keyword">==</span> <span class="BuiltInConstant">null</span>) <span class="Keyword">&amp;</span><span class="Keyword">&amp;</span> (<span class="Keyword">typeof</span> world <span class="Keyword">===</span> <span class="String"><span class="String">&quot;</span>undefined<span class="String">&quot;</span></span> <span class="Keyword">||</span> world <span class="Keyword">===</span> <span class="BuiltInConstant">null</span>)) {
solipsism <span class="Keyword">=</span> <span class="BuiltInConstant">true</span>;
}
@@ -1383,7 +1412,7 @@ speed <span class="Keyword">=</span> <span class="Number">0</span>;
footprints <span class="Keyword">=</span> <span class="Keyword">typeof</span> yeti <span class="Keyword">!</span><span class="Keyword">==</span> <span class="String"><span class="String">&quot;</span>undefined<span class="String">&quot;</span></span> <span class="Keyword">&amp;</span><span class="Keyword">&amp;</span> yeti <span class="Keyword">!</span><span class="Keyword">==</span> <span class="BuiltInConstant">null</span> ? yeti : <span class="String"><span class="String">&quot;</span>bear<span class="String">&quot;</span></span>;
</pre><script>window.example21 = "solipsism = true if mind? and not world?\n\nspeed = 0\nspeed ?= 15\n\nfootprints = yeti ? \"bear\"\n\nalert footprints"</script><div class='minibutton load' onclick='javascript: loadConsole(example21);'>load</div><div class='minibutton ok' onclick='javascript: var footprints, solipsism, speed;
if ((typeof mind !== "undefined" && mind !== null) && !(typeof world !== "undefined" && world !== null)) {
if ((typeof mind !== "undefined" && mind !== null) && (typeof world === "undefined" || world === null)) {
solipsism = true;
}
@@ -1488,7 +1517,7 @@ Snake <span class="Keyword">=</span> (<span class="Storage">function</span>(_sup
__extends(Snake, _super);
<span class="Storage">function</span> <span class="FunctionName">Snake</span>() {
<span class="Keyword">return</span> Snake.__super__.<span class="LibraryConstant">constructor</span>.<span class="LibraryFunction">apply</span>(<span class="Variable">this</span>, arguments);
Snake.__super__.<span class="LibraryConstant">constructor</span>.<span class="LibraryFunction">apply</span>(<span class="Variable">this</span>, arguments);
}
<span class="LibraryClassType">Snake</span>.<span class="LibraryConstant">prototype</span>.<span class="FunctionName">move</span> = <span class="Storage">function</span>() {
@@ -1505,7 +1534,7 @@ Horse <span class="Keyword">=</span> (<span class="Storage">function</span>(_sup
__extends(Horse, _super);
<span class="Storage">function</span> <span class="FunctionName">Horse</span>() {
<span class="Keyword">return</span> Horse.__super__.<span class="LibraryConstant">constructor</span>.<span class="LibraryFunction">apply</span>(<span class="Variable">this</span>, arguments);
Horse.__super__.<span class="LibraryConstant">constructor</span>.<span class="LibraryFunction">apply</span>(<span class="Variable">this</span>, arguments);
}
<span class="LibraryClassType">Horse</span>.<span class="LibraryConstant">prototype</span>.<span class="FunctionName">move</span> = <span class="Storage">function</span>() {
@@ -1547,7 +1576,7 @@ Snake = (function(_super) {
__extends(Snake, _super);
function Snake() {
return Snake.__super__.constructor.apply(this, arguments);
Snake.__super__.constructor.apply(this, arguments);
}
Snake.prototype.move = function() {
@@ -1564,7 +1593,7 @@ Horse = (function(_super) {
__extends(Horse, _super);
function Horse() {
return Horse.__super__.constructor.apply(this, arguments);
Horse.__super__.constructor.apply(this, arguments);
}
Horse.prototype.move = function() {
@@ -1994,18 +2023,18 @@ html = "<strong>\n cup of coffeescript\n</strong>";
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 v1.4.0</span>
<span class="Comment">CoffeeScript Compiler v1.5.0</span>
<span class="Comment">Released under the MIT License</span>
<span class="Comment"><span class="Comment">###</span></span>
</pre><pre class="idle"><span class="Comment"><span class="Comment">/*</span></span>
<span class="Comment">CoffeeScript Compiler v1.4.0</span>
<span class="Comment">CoffeeScript Compiler v1.5.0</span>
<span class="Comment">Released under the MIT License</span>
<span class="Comment"><span class="Comment">*/</span></span>
</pre><script>window.example37 = "###\nCoffeeScript Compiler v1.4.0\nReleased under the MIT License\n###\n\n\n"</script><div class='minibutton load' onclick='javascript: loadConsole(example37);'>load</div><br class='clear' /></div>
</pre><script>window.example37 = "###\nCoffeeScript Compiler v1.5.0\nReleased under the MIT License\n###\n\n\n"</script><div class='minibutton load' onclick='javascript: loadConsole(example37);'>load</div><br class='clear' /></div>
<p>
<span id="regexes" class="bookmark"></span>
@@ -2139,7 +2168,7 @@ task(<span class="String"><span class="String">'</span>build:parser<span class="
is a reimagination of the excellent book
<a href="http://eloquentjavascript.net/">Eloquent JavaScript</a>, as if
it had been written in CoffeeScript instead. Covers language features
as well a the functional and object oriented programming styles. By
as well as the functional and object oriented programming styles. By
<a href="https://github.com/autotelicum">E. Hoigaard</a>.
</li>
<li>
@@ -2155,6 +2184,17 @@ task(<span class="String"><span class="String">'</span>build:parser<span class="
towards real-world usage both in the browser (jQuery) and on the server
size (Rails, Node).
</li>
<li>
<a href="http://ristrettolo.gy">CoffeeScript Ristretto</a>
is a deep dive into CoffeeScript's semantics from simple functions up through
closures, higher-order functions, objects, classes, combinators, and decorators.
By <a href="http://braythwayt.com/">Reg Braithwaite</a>.
</li>
<li>
<a href="https://efendibooks.com/minibooks/testing-with-coffeescript">Testing with CoffeeScript</a>
is a succinct and freely downloadable guide to building testable
applications with CoffeeScript and Jasmine.
</li>
</ul>
<h2>
@@ -2199,11 +2239,6 @@ task(<span class="String"><span class="String">'</span>build:parser<span class="
<b>sstephenson</b>'s <a href="http://pow.cx/">Pow</a>,
a zero-configuration Rack server, with comprehensive annotated source.
</li>
<li>
<b>frank06</b>'s <a href="http://riakjs.org/">riak-js</a>, a Node.js client for
<a href="http://www.basho.com/Riak.html">Riak</a>, with support for HTTP
and Protocol Buffers.
</li>
<li>
<b>technoweenie</b>'s <a href="https://github.com/technoweenie/coffee-resque">Coffee-Resque</a>,
a port of <a href="https://github.com/defunkt/resque">Resque</a> for Node.js.
@@ -2292,6 +2327,34 @@ task(<span class="String"><span class="String">'</span>build:parser<span class="
Change Log
</h2>
<p>
<b class="header" style="margin-top: 20px;">
<a href="https://github.com/jashkenas/coffee-script/compare/1.4.0...1.5.0">1.5.0</a>
<span class="timestamp"> &ndash; <small>Feb 25, 2013</small></span>
</b>
<ul>
<li>
First release of <a href="#literate">Literate CoffeeScript</a>.
</li>
<li>
The CoffeeScript REPL is now based on the Node.js REPL, and should work
better and more familiarly.
</li>
<li>
Returning explicit values from constructors is now forbidden. If you want
to return an arbitrary value, use a function, not a constructor.
</li>
<li>
You can now loop over an array backwards, without having to manually
deal with the indexes.
</li>
<li>
Source locations are now preserved in the CoffeeScript AST, although
source maps are not yet being emitted.
</li>
</ul>
</p>
<p>
<b class="header" style="margin-top: 20px;">
<a href="https://github.com/jashkenas/coffee-script/compare/1.3.3...1.4.0">1.4.0</a>

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.5.0-pre
// Generated by CoffeeScript 1.5.0
(function() {
var CoffeeScript, runScripts;

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.5.0-pre
// Generated by CoffeeScript 1.5.0
(function() {
var CoffeeScript, cakefileDirectory, existsSync, fatalError, fs, helpers, missingTask, oparse, options, optparse, path, printTasks, switches, tasks;

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.5.0-pre
// Generated by CoffeeScript 1.5.0
(function() {
var Lexer, compile, ext, extensions, fs, lexer, loadFile, parser, path, vm, _i, _len,
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; },
@@ -32,7 +32,7 @@
}
}
exports.VERSION = '1.5.0-pre';
exports.VERSION = '1.5.0';
exports.helpers = require('./helpers');
@@ -152,8 +152,14 @@
parser.lexer = {
lex: function() {
var tag, _ref;
_ref = this.tokens[this.pos++] || [''], tag = _ref[0], this.yytext = _ref[1], this.yylineno = _ref[2];
var tag, token;
token = this.tokens[this.pos++];
if (token) {
tag = token[0], this.yytext = token[1], this.yylloc = token[2];
this.yylineno = this.yylloc.first_line;
} else {
tag = '';
}
return tag;
},
setInput: function(tokens) {

View File

@@ -1,6 +1,6 @@
// Generated by CoffeeScript 1.5.0-pre
// Generated by CoffeeScript 1.5.0
(function() {
var BANNER, CoffeeScript, EventEmitter, SWITCHES, coffee_exts, compileJoin, compileOptions, compilePath, compileScript, compileStdio, exec, exists, forkNode, fs, helpers, hidden, joinTimeout, lint, loadRequires, notSources, optionParser, optparse, opts, outputPath, parseOptions, path, printLine, printTokens, printWarn, removeSource, sourceCode, sources, spawn, timeLog, unwatchDir, usage, version, wait, watch, watchDir, watchers, writeJs, _ref,
var BANNER, CoffeeScript, EventEmitter, SWITCHES, coffee_exts, compileJoin, compileOptions, compilePath, compileScript, compileStdio, exec, exists, forkNode, fs, helpers, hidden, joinTimeout, lint, notSources, optionParser, optparse, opts, outputPath, parseOptions, path, printLine, printTokens, printWarn, removeSource, sourceCode, sources, spawn, timeLog, unwatchDir, usage, version, wait, watch, watchDir, watchers, writeJs, _ref,
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
fs = require('fs');
@@ -35,7 +35,7 @@
BANNER = 'Usage: coffee [options] path/to/script.coffee -- [args]\n\nIf called without options, `coffee` will run your script.';
SWITCHES = [['-b', '--bare', 'compile without a top-level function wrapper'], ['-c', '--compile', 'compile to JavaScript and save as .js files'], ['-e', '--eval', 'pass a string from the command line as input'], ['-h', '--help', 'display this help message'], ['-i', '--interactive', 'run an interactive CoffeeScript REPL'], ['-j', '--join [FILE]', 'concatenate the source CoffeeScript before compiling'], ['-l', '--lint', 'pipe the compiled JavaScript through JavaScript Lint'], ['-n', '--nodes', 'print out the parse tree that the parser produces'], ['--nodejs [ARGS]', 'pass options directly to the "node" binary'], ['-o', '--output [DIR]', 'set the output directory for compiled JavaScript'], ['-p', '--print', 'print out the compiled JavaScript'], ['-r', '--require [FILE*]', 'require a library before executing your script'], ['-s', '--stdio', 'listen for and compile scripts over stdio'], ['-t', '--tokens', 'print out the tokens that the lexer/rewriter produce'], ['-v', '--version', 'display the version number'], ['-w', '--watch', 'watch scripts for changes and rerun commands']];
SWITCHES = [['-b', '--bare', 'compile without a top-level function wrapper'], ['-c', '--compile', 'compile to JavaScript and save as .js files'], ['-e', '--eval', 'pass a string from the command line as input'], ['-h', '--help', 'display this help message'], ['-i', '--interactive', 'run an interactive CoffeeScript REPL'], ['-j', '--join [FILE]', 'concatenate the source CoffeeScript before compiling'], ['-l', '--lint', 'pipe the compiled JavaScript through JavaScript Lint'], ['-n', '--nodes', 'print out the parse tree that the parser produces'], ['--nodejs [ARGS]', 'pass options directly to the "node" binary'], ['-o', '--output [DIR]', 'set the output directory for compiled JavaScript'], ['-p', '--print', 'print out the compiled JavaScript'], ['-s', '--stdio', 'listen for and compile scripts over stdio'], ['-t', '--tokens', 'print out the tokens that the lexer/rewriter produce'], ['-v', '--version', 'display the version number'], ['-w', '--watch', 'watch scripts for changes and rerun commands']];
opts = {};
@@ -63,9 +63,6 @@
if (opts.version) {
return version();
}
if (opts.require) {
loadRequires();
}
if (opts.interactive) {
return require('./repl').start();
}
@@ -84,7 +81,6 @@
literals = opts.run ? sources.splice(1) : [];
process.argv = process.argv.slice(0, 2).concat(literals);
process.argv[0] = 'coffee';
process.execPath = require.main.filename;
_results = [];
for (_i = 0, _len = sources.length; _i < _len; _i++) {
source = sources[_i];
@@ -100,7 +96,7 @@
throw err;
}
if ((err != null ? err.code : void 0) === 'ENOENT') {
if (topLevel && (_ref1 = path.extname(source), __indexOf.call(coffee_exts, _ref1) < 0)) {
if (topLevel && source && (_ref1 = path.extname(source), __indexOf.call(coffee_exts, _ref1) < 0)) {
source = sources[sources.indexOf(source)] = "" + source + ".coffee";
return compilePath(source, topLevel, base);
}
@@ -236,18 +232,6 @@
}
};
loadRequires = function() {
var realFilename, req, _i, _len, _ref1;
realFilename = module.filename;
module.filename = '.';
_ref1 = opts.require;
for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
req = _ref1[_i];
require(req);
}
return module.filename = realFilename;
};
watch = function(source, base) {
var compile, compileTimeout, prevStats, rewatch, watchErr, watcher;
prevStats = null;
@@ -447,14 +431,16 @@
};
printTokens = function(tokens) {
var strings, tag, token, value;
var locationData, strings, tag, token, value;
strings = (function() {
var _i, _len, _ref1, _results;
var _i, _len, _results;
_results = [];
for (_i = 0, _len = tokens.length; _i < _len; _i++) {
token = tokens[_i];
_ref1 = [token[0], token[1].toString().replace(/\n/, '\\n')], tag = _ref1[0], value = _ref1[1];
_results.push("[" + tag + " " + value + "]");
tag = token[0];
value = token[1].toString().replace(/\n/, '\\n');
locationData = helpers.locationDataToString(token[2]);
_results.push("[" + tag + " " + value + " " + locationData + "]");
}
return _results;
})();

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.5.0-pre
// Generated by CoffeeScript 1.5.0
(function() {
var Parser, alt, alternatives, grammar, name, o, operators, token, tokens, unwrap;
@@ -7,15 +7,26 @@
unwrap = /^function\s*\(\)\s*\{\s*return\s*([\s\S]*);\s*\}/;
o = function(patternString, action, options) {
var match;
var addLocationDataFn, match, patternCount;
patternString = patternString.replace(/\s{2,}/g, ' ');
patternCount = patternString.split(' ').length;
if (!action) {
return [patternString, '$$ = $1;', options];
}
action = (match = unwrap.exec(action)) ? match[1] : "(" + action + "())";
action = action.replace(/\bnew /g, '$&yy.');
action = action.replace(/\b(?:Block\.wrap|extend)\b/g, 'yy.$&');
return [patternString, "$$ = " + action + ";", options];
action = action.replace(/\b(Op|Value\.(create|wrap))\b/g, 'yy.$&');
addLocationDataFn = function(first, last) {
if (!last) {
return "yy.addLocationDataFn(@" + first + ")";
} else {
return "yy.addLocationDataFn(@" + first + ", @" + last + ")";
}
};
action = action.replace(/LOC\(([0-9]*)\)/g, addLocationDataFn('$1'));
action = action.replace(/LOC\(([0-9]*),\s*([0-9]*)\)/g, addLocationDataFn('$1', '$2'));
return [patternString, "$$ = " + (addLocationDataFn(1, patternCount)) + "(" + action + ");", options];
};
grammar = {
@@ -83,12 +94,12 @@
],
AssignObj: [
o('ObjAssignable', function() {
return new Value($1);
return Value.wrap($1);
}), o('ObjAssignable : Expression', function() {
return new Assign(new Value($1), $3, 'object');
return new Assign(LOC(1)(Value.wrap($1)), $3, 'object');
}), o('ObjAssignable :\
INDENT Expression OUTDENT', function() {
return new Assign(new Value($1), $4, 'object');
return new Assign(LOC(1)(Value.wrap($1)), $4, 'object');
}), o('Comment')
],
ObjAssignable: [o('Identifier'), o('AlphaNumeric'), o('ThisProperty')],
@@ -149,27 +160,27 @@
],
SimpleAssignable: [
o('Identifier', function() {
return new Value($1);
return Value.wrap($1);
}), o('Value Accessor', function() {
return $1.add($2);
}), o('Invocation Accessor', function() {
return new Value($1, [].concat($2));
return Value.wrap($1, [].concat($2));
}), o('ThisProperty')
],
Assignable: [
o('SimpleAssignable'), o('Array', function() {
return new Value($1);
return Value.wrap($1);
}), o('Object', function() {
return new Value($1);
return Value.wrap($1);
})
],
Value: [
o('Assignable'), o('Literal', function() {
return new Value($1);
return Value.wrap($1);
}), o('Parenthetical', function() {
return new Value($1);
return Value.wrap($1);
}), o('Range', function() {
return new Value($1);
return Value.wrap($1);
}), o('This')
],
Accessor: [
@@ -178,7 +189,7 @@
}), o('?. Identifier', function() {
return new Access($2, 'soak');
}), o(':: Identifier', function() {
return [new Access(new Literal('prototype')), new Access($2)];
return [LOC(1)(new Access(new Literal('prototype'))), LOC(2)(new Access($2))];
}), o('::', function() {
return new Access(new Literal('prototype'));
}), o('Index')
@@ -263,14 +274,14 @@
],
This: [
o('THIS', function() {
return new Value(new Literal('this'));
return Value.wrap(new Literal('this'));
}), o('@', function() {
return new Value(new Literal('this'));
return Value.wrap(new Literal('this'));
})
],
ThisProperty: [
o('@ Identifier', function() {
return new Value(new Literal('this'), [new Access($2)], 'this');
return Value.wrap(LOC(1)(new Literal('this')), [LOC(2)(new Access($2))], 'this');
})
],
Array: [
@@ -337,7 +348,7 @@
o('CATCH Identifier Block', function() {
return [$2, $3];
}), o('CATCH Object Block', function() {
return [new Value($2), $3];
return [LOC(2)(Value.wrap($2)), $3];
})
],
Throw: [
@@ -374,18 +385,18 @@
o('WhileSource Block', function() {
return $1.addBody($2);
}), o('Statement WhileSource', function() {
return $2.addBody(Block.wrap([$1]));
return $2.addBody(LOC(1)(Block.wrap([$1])));
}), o('Expression WhileSource', function() {
return $2.addBody(Block.wrap([$1]));
return $2.addBody(LOC(1)(Block.wrap([$1])));
}), o('Loop', function() {
return $1;
})
],
Loop: [
o('LOOP Block', function() {
return new While(new Literal('true')).addBody($2);
return new While(LOC(1)(new Literal('true'))).addBody($2);
}), o('LOOP Expression', function() {
return new While(new Literal('true')).addBody(Block.wrap([$2]));
return new While(LOC(1)(new Literal('true'))).addBody(LOC(2)(Block.wrap([$2])));
})
],
For: [
@@ -400,7 +411,7 @@
ForBody: [
o('FOR Range', function() {
return {
source: new Value($2)
source: LOC(2)(Value.wrap($2))
};
}), o('ForStart ForSource', function() {
$2.own = $1.own;
@@ -419,9 +430,9 @@
],
ForValue: [
o('Identifier'), o('ThisProperty'), o('Array', function() {
return new Value($1);
return Value.wrap($1);
}), o('Object', function() {
return new Value($1);
return Value.wrap($1);
})
],
ForVariables: [
@@ -509,12 +520,12 @@
o('IfBlock'), o('IfBlock ELSE Block', function() {
return $1.addElse($3);
}), o('Statement POST_IF Expression', function() {
return new If($3, Block.wrap([$1]), {
return new If($3, LOC(1)(Block.wrap([$1])), {
type: $2,
statement: true
});
}), o('Expression POST_IF Expression', function() {
return new If($3, Block.wrap([$1]), {
return new If($3, LOC(1)(Block.wrap([$1])), {
type: $2,
statement: true
});
@@ -522,42 +533,42 @@
],
Operation: [
o('UNARY Expression', function() {
return new Op($1, $2);
return Op.create($1, $2);
}), o('- Expression', (function() {
return new Op('-', $2);
return Op.create('-', $2);
}), {
prec: 'UNARY'
}), o('+ Expression', (function() {
return new Op('+', $2);
return Op.create('+', $2);
}), {
prec: 'UNARY'
}), o('-- SimpleAssignable', function() {
return new Op('--', $2);
return Op.create('--', $2);
}), o('++ SimpleAssignable', function() {
return new Op('++', $2);
return Op.create('++', $2);
}), o('SimpleAssignable --', function() {
return new Op('--', $1, null, true);
return Op.create('--', $1, null, true);
}), o('SimpleAssignable ++', function() {
return new Op('++', $1, null, true);
return Op.create('++', $1, null, true);
}), o('Expression ?', function() {
return new Existence($1);
}), o('Expression + Expression', function() {
return new Op('+', $1, $3);
return Op.create('+', $1, $3);
}), o('Expression - Expression', function() {
return new Op('-', $1, $3);
return Op.create('-', $1, $3);
}), o('Expression MATH Expression', function() {
return new Op($2, $1, $3);
return Op.create($2, $1, $3);
}), o('Expression SHIFT Expression', function() {
return new Op($2, $1, $3);
return Op.create($2, $1, $3);
}), o('Expression COMPARE Expression', function() {
return new Op($2, $1, $3);
return Op.create($2, $1, $3);
}), o('Expression LOGIC Expression', function() {
return new Op($2, $1, $3);
return Op.create($2, $1, $3);
}), o('Expression RELATION Expression', function() {
if ($2.charAt(0) === '!') {
return new Op($2.slice(1), $1, $3).invert();
return Op.create($2.slice(1), $1, $3).invert();
} else {
return new Op($2, $1, $3);
return Op.create($2, $1, $3);
}
}), o('SimpleAssignable COMPOUND_ASSIGN\
Expression', function() {

View File

@@ -1,6 +1,6 @@
// Generated by CoffeeScript 1.5.0-pre
// Generated by CoffeeScript 1.5.0
(function() {
var extend, flatten, _ref;
var buildLocationData, extend, flatten, _ref;
exports.starts = function(string, literal, start) {
return literal === string.substr(start, literal.length);
@@ -85,4 +85,40 @@
return false;
};
buildLocationData = function(first, last) {
if (!last) {
return first;
} else {
return {
first_line: first.first_line,
first_column: first.first_column,
last_line: last.last_line,
last_column: last.last_column
};
}
};
exports.addLocationDataFn = function(first, last) {
return function(obj) {
if (((typeof obj) === 'object') && (!!obj['updateLocationDataIfMissing'])) {
obj.updateLocationDataIfMissing(buildLocationData(first, last));
}
return obj;
};
};
exports.locationDataToString = function(obj) {
var locationData;
if (("2" in obj) && ("first_line" in obj[2])) {
locationData = obj[2];
} else if ("first_line" in obj) {
locationData = obj;
}
if (locationData) {
return ("" + (locationData.first_line + 1) + ":" + (locationData.first_column + 1) + "-") + ("" + (locationData.last_line + 1) + ":" + (locationData.last_column + 1));
} else {
return "No location data";
}
};
}).call(this);

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.5.0-pre
// Generated by CoffeeScript 1.5.0
(function() {
var key, val, _ref;

View File

@@ -1,33 +1,36 @@
// Generated by CoffeeScript 1.5.0-pre
// Generated by CoffeeScript 1.5.0
(function() {
var BOM, BOOL, CALLABLE, CODE, COFFEE_ALIASES, COFFEE_ALIAS_MAP, COFFEE_KEYWORDS, COMMENT, COMPARE, COMPOUND_ASSIGN, HEREDOC, HEREDOC_ILLEGAL, HEREDOC_INDENT, HEREGEX, HEREGEX_OMIT, IDENTIFIER, INDEXABLE, INVERSES, JSTOKEN, JS_FORBIDDEN, JS_KEYWORDS, LINE_BREAK, LINE_CONTINUER, LITERATE, LOGIC, Lexer, MATH, MULTILINER, MULTI_DENT, NOT_REGEX, NOT_SPACED_REGEX, NUMBER, OPERATOR, REGEX, RELATION, RESERVED, Rewriter, SHIFT, SIMPLESTR, STRICT_PROSCRIBED, TRAILING_SPACES, UNARY, WHITESPACE, compact, count, key, last, starts, _ref, _ref1,
var BOM, BOOL, CALLABLE, CODE, COFFEE_ALIASES, COFFEE_ALIAS_MAP, COFFEE_KEYWORDS, COMMENT, COMPARE, COMPOUND_ASSIGN, HEREDOC, HEREDOC_ILLEGAL, HEREDOC_INDENT, HEREGEX, HEREGEX_OMIT, IDENTIFIER, INDEXABLE, INVERSES, JSTOKEN, JS_FORBIDDEN, JS_KEYWORDS, LINE_BREAK, LINE_CONTINUER, LITERATE, LOGIC, Lexer, MATH, MULTILINER, MULTI_DENT, NOT_REGEX, NOT_SPACED_REGEX, NUMBER, OPERATOR, REGEX, RELATION, RESERVED, Rewriter, SHIFT, SIMPLESTR, STRICT_PROSCRIBED, TRAILING_SPACES, UNARY, WHITESPACE, compact, count, key, last, locationDataToString, starts, _ref, _ref1,
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
_ref = require('./rewriter'), Rewriter = _ref.Rewriter, INVERSES = _ref.INVERSES;
_ref1 = require('./helpers'), count = _ref1.count, starts = _ref1.starts, compact = _ref1.compact, last = _ref1.last;
_ref1 = require('./helpers'), count = _ref1.count, starts = _ref1.starts, compact = _ref1.compact, last = _ref1.last, locationDataToString = _ref1.locationDataToString;
exports.Lexer = Lexer = (function() {
function Lexer() {}
Lexer.prototype.tokenize = function(code, opts) {
var i, tag;
var consumed, i, tag, _ref2;
if (opts == null) {
opts = {};
}
this.literate = opts.literate;
code = this.clean(code);
this.line = opts.line || 0;
this.indent = 0;
this.indebt = 0;
this.outdebt = 0;
this.indents = [];
this.ends = [];
this.tokens = [];
this.chunkLine = opts.line || 0;
this.chunkColumn = opts.column || 0;
i = 0;
while (this.chunk = code.slice(i)) {
i += this.identifierToken() || this.commentToken() || this.whitespaceToken() || this.lineToken() || this.heredocToken() || this.stringToken() || this.numberToken() || this.regexToken() || this.jsToken() || this.literalToken();
consumed = this.identifierToken() || this.commentToken() || this.whitespaceToken() || this.lineToken() || this.heredocToken() || this.stringToken() || this.numberToken() || this.regexToken() || this.jsToken() || this.literalToken();
_ref2 = this.getLineAndColumnFromChunk(consumed), this.chunkLine = _ref2[0], this.chunkColumn = _ref2[1];
i += consumed;
}
this.closeIndentation();
if (tag = this.ends.pop()) {
@@ -69,11 +72,13 @@
};
Lexer.prototype.identifierToken = function() {
var colon, forcedIdentifier, id, input, match, prev, tag, _ref2, _ref3;
var colon, colonOffset, forcedIdentifier, id, idLength, input, match, poppedToken, prev, tag, tagToken, _ref2, _ref3, _ref4;
if (!(match = IDENTIFIER.exec(this.chunk))) {
return 0;
}
input = match[0], id = match[1], colon = match[2];
idLength = id.length;
poppedToken = void 0;
if (id === 'own' && this.tag() === 'FOR') {
this.token('OWN', id);
return id.length;
@@ -97,7 +102,7 @@
} else {
tag = 'RELATION';
if (this.value() === '!') {
this.tokens.pop();
poppedToken = this.tokens.pop();
id = '!' + id;
}
}
@@ -137,9 +142,13 @@
}
})();
}
this.token(tag, id);
tagToken = this.token(tag, id, 0, idLength);
if (poppedToken) {
_ref4 = [poppedToken[2].first_line, poppedToken[2].first_column], tagToken[2].first_line = _ref4[0], tagToken[2].first_column = _ref4[1];
}
if (colon) {
this.token(':', ':');
colonOffset = input.lastIndexOf(':');
this.token(':', ':', colonOffset, colon.length);
}
return input.length;
};
@@ -166,7 +175,7 @@
if (binaryLiteral = /^0b([01]+)/.exec(number)) {
number = '0x' + (parseInt(binaryLiteral[1], 2)).toString(16);
}
this.token('NUMBER', number);
this.token('NUMBER', number, 0, lexedLength);
return lexedLength;
};
@@ -177,16 +186,20 @@
if (!(match = SIMPLESTR.exec(this.chunk))) {
return 0;
}
this.token('STRING', (string = match[0]).replace(MULTILINER, '\\\n'));
string = match[0];
this.token('STRING', string.replace(MULTILINER, '\\\n'), 0, string.length);
break;
case '"':
if (!(string = this.balancedString(this.chunk, '"'))) {
return 0;
}
if (0 < string.indexOf('#{', 1)) {
this.interpolateString(string.slice(1, -1));
this.interpolateString(string.slice(1, -1), {
strOffset: 1,
lexedLength: string.length
});
} else {
this.token('STRING', this.escapeLines(string));
this.token('STRING', this.escapeLines(string, 0, string.length));
}
break;
default:
@@ -195,7 +208,6 @@
if (octalEsc = /^(?:\\.|[^\\])*\\(?:0[0-7]|[1-7])/.test(string)) {
this.error("octal escape sequences " + string + " are not allowed");
}
this.line += count(string, '\n');
return string.length;
};
@@ -212,12 +224,13 @@
});
if (quote === '"' && 0 <= doc.indexOf('#{')) {
this.interpolateString(doc, {
heredoc: true
heredoc: true,
strOffset: 3,
lexedLength: heredoc.length
});
} else {
this.token('STRING', this.makeString(doc, quote, true));
this.token('STRING', this.makeString(doc, quote, true), 0, heredoc.length);
}
this.line += count(heredoc, '\n');
return heredoc.length;
};
@@ -231,9 +244,8 @@
this.token('HERECOMMENT', this.sanitizeHeredoc(here, {
herecomment: true,
indent: Array(this.indent + 1).join(' ')
}));
}), 0, comment.length);
}
this.line += count(comment, '\n');
return comment.length;
};
@@ -242,8 +254,7 @@
if (!(this.chunk.charAt(0) === '`' && (match = JSTOKEN.exec(this.chunk)))) {
return 0;
}
this.token('JS', (script = match[0]).slice(1, -1));
this.line += count(script, '\n');
this.token('JS', (script = match[0]).slice(1, -1), 0, script.length);
return script.length;
};
@@ -254,7 +265,6 @@
}
if (match = HEREGEX.exec(this.chunk)) {
length = this.heregexToken(match);
this.line += count(match[0], '\n');
return length;
}
prev = last(this.tokens);
@@ -271,49 +281,60 @@
if (regex === '//') {
regex = '/(?:)/';
}
this.token('REGEX', "" + regex + flags);
this.token('REGEX', "" + regex + flags, 0, match.length);
return match.length;
};
Lexer.prototype.heregexToken = function(match) {
var body, flags, heregex, re, tag, tokens, value, _i, _len, _ref2, _ref3, _ref4, _ref5;
var body, flags, flagsOffset, heregex, plusToken, prev, re, tag, token, tokens, value, _i, _len, _ref2, _ref3, _ref4;
heregex = match[0], body = match[1], flags = match[2];
if (0 > body.indexOf('#{')) {
re = body.replace(HEREGEX_OMIT, '').replace(/\//g, '\\/');
if (re.match(/^\*/)) {
this.error('regular expressions cannot begin with `*`');
}
this.token('REGEX', "/" + (re || '(?:)') + "/" + flags);
this.token('REGEX', "/" + (re || '(?:)') + "/" + flags, 0, heregex.length);
return heregex.length;
}
this.token('IDENTIFIER', 'RegExp');
this.tokens.push(['CALL_START', '(']);
this.token('IDENTIFIER', 'RegExp', 0, 0);
this.token('CALL_START', '(', 0, 0);
tokens = [];
_ref2 = this.interpolateString(body, {
regex: true
});
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
_ref3 = _ref2[_i], tag = _ref3[0], value = _ref3[1];
token = _ref2[_i];
tag = token[0], value = token[1];
if (tag === 'TOKENS') {
tokens.push.apply(tokens, value);
} else {
} else if (tag === 'NEOSTRING') {
if (!(value = value.replace(HEREGEX_OMIT, ''))) {
continue;
}
value = value.replace(/\\/g, '\\\\');
tokens.push(['STRING', this.makeString(value, '"', true)]);
token[0] = 'STRING';
token[1] = this.makeString(value, '"', true);
tokens.push(token);
} else {
this.error("Unexpected " + tag);
}
tokens.push(['+', '+']);
prev = last(this.tokens);
plusToken = ['+', '+'];
plusToken[2] = prev[2];
tokens.push(plusToken);
}
tokens.pop();
if (((_ref4 = tokens[0]) != null ? _ref4[0] : void 0) !== 'STRING') {
this.tokens.push(['STRING', '""'], ['+', '+']);
if (((_ref3 = tokens[0]) != null ? _ref3[0] : void 0) !== 'STRING') {
this.token('STRING', '""', 0, 0);
this.token('+', '+', 0, 0);
}
(_ref5 = this.tokens).push.apply(_ref5, tokens);
(_ref4 = this.tokens).push.apply(_ref4, tokens);
if (flags) {
this.tokens.push([',', ','], ['STRING', '"' + flags + '"']);
flagsOffset = heregex.lastIndexOf(flags);
this.token(',', ',', flagsOffset, 0);
this.token('STRING', '"' + flags + '"', flagsOffset, flags.length);
}
this.token(')', ')');
this.token(')', ')', heregex.length - 1, 0);
return heregex.length;
};
@@ -323,7 +344,6 @@
return 0;
}
indent = match[0];
this.line += count(indent, '\n');
this.seenFor = false;
size = indent.length - 1 - indent.lastIndexOf('\n');
noNewlines = this.unfinished();
@@ -331,7 +351,7 @@
if (noNewlines) {
this.suppressNewlines();
} else {
this.newlineToken();
this.newlineToken(0);
}
return indent.length;
}
@@ -342,19 +362,19 @@
return indent.length;
}
diff = size - this.indent + this.outdebt;
this.token('INDENT', diff);
this.token('INDENT', diff, 0, indent.length);
this.indents.push(diff);
this.ends.push('OUTDENT');
this.outdebt = this.indebt = 0;
} else {
this.indebt = 0;
this.outdentToken(this.indent - size, noNewlines);
this.outdentToken(this.indent - size, noNewlines, indent.length);
}
this.indent = size;
return indent.length;
};
Lexer.prototype.outdentToken = function(moveOut, noNewlines) {
Lexer.prototype.outdentToken = function(moveOut, noNewlines, outdentLength) {
var dent, len;
while (moveOut > 0) {
len = this.indents.length - 1;
@@ -367,11 +387,11 @@
this.outdebt -= this.indents[len];
moveOut -= this.indents[len];
} else {
dent = this.indents.pop() - this.outdebt;
dent = this.indents.pop() + this.outdebt;
moveOut -= dent;
this.outdebt = 0;
this.pair('OUTDENT');
this.token('OUTDENT', dent);
this.token('OUTDENT', dent, 0, outdentLength);
}
}
if (dent) {
@@ -381,7 +401,7 @@
this.tokens.pop();
}
if (!(this.tag() === 'TERMINATOR' || noNewlines)) {
this.token('TERMINATOR', '\n');
this.token('TERMINATOR', '\n', outdentLength, 0);
}
return this;
};
@@ -402,12 +422,12 @@
}
};
Lexer.prototype.newlineToken = function() {
Lexer.prototype.newlineToken = function(offset) {
while (this.value() === ';') {
this.tokens.pop();
}
if (this.tag() !== 'TERMINATOR') {
this.token('TERMINATOR', '\n');
this.token('TERMINATOR', '\n', offset, 0);
}
return this;
};
@@ -581,11 +601,18 @@
};
Lexer.prototype.interpolateString = function(str, options) {
var expr, heredoc, i, inner, interpolated, len, letter, nested, pi, regex, tag, tokens, value, _i, _len, _ref2, _ref3, _ref4;
var column, expr, heredoc, i, inner, interpolated, len, letter, lexedLength, line, locationToken, nested, offsetInChunk, pi, plusToken, popped, regex, strOffset, tag, token, tokens, value, _i, _len, _ref2, _ref3, _ref4;
if (options == null) {
options = {};
}
heredoc = options.heredoc, regex = options.regex;
heredoc = options.heredoc, regex = options.regex, offsetInChunk = options.offsetInChunk, strOffset = options.strOffset, lexedLength = options.lexedLength;
offsetInChunk = offsetInChunk || 0;
strOffset = strOffset || 0;
lexedLength = lexedLength || str.length;
if (heredoc && str.length > 0 && str[0] === '\n') {
str = str.slice(1);
strOffset++;
}
tokens = [];
pi = 0;
i = -1;
@@ -598,22 +625,24 @@
continue;
}
if (pi < i) {
tokens.push(['NEOSTRING', str.slice(pi, i)]);
tokens.push(this.makeToken('NEOSTRING', str.slice(pi, i), strOffset + pi));
}
inner = expr.slice(1, -1);
if (inner.length) {
_ref2 = this.getLineAndColumnFromChunk(strOffset + i + 1), line = _ref2[0], column = _ref2[1];
nested = new Lexer().tokenize(inner, {
line: this.line,
line: line,
column: column,
rewrite: false
});
nested.pop();
if (((_ref2 = nested[0]) != null ? _ref2[0] : void 0) === 'TERMINATOR') {
nested.shift();
popped = nested.pop();
if (((_ref3 = nested[0]) != null ? _ref3[0] : void 0) === 'TERMINATOR') {
popped = nested.shift();
}
if (len = nested.length) {
if (len > 1) {
nested.unshift(['(', '(', this.line]);
nested.push([')', ')', this.line]);
nested.unshift(this.makeToken('(', '(', strOffset + i + 1, 0));
nested.push(this.makeToken(')', ')', strOffset + i + 1 + inner.length, 0));
}
tokens.push(['TOKENS', nested]);
}
@@ -622,33 +651,47 @@
pi = i + 1;
}
if ((i > pi && pi < str.length)) {
tokens.push(['NEOSTRING', str.slice(pi)]);
tokens.push(this.makeToken('NEOSTRING', str.slice(pi), strOffset + pi));
}
if (regex) {
return tokens;
}
if (!tokens.length) {
return this.token('STRING', '""');
return this.token('STRING', '""', offsetInChunk, lexedLength);
}
if (tokens[0][0] !== 'NEOSTRING') {
tokens.unshift(['', '']);
tokens.unshift(this.makeToken('NEOSTRING', '', offsetInChunk));
}
if (interpolated = tokens.length > 1) {
this.token('(', '(');
this.token('(', '(', offsetInChunk, 0);
}
for (i = _i = 0, _len = tokens.length; _i < _len; i = ++_i) {
_ref3 = tokens[i], tag = _ref3[0], value = _ref3[1];
token = tokens[i];
tag = token[0], value = token[1];
if (i) {
this.token('+', '+');
if (i) {
plusToken = this.token('+', '+');
}
locationToken = tag === 'TOKENS' ? value[0] : token;
plusToken[2] = {
first_line: locationToken[2].first_line,
first_column: locationToken[2].first_column,
last_line: locationToken[2].first_line,
last_column: locationToken[2].first_column
};
}
if (tag === 'TOKENS') {
(_ref4 = this.tokens).push.apply(_ref4, value);
} else if (tag === 'NEOSTRING') {
token[0] = 'STRING';
token[1] = this.makeString(value, '"', heredoc);
this.tokens.push(token);
} else {
this.token('STRING', this.makeString(value, '"', heredoc));
this.error("Unexpected " + tag);
}
}
if (interpolated) {
this.token(')', ')');
this.token(')', ')', offsetInChunk + lexedLength, 0);
}
return tokens;
};
@@ -666,8 +709,46 @@
return this.ends.pop();
};
Lexer.prototype.token = function(tag, value) {
return this.tokens.push([tag, value, this.line]);
Lexer.prototype.getLineAndColumnFromChunk = function(offset) {
var column, lineCount, lines, string;
if (offset === 0) {
return [this.chunkLine, this.chunkColumn];
}
if (offset >= this.chunk.length) {
string = this.chunk;
} else {
string = this.chunk.slice(0, +(offset - 1) + 1 || 9e9);
}
lineCount = count(string, '\n');
column = this.chunkColumn;
if (lineCount > 0) {
lines = string.split('\n');
column = (last(lines)).length;
} else {
column += string.length;
}
return [this.chunkLine + lineCount, column];
};
Lexer.prototype.makeToken = function(tag, value, offsetInChunk, length) {
var lastCharacter, locationData, token, _ref2, _ref3;
offsetInChunk = offsetInChunk || 0;
if (length === void 0) {
length = value.length;
}
locationData = {};
_ref2 = this.getLineAndColumnFromChunk(offsetInChunk), locationData.first_line = _ref2[0], locationData.first_column = _ref2[1];
lastCharacter = length > 0 ? length - 1 : 0;
_ref3 = this.getLineAndColumnFromChunk(offsetInChunk + (length - 1)), locationData.last_line = _ref3[0], locationData.last_column = _ref3[1];
token = [tag, value, locationData];
return token;
};
Lexer.prototype.token = function(tag, value, offsetInChunk, length) {
var token;
token = this.makeToken(tag, value, offsetInChunk, length);
this.tokens.push(token);
return token;
};
Lexer.prototype.tag = function(index, tag) {
@@ -705,7 +786,7 @@
};
Lexer.prototype.error = function(message) {
throw SyntaxError("" + message + " on line " + (this.line + 1));
throw SyntaxError("" + message + " on line " + (this.chunkLine + 1));
};
return Lexer;

View File

@@ -1,6 +1,6 @@
// Generated by CoffeeScript 1.5.0-pre
// Generated by CoffeeScript 1.5.0
(function() {
var Access, Arr, Assign, Base, Block, Call, Class, Closure, Code, Comment, Existence, Extends, For, IDENTIFIER, IDENTIFIER_STR, IS_STRING, If, In, Index, LEVEL_ACCESS, LEVEL_COND, LEVEL_LIST, LEVEL_OP, LEVEL_PAREN, LEVEL_TOP, Literal, METHOD_DEF, NEGATE, NO, Obj, Op, Param, Parens, RESERVED, Range, Return, SIMPLENUM, STRICT_PROSCRIBED, Scope, Slice, Splat, Switch, TAB, THIS, Throw, Try, UTILITIES, Value, While, YES, compact, del, ends, extend, flatten, last, merge, multident, some, starts, unfoldSoak, utility, _ref, _ref1,
var Access, Arr, Assign, Base, Block, Call, Class, Closure, Code, Comment, Existence, Extends, For, IDENTIFIER, IDENTIFIER_STR, IS_STRING, If, In, Index, LEVEL_ACCESS, LEVEL_COND, LEVEL_LIST, LEVEL_OP, LEVEL_PAREN, LEVEL_TOP, Literal, METHOD_DEF, NEGATE, NO, Obj, Op, Param, Parens, RESERVED, Range, Return, SIMPLENUM, STRICT_PROSCRIBED, Scope, Slice, Splat, Switch, TAB, THIS, Throw, Try, UTILITIES, Value, While, YES, addLocationDataFn, compact, del, ends, extend, flatten, last, locationDataToString, merge, multident, some, starts, unfoldSoak, utility, _ref, _ref1,
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
@@ -9,10 +9,12 @@
_ref = require('./lexer'), RESERVED = _ref.RESERVED, STRICT_PROSCRIBED = _ref.STRICT_PROSCRIBED;
_ref1 = require('./helpers'), compact = _ref1.compact, flatten = _ref1.flatten, extend = _ref1.extend, merge = _ref1.merge, del = _ref1.del, starts = _ref1.starts, ends = _ref1.ends, last = _ref1.last, some = _ref1.some;
_ref1 = require('./helpers'), compact = _ref1.compact, flatten = _ref1.flatten, extend = _ref1.extend, merge = _ref1.merge, del = _ref1.del, starts = _ref1.starts, ends = _ref1.ends, last = _ref1.last, some = _ref1.some, addLocationDataFn = _ref1.addLocationDataFn, locationDataToString = _ref1.locationDataToString;
exports.extend = extend;
exports.addLocationDataFn = addLocationDataFn;
YES = function() {
return true;
};
@@ -73,15 +75,6 @@
}
};
Base.prototype.compileLoopReference = function(o, name) {
var src, tmp;
src = tmp = this.compile(o, LEVEL_LIST);
if (!((-Infinity < +src && +src < Infinity) || IDENTIFIER.test(src) && o.scope.check(src, true))) {
src = "" + (tmp = o.scope.freeVariable(name)) + " = " + src;
}
return [src, tmp];
};
Base.prototype.makeReturn = function(res) {
var me;
me = this.unwrapAll();
@@ -122,14 +115,15 @@
};
Base.prototype.toString = function(idt, name) {
var tree;
var location, tree;
if (idt == null) {
idt = '';
}
if (name == null) {
name = this.constructor.name;
}
tree = '\n' + idt + name;
location = this.locationData ? locationDataToString(this.locationData) : "??";
tree = '\n' + idt + location + ": " + name;
if (this.soak) {
tree += '?';
}
@@ -170,7 +164,7 @@
};
Base.prototype.invert = function() {
return new Op('!', this);
return Op.create('!', this);
};
Base.prototype.unwrapAll = function() {
@@ -200,6 +194,16 @@
Base.prototype.assigns = NO;
Base.prototype.updateLocationDataIfMissing = function(locationData) {
if (!this.locationData) {
this.locationData = {};
extend(this.locationData, locationData);
}
return this.eachChild(function(child) {
return child.updateLocationDataIfMissing(locationData);
});
};
return Base;
})();
@@ -484,7 +488,7 @@
__extends(Undefined, _super);
function Undefined() {
return Undefined.__super__.constructor.apply(this, arguments);
Undefined.__super__.constructor.apply(this, arguments);
}
Undefined.prototype.isAssignable = NO;
@@ -508,7 +512,7 @@
__extends(Null, _super);
function Null() {
return Null.__super__.constructor.apply(this, arguments);
Null.__super__.constructor.apply(this, arguments);
}
Null.prototype.isAssignable = NO;
@@ -583,16 +587,21 @@
__extends(Value, _super);
function Value(base, props, tag) {
Value.wrap = function(base, props, tag) {
if (!props && base instanceof Value) {
return base;
} else {
return new Value(base, props, tag);
}
};
function Value(base, properties, tag) {
this.base = base;
this.properties = props || [];
if (tag) {
this[tag] = true;
this.properties = properties;
this.properties || (this.properties = []);
if (tag === 'this') {
this["this"] = true;
}
return this;
}
Value.prototype.children = ['base', 'properties'];
@@ -675,10 +684,10 @@
if (this.properties.length < 2 && !this.base.isComplex() && !(name != null ? name.isComplex() : void 0)) {
return [this, this];
}
base = new Value(this.base, this.properties.slice(0, -1));
base = Value.wrap(this.base, this.properties.slice(0, -1));
if (base.isComplex()) {
bref = new Literal(o.scope.freeVariable('base'));
base = new Value(new Parens(new Assign(bref, base)));
base = Value.wrap(new Parens(new Assign(bref, base)));
}
if (!name) {
return [base, bref];
@@ -688,7 +697,7 @@
name = new Index(new Assign(nref, name.index));
nref = new Index(nref);
}
return [base.add(name), new Value(bref || base.base, [nref || name])];
return [base.add(name), Value.wrap(bref || base.base, [nref || name])];
};
Value.prototype.compileNode = function(o) {
@@ -707,26 +716,23 @@
};
Value.prototype.unfoldSoak = function(o) {
var result,
var _ref2,
_this = this;
if (this.unfoldedSoak != null) {
return this.unfoldedSoak;
}
result = (function() {
var fst, i, ifn, prop, ref, snd, _i, _len, _ref2;
return (_ref2 = this.unfoldedSoak) != null ? _ref2 : this.unfoldedSoak = (function() {
var fst, i, ifn, prop, ref, snd, _i, _len, _ref3, _ref4;
if (ifn = _this.base.unfoldSoak(o)) {
Array.prototype.push.apply(ifn.body.properties, _this.properties);
(_ref3 = ifn.body.properties).push.apply(_ref3, _this.properties);
return ifn;
}
_ref2 = _this.properties;
for (i = _i = 0, _len = _ref2.length; _i < _len; i = ++_i) {
prop = _ref2[i];
_ref4 = _this.properties;
for (i = _i = 0, _len = _ref4.length; _i < _len; i = ++_i) {
prop = _ref4[i];
if (!prop.soak) {
continue;
}
prop.soak = false;
fst = new Value(_this.base, _this.properties.slice(0, i));
snd = new Value(_this.base, _this.properties.slice(i));
fst = Value.wrap(_this.base, _this.properties.slice(0, i));
snd = Value.wrap(_this.base, _this.properties.slice(i));
if (fst.isComplex()) {
ref = new Literal(o.scope.freeVariable('ref'));
fst = new Parens(new Assign(ref, fst));
@@ -736,9 +742,8 @@
soak: true
});
}
return null;
return false;
})();
return this.unfoldedSoak = result || false;
};
return Value;
@@ -811,7 +816,7 @@
accesses.push(new Access(new Literal('constructor')));
}
accesses.push(new Access(new Literal(name)));
return (new Value(new Literal(method.klass), accesses)).compile(o);
return (Value.wrap(new Literal(method.klass), accesses)).compile(o);
} else {
return "" + name + ".__super__.constructor";
}
@@ -830,15 +835,15 @@
if (ifn = unfoldSoak(o, this, 'variable')) {
return ifn;
}
_ref2 = new Value(this.variable).cacheReference(o), left = _ref2[0], rite = _ref2[1];
_ref2 = Value.wrap(this.variable).cacheReference(o), left = _ref2[0], rite = _ref2[1];
} else {
left = new Literal(this.superReference(o));
rite = new Value(left);
rite = Value.wrap(left);
}
rite = new Call(rite, this.args);
rite.isNew = this.isNew;
left = new Literal("typeof " + (left.compile(o)) + " === \"function\"");
return new If(left, new Value(rite), {
return new If(left, Value.wrap(rite), {
soak: true
});
}
@@ -925,10 +930,6 @@
}
};
Call.prototype.compileSuper = function(args, o) {
return "" + (this.superReference(o)) + ".call(" + (this.superThis(o)) + (args.length ? ', ' : '') + args + ")";
};
Call.prototype.compileSplat = function(o, splatArgs) {
var base, fun, idt, name, ref;
if (this.isSuper) {
@@ -938,7 +939,7 @@
idt = this.tab + TAB;
return "(function(func, args, ctor) {\n" + idt + "ctor.prototype = func.prototype;\n" + idt + "var child = new ctor, result = func.apply(child, args);\n" + idt + "return Object(result) === result ? result : child;\n" + this.tab + "})(" + (this.variable.compile(o, LEVEL_LIST)) + ", " + splatArgs + ", function(){})";
}
base = new Value(this.variable);
base = Value.wrap(this.variable);
if ((name = base.properties.pop()) && base.isComplex()) {
ref = o.scope.freeVariable('ref');
fun = "(" + ref + " = " + (base.compile(o, LEVEL_LIST)) + ")" + (name.compile(o));
@@ -973,7 +974,7 @@
Extends.prototype.children = ['child', 'parent'];
Extends.prototype.compile = function(o) {
return new Call(new Value(new Literal(utility('extends'))), [this.child, this.parent]).compile(o);
return new Call(Value.wrap(new Literal(utility('extends'))), [this.child, this.parent]).compile(o);
};
return Extends;
@@ -1079,7 +1080,7 @@
varPart += ", " + this.step;
}
_ref2 = ["" + idx + " <" + this.equals, "" + idx + " >" + this.equals], lt = _ref2[0], gt = _ref2[1];
condPart = this.stepNum ? +this.stepNum > 0 ? "" + lt + " " + this.toVar : "" + gt + " " + this.toVar : known ? ((_ref3 = [+this.fromNum, +this.toNum], from = _ref3[0], to = _ref3[1], _ref3), from <= to ? "" + lt + " " + to : "" + gt + " " + to) : (cond = "" + this.fromVar + " <= " + this.toVar, "" + cond + " ? " + lt + " " + this.toVar + " : " + gt + " " + this.toVar);
condPart = this.stepNum ? +this.stepNum > 0 ? "" + lt + " " + this.toVar : "" + gt + " " + this.toVar : known ? ((_ref3 = [+this.fromNum, +this.toNum], from = _ref3[0], to = _ref3[1], _ref3), from <= to ? "" + lt + " " + to : "" + gt + " " + to) : (cond = this.stepVar ? "" + this.stepVar + " > 0" : "" + this.fromVar + " <= " + this.toVar, "" + cond + " ? " + lt + " " + this.toVar + " : " + gt + " " + this.toVar);
stepPart = this.stepVar ? "" + idx + " += " + this.stepVar : known ? namedIndex ? from <= to ? "++" + idx : "--" + idx : from <= to ? "" + idx + "++" : "" + idx + "--" : namedIndex ? "" + cond + " ? ++" + idx + " : --" + idx : "" + cond + " ? " + idx + "++ : " + idx + "--";
if (namedIndex) {
varPart = "" + idxName + " = " + varPart;
@@ -1326,16 +1327,12 @@
};
Class.prototype.addBoundFunctions = function(o) {
var bvar, lhs, _i, _len, _ref2, _results;
if (this.boundFuncs.length) {
_ref2 = this.boundFuncs;
_results = [];
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
bvar = _ref2[_i];
lhs = (new Value(new Literal("this"), [new Access(bvar)])).compile(o);
_results.push(this.ctor.body.unshift(new Literal("" + lhs + " = " + (utility('bind')) + "(" + lhs + ", this)")));
}
return _results;
var bvar, lhs, _i, _len, _ref2;
_ref2 = this.boundFuncs;
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
bvar = _ref2[_i];
lhs = (Value.wrap(new Literal("this"), [new Access(bvar)])).compile(o);
this.ctor.body.unshift(new Literal("" + lhs + " = " + (utility('bind')) + "(" + lhs + ", this)"));
}
};
@@ -1370,7 +1367,7 @@
func.context = name;
}
} else {
assign.variable = new Value(new Literal(name), [new Access(new Literal('prototype')), new Access(base)]);
assign.variable = Value.wrap(new Literal(name), [new Access(new Literal('prototype')), new Access(base)]);
if (func instanceof Code && func.bound) {
this.boundFuncs.push(base);
func.bound = false;
@@ -1415,7 +1412,8 @@
return this.directives = expressions.splice(0, index);
};
Class.prototype.ensureConstructor = function(name) {
Class.prototype.ensureConstructor = function(name, o) {
var returnExpr;
if (!this.ctor) {
this.ctor = new Code;
if (this.parent) {
@@ -1424,12 +1422,20 @@
if (this.externalCtor) {
this.ctor.body.push(new Literal("" + this.externalCtor + ".apply(this, arguments)"));
}
this.ctor.body.makeReturn();
this.body.expressions.unshift(this.ctor);
}
this.ctor.ctor = this.ctor.name = name;
this.ctor.klass = null;
return this.ctor.noReturn = true;
this.ctor.noReturn = true;
returnExpr = null;
this.ctor.body.traverseChildren(false, function(node) {
if (node instanceof Return && (returnExpr = node.expression)) {
return false;
}
});
if (returnExpr) {
throw SyntaxError("cannot return a value from a constructor: \"" + (returnExpr.compileNode(o)) + "\" in class " + name);
}
};
Class.prototype.compileNode = function(o) {
@@ -1443,7 +1449,7 @@
this.hoistDirectivePrologue();
this.setContext(name);
this.walkBody(name, o);
this.ensureConstructor(name);
this.ensureConstructor(name, o);
this.body.spaced = true;
if (!(this.ctor instanceof Code)) {
this.body.expressions.unshift(this.ctor);
@@ -1546,7 +1552,7 @@
};
Assign.prototype.compilePatternMatch = function(o) {
var acc, assigns, code, i, idx, isObject, ivar, name, obj, objects, olen, ref, rest, splat, top, val, value, vvar, _i, _len, _ref2, _ref3, _ref4, _ref5, _ref6, _ref7, _ref8;
var acc, assigns, code, i, idx, isObject, ivar, name, obj, objects, olen, ref, rest, splat, top, val, value, vvar, _i, _len, _ref2, _ref3, _ref4, _ref5, _ref6, _ref7;
top = o.level === LEVEL_TOP;
value = this.value;
objects = this.variable.base.objects;
@@ -1563,16 +1569,12 @@
if (obj instanceof Assign) {
_ref2 = obj, (_ref3 = _ref2.variable, idx = _ref3.base), obj = _ref2.value;
} else {
if (obj.base instanceof Parens) {
_ref4 = new Value(obj.unwrapAll()).cacheReference(o), obj = _ref4[0], idx = _ref4[1];
} else {
idx = isObject ? obj["this"] ? obj.properties[0].name : obj : new Literal(0);
}
idx = isObject ? obj["this"] ? obj.properties[0].name : obj : new Literal(0);
}
acc = IDENTIFIER.test(idx.unwrap().value || 0);
value = new Value(value);
value = Value.wrap(value);
value.properties.push(new (acc ? Access : Index)(idx));
if (_ref5 = obj.unwrap().value, __indexOf.call(RESERVED, _ref5) >= 0) {
if (_ref4 = obj.unwrap().value, __indexOf.call(RESERVED, _ref4) >= 0) {
throw new SyntaxError("assignment to a reserved word: " + (obj.compile(o)) + " = " + (value.compile(o)));
}
return new Assign(obj, value, null, {
@@ -1591,10 +1593,10 @@
idx = i;
if (isObject) {
if (obj instanceof Assign) {
_ref6 = obj, (_ref7 = _ref6.variable, idx = _ref7.base), obj = _ref6.value;
_ref5 = obj, (_ref6 = _ref5.variable, idx = _ref6.base), obj = _ref5.value;
} else {
if (obj.base instanceof Parens) {
_ref8 = new Value(obj.unwrapAll()).cacheReference(o), obj = _ref8[0], idx = _ref8[1];
_ref7 = Value.wrap(obj.unwrapAll()).cacheReference(o), obj = _ref7[0], idx = _ref7[1];
} else {
idx = obj["this"] ? obj.properties[0].name : obj;
}
@@ -1624,7 +1626,7 @@
} else {
acc = isObject && IDENTIFIER.test(idx.unwrap().value || 0);
}
val = new Value(new Literal(vvar), [new (acc ? Access : Index)(idx)]);
val = Value.wrap(new Literal(vvar), [new (acc ? Access : Index)(idx)]);
}
if ((name != null) && __indexOf.call(RESERVED, name) >= 0) {
throw new SyntaxError("assignment to a reserved word: " + (obj.compile(o)) + " = " + (val.compile(o)));
@@ -1654,7 +1656,7 @@
if (__indexOf.call(this.context, "?") >= 0) {
o.isExistentialEquals = true;
}
return new Op(this.context.slice(0, -1), left, new Assign(right, this.value, '=')).compile(o);
return Op.create(this.context.slice(0, -1), left, new Assign(right, this.value, '=')).compile(o);
};
Assign.prototype.compileSplice = function(o) {
@@ -1743,7 +1745,7 @@
o.scope.add(p.value, 'var', true);
}
}
splats = new Assign(new Value(new Arr((function() {
splats = new Assign(Value.wrap(new Arr((function() {
var _l, _len3, _ref5, _results;
_ref5 = this.params;
_results = [];
@@ -1752,7 +1754,7 @@
_results.push(p.asReference(o));
}
return _results;
}).call(this))), new Value(new Literal('arguments')));
}).call(this))), Value.wrap(new Literal('arguments')));
break;
}
_ref5 = this.params;
@@ -1761,16 +1763,16 @@
if (param.isComplex()) {
val = ref = param.asReference(o);
if (param.value) {
val = new Op('?', ref, param.value);
val = Op.create('?', ref, param.value);
}
exprs.push(new Assign(new Value(param.name), val, '=', {
exprs.push(new Assign(Value.wrap(param.name), val, '=', {
param: true
}));
} else {
ref = param;
if (param.value) {
lit = new Literal(ref.name.value + ' == null');
val = new Assign(new Value(param.name), param.value, '=');
val = new Assign(Value.wrap(param.name), param.value, '=');
exprs.push(new If(lit, val));
}
}
@@ -1883,7 +1885,7 @@
} else if (node.isComplex()) {
node = new Literal(o.scope.freeVariable('arg'));
}
node = new Value(node);
node = Value.wrap(node);
if (this.splat) {
node = new Splat(node);
}
@@ -1958,11 +1960,7 @@
};
Splat.prototype.compile = function(o) {
if (this.index != null) {
return this.compileParam(o);
} else {
return this.name.compile(o);
}
return this.name.compile(o);
};
Splat.prototype.unwrap = function() {
@@ -2096,7 +2094,7 @@
__extends(Op, _super);
function Op(op, first, second, flip) {
Op.create = function(op, first, second, flip) {
if (op === 'in') {
return new In(first, second);
}
@@ -2111,11 +2109,14 @@
first = new Parens(first);
}
}
this.operator = CONVERSIONS[op] || op;
return new Op(op, first, second, flip);
};
function Op(op, first, second, flip) {
this.first = first;
this.second = second;
this.operator = CONVERSIONS[op] || op;
this.flip = !!flip;
return this;
}
CONVERSIONS = {
@@ -2177,7 +2178,7 @@
} else if (this.operator === '!' && (fst = this.first.unwrap()) instanceof Op && ((_ref2 = fst.operator) === '!' || _ref2 === 'in' || _ref2 === 'instanceof')) {
return fst;
} else {
return new Op('!', this);
return Op.create('!', this);
}
};
@@ -2186,7 +2187,7 @@
return ((_ref2 = this.operator) === '++' || _ref2 === '--' || _ref2 === 'delete') && unfoldSoak(o, this, 'first');
};
Op.prototype.generateDo = function(exp) {
Op.generateDo = function(exp) {
var call, func, param, passedParams, ref, _i, _len, _ref2;
passedParams = [];
func = exp instanceof Assign && (ref = exp.value.unwrap()) instanceof Code ? ref : exp;
@@ -2554,7 +2555,7 @@
For.prototype.children = ['body', 'source', 'guard', 'step'];
For.prototype.compileNode = function(o) {
var body, defPart, forPart, forVarPart, guardPart, idt1, index, ivar, kvar, kvarAssign, lastJumps, lvar, name, namePart, ref, resultPart, returnResult, rvar, scope, source, stepPart, stepvar, svar, varPart, _ref2;
var body, compare, compareDown, declare, declareDown, defPart, down, forPart, guardPart, idt1, increment, index, ivar, kvar, kvarAssign, lastJumps, lvar, name, namePart, ref, resultPart, returnResult, rvar, scope, source, step, stepNum, stepVar, svar, varPart, _ref2, _ref3;
body = Block.wrap([this.body]);
lastJumps = (_ref2 = last(body.expressions)) != null ? _ref2.jumps() : void 0;
if (lastJumps && lastJumps instanceof Return) {
@@ -2577,7 +2578,8 @@
kvar = (this.range && name) || index || ivar;
kvarAssign = kvar !== ivar ? "" + kvar + " = " : "";
if (this.step && !this.range) {
stepvar = scope.freeVariable("step");
_ref3 = this.step.cache(o, LEVEL_LIST), step = _ref3[0], stepVar = _ref3[1];
stepNum = stepVar.match(SIMPLENUM);
}
if (this.pattern) {
name = ivar;
@@ -2595,20 +2597,38 @@
} else {
svar = this.source.compile(o, LEVEL_LIST);
if ((name || this.own) && !IDENTIFIER.test(svar)) {
defPart = "" + this.tab + (ref = scope.freeVariable('ref')) + " = " + svar + ";\n";
defPart += "" + this.tab + (ref = scope.freeVariable('ref')) + " = " + svar + ";\n";
svar = ref;
}
if (name && !this.pattern) {
namePart = "" + name + " = " + svar + "[" + kvar + "]";
}
if (!this.object) {
lvar = scope.freeVariable('len');
forVarPart = "" + kvarAssign + ivar + " = 0, " + lvar + " = " + svar + ".length";
if (this.step) {
forVarPart += ", " + stepvar + " = " + (this.step.compile(o, LEVEL_OP));
if (step !== stepVar) {
defPart += "" + this.tab + step + ";\n";
}
stepPart = "" + kvarAssign + (this.step ? "" + ivar + " += " + stepvar : (kvar !== ivar ? "++" + ivar : "" + ivar + "++"));
forPart = "" + forVarPart + "; " + ivar + " < " + lvar + "; " + stepPart;
if (!(this.step && stepNum && (down = +stepNum < 0))) {
lvar = scope.freeVariable('len');
}
declare = "" + kvarAssign + ivar + " = 0, " + lvar + " = " + svar + ".length";
declareDown = "" + kvarAssign + ivar + " = " + svar + ".length - 1";
compare = "" + ivar + " < " + lvar;
compareDown = "" + ivar + " >= 0";
if (this.step) {
if (stepNum) {
if (down) {
compare = compareDown;
declare = declareDown;
}
} else {
compare = "" + stepVar + " > 0 ? " + compare + " : " + compareDown;
declare = "(" + stepVar + " > 0 ? (" + declare + ") : " + declareDown + ")";
}
increment = "" + ivar + " += " + stepVar;
} else {
increment = "" + (kvar !== ivar ? "++" + ivar : "" + ivar + "++");
}
forPart = "" + declare + "; " + compare + "; " + kvarAssign + increment;
}
}
if (this.returns) {
@@ -2663,7 +2683,7 @@
}
fn = ((_ref6 = val.base) != null ? _ref6.unwrapAll() : void 0) || val;
ref = new Literal(o.scope.freeVariable('fn'));
base = new Value(ref);
base = Value.wrap(ref);
if (val.base) {
_ref7 = [base, val], val.base = _ref7[0], base = _ref7[1];
}
@@ -2894,7 +2914,7 @@
if (mentionsArgs) {
args.push(new Literal('arguments'));
}
func = new Value(func, [new Access(meth)]);
func = Value.wrap(func, [new Access(meth)]);
}
func.noReturn = noReturn;
call = new Call(func, args);
@@ -2918,7 +2938,7 @@
return;
}
parent[name] = ifn.body;
ifn.body = new Value(parent);
ifn.body = Value.wrap(parent);
return ifn;
};

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.5.0-pre
// Generated by CoffeeScript 1.5.0
(function() {
var LONG_FLAG, MULTI_FLAG, OPTIONAL, OptionParser, SHORT_FLAG, buildRule, buildRules, normalizeArguments;

View File

@@ -9,15 +9,15 @@ performAction: function anonymous(yytext,yyleng,yylineno,yy,yystate,$$,_$) {
var $0 = $$.length - 1;
switch (yystate) {
case 1:return this.$ = new yy.Block;
case 1:return this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Block);
break;
case 2:return this.$ = $$[$0];
break;
case 3:return this.$ = $$[$0-1];
break;
case 4:this.$ = yy.Block.wrap([$$[$0]]);
case 4:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(yy.Block.wrap([$$[$0]]));
break;
case 5:this.$ = $$[$0-2].push($$[$0]);
case 5:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])($$[$0-2].push($$[$0]));
break;
case 6:this.$ = $$[$0-1];
break;
@@ -29,7 +29,7 @@ case 9:this.$ = $$[$0];
break;
case 10:this.$ = $$[$0];
break;
case 11:this.$ = new yy.Literal($$[$0]);
case 11:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Literal($$[$0]));
break;
case 12:this.$ = $$[$0];
break;
@@ -55,41 +55,41 @@ case 22:this.$ = $$[$0];
break;
case 23:this.$ = $$[$0];
break;
case 24:this.$ = new yy.Block;
case 24:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Block);
break;
case 25:this.$ = $$[$0-1];
case 25:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])($$[$0-1]);
break;
case 26:this.$ = new yy.Literal($$[$0]);
case 26:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Literal($$[$0]));
break;
case 27:this.$ = new yy.Literal($$[$0]);
case 27:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Literal($$[$0]));
break;
case 28:this.$ = new yy.Literal($$[$0]);
case 28:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Literal($$[$0]));
break;
case 29:this.$ = $$[$0];
break;
case 30:this.$ = new yy.Literal($$[$0]);
case 30:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Literal($$[$0]));
break;
case 31:this.$ = new yy.Literal($$[$0]);
case 31:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Literal($$[$0]));
break;
case 32:this.$ = new yy.Literal($$[$0]);
case 32:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Literal($$[$0]));
break;
case 33:this.$ = new yy.Undefined;
case 33:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Undefined);
break;
case 34:this.$ = new yy.Null;
case 34:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Null);
break;
case 35:this.$ = new yy.Bool($$[$0]);
case 35:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Bool($$[$0]));
break;
case 36:this.$ = new yy.Assign($$[$0-2], $$[$0]);
case 36:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Assign($$[$0-2], $$[$0]));
break;
case 37:this.$ = new yy.Assign($$[$0-3], $$[$0]);
case 37:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])(new yy.Assign($$[$0-3], $$[$0]));
break;
case 38:this.$ = new yy.Assign($$[$0-4], $$[$0-1]);
case 38:this.$ = yy.addLocationDataFn(_$[$0-4], _$[$0])(new yy.Assign($$[$0-4], $$[$0-1]));
break;
case 39:this.$ = new yy.Value($$[$0]);
case 39:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(yy.Value.wrap($$[$0]));
break;
case 40:this.$ = new yy.Assign(new yy.Value($$[$0-2]), $$[$0], 'object');
case 40:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Assign(yy.addLocationDataFn(_$[$0-2])(yy.Value.wrap($$[$0-2])), $$[$0], 'object'));
break;
case 41:this.$ = new yy.Assign(new yy.Value($$[$0-4]), $$[$0-1], 'object');
case 41:this.$ = yy.addLocationDataFn(_$[$0-4], _$[$0])(new yy.Assign(yy.addLocationDataFn(_$[$0-4])(yy.Value.wrap($$[$0-4])), $$[$0-1], 'object'));
break;
case 42:this.$ = $$[$0];
break;
@@ -99,39 +99,39 @@ case 44:this.$ = $$[$0];
break;
case 45:this.$ = $$[$0];
break;
case 46:this.$ = new yy.Return($$[$0]);
case 46:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Return($$[$0]));
break;
case 47:this.$ = new yy.Return;
case 47:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Return);
break;
case 48:this.$ = new yy.Comment($$[$0]);
case 48:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Comment($$[$0]));
break;
case 49:this.$ = new yy.Code($$[$0-3], $$[$0], $$[$0-1]);
case 49:this.$ = yy.addLocationDataFn(_$[$0-4], _$[$0])(new yy.Code($$[$0-3], $$[$0], $$[$0-1]));
break;
case 50:this.$ = new yy.Code([], $$[$0], $$[$0-1]);
case 50:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Code([], $$[$0], $$[$0-1]));
break;
case 51:this.$ = 'func';
case 51:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])('func');
break;
case 52:this.$ = 'boundfunc';
case 52:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])('boundfunc');
break;
case 53:this.$ = $$[$0];
break;
case 54:this.$ = $$[$0];
break;
case 55:this.$ = [];
case 55:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])([]);
break;
case 56:this.$ = [$$[$0]];
case 56:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])([$$[$0]]);
break;
case 57:this.$ = $$[$0-2].concat($$[$0]);
case 57:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])($$[$0-2].concat($$[$0]));
break;
case 58:this.$ = $$[$0-3].concat($$[$0]);
case 58:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])($$[$0-3].concat($$[$0]));
break;
case 59:this.$ = $$[$0-5].concat($$[$0-2]);
case 59:this.$ = yy.addLocationDataFn(_$[$0-5], _$[$0])($$[$0-5].concat($$[$0-2]));
break;
case 60:this.$ = new yy.Param($$[$0]);
case 60:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Param($$[$0]));
break;
case 61:this.$ = new yy.Param($$[$0-1], null, true);
case 61:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Param($$[$0-1], null, true));
break;
case 62:this.$ = new yy.Param($$[$0-2], $$[$0]);
case 62:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Param($$[$0-2], $$[$0]));
break;
case 63:this.$ = $$[$0];
break;
@@ -141,129 +141,129 @@ case 65:this.$ = $$[$0];
break;
case 66:this.$ = $$[$0];
break;
case 67:this.$ = new yy.Splat($$[$0-1]);
case 67:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Splat($$[$0-1]));
break;
case 68:this.$ = new yy.Value($$[$0]);
case 68:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(yy.Value.wrap($$[$0]));
break;
case 69:this.$ = $$[$0-1].add($$[$0]);
case 69:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])($$[$0-1].add($$[$0]));
break;
case 70:this.$ = new yy.Value($$[$0-1], [].concat($$[$0]));
case 70:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(yy.Value.wrap($$[$0-1], [].concat($$[$0])));
break;
case 71:this.$ = $$[$0];
break;
case 72:this.$ = $$[$0];
break;
case 73:this.$ = new yy.Value($$[$0]);
case 73:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(yy.Value.wrap($$[$0]));
break;
case 74:this.$ = new yy.Value($$[$0]);
case 74:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(yy.Value.wrap($$[$0]));
break;
case 75:this.$ = $$[$0];
break;
case 76:this.$ = new yy.Value($$[$0]);
case 76:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(yy.Value.wrap($$[$0]));
break;
case 77:this.$ = new yy.Value($$[$0]);
case 77:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(yy.Value.wrap($$[$0]));
break;
case 78:this.$ = new yy.Value($$[$0]);
case 78:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(yy.Value.wrap($$[$0]));
break;
case 79:this.$ = $$[$0];
break;
case 80:this.$ = new yy.Access($$[$0]);
case 80:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Access($$[$0]));
break;
case 81:this.$ = new yy.Access($$[$0], 'soak');
case 81:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Access($$[$0], 'soak'));
break;
case 82:this.$ = [new yy.Access(new yy.Literal('prototype')), new yy.Access($$[$0])];
case 82:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])([yy.addLocationDataFn(_$[$0-1])(new yy.Access(new yy.Literal('prototype'))), yy.addLocationDataFn(_$[$0])(new yy.Access($$[$0]))]);
break;
case 83:this.$ = new yy.Access(new yy.Literal('prototype'));
case 83:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Access(new yy.Literal('prototype')));
break;
case 84:this.$ = $$[$0];
break;
case 85:this.$ = $$[$0-1];
case 85:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])($$[$0-1]);
break;
case 86:this.$ = yy.extend($$[$0], {
case 86:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(yy.extend($$[$0], {
soak: true
});
}));
break;
case 87:this.$ = new yy.Index($$[$0]);
case 87:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Index($$[$0]));
break;
case 88:this.$ = new yy.Slice($$[$0]);
case 88:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Slice($$[$0]));
break;
case 89:this.$ = new yy.Obj($$[$0-2], $$[$0-3].generated);
case 89:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])(new yy.Obj($$[$0-2], $$[$0-3].generated));
break;
case 90:this.$ = [];
case 90:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])([]);
break;
case 91:this.$ = [$$[$0]];
case 91:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])([$$[$0]]);
break;
case 92:this.$ = $$[$0-2].concat($$[$0]);
case 92:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])($$[$0-2].concat($$[$0]));
break;
case 93:this.$ = $$[$0-3].concat($$[$0]);
case 93:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])($$[$0-3].concat($$[$0]));
break;
case 94:this.$ = $$[$0-5].concat($$[$0-2]);
case 94:this.$ = yy.addLocationDataFn(_$[$0-5], _$[$0])($$[$0-5].concat($$[$0-2]));
break;
case 95:this.$ = new yy.Class;
case 95:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Class);
break;
case 96:this.$ = new yy.Class(null, null, $$[$0]);
case 96:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Class(null, null, $$[$0]));
break;
case 97:this.$ = new yy.Class(null, $$[$0]);
case 97:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Class(null, $$[$0]));
break;
case 98:this.$ = new yy.Class(null, $$[$0-1], $$[$0]);
case 98:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])(new yy.Class(null, $$[$0-1], $$[$0]));
break;
case 99:this.$ = new yy.Class($$[$0]);
case 99:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Class($$[$0]));
break;
case 100:this.$ = new yy.Class($$[$0-1], null, $$[$0]);
case 100:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Class($$[$0-1], null, $$[$0]));
break;
case 101:this.$ = new yy.Class($$[$0-2], $$[$0]);
case 101:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])(new yy.Class($$[$0-2], $$[$0]));
break;
case 102:this.$ = new yy.Class($$[$0-3], $$[$0-1], $$[$0]);
case 102:this.$ = yy.addLocationDataFn(_$[$0-4], _$[$0])(new yy.Class($$[$0-3], $$[$0-1], $$[$0]));
break;
case 103:this.$ = new yy.Call($$[$0-2], $$[$0], $$[$0-1]);
case 103:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Call($$[$0-2], $$[$0], $$[$0-1]));
break;
case 104:this.$ = new yy.Call($$[$0-2], $$[$0], $$[$0-1]);
case 104:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Call($$[$0-2], $$[$0], $$[$0-1]));
break;
case 105:this.$ = new yy.Call('super', [new yy.Splat(new yy.Literal('arguments'))]);
case 105:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Call('super', [new yy.Splat(new yy.Literal('arguments'))]));
break;
case 106:this.$ = new yy.Call('super', $$[$0]);
case 106:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Call('super', $$[$0]));
break;
case 107:this.$ = false;
case 107:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(false);
break;
case 108:this.$ = true;
case 108:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(true);
break;
case 109:this.$ = [];
case 109:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])([]);
break;
case 110:this.$ = $$[$0-2];
case 110:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])($$[$0-2]);
break;
case 111:this.$ = new yy.Value(new yy.Literal('this'));
case 111:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(yy.Value.wrap(new yy.Literal('this')));
break;
case 112:this.$ = new yy.Value(new yy.Literal('this'));
case 112:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(yy.Value.wrap(new yy.Literal('this')));
break;
case 113:this.$ = new yy.Value(new yy.Literal('this'), [new yy.Access($$[$0])], 'this');
case 113:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(yy.Value.wrap(yy.addLocationDataFn(_$[$0-1])(new yy.Literal('this')), [yy.addLocationDataFn(_$[$0])(new yy.Access($$[$0]))], 'this'));
break;
case 114:this.$ = new yy.Arr([]);
case 114:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Arr([]));
break;
case 115:this.$ = new yy.Arr($$[$0-2]);
case 115:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])(new yy.Arr($$[$0-2]));
break;
case 116:this.$ = 'inclusive';
case 116:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])('inclusive');
break;
case 117:this.$ = 'exclusive';
case 117:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])('exclusive');
break;
case 118:this.$ = new yy.Range($$[$0-3], $$[$0-1], $$[$0-2]);
case 118:this.$ = yy.addLocationDataFn(_$[$0-4], _$[$0])(new yy.Range($$[$0-3], $$[$0-1], $$[$0-2]));
break;
case 119:this.$ = new yy.Range($$[$0-2], $$[$0], $$[$0-1]);
case 119:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Range($$[$0-2], $$[$0], $$[$0-1]));
break;
case 120:this.$ = new yy.Range($$[$0-1], null, $$[$0]);
case 120:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Range($$[$0-1], null, $$[$0]));
break;
case 121:this.$ = new yy.Range(null, $$[$0], $$[$0-1]);
case 121:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Range(null, $$[$0], $$[$0-1]));
break;
case 122:this.$ = new yy.Range(null, null, $$[$0]);
case 122:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Range(null, null, $$[$0]));
break;
case 123:this.$ = [$$[$0]];
case 123:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])([$$[$0]]);
break;
case 124:this.$ = $$[$0-2].concat($$[$0]);
case 124:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])($$[$0-2].concat($$[$0]));
break;
case 125:this.$ = $$[$0-3].concat($$[$0]);
case 125:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])($$[$0-3].concat($$[$0]));
break;
case 126:this.$ = $$[$0-2];
case 126:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])($$[$0-2]);
break;
case 127:this.$ = $$[$0-5].concat($$[$0-2]);
case 127:this.$ = yy.addLocationDataFn(_$[$0-5], _$[$0])($$[$0-5].concat($$[$0-2]));
break;
case 128:this.$ = $$[$0];
break;
@@ -271,207 +271,207 @@ case 129:this.$ = $$[$0];
break;
case 130:this.$ = $$[$0];
break;
case 131:this.$ = [].concat($$[$0-2], $$[$0]);
case 131:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])([].concat($$[$0-2], $$[$0]));
break;
case 132:this.$ = new yy.Try($$[$0]);
case 132:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Try($$[$0]));
break;
case 133:this.$ = new yy.Try($$[$0-1], $$[$0][0], $$[$0][1]);
case 133:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Try($$[$0-1], $$[$0][0], $$[$0][1]));
break;
case 134:this.$ = new yy.Try($$[$0-2], null, null, $$[$0]);
case 134:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])(new yy.Try($$[$0-2], null, null, $$[$0]));
break;
case 135:this.$ = new yy.Try($$[$0-3], $$[$0-2][0], $$[$0-2][1], $$[$0]);
case 135:this.$ = yy.addLocationDataFn(_$[$0-4], _$[$0])(new yy.Try($$[$0-3], $$[$0-2][0], $$[$0-2][1], $$[$0]));
break;
case 136:this.$ = [$$[$0-1], $$[$0]];
case 136:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])([$$[$0-1], $$[$0]]);
break;
case 137:this.$ = [new yy.Value($$[$0-1]), $$[$0]];
case 137:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])([yy.addLocationDataFn(_$[$0-1])(yy.Value.wrap($$[$0-1])), $$[$0]]);
break;
case 138:this.$ = new yy.Throw($$[$0]);
case 138:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Throw($$[$0]));
break;
case 139:this.$ = new yy.Parens($$[$0-1]);
case 139:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Parens($$[$0-1]));
break;
case 140:this.$ = new yy.Parens($$[$0-2]);
case 140:this.$ = yy.addLocationDataFn(_$[$0-4], _$[$0])(new yy.Parens($$[$0-2]));
break;
case 141:this.$ = new yy.While($$[$0]);
case 141:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.While($$[$0]));
break;
case 142:this.$ = new yy.While($$[$0-2], {
case 142:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])(new yy.While($$[$0-2], {
guard: $$[$0]
});
}));
break;
case 143:this.$ = new yy.While($$[$0], {
case 143:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.While($$[$0], {
invert: true
});
}));
break;
case 144:this.$ = new yy.While($$[$0-2], {
case 144:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])(new yy.While($$[$0-2], {
invert: true,
guard: $$[$0]
}));
break;
case 145:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])($$[$0-1].addBody($$[$0]));
break;
case 146:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])($$[$0].addBody(yy.addLocationDataFn(_$[$0-1])(yy.Block.wrap([$$[$0-1]]))));
break;
case 147:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])($$[$0].addBody(yy.addLocationDataFn(_$[$0-1])(yy.Block.wrap([$$[$0-1]]))));
break;
case 148:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])($$[$0]);
break;
case 149:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.While(yy.addLocationDataFn(_$[$0-1])(new yy.Literal('true'))).addBody($$[$0]));
break;
case 150:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.While(yy.addLocationDataFn(_$[$0-1])(new yy.Literal('true'))).addBody(yy.addLocationDataFn(_$[$0])(yy.Block.wrap([$$[$0]]))));
break;
case 151:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.For($$[$0-1], $$[$0]));
break;
case 152:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.For($$[$0-1], $$[$0]));
break;
case 153:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.For($$[$0], $$[$0-1]));
break;
case 154:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])({
source: yy.addLocationDataFn(_$[$0])(yy.Value.wrap($$[$0]))
});
break;
case 145:this.$ = $$[$0-1].addBody($$[$0]);
break;
case 146:this.$ = $$[$0].addBody(yy.Block.wrap([$$[$0-1]]));
break;
case 147:this.$ = $$[$0].addBody(yy.Block.wrap([$$[$0-1]]));
break;
case 148:this.$ = $$[$0];
break;
case 149:this.$ = new yy.While(new yy.Literal('true')).addBody($$[$0]);
break;
case 150:this.$ = new yy.While(new yy.Literal('true')).addBody(yy.Block.wrap([$$[$0]]));
break;
case 151:this.$ = new yy.For($$[$0-1], $$[$0]);
break;
case 152:this.$ = new yy.For($$[$0-1], $$[$0]);
break;
case 153:this.$ = new yy.For($$[$0], $$[$0-1]);
break;
case 154:this.$ = {
source: new yy.Value($$[$0])
};
break;
case 155:this.$ = (function () {
case 155:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])((function () {
$$[$0].own = $$[$0-1].own;
$$[$0].name = $$[$0-1][0];
$$[$0].index = $$[$0-1][1];
return $$[$0];
}());
}()));
break;
case 156:this.$ = $$[$0];
case 156:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])($$[$0]);
break;
case 157:this.$ = (function () {
case 157:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])((function () {
$$[$0].own = true;
return $$[$0];
}());
}()));
break;
case 158:this.$ = $$[$0];
break;
case 159:this.$ = $$[$0];
break;
case 160:this.$ = new yy.Value($$[$0]);
case 160:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(yy.Value.wrap($$[$0]));
break;
case 161:this.$ = new yy.Value($$[$0]);
case 161:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(yy.Value.wrap($$[$0]));
break;
case 162:this.$ = [$$[$0]];
case 162:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])([$$[$0]]);
break;
case 163:this.$ = [$$[$0-2], $$[$0]];
case 163:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])([$$[$0-2], $$[$0]]);
break;
case 164:this.$ = {
case 164:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])({
source: $$[$0]
};
});
break;
case 165:this.$ = {
case 165:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])({
source: $$[$0],
object: true
};
});
break;
case 166:this.$ = {
case 166:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])({
source: $$[$0-2],
guard: $$[$0]
};
});
break;
case 167:this.$ = {
case 167:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])({
source: $$[$0-2],
guard: $$[$0],
object: true
};
});
break;
case 168:this.$ = {
case 168:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])({
source: $$[$0-2],
step: $$[$0]
};
});
break;
case 169:this.$ = {
case 169:this.$ = yy.addLocationDataFn(_$[$0-5], _$[$0])({
source: $$[$0-4],
guard: $$[$0-2],
step: $$[$0]
};
});
break;
case 170:this.$ = {
case 170:this.$ = yy.addLocationDataFn(_$[$0-5], _$[$0])({
source: $$[$0-4],
step: $$[$0-2],
guard: $$[$0]
};
});
break;
case 171:this.$ = new yy.Switch($$[$0-3], $$[$0-1]);
case 171:this.$ = yy.addLocationDataFn(_$[$0-4], _$[$0])(new yy.Switch($$[$0-3], $$[$0-1]));
break;
case 172:this.$ = new yy.Switch($$[$0-5], $$[$0-3], $$[$0-1]);
case 172:this.$ = yy.addLocationDataFn(_$[$0-6], _$[$0])(new yy.Switch($$[$0-5], $$[$0-3], $$[$0-1]));
break;
case 173:this.$ = new yy.Switch(null, $$[$0-1]);
case 173:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])(new yy.Switch(null, $$[$0-1]));
break;
case 174:this.$ = new yy.Switch(null, $$[$0-3], $$[$0-1]);
case 174:this.$ = yy.addLocationDataFn(_$[$0-5], _$[$0])(new yy.Switch(null, $$[$0-3], $$[$0-1]));
break;
case 175:this.$ = $$[$0];
break;
case 176:this.$ = $$[$0-1].concat($$[$0]);
case 176:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])($$[$0-1].concat($$[$0]));
break;
case 177:this.$ = [[$$[$0-1], $$[$0]]];
case 177:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])([[$$[$0-1], $$[$0]]]);
break;
case 178:this.$ = [[$$[$0-2], $$[$0-1]]];
case 178:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])([[$$[$0-2], $$[$0-1]]]);
break;
case 179:this.$ = new yy.If($$[$0-1], $$[$0], {
type: $$[$0-2]
});
break;
case 180:this.$ = $$[$0-4].addElse(new yy.If($$[$0-1], $$[$0], {
case 179:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.If($$[$0-1], $$[$0], {
type: $$[$0-2]
}));
break;
case 180:this.$ = yy.addLocationDataFn(_$[$0-4], _$[$0])($$[$0-4].addElse(new yy.If($$[$0-1], $$[$0], {
type: $$[$0-2]
})));
break;
case 181:this.$ = $$[$0];
break;
case 182:this.$ = $$[$0-2].addElse($$[$0]);
case 182:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])($$[$0-2].addElse($$[$0]));
break;
case 183:this.$ = new yy.If($$[$0], yy.Block.wrap([$$[$0-2]]), {
case 183:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.If($$[$0], yy.addLocationDataFn(_$[$0-2])(yy.Block.wrap([$$[$0-2]])), {
type: $$[$0-1],
statement: true
});
}));
break;
case 184:this.$ = new yy.If($$[$0], yy.Block.wrap([$$[$0-2]]), {
case 184:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.If($$[$0], yy.addLocationDataFn(_$[$0-2])(yy.Block.wrap([$$[$0-2]])), {
type: $$[$0-1],
statement: true
});
}));
break;
case 185:this.$ = new yy.Op($$[$0-1], $$[$0]);
case 185:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(yy.Op.create($$[$0-1], $$[$0]));
break;
case 186:this.$ = new yy.Op('-', $$[$0]);
case 186:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(yy.Op.create('-', $$[$0]));
break;
case 187:this.$ = new yy.Op('+', $$[$0]);
case 187:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(yy.Op.create('+', $$[$0]));
break;
case 188:this.$ = new yy.Op('--', $$[$0]);
case 188:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(yy.Op.create('--', $$[$0]));
break;
case 189:this.$ = new yy.Op('++', $$[$0]);
case 189:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(yy.Op.create('++', $$[$0]));
break;
case 190:this.$ = new yy.Op('--', $$[$0-1], null, true);
case 190:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(yy.Op.create('--', $$[$0-1], null, true));
break;
case 191:this.$ = new yy.Op('++', $$[$0-1], null, true);
case 191:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(yy.Op.create('++', $$[$0-1], null, true));
break;
case 192:this.$ = new yy.Existence($$[$0-1]);
case 192:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Existence($$[$0-1]));
break;
case 193:this.$ = new yy.Op('+', $$[$0-2], $$[$0]);
case 193:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(yy.Op.create('+', $$[$0-2], $$[$0]));
break;
case 194:this.$ = new yy.Op('-', $$[$0-2], $$[$0]);
case 194:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(yy.Op.create('-', $$[$0-2], $$[$0]));
break;
case 195:this.$ = new yy.Op($$[$0-1], $$[$0-2], $$[$0]);
case 195:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(yy.Op.create($$[$0-1], $$[$0-2], $$[$0]));
break;
case 196:this.$ = new yy.Op($$[$0-1], $$[$0-2], $$[$0]);
case 196:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(yy.Op.create($$[$0-1], $$[$0-2], $$[$0]));
break;
case 197:this.$ = new yy.Op($$[$0-1], $$[$0-2], $$[$0]);
case 197:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(yy.Op.create($$[$0-1], $$[$0-2], $$[$0]));
break;
case 198:this.$ = new yy.Op($$[$0-1], $$[$0-2], $$[$0]);
case 198:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(yy.Op.create($$[$0-1], $$[$0-2], $$[$0]));
break;
case 199:this.$ = (function () {
case 199:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])((function () {
if ($$[$0-1].charAt(0) === '!') {
return new yy.Op($$[$0-1].slice(1), $$[$0-2], $$[$0]).invert();
return yy.Op.create($$[$0-1].slice(1), $$[$0-2], $$[$0]).invert();
} else {
return new yy.Op($$[$0-1], $$[$0-2], $$[$0]);
return yy.Op.create($$[$0-1], $$[$0-2], $$[$0]);
}
}());
}()));
break;
case 200:this.$ = new yy.Assign($$[$0-2], $$[$0], $$[$0-1]);
case 200:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Assign($$[$0-2], $$[$0], $$[$0-1]));
break;
case 201:this.$ = new yy.Assign($$[$0-4], $$[$0-1], $$[$0-3]);
case 201:this.$ = yy.addLocationDataFn(_$[$0-4], _$[$0])(new yy.Assign($$[$0-4], $$[$0-1], $$[$0-3]));
break;
case 202:this.$ = new yy.Assign($$[$0-3], $$[$0], $$[$0-2]);
case 202:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])(new yy.Assign($$[$0-3], $$[$0], $$[$0-2]));
break;
case 203:this.$ = new yy.Extends($$[$0-2], $$[$0]);
case 203:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Extends($$[$0-2], $$[$0]));
break;
}
},

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.5.0-pre
// Generated by CoffeeScript 1.5.0
(function() {
var CoffeeScript, addMultilineHandler, merge, nodeREPL, replDefaults, vm;

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.5.0-pre
// Generated by CoffeeScript 1.5.0
(function() {
var BALANCED_PAIRS, EXPRESSION_CLOSE, EXPRESSION_END, EXPRESSION_START, IMPLICIT_BLOCK, IMPLICIT_CALL, IMPLICIT_END, IMPLICIT_FUNC, IMPLICIT_UNSPACED_CALL, INVERSES, LINEBREAKS, SINGLE_CLOSERS, SINGLE_LINERS, left, rite, _i, _len, _ref,
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; },
@@ -18,6 +18,7 @@
this.tagPostfixConditionals();
this.addImplicitBraces();
this.addImplicitParentheses();
this.addLocationDataToGeneratedTokens();
return this.tokens;
};
@@ -133,7 +134,7 @@
};
action = function(token, i) {
var tok;
tok = this.generate('}', '}', token[2]);
tok = this.generate('}', '}');
return this.tokens.splice(i, 0, tok);
};
return this.scanTokens(function(token, i, tokens) {
@@ -160,7 +161,7 @@
startsLine = !prevTag || (__indexOf.call(LINEBREAKS, prevTag) >= 0);
value = new String('{');
value.generated = true;
tok = this.generate('{', value, token[2]);
tok = this.generate('{', value);
tokens.splice(idx, 0, tok);
this.detectEnd(i + 2, condition, action);
return 2;
@@ -168,8 +169,9 @@
};
Rewriter.prototype.addImplicitParentheses = function() {
var action, condition, noCall, seenControl, seenSingle;
var action, callIndex, condition, noCall, seenControl, seenSingle;
noCall = seenSingle = seenControl = false;
callIndex = null;
condition = function(token, i) {
var post, tag, _ref, _ref1;
tag = token[0];
@@ -185,10 +187,10 @@
if ((tag === '.' || tag === '?.' || tag === '::') && this.tag(i - 1) === 'OUTDENT') {
return true;
}
return !token.generated && this.tag(i - 1) !== ',' && (__indexOf.call(IMPLICIT_END, tag) >= 0 || (tag === 'INDENT' && !seenControl)) && (tag !== 'INDENT' || (((_ref = this.tag(i - 2)) !== 'CLASS' && _ref !== 'EXTENDS') && (_ref1 = this.tag(i - 1), __indexOf.call(IMPLICIT_BLOCK, _ref1) < 0) && !((post = this.tokens[i + 1]) && post.generated && post[0] === '{')));
return !token.generated && this.tag(i - 1) !== ',' && (__indexOf.call(IMPLICIT_END, tag) >= 0 || (tag === 'INDENT' && !seenControl)) && (tag !== 'INDENT' || (((_ref = this.tag(i - 2)) !== 'CLASS' && _ref !== 'EXTENDS') && (_ref1 = this.tag(i - 1), __indexOf.call(IMPLICIT_BLOCK, _ref1) < 0) && !(callIndex === i - 1 && (post = this.tokens[i + 1]) && post.generated && post[0] === '{')));
};
action = function(token, i) {
return this.tokens.splice(i, 0, this.generate('CALL_END', ')', token[2]));
return this.tokens.splice(i, 0, this.generate('CALL_END', ')'));
};
return this.scanTokens(function(token, i, tokens) {
var callObject, current, next, prev, tag, _ref, _ref1, _ref2;
@@ -212,6 +214,7 @@
if (!(callObject || (prev != null ? prev.spaced : void 0) && (prev.call || (_ref2 = prev[0], __indexOf.call(IMPLICIT_FUNC, _ref2) >= 0)) && (__indexOf.call(IMPLICIT_CALL, tag) >= 0 || !(token.spaced || token.newLine) && __indexOf.call(IMPLICIT_UNSPACED_CALL, tag) >= 0))) {
return 1;
}
callIndex = i;
tokens.splice(i, 0, this.generate('CALL_START', '(', token[2]));
this.detectEnd(i + 1, condition, action);
if (prev[0] === '?') {
@@ -221,6 +224,32 @@
});
};
Rewriter.prototype.addLocationDataToGeneratedTokens = function() {
return this.scanTokens(function(token, i, tokens) {
var prevToken, tag;
tag = token[0];
if ((token.generated || token.explicit) && (!token[2])) {
if (i > 0) {
prevToken = tokens[i - 1];
token[2] = {
first_line: prevToken[2].last_line,
first_column: prevToken[2].last_column,
last_line: prevToken[2].last_line,
last_column: prevToken[2].last_column
};
} else {
token[2] = {
first_line: 0,
first_column: 0,
last_line: 0,
last_column: 0
};
}
}
return 1;
});
};
Rewriter.prototype.addImplicitIndentation = function() {
var action, condition, indent, outdent, starter;
starter = indent = outdent = null;
@@ -290,17 +319,20 @@
if (implicit == null) {
implicit = false;
}
indent = ['INDENT', 2, token[2]];
outdent = ['OUTDENT', 2, token[2]];
indent = ['INDENT', 2];
outdent = ['OUTDENT', 2];
if (implicit) {
indent.generated = outdent.generated = true;
}
if (!implicit) {
indent.explicit = outdent.explicit = true;
}
return [indent, outdent];
};
Rewriter.prototype.generate = function(tag, value, line) {
Rewriter.prototype.generate = function(tag, value) {
var tok;
tok = [tag, value, line];
tok = [tag, value];
tok.generated = true;
return tok;
};

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.5.0-pre
// Generated by CoffeeScript 1.5.0
(function() {
var Scope, extend, last, _ref;

View File

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

View File

@@ -26,7 +26,7 @@ if require.extensions
require.extensions[ext] = loadFile
# The current CoffeeScript version number.
exports.VERSION = '1.5.0-pre'
exports.VERSION = '1.5.0'
# Expose helpers for testing.
exports.helpers = require './helpers'
@@ -122,7 +122,13 @@ lexer = new Lexer
# directly as a "Jison lexer".
parser.lexer =
lex: ->
[tag, @yytext, @yylineno] = @tokens[@pos++] or ['']
token = @tokens[@pos++]
if token
[tag, @yytext, @yylloc] = token
@yylineno = @yylloc.first_line
else
tag = ''
tag
setInput: (@tokens) ->
@pos = 0

View File

@@ -43,7 +43,6 @@ SWITCHES = [
[ '--nodejs [ARGS]', 'pass options directly to the "node" binary']
['-o', '--output [DIR]', 'set the output directory for compiled JavaScript']
['-p', '--print', 'print out the compiled JavaScript']
['-r', '--require [FILE*]', 'require a library before executing your script']
['-s', '--stdio', 'listen for and compile scripts over stdio']
['-t', '--tokens', 'print out the tokens that the lexer/rewriter produce']
['-v', '--version', 'display the version number']
@@ -67,7 +66,6 @@ exports.run = ->
return forkNode() if opts.nodejs
return usage() if opts.help
return version() if opts.version
loadRequires() if opts.require
return require('./repl').start() if opts.interactive
if opts.watch and !fs.watch
return printWarn "The --watch feature depends on Node v0.6.0+. You are running #{process.version}."
@@ -77,7 +75,6 @@ exports.run = ->
literals = if opts.run then sources.splice 1 else []
process.argv = process.argv[0..1].concat literals
process.argv[0] = 'coffee'
process.execPath = require.main.filename
for source in sources
compilePath source, yes, path.normalize source
@@ -88,7 +85,7 @@ compilePath = (source, topLevel, base) ->
fs.stat source, (err, stats) ->
throw err if err and err.code isnt 'ENOENT'
if err?.code is 'ENOENT'
if topLevel and path.extname(source) not in coffee_exts
if topLevel and source and path.extname(source) not in coffee_exts
source = sources[sources.indexOf(source)] = "#{source}.coffee"
return compilePath source, topLevel, base
if topLevel
@@ -165,13 +162,6 @@ compileJoin = ->
joinTimeout = wait 100, ->
compileScript opts.join, sourceCode.join('\n'), opts.join
# Load files that are to-be-required before compilation occurs.
loadRequires = ->
realFilename = module.filename
module.filename = '.'
require req for req in opts.require
module.filename = realFilename
# Watch a source CoffeeScript file using `fs.watch`, recompiling it every
# time the file is updated. May be used in combination with other options,
# such as `--lint` or `--print`.
@@ -301,8 +291,10 @@ lint = (file, js) ->
# Pretty-print a stream of tokens.
printTokens = (tokens) ->
strings = for token in tokens
[tag, value] = [token[0], token[1].toString().replace(/\n/, '\\n')]
"[#{tag} #{value}]"
tag = token[0]
value = token[1].toString().replace(/\n/, '\\n')
locationData = helpers.locationDataToString token[2]
"[#{tag} #{value} #{locationData}]"
printLine strings.join(' ')
# Use the [OptionParser module](optparse.html) to extract all options from

View File

@@ -32,11 +32,28 @@ unwrap = /^function\s*\(\)\s*\{\s*return\s*([\s\S]*);\s*\}/
# previous nonterminal.
o = (patternString, action, options) ->
patternString = patternString.replace /\s{2,}/g, ' '
patternCount = patternString.split(' ').length
return [patternString, '$$ = $1;', options] unless action
action = if match = unwrap.exec action then match[1] else "(#{action}())"
# All runtime functions we need are defined on "yy"
action = action.replace /\bnew /g, '$&yy.'
action = action.replace /\b(?:Block\.wrap|extend)\b/g, 'yy.$&'
[patternString, "$$ = #{action};", options]
action = action.replace /\b(Op|Value\.(create|wrap))\b/g, 'yy.$&'
# Returns a function which adds location data to the first parameter passed
# in, and returns the parameter. If the parameter is not a node, it will
# just be passed through unaffected.
addLocationDataFn = (first, last) ->
if not last
"yy.addLocationDataFn(@#{first})"
else
"yy.addLocationDataFn(@#{first}, @#{last})"
action = action.replace /LOC\(([0-9]*)\)/g, addLocationDataFn('$1')
action = action.replace /LOC\(([0-9]*),\s*([0-9]*)\)/g, addLocationDataFn('$1', '$2')
[patternString, "$$ = #{addLocationDataFn(1, patternCount)}(#{action});", options]
# Grammatical Rules
# -----------------
@@ -142,10 +159,10 @@ grammar =
# Assignment when it happens within an object literal. The difference from
# the ordinary **Assign** is that these allow numbers and strings as keys.
AssignObj: [
o 'ObjAssignable', -> new Value $1
o 'ObjAssignable : Expression', -> new Assign new Value($1), $3, 'object'
o 'ObjAssignable', -> Value.wrap $1
o 'ObjAssignable : Expression', -> new Assign LOC(1)(Value.wrap($1)), $3, 'object'
o 'ObjAssignable :
INDENT Expression OUTDENT', -> new Assign new Value($1), $4, 'object'
INDENT Expression OUTDENT', -> new Assign LOC(1)(Value.wrap($1)), $4, 'object'
o 'Comment'
]
@@ -219,26 +236,26 @@ grammar =
# Variables and properties that can be assigned to.
SimpleAssignable: [
o 'Identifier', -> new Value $1
o 'Identifier', -> Value.wrap $1
o 'Value Accessor', -> $1.add $2
o 'Invocation Accessor', -> new Value $1, [].concat $2
o 'Invocation Accessor', -> Value.wrap $1, [].concat $2
o 'ThisProperty'
]
# Everything that can be assigned to.
Assignable: [
o 'SimpleAssignable'
o 'Array', -> new Value $1
o 'Object', -> new Value $1
o 'Array', -> Value.wrap $1
o 'Object', -> Value.wrap $1
]
# The types of things that can be treated as values -- assigned to, invoked
# as functions, indexed into, named as a class, etc.
Value: [
o 'Assignable'
o 'Literal', -> new Value $1
o 'Parenthetical', -> new Value $1
o 'Range', -> new Value $1
o 'Literal', -> Value.wrap $1
o 'Parenthetical', -> Value.wrap $1
o 'Range', -> Value.wrap $1
o 'This'
]
@@ -247,7 +264,7 @@ grammar =
Accessor: [
o '. Identifier', -> new Access $2
o '?. Identifier', -> new Access $2, 'soak'
o ':: Identifier', -> [(new Access new Literal 'prototype'), new Access $2]
o ':: Identifier', -> [LOC(1)(new Access new Literal 'prototype'), LOC(2)(new Access $2)]
o '::', -> new Access new Literal 'prototype'
o 'Index'
]
@@ -313,13 +330,13 @@ grammar =
# A reference to the *this* current object.
This: [
o 'THIS', -> new Value new Literal 'this'
o '@', -> new Value new Literal 'this'
o 'THIS', -> Value.wrap new Literal 'this'
o '@', -> Value.wrap new Literal 'this'
]
# A reference to a property on *this*.
ThisProperty: [
o '@ Identifier', -> new Value new Literal('this'), [new Access($2)], 'this'
o '@ Identifier', -> Value.wrap LOC(1)(new Literal('this')), [LOC(2)(new Access($2))], 'this'
]
# The array literal.
@@ -383,7 +400,7 @@ grammar =
# A catch clause names its error and runs a block of code.
Catch: [
o 'CATCH Identifier Block', -> [$2, $3]
o 'CATCH Object Block', -> [new Value($2), $3]
o 'CATCH Object Block', -> [LOC(2)(Value.wrap($2)), $3]
]
# Throw an exception object.
@@ -412,14 +429,14 @@ grammar =
# or postfix, with a single expression. There is no do..while.
While: [
o 'WhileSource Block', -> $1.addBody $2
o 'Statement WhileSource', -> $2.addBody Block.wrap [$1]
o 'Expression WhileSource', -> $2.addBody Block.wrap [$1]
o 'Statement WhileSource', -> $2.addBody LOC(1) Block.wrap([$1])
o 'Expression WhileSource', -> $2.addBody LOC(1) Block.wrap([$1])
o 'Loop', -> $1
]
Loop: [
o 'LOOP Block', -> new While(new Literal 'true').addBody $2
o 'LOOP Expression', -> new While(new Literal 'true').addBody Block.wrap [$2]
o 'LOOP Block', -> new While(LOC(1) new Literal 'true').addBody $2
o 'LOOP Expression', -> new While(LOC(1) new Literal 'true').addBody LOC(2) Block.wrap [$2]
]
# Array, object, and range comprehensions, at the most generic level.
@@ -432,7 +449,7 @@ grammar =
]
ForBody: [
o 'FOR Range', -> source: new Value($2)
o 'FOR Range', -> source: LOC(2) Value.wrap($2)
o 'ForStart ForSource', -> $2.own = $1.own; $2.name = $1[0]; $2.index = $1[1]; $2
]
@@ -446,8 +463,8 @@ grammar =
ForValue: [
o 'Identifier'
o 'ThisProperty'
o 'Array', -> new Value $1
o 'Object', -> new Value $1
o 'Array', -> Value.wrap $1
o 'Object', -> Value.wrap $1
]
# An array or range comprehension has variables for the current element
@@ -502,8 +519,8 @@ grammar =
If: [
o 'IfBlock'
o 'IfBlock ELSE Block', -> $1.addElse $3
o 'Statement POST_IF Expression', -> new If $3, Block.wrap([$1]), type: $2, statement: true
o 'Expression POST_IF Expression', -> new If $3, Block.wrap([$1]), type: $2, statement: true
o 'Statement POST_IF Expression', -> new If $3, LOC(1)(Block.wrap [$1]), type: $2, statement: true
o 'Expression POST_IF Expression', -> new If $3, LOC(1)(Block.wrap [$1]), type: $2, statement: true
]
# Arithmetic and logical operators, working on one or more operands.
@@ -513,30 +530,30 @@ grammar =
# -type rule, but in order to make the precedence binding possible, separate
# rules are necessary.
Operation: [
o 'UNARY Expression', -> new Op $1 , $2
o '- Expression', (-> new Op '-', $2), prec: 'UNARY'
o '+ Expression', (-> new Op '+', $2), prec: 'UNARY'
o 'UNARY Expression', -> Op.create $1 , $2
o '- Expression', (-> Op.create '-', $2), prec: 'UNARY'
o '+ Expression', (-> Op.create '+', $2), prec: 'UNARY'
o '-- SimpleAssignable', -> new Op '--', $2
o '++ SimpleAssignable', -> new Op '++', $2
o 'SimpleAssignable --', -> new Op '--', $1, null, true
o 'SimpleAssignable ++', -> new Op '++', $1, null, true
o '-- SimpleAssignable', -> Op.create '--', $2
o '++ SimpleAssignable', -> Op.create '++', $2
o 'SimpleAssignable --', -> Op.create '--', $1, null, true
o 'SimpleAssignable ++', -> Op.create '++', $1, null, true
# [The existential operator](http://jashkenas.github.com/coffee-script/#existence).
o 'Expression ?', -> new Existence $1
o 'Expression + Expression', -> new Op '+' , $1, $3
o 'Expression - Expression', -> new Op '-' , $1, $3
o 'Expression + Expression', -> Op.create '+' , $1, $3
o 'Expression - Expression', -> Op.create '-' , $1, $3
o 'Expression MATH Expression', -> new Op $2, $1, $3
o 'Expression SHIFT Expression', -> new Op $2, $1, $3
o 'Expression COMPARE Expression', -> new Op $2, $1, $3
o 'Expression LOGIC Expression', -> new Op $2, $1, $3
o 'Expression MATH Expression', -> Op.create $2, $1, $3
o 'Expression SHIFT Expression', -> Op.create $2, $1, $3
o 'Expression COMPARE Expression', -> Op.create $2, $1, $3
o 'Expression LOGIC Expression', -> Op.create $2, $1, $3
o 'Expression RELATION Expression', ->
if $2.charAt(0) is '!'
new Op($2[1..], $1, $3).invert()
Op.create($2[1..], $1, $3).invert()
else
new Op $2, $1, $3
Op.create $2, $1, $3
o 'SimpleAssignable COMPOUND_ASSIGN
Expression', -> new Assign $1, $3, $2

View File

@@ -59,3 +59,37 @@ exports.last = (array, back) -> array[array.length - (back or 0) - 1]
exports.some = Array::some ? (fn) ->
return true for e in this when fn e
false
# Merge two jison-style location data objects together.
# If `last` is not provided, this will simply return `first`.
buildLocationData = (first, last) ->
if not last
first
else
first_line: first.first_line
first_column: first.first_column
last_line: last.last_line
last_column: last.last_column
# This returns a function which takes an object as a parameter, and if that object is an AST node,
# updates that object's locationData. The object is returned either way.
exports.addLocationDataFn = (first, last) ->
(obj) ->
if ((typeof obj) is 'object') and (!!obj['updateLocationDataIfMissing'])
obj.updateLocationDataIfMissing buildLocationData(first, last)
return obj
# Convert jison location data to a string.
# `obj` can be a token, or a locationData.
exports.locationDataToString = (obj) ->
if ("2" of obj) and ("first_line" of obj[2]) then locationData = obj[2]
else if "first_line" of obj then locationData = obj
if locationData
"#{locationData.first_line + 1}:#{locationData.first_column + 1}-" +
"#{locationData.last_line + 1}:#{locationData.last_column + 1}"
else
"No location data"

View File

@@ -3,14 +3,16 @@
# a token is produced, we consume the match, and start again. Tokens are in the
# form:
#
# [tag, value, lineNumber]
# [tag, value, locationData]
#
# Which is a format that can be fed directly into [Jison](http://github.com/zaach/jison).
# where locationData is {first_line, first_column, last_line, last_column}, which is a
# format that can be fed directly into [Jison](http://github.com/zaach/jison). These
# are read by jison in the `parser.lexer` function defined in coffee-script.coffee.
{Rewriter, INVERSES} = require './rewriter'
# Import the helpers we need.
{count, starts, compact, last} = require './helpers'
{count, starts, compact, last, locationDataToString} = require './helpers'
# The Lexer Class
# ---------------
@@ -34,7 +36,6 @@ exports.Lexer = class Lexer
tokenize: (code, opts = {}) ->
@literate = opts.literate # Are we lexing literate CoffeeScript?
code = @clean code # The stripped, cleaned original source code.
@line = opts.line or 0 # The current line.
@indent = 0 # The current indentation level.
@indebt = 0 # The over-indentation at the current level.
@outdebt = 0 # The under-outdentation at the current level.
@@ -42,12 +43,18 @@ exports.Lexer = class Lexer
@ends = [] # The stack for pairing up tokens.
@tokens = [] # Stream of parsed tokens in the form `['TYPE', value, line]`.
@chunkLine =
opts.line or 0 # The start line for the current @chunk.
@chunkColumn =
opts.column or 0 # The start column of the current @chunk.
# At every position, run through this list of attempted matches,
# short-circuiting if any of them succeed. Their order determines precedence:
# `@literalToken` is the fallback catch-all.
i = 0
while @chunk = code[i..]
i += @identifierToken() or
consumed = \
@identifierToken() or
@commentToken() or
@whitespaceToken() or
@lineToken() or
@@ -58,6 +65,11 @@ exports.Lexer = class Lexer
@jsToken() or
@literalToken()
# Update position
[@chunkLine, @chunkColumn] = @getLineAndColumnFromChunk consumed
i += consumed
@closeIndentation()
@error "missing #{tag}" if tag = @ends.pop()
return @tokens if opts.rewrite is off
@@ -92,6 +104,10 @@ exports.Lexer = class Lexer
return 0 unless match = IDENTIFIER.exec @chunk
[input, id, colon] = match
# Preserve length of id for location data
idLength = id.length
poppedToken = undefined
if id is 'own' and @tag() is 'FOR'
@token 'OWN', id
return id.length
@@ -117,7 +133,7 @@ exports.Lexer = class Lexer
else
tag = 'RELATION'
if @value() is '!'
@tokens.pop()
poppedToken = @tokens.pop()
id = '!' + id
if id in JS_FORBIDDEN
@@ -138,8 +154,14 @@ exports.Lexer = class Lexer
when 'break', 'continue' then 'STATEMENT'
else tag
@token tag, id
@token ':', ':' if colon
tagToken = @token tag, id, 0, idLength
if poppedToken
[tagToken[2].first_line, tagToken[2].first_column] =
[poppedToken[2].first_line, poppedToken[2].first_column]
if colon
colonOffset = input.lastIndexOf ':'
@token ':', ':', colonOffset, colon.length
input.length
# Matches numbers, including decimals, hex, and exponential notation.
@@ -160,7 +182,7 @@ exports.Lexer = class Lexer
number = '0x' + (parseInt octalLiteral[1], 8).toString 16
if binaryLiteral = /^0b([01]+)/.exec number
number = '0x' + (parseInt binaryLiteral[1], 2).toString 16
@token 'NUMBER', number
@token 'NUMBER', number, 0, lexedLength
lexedLength
# Matches strings, including multi-line strings. Ensures that quotation marks
@@ -169,18 +191,18 @@ exports.Lexer = class Lexer
switch @chunk.charAt 0
when "'"
return 0 unless match = SIMPLESTR.exec @chunk
@token 'STRING', (string = match[0]).replace MULTILINER, '\\\n'
string = match[0]
@token 'STRING', string.replace(MULTILINER, '\\\n'), 0, string.length
when '"'
return 0 unless string = @balancedString @chunk, '"'
if 0 < string.indexOf '#{', 1
@interpolateString string[1...-1]
@interpolateString string[1...-1], strOffset: 1, lexedLength: string.length
else
@token 'STRING', @escapeLines string
@token 'STRING', @escapeLines string, 0, string.length
else
return 0
if octalEsc = /^(?:\\.|[^\\])*\\(?:0[0-7]|[1-7])/.test string
@error "octal escape sequences #{string} are not allowed"
@line += count string, '\n'
string.length
# Matches heredocs, adjusting indentation to the correct level, as heredocs
@@ -191,10 +213,9 @@ exports.Lexer = class Lexer
quote = heredoc.charAt 0
doc = @sanitizeHeredoc match[2], quote: quote, indent: null
if quote is '"' and 0 <= doc.indexOf '#{'
@interpolateString doc, heredoc: yes
@interpolateString doc, heredoc: yes, strOffset: 3, lexedLength: heredoc.length
else
@token 'STRING', @makeString doc, quote, yes
@line += count heredoc, '\n'
@token 'STRING', @makeString(doc, quote, yes), 0, heredoc.length
heredoc.length
# Matches and consumes comments.
@@ -202,16 +223,16 @@ exports.Lexer = class Lexer
return 0 unless match = @chunk.match COMMENT
[comment, here] = match
if here
@token 'HERECOMMENT', @sanitizeHeredoc here,
herecomment: true, indent: Array(@indent + 1).join(' ')
@line += count comment, '\n'
@token 'HERECOMMENT',
(@sanitizeHeredoc here,
herecomment: true, indent: Array(@indent + 1).join(' ')),
0, comment.length
comment.length
# Matches JavaScript interpolated directly into the source via backticks.
jsToken: ->
return 0 unless @chunk.charAt(0) is '`' and match = JSTOKEN.exec @chunk
@token 'JS', (script = match[0])[1...-1]
@line += count script, '\n'
@token 'JS', (script = match[0])[1...-1], 0, script.length
script.length
# Matches regular expression literals. Lexing regular expressions is difficult
@@ -221,7 +242,6 @@ exports.Lexer = class Lexer
return 0 if @chunk.charAt(0) isnt '/'
if match = HEREGEX.exec @chunk
length = @heregexToken match
@line += count match[0], '\n'
return length
prev = last @tokens
@@ -230,7 +250,7 @@ exports.Lexer = class Lexer
[match, regex, flags] = match
if regex[..1] is '/*' then @error 'regular expressions cannot begin with `*`'
if regex is '//' then regex = '/(?:)/'
@token 'REGEX', "#{regex}#{flags}"
@token 'REGEX', "#{regex}#{flags}", 0, match.length
match.length
# Matches multiline extended regular expressions.
@@ -239,24 +259,45 @@ exports.Lexer = class Lexer
if 0 > body.indexOf '#{'
re = body.replace(HEREGEX_OMIT, '').replace(/\//g, '\\/')
if re.match /^\*/ then @error 'regular expressions cannot begin with `*`'
@token 'REGEX', "/#{ re or '(?:)' }/#{flags}"
@token 'REGEX', "/#{ re or '(?:)' }/#{flags}", 0, heregex.length
return heregex.length
@token 'IDENTIFIER', 'RegExp'
@tokens.push ['CALL_START', '(']
@token 'IDENTIFIER', 'RegExp', 0, 0
@token 'CALL_START', '(', 0, 0
tokens = []
for [tag, value] in @interpolateString(body, regex: yes)
for token in @interpolateString(body, regex: yes)
[tag, value] = token
if tag is 'TOKENS'
tokens.push value...
else
else if tag is 'NEOSTRING'
continue unless value = value.replace HEREGEX_OMIT, ''
# Convert NEOSTRING into STRING
value = value.replace /\\/g, '\\\\'
tokens.push ['STRING', @makeString(value, '"', yes)]
tokens.push ['+', '+']
token[0] = 'STRING'
token[1] = @makeString(value, '"', yes)
tokens.push token
else
@error "Unexpected #{tag}"
prev = last @tokens
plusToken = ['+', '+']
plusToken[2] = prev[2] # Copy location data
tokens.push plusToken
# Remove the extra "+"
tokens.pop()
@tokens.push ['STRING', '""'], ['+', '+'] unless tokens[0]?[0] is 'STRING'
unless tokens[0]?[0] is 'STRING'
@token 'STRING', '""', 0, 0
@token '+', '+', 0, 0
@tokens.push tokens...
@tokens.push [',', ','], ['STRING', '"' + flags + '"'] if flags
@token ')', ')'
if flags
# Find the flags in the heregex
flagsOffset = heregex.lastIndexOf flags
@token ',', ',', flagsOffset, 0
@token 'STRING', '"' + flags + '"', flagsOffset, flags.length
@token ')', ')', heregex.length-1, 0
heregex.length
# Matches newlines, indents, and outdents, and determines which is which.
@@ -272,32 +313,32 @@ exports.Lexer = class Lexer
lineToken: ->
return 0 unless match = MULTI_DENT.exec @chunk
indent = match[0]
@line += count indent, '\n'
@seenFor = no
size = indent.length - 1 - indent.lastIndexOf '\n'
noNewlines = @unfinished()
if size - @indebt is @indent
if noNewlines then @suppressNewlines() else @newlineToken()
if noNewlines then @suppressNewlines() else @newlineToken 0
return indent.length
if size > @indent
if noNewlines
@indebt = size - @indent
@suppressNewlines()
return indent.length
diff = size - @indent + @outdebt
@token 'INDENT', diff
@token 'INDENT', diff, 0, indent.length
@indents.push diff
@ends.push 'OUTDENT'
@outdebt = @indebt = 0
else
@indebt = 0
@outdentToken @indent - size, noNewlines
@outdentToken @indent - size, noNewlines, indent.length
@indent = size
indent.length
# Record an outdent token or multiple tokens, if we happen to be moving back
# inwards past several recorded indents.
outdentToken: (moveOut, noNewlines) ->
outdentToken: (moveOut, noNewlines, outdentLength) ->
while moveOut > 0
len = @indents.length - 1
if @indents[len] is undefined
@@ -309,14 +350,15 @@ exports.Lexer = class Lexer
@outdebt -= @indents[len]
moveOut -= @indents[len]
else
dent = @indents.pop() - @outdebt
dent = @indents.pop() + @outdebt
moveOut -= dent
@outdebt = 0
@pair 'OUTDENT'
@token 'OUTDENT', dent
@token 'OUTDENT', dent, 0, outdentLength
@outdebt -= moveOut if dent
@tokens.pop() while @value() is ';'
@token 'TERMINATOR', '\n' unless @tag() is 'TERMINATOR' or noNewlines
@token 'TERMINATOR', '\n', outdentLength, 0 unless @tag() is 'TERMINATOR' or noNewlines
this
# Matches and consumes non-meaningful whitespace. Tag the previous token
@@ -329,9 +371,9 @@ exports.Lexer = class Lexer
if match then match[0].length else 0
# Generate a newline token. Consecutive newlines get merged together.
newlineToken: ->
newlineToken: (offset) ->
@tokens.pop() while @value() is ';'
@token 'TERMINATOR', '\n' unless @tag() is 'TERMINATOR'
@token 'TERMINATOR', '\n', offset, 0 unless @tag() is 'TERMINATOR'
this
# Use a `\` at a line-ending to suppress the newline.
@@ -467,8 +509,28 @@ exports.Lexer = class Lexer
# If it encounters an interpolation, this method will recursively create a
# new Lexer, tokenize the interpolated contents, and merge them into the
# token stream.
#
# - `str` is the start of the string contents (IE with the " or """ stripped
# off.)
# - `options.offsetInChunk` is the start of the interpolated string in the
# current chunk, including the " or """, etc... If not provided, this is
# assumed to be 0. `options.lexedLength` is the length of the
# interpolated string, including both the start and end quotes. Both of these
# values are ignored if `options.regex` is true.
# - `options.strOffset` is the offset of str, relative to the start of the
# current chunk.
interpolateString: (str, options = {}) ->
{heredoc, regex} = options
{heredoc, regex, offsetInChunk, strOffset, lexedLength} = options
offsetInChunk = offsetInChunk || 0
strOffset = strOffset || 0
lexedLength = lexedLength || str.length
# Clip leading \n from heredoc
if heredoc and str.length > 0 and str[0] == '\n'
str = str[1...]
strOffset++
# Parse the string.
tokens = []
pi = 0
i = -1
@@ -479,31 +541,58 @@ exports.Lexer = class Lexer
unless letter is '#' and str.charAt(i+1) is '{' and
(expr = @balancedString str[i + 1..], '}')
continue
tokens.push ['NEOSTRING', str[pi...i]] if pi < i
# NEOSTRING is a fake token. This will be converted to a string below.
tokens.push @makeToken('NEOSTRING', str[pi...i], strOffset + pi) if pi < i
inner = expr[1...-1]
if inner.length
nested = new Lexer().tokenize inner, line: @line, rewrite: off
nested.pop()
nested.shift() if nested[0]?[0] is 'TERMINATOR'
[line, column] = @getLineAndColumnFromChunk(strOffset + i + 1)
nested = new Lexer().tokenize inner, line: line, column: column, rewrite: off
popped = nested.pop()
popped = nested.shift() if nested[0]?[0] is 'TERMINATOR'
if len = nested.length
if len > 1
nested.unshift ['(', '(', @line]
nested.push [')', ')', @line]
nested.unshift @makeToken '(', '(', strOffset + i + 1, 0
nested.push @makeToken ')', ')', strOffset + i + 1 + inner.length, 0
# Push a fake 'TOKENS' token, which will get turned into real tokens below.
tokens.push ['TOKENS', nested]
i += expr.length
pi = i + 1
tokens.push ['NEOSTRING', str[pi..]] if i > pi < str.length
tokens.push @makeToken('NEOSTRING', str[pi..], strOffset + pi) if i > pi < str.length
# If regex, then return now and let the regex code deal with all these fake tokens
return tokens if regex
return @token 'STRING', '""' unless tokens.length
tokens.unshift ['', ''] unless tokens[0][0] is 'NEOSTRING'
@token '(', '(' if interpolated = tokens.length > 1
for [tag, value], i in tokens
@token '+', '+' if i
# If we didn't find any tokens, then just return an empty string.
return @token 'STRING', '""', offsetInChunk, lexedLength unless tokens.length
# If the first token is not a string, add a fake empty string to the beginning.
tokens.unshift @makeToken('NEOSTRING', '', offsetInChunk) unless tokens[0][0] is 'NEOSTRING'
@token '(', '(', offsetInChunk, 0 if interpolated = tokens.length > 1
# Push all the tokens
for token, i in tokens
[tag, value] = token
if i
# Create a 0-length "+" token.
plusToken = @token '+', '+' if i
locationToken = if tag == 'TOKENS' then value[0] else token
plusToken[2] =
first_line: locationToken[2].first_line
first_column: locationToken[2].first_column
last_line: locationToken[2].first_line
last_column: locationToken[2].first_column
if tag is 'TOKENS'
# Push all the tokens in the fake 'TOKENS' token. These already have
# sane location data.
@tokens.push value...
else if tag is 'NEOSTRING'
# Convert NEOSTRING into STRING
token[0] = 'STRING'
token[1] = @makeString value, '"', heredoc
@tokens.push token
else
@token 'STRING', @makeString value, '"', heredoc
@token ')', ')' if interpolated
@error "Unexpected #{tag}"
@token ')', ')', offsetInChunk + lexedLength, 0 if interpolated
tokens
# Pairs up a closing token, ensuring that all listed pairs of tokens are
@@ -524,9 +613,59 @@ exports.Lexer = class Lexer
# Helpers
# -------
# Add a token to the results, taking note of the line number.
token: (tag, value) ->
@tokens.push [tag, value, @line]
# Returns the line and column number from an offset into the current chunk.
#
# `offset` is a number of characters into @chunk.
getLineAndColumnFromChunk: (offset) ->
if offset is 0
return [@chunkLine, @chunkColumn]
if offset >= @chunk.length
string = @chunk
else
string = @chunk[..offset-1]
lineCount = count string, '\n'
column = @chunkColumn
if lineCount > 0
lines = string.split '\n'
column = (last lines).length
else
column += string.length
return [@chunkLine + lineCount, column]
# Same as "token", exception this just returns the token without adding it
# to the results.
makeToken: (tag, value, offsetInChunk, length) ->
offsetInChunk = offsetInChunk || 0
if length is undefined then length = value.length
locationData = {}
[locationData.first_line, locationData.first_column] =
@getLineAndColumnFromChunk offsetInChunk
# Use length - 1 for the final offset - we're supplying the last_line and the last_column,
# so if last_column == first_column, then we're looking at a character of length 1.
lastCharacter = if length > 0 then (length - 1) else 0
[locationData.last_line, locationData.last_column] =
@getLineAndColumnFromChunk offsetInChunk + (length - 1)
token = [tag, value, locationData]
return token
# Add a token to the results.
# `offset` is the offset into the current @chunk where the token starts.
# `length` is the length of the token in the @chunk, after the offset. If
# not specified, the length of `value` will be used.
#
# Returns the new token.
token: (tag, value, offsetInChunk, length) ->
token = @makeToken tag, value, offsetInChunk, length
@tokens.push token
return token
# Peek at a tag in the current token stream.
tag: (index, tag) ->
@@ -556,7 +695,9 @@ exports.Lexer = class Lexer
# Throws a syntax error on the current `@line`.
error: (message) ->
throw SyntaxError "#{message} on line #{ @line + 1}"
# TODO: Are there some cases we could improve the error line number by
# passing the offset in the chunk where the error happened?
throw SyntaxError "#{message} on line #{ @chunkLine + 1 }"
# Constants
# ---------

View File

@@ -7,9 +7,11 @@
{RESERVED, STRICT_PROSCRIBED} = require './lexer'
# Import the helpers we plan to use.
{compact, flatten, extend, merge, del, starts, ends, last, some} = require './helpers'
{compact, flatten, extend, merge, del, starts, ends, last, some, addLocationDataFn, locationDataToString} = require './helpers'
exports.extend = extend # for parser
# Functions required by parser
exports.extend = extend
exports.addLocationDataFn = addLocationDataFn
# Constant functions for nodes that don't need customization.
YES = -> yes
@@ -66,13 +68,6 @@ exports.Base = class Base
sub = new Assign ref, this
if level then [sub.compile(o, level), ref.value] else [sub, ref]
# Compile to a source/variable pair suitable for looping.
compileLoopReference: (o, name) ->
src = tmp = @compile o, LEVEL_LIST
unless -Infinity < +src < Infinity or IDENTIFIER.test(src) and o.scope.check(src, yes)
src = "#{ tmp = o.scope.freeVariable name } = #{src}"
[src, tmp]
# Construct a node that returns the current node's result.
# Note that this is overridden for smarter behavior for
# many statement nodes (e.g. If, For)...
@@ -108,7 +103,8 @@ exports.Base = class Base
# `toString` representation of the node, for inspecting the parse tree.
# This is what `coffee --nodes` prints out.
toString: (idt = '', name = @constructor.name) ->
tree = '\n' + idt + name
location = if @locationData then locationDataToString @locationData else "??"
tree = '\n' + idt + location + ": " + name
tree += '?' if @soak
@eachChild (node) -> tree += node.toString idt + TAB
tree
@@ -127,7 +123,7 @@ exports.Base = class Base
child.traverseChildren crossScope, func
invert: ->
new Op '!', this
Op.create '!', this
unwrapAll: ->
node = this
@@ -150,6 +146,16 @@ exports.Base = class Base
# Is this node used to assign a certain variable?
assigns: NO
# For this node and all descendents, set the location data to `locationData` if the location
# data is not already set.
updateLocationDataIfMissing: (locationData) ->
if not @locationData
@locationData = {}
extend @locationData, locationData
@eachChild (child) ->
child.updateLocationDataIfMissing locationData
#### Block
# The block is the list of expressions that forms the body of an
@@ -378,12 +384,15 @@ exports.Return = class Return extends Base
# A value, variable or literal or parenthesized, indexed or dotted into,
# or vanilla.
exports.Value = class Value extends Base
constructor: (base, props, tag) ->
return base if not props and base instanceof Value
@base = base
@properties = props or []
@[tag] = true if tag
return this
@wrap: (base, props, tag) ->
if not props and base instanceof Value
base
else
new Value base, props, tag
constructor: (@base, @properties, tag) ->
@properties or= []
@this = true if tag is 'this'
children: ['base', 'properties']
@@ -429,16 +438,16 @@ exports.Value = class Value extends Base
name = last @properties
if @properties.length < 2 and not @base.isComplex() and not name?.isComplex()
return [this, this] # `a` `a.b`
base = new Value @base, @properties[...-1]
base = Value.wrap @base, @properties[...-1]
if base.isComplex() # `a().b`
bref = new Literal o.scope.freeVariable 'base'
base = new Value new Parens new Assign bref, base
base = Value.wrap new Parens new Assign bref, base
return [base, bref] unless name # `a()`
if name.isComplex() # `a[b()]`
nref = new Literal o.scope.freeVariable 'name'
name = new Index new Assign nref, name.index
nref = new Index nref
[base.add(name), new Value(bref or base.base, [nref or name])]
[base.add(name), Value.wrap(bref or base.base, [nref or name])]
# We compile a value to JavaScript by compiling and joining each property.
# Things get much more interesting if the chain of properties has *soak*
@@ -454,22 +463,20 @@ exports.Value = class Value extends Base
# Unfold a soak into an `If`: `a?.b` -> `a.b if a?`
unfoldSoak: (o) ->
return @unfoldedSoak if @unfoldedSoak?
result = do =>
@unfoldedSoak ?= do =>
if ifn = @base.unfoldSoak o
Array::push.apply ifn.body.properties, @properties
ifn.body.properties.push @properties...
return ifn
for prop, i in @properties when prop.soak
prop.soak = off
fst = new Value @base, @properties[...i]
snd = new Value @base, @properties[i..]
fst = Value.wrap @base, @properties[...i]
snd = Value.wrap @base, @properties[i..]
if fst.isComplex()
ref = new Literal o.scope.freeVariable 'ref'
fst = new Parens new Assign ref, fst
snd.base = ref
return new If new Existence(fst), snd, soak: on
null
@unfoldedSoak = result or no
no
#### Comment
@@ -518,7 +525,7 @@ exports.Call = class Call extends Base
accesses = [new Access(new Literal '__super__')]
accesses.push new Access new Literal 'constructor' if method.static
accesses.push new Access new Literal name
(new Value (new Literal method.klass), accesses).compile o
(Value.wrap (new Literal method.klass), accesses).compile o
else
"#{name}.__super__.constructor"
@@ -532,14 +539,14 @@ exports.Call = class Call extends Base
if @soak
if @variable
return ifn if ifn = unfoldSoak o, this, 'variable'
[left, rite] = new Value(@variable).cacheReference o
[left, rite] = Value.wrap(@variable).cacheReference o
else
left = new Literal @superReference o
rite = new Value left
rite = Value.wrap left
rite = new Call rite, @args
rite.isNew = @isNew
left = new Literal "typeof #{ left.compile o } === \"function\""
return new If left, new Value(rite), soak: yes
return new If left, Value.wrap(rite), soak: yes
call = this
list = []
loop
@@ -589,11 +596,6 @@ exports.Call = class Call extends Base
else
(if @isNew then 'new ' else '') + @variable.compile(o, LEVEL_ACCESS) + "(#{args})"
# `super()` is converted into a call against the superclass's implementation
# of the current function.
compileSuper: (args, o) ->
"#{@superReference(o)}.call(#{@superThis(o)}#{ if args.length then ', ' else '' }#{args})"
# If you call a function with a splat, it's converted into a JavaScript
# `.apply()` 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
@@ -609,7 +611,7 @@ exports.Call = class Call extends Base
#{idt}return Object(result) === result ? result : child;
#{@tab}})(#{ @variable.compile o, LEVEL_LIST }, #{splatArgs}, function(){})
"""
base = new Value @variable
base = Value.wrap @variable
if (name = base.properties.pop()) and base.isComplex()
ref = o.scope.freeVariable 'ref'
fun = "(#{ref} = #{ base.compile o, LEVEL_LIST })#{ name.compile o }"
@@ -635,7 +637,7 @@ exports.Extends = class Extends extends Base
# Hooks one constructor into another's prototype chain.
compile: (o) ->
new Call(new Value(new Literal utility 'extends'), [@child, @parent]).compile o
new Call(Value.wrap(new Literal utility 'extends'), [@child, @parent]).compile o
#### Access
@@ -714,7 +716,7 @@ exports.Range = class Range extends Base
[from, to] = [+@fromNum, +@toNum]
if from <= to then "#{lt} #{to}" else "#{gt} #{to}"
else
cond = "#{@fromVar} <= #{@toVar}"
cond = if @stepVar then "#{@stepVar} > 0" else "#{@fromVar} <= #{@toVar}"
"#{cond} ? #{lt} #{@toVar} : #{gt} #{@toVar}"
# Generate the step.
@@ -892,10 +894,10 @@ exports.Class = class Class extends Base
# Ensure that all functions bound to the instance are proxied in the
# constructor.
addBoundFunctions: (o) ->
if @boundFuncs.length
for bvar in @boundFuncs
lhs = (new Value (new Literal "this"), [new Access bvar]).compile o
@ctor.body.unshift new Literal "#{lhs} = #{utility 'bind'}(#{lhs}, this)"
for bvar in @boundFuncs
lhs = (Value.wrap (new Literal "this"), [new Access bvar]).compile o
@ctor.body.unshift new Literal "#{lhs} = #{utility 'bind'}(#{lhs}, this)"
return
# Merge the properties from a top-level object as prototypal properties
# on the class.
@@ -922,7 +924,7 @@ exports.Class = class Class extends Base
if func.bound
func.context = name
else
assign.variable = new Value(new Literal(name), [(new Access new Literal 'prototype'), new Access base ])
assign.variable = Value.wrap(new Literal(name), [(new Access new Literal 'prototype'), new Access base ])
if func instanceof Code and func.bound
@boundFuncs.push base
func.bound = no
@@ -951,17 +953,23 @@ exports.Class = class Class extends Base
# Make sure that a constructor is defined for the class, and properly
# configured.
ensureConstructor: (name) ->
ensureConstructor: (name, o) ->
if not @ctor
@ctor = new Code
@ctor.body.push new Literal "#{name}.__super__.constructor.apply(this, arguments)" if @parent
@ctor.body.push new Literal "#{@externalCtor}.apply(this, arguments)" if @externalCtor
@ctor.body.makeReturn()
@body.expressions.unshift @ctor
@ctor.ctor = @ctor.name = name
@ctor.klass = null
@ctor.noReturn = yes
# Prevent constructor from returning a value.
returnExpr = null
@ctor.body.traverseChildren no, (node) ->
return no if node instanceof Return and (returnExpr = node.expression)
if returnExpr
throw SyntaxError "cannot return a value from a constructor: \"#{returnExpr.compileNode o}\" in class #{name}"
# 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.
@@ -974,7 +982,7 @@ exports.Class = class Class extends Base
@hoistDirectivePrologue()
@setContext name
@walkBody name, o
@ensureConstructor name
@ensureConstructor name, o
@body.spaced = yes
@body.expressions.unshift @ctor unless @ctor instanceof Code
@body.expressions.push lname
@@ -1060,15 +1068,12 @@ exports.Assign = class Assign extends Base
if obj instanceof Assign
{variable: {base: idx}, value: obj} = obj
else
if obj.base instanceof Parens
[obj, idx] = new Value(obj.unwrapAll()).cacheReference o
idx = if isObject
if obj.this then obj.properties[0].name else obj
else
idx = if isObject
if obj.this then obj.properties[0].name else obj
else
new Literal 0
new Literal 0
acc = IDENTIFIER.test idx.unwrap().value or 0
value = new Value value
value = Value.wrap value
value.properties.push new (if acc then Access else Index) idx
if obj.unwrap().value in RESERVED
throw new SyntaxError "assignment to a reserved word: #{obj.compile o} = #{value.compile o}"
@@ -1089,7 +1094,7 @@ exports.Assign = class Assign extends Base
else
# A shorthand `{a, b, @c} = val` pattern-match.
if obj.base instanceof Parens
[obj, idx] = new Value(obj.unwrapAll()).cacheReference o
[obj, idx] = Value.wrap(obj.unwrapAll()).cacheReference o
else
idx = if obj.this then obj.properties[0].name else obj
if not splat and obj instanceof Splat
@@ -1114,7 +1119,7 @@ exports.Assign = class Assign extends Base
acc = no
else
acc = isObject and IDENTIFIER.test idx.unwrap().value or 0
val = new Value new Literal(vvar), [new (if acc then Access else Index) idx]
val = Value.wrap new Literal(vvar), [new (if acc then Access else Index) idx]
if name? and name in RESERVED
throw new SyntaxError "assignment to a reserved word: #{obj.compile o} = #{val.compile o}"
assigns.push new Assign(obj, val, null, param: @param, subpattern: yes).compile o, LEVEL_LIST
@@ -1132,7 +1137,7 @@ exports.Assign = class Assign extends Base
left.base.value != "this" and not o.scope.check left.base.value
throw new Error "the variable \"#{left.base.value}\" can't be assigned with #{@context} because it has not been defined."
if "?" in @context then o.isExistentialEquals = true
new Op(@context[...-1], left, new Assign(right, @value, '=') ).compile o
Op.create(@context[...-1], left, new Assign(right, @value, '=') ).compile o
# Compile the assignment from an array splice literal, using JavaScript's
# `Array#splice` method.
@@ -1190,19 +1195,19 @@ exports.Code = class Code extends Base
for {name: p} in @params
if p.this then p = p.properties[0].name
if p.value then o.scope.add p.value, 'var', yes
splats = new Assign new Value(new Arr(p.asReference o for p in @params)),
new Value new Literal 'arguments'
splats = new Assign Value.wrap(new Arr(p.asReference o for p in @params)),
Value.wrap new Literal 'arguments'
break
for param in @params
if param.isComplex()
val = ref = param.asReference o
val = new Op '?', ref, param.value if param.value
exprs.push new Assign new Value(param.name), val, '=', param: yes
val = Op.create '?', ref, param.value if param.value
exprs.push new Assign Value.wrap(param.name), val, '=', param: yes
else
ref = param
if param.value
lit = new Literal ref.name.value + ' == null'
val = new Assign new Value(param.name), param.value, '='
val = new Assign Value.wrap(param.name), param.value, '='
exprs.push new If lit, val
params.push ref unless splats
wasEmpty = @body.isEmpty()
@@ -1263,7 +1268,7 @@ exports.Param = class Param extends Base
node = new Literal o.scope.freeVariable node.value
else if node.isComplex()
node = new Literal o.scope.freeVariable 'arg'
node = new Value node
node = Value.wrap node
node = new Splat node if @splat
@reference = node
@@ -1323,7 +1328,7 @@ exports.Splat = class Splat extends Base
@name.assigns name
compile: (o) ->
if @index? then @compileParam o else @name.compile o
@name.compile o
unwrap: -> @name
@@ -1407,18 +1412,19 @@ exports.While = class While extends Base
# Simple Arithmetic and logical operations. Performs some conversion from
# CoffeeScript operations into their JavaScript equivalents.
exports.Op = class Op extends Base
constructor: (op, first, second, flip ) ->
return new In first, second if op is 'in'
@create: (op, first, second, flip) ->
if op is 'in'
return new In first, second
if op is 'do'
return @generateDo first
if op is 'new'
return first.newInstance() if first instanceof Call and not first.do and not first.isNew
first = new Parens first if first instanceof Code and first.bound or first.do
return new Op op, first, second, flip
constructor: (op, @first, @second, flip ) ->
@operator = CONVERSIONS[op] or op
@first = first
@second = second
@flip = !!flip
return this
# The map of conversions from CoffeeScript to JavaScript symbols.
CONVERSIONS =
@@ -1471,12 +1477,12 @@ exports.Op = class Op extends Base
fst.operator in ['!', 'in', 'instanceof']
fst
else
new Op '!', this
Op.create '!', this
unfoldSoak: (o) ->
@operator in ['++', '--', 'delete'] and unfoldSoak o, this, 'first'
generateDo: (exp) ->
@generateDo: (exp) ->
passedParams = []
func = if exp instanceof Assign and (ref = exp.value.unwrap()) instanceof Code
ref
@@ -1734,8 +1740,9 @@ exports.For = class For extends While
ivar = (@object and index) or scope.freeVariable 'i'
kvar = (@range and name) or index or ivar
kvarAssign = if kvar isnt ivar then "#{kvar} = " else ""
# the `_by` variable is created twice in `Range`s if we don't prevent it from being declared here
stepvar = scope.freeVariable "step" if @step and not @range
if @step and not @range
[step, stepVar] = @step.cache o, LEVEL_LIST
stepNum = stepVar.match SIMPLENUM
name = ivar if @pattern
varPart = ''
guardPart = ''
@@ -1746,16 +1753,29 @@ exports.For = class For extends While
else
svar = @source.compile o, LEVEL_LIST
if (name or @own) and not IDENTIFIER.test svar
defPart = "#{@tab}#{ref = scope.freeVariable 'ref'} = #{svar};\n"
defPart += "#{@tab}#{ref = scope.freeVariable 'ref'} = #{svar};\n"
svar = ref
if name and not @pattern
namePart = "#{name} = #{svar}[#{kvar}]"
unless @object
lvar = scope.freeVariable 'len'
forVarPart = "#{kvarAssign}#{ivar} = 0, #{lvar} = #{svar}.length"
forVarPart += ", #{stepvar} = #{@step.compile o, LEVEL_OP}" if @step
stepPart = "#{kvarAssign}#{if @step then "#{ivar} += #{stepvar}" else (if kvar isnt ivar then "++#{ivar}" else "#{ivar}++")}"
forPart = "#{forVarPart}; #{ivar} < #{lvar}; #{stepPart}"
if not @object
defPart += "#{@tab}#{step};\n" if step isnt stepVar
lvar = scope.freeVariable 'len' unless @step and stepNum and down = (+stepNum < 0)
declare = "#{kvarAssign}#{ivar} = 0, #{lvar} = #{svar}.length"
declareDown = "#{kvarAssign}#{ivar} = #{svar}.length - 1"
compare = "#{ivar} < #{lvar}"
compareDown = "#{ivar} >= 0"
if @step
if stepNum
if down
compare = compareDown
declare = declareDown
else
compare = "#{stepVar} > 0 ? #{compare} : #{compareDown}"
declare = "(#{stepVar} > 0 ? (#{declare}) : #{declareDown})"
increment = "#{ivar} += #{stepVar}"
else
increment = "#{if kvar isnt ivar then "++#{ivar}" else "#{ivar}++"}"
forPart = "#{declare}; #{compare}; #{kvarAssign}#{increment}"
if @returns
resultPart = "#{@tab}#{rvar} = [];\n"
returnResult = "\n#{@tab}return #{rvar};"
@@ -1791,7 +1811,7 @@ exports.For = class For extends While
val.properties[0].name?.value in ['call', 'apply'])
fn = val.base?.unwrapAll() or val
ref = new Literal o.scope.freeVariable 'fn'
base = new Value ref
base = Value.wrap ref
if val.base
[val.base, base] = [base, val]
body.expressions[idx] = new Call base, expr.args
@@ -1939,7 +1959,7 @@ Closure =
meth = new Literal if mentionsArgs then 'apply' else 'call'
args = [new Literal 'this']
args.push new Literal 'arguments' if mentionsArgs
func = new Value func, [new Access meth]
func = Value.wrap func, [new Access meth]
func.noReturn = noReturn
call = new Call func, args
if statement then Block.wrap [call] else call
@@ -1956,7 +1976,7 @@ Closure =
unfoldSoak = (o, parent, name) ->
return unless ifn = parent[name].unfoldSoak o
parent[name] = ifn.body
ifn.body = new Value parent
ifn.body = Value.wrap parent
ifn
# Constants

View File

@@ -26,6 +26,7 @@ class exports.Rewriter
@tagPostfixConditionals()
@addImplicitBraces()
@addImplicitParentheses()
@addLocationDataToGeneratedTokens()
@tokens
# Rewrite the token stream, looking one token ahead and behind.
@@ -113,7 +114,7 @@ class exports.Rewriter
[tag] = token
sameLine = no if tag in LINEBREAKS
return (
(tag in ['TERMINATOR', 'OUTDENT'] or
(tag in ['TERMINATOR', 'OUTDENT'] or
(tag in IMPLICIT_END and sameLine and not (i - startIndex is 1))) and
((!startsLine and @tag(i - 1) isnt ',') or
not (two?[0] is ':' or one?[0] is '@' and three?[0] is ':'))) or
@@ -122,7 +123,7 @@ class exports.Rewriter
)
action = (token, i) ->
tok = @generate '}', '}', token[2]
tok = @generate '}', '}'
@tokens.splice i, 0, tok
@scanTokens (token, i, tokens) ->
@@ -143,7 +144,7 @@ class exports.Rewriter
startsLine = not prevTag or (prevTag in LINEBREAKS)
value = new String('{')
value.generated = yes
tok = @generate '{', value, token[2]
tok = @generate '{', value
tokens.splice idx, 0, tok
@detectEnd i + 2, condition, action
2
@@ -154,6 +155,7 @@ class exports.Rewriter
addImplicitParentheses: ->
noCall = seenSingle = seenControl = no
callIndex = null
condition = (token, i) ->
[tag] = token
@@ -165,10 +167,10 @@ class exports.Rewriter
(tag is 'INDENT' and not seenControl)) and
(tag isnt 'INDENT' or
(@tag(i - 2) not in ['CLASS', 'EXTENDS'] and @tag(i - 1) not in IMPLICIT_BLOCK and
not ((post = @tokens[i + 1]) and post.generated and post[0] is '{')))
not (callIndex is i - 1 and (post = @tokens[i + 1]) and post.generated and post[0] is '{')))
action = (token, i) ->
@tokens.splice i, 0, @generate 'CALL_END', ')', token[2]
@tokens.splice i, 0, @generate 'CALL_END', ')'
@scanTokens (token, i, tokens) ->
tag = token[0]
@@ -185,17 +187,37 @@ class exports.Rewriter
return 1 unless callObject or
prev?.spaced and (prev.call or prev[0] in IMPLICIT_FUNC) and
(tag in IMPLICIT_CALL or not (token.spaced or token.newLine) and tag in IMPLICIT_UNSPACED_CALL)
callIndex = i
tokens.splice i, 0, @generate 'CALL_START', '(', token[2]
@detectEnd i + 1, condition, action
prev[0] = 'FUNC_EXIST' if prev[0] is '?'
2
# Add location data to all tokens generated by the rewriter.
addLocationDataToGeneratedTokens: ->
@scanTokens (token, i, tokens) ->
tag = token[0]
if (token.generated or token.explicit) and (not token[2])
if i > 0
prevToken = tokens[i-1]
token[2] =
first_line: prevToken[2].last_line
first_column: prevToken[2].last_column
last_line: prevToken[2].last_line
last_column: prevToken[2].last_column
else
token[2] =
first_line: 0
first_column: 0
last_line: 0
last_column: 0
return 1
# Because our grammar is LALR(1), it can't handle some single-line
# expressions that lack ending delimiters. The **Rewriter** 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.
addImplicitIndentation: ->
starter = indent = outdent = null
condition = (token, i) ->
@@ -248,14 +270,15 @@ class exports.Rewriter
# Generate the indentation tokens, based on another token on the same line.
indentation: (token, implicit = no) ->
indent = ['INDENT', 2, token[2]]
outdent = ['OUTDENT', 2, token[2]]
indent = ['INDENT', 2]
outdent = ['OUTDENT', 2]
indent.generated = outdent.generated = yes if implicit
indent.explicit = outdent.explicit = yes if not implicit
[indent, outdent]
# Create a generated token: one that exists due to a use of implicit syntax.
generate: (tag, value, line) ->
tok = [tag, value, line]
generate: (tag, value) ->
tok = [tag, value]
tok.generated = yes
tok

View File

@@ -293,10 +293,10 @@ test "#1627: prohibit conditional assignment of undefined variables", ->
doesNotThrow (-> CoffeeScript.compile "x = null; do -> x ?= 10"), "allow (x = null; do -> x ?= 10)"
doesNotThrow (-> CoffeeScript.compile "x = null; do -> x ||= 10"), "allow (x = null; do -> x ||= 10)"
doesNotThrow (-> CoffeeScript.compile "x = null; do -> x or= 10"), "allow (x = null; do -> x or= 10)"
throws (-> CoffeeScript.compile "-> -> -> x ?= 10"), null, "prohibit (-> -> -> x ?= 10)"
doesNotThrow (-> CoffeeScript.compile "x = null; -> -> -> x ?= 10"), "allow (x = null; -> -> -> x ?= 10)"
test "more existential assignment", ->
global.temp ?= 0
eq global.temp, 0
@@ -311,7 +311,7 @@ test "#1348, #1216: existential assignment compilation", ->
eq nonce, b
#the first ?= compiles into a statement; the second ?= compiles to a ternary expression
eq a ?= b ?= 1, nonce
if a then a ?= 2 else a = 3
eq a, nonce
@@ -375,3 +375,8 @@ test '#2532: compound assignment with terminator', ->
!
"
"""
test "#2613: parens on LHS of destructuring", ->
a = {}
[(a).b] = [1, 2, 3]
eq a.b, 1

View File

@@ -595,11 +595,6 @@ test "#1813: Passing class definitions as expressions", ->
eq result, B
test "#1966: external constructors should produce their return value", ->
ctor = -> {}
class A then constructor: ctor
ok (new A) not instanceof A
test "#1980: regression with an inherited class with static function members", ->
class A
@@ -680,3 +675,24 @@ test "#2052: classes should work in strict mode", ->
test "#2630: class bodies can't reference arguments", ->
throws ->
CoffeeScript.compile('class Test then arguments')
test "#2359: instanceof should work when extending native objects", ->
class MyError extends Error
ok new MyError instanceof MyError
test '#2359: external constructors returning "other typed" objets', ->
ctor = -> {}
class A then constructor: ctor
ok new A instanceof A
ok new ctor not instanceof A
ok new ctor not instanceof ctor
test "#2359: constructors should not return an explicit value", ->
throws -> CoffeeScript.run "class then constructor: -> return 5"
throws -> CoffeeScript.run """
class
constructor: ->
if foo
return bar: 7
baz()
"""

View File

@@ -244,8 +244,8 @@ test "Optimized range comprehensions.", ->
exxes = ('x' for [0...10])
ok exxes.join(' ') is 'x x x x x x x x x x'
test "Loop variables should be able to reference outer variables", ->
outer = 1
do ->
@@ -411,7 +411,8 @@ test "#1326: `by` value is uncached", ->
rangeCompileSimple = []
#exercises For.compile
for v,i in a by f() then forCompile.push i
for v, i in a by f()
forCompile.push i
#exercises Range.compileSimple
rangeCompileSimple = (i for i in [0..2] by g())
@@ -491,7 +492,7 @@ test "#2007: Return object literal from comprehension", ->
eq 2, y.length
eq 1, y[0].x
eq 0, y[1].x
test "#2274: Allow @values as loop variables", ->
obj = {
item: null
@@ -502,3 +503,41 @@ test "#2274: Allow @values as loop variables", ->
eq obj.item, null
obj.method()
eq obj.item, 3
test "#2525, #1187, #1208, #1758, looping over an array forwards", ->
list = [0, 1, 2, 3, 4]
ident = (x) -> x
arrayEq (i for i in list), list
arrayEq (index for i, index in list), list
arrayEq (i for i in list by 1), list
arrayEq (i for i in list by ident 1), list
arrayEq (i for i in list by ident(1) * 2), [0, 2, 4]
arrayEq (index for i, index in list by ident(1) * 2), [0, 2, 4]
test "#2525, #1187, #1208, #1758, looping over an array backwards", ->
list = [0, 1, 2, 3, 4]
backwards = [4, 3, 2, 1, 0]
ident = (x) -> x
arrayEq (i for i in list by -1), backwards
arrayEq (index for i, index in list by -1), backwards
arrayEq (i for i in list by ident -1), backwards
arrayEq (i for i in list by ident(-1) * 2), [4, 2, 0]
arrayEq (index for i, index in list by ident(-1) * 2), [4, 2, 0]

View File

@@ -550,3 +550,11 @@ test "#960: improved 'do'", ->
eq two, 2
func
eq ret, func
test "#2617: implicit call before unrelated implicit object", ->
pass = ->
true
result = if pass 1
one: 1
eq result.one, 1

View File

@@ -213,3 +213,15 @@ test "#2621: fancy destructuring in parameter lists", ->
eq(a, 'a')
func({prop1: {key1: 'key1'}, prop2: {key2: 'key2', key3: ['a', 'b', 'c']}})
test "#1435 Indented property access", ->
rec = -> rec: rec
eq 1, do ->
rec()
.rec ->
rec()
.rec ->
rec.rec()
.rec()
1

46
test/location.coffee Normal file
View File

@@ -0,0 +1,46 @@
testScript = '''
if true
x = 6
console.log "A console #{x + 7} log"
foo = "bar"
z = /// ^ (a#{foo}) ///
x = () ->
try
console.log "foo"
catch err
# Rewriter will generate explicit indentation here.
return null
'''
test "Verify location of generated tokens", ->
tokens = CoffeeScript.tokens "a = 79"
eq tokens.length, 4
aToken = tokens[0]
eq aToken[2].first_line, 0
eq aToken[2].first_column, 0
eq aToken[2].last_line, 0
eq aToken[2].last_column, 0
equalsToken = tokens[1]
eq equalsToken[2].first_line, 0
eq equalsToken[2].first_column, 2
eq equalsToken[2].last_line, 0
eq equalsToken[2].last_column, 2
numberToken = tokens[2]
eq numberToken[2].first_line, 0
eq numberToken[2].first_column, 4
eq numberToken[2].last_line, 0
eq numberToken[2].last_column, 5
test "Verify all tokens get a location", ->
doesNotThrow ->
tokens = CoffeeScript.tokens testScript
for token in tokens
ok !!token[2]

View File

@@ -1,3 +1,5 @@
return if global.testingBrowser
# REPL
# ----
Stream = require 'stream'