mirror of
https://github.com/jashkenas/coffeescript.git
synced 2026-05-03 03:00:14 -04:00
merged
This commit is contained in:
45
Cakefile
45
Cakefile
@@ -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.
|
||||
|
||||
1
Rakefile
1
Rakefile
@@ -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")
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
###
|
||||
CoffeeScript Compiler v1.4.0
|
||||
CoffeeScript Compiler v1.5.0
|
||||
Released under the MIT License
|
||||
###
|
||||
|
||||
|
||||
@@ -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 … <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">¶</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">'./coffee-script'</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 … <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">¶</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">'./coffee-script'</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">¶</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 = {}) -></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">¶</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 = {}) -></span>
|
||||
|
||||
@@ -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 … <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">¶</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 … <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">¶</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>
|
||||
|
||||
@@ -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 … <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">¶</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 … <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">¶</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">'fs'</span>
|
||||
<span class="nv">path = </span><span class="nx">require</span> <span class="s">'path'</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">'./lexer'</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">'./parser'</span>
|
||||
<span class="nv">vm = </span><span class="nx">require</span> <span class="s">'vm'</span>
|
||||
|
||||
<span class="nv">stripBOM = </span><span class="nf">(content) -></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">'fs'</span>
|
||||
<span class="nv">path = </span><span class="nx">require</span> <span class="s">'path'</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">'./lexer'</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">'./parser'</span>
|
||||
<span class="nv">vm = </span><span class="nx">require</span> <span class="s">'vm'</span></pre></div> </td> </tr> <tr id="section-2"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-2">¶</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">'.coffee'</span><span class="p">,</span> <span class="s">'.litcoffee'</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">¶</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) -></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">'utf8'</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">'.coffee'</span><span class="p">]</span> <span class="o">=</span> <span class="nf">(module, filename) -></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">'utf8'</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">¶</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">'1.4.0'</span></pre></div> </td> </tr> <tr id="section-3"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-3">¶</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">¶</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">'./helpers'</span></pre></div> </td> </tr> <tr id="section-5"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-5">¶</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">¶</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">'1.5.0'</span></pre></div> </td> </tr> <tr id="section-5"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-5">¶</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">'./helpers'</span></pre></div> </td> </tr> <tr id="section-6"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-6">¶</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 = {}) -></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">"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">"</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">"Generated by CoffeeScript </span><span class="si">#{</span><span class="nx">@VERSION</span><span class="si">}</span><span class="s">"</span>
|
||||
<span class="s">"// </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">"</span></pre></div> </td> </tr> <tr id="section-6"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-6">¶</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) -></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">¶</a> </div> <p>Parse a string of CoffeeScript code or an array of lexed tokens, and
|
||||
<span class="s">"// </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">"</span></pre></div> </td> </tr> <tr id="section-7"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-7">¶</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) -></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">¶</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) -></span>
|
||||
<span class="k">if</span> <span class="k">typeof</span> <span class="nx">source</span> <span class="o">is</span> <span class="s">'string'</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">¶</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">¶</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 = {}) -></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">¶</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">'.'</span></pre></div> </td> </tr> <tr id="section-10"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-10">¶</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">¶</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">'module'</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">¶</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">'.coffee'</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">¶</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">'.'</span></pre></div> </td> </tr> <tr id="section-11"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-11">¶</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">¶</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">'module'</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">¶</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">¶</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">¶</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 = {}) -></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">'eval'</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">¶</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">¶</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">'module'</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">'eval'</span><span class="p">)</span>
|
||||
<span class="nv">sandbox.require = _require = </span><span class="nf">(path) -></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">'paths'</span></pre></div> </td> </tr> <tr id="section-15"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-15">¶</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">'paths'</span></pre></div> </td> </tr> <tr id="section-16"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-16">¶</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) -></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">¶</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">¶</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">¶</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">¶</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">-></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">''</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">''</span>
|
||||
|
||||
<span class="nx">tag</span>
|
||||
<span class="nv">setInput: </span><span class="nf">(@tokens) -></span>
|
||||
<span class="vi">@pos = </span><span class="mi">0</span>
|
||||
|
||||
@@ -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 … <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">¶</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 … <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">¶</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">'--nodejs [ARGS]'</span><span class="p">,</span> <span class="s">'pass options directly to the "node" binary'</span><span class="p">]</span>
|
||||
<span class="p">[</span><span class="s">'-o'</span><span class="p">,</span> <span class="s">'--output [DIR]'</span><span class="p">,</span> <span class="s">'set the output directory for compiled JavaScript'</span><span class="p">]</span>
|
||||
<span class="p">[</span><span class="s">'-p'</span><span class="p">,</span> <span class="s">'--print'</span><span class="p">,</span> <span class="s">'print out the compiled JavaScript'</span><span class="p">]</span>
|
||||
<span class="p">[</span><span class="s">'-r'</span><span class="p">,</span> <span class="s">'--require [FILE*]'</span><span class="p">,</span> <span class="s">'require a library before executing your script'</span><span class="p">]</span>
|
||||
<span class="p">[</span><span class="s">'-s'</span><span class="p">,</span> <span class="s">'--stdio'</span><span class="p">,</span> <span class="s">'listen for and compile scripts over stdio'</span><span class="p">]</span>
|
||||
<span class="p">[</span><span class="s">'-t'</span><span class="p">,</span> <span class="s">'--tokens'</span><span class="p">,</span> <span class="s">'print out the tokens that the lexer/rewriter produce'</span><span class="p">]</span>
|
||||
<span class="p">[</span><span class="s">'-v'</span><span class="p">,</span> <span class="s">'--version'</span><span class="p">,</span> <span class="s">'display the version number'</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">¶</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">'.coffee'</span><span class="p">,</span> <span class="s">'.litcoffee'</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">¶</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">-></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">'./repl'</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">'./repl'</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">"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">."</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">'./repl'</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">'./repl'</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">'coffee'</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">¶</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) -></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) -></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) -></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">'ENOENT'</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">'ENOENT'</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">'.coffee'</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">"</span><span class="si">#{</span><span class="nx">source</span><span class="si">}</span><span class="s">.coffee"</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">"File not found: </span><span class="si">#{</span><span class="nx">source</span><span class="si">}</span><span class="s">"</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">'node_modules'</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) -></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">'ENOENT'</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">-></span> <span class="kc">null</span>
|
||||
<span class="nx">files</span><span class="p">.</span><span class="nx">forEach</span> <span class="nf">(file) -></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">'.coffee'</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) -></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">'ENOENT'</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">'compile'</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) -></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">-></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">'\n'</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">¶</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">-></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">'.'</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">¶</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">'\n'</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">¶</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) -></span>
|
||||
|
||||
@@ -173,7 +167,7 @@ such as <code>--lint</code> or <code>--print</code>.</p> </td>
|
||||
|
||||
<span class="nv">rewatch = </span><span class="nf">-></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">¶</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) -></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">¶</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) -></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">-></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">>=</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) -></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">¶</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">¶</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) -></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) -></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">'ENOENT'</span>
|
||||
<span class="nx">timeLog</span> <span class="s">"removed </span><span class="si">#{</span><span class="nx">source</span><span class="si">}</span><span class="s">"</span></pre></div> </td> </tr> <tr id="section-16"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-16">¶</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) -></span>
|
||||
<span class="nx">timeLog</span> <span class="s">"removed </span><span class="si">#{</span><span class="nx">source</span><span class="si">}</span><span class="s">"</span></pre></div> </td> </tr> <tr id="section-15"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-15">¶</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) -></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">'.js'</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">'.'</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">¶</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">¶</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) -></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">"compiled </span><span class="si">#{</span><span class="nx">source</span><span class="si">}</span><span class="s">"</span>
|
||||
<span class="nx">exists</span> <span class="nx">jsDir</span><span class="p">,</span> <span class="nf">(itExists) -></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">"mkdir -p </span><span class="si">#{</span><span class="nx">jsDir</span><span class="si">}</span><span class="s">"</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">¶</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) -></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">¶</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) -></span>
|
||||
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span> <span class="s">"</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">"</span></pre></div> </td> </tr> <tr id="section-20"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-20">¶</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">"mkdir -p </span><span class="si">#{</span><span class="nx">jsDir</span><span class="si">}</span><span class="s">"</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">¶</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) -></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">¶</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) -></span>
|
||||
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span> <span class="s">"</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">"</span></pre></div> </td> </tr> <tr id="section-19"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-19">¶</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) -></span>
|
||||
<span class="nv">printIt = </span><span class="nf">(buffer) -></span> <span class="nx">printLine</span> <span class="nx">file</span> <span class="o">+</span> <span class="s">':\t'</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">'/../../extras/jsl.conf'</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">'data'</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">'data'</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">¶</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) -></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">¶</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) -></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">'\\n'</span><span class="p">)]</span>
|
||||
<span class="s">"[</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="nx">printLine</span> <span class="nx">strings</span><span class="p">.</span><span class="nx">join</span><span class="p">(</span><span class="s">' '</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">¶</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">'\\n'</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">"[</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">]"</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">' '</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">¶</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">-></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">¶</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) -></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">¶</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">¶</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) -></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">'.litcoffee'</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">¶</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">-></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">¶</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">¶</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">-></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">¶</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">-></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">¶</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">-></span>
|
||||
<span class="nx">printLine</span> <span class="s">"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">"</span>
|
||||
|
||||
</pre></div> </td> </tr> </tbody> </table> </div> </body> </html>
|
||||
@@ -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 … <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">¶</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 … <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">¶</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) -></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">' '</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">' '</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">'$$ = $1;'</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">"(</span><span class="si">#{</span><span class="nx">action</span><span class="si">}</span><span class="s">())"</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">'$&yy.'</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">"(</span><span class="si">#{</span><span class="nx">action</span><span class="si">}</span><span class="s">())"</span></pre></div> </td> </tr> <tr id="section-6"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-6">¶</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">'$&yy.'</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">'yy.$&'</span>
|
||||
<span class="p">[</span><span class="nx">patternString</span><span class="p">,</span> <span class="s">"$$ = </span><span class="si">#{</span><span class="nx">action</span><span class="si">}</span><span class="s">;"</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">¶</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">¶</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">'yy.$&'</span></pre></div> </td> </tr> <tr id="section-7"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-7">¶</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) -></span>
|
||||
<span class="k">if</span> <span class="o">not</span> <span class="nx">last</span>
|
||||
<span class="s">"yy.addLocationDataFn(@</span><span class="si">#{</span><span class="nx">first</span><span class="si">}</span><span class="s">)"</span>
|
||||
<span class="k">else</span>
|
||||
<span class="s">"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">)"</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">'$1'</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">'$1'</span><span class="p">,</span> <span class="s">'$2'</span><span class="p">)</span>
|
||||
|
||||
<span class="p">[</span><span class="nx">patternString</span><span class="p">,</span> <span class="s">"$$ = </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">);"</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">¶</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">¶</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">¶</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">¶</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">''</span><span class="p">,</span> <span class="nf">-></span> <span class="k">new</span> <span class="nx">Block</span>
|
||||
<span class="nx">o</span> <span class="s">'Body'</span>
|
||||
<span class="nx">o</span> <span class="s">'Block TERMINATOR'</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">¶</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">¶</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">'Line'</span><span class="p">,</span> <span class="nf">-></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">'Body TERMINATOR Line'</span><span class="p">,</span> <span class="nf">-></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">'Body TERMINATOR'</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">¶</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">¶</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">'Expression'</span>
|
||||
<span class="nx">o</span> <span class="s">'Statement'</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">¶</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">¶</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">'Return'</span>
|
||||
<span class="nx">o</span> <span class="s">'Comment'</span>
|
||||
<span class="nx">o</span> <span class="s">'STATEMENT'</span><span class="p">,</span> <span class="nf">-></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">¶</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">¶</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">'Switch'</span>
|
||||
<span class="nx">o</span> <span class="s">'Class'</span>
|
||||
<span class="nx">o</span> <span class="s">'Throw'</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">¶</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">¶</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">'INDENT OUTDENT'</span><span class="p">,</span> <span class="nf">-></span> <span class="k">new</span> <span class="nx">Block</span>
|
||||
<span class="nx">o</span> <span class="s">'INDENT Body OUTDENT'</span><span class="p">,</span> <span class="nf">-></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">¶</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">¶</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">'IDENTIFIER'</span><span class="p">,</span> <span class="nf">-></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">¶</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">¶</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">'NUMBER'</span><span class="p">,</span> <span class="nf">-></span> <span class="k">new</span> <span class="nx">Literal</span> <span class="nx">$1</span>
|
||||
<span class="nx">o</span> <span class="s">'STRING'</span><span class="p">,</span> <span class="nf">-></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">¶</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">¶</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">'AlphaNumeric'</span>
|
||||
<span class="nx">o</span> <span class="s">'JS'</span><span class="p">,</span> <span class="nf">-></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">'UNDEFINED'</span><span class="p">,</span> <span class="nf">-></span> <span class="k">new</span> <span class="nx">Undefined</span>
|
||||
<span class="nx">o</span> <span class="s">'NULL'</span><span class="p">,</span> <span class="nf">-></span> <span class="k">new</span> <span class="nx">Null</span>
|
||||
<span class="nx">o</span> <span class="s">'BOOL'</span><span class="p">,</span> <span class="nf">-></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">¶</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">¶</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">'Assignable = Expression'</span><span class="p">,</span> <span class="nf">-></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">'Assignable = TERMINATOR Expression'</span><span class="p">,</span> <span class="nf">-></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">'Assignable = INDENT Expression OUTDENT'</span><span class="p">,</span> <span class="nf">-></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">¶</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">¶</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">'ObjAssignable'</span><span class="p">,</span> <span class="nf">-></span> <span class="k">new</span> <span class="nx">Value</span> <span class="nx">$1</span>
|
||||
<span class="nx">o</span> <span class="s">'ObjAssignable : Expression'</span><span class="p">,</span> <span class="nf">-></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">'object'</span>
|
||||
<span class="nx">o</span> <span class="s">'ObjAssignable'</span><span class="p">,</span> <span class="nf">-></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">'ObjAssignable : Expression'</span><span class="p">,</span> <span class="nf">-></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">'object'</span>
|
||||
<span class="nx">o</span> <span class="s">'ObjAssignable :</span>
|
||||
<span class="s"> INDENT Expression OUTDENT'</span><span class="p">,</span> <span class="nf">-></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">'object'</span>
|
||||
<span class="s"> INDENT Expression OUTDENT'</span><span class="p">,</span> <span class="nf">-></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">'object'</span>
|
||||
<span class="nx">o</span> <span class="s">'Comment'</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">'Identifier'</span>
|
||||
<span class="nx">o</span> <span class="s">'AlphaNumeric'</span>
|
||||
<span class="nx">o</span> <span class="s">'ThisProperty'</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">¶</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">¶</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">'RETURN Expression'</span><span class="p">,</span> <span class="nf">-></span> <span class="k">new</span> <span class="nx">Return</span> <span class="nx">$2</span>
|
||||
<span class="nx">o</span> <span class="s">'RETURN'</span><span class="p">,</span> <span class="nf">-></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">¶</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">¶</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">'HERECOMMENT'</span><span class="p">,</span> <span class="nf">-></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">¶</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">¶</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">'PARAM_START ParamList PARAM_END FuncGlyph Block'</span><span class="p">,</span> <span class="nf">-></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">'FuncGlyph Block'</span><span class="p">,</span> <span class="nf">-></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">¶</a> </div> <p>CoffeeScript has two different symbols for functions. <code>-></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">¶</a> </div> <p>CoffeeScript has two different symbols for functions. <code>-></code> is for ordinary
|
||||
functions, and <code>=></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">'->'</span><span class="p">,</span> <span class="nf">-></span> <span class="s">'func'</span>
|
||||
<span class="nx">o</span> <span class="s">'=>'</span><span class="p">,</span> <span class="nf">-></span> <span class="s">'boundfunc'</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">¶</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">¶</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">''</span>
|
||||
<span class="nx">o</span> <span class="s">','</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">¶</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">¶</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">''</span><span class="p">,</span> <span class="nf">-></span> <span class="p">[]</span>
|
||||
<span class="nx">o</span> <span class="s">'Param'</span><span class="p">,</span> <span class="nf">-></span> <span class="p">[</span><span class="nx">$1</span><span class="p">]</span>
|
||||
<span class="nx">o</span> <span class="s">'ParamList , Param'</span><span class="p">,</span> <span class="nf">-></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">'ParamList OptComma TERMINATOR Param'</span><span class="p">,</span> <span class="nf">-></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">'ParamList OptComma INDENT ParamList OptComma OUTDENT'</span><span class="p">,</span> <span class="nf">-></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">¶</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">¶</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">'ParamVar'</span><span class="p">,</span> <span class="nf">-></span> <span class="k">new</span> <span class="nx">Param</span> <span class="nx">$1</span>
|
||||
<span class="nx">o</span> <span class="s">'ParamVar ...'</span><span class="p">,</span> <span class="nf">-></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">'ParamVar = Expression'</span><span class="p">,</span> <span class="nf">-></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">¶</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">¶</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">'Identifier'</span>
|
||||
<span class="nx">o</span> <span class="s">'ThisProperty'</span>
|
||||
<span class="nx">o</span> <span class="s">'Array'</span>
|
||||
<span class="nx">o</span> <span class="s">'Object'</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">¶</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">¶</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">'Expression ...'</span><span class="p">,</span> <span class="nf">-></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">¶</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">'Identifier'</span><span class="p">,</span> <span class="nf">-></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">¶</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">'Identifier'</span><span class="p">,</span> <span class="nf">-></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">'Value Accessor'</span><span class="p">,</span> <span class="nf">-></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">'Invocation Accessor'</span><span class="p">,</span> <span class="nf">-></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">'Invocation Accessor'</span><span class="p">,</span> <span class="nf">-></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">'ThisProperty'</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">¶</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">¶</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">'SimpleAssignable'</span>
|
||||
<span class="nx">o</span> <span class="s">'Array'</span><span class="p">,</span> <span class="nf">-></span> <span class="k">new</span> <span class="nx">Value</span> <span class="nx">$1</span>
|
||||
<span class="nx">o</span> <span class="s">'Object'</span><span class="p">,</span> <span class="nf">-></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">¶</a> </div> <p>The types of things that can be treated as values -- assigned to, invoked
|
||||
<span class="nx">o</span> <span class="s">'Array'</span><span class="p">,</span> <span class="nf">-></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">'Object'</span><span class="p">,</span> <span class="nf">-></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">¶</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">'Assignable'</span>
|
||||
<span class="nx">o</span> <span class="s">'Literal'</span><span class="p">,</span> <span class="nf">-></span> <span class="k">new</span> <span class="nx">Value</span> <span class="nx">$1</span>
|
||||
<span class="nx">o</span> <span class="s">'Parenthetical'</span><span class="p">,</span> <span class="nf">-></span> <span class="k">new</span> <span class="nx">Value</span> <span class="nx">$1</span>
|
||||
<span class="nx">o</span> <span class="s">'Range'</span><span class="p">,</span> <span class="nf">-></span> <span class="k">new</span> <span class="nx">Value</span> <span class="nx">$1</span>
|
||||
<span class="nx">o</span> <span class="s">'Literal'</span><span class="p">,</span> <span class="nf">-></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">'Parenthetical'</span><span class="p">,</span> <span class="nf">-></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">'Range'</span><span class="p">,</span> <span class="nf">-></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">'This'</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">¶</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">¶</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">'. Identifier'</span><span class="p">,</span> <span class="nf">-></span> <span class="k">new</span> <span class="nx">Access</span> <span class="nx">$2</span>
|
||||
<span class="nx">o</span> <span class="s">'?. Identifier'</span><span class="p">,</span> <span class="nf">-></span> <span class="k">new</span> <span class="nx">Access</span> <span class="nx">$2</span><span class="p">,</span> <span class="s">'soak'</span>
|
||||
<span class="nx">o</span> <span class="s">':: Identifier'</span><span class="p">,</span> <span class="nf">-></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">'prototype'</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">':: Identifier'</span><span class="p">,</span> <span class="nf">-></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">'prototype'</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">'::'</span><span class="p">,</span> <span class="nf">-></span> <span class="k">new</span> <span class="nx">Access</span> <span class="k">new</span> <span class="nx">Literal</span> <span class="s">'prototype'</span>
|
||||
<span class="nx">o</span> <span class="s">'Index'</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">¶</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">¶</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">'INDEX_START IndexValue INDEX_END'</span><span class="p">,</span> <span class="nf">-></span> <span class="nx">$2</span>
|
||||
<span class="nx">o</span> <span class="s">'INDEX_SOAK Index'</span><span class="p">,</span> <span class="nf">-></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">'Expression'</span><span class="p">,</span> <span class="nf">-></span> <span class="k">new</span> <span class="nx">Index</span> <span class="nx">$1</span>
|
||||
<span class="nx">o</span> <span class="s">'Slice'</span><span class="p">,</span> <span class="nf">-></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">¶</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">¶</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">'{ AssignList OptComma }'</span><span class="p">,</span> <span class="nf">-></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">¶</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">¶</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">''</span><span class="p">,</span> <span class="nf">-></span> <span class="p">[]</span>
|
||||
<span class="nx">o</span> <span class="s">'AssignObj'</span><span class="p">,</span> <span class="nf">-></span> <span class="p">[</span><span class="nx">$1</span><span class="p">]</span>
|
||||
<span class="nx">o</span> <span class="s">'AssignList , AssignObj'</span><span class="p">,</span> <span class="nf">-></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">'AssignList OptComma TERMINATOR AssignObj'</span><span class="p">,</span> <span class="nf">-></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">'AssignList OptComma INDENT AssignList OptComma OUTDENT'</span><span class="p">,</span> <span class="nf">-></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">¶</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">¶</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">'CLASS'</span><span class="p">,</span> <span class="nf">-></span> <span class="k">new</span> <span class="nx">Class</span>
|
||||
<span class="nx">o</span> <span class="s">'CLASS Block'</span><span class="p">,</span> <span class="nf">-></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">'CLASS SimpleAssignable Block'</span><span class="p">,</span> <span class="nf">-></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">'CLASS SimpleAssignable EXTENDS Expression'</span><span class="p">,</span> <span class="nf">-></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">'CLASS SimpleAssignable EXTENDS Expression Block'</span><span class="p">,</span> <span class="nf">-></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">¶</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">¶</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">'Value OptFuncExist Arguments'</span><span class="p">,</span> <span class="nf">-></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">'Invocation OptFuncExist Arguments'</span><span class="p">,</span> <span class="nf">-></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">'SUPER'</span><span class="p">,</span> <span class="nf">-></span> <span class="k">new</span> <span class="nx">Call</span> <span class="s">'super'</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">'arguments'</span><span class="p">]</span>
|
||||
<span class="nx">o</span> <span class="s">'SUPER Arguments'</span><span class="p">,</span> <span class="nf">-></span> <span class="k">new</span> <span class="nx">Call</span> <span class="s">'super'</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">¶</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">¶</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">''</span><span class="p">,</span> <span class="nf">-></span> <span class="kc">no</span>
|
||||
<span class="nx">o</span> <span class="s">'FUNC_EXIST'</span><span class="p">,</span> <span class="nf">-></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">¶</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">¶</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">'CALL_START CALL_END'</span><span class="p">,</span> <span class="nf">-></span> <span class="p">[]</span>
|
||||
<span class="nx">o</span> <span class="s">'CALL_START ArgList OptComma CALL_END'</span><span class="p">,</span> <span class="nf">-></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">¶</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">'THIS'</span><span class="p">,</span> <span class="nf">-></span> <span class="k">new</span> <span class="nx">Value</span> <span class="k">new</span> <span class="nx">Literal</span> <span class="s">'this'</span>
|
||||
<span class="nx">o</span> <span class="s">'@'</span><span class="p">,</span> <span class="nf">-></span> <span class="k">new</span> <span class="nx">Value</span> <span class="k">new</span> <span class="nx">Literal</span> <span class="s">'this'</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">¶</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">'@ Identifier'</span><span class="p">,</span> <span class="nf">-></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">'this'</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">'this'</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">¶</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">¶</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">'THIS'</span><span class="p">,</span> <span class="nf">-></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">'this'</span>
|
||||
<span class="nx">o</span> <span class="s">'@'</span><span class="p">,</span> <span class="nf">-></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">'this'</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">¶</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">'@ Identifier'</span><span class="p">,</span> <span class="nf">-></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">'this'</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">'this'</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">¶</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">'[ ]'</span><span class="p">,</span> <span class="nf">-></span> <span class="k">new</span> <span class="nx">Arr</span> <span class="p">[]</span>
|
||||
<span class="nx">o</span> <span class="s">'[ ArgList OptComma ]'</span><span class="p">,</span> <span class="nf">-></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">¶</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">¶</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">'..'</span><span class="p">,</span> <span class="nf">-></span> <span class="s">'inclusive'</span>
|
||||
<span class="nx">o</span> <span class="s">'...'</span><span class="p">,</span> <span class="nf">-></span> <span class="s">'exclusive'</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">¶</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">¶</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">'[ Expression RangeDots Expression ]'</span><span class="p">,</span> <span class="nf">-></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">¶</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">¶</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">'Expression RangeDots Expression'</span><span class="p">,</span> <span class="nf">-></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">'Expression RangeDots'</span><span class="p">,</span> <span class="nf">-></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">'RangeDots Expression'</span><span class="p">,</span> <span class="nf">-></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">'RangeDots'</span><span class="p">,</span> <span class="nf">-></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">¶</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">¶</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">'Arg'</span><span class="p">,</span> <span class="nf">-></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">'ArgList OptComma TERMINATOR Arg'</span><span class="p">,</span> <span class="nf">-></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">'INDENT ArgList OptComma OUTDENT'</span><span class="p">,</span> <span class="nf">-></span> <span class="nx">$2</span>
|
||||
<span class="nx">o</span> <span class="s">'ArgList OptComma INDENT ArgList OptComma OUTDENT'</span><span class="p">,</span> <span class="nf">-></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">¶</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">¶</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">'Expression'</span>
|
||||
<span class="nx">o</span> <span class="s">'Splat'</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">¶</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">¶</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">'Expression'</span>
|
||||
<span class="nx">o</span> <span class="s">'SimpleArgs , Expression'</span><span class="p">,</span> <span class="nf">-></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">¶</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">¶</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">'TRY Block'</span><span class="p">,</span> <span class="nf">-></span> <span class="k">new</span> <span class="nx">Try</span> <span class="nx">$2</span>
|
||||
<span class="nx">o</span> <span class="s">'TRY Block Catch'</span><span class="p">,</span> <span class="nf">-></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">'TRY Block FINALLY Block'</span><span class="p">,</span> <span class="nf">-></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">'TRY Block Catch FINALLY Block'</span><span class="p">,</span> <span class="nf">-></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">¶</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">¶</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">'CATCH Identifier Block'</span><span class="p">,</span> <span class="nf">-></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">¶</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">'CATCH Object Block'</span><span class="p">,</span> <span class="nf">-></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">¶</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">'THROW Expression'</span><span class="p">,</span> <span class="nf">-></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">¶</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">¶</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">'( Body )'</span><span class="p">,</span> <span class="nf">-></span> <span class="k">new</span> <span class="nx">Parens</span> <span class="nx">$2</span>
|
||||
<span class="nx">o</span> <span class="s">'( INDENT Body OUTDENT )'</span><span class="p">,</span> <span class="nf">-></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">¶</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">¶</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">'WHILE Expression'</span><span class="p">,</span> <span class="nf">-></span> <span class="k">new</span> <span class="nx">While</span> <span class="nx">$2</span>
|
||||
<span class="nx">o</span> <span class="s">'WHILE Expression WHEN Expression'</span><span class="p">,</span> <span class="nf">-></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">'UNTIL Expression'</span><span class="p">,</span> <span class="nf">-></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">'UNTIL Expression WHEN Expression'</span><span class="p">,</span> <span class="nf">-></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">¶</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">¶</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">'WhileSource Block'</span><span class="p">,</span> <span class="nf">-></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">'Statement WhileSource'</span><span class="p">,</span> <span class="nf">-></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">'Expression WhileSource'</span><span class="p">,</span> <span class="nf">-></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">'Statement WhileSource'</span><span class="p">,</span> <span class="nf">-></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">'Expression WhileSource'</span><span class="p">,</span> <span class="nf">-></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">'Loop'</span><span class="p">,</span> <span class="nf">-></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">'LOOP Block'</span><span class="p">,</span> <span class="nf">-></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">'true'</span><span class="p">).</span><span class="nx">addBody</span> <span class="nx">$2</span>
|
||||
<span class="nx">o</span> <span class="s">'LOOP Expression'</span><span class="p">,</span> <span class="nf">-></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">'true'</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">¶</a> </div> <p>Array, object, and range comprehensions, at the most generic level.
|
||||
<span class="nx">o</span> <span class="s">'LOOP Block'</span><span class="p">,</span> <span class="nf">-></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">'true'</span><span class="p">).</span><span class="nx">addBody</span> <span class="nx">$2</span>
|
||||
<span class="nx">o</span> <span class="s">'LOOP Expression'</span><span class="p">,</span> <span class="nf">-></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">'true'</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">¶</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">'Statement ForBody'</span><span class="p">,</span> <span class="nf">-></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">'FOR Range'</span><span class="p">,</span> <span class="nf">-></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">'FOR Range'</span><span class="p">,</span> <span class="nf">-></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">'ForStart ForSource'</span><span class="p">,</span> <span class="nf">-></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">'FOR ForVariables'</span><span class="p">,</span> <span class="nf">-></span> <span class="nx">$2</span>
|
||||
<span class="nx">o</span> <span class="s">'FOR OWN ForVariables'</span><span class="p">,</span> <span class="nf">-></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">¶</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">¶</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">'Identifier'</span>
|
||||
<span class="nx">o</span> <span class="s">'ThisProperty'</span>
|
||||
<span class="nx">o</span> <span class="s">'Array'</span><span class="p">,</span> <span class="nf">-></span> <span class="k">new</span> <span class="nx">Value</span> <span class="nx">$1</span>
|
||||
<span class="nx">o</span> <span class="s">'Object'</span><span class="p">,</span> <span class="nf">-></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">¶</a> </div> <p>An array or range comprehension has variables for the current element
|
||||
<span class="nx">o</span> <span class="s">'Array'</span><span class="p">,</span> <span class="nf">-></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">'Object'</span><span class="p">,</span> <span class="nf">-></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">¶</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">'ForValue'</span><span class="p">,</span> <span class="nf">-></span> <span class="p">[</span><span class="nx">$1</span><span class="p">]</span>
|
||||
<span class="nx">o</span> <span class="s">'ForValue , ForValue'</span><span class="p">,</span> <span class="nf">-></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">¶</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">¶</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">'FORIN Expression'</span><span class="p">,</span> <span class="nf">-></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">'When'</span>
|
||||
<span class="nx">o</span> <span class="s">'Whens When'</span><span class="p">,</span> <span class="nf">-></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">¶</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">¶</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">'LEADING_WHEN SimpleArgs Block'</span><span class="p">,</span> <span class="nf">-></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">'LEADING_WHEN SimpleArgs Block TERMINATOR'</span><span class="p">,</span> <span class="nf">-></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">¶</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">¶</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">'IF Expression Block'</span><span class="p">,</span> <span class="nf">-></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">'IfBlock ELSE IF Expression Block'</span><span class="p">,</span> <span class="nf">-></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">¶</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">¶</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">'IfBlock'</span>
|
||||
<span class="nx">o</span> <span class="s">'IfBlock ELSE Block'</span><span class="p">,</span> <span class="nf">-></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">'Statement POST_IF Expression'</span><span class="p">,</span> <span class="nf">-></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">'Expression POST_IF Expression'</span><span class="p">,</span> <span class="nf">-></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">¶</a> </div> <p>Arithmetic and logical operators, working on one or more operands.
|
||||
<span class="nx">o</span> <span class="s">'Statement POST_IF Expression'</span><span class="p">,</span> <span class="nf">-></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">'Expression POST_IF Expression'</span><span class="p">,</span> <span class="nf">-></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">¶</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">'UNARY Expression'</span><span class="p">,</span> <span class="nf">-></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">'- Expression'</span><span class="p">,</span> <span class="p">(</span><span class="nf">-></span> <span class="k">new</span> <span class="nx">Op</span> <span class="s">'-'</span><span class="p">,</span> <span class="nx">$2</span><span class="p">),</span> <span class="nv">prec: </span><span class="s">'UNARY'</span>
|
||||
<span class="nx">o</span> <span class="s">'+ Expression'</span><span class="p">,</span> <span class="p">(</span><span class="nf">-></span> <span class="k">new</span> <span class="nx">Op</span> <span class="s">'+'</span><span class="p">,</span> <span class="nx">$2</span><span class="p">),</span> <span class="nv">prec: </span><span class="s">'UNARY'</span>
|
||||
<span class="nx">o</span> <span class="s">'UNARY Expression'</span><span class="p">,</span> <span class="nf">-></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">'- Expression'</span><span class="p">,</span> <span class="p">(</span><span class="nf">-></span> <span class="nx">Op</span><span class="p">.</span><span class="nx">create</span> <span class="s">'-'</span><span class="p">,</span> <span class="nx">$2</span><span class="p">),</span> <span class="nv">prec: </span><span class="s">'UNARY'</span>
|
||||
<span class="nx">o</span> <span class="s">'+ Expression'</span><span class="p">,</span> <span class="p">(</span><span class="nf">-></span> <span class="nx">Op</span><span class="p">.</span><span class="nx">create</span> <span class="s">'+'</span><span class="p">,</span> <span class="nx">$2</span><span class="p">),</span> <span class="nv">prec: </span><span class="s">'UNARY'</span>
|
||||
|
||||
<span class="nx">o</span> <span class="s">'-- SimpleAssignable'</span><span class="p">,</span> <span class="nf">-></span> <span class="k">new</span> <span class="nx">Op</span> <span class="s">'--'</span><span class="p">,</span> <span class="nx">$2</span>
|
||||
<span class="nx">o</span> <span class="s">'++ SimpleAssignable'</span><span class="p">,</span> <span class="nf">-></span> <span class="k">new</span> <span class="nx">Op</span> <span class="s">'++'</span><span class="p">,</span> <span class="nx">$2</span>
|
||||
<span class="nx">o</span> <span class="s">'SimpleAssignable --'</span><span class="p">,</span> <span class="nf">-></span> <span class="k">new</span> <span class="nx">Op</span> <span class="s">'--'</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">'SimpleAssignable ++'</span><span class="p">,</span> <span class="nf">-></span> <span class="k">new</span> <span class="nx">Op</span> <span class="s">'++'</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">¶</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">'Expression ?'</span><span class="p">,</span> <span class="nf">-></span> <span class="k">new</span> <span class="nx">Existence</span> <span class="nx">$1</span>
|
||||
<span class="nx">o</span> <span class="s">'-- SimpleAssignable'</span><span class="p">,</span> <span class="nf">-></span> <span class="nx">Op</span><span class="p">.</span><span class="nx">create</span> <span class="s">'--'</span><span class="p">,</span> <span class="nx">$2</span>
|
||||
<span class="nx">o</span> <span class="s">'++ SimpleAssignable'</span><span class="p">,</span> <span class="nf">-></span> <span class="nx">Op</span><span class="p">.</span><span class="nx">create</span> <span class="s">'++'</span><span class="p">,</span> <span class="nx">$2</span>
|
||||
<span class="nx">o</span> <span class="s">'SimpleAssignable --'</span><span class="p">,</span> <span class="nf">-></span> <span class="nx">Op</span><span class="p">.</span><span class="nx">create</span> <span class="s">'--'</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">'SimpleAssignable ++'</span><span class="p">,</span> <span class="nf">-></span> <span class="nx">Op</span><span class="p">.</span><span class="nx">create</span> <span class="s">'++'</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">¶</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">'Expression ?'</span><span class="p">,</span> <span class="nf">-></span> <span class="k">new</span> <span class="nx">Existence</span> <span class="nx">$1</span>
|
||||
|
||||
<span class="nx">o</span> <span class="s">'Expression + Expression'</span><span class="p">,</span> <span class="nf">-></span> <span class="k">new</span> <span class="nx">Op</span> <span class="s">'+'</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">'Expression - Expression'</span><span class="p">,</span> <span class="nf">-></span> <span class="k">new</span> <span class="nx">Op</span> <span class="s">'-'</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">'Expression + Expression'</span><span class="p">,</span> <span class="nf">-></span> <span class="nx">Op</span><span class="p">.</span><span class="nx">create</span> <span class="s">'+'</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">'Expression - Expression'</span><span class="p">,</span> <span class="nf">-></span> <span class="nx">Op</span><span class="p">.</span><span class="nx">create</span> <span class="s">'-'</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">'Expression MATH Expression'</span><span class="p">,</span> <span class="nf">-></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">'Expression SHIFT Expression'</span><span class="p">,</span> <span class="nf">-></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">'Expression COMPARE Expression'</span><span class="p">,</span> <span class="nf">-></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">'Expression LOGIC Expression'</span><span class="p">,</span> <span class="nf">-></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">'Expression MATH Expression'</span><span class="p">,</span> <span class="nf">-></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">'Expression SHIFT Expression'</span><span class="p">,</span> <span class="nf">-></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">'Expression COMPARE Expression'</span><span class="p">,</span> <span class="nf">-></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">'Expression LOGIC Expression'</span><span class="p">,</span> <span class="nf">-></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">'Expression RELATION Expression'</span><span class="p">,</span> <span class="nf">-></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">'!'</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">'SimpleAssignable COMPOUND_ASSIGN</span>
|
||||
<span class="s"> Expression'</span><span class="p">,</span> <span class="nf">-></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">'SimpleAssignable COMPOUND_ASSIGN</span>
|
||||
<span class="s"> INDENT Expression OUTDENT'</span><span class="p">,</span> <span class="nf">-></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">'SimpleAssignable COMPOUND_ASSIGN TERMINATOR</span>
|
||||
<span class="s"> Expression'</span><span class="p">,</span> <span class="nf">-></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">'SimpleAssignable EXTENDS Expression'</span><span class="p">,</span> <span class="nf">-></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">¶</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">¶</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">¶</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">¶</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">'right'</span><span class="p">,</span> <span class="s">'FORIN'</span><span class="p">,</span> <span class="s">'FOROF'</span><span class="p">,</span> <span class="s">'BY'</span><span class="p">,</span> <span class="s">'WHEN'</span><span class="p">]</span>
|
||||
<span class="p">[</span><span class="s">'right'</span><span class="p">,</span> <span class="s">'IF'</span><span class="p">,</span> <span class="s">'ELSE'</span><span class="p">,</span> <span class="s">'FOR'</span><span class="p">,</span> <span class="s">'WHILE'</span><span class="p">,</span> <span class="s">'UNTIL'</span><span class="p">,</span> <span class="s">'LOOP'</span><span class="p">,</span> <span class="s">'SUPER'</span><span class="p">,</span> <span class="s">'CLASS'</span><span class="p">]</span>
|
||||
<span class="p">[</span><span class="s">'right'</span><span class="p">,</span> <span class="s">'POST_IF'</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">¶</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">¶</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">¶</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">¶</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">' '</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">"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">"</span> <span class="k">if</span> <span class="nx">name</span> <span class="o">is</span> <span class="s">'Root'</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">¶</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">¶</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>
|
||||
|
||||
@@ -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 … <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">¶</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 … <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">¶</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">¶</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) -></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">¶</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) -></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">¶</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) -></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">¶</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) -></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">¶</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) -></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">¶</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) -></span>
|
||||
<span class="nf">(obj) -></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">'object'</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">'updateLocationDataIfMissing'</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">¶</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) -></span>
|
||||
<span class="k">if</span> <span class="p">(</span><span class="s">"2"</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">"first_line"</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">"first_line"</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">"</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">-"</span> <span class="o">+</span>
|
||||
<span class="s">"</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">"</span>
|
||||
<span class="k">else</span>
|
||||
<span class="s">"No location data"</span>
|
||||
|
||||
</pre></div> </td> </tr> </tbody> </table> </div> </body> </html>
|
||||
@@ -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 … <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">¶</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">'./coffee-script'</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 … <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">¶</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">'./coffee-script'</span>
|
||||
|
||||
</pre></div> </td> </tr> </tbody> </table> </div> </body> </html>
|
||||
File diff suppressed because one or more lines are too long
@@ -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 … <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">¶</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 … <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">¶</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">'./scope'</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">'./lexer'</span></pre></div> </td> </tr> <tr id="section-2"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-2">¶</a> </div> <p>Import the helpers we plan to use.</p> </td> <td class="code"> <div class="highlight"><pre><span class="p">{</span><span class="nx">compact</span><span class="p">,</span> <span class="nx">flatten</span><span class="p">,</span> <span class="nx">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">'./helpers'</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">¶</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">-></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">'./lexer'</span></pre></div> </td> </tr> <tr id="section-2"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-2">¶</a> </div> <p>Import the helpers we plan to use.</p> </td> <td class="code"> <div class="highlight"><pre><span class="p">{</span><span class="nx">compact</span><span class="p">,</span> <span class="nx">flatten</span><span class="p">,</span> <span class="nx">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">'./helpers'</span></pre></div> </td> </tr> <tr id="section-3"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-3">¶</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">¶</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">-></span> <span class="kc">yes</span>
|
||||
<span class="nv">NO = </span><span class="nf">-></span> <span class="kc">no</span>
|
||||
<span class="nv">THIS = </span><span class="nf">-></span> <span class="k">this</span>
|
||||
<span class="nv">NEGATE = </span><span class="nf">-></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">¶</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">¶</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">-></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">¶</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">¶</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">¶</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">¶</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">¶</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">¶</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) -></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">'cannot use a pure statement in an expression.'</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">¶</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">¶</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) -></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">'ref'</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">¶</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) -></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"><</span> <span class="o">+</span><span class="nx">src</span> <span class="o"><</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">"</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">"</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">¶</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">¶</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) -></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">¶</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 = '', name = @constructor.name) -></span>
|
||||
<span class="nv">tree = </span><span class="s">'\n'</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">"??"</span>
|
||||
<span class="nv">tree = </span><span class="s">'\n'</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">": "</span> <span class="o">+</span> <span class="nx">name</span>
|
||||
<span class="nx">tree</span> <span class="o">+=</span> <span class="s">'?'</span> <span class="k">if</span> <span class="nx">@soak</span>
|
||||
<span class="nx">@eachChild</span> <span class="nf">(node) -></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">¶</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) -></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">-></span>
|
||||
<span class="k">new</span> <span class="nx">Op</span> <span class="s">'!'</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">'!'</span><span class="p">,</span> <span class="k">this</span>
|
||||
|
||||
<span class="nv">unwrapAll: </span><span class="nf">-></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">¶</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">¶</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">¶</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">¶</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">¶</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) -></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) -></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">¶</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">¶</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) -></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">'expressions'</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">¶</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) -></span>
|
||||
<span class="nv">children: </span><span class="p">[</span><span class="s">'expressions'</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">¶</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) -></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">¶</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">-></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">¶</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) -></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">¶</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">-></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">¶</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) -></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">¶</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">¶</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">-></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">¶</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">-></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">¶</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">-></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) -></span>
|
||||
@@ -122,7 +125,7 @@ it back out.</p> </td> <td class="code"> <
|
||||
|
||||
<span class="nv">jumps: </span><span class="nf">(o) -></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">¶</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">¶</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) -></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">¶</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) -></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">¶</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">¶</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) -></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">¶</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) -></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">¶</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">¶</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">"</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">;"</span>
|
||||
<span class="nv">code = </span><span class="s">"</span><span class="si">#{</span><span class="nx">code</span><span class="si">}</span><span class="s">\n"</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">'\n'</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">', '</span><span class="p">)</span> <span class="o">or</span> <span class="s">'void 0'</span>
|
||||
<span class="k">if</span> <span class="nx">codes</span><span class="p">.</span><span class="nx">length</span> <span class="o">></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">>=</span> <span class="nx">LEVEL_LIST</span> <span class="k">then</span> <span class="s">"(</span><span class="si">#{</span><span class="nx">code</span><span class="si">}</span><span class="s">)"</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">¶</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">></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">>=</span> <span class="nx">LEVEL_LIST</span> <span class="k">then</span> <span class="s">"(</span><span class="si">#{</span><span class="nx">code</span><span class="si">}</span><span class="s">)"</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">¶</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) -></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">"</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"</span></pre></div> </td> </tr> <tr id="section-30"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-30">¶</a> </div> <p>Compile the expressions body for the contents of a function, with
|
||||
<span class="s">"</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"</span></pre></div> </td> </tr> <tr id="section-31"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-31">¶</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) -></span>
|
||||
<span class="nv">code = post = </span><span class="s">''</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">",\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">"</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">",\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">"</span>
|
||||
<span class="nx">code</span> <span class="o">+=</span> <span class="s">';\n'</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">¶</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">¶</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) -></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">¶</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">¶</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">¶</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">¶</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) -></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">-></span> <span class="nx">@val</span>
|
||||
<span class="nv">constructor: </span><span class="nf">(@val) -></span></pre></div> </td> </tr> <tr id="section-34"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-34">¶</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">¶</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) -></span></pre></div> </td> </tr> <tr id="section-35"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-35">¶</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">¶</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) -></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) -></span>
|
||||
<span class="nx">@tab</span> <span class="o">+</span> <span class="s">"return</span><span class="si">#{</span><span class="p">[</span><span class="s">" </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">"</span> <span class="k">if</span> <span class="nx">@expression</span><span class="p">]</span><span class="si">}</span><span class="s">;"</span></pre></div> </td> </tr> <tr id="section-36"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-36">¶</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">¶</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">"return</span><span class="si">#{</span><span class="p">[</span><span class="s">" </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">"</span> <span class="k">if</span> <span class="nx">@expression</span><span class="p">]</span><span class="si">}</span><span class="s">;"</span></pre></div> </td> </tr> <tr id="section-37"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-37">¶</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">¶</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) -></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) -></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">'base'</span><span class="p">,</span> <span class="s">'properties'</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">¶</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) -></span>
|
||||
<span class="nv">constructor: </span><span class="nf">(@base, @properties, tag) -></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">'this'</span>
|
||||
|
||||
<span class="nv">children: </span><span class="p">[</span><span class="s">'base'</span><span class="p">,</span> <span class="s">'properties'</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">¶</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) -></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">-></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">¶</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">-></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">¶</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">-></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">-></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">-></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">-></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">-></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">¶</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">¶</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">-></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">¶</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">¶</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) -></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"><</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">'base'</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">'name'</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">¶</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">¶</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) -></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">"</span><span class="si">#{</span><span class="nx">code</span><span class="si">}</span><span class="s">."</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">¶</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) -></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">=></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">¶</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) -></span>
|
||||
<span class="nx">@unfoldedSoak</span> <span class="o">?=</span> <span class="nx">do</span> <span class="o">=></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">'ref'</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">¶</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">¶</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">¶</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">¶</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) -></span>
|
||||
|
||||
@@ -358,20 +361,20 @@ at the same position.</p> </td> <td class="code">
|
||||
<span class="nv">compileNode: </span><span class="nf">(o, level) -></span>
|
||||
<span class="nv">code = </span><span class="s">'/*'</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">"\n</span><span class="si">#{</span><span class="nx">@tab</span><span class="si">}</span><span class="s">*/\n"</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">¶</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">¶</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">¶</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">¶</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) -></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">'super'</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">'variable'</span><span class="p">,</span> <span class="s">'args'</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">¶</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">-></span>
|
||||
<span class="nv">children: </span><span class="p">[</span><span class="s">'variable'</span><span class="p">,</span> <span class="s">'args'</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">¶</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">-></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">¶</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">¶</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) -></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">'cannot call super outside of a function.'</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">'__super__'</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">'constructor'</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">"</span><span class="si">#{</span><span class="nx">name</span><span class="si">}</span><span class="s">.__super__.constructor"</span></pre></div> </td> </tr> <tr id="section-50"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-50">¶</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) -></span>
|
||||
<span class="s">"</span><span class="si">#{</span><span class="nx">name</span><span class="si">}</span><span class="s">.__super__.constructor"</span></pre></div> </td> </tr> <tr id="section-51"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-51">¶</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) -></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">"this"</span></pre></div> </td> </tr> <tr id="section-51"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-51">¶</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) -></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">"this"</span></pre></div> </td> </tr> <tr id="section-52"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-52">¶</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) -></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">'variable'</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">"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"> === \"function\""</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">'variable'</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">¶</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">¶</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) -></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">¶</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) -></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">¶</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) -></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">".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">', '</span> <span class="o">+</span> <span class="nx">args</span> <span class="si">}</span><span class="s">)"</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">'new '</span> <span class="k">else</span> <span class="s">''</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">"(</span><span class="si">#{</span><span class="nx">args</span><span class="si">}</span><span class="s">)"</span></pre></div> </td> </tr> <tr id="section-54"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-54">¶</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) -></span>
|
||||
<span class="s">"</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">', '</span> <span class="k">else</span> <span class="s">''</span> <span class="si">}#{</span><span class="nx">args</span><span class="si">}</span><span class="s">)"</span></pre></div> </td> </tr> <tr id="section-55"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-55">¶</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">'new '</span> <span class="k">else</span> <span class="s">''</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">"(</span><span class="si">#{</span><span class="nx">args</span><span class="si">}</span><span class="s">)"</span></pre></div> </td> </tr> <tr id="section-55"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-55">¶</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) -></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"> """</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">'ref'</span>
|
||||
<span class="nv">fun = </span><span class="s">"(</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">"</span>
|
||||
@@ -472,7 +473,7 @@ After <code>goog.inherits</code> from the
|
||||
<span class="nv">constructor: </span><span class="nf">(@child, @parent) -></span>
|
||||
|
||||
<span class="nv">children: </span><span class="p">[</span><span class="s">'child'</span><span class="p">,</span> <span class="s">'parent'</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">¶</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) -></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">'extends'</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">¶</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">¶</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">'extends'</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">¶</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">¶</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) -></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"><=</span> <span class="nx">to</span> <span class="k">then</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">to</span><span class="si">}</span><span class="s">"</span> <span class="k">else</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">to</span><span class="si">}</span><span class="s">"</span>
|
||||
<span class="k">else</span>
|
||||
<span class="nv">cond = </span><span class="s">"</span><span class="si">#{</span><span class="nx">@fromVar</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="nv">cond = </span><span class="k">if</span> <span class="nx">@stepVar</span> <span class="k">then</span> <span class="s">"</span><span class="si">#{</span><span class="nx">@stepVar</span><span class="si">}</span><span class="s"> > 0"</span> <span class="k">else</span> <span class="s">"</span><span class="si">#{</span><span class="nx">@fromVar</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="s">"</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">"</span></pre></div> </td> </tr> <tr id="section-69"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-69">¶</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">"</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">"</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">¶</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) -></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">"this"</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">"</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">'bind'</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)"</span></pre></div> </td> </tr> <tr id="section-84"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-84">¶</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">"this"</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">"</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">'bind'</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)"</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">¶</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) -></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">'prototype'</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">'prototype'</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">¶</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) -></span>
|
||||
configured.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">ensureConstructor: </span><span class="nf">(name, o) -></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">"</span><span class="si">#{</span><span class="nx">name</span><span class="si">}</span><span class="s">.__super__.constructor.apply(this, arguments)"</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">"</span><span class="si">#{</span><span class="nx">@externalCtor</span><span class="si">}</span><span class="s">.apply(this, arguments)"</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">¶</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">¶</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) -></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">"cannot return a value from a constructor: \"</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">\" in class </span><span class="si">#{</span><span class="nx">name</span><span class="si">}</span><span class="s">"</span></pre></div> </td> </tr> <tr id="section-89"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-89">¶</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) -></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">¶</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">¶</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">¶</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">¶</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) -></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">'object'</span> <span class="k">then</span> <span class="s">'value'</span> <span class="k">else</span> <span class="s">'variable'</span><span class="p">].</span><span class="nx">assigns</span> <span class="nx">name</span>
|
||||
|
||||
<span class="nv">unfoldSoak: </span><span class="nf">(o) -></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">'variable'</span></pre></div> </td> </tr> <tr id="section-91"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-91">¶</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">'variable'</span></pre></div> </td> </tr> <tr id="section-92"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-92">¶</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) -></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">"</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">"</span> <span class="k">if</span> <span class="nx">@context</span> <span class="o">is</span> <span class="s">'object'</span>
|
||||
<span class="nv">val = </span><span class="nx">name</span> <span class="o">+</span> <span class="s">" </span><span class="si">#{</span> <span class="nx">@context</span> <span class="o">or</span> <span class="s">'='</span> <span class="si">}</span><span class="s"> "</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"><=</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">"(</span><span class="si">#{</span><span class="nx">val</span><span class="si">}</span><span class="s">)"</span></pre></div> </td> </tr> <tr id="section-92"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-92">¶</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"><=</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">"(</span><span class="si">#{</span><span class="nx">val</span><span class="si">}</span><span class="s">)"</span></pre></div> </td> </tr> <tr id="section-93"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-93">¶</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) -></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">>=</span> <span class="nx">LEVEL_OP</span> <span class="k">then</span> <span class="s">"(</span><span class="si">#{</span><span class="nx">code</span><span class="si">}</span><span class="s">)"</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">¶</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">¶</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">"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">"</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">"</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">'ref'</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">"</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">¶</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">¶</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">¶</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">¶</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">¶</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">¶</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">"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">"</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">', '</span>
|
||||
<span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">level</span> <span class="o"><</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">"(</span><span class="si">#{</span><span class="nx">code</span><span class="si">}</span><span class="s">)"</span></pre></div> </td> </tr> <tr id="section-97"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-97">¶</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"><</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">"(</span><span class="si">#{</span><span class="nx">code</span><span class="si">}</span><span class="s">)"</span></pre></div> </td> </tr> <tr id="section-98"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-98">¶</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) -></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">¶</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">¶</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">"this"</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">"the variable \"</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">\" can'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."</span>
|
||||
<span class="k">if</span> <span class="s">"?"</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">'='</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">¶</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">'='</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">¶</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) -></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">"9e9"</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">"[].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">"</span>
|
||||
<span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">level</span> <span class="o">></span> <span class="nx">LEVEL_TOP</span> <span class="k">then</span> <span class="s">"(</span><span class="si">#{</span><span class="nx">code</span><span class="si">}</span><span class="s">)"</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">¶</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">¶</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">></span> <span class="nx">LEVEL_TOP</span> <span class="k">then</span> <span class="s">"(</span><span class="si">#{</span><span class="nx">code</span><span class="si">}</span><span class="s">)"</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">¶</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">¶</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) -></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">-></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">¶</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">¶</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>=></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">'var'</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">'arguments'</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">'arguments'</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">'?'</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">'='</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">'?'</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">'='</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">' == null'</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">'='</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">'='</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">"\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">"</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">'}'</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">>=</span> <span class="nx">LEVEL_ACCESS</span><span class="p">)</span> <span class="k">then</span> <span class="s">"(</span><span class="si">#{</span><span class="nx">code</span><span class="si">}</span><span class="s">)"</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">¶</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">-></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">>=</span> <span class="nx">LEVEL_ACCESS</span><span class="p">)</span> <span class="k">then</span> <span class="s">"(</span><span class="si">#{</span><span class="nx">code</span><span class="si">}</span><span class="s">)"</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">¶</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">-></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">¶</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">¶</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) -></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">¶</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">¶</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">¶</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">¶</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) -></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">'arg'</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">-></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">¶</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">¶</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)-></span>
|
||||
<span class="nv">atParam = </span><span class="nf">(obj) -></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">¶</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">¶</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">¶</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">¶</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">¶</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">¶</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">¶</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">¶</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">¶</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">¶</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">¶</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">¶</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">¶</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">¶</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">"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">"</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">¶</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">¶</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">¶</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">¶</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">'name'</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) -></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">-></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">¶</a> </div> <p>Utility function that converts an arbitrary number of elements, mixed with
|
||||
<span class="nv">unwrap: </span><span class="nf">-></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">¶</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) -></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">"[</span><span class="si">#{</span><span class="nx">code</span><span class="si">}</span><span class="s">]"</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">".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">', '</span> <span class="si">}</span><span class="s">)"</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">"[</span><span class="si">#{</span> <span class="nx">base</span><span class="p">.</span><span class="nx">join</span> <span class="s">', '</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">', '</span> <span class="si">}</span><span class="s">)"</span></pre></div> </td> </tr> <tr id="section-118"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-118">¶</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">¶</a> </div> <p>A while loop, the only sort of low-level loop exposed by CoffeeScript. From
|
||||
<span class="s">"[</span><span class="si">#{</span> <span class="nx">base</span><span class="p">.</span><span class="nx">join</span> <span class="s">', '</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">', '</span> <span class="si">}</span><span class="s">)"</span></pre></div> </td> </tr> <tr id="section-119"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-119">¶</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">¶</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) -></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">¶</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">¶</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) -></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">"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">}"</span>
|
||||
<span class="k">if</span> <span class="nx">@returns</span>
|
||||
<span class="nx">code</span> <span class="o">+=</span> <span class="s">"\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">;"</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">¶</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">¶</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">¶</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">¶</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 ) -></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">'in'</span>
|
||||
<span class="vi">@create: </span><span class="nf">(op, first, second, flip) -></span>
|
||||
<span class="k">if</span> <span class="nx">op</span> <span class="o">is</span> <span class="s">'in'</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">'do'</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">'new'</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 ) -></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">¶</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">¶</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">'=='</span><span class="o">:</span> <span class="s">'==='</span>
|
||||
<span class="s">'!='</span><span class="o">:</span> <span class="s">'!=='</span>
|
||||
<span class="s">'of'</span><span class="o">:</span> <span class="s">'in'</span></pre></div> </td> </tr> <tr id="section-124"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-124">¶</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">'of'</span><span class="o">:</span> <span class="s">'in'</span></pre></div> </td> </tr> <tr id="section-125"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-125">¶</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">'!=='</span><span class="o">:</span> <span class="s">'==='</span>
|
||||
<span class="s">'==='</span><span class="o">:</span> <span class="s">'!=='</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">-></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">'+'</span><span class="p">,</span> <span class="s">'-'</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">¶</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">'+'</span><span class="p">,</span> <span class="s">'-'</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">¶</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">-></span>
|
||||
<span class="nx">@operator</span> <span class="k">in</span> <span class="p">[</span><span class="s">'<'</span><span class="p">,</span> <span class="s">'>'</span><span class="p">,</span> <span class="s">'>='</span><span class="p">,</span> <span class="s">'<='</span><span class="p">,</span> <span class="s">'==='</span><span class="p">,</span> <span class="s">'!=='</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">'!'</span><span class="p">,</span> <span class="s">'in'</span><span class="p">,</span> <span class="s">'instanceof'</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">'!'</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">'!'</span><span class="p">,</span> <span class="k">this</span>
|
||||
|
||||
<span class="nv">unfoldSoak: </span><span class="nf">(o) -></span>
|
||||
<span class="nx">@operator</span> <span class="k">in</span> <span class="p">[</span><span class="s">'++'</span><span class="p">,</span> <span class="s">'--'</span><span class="p">,</span> <span class="s">'delete'</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">'first'</span>
|
||||
|
||||
<span class="nv">generateDo: </span><span class="nf">(exp) -></span>
|
||||
<span class="vi">@generateDo: </span><span class="nf">(exp) -></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) -></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">¶</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">¶</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">'delete'</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">'delete operand may not be argument or var'</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">'?'</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">' '</span> <span class="o">+</span> <span class="nx">@operator</span> <span class="o">+</span> <span class="s">' '</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"><=</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">"(</span><span class="si">#{</span><span class="nx">code</span><span class="si">}</span><span class="s">)"</span></pre></div> </td> </tr> <tr id="section-127"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-127">¶</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"><=</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">"(</span><span class="si">#{</span><span class="nx">code</span><span class="si">}</span><span class="s">)"</span></pre></div> </td> </tr> <tr id="section-128"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-128">¶</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 < 65 > 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">'if'</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">¶</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) -></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">'if'</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">¶</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) -></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">'!'</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">>=</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">'+'</span><span class="p">,</span> <span class="s">'-'</span><span class="p">]</span>
|
||||
<span class="nx">parts</span><span class="p">.</span><span class="nx">push</span> <span class="s">' '</span> <span class="k">if</span> <span class="nx">op</span> <span class="k">in</span> <span class="p">[</span><span class="s">'new'</span><span class="p">,</span> <span class="s">'typeof'</span><span class="p">,</span> <span class="s">'delete'</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">''</span>
|
||||
|
||||
<span class="nv">toString: </span><span class="nf">(idt) -></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">' '</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">¶</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">' '</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">¶</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) -></span>
|
||||
|
||||
<span class="nv">children: </span><span class="p">[</span><span class="s">'object'</span><span class="p">,</span> <span class="s">'array'</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">¶</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">¶</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) -></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"><</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">"(</span><span class="si">#{</span><span class="nx">code</span><span class="si">}</span><span class="s">)"</span>
|
||||
|
||||
<span class="nv">toString: </span><span class="nf">(idt) -></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">'!'</span> <span class="k">else</span> <span class="s">''</span></pre></div> </td> </tr> <tr id="section-131"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-131">¶</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">¶</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">'!'</span> <span class="k">else</span> <span class="s">''</span></pre></div> </td> </tr> <tr id="section-132"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-132">¶</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">¶</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) -></span>
|
||||
|
||||
<span class="nv">children: </span><span class="p">[</span><span class="s">'attempt'</span><span class="p">,</span> <span class="s">'recovery'</span><span class="p">,</span> <span class="s">'ensure'</span><span class="p">]</span>
|
||||
@@ -1254,17 +1259,20 @@ true
|
||||
<span class="nv">makeReturn: </span><span class="nf">(res) -></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">¶</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">¶</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) -></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">" (</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">) "</span> <span class="k">else</span> <span class="s">' '</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">'_error'</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">"catch variable may not be \"</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">\""</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">'param'</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">" 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">}"</span>
|
||||
<span class="s">" 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">}"</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">' catch (_error) {}'</span>
|
||||
|
||||
@@ -1272,16 +1280,16 @@ is optional, the <em>catch</em> is not.</p> </td> <td cl
|
||||
|
||||
<span class="s">"""</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">''</span> <span class="si">}#{</span><span class="nx">ensurePart</span><span class="si">}</span><span class="s">"""</span></pre></div> </td> </tr> <tr id="section-134"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-134">¶</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">¶</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">''</span> <span class="si">}#{</span><span class="nx">ensurePart</span><span class="si">}</span><span class="s">"""</span></pre></div> </td> </tr> <tr id="section-135"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-135">¶</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">¶</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) -></span>
|
||||
|
||||
<span class="nv">children: </span><span class="p">[</span><span class="s">'expression'</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">¶</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">¶</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) -></span>
|
||||
<span class="nx">@tab</span> <span class="o">+</span> <span class="s">"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">;"</span></pre></div> </td> </tr> <tr id="section-137"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-137">¶</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">¶</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">"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">;"</span></pre></div> </td> </tr> <tr id="section-138"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-138">¶</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">¶</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) -></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">'==='</span><span class="p">,</span> <span class="s">'||'</span><span class="p">]</span> <span class="k">else</span> <span class="p">[</span><span class="s">'!=='</span><span class="p">,</span> <span class="s">'&&'</span><span class="p">]</span>
|
||||
<span class="nv">code = </span><span class="s">"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"> \"undefined\" </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"</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">¶</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">"</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">'=='</span> <span class="k">else</span> <span class="s">'!='</span><span class="si">}</span><span class="s"> null"</span>
|
||||
<span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">level</span> <span class="o"><=</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">"(</span><span class="si">#{</span><span class="nx">code</span><span class="si">}</span><span class="s">)"</span></pre></div> </td> </tr> <tr id="section-140"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-140">¶</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">¶</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">¶</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">"</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">'=='</span> <span class="k">else</span> <span class="s">'!='</span><span class="si">}</span><span class="s"> null"</span>
|
||||
<span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">level</span> <span class="o"><=</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">"(</span><span class="si">#{</span><span class="nx">code</span><span class="si">}</span><span class="s">)"</span></pre></div> </td> </tr> <tr id="section-141"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-141">¶</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">¶</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"><</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">"(</span><span class="si">#{</span><span class="nx">code</span><span class="si">}</span><span class="s">)"</span></pre></div> </td> </tr> <tr id="section-142"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-142">¶</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">¶</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">"(</span><span class="si">#{</span><span class="nx">code</span><span class="si">}</span><span class="s">)"</span></pre></div> </td> </tr> <tr id="section-143"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-143">¶</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">¶</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">'cannot pattern match over range loops'</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">'body'</span><span class="p">,</span> <span class="s">'source'</span><span class="p">,</span> <span class="s">'guard'</span><span class="p">,</span> <span class="s">'step'</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">¶</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">'body'</span><span class="p">,</span> <span class="s">'source'</span><span class="p">,</span> <span class="s">'guard'</span><span class="p">,</span> <span class="s">'step'</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">¶</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) -></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">'results'</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">'i'</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">"</span><span class="si">#{</span><span class="nx">kvar</span><span class="si">}</span><span class="s"> = "</span> <span class="k">else</span> <span class="s">""</span></pre></div> </td> </tr> <tr id="section-145"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-145">¶</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">"step"</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">"</span><span class="si">#{</span><span class="nx">kvar</span><span class="si">}</span><span class="s"> = "</span> <span class="k">else</span> <span class="s">""</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">''</span>
|
||||
<span class="nv">guardPart = </span><span class="s">''</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">"</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">'ref'</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"</span>
|
||||
<span class="nx">defPart</span> <span class="o">+=</span> <span class="s">"</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">'ref'</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"</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">"</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">]"</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">'len'</span>
|
||||
<span class="nv">forVarPart = </span><span class="s">"</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"</span>
|
||||
<span class="nx">forVarPart</span> <span class="o">+=</span> <span class="s">", </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">"</span> <span class="k">if</span> <span class="nx">@step</span>
|
||||
<span class="nv">stepPart = </span><span class="s">"</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">"</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">"</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">"++</span><span class="si">#{</span><span class="nx">ivar</span><span class="si">}</span><span class="s">"</span> <span class="k">else</span> <span class="s">"</span><span class="si">#{</span><span class="nx">ivar</span><span class="si">}</span><span class="s">++"</span><span class="p">)</span><span class="si">}</span><span class="s">"</span>
|
||||
<span class="nv">forPart = </span><span class="s">"</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"> < </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">"</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">"</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"</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">'len'</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"><</span> <span class="mi">0</span><span class="p">)</span>
|
||||
<span class="nv">declare = </span><span class="s">"</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"</span>
|
||||
<span class="nv">declareDown = </span><span class="s">"</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"</span>
|
||||
<span class="nv">compare = </span><span class="s">"</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">lvar</span><span class="si">}</span><span class="s">"</span>
|
||||
<span class="nv">compareDown = </span><span class="s">"</span><span class="si">#{</span><span class="nx">ivar</span><span class="si">}</span><span class="s"> >= 0"</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">"</span><span class="si">#{</span><span class="nx">stepVar</span><span class="si">}</span><span class="s"> > 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">"</span>
|
||||
<span class="nv">declare = </span><span class="s">"(</span><span class="si">#{</span><span class="nx">stepVar</span><span class="si">}</span><span class="s"> > 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">)"</span>
|
||||
<span class="nv">increment = </span><span class="s">"</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">"</span>
|
||||
<span class="k">else</span>
|
||||
<span class="nv">increment = </span><span class="s">"</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">"++</span><span class="si">#{</span><span class="nx">ivar</span><span class="si">}</span><span class="s">"</span> <span class="k">else</span> <span class="s">"</span><span class="si">#{</span><span class="nx">ivar</span><span class="si">}</span><span class="s">++"</span><span class="si">}</span><span class="s">"</span>
|
||||
<span class="nv">forPart = </span><span class="s">"</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">"</span>
|
||||
<span class="k">if</span> <span class="nx">@returns</span>
|
||||
<span class="nv">resultPart = </span><span class="s">"</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"</span>
|
||||
<span class="nv">returnResult = </span><span class="s">"\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">;"</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">'call'</span><span class="p">,</span> <span class="s">'apply'</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">'fn'</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">"Class bodies shouldn't reference arguments"</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">'apply'</span> <span class="k">else</span> <span class="s">'call'</span>
|
||||
<span class="nv">args = </span><span class="p">[</span><span class="k">new</span> <span class="nx">Literal</span> <span class="s">'this'</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">'arguments'</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">¶</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) -></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">¶</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">¶</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">-></span> <span class="s">"""</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">'hasProp'</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>
|
||||
|
||||
@@ -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 … <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">¶</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 … <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">¶</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
|
||||
|
||||
@@ -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 … <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">¶</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 … <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">¶</a> </div> </td> <td class="code"> <div class="highlight"><pre><span class="nv">vm = </span><span class="nx">require</span> <span class="s">'vm'</span>
|
||||
<span class="nv">nodeREPL = </span><span class="nx">require</span> <span class="s">'repl'</span>
|
||||
<span class="nv">CoffeeScript = </span><span class="nx">require</span> <span class="s">'./coffee-script'</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">'./helpers'</span>
|
||||
|
||||
<pre><code>coffee> 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">¶</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">¶</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">'./coffee-script'</span>
|
||||
<span class="nv">readline = </span><span class="nx">require</span> <span class="s">'readline'</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">'util'</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">'vm'</span>
|
||||
<span class="nv">Module = </span><span class="nx">require</span> <span class="s">'module'</span></pre></div> </td> </tr> <tr id="section-4"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-4">¶</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">¶</a> </div> <p>Config</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">REPL_PROMPT = </span><span class="s">'coffee> '</span>
|
||||
<span class="nv">REPL_PROMPT_MULTILINE = </span><span class="s">'------> '</span>
|
||||
<span class="nv">REPL_PROMPT_CONTINUATION = </span><span class="s">'......> '</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">'win32'</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">¶</a> </div> <p>Log an error.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">error = </span><span class="nf">(err) -></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">'\n'</span></pre></div> </td> </tr> <tr id="section-7"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-7">¶</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">¶</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">¶</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) -></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">¶</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) -></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">¶</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) -></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">""</span> <span class="k">if</span> <span class="nx">text</span> <span class="o">is</span> <span class="s">""</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">'Object.getOwnPropertyNames(Object(this))'</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">'__'</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">¶</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) -></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">¶</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">'uncaughtException'</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">¶</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">''</span></pre></div> </td> </tr> <tr id="section-15"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-15">¶</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) -></span></pre></div> </td> </tr> <tr id="section-16"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-16">¶</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">"$1$2$3"</span></pre></div> </td> </tr> <tr id="section-17"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-17">¶</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">""</span>
|
||||
<span class="k">if</span> <span class="nx">multilineMode</span>
|
||||
<span class="nx">backlog</span> <span class="o">+=</span> <span class="s">"</span><span class="si">#{</span><span class="nx">buffer</span><span class="si">}</span><span class="s">\n"</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">'coffee> '</span><span class="p">,</span>
|
||||
<span class="nb">eval</span><span class="o">:</span> <span class="nf">(input, context, filename, cb) -></span></pre></div> </td> </tr> <tr id="section-2"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-2">¶</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">'\n'</span></pre></div> </td> </tr> <tr id="section-3"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-3">¶</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">'$1$2$3'</span></pre></div> </td> </tr> <tr id="section-4"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-4">¶</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">¶</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">"_=(</span><span class="si">#{</span><span class="nx">input</span><span class="si">}</span><span class="s">\n)"</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) -></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">/^[^> ]*/</span><span class="p">,</span> <span class="nf">(x) -></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">'-'</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">/^[^> ]*>?/</span><span class="p">,</span> <span class="nf">(x) -></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">'.'</span><span class="p">)</span>
|
||||
<span class="nv">buffer: </span><span class="s">''</span></pre></div> </td> </tr> <tr id="section-6"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-6">¶</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">'line'</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">'line'</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">'line'</span><span class="p">,</span> <span class="nf">(cmd) -></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">"</span><span class="si">#{</span><span class="nx">cmd</span><span class="si">}</span><span class="s">\n"</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">¶</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">'keypress'</span><span class="p">,</span> <span class="nf">(char, key) -></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">'v'</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">¶</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">¶</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">¶</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">''</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">¶</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">'\uFF00'</span>
|
||||
<span class="nx">rli</span><span class="p">.</span><span class="nx">emit</span> <span class="s">'line'</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">''</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">'\\'</span>
|
||||
<span class="nv">backlog = </span><span class="s">"</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"</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">''</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">"_=(</span><span class="si">#{</span><span class="nx">code</span><span class="si">}</span><span class="s">\n)"</span><span class="p">,</span> <span class="p">{</span>
|
||||
<span class="nv">filename: </span><span class="s">'repl'</span>
|
||||
<span class="nv">modulename: </span><span class="s">'repl'</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">"</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"</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">¶</a> </div> <p>handle piped input</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">pipedInput = </span><span class="s">''</span>
|
||||
<span class="nv">repl =</span>
|
||||
<span class="nv">prompt: </span><span class="nf">-></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) -></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">-></span>
|
||||
<span class="nx">stdin</span><span class="p">.</span><span class="nx">on</span> <span class="s">'data'</span><span class="p">,</span> <span class="nf">(chunk) -></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">"\n"</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">"</span><span class="si">#{</span><span class="nx">line</span><span class="si">}</span><span class="s">\n"</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">'end'</span><span class="p">,</span> <span class="nf">-></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">"\n"</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">"</span><span class="si">#{</span><span class="nx">line</span><span class="si">}</span><span class="s">\n"</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">'\n'</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">¶</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"><</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">'data'</span><span class="p">,</span> <span class="nf">(buffer) -></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">¶</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">'keypress'</span><span class="p">,</span> <span class="nf">(char, key) -></span></pre></div> </td> </tr> <tr id="section-21"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-21">¶</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">'v'</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">''</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">¶</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">'keypress'</span><span class="p">,</span> <span class="nf">(char, key) -></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">¶</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">'d'</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">'attemptClose'</span><span class="p">,</span> <span class="nf">-></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">''</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">'\n(^C again to quit)'</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">''</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">'close'</span><span class="p">,</span> <span class="nf">-></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">'\n'</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">'line'</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 = {}) -></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">'exit'</span><span class="p">,</span> <span class="nf">-></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">'\n'</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>
|
||||
@@ -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 … <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">¶</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 … <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">¶</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">¶</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">'TERMINATOR'</span><span class="p">,</span> <span class="s">'OUTDENT'</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">'TERMINATOR'</span><span class="p">,</span> <span class="s">'OUTDENT'</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">','</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">':'</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">'@'</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">':'</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) -></span>
|
||||
<span class="nv">tok = </span><span class="nx">@generate</span> <span class="s">'}'</span><span class="p">,</span> <span class="s">'}'</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">'}'</span><span class="p">,</span> <span class="s">'}'</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) -></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">'{'</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">'{'</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">'{'</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">¶</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">-></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) -></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">'INDENT'</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">'INDENT'</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">'CLASS'</span><span class="p">,</span> <span class="s">'EXTENDS'</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">'{'</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">'{'</span><span class="p">)))</span>
|
||||
|
||||
<span class="nv">action = </span><span class="nf">(token, 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">'CALL_END'</span><span class="p">,</span> <span class="s">')'</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">'CALL_END'</span><span class="p">,</span> <span class="s">')'</span>
|
||||
|
||||
<span class="nx">@scanTokens</span> <span class="nf">(token, i, tokens) -></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">'CALL_START'</span><span class="p">,</span> <span class="s">'('</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">'FUNC_EXIST'</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">'?'</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">¶</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">¶</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">-></span>
|
||||
<span class="nx">@scanTokens</span> <span class="nf">(token, i, tokens) -></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">></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">¶</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">-></span>
|
||||
|
||||
<span class="nv">starter = indent = outdent = </span><span class="kc">null</span>
|
||||
|
||||
<span class="nv">condition = </span><span class="nf">(token, i) -></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">'THEN'</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">¶</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">¶</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">-></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">'IF'</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">¶</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) -></span>
|
||||
<span class="nv">indent = </span><span class="p">[</span><span class="s">'INDENT'</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">'OUTDENT'</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">¶</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) -></span>
|
||||
<span class="nv">indent = </span><span class="p">[</span><span class="s">'INDENT'</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">'OUTDENT'</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">¶</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) -></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">¶</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) -></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">¶</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) -></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">¶</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">¶</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">¶</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) -></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">¶</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">¶</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">'('</span><span class="p">,</span> <span class="s">')'</span><span class="p">]</span>
|
||||
<span class="p">[</span><span class="s">'['</span><span class="p">,</span> <span class="s">']'</span><span class="p">]</span>
|
||||
<span class="p">[</span><span class="s">'{'</span><span class="p">,</span> <span class="s">'}'</span><span class="p">]</span>
|
||||
@@ -224,20 +244,20 @@ different precedence.</p> </td> <td class="code">
|
||||
<span class="p">[</span><span class="s">'CALL_START'</span><span class="p">,</span> <span class="s">'CALL_END'</span><span class="p">]</span>
|
||||
<span class="p">[</span><span class="s">'PARAM_START'</span><span class="p">,</span> <span class="s">'PARAM_END'</span><span class="p">]</span>
|
||||
<span class="p">[</span><span class="s">'INDEX_START'</span><span class="p">,</span> <span class="s">'INDEX_END'</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">¶</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">¶</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">¶</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">¶</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">¶</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">'CATCH'</span><span class="p">,</span> <span class="s">'WHEN'</span><span class="p">,</span> <span class="s">'ELSE'</span><span class="p">,</span> <span class="s">'FINALLY'</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">¶</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">'IDENTIFIER'</span><span class="p">,</span> <span class="s">'SUPER'</span><span class="p">,</span> <span class="s">')'</span><span class="p">,</span> <span class="s">'CALL_END'</span><span class="p">,</span> <span class="s">']'</span><span class="p">,</span> <span class="s">'INDEX_END'</span><span class="p">,</span> <span class="s">'@'</span><span class="p">,</span> <span class="s">'THIS'</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">¶</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">¶</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">'CATCH'</span><span class="p">,</span> <span class="s">'WHEN'</span><span class="p">,</span> <span class="s">'ELSE'</span><span class="p">,</span> <span class="s">'FINALLY'</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">¶</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">'IDENTIFIER'</span><span class="p">,</span> <span class="s">'SUPER'</span><span class="p">,</span> <span class="s">')'</span><span class="p">,</span> <span class="s">'CALL_END'</span><span class="p">,</span> <span class="s">']'</span><span class="p">,</span> <span class="s">'INDEX_END'</span><span class="p">,</span> <span class="s">'@'</span><span class="p">,</span> <span class="s">'THIS'</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">¶</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">'IDENTIFIER'</span><span class="p">,</span> <span class="s">'NUMBER'</span><span class="p">,</span> <span class="s">'STRING'</span><span class="p">,</span> <span class="s">'JS'</span><span class="p">,</span> <span class="s">'REGEX'</span><span class="p">,</span> <span class="s">'NEW'</span><span class="p">,</span> <span class="s">'PARAM_START'</span><span class="p">,</span> <span class="s">'CLASS'</span>
|
||||
<span class="s">'IF'</span><span class="p">,</span> <span class="s">'TRY'</span><span class="p">,</span> <span class="s">'SWITCH'</span><span class="p">,</span> <span class="s">'THIS'</span><span class="p">,</span> <span class="s">'BOOL'</span><span class="p">,</span> <span class="s">'NULL'</span><span class="p">,</span> <span class="s">'UNDEFINED'</span><span class="p">,</span> <span class="s">'UNARY'</span><span class="p">,</span> <span class="s">'SUPER'</span>
|
||||
<span class="s">'@'</span><span class="p">,</span> <span class="s">'->'</span><span class="p">,</span> <span class="s">'=>'</span><span class="p">,</span> <span class="s">'['</span><span class="p">,</span> <span class="s">'('</span><span class="p">,</span> <span class="s">'{'</span><span class="p">,</span> <span class="s">'--'</span><span class="p">,</span> <span class="s">'++'</span>
|
||||
<span class="p">]</span>
|
||||
|
||||
<span class="nv">IMPLICIT_UNSPACED_CALL = </span><span class="p">[</span><span class="s">'+'</span><span class="p">,</span> <span class="s">'-'</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">¶</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">'->'</span><span class="p">,</span> <span class="s">'=>'</span><span class="p">,</span> <span class="s">'{'</span><span class="p">,</span> <span class="s">'['</span><span class="p">,</span> <span class="s">','</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">¶</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">'POST_IF'</span><span class="p">,</span> <span class="s">'FOR'</span><span class="p">,</span> <span class="s">'WHILE'</span><span class="p">,</span> <span class="s">'UNTIL'</span><span class="p">,</span> <span class="s">'WHEN'</span><span class="p">,</span> <span class="s">'BY'</span><span class="p">,</span> <span class="s">'LOOP'</span><span class="p">,</span> <span class="s">'TERMINATOR'</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">¶</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">'+'</span><span class="p">,</span> <span class="s">'-'</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">¶</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">'->'</span><span class="p">,</span> <span class="s">'=>'</span><span class="p">,</span> <span class="s">'{'</span><span class="p">,</span> <span class="s">'['</span><span class="p">,</span> <span class="s">','</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">¶</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">'POST_IF'</span><span class="p">,</span> <span class="s">'FOR'</span><span class="p">,</span> <span class="s">'WHILE'</span><span class="p">,</span> <span class="s">'UNTIL'</span><span class="p">,</span> <span class="s">'WHEN'</span><span class="p">,</span> <span class="s">'BY'</span><span class="p">,</span> <span class="s">'LOOP'</span><span class="p">,</span> <span class="s">'TERMINATOR'</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">¶</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">'ELSE'</span><span class="p">,</span> <span class="s">'->'</span><span class="p">,</span> <span class="s">'=>'</span><span class="p">,</span> <span class="s">'TRY'</span><span class="p">,</span> <span class="s">'FINALLY'</span><span class="p">,</span> <span class="s">'THEN'</span><span class="p">]</span>
|
||||
<span class="nv">SINGLE_CLOSERS = </span><span class="p">[</span><span class="s">'TERMINATOR'</span><span class="p">,</span> <span class="s">'CATCH'</span><span class="p">,</span> <span class="s">'FINALLY'</span><span class="p">,</span> <span class="s">'ELSE'</span><span class="p">,</span> <span class="s">'OUTDENT'</span><span class="p">,</span> <span class="s">'LEADING_WHEN'</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">¶</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">'TERMINATOR'</span><span class="p">,</span> <span class="s">'INDENT'</span><span class="p">,</span> <span class="s">'OUTDENT'</span><span class="p">]</span>
|
||||
<span class="nv">SINGLE_CLOSERS = </span><span class="p">[</span><span class="s">'TERMINATOR'</span><span class="p">,</span> <span class="s">'CATCH'</span><span class="p">,</span> <span class="s">'FINALLY'</span><span class="p">,</span> <span class="s">'ELSE'</span><span class="p">,</span> <span class="s">'OUTDENT'</span><span class="p">,</span> <span class="s">'LEADING_WHEN'</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">¶</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">'TERMINATOR'</span><span class="p">,</span> <span class="s">'INDENT'</span><span class="p">,</span> <span class="s">'OUTDENT'</span><span class="p">]</span>
|
||||
|
||||
</pre></div> </td> </tr> </tbody> </table> </div> </body> </html>
|
||||
@@ -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 —
|
||||
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"> – <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>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Generated by CoffeeScript 1.4.0
|
||||
// Generated by CoffeeScript 1.5.0
|
||||
var volume, winner;
|
||||
|
||||
if (ignition === true) {
|
||||
|
||||
@@ -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'];
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Generated by CoffeeScript 1.4.0
|
||||
// Generated by CoffeeScript 1.5.0
|
||||
var fs;
|
||||
|
||||
fs = require('fs');
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Generated by CoffeeScript 1.4.0
|
||||
// Generated by CoffeeScript 1.5.0
|
||||
var cholesterol, healthy;
|
||||
|
||||
cholesterol = 127;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Generated by CoffeeScript 1.4.0
|
||||
// Generated by CoffeeScript 1.5.0
|
||||
var date, mood;
|
||||
|
||||
if (singing) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Generated by CoffeeScript 1.4.0
|
||||
// Generated by CoffeeScript 1.5.0
|
||||
var fill;
|
||||
|
||||
fill = function(container, liquid) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Generated by CoffeeScript 1.4.0
|
||||
// Generated by CoffeeScript 1.5.0
|
||||
var filename, _fn, _i, _len;
|
||||
|
||||
_fn = function(filename) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Generated by CoffeeScript 1.4.0
|
||||
// Generated by CoffeeScript 1.5.0
|
||||
var hi;
|
||||
|
||||
hi = function() {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Generated by CoffeeScript 1.4.0
|
||||
// Generated by CoffeeScript 1.5.0
|
||||
var eldest, grade;
|
||||
|
||||
grade = function(student) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Generated by CoffeeScript 1.4.0
|
||||
// Generated by CoffeeScript 1.5.0
|
||||
var globals, name;
|
||||
|
||||
globals = ((function() {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Generated by CoffeeScript 1.4.0
|
||||
// Generated by CoffeeScript 1.5.0
|
||||
|
||||
alert((function() {
|
||||
try {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Generated by CoffeeScript 1.4.0
|
||||
// Generated by CoffeeScript 1.5.0
|
||||
var Account;
|
||||
|
||||
Account = function(customer, cart) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Generated by CoffeeScript 1.4.0
|
||||
// Generated by CoffeeScript 1.5.0
|
||||
var cube, square;
|
||||
|
||||
square = function(x) {
|
||||
|
||||
@@ -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>";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Generated by CoffeeScript 1.4.0
|
||||
// Generated by CoffeeScript 1.5.0
|
||||
var OPERATOR;
|
||||
|
||||
OPERATOR = /^(?:[-=]>|[-+*\/%<>&|^!?=]=|>>>=?|([-+:])\1|([&|<>])\2=?|\?\.|\.{2,3})/;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Generated by CoffeeScript 1.4.0
|
||||
// Generated by CoffeeScript 1.5.0
|
||||
var author, quote, sentence;
|
||||
|
||||
author = "Wittgenstein";
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Generated by CoffeeScript 1.4.0
|
||||
// Generated by CoffeeScript 1.5.0
|
||||
var age, ages, child, yearsOld;
|
||||
|
||||
yearsOld = {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Generated by CoffeeScript 1.4.0
|
||||
// Generated by CoffeeScript 1.5.0
|
||||
var city, futurists, name, street, _ref, _ref1;
|
||||
|
||||
futurists = {
|
||||
|
||||
@@ -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"];
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Generated by CoffeeScript 1.4.0
|
||||
// Generated by CoffeeScript 1.5.0
|
||||
|
||||
$('.account').attr({
|
||||
"class": 'active'
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Generated by CoffeeScript 1.4.0
|
||||
// Generated by CoffeeScript 1.5.0
|
||||
var theBait, theSwitch, _ref;
|
||||
|
||||
theBait = 1000;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
2
documentation/js/prototypes.js
vendored
2
documentation/js/prototypes.js
vendored
@@ -1,4 +1,4 @@
|
||||
// Generated by CoffeeScript 1.4.0
|
||||
// Generated by CoffeeScript 1.5.0
|
||||
|
||||
String.prototype.dasherize = function() {
|
||||
return this.replace(/_/g, "-");
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Generated by CoffeeScript 1.4.0
|
||||
// Generated by CoffeeScript 1.5.0
|
||||
var countdown, num;
|
||||
|
||||
countdown = (function() {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Generated by CoffeeScript 1.4.0
|
||||
// Generated by CoffeeScript 1.5.0
|
||||
var changeNumbers, inner, outer;
|
||||
|
||||
outer = 1;
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Generated by CoffeeScript 1.4.0
|
||||
// Generated by CoffeeScript 1.5.0
|
||||
var awardMedals, contenders, gold, rest, silver,
|
||||
__slice = [].slice;
|
||||
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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...";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Generated by CoffeeScript 1.4.0
|
||||
// Generated by CoffeeScript 1.5.0
|
||||
|
||||
switch (day) {
|
||||
case "Mon":
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Generated by CoffeeScript 1.4.0
|
||||
// Generated by CoffeeScript 1.5.0
|
||||
|
||||
try {
|
||||
allHellBreaksLoose();
|
||||
|
||||
@@ -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
105
index.html
105
index.html
@@ -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 —
|
||||
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">"</span>undefined<span class="String">"</span></span> <span class="Keyword">&</span><span class="Keyword">&</span> mind <span class="Keyword">!</span><span class="Keyword">==</span> <span class="BuiltInConstant">null</span>) <span class="Keyword">&</span><span class="Keyword">&</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">"</span>undefined<span class="String">"</span></span> <span class="Keyword">&</span><span class="Keyword">&</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">"</span>undefined<span class="String">"</span></span> <span class="Keyword">&</span><span class="Keyword">&</span> mind <span class="Keyword">!</span><span class="Keyword">==</span> <span class="BuiltInConstant">null</span>) <span class="Keyword">&</span><span class="Keyword">&</span> (<span class="Keyword">typeof</span> world <span class="Keyword">===</span> <span class="String"><span class="String">"</span>undefined<span class="String">"</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">"</span>undefined<span class="String">"</span></span> <span class="Keyword">&</span><span class="Keyword">&</span> yeti <span class="Keyword">!</span><span class="Keyword">==</span> <span class="BuiltInConstant">null</span> ? yeti : <span class="String"><span class="String">"</span>bear<span class="String">"</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"> – <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>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Generated by CoffeeScript 1.5.0-pre
|
||||
// Generated by CoffeeScript 1.5.0
|
||||
(function() {
|
||||
var CoffeeScript, runScripts;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
})();
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Generated by CoffeeScript 1.5.0-pre
|
||||
// Generated by CoffeeScript 1.5.0
|
||||
(function() {
|
||||
var key, val, _ref;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
},
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Generated by CoffeeScript 1.5.0-pre
|
||||
// Generated by CoffeeScript 1.5.0
|
||||
(function() {
|
||||
var Scope, extend, last, _ref;
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
|
||||
265
src/lexer.coffee
265
src/lexer.coffee
@@ -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
|
||||
# ---------
|
||||
|
||||
186
src/nodes.coffee
186
src/nodes.coffee
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
"""
|
||||
|
||||
@@ -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]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
46
test/location.coffee
Normal 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]
|
||||
@@ -1,3 +1,5 @@
|
||||
return if global.testingBrowser
|
||||
|
||||
# REPL
|
||||
# ----
|
||||
Stream = require 'stream'
|
||||
|
||||
Reference in New Issue
Block a user