Compare commits

..

16 Commits
1.1.0 ... 1.1.1

Author SHA1 Message Date
Jeremy Ashkenas
d4d027159f rebuilding browser/source 2011-05-10 10:04:25 -04:00
Jeremy Ashkenas
a8a581acae Never return from a constructor. 2011-05-10 10:03:22 -04:00
Jeremy Ashkenas
9e4fa02cdb CoffeeScript 1.1.1 2011-05-10 09:27:19 -04:00
Jeremy Ashkenas
6d6e07604e Fixing external constructors / order of execution for once and for all ... knock on wood. 2011-05-10 09:24:20 -04:00
Michael Ficarra
f4b8e19c7f adding another failing test case related to #1182 2011-05-08 17:16:45 -04:00
Michael Ficarra
56b2b02637 some cleanup, renaming temporary variable from _by to _step 2011-05-06 23:10:46 -04:00
Michael Ficarra
d031c26229 Merge git://github.com/geraldalewis/coffee-script into geraldalewis_issue1326 2011-05-06 22:53:26 -04:00
Michael Ficarra
4046fcf971 adding failing test case for #1182 execution order bug mentioned by
@satyr
2011-05-06 09:48:12 -04:00
Michael Ficarra
7a4fd2ec01 slightly improved fix for #1182 and #1313 2011-05-06 09:47:40 -04:00
Michael Ficarra
73731ba155 Merge branch 'issue1313' 2011-05-06 01:10:27 -04:00
Michael Ficarra
8781a148db issues #1313 and #1182: better class compilation in presence of
externally defined constructors and inheritence via `extends`. Thanks to
@stephank for the suggested approach.
2011-05-06 01:00:35 -04:00
Gerald Lewis
0e978a0d99 Merge branch 'issue_1326' 2011-05-04 13:14:46 -04:00
Gerald Lewis
ac46ede170 Fix for #1326 by value is uncached 2011-05-04 13:12:05 -04:00
Satoshi Murakami
ad669fc23a command: JSLint => JavaScript Lint 2011-05-04 10:04:17 -07:00
Jeremy Ashkenas
71bcdb91c8 fixing changelog -- it was a regression from an earlier commit, not a true fix. 2011-05-01 14:29:48 -04:00
Jeremy Ashkenas
08294dc4d6 s/process.mainModule/require.main 2011-05-01 13:45:47 -04:00
19 changed files with 347 additions and 238 deletions

View File

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

View File

@@ -13,7 +13,7 @@ execute all scripts present in <code>text/coffeescript</code> tags.</p>
<span class="nv">content = </span><span class="nx">compile</span> <span class="nx">fs</span><span class="p">.</span><span class="nx">readFileSync</span><span class="p">(</span><span class="nx">filename</span><span class="p">,</span> <span class="s1">&#39;utf8&#39;</span><span class="p">),</span> <span class="p">{</span><span class="nx">filename</span><span class="p">}</span>
<span class="nx">module</span><span class="p">.</span><span class="nx">_compile</span> <span class="nx">content</span><span class="p">,</span> <span class="nx">filename</span>
<span class="k">else</span> <span class="k">if</span> <span class="nx">require</span><span class="p">.</span><span class="nx">registerExtension</span>
<span class="nx">require</span><span class="p">.</span><span class="nx">registerExtension</span> <span class="s1">&#39;.coffee&#39;</span><span class="p">,</span> <span class="p">(</span><span class="nx">content</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nx">compile</span> <span class="nx">content</span></pre></div> </td> </tr> <tr id="section-3"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-3">&#182;</a> </div> <p>The current CoffeeScript version number.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.VERSION = </span><span class="s1">&#39;1.1.0&#39;</span></pre></div> </td> </tr> <tr id="section-4"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-4">&#182;</a> </div> <p>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-5"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-5">&#182;</a> </div> <p>Expose helpers for testing.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.helpers = </span><span class="nx">require</span> <span class="s1">&#39;./helpers&#39;</span></pre></div> </td> </tr> <tr id="section-6"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-6">&#182;</a> </div> <p>Compile a string of CoffeeScript code to JavaScript, using the Coffee/Jison
<span class="nx">require</span><span class="p">.</span><span class="nx">registerExtension</span> <span class="s1">&#39;.coffee&#39;</span><span class="p">,</span> <span class="p">(</span><span class="nx">content</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nx">compile</span> <span class="nx">content</span></pre></div> </td> </tr> <tr id="section-3"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-3">&#182;</a> </div> <p>The current CoffeeScript version number.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.VERSION = </span><span class="s1">&#39;1.1.1&#39;</span></pre></div> </td> </tr> <tr id="section-4"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-4">&#182;</a> </div> <p>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-5"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-5">&#182;</a> </div> <p>Expose helpers for testing.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.helpers = </span><span class="nx">require</span> <span class="s1">&#39;./helpers&#39;</span></pre></div> </td> </tr> <tr id="section-6"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-6">&#182;</a> </div> <p>Compile a string of CoffeeScript code to JavaScript, using the Coffee/Jison
compiler.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.compile = compile = </span><span class="p">(</span><span class="nx">code</span><span class="p">,</span> <span class="nv">options = </span><span class="p">{})</span> <span class="o">-&gt;</span>
<span class="k">try</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>

View File

@@ -1,6 +1,6 @@
<!DOCTYPE html> <html> <head> <title>command.coffee</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <link rel="stylesheet" media="all" href="docco.css" /> </head> <body> <div id="container"> <div id="background"></div> <div id="jump_to"> Jump To &hellip; <div id="jump_wrapper"> <div id="jump_page"> <a class="source" href="browser.html"> browser.coffee </a> <a class="source" href="cake.html"> cake.coffee </a> <a class="source" href="coffee-script.html"> coffee-script.coffee </a> <a class="source" href="command.html"> command.coffee </a> <a class="source" href="grammar.html"> grammar.coffee </a> <a class="source" href="helpers.html"> helpers.coffee </a> <a class="source" href="index.html"> index.coffee </a> <a class="source" href="lexer.html"> lexer.coffee </a> <a class="source" href="nodes.html"> nodes.coffee </a> <a class="source" href="optparse.html"> optparse.coffee </a> <a class="source" href="repl.html"> repl.coffee </a> <a class="source" href="rewriter.html"> rewriter.coffee </a> <a class="source" href="scope.html"> scope.coffee </a> </div> </div> </div> <table cellpadding="0" cellspacing="0"> <thead> <tr> <th class="docs"> <h1> command.coffee </h1> </th> <th class="code"> </th> </tr> </thead> <tbody> <tr id="section-1"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-1">&#182;</a> </div> <p>The <code>coffee</code> utility. Handles command-line compilation of CoffeeScript
into various forms: saved into <code>.js</code> files or printed to stdout, piped to
<a href="http://javascriptlint.com/">JSLint</a> or recompiled every time the source is
<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
interactive REPL.</p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-2"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-2">&#182;</a> </div> <p>External dependencies.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">fs = </span><span class="nx">require</span> <span class="s1">&#39;fs&#39;</span>
<span class="nv">path = </span><span class="nx">require</span> <span class="s1">&#39;path&#39;</span>
@@ -20,7 +20,7 @@ interactive REPL.</p> </td> <td class="code">
<span class="p">[</span><span class="s1">&#39;-j&#39;</span><span class="p">,</span> <span class="s1">&#39;--join [FILE]&#39;</span><span class="p">,</span> <span class="s1">&#39;concatenate the scripts before compiling&#39;</span><span class="p">]</span>
<span class="p">[</span><span class="s1">&#39;-w&#39;</span><span class="p">,</span> <span class="s1">&#39;--watch&#39;</span><span class="p">,</span> <span class="s1">&#39;watch scripts for changes, and recompile&#39;</span><span class="p">]</span>
<span class="p">[</span><span class="s1">&#39;-p&#39;</span><span class="p">,</span> <span class="s1">&#39;--print&#39;</span><span class="p">,</span> <span class="s1">&#39;print the compiled JavaScript to stdout&#39;</span><span class="p">]</span>
<span class="p">[</span><span class="s1">&#39;-l&#39;</span><span class="p">,</span> <span class="s1">&#39;--lint&#39;</span><span class="p">,</span> <span class="s1">&#39;pipe the compiled JavaScript through JSLint&#39;</span><span class="p">]</span>
<span class="p">[</span><span class="s1">&#39;-l&#39;</span><span class="p">,</span> <span class="s1">&#39;--lint&#39;</span><span class="p">,</span> <span class="s1">&#39;pipe the compiled JavaScript through JavaScript Lint&#39;</span><span class="p">]</span>
<span class="p">[</span><span class="s1">&#39;-s&#39;</span><span class="p">,</span> <span class="s1">&#39;--stdio&#39;</span><span class="p">,</span> <span class="s1">&#39;listen for and compile scripts over stdio&#39;</span><span class="p">]</span>
<span class="p">[</span><span class="s1">&#39;-e&#39;</span><span class="p">,</span> <span class="s1">&#39;--eval&#39;</span><span class="p">,</span> <span class="s1">&#39;compile a string from the command line&#39;</span><span class="p">]</span>
<span class="p">[</span><span class="s1">&#39;-r&#39;</span><span class="p">,</span> <span class="s1">&#39;--require [FILE*]&#39;</span><span class="p">,</span> <span class="s1">&#39;require a library before executing your script&#39;</span><span class="p">]</span>
@@ -49,7 +49,7 @@ Many flags cause us to divert before compiling anything. Flags passed after
<span class="nv">opts.literals = </span><span class="nx">sources</span><span class="p">.</span><span class="nx">splice</span><span class="p">(</span><span class="mi">1</span><span class="p">).</span><span class="nx">concat</span> <span class="nx">opts</span><span class="p">.</span><span class="nx">literals</span>
<span class="nv">process.ARGV = process.argv = </span><span class="nx">process</span><span class="p">.</span><span class="nx">argv</span><span class="p">.</span><span class="nx">slice</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">2</span><span class="p">).</span><span class="nx">concat</span> <span class="nx">opts</span><span class="p">.</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="s1">&#39;coffee&#39;</span>
<span class="nv">process.execPath = </span><span class="nx">process</span><span class="p">.</span><span class="nx">mainModule</span><span class="p">.</span><span class="nx">filename</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="nx">compileScripts</span><span class="p">()</span></pre></div> </td> </tr> <tr id="section-8"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-8">&#182;</a> </div> <p>Asynchronously read in each CoffeeScript in a list of source files and
compile them. 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">compileScripts = </span><span class="o">-&gt;</span>

View File

@@ -115,7 +115,7 @@ table td {
}
pre, tt, code {
font-size: 12px; line-height: 18px;
font-family: Menlo, Monaco, Consolas, "Lucida Console", monospace;
font-family: Monaco, Consolas, "Lucida Console", monospace;
margin: 0; padding: 0;
}

View File

@@ -285,7 +285,7 @@ evaluate anything twice when building the soak chain.</p> </td>
<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-42"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-42">&#182;</a> </div> <p>Unfold a soak into an <code>If</code>: <code>a?.b</code> -> <code>a.b if a?</code></p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">unfoldSoak</span><span class="o">:</span> <span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="k">return</span> <span class="nx">@unfoldedSoak</span> <span class="k">if</span> <span class="nx">@unfoldedSoak</span><span class="o">?</span>
<span class="nv">result = </span><span class="nx">do</span> <span class="o">=&gt;</span>
<span class="nv">result = </span><span class="nx">do</span> <span class="o">=&gt;</span>
<span class="k">if</span> <span class="nv">ifn = </span><span class="nx">@base</span><span class="p">.</span><span class="nx">unfoldSoak</span> <span class="nx">o</span>
<span class="nb">Array</span><span class="o">::</span><span class="nx">push</span><span class="p">.</span><span class="nx">apply</span> <span class="nx">ifn</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">properties</span><span class="p">,</span> <span class="nx">@properties</span>
<span class="k">return</span> <span class="nx">ifn</span>
@@ -460,23 +460,26 @@ But only if they need to be cached to avoid double evaluation.</p> <
<span class="nx">parts</span><span class="p">.</span><span class="nx">push</span> <span class="nx">@to</span> <span class="k">if</span> <span class="nx">@to</span> <span class="o">isnt</span> <span class="nx">@toVar</span></pre></div> </td> </tr> <tr id="section-64"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-64">&#182;</a> </div> <p>When compiled normally, the range returns the contents of the <em>for loop</em>
needed to iterate over the values in the range. Used by comprehensions.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">compileNode</span><span class="o">:</span> <span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nx">@compileVariables</span> <span class="nx">o</span>
<span class="k">return</span> <span class="nx">@compileArray</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="nx">unless</span> <span class="nx">o</span><span class="p">.</span><span class="nx">index</span>
<span class="k">return</span> <span class="nx">@compileSimple</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="k">if</span> <span class="nx">@fromNum</span> <span class="o">and</span> <span class="nx">@toNum</span>
<span class="k">return</span> <span class="nx">@compileArray</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="nx">unless</span> <span class="nx">o</span><span class="p">.</span><span class="nx">index</span>
<span class="k">return</span> <span class="nx">@compileSimple</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="k">if</span> <span class="nx">@fromNum</span> <span class="o">and</span> <span class="nx">@toNum</span>
<span class="nv">idx = </span><span class="nx">del</span> <span class="nx">o</span><span class="p">,</span> <span class="s1">&#39;index&#39;</span>
<span class="nv">step = </span><span class="nx">del</span> <span class="nx">o</span><span class="p">,</span> <span class="s1">&#39;step&#39;</span>
<span class="nv">vars = </span><span class="s2">&quot;#{idx} = #{@from}&quot;</span> <span class="o">+</span> <span class="k">if</span> <span class="nx">@to</span> <span class="o">isnt</span> <span class="nx">@toVar</span> <span class="k">then</span> <span class="s2">&quot;, #{@to}&quot;</span> <span class="k">else</span> <span class="s1">&#39;&#39;</span>
<span class="nv">stepvar = </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="s2">&quot;step&quot;</span> <span class="k">if</span> <span class="nx">step</span>
<span class="nv">varPart = </span><span class="s2">&quot;#{idx} = #{@from}&quot;</span> <span class="o">+</span> <span class="p">(</span> <span class="k">if</span> <span class="nx">@to</span> <span class="o">isnt</span> <span class="nx">@toVar</span> <span class="k">then</span> <span class="s2">&quot;, #{@to}&quot;</span> <span class="k">else</span> <span class="s1">&#39;&#39;</span> <span class="p">)</span> <span class="o">+</span> <span class="k">if</span> <span class="nx">step</span> <span class="k">then</span> <span class="s2">&quot;, #{stepvar} = #{step.compile(o)}&quot;</span> <span class="k">else</span> <span class="s1">&#39;&#39;</span>
<span class="nv">cond = </span><span class="s2">&quot;#{@fromVar} &lt;= #{@toVar}&quot;</span>
<span class="nv">compare = </span><span class="s2">&quot;#{cond} ? #{idx} &lt;#{@equals} #{@toVar} : #{idx} &gt;#{@equals} #{@toVar}&quot;</span>
<span class="nv">incr = </span><span class="k">if</span> <span class="nx">step</span> <span class="k">then</span> <span class="s2">&quot;#{idx} += #{step.compile(o)}&quot;</span> <span class="k">else</span> <span class="s2">&quot;#{cond} ? #{idx}++ : #{idx}--&quot;</span>
<span class="s2">&quot;#{vars}; #{compare}; #{incr}&quot;</span></pre></div> </td> </tr> <tr id="section-65"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-65">&#182;</a> </div> <p>Compile a simple range comprehension, with integers.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">compileSimple</span><span class="o">:</span> <span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">condPart = </span><span class="s2">&quot;#{cond} ? #{idx} &lt;#{@equals} #{@toVar} : #{idx} &gt;#{@equals} #{@toVar}&quot;</span>
<span class="nv">stepPart = </span><span class="k">if</span> <span class="nx">step</span> <span class="k">then</span> <span class="s2">&quot;#{idx} += #{stepvar}&quot;</span> <span class="k">else</span> <span class="s2">&quot;#{cond} ? #{idx}++ : #{idx}--&quot;</span>
<span class="s2">&quot;#{varPart}; #{condPart}; #{stepPart}&quot;</span></pre></div> </td> </tr> <tr id="section-65"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-65">&#182;</a> </div> <p>Compile a simple range comprehension, with integers.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">compileSimple</span><span class="o">:</span> <span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="p">[</span><span class="nx">from</span><span class="p">,</span> <span class="nx">to</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="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="nv">idx = </span><span class="nx">del</span> <span class="nx">o</span><span class="p">,</span> <span class="s1">&#39;index&#39;</span>
<span class="nv">step = </span><span class="nx">del</span> <span class="nx">o</span><span class="p">,</span> <span class="s1">&#39;step&#39;</span>
<span class="nx">step</span> <span class="o">and=</span> <span class="s2">&quot;#{idx} += #{step.compile(o)}&quot;</span>
<span class="k">if</span> <span class="nx">from</span> <span class="o">&lt;=</span> <span class="nx">to</span>
<span class="s2">&quot;#{idx} = #{from}; #{idx} &lt;#{@equals} #{to}; #{step or &quot;</span><span class="c1">#{idx}++&quot;}&quot;</span>
<span class="k">else</span>
<span class="s2">&quot;#{idx} = #{from}; #{idx} &gt;#{@equals} #{to}; #{step or &quot;</span><span class="c1">#{idx}--&quot;}&quot;</span></pre></div> </td> </tr> <tr id="section-66"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-66">&#182;</a> </div> <p>When used as a value, expand the range into the equivalent array.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">compileArray</span><span class="o">:</span> <span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">stepvar = </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="s2">&quot;step&quot;</span> <span class="k">if</span> <span class="nx">step</span>
<span class="nv">varPart = </span><span class="s2">&quot;#{idx} = #{from}&quot;</span>
<span class="nx">varPart</span> <span class="o">+=</span> <span class="s2">&quot;, #{stepvar} = #{step.compile(o)}&quot;</span> <span class="k">if</span> <span class="nx">step</span>
<span class="nv">condPart = </span><span class="k">if</span> <span class="nx">from</span> <span class="o">&lt;=</span> <span class="nx">to</span> <span class="k">then</span> <span class="s2">&quot;#{idx} &lt;#{@equals} #{to}&quot;</span> <span class="k">else</span> <span class="s2">&quot;#{idx} &gt;#{@equals} #{to}&quot;</span>
<span class="nv">stepPart = </span><span class="s2">&quot;#{idx} += #{stepvar}&quot;</span> <span class="k">if</span> <span class="nx">step</span>
<span class="nv">stepPart = </span><span class="p">(</span> <span class="k">if</span> <span class="nx">from</span> <span class="o">&lt;=</span> <span class="nx">to</span> <span class="k">then</span> <span class="s2">&quot;#{idx}++&quot;</span> <span class="k">else</span> <span class="s2">&quot;#{idx}--&quot;</span> <span class="p">)</span> <span class="k">if</span> <span class="o">not</span> <span class="nx">step</span>
<span class="s2">&quot;#{varPart}; #{condPart}; #{stepPart}&quot;</span></pre></div> </td> </tr> <tr id="section-66"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-66">&#182;</a> </div> <p>When used as a value, expand the range into the equivalent array.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">compileArray</span><span class="o">:</span> <span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="k">if</span> <span class="nx">@fromNum</span> <span class="o">and</span> <span class="nx">@toNum</span> <span class="o">and</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">abs</span><span class="p">(</span><span class="nx">@fromNum</span> <span class="o">-</span> <span class="nx">@toNum</span><span class="p">)</span> <span class="o">&lt;=</span> <span class="mi">20</span>
<span class="nv">range = </span><span class="p">[</span><span class="o">+</span><span class="nx">@fromNum</span><span class="p">..</span><span class="o">+</span><span class="nx">@toNum</span><span class="p">]</span>
<span class="nx">range</span><span class="p">.</span><span class="nx">pop</span><span class="p">()</span> <span class="k">if</span> <span class="nx">@exclusive</span>
@@ -595,10 +598,10 @@ constructor.</p> </td> <td class="code"> <
<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">bname = </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="s2">&quot;this.#{bname} = #{utility &#39;bind&#39;}(this.#{bname}, this);&quot;</span></pre></div> </td> </tr> <tr id="section-79"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-79">&#182;</a> </div> <p>Merge the properties from a top-level object as prototypal properties
on the class.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">addProperties</span><span class="o">:</span> <span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="nx">name</span><span class="p">)</span> <span class="o">-&gt;</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="s2">&quot;this.#{bname} = #{utility &#39;bind&#39;}(this.#{bname}, this)&quot;</span></pre></div> </td> </tr> <tr id="section-79"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-79">&#182;</a> </div> <p>Merge the properties from a top-level object as prototypal properties
on the class.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">addProperties</span><span class="o">:</span> <span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="nx">name</span><span class="p">,</span> <span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">props = </span><span class="nx">node</span><span class="p">.</span><span class="nx">base</span><span class="p">.</span><span class="nx">properties</span><span class="p">.</span><span class="nx">slice</span> <span class="mi">0</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>
<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>
<span class="k">if</span> <span class="nx">assign</span> <span class="k">instanceof</span> <span class="nx">Assign</span>
<span class="nv">base = </span><span class="nx">assign</span><span class="p">.</span><span class="nx">variable</span><span class="p">.</span><span class="nx">base</span>
<span class="k">delete</span> <span class="nx">assign</span><span class="p">.</span><span class="nx">context</span>
@@ -611,25 +614,28 @@ on the class.</p> </td> <td class="code">
<span class="k">if</span> <span class="nx">func</span> <span class="k">instanceof</span> <span class="nx">Code</span>
<span class="nv">assign = </span><span class="vi">@ctor = </span><span class="nx">func</span>
<span class="k">else</span>
<span class="nv">assign = </span><span class="vi">@ctor = </span><span class="k">new</span> <span class="nx">Assign</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">name</span><span class="p">),</span> <span class="nx">func</span><span class="p">)</span>
<span class="vi">@externalCtor = </span><span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span> <span class="s1">&#39;class&#39;</span>
<span class="nv">assign = </span><span class="k">new</span> <span class="nx">Assign</span> <span class="k">new</span> <span class="nx">Literal</span><span class="p">(</span><span class="nx">@externalCtor</span><span class="p">),</span> <span class="nx">func</span>
<span class="k">else</span>
<span class="nx">unless</span> <span class="nx">assign</span><span class="p">.</span><span class="nx">variable</span><span class="p">.</span><span class="k">this</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="p">(</span><span class="nx">base</span><span class="p">,</span> <span class="s1">&#39;proto&#39;</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>
<span class="nx">assign</span></pre></div> </td> </tr> <tr id="section-80"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-80">&#182;</a> </div> <p>Walk the body of the class, looking for prototype properties to be converted.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">walkBody</span><span class="o">:</span> <span class="p">(</span><span class="nx">name</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nx">assign</span>
<span class="nx">compact</span> <span class="nx">exprs</span></pre></div> </td> </tr> <tr id="section-80"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-80">&#182;</a> </div> <p>Walk the body of the class, looking for prototype properties to be converted.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">walkBody</span><span class="o">:</span> <span class="p">(</span><span class="nx">name</span><span class="p">,</span> <span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nx">@traverseChildren</span> <span class="kc">false</span><span class="p">,</span> <span class="p">(</span><span class="nx">child</span><span class="p">)</span> <span class="o">=&gt;</span>
<span class="k">return</span> <span class="kc">false</span> <span class="k">if</span> <span class="nx">child</span> <span class="k">instanceof</span> <span class="nx">Class</span>
<span class="k">if</span> <span class="nx">child</span> <span class="k">instanceof</span> <span class="nx">Block</span>
<span class="k">for</span> <span class="nx">node</span><span class="p">,</span> <span class="nx">i</span> <span class="k">in</span> <span class="nv">exps = </span><span class="nx">child</span><span class="p">.</span><span class="nx">expressions</span>
<span class="k">if</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">isObject</span><span class="p">(</span><span class="kc">true</span><span class="p">)</span>
<span class="nx">exps</span><span class="p">[</span><span class="nx">i</span><span class="p">]</span> <span class="o">=</span> <span class="nx">@addProperties</span> <span class="nx">node</span><span class="p">,</span> <span class="nx">name</span>
<span class="nx">exps</span><span class="p">[</span><span class="nx">i</span><span class="p">]</span> <span class="o">=</span> <span class="nx">@addProperties</span> <span class="nx">node</span><span class="p">,</span> <span class="nx">name</span><span class="p">,</span> <span class="nx">o</span>
<span class="nv">child.expressions = exps = </span><span class="nx">flatten</span> <span class="nx">exps</span></pre></div> </td> </tr> <tr id="section-81"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-81">&#182;</a> </div> <p>Make sure that a constructor is defined for the class, and properly
configured.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">ensureConstructor</span><span class="o">:</span> <span class="p">(</span><span class="nx">name</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="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">Call</span> <span class="s1">&#39;super&#39;</span><span class="p">,</span> <span class="p">[</span><span class="k">new</span> <span class="nx">Splat</span> <span class="k">new</span> <span class="nx">Literal</span> <span class="s1">&#39;arguments&#39;</span><span class="p">]</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="s2">&quot;#{name}.__super__.constructor.apply(this, arguments)&quot;</span> <span class="k">if</span> <span class="nx">@parent</span>
<span class="nx">@ctor</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">push</span> <span class="k">new</span> <span class="nx">Literal</span> <span class="s2">&quot;#{@externalCtor}.apply(this, arguments)&quot;</span> <span class="k">if</span> <span class="nx">@externalCtor</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>
@@ -641,9 +647,10 @@ constructor, property assignments, and inheritance getting built out below.</p>
<span class="nv">lname = </span><span class="k">new</span> <span class="nx">Literal</span> <span class="nx">name</span>
<span class="nx">@setContext</span> <span class="nx">name</span>
<span class="nx">@walkBody</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">@body</span><span class="p">.</span><span class="nx">expressions</span><span class="p">.</span><span class="nx">splice</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="k">new</span> <span class="nx">Extends</span><span class="p">(</span><span class="nx">lname</span><span class="p">,</span> <span class="nx">@parent</span><span class="p">)</span> <span class="k">if</span> <span class="nx">@parent</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="k">new</span> <span class="nx">Extends</span> <span class="nx">lname</span><span class="p">,</span> <span class="nx">@parent</span> <span class="k">if</span> <span class="nx">@parent</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="nx">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>
<span class="nx">@addBoundFunctions</span> <span class="nx">o</span>
@@ -1146,50 +1153,51 @@ you can map and filter in a single pass.</p> </td> <td c
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="nx">compileNode</span><span class="o">:</span> <span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">body = </span><span class="nx">Block</span><span class="p">.</span><span class="nx">wrap</span> <span class="p">[</span><span class="nx">@body</span><span class="p">]</span>
<span class="nv">lastJumps = </span><span class="nx">last</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="o">?</span><span class="p">.</span><span class="nx">jumps</span><span class="p">()</span>
<span class="vi">@returns = </span><span class="kc">no</span> <span class="k">if</span> <span class="nx">lastJumps</span> <span class="o">and</span> <span class="nx">lastJumps</span> <span class="k">instanceof</span> <span class="nx">Return</span>
<span class="nv">source = </span><span class="k">if</span> <span class="nx">@range</span> <span class="k">then</span> <span class="nx">@source</span><span class="p">.</span><span class="nx">base</span> <span class="k">else</span> <span class="nx">@source</span>
<span class="nv">scope = </span><span class="nx">o</span><span class="p">.</span><span class="nx">scope</span>
<span class="nv">name = </span><span class="nx">@name</span> <span class="o">and</span> <span class="nx">@name</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_LIST</span>
<span class="nv">index = </span><span class="nx">@index</span> <span class="o">and</span> <span class="nx">@index</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_LIST</span>
<span class="nv">body = </span><span class="nx">Block</span><span class="p">.</span><span class="nx">wrap</span> <span class="p">[</span><span class="nx">@body</span><span class="p">]</span>
<span class="nv">lastJumps = </span><span class="nx">last</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="o">?</span><span class="p">.</span><span class="nx">jumps</span><span class="p">()</span>
<span class="vi">@returns = </span><span class="kc">no</span> <span class="k">if</span> <span class="nx">lastJumps</span> <span class="o">and</span> <span class="nx">lastJumps</span> <span class="k">instanceof</span> <span class="nx">Return</span>
<span class="nv">source = </span><span class="k">if</span> <span class="nx">@range</span> <span class="k">then</span> <span class="nx">@source</span><span class="p">.</span><span class="nx">base</span> <span class="k">else</span> <span class="nx">@source</span>
<span class="nv">scope = </span><span class="nx">o</span><span class="p">.</span><span class="nx">scope</span>
<span class="nv">name = </span><span class="nx">@name</span> <span class="o">and</span> <span class="nx">@name</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_LIST</span>
<span class="nv">index = </span><span class="nx">@index</span> <span class="o">and</span> <span class="nx">@index</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_LIST</span>
<span class="nx">scope</span><span class="p">.</span><span class="nx">find</span><span class="p">(</span><span class="nx">name</span><span class="p">,</span> <span class="nx">immediate</span><span class="o">:</span> <span class="kc">yes</span><span class="p">)</span> <span class="k">if</span> <span class="nx">name</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">@pattern</span>
<span class="nx">scope</span><span class="p">.</span><span class="nx">find</span><span class="p">(</span><span class="nx">index</span><span class="p">,</span> <span class="nx">immediate</span><span class="o">:</span> <span class="kc">yes</span><span class="p">)</span> <span class="k">if</span> <span class="nx">index</span>
<span class="nv">rvar = </span><span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span> <span class="s1">&#39;results&#39;</span> <span class="k">if</span> <span class="nx">@returns</span>
<span class="nv">ivar = </span><span class="p">(</span><span class="k">if</span> <span class="nx">@range</span> <span class="k">then</span> <span class="nx">name</span> <span class="k">else</span> <span class="nx">index</span><span class="p">)</span> <span class="o">or</span> <span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span> <span class="s1">&#39;i&#39;</span>
<span class="nv">name = </span><span class="nx">ivar</span> <span class="k">if</span> <span class="nx">@pattern</span>
<span class="nv">varPart = </span><span class="s1">&#39;&#39;</span>
<span class="nv">guardPart = </span><span class="s1">&#39;&#39;</span>
<span class="nv">defPart = </span><span class="s1">&#39;&#39;</span>
<span class="nv">idt1 = </span><span class="nx">@tab</span> <span class="o">+</span> <span class="nx">TAB</span>
<span class="nv">rvar = </span><span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span> <span class="s1">&#39;results&#39;</span> <span class="k">if</span> <span class="nx">@returns</span>
<span class="nv">ivar = </span><span class="p">(</span><span class="k">if</span> <span class="nx">@range</span> <span class="k">then</span> <span class="nx">name</span> <span class="k">else</span> <span class="nx">index</span><span class="p">)</span> <span class="o">or</span> <span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span> <span class="s1">&#39;i&#39;</span></pre></div> </td> </tr> <tr id="section-127"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-127">&#182;</a> </div> <p>the <code>_by</code> variable is created twice in <code>Range</code>s if we don't prevent it from being declared here</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">stepvar = </span><span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span> <span class="s2">&quot;step&quot;</span> <span class="k">if</span> <span class="nx">@step</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">@range</span>
<span class="nv">name = </span><span class="nx">ivar</span> <span class="k">if</span> <span class="nx">@pattern</span>
<span class="nv">varPart = </span><span class="s1">&#39;&#39;</span>
<span class="nv">guardPart = </span><span class="s1">&#39;&#39;</span>
<span class="nv">defPart = </span><span class="s1">&#39;&#39;</span>
<span class="nv">idt1 = </span><span class="nx">@tab</span> <span class="o">+</span> <span class="nx">TAB</span>
<span class="k">if</span> <span class="nx">@range</span>
<span class="nv">forPart = </span><span class="nx">source</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">merge</span><span class="p">(</span><span class="nx">o</span><span class="p">,</span> <span class="p">{</span><span class="nx">index</span><span class="o">:</span> <span class="nx">ivar</span><span class="p">,</span> <span class="nx">@step</span><span class="p">})</span>
<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="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">@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="s2">&quot;#{@tab}#{ref = scope.freeVariable &#39;ref&#39;} = #{svar};\n&quot;</span>
<span class="nv">svar = </span><span class="nx">ref</span>
<span class="nv">defPart = </span><span class="s2">&quot;#{@tab}#{ref = scope.freeVariable &#39;ref&#39;} = #{svar};\n&quot;</span>
<span class="nv">svar = </span><span class="nx">ref</span>
<span class="k">if</span> <span class="nx">name</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">@pattern</span>
<span class="nv">namePart = </span><span class="s2">&quot;#{name} = #{svar}[#{ivar}]&quot;</span>
<span class="nv">namePart = </span><span class="s2">&quot;#{name} = #{svar}[#{ivar}]&quot;</span>
<span class="nx">unless</span> <span class="nx">@object</span>
<span class="nv">lvar = </span><span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span> <span class="s1">&#39;len&#39;</span>
<span class="nv">stepPart = </span><span class="k">if</span> <span class="nx">@step</span> <span class="k">then</span> <span class="s2">&quot;#{ivar} += #{ @step.compile(o, LEVEL_OP) }&quot;</span> <span class="k">else</span> <span class="s2">&quot;#{ivar}++&quot;</span>
<span class="nv">forPart = </span><span class="s2">&quot;#{ivar} = 0, #{lvar} = #{svar}.length; #{ivar} &lt; #{lvar}; #{stepPart}&quot;</span>
<span class="nv">lvar = </span><span class="nx">scope</span><span class="p">.</span><span class="nx">freeVariable</span> <span class="s1">&#39;len&#39;</span>
<span class="nv">forVarPart = </span><span class="s2">&quot;#{ivar} = 0, #{lvar} = #{svar}.length&quot;</span> <span class="o">+</span> <span class="k">if</span> <span class="nx">@step</span> <span class="k">then</span> <span class="s2">&quot;, #{stepvar} = #{@step.compile(o, LEVEL_OP)}&quot;</span> <span class="k">else</span> <span class="s1">&#39;&#39;</span>
<span class="nv">stepPart = </span><span class="k">if</span> <span class="nx">@step</span> <span class="k">then</span> <span class="s2">&quot;#{ivar} += #{stepvar}&quot;</span> <span class="k">else</span> <span class="s2">&quot;#{ivar}++&quot;</span>
<span class="nv">forPart = </span><span class="s2">&quot;#{forVarPart}; #{ivar} &lt; #{lvar}; #{stepPart}&quot;</span>
<span class="k">if</span> <span class="nx">@returns</span>
<span class="nv">resultPart = </span><span class="s2">&quot;#{@tab}#{rvar} = [];\n&quot;</span>
<span class="nv">returnResult = </span><span class="s2">&quot;\n#{@tab}return #{rvar};&quot;</span>
<span class="nv">body = </span><span class="nx">Push</span><span class="p">.</span><span class="nx">wrap</span> <span class="nx">rvar</span><span class="p">,</span> <span class="nx">body</span>
<span class="nv">resultPart = </span><span class="s2">&quot;#{@tab}#{rvar} = [];\n&quot;</span>
<span class="nv">returnResult = </span><span class="s2">&quot;\n#{@tab}return #{rvar};&quot;</span>
<span class="nv">body = </span><span class="nx">Push</span><span class="p">.</span><span class="nx">wrap</span> <span class="nx">rvar</span><span class="p">,</span> <span class="nx">body</span>
<span class="k">if</span> <span class="nx">@guard</span>
<span class="nv">body = </span><span class="nx">Block</span><span class="p">.</span><span class="nx">wrap</span> <span class="p">[</span><span class="k">new</span> <span class="nx">If</span> <span class="nx">@guard</span><span class="p">,</span> <span class="nx">body</span><span class="p">]</span>
<span class="nv">body = </span><span class="nx">Block</span><span class="p">.</span><span class="nx">wrap</span> <span class="p">[</span><span class="k">new</span> <span class="nx">If</span> <span class="nx">@guard</span><span class="p">,</span> <span class="nx">body</span><span class="p">]</span>
<span class="k">if</span> <span class="nx">@pattern</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="k">new</span> <span class="nx">Assign</span> <span class="nx">@name</span><span class="p">,</span> <span class="k">new</span> <span class="nx">Literal</span> <span class="s2">&quot;#{svar}[#{ivar}]&quot;</span>
<span class="nx">defPart</span> <span class="o">+=</span> <span class="nx">@pluckDirectCall</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">body</span>
<span class="nv">varPart = </span><span class="s2">&quot;\n#{idt1}#{namePart};&quot;</span> <span class="k">if</span> <span class="nx">namePart</span>
<span class="nx">defPart</span> <span class="o">+=</span> <span class="nx">@pluckDirectCall</span> <span class="nx">o</span><span class="p">,</span> <span class="nx">body</span>
<span class="nv">varPart = </span><span class="s2">&quot;\n#{idt1}#{namePart};&quot;</span> <span class="k">if</span> <span class="nx">namePart</span>
<span class="k">if</span> <span class="nx">@object</span>
<span class="nv">forPart = </span><span class="s2">&quot;#{ivar} in #{svar}&quot;</span>
<span class="nv">guardPart = </span><span class="s2">&quot;\n#{idt1}if (!#{utility(&#39;hasProp&#39;)}.call(#{svar}, #{ivar})) continue;&quot;</span> <span class="k">if</span> <span class="nx">@own</span>
<span class="nv">body = </span><span class="nx">body</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">merge</span><span class="p">(</span><span class="nx">o</span><span class="p">,</span> <span class="nx">indent</span><span class="o">:</span> <span class="nx">idt1</span><span class="p">),</span> <span class="nx">LEVEL_TOP</span>
<span class="nv">body = </span><span class="s1">&#39;\n&#39;</span> <span class="o">+</span> <span class="nx">body</span> <span class="o">+</span> <span class="s1">&#39;\n&#39;</span> <span class="k">if</span> <span class="nx">body</span>
<span class="nv">forPart = </span><span class="s2">&quot;#{ivar} in #{svar}&quot;</span>
<span class="nv">guardPart = </span><span class="s2">&quot;\n#{idt1}if (!#{utility(&#39;hasProp&#39;)}.call(#{svar}, #{ivar})) continue;&quot;</span> <span class="k">if</span> <span class="nx">@own</span>
<span class="nv">body = </span><span class="nx">body</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">merge</span><span class="p">(</span><span class="nx">o</span><span class="p">,</span> <span class="nx">indent</span><span class="o">:</span> <span class="nx">idt1</span><span class="p">),</span> <span class="nx">LEVEL_TOP</span>
<span class="nv">body = </span><span class="s1">&#39;\n&#39;</span> <span class="o">+</span> <span class="nx">body</span> <span class="o">+</span> <span class="s1">&#39;\n&#39;</span> <span class="k">if</span> <span class="nx">body</span>
<span class="s2">&quot;&quot;&quot;</span>
<span class="s2"> #{defPart}#{resultPart or &#39;&#39;}#{@tab}for (#{forPart}) {#{guardPart}#{varPart}#{body}#{@tab}}#{returnResult or &#39;&#39;}</span>
<span class="s2"> &quot;&quot;&quot;</span>
@@ -1213,7 +1221,7 @@ some cannot.</p> </td> <td class="code"> <
<span class="nx">args</span><span class="p">.</span><span class="nx">unshift</span> <span class="k">new</span> <span class="nx">Literal</span> <span class="s1">&#39;this&#39;</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>
<span class="nx">defs</span> <span class="o">+=</span> <span class="nx">@tab</span> <span class="o">+</span> <span class="k">new</span> <span class="nx">Assign</span><span class="p">(</span><span class="nx">ref</span><span class="p">,</span> <span class="nx">fn</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_TOP</span><span class="p">)</span> <span class="o">+</span> <span class="s1">&#39;;\n&#39;</span>
<span class="nx">defs</span></pre></div> </td> </tr> <tr id="section-127"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-127">&#182;</a> </div> <h3>Switch</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-128"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-128">&#182;</a> </div> <p>A JavaScript <em>switch</em> statement. Converts into a returnable expression on-demand.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.Switch = </span><span class="nx">class</span> <span class="nx">Switch</span> <span class="k">extends</span> <span class="nx">Base</span>
<span class="nx">defs</span></pre></div> </td> </tr> <tr id="section-128"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-128">&#182;</a> </div> <h3>Switch</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-129"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-129">&#182;</a> </div> <p>A JavaScript <em>switch</em> statement. Converts into a returnable expression on-demand.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.Switch = </span><span class="nx">class</span> <span class="nx">Switch</span> <span class="k">extends</span> <span class="nx">Base</span>
<span class="nx">constructor</span><span class="o">:</span> <span class="p">(</span><span class="nx">@subject</span><span class="p">,</span> <span class="nx">@cases</span><span class="p">,</span> <span class="nx">@otherwise</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nx">children</span><span class="o">:</span> <span class="p">[</span><span class="s1">&#39;subject&#39;</span><span class="p">,</span> <span class="s1">&#39;cases&#39;</span><span class="p">,</span> <span class="s1">&#39;otherwise&#39;</span><span class="p">]</span>
@@ -1244,7 +1252,7 @@ some cannot.</p> </td> <td class="code"> <
<span class="k">continue</span> <span class="k">if</span> <span class="nx">expr</span> <span class="k">instanceof</span> <span class="nx">Return</span> <span class="o">or</span> <span class="p">(</span><span class="nx">expr</span> <span class="k">instanceof</span> <span class="nx">Literal</span> <span class="o">and</span> <span class="nx">expr</span><span class="p">.</span><span class="nx">jumps</span><span class="p">()</span> <span class="o">and</span> <span class="nx">expr</span><span class="p">.</span><span class="nx">value</span> <span class="o">isnt</span> <span class="s1">&#39;debugger&#39;</span><span class="p">)</span>
<span class="nx">code</span> <span class="o">+=</span> <span class="nx">idt2</span> <span class="o">+</span> <span class="s1">&#39;break;\n&#39;</span>
<span class="nx">code</span> <span class="o">+=</span> <span class="nx">idt1</span> <span class="o">+</span> <span class="s2">&quot;default:\n#{ @otherwise.compile o, LEVEL_TOP }\n&quot;</span> <span class="k">if</span> <span class="nx">@otherwise</span> <span class="o">and</span> <span class="nx">@otherwise</span><span class="p">.</span><span class="nx">expressions</span><span class="p">.</span><span class="nx">length</span>
<span class="nx">code</span> <span class="o">+</span> <span class="nx">@tab</span> <span class="o">+</span> <span class="s1">&#39;}&#39;</span></pre></div> </td> </tr> <tr id="section-129"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-129">&#182;</a> </div> <h3>If</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-130"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-130">&#182;</a> </div> <p><em>If/else</em> statements. Acts as an expression by pushing down requested returns
<span class="nx">code</span> <span class="o">+</span> <span class="nx">@tab</span> <span class="o">+</span> <span class="s1">&#39;}&#39;</span></pre></div> </td> </tr> <tr id="section-130"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-130">&#182;</a> </div> <h3>If</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-131"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-131">&#182;</a> </div> <p><em>If/else</em> statements. Acts as an expression by pushing down requested returns
to the last line of each clause.</p>
<p>Single-expression <strong>Ifs</strong> are compiled into conditional operators if possible,
@@ -1258,13 +1266,13 @@ because ternaries are already proper expressions, and don't need conversion.</p>
<span class="nx">children</span><span class="o">:</span> <span class="p">[</span><span class="s1">&#39;condition&#39;</span><span class="p">,</span> <span class="s1">&#39;body&#39;</span><span class="p">,</span> <span class="s1">&#39;elseBody&#39;</span><span class="p">]</span>
<span class="nx">bodyNode</span><span class="o">:</span> <span class="o">-&gt;</span> <span class="nx">@body</span><span class="o">?</span><span class="p">.</span><span class="nx">unwrap</span><span class="p">()</span>
<span class="nx">elseBodyNode</span><span class="o">:</span> <span class="o">-&gt;</span> <span class="nx">@elseBody</span><span class="o">?</span><span class="p">.</span><span class="nx">unwrap</span><span class="p">()</span></pre></div> </td> </tr> <tr id="section-131"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-131">&#182;</a> </div> <p>Rewrite a chain of <strong>Ifs</strong> to add a default case as the final <em>else</em>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">addElse</span><span class="o">:</span> <span class="p">(</span><span class="nx">elseBody</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nx">elseBodyNode</span><span class="o">:</span> <span class="o">-&gt;</span> <span class="nx">@elseBody</span><span class="o">?</span><span class="p">.</span><span class="nx">unwrap</span><span class="p">()</span></pre></div> </td> </tr> <tr id="section-132"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-132">&#182;</a> </div> <p>Rewrite a chain of <strong>Ifs</strong> to add a default case as the final <em>else</em>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">addElse</span><span class="o">:</span> <span class="p">(</span><span class="nx">elseBody</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="k">if</span> <span class="nx">@isChain</span>
<span class="nx">@elseBodyNode</span><span class="p">().</span><span class="nx">addElse</span> <span class="nx">elseBody</span>
<span class="k">else</span>
<span class="vi">@isChain = </span><span class="nx">elseBody</span> <span class="k">instanceof</span> <span class="nx">If</span>
<span class="vi">@elseBody = </span><span class="nx">@ensureBlock</span> <span class="nx">elseBody</span>
<span class="k">this</span></pre></div> </td> </tr> <tr id="section-132"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-132">&#182;</a> </div> <p>The <strong>If</strong> only compiles into a statement if either of its bodies needs
<span class="k">this</span></pre></div> </td> </tr> <tr id="section-133"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-133">&#182;</a> </div> <p>The <strong>If</strong> only compiles into a statement if either of its bodies needs
to be a statement. Otherwise a conditional operator is safe.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">isStatement</span><span class="o">:</span> <span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nx">o</span><span class="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="nx">@bodyNode</span><span class="p">().</span><span class="nx">isStatement</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">or</span> <span class="nx">@elseBodyNode</span><span class="p">()</span><span class="o">?</span><span class="p">.</span><span class="nx">isStatement</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span>
@@ -1280,7 +1288,7 @@ to be a statement. Otherwise a conditional operator is safe.</p> </t
<span class="k">this</span>
<span class="nx">ensureBlock</span><span class="o">:</span> <span class="p">(</span><span class="nx">node</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="k">if</span> <span class="nx">node</span> <span class="k">instanceof</span> <span class="nx">Block</span> <span class="k">then</span> <span class="nx">node</span> <span class="k">else</span> <span class="k">new</span> <span class="nx">Block</span> <span class="p">[</span><span class="nx">node</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-133"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-133">&#182;</a> </div> <p>Compile the <strong>If</strong> as a regular <em>if-else</em> statement. Flattened chains
<span class="k">if</span> <span class="nx">node</span> <span class="k">instanceof</span> <span class="nx">Block</span> <span class="k">then</span> <span class="nx">node</span> <span class="k">else</span> <span class="k">new</span> <span class="nx">Block</span> <span class="p">[</span><span class="nx">node</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-134"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-134">&#182;</a> </div> <p>Compile the <strong>If</strong> as a regular <em>if-else</em> statement. Flattened chains
force inner <em>else</em> bodies into statement form.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">compileStatement</span><span class="o">:</span> <span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">child = </span><span class="nx">del</span> <span class="nx">o</span><span class="p">,</span> <span class="s1">&#39;chainChild&#39;</span>
<span class="nv">cond = </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>
@@ -1295,7 +1303,7 @@ force inner <em>else</em> bodies into statement form.</p> </td>
<span class="nv">o.chainChild = </span><span class="kc">yes</span>
<span class="nx">@elseBody</span><span class="p">.</span><span class="nx">unwrap</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="k">else</span>
<span class="s2">&quot;{\n#{ @elseBody.compile o, LEVEL_TOP }\n#{@tab}}&quot;</span></pre></div> </td> </tr> <tr id="section-134"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-134">&#182;</a> </div> <p>Compile the If as a conditional operator.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">compileExpression</span><span class="o">:</span> <span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="s2">&quot;{\n#{ @elseBody.compile o, LEVEL_TOP }\n#{@tab}}&quot;</span></pre></div> </td> </tr> <tr id="section-135"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-135">&#182;</a> </div> <p>Compile the If as a conditional operator.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">compileExpression</span><span class="o">:</span> <span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">cond = </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_COND</span>
<span class="nv">body = </span><span class="nx">@bodyNode</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="nv">alt = </span><span class="k">if</span> <span class="nx">@elseBodyNode</span><span class="p">()</span> <span class="k">then</span> <span class="nx">@elseBodyNode</span><span class="p">().</span><span class="nx">compile</span><span class="p">(</span><span class="nx">o</span><span class="p">,</span> <span class="nx">LEVEL_LIST</span><span class="p">)</span> <span class="k">else</span> <span class="s1">&#39;void 0&#39;</span>
@@ -1303,14 +1311,14 @@ force inner <em>else</em> bodies into statement form.</p> </td>
<span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">level</span> <span class="o">&gt;=</span> <span class="nx">LEVEL_COND</span> <span class="k">then</span> <span class="s2">&quot;(#{code})&quot;</span> <span class="k">else</span> <span class="nx">code</span>
<span class="nx">unfoldSoak</span><span class="o">:</span> <span class="o">-&gt;</span>
<span class="nx">@soak</span> <span class="o">and</span> <span class="k">this</span></pre></div> </td> </tr> <tr id="section-135"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-135">&#182;</a> </div> <h2>Faux-Nodes</h2>
<span class="nx">@soak</span> <span class="o">and</span> <span class="k">this</span></pre></div> </td> </tr> <tr id="section-136"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-136">&#182;</a> </div> <h2>Faux-Nodes</h2>
<p>Faux-nodes are never created by the grammar, but are used during code
generation to generate other combinations of nodes.</p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-136"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-136">&#182;</a> </div> <h3>Push</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-137"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-137">&#182;</a> </div> <p>The <strong>Push</strong> creates the tree for <code>array.push(value)</code>,
generation to generate other combinations of nodes.</p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-137"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-137">&#182;</a> </div> <h3>Push</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-138"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-138">&#182;</a> </div> <p>The <strong>Push</strong> creates the tree for <code>array.push(value)</code>,
which is helpful for recording the result arrays from comprehensions.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">Push =</span>
<span class="nx">wrap</span><span class="o">:</span> <span class="p">(</span><span class="nx">name</span><span class="p">,</span> <span class="nx">exps</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="k">return</span> <span class="nx">exps</span> <span class="k">if</span> <span class="nx">exps</span><span class="p">.</span><span class="nx">isEmpty</span><span class="p">()</span> <span class="o">or</span> <span class="nx">last</span><span class="p">(</span><span class="nx">exps</span><span class="p">.</span><span class="nx">expressions</span><span class="p">).</span><span class="nx">jumps</span><span class="p">()</span>
<span class="nx">exps</span><span class="p">.</span><span class="nx">push</span> <span class="k">new</span> <span class="nx">Call</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="s1">&#39;push&#39;</span><span class="p">]),</span> <span class="p">[</span><span class="nx">exps</span><span class="p">.</span><span class="nx">pop</span><span class="p">()]</span></pre></div> </td> </tr> <tr id="section-138"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-138">&#182;</a> </div> <h3>Closure</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-139"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-139">&#182;</a> </div> <p>A faux-node used to wrap an expressions body in a closure.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">Closure =</span></pre></div> </td> </tr> <tr id="section-140"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-140">&#182;</a> </div> <p>Wrap the expressions body, unless it contains a pure statement,
<span class="nx">exps</span><span class="p">.</span><span class="nx">push</span> <span class="k">new</span> <span class="nx">Call</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="s1">&#39;push&#39;</span><span class="p">]),</span> <span class="p">[</span><span class="nx">exps</span><span class="p">.</span><span class="nx">pop</span><span class="p">()]</span></pre></div> </td> </tr> <tr id="section-139"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-139">&#182;</a> </div> <h3>Closure</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-140"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-140">&#182;</a> </div> <p>A faux-node used to wrap an expressions body in a closure.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">Closure =</span></pre></div> </td> </tr> <tr id="section-141"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-141">&#182;</a> </div> <p>Wrap the expressions body, unless it contains a pure statement,
in which case, no dice. If the body mentions <code>this</code> or <code>arguments</code>,
then make sure that the closure wrapper preserves the original values.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">wrap</span><span class="o">:</span> <span class="p">(</span><span class="nx">expressions</span><span class="p">,</span> <span class="nx">statement</span><span class="p">,</span> <span class="nx">noReturn</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="k">return</span> <span class="nx">expressions</span> <span class="k">if</span> <span class="nx">expressions</span><span class="p">.</span><span class="nx">jumps</span><span class="p">()</span>
@@ -1329,11 +1337,11 @@ then make sure that the closure wrapper preserves the original values.</p>
<span class="nx">node</span> <span class="k">instanceof</span> <span class="nx">Literal</span> <span class="o">and</span> <span class="nx">node</span><span class="p">.</span><span class="nx">value</span> <span class="o">is</span> <span class="s1">&#39;arguments&#39;</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">node</span><span class="p">.</span><span class="nx">asKey</span>
<span class="nx">literalThis</span><span class="o">:</span> <span class="p">(</span><span class="nx">node</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="p">(</span><span class="nx">node</span> <span class="k">instanceof</span> <span class="nx">Literal</span> <span class="o">and</span> <span class="nx">node</span><span class="p">.</span><span class="nx">value</span> <span class="o">is</span> <span class="s1">&#39;this&#39;</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">node</span><span class="p">.</span><span class="nx">asKey</span><span class="p">)</span> <span class="o">or</span>
<span class="p">(</span><span class="nx">node</span> <span class="k">instanceof</span> <span class="nx">Code</span> <span class="o">and</span> <span class="nx">node</span><span class="p">.</span><span class="nx">bound</span><span class="p">)</span></pre></div> </td> </tr> <tr id="section-141"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-141">&#182;</a> </div> <p>Unfold a node's child if soak, then tuck the node under created <code>If</code></p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">unfoldSoak = </span><span class="p">(</span><span class="nx">o</span><span class="p">,</span> <span class="nx">parent</span><span class="p">,</span> <span class="nx">name</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="p">(</span><span class="nx">node</span> <span class="k">instanceof</span> <span class="nx">Code</span> <span class="o">and</span> <span class="nx">node</span><span class="p">.</span><span class="nx">bound</span><span class="p">)</span></pre></div> </td> </tr> <tr id="section-142"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-142">&#182;</a> </div> <p>Unfold a node's child if soak, then tuck the node under created <code>If</code></p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">unfoldSoak = </span><span class="p">(</span><span class="nx">o</span><span class="p">,</span> <span class="nx">parent</span><span class="p">,</span> <span class="nx">name</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="k">return</span> <span class="nx">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="nx">ifn</span></pre></div> </td> </tr> <tr id="section-142"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-142">&#182;</a> </div> <h2>Constants</h2> </td> <td class="code"> <div class="highlight"><pre><span class="nv">UTILITIES =</span></pre></div> </td> </tr> <tr id="section-143"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-143">&#182;</a> </div> <p>Correctly set up a prototype chain for inheritance, including a reference
<span class="nx">ifn</span></pre></div> </td> </tr> <tr id="section-143"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-143">&#182;</a> </div> <h2>Constants</h2> </td> <td class="code"> <div class="highlight"><pre><span class="nv">UTILITIES =</span></pre></div> </td> </tr> <tr id="section-144"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-144">&#182;</a> </div> <p>Correctly set up a prototype chain for inheritance, including a reference
to the superclass for <code>super()</code> calls, and copies of any static properties.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">extends</span><span class="o">:</span> <span class="s1">&#39;&#39;&#39;</span>
<span class="s1"> function(child, parent) {</span>
<span class="s1"> for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }</span>
@@ -1343,26 +1351,26 @@ to the superclass for <code>super()</code> calls, and copies of any static prope
<span class="s1"> child.__super__ = parent.prototype;</span>
<span class="s1"> return child;</span>
<span class="s1"> }</span>
<span class="s1"> &#39;&#39;&#39;</span></pre></div> </td> </tr> <tr id="section-144"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-144">&#182;</a> </div> <p>Create a function bound to the current value of "this".</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">bind</span><span class="o">:</span> <span class="s1">&#39;&#39;&#39;</span>
<span class="s1"> &#39;&#39;&#39;</span></pre></div> </td> </tr> <tr id="section-145"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-145">&#182;</a> </div> <p>Create a function bound to the current value of "this".</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">bind</span><span class="o">:</span> <span class="s1">&#39;&#39;&#39;</span>
<span class="s1"> function(fn, me){ return function(){ return fn.apply(me, arguments); }; }</span>
<span class="s1"> &#39;&#39;&#39;</span></pre></div> </td> </tr> <tr id="section-145"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-145">&#182;</a> </div> <p>Discover if an item is in an array.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">indexOf</span><span class="o">:</span> <span class="s1">&#39;&#39;&#39;</span>
<span class="s1"> &#39;&#39;&#39;</span></pre></div> </td> </tr> <tr id="section-146"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-146">&#182;</a> </div> <p>Discover if an item is in an array.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">indexOf</span><span class="o">:</span> <span class="s1">&#39;&#39;&#39;</span>
<span class="s1"> Array.prototype.indexOf || function(item) {</span>
<span class="s1"> for (var i = 0, l = this.length; i &lt; l; i++) {</span>
<span class="s1"> if (this[i] === item) return i;</span>
<span class="s1"> }</span>
<span class="s1"> return -1;</span>
<span class="s1"> }</span>
<span class="s1"> &#39;&#39;&#39;</span></pre></div> </td> </tr> <tr id="section-146"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-146">&#182;</a> </div> <p>Shortcuts to speed up the lookup time for native functions.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">hasProp</span><span class="o">:</span> <span class="s1">&#39;Object.prototype.hasOwnProperty&#39;</span>
<span class="nx">slice</span> <span class="o">:</span> <span class="s1">&#39;Array.prototype.slice&#39;</span></pre></div> </td> </tr> <tr id="section-147"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-147">&#182;</a> </div> <p>Levels indicates a node's position in the AST. Useful for knowing if
<span class="s1"> &#39;&#39;&#39;</span></pre></div> </td> </tr> <tr id="section-147"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-147">&#182;</a> </div> <p>Shortcuts to speed up the lookup time for native functions.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">hasProp</span><span class="o">:</span> <span class="s1">&#39;Object.prototype.hasOwnProperty&#39;</span>
<span class="nx">slice</span> <span class="o">:</span> <span class="s1">&#39;Array.prototype.slice&#39;</span></pre></div> </td> </tr> <tr id="section-148"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-148">&#182;</a> </div> <p>Levels indicates a node's position in the AST. Useful for knowing if
parens are necessary or superfluous.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">LEVEL_TOP = </span><span class="mi">1</span> <span class="c1"># ...;</span>
<span class="nv">LEVEL_PAREN = </span><span class="mi">2</span> <span class="c1"># (...)</span>
<span class="nv">LEVEL_LIST = </span><span class="mi">3</span> <span class="c1"># [...]</span>
<span class="nv">LEVEL_COND = </span><span class="mi">4</span> <span class="c1"># ... ? x : y</span>
<span class="nv">LEVEL_OP = </span><span class="mi">5</span> <span class="c1"># !...</span>
<span class="nv">LEVEL_ACCESS = </span><span class="mi">6</span> <span class="c1"># ...[0]</span></pre></div> </td> </tr> <tr id="section-148"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-148">&#182;</a> </div> <p>Tabs are two spaces for pretty printing.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">TAB = </span><span class="s1">&#39; &#39;</span>
<span class="nv">LEVEL_ACCESS = </span><span class="mi">6</span> <span class="c1"># ...[0]</span></pre></div> </td> </tr> <tr id="section-149"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-149">&#182;</a> </div> <p>Tabs are two spaces for pretty printing.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">TAB = </span><span class="s1">&#39; &#39;</span>
<span class="nv">IDENTIFIER = </span><span class="sr">/^[$A-Za-z_\x7f-\uffff][$\w\x7f-\uffff]*$/</span>
<span class="nv">SIMPLENUM = </span><span class="sr">/^[+-]?\d+$/</span></pre></div> </td> </tr> <tr id="section-149"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-149">&#182;</a> </div> <p>Is a literal value a string?</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">IS_STRING = </span><span class="sr">/^[&#39;&quot;]/</span></pre></div> </td> </tr> <tr id="section-150"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-150">&#182;</a> </div> <h2>Utility Functions</h2> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-151"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-151">&#182;</a> </div> <p>Helper for ensuring that utility functions are assigned at the top level.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">utility = </span><span class="p">(</span><span class="nx">name</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">SIMPLENUM = </span><span class="sr">/^[+-]?\d+$/</span></pre></div> </td> </tr> <tr id="section-150"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-150">&#182;</a> </div> <p>Is a literal value a string?</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">IS_STRING = </span><span class="sr">/^[&#39;&quot;]/</span></pre></div> </td> </tr> <tr id="section-151"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-151">&#182;</a> </div> <h2>Utility Functions</h2> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-152"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-152">&#182;</a> </div> <p>Helper for ensuring that utility functions are assigned at the top level.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">utility = </span><span class="p">(</span><span class="nx">name</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">ref = </span><span class="s2">&quot;__#{name}&quot;</span>
<span class="nx">Scope</span><span class="p">.</span><span class="nx">root</span><span class="p">.</span><span class="nx">assign</span> <span class="nx">ref</span><span class="p">,</span> <span class="nx">UTILITIES</span><span class="p">[</span><span class="nx">name</span><span class="p">]</span>
<span class="nx">ref</span>

View File

@@ -131,7 +131,7 @@
<p>
<b>Latest Version:</b>
<a href="http://github.com/jashkenas/coffee-script/tarball/1.1.0">1.1.0</a>
<a href="http://github.com/jashkenas/coffee-script/tarball/1.1.1">1.1.1</a>
</p>
<h2>
@@ -1020,6 +1020,14 @@ Expressions
Change Log
</h2>
<p>
<b class="header" style="margin-top: 20px;">1.1.1
<span class="timestamp"> &ndash; <small>May 10, 2011</small></span>
</b>
Bugfix release for classes with external constructor functions, see
issue #1182.
</p>
<p>
<b class="header" style="margin-top: 20px;">1.1.0
<span class="timestamp"> &ndash; <small>May 1, 2011</small></span>
@@ -1035,7 +1043,6 @@ Expressions
Fixed an edge-case infinite loop in <tt>addImplicitParentheses</tt>.
Fixed exponential slowdown with long chains of function calls.
Globals no longer leak into the CoffeeScript REPL.
Function calls can be used as default values for parameters.
Splatted parameters are declared local to the function.
</p>

View File

@@ -1,4 +1,4 @@
/*
CoffeeScript Compiler v1.1.0
CoffeeScript Compiler v1.1.1
Released under the MIT License
*/

View File

@@ -17,10 +17,10 @@ Animal = (function() {
return Animal;
})();
Snake = (function() {
__extends(Snake, Animal);
function Snake() {
Snake.__super__.constructor.apply(this, arguments);
}
__extends(Snake, Animal);
Snake.prototype.move = function() {
alert("Slithering...");
return Snake.__super__.move.call(this, 5);
@@ -28,10 +28,10 @@ Snake = (function() {
return Snake;
})();
Horse = (function() {
__extends(Horse, Animal);
function Horse() {
Horse.__super__.constructor.apply(this, arguments);
}
__extends(Horse, Animal);
Horse.prototype.move = function() {
alert("Galloping...");
return Horse.__super__.move.call(this, 45);

File diff suppressed because one or more lines are too long

View File

@@ -109,7 +109,7 @@
<p>
<b>Latest Version:</b>
<a href="http://github.com/jashkenas/coffee-script/tarball/1.1.0">1.1.0</a>
<a href="http://github.com/jashkenas/coffee-script/tarball/1.1.1">1.1.1</a>
</p>
<h2>
@@ -1312,10 +1312,10 @@ Animal <span class="Keyword">=</span> (<span class="Storage">function</span>() {
<span class="Keyword">return</span> Animal;
})();
Snake <span class="Keyword">=</span> (<span class="Storage">function</span>() {
__extends(Snake, Animal);
<span class="Storage">function</span> <span class="FunctionName">Snake</span>() {
Snake.__super__.<span class="LibraryConstant">constructor</span>.<span class="LibraryFunction">apply</span>(<span class="Variable">this</span>, arguments);
}
__extends(Snake, Animal);
<span class="LibraryClassType">Snake</span>.<span class="LibraryConstant">prototype</span>.<span class="FunctionName">move</span> = <span class="Storage">function</span>() {
<span class="LibraryFunction">alert</span>(<span class="String"><span class="String">&quot;</span>Slithering...<span class="String">&quot;</span></span>);
<span class="Keyword">return</span> Snake.__super__.move.<span class="LibraryFunction">call</span>(<span class="Variable">this</span>, <span class="Number">5</span>);
@@ -1323,10 +1323,10 @@ Snake <span class="Keyword">=</span> (<span class="Storage">function</span>() {
<span class="Keyword">return</span> Snake;
})();
Horse <span class="Keyword">=</span> (<span class="Storage">function</span>() {
__extends(Horse, Animal);
<span class="Storage">function</span> <span class="FunctionName">Horse</span>() {
Horse.__super__.<span class="LibraryConstant">constructor</span>.<span class="LibraryFunction">apply</span>(<span class="Variable">this</span>, arguments);
}
__extends(Horse, Animal);
<span class="LibraryClassType">Horse</span>.<span class="LibraryConstant">prototype</span>.<span class="FunctionName">move</span> = <span class="Storage">function</span>() {
<span class="LibraryFunction">alert</span>(<span class="String"><span class="String">&quot;</span>Galloping...<span class="String">&quot;</span></span>);
<span class="Keyword">return</span> Horse.__super__.move.<span class="LibraryFunction">call</span>(<span class="Variable">this</span>, <span class="Number">45</span>);
@@ -1356,10 +1356,10 @@ Animal = (function() {
return Animal;
})();
Snake = (function() {
__extends(Snake, Animal);
function Snake() {
Snake.__super__.constructor.apply(this, arguments);
}
__extends(Snake, Animal);
Snake.prototype.move = function() {
alert("Slithering...");
return Snake.__super__.move.call(this, 5);
@@ -1367,10 +1367,10 @@ Snake = (function() {
return Snake;
})();
Horse = (function() {
__extends(Horse, Animal);
function Horse() {
Horse.__super__.constructor.apply(this, arguments);
}
__extends(Horse, Animal);
Horse.prototype.move = function() {
alert("Galloping...");
return Horse.__super__.move.call(this, 45);
@@ -1725,16 +1725,16 @@ html <span class="Keyword">=</span> <span class="String"><span class="String">'<
are preserved in the generated code.
</p>
<div class='code'><pre class="idle"><span class="Comment"><span class="Comment">###</span></span>
<span class="Comment">CoffeeScript Compiler v1.1.0</span>
<span class="Comment">CoffeeScript Compiler v1.1.1</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.1.0</span>
<span class="Comment">CoffeeScript Compiler v1.1.1</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.1.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.1.1\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>
@@ -1936,6 +1936,14 @@ task(<span class="String"><span class="String">'</span>build:parser<span class="
Change Log
</h2>
<p>
<b class="header" style="margin-top: 20px;">1.1.1
<span class="timestamp"> &ndash; <small>May 10, 2011</small></span>
</b>
Bugfix release for classes with external constructor functions, see
issue #1182.
</p>
<p>
<b class="header" style="margin-top: 20px;">1.1.0
<span class="timestamp"> &ndash; <small>May 1, 2011</small></span>
@@ -1951,7 +1959,6 @@ task(<span class="String"><span class="String">'</span>build:parser<span class="
Fixed an edge-case infinite loop in <tt>addImplicitParentheses</tt>.
Fixed exponential slowdown with long chains of function calls.
Globals no longer leak into the CoffeeScript REPL.
Function calls can be used as default values for parameters.
Splatted parameters are declared local to the function.
</p>

View File

@@ -18,7 +18,7 @@
return compile(content);
});
}
exports.VERSION = '1.1.0';
exports.VERSION = '1.1.1';
exports.RESERVED = RESERVED;
exports.helpers = require('./helpers');
exports.compile = compile = function(code, options) {

View File

@@ -15,7 +15,7 @@
return process.binding('stdio').writeError(line + '\n');
};
BANNER = 'Usage: coffee [options] path/to/script.coffee';
SWITCHES = [['-c', '--compile', 'compile to JavaScript and save as .js files'], ['-i', '--interactive', 'run an interactive CoffeeScript REPL'], ['-o', '--output [DIR]', 'set the directory for compiled JavaScript'], ['-j', '--join [FILE]', 'concatenate the scripts before compiling'], ['-w', '--watch', 'watch scripts for changes, and recompile'], ['-p', '--print', 'print the compiled JavaScript to stdout'], ['-l', '--lint', 'pipe the compiled JavaScript through JSLint'], ['-s', '--stdio', 'listen for and compile scripts over stdio'], ['-e', '--eval', 'compile a string from the command line'], ['-r', '--require [FILE*]', 'require a library before executing your script'], ['-b', '--bare', 'compile without the top-level function wrapper'], ['-t', '--tokens', 'print the tokens that the lexer produces'], ['-n', '--nodes', 'print the parse tree that Jison produces'], ['--nodejs [ARGS]', 'pass options through to the "node" binary'], ['-v', '--version', 'display CoffeeScript version'], ['-h', '--help', 'display this help message']];
SWITCHES = [['-c', '--compile', 'compile to JavaScript and save as .js files'], ['-i', '--interactive', 'run an interactive CoffeeScript REPL'], ['-o', '--output [DIR]', 'set the directory for compiled JavaScript'], ['-j', '--join [FILE]', 'concatenate the scripts before compiling'], ['-w', '--watch', 'watch scripts for changes, and recompile'], ['-p', '--print', 'print the compiled JavaScript to stdout'], ['-l', '--lint', 'pipe the compiled JavaScript through JavaScript Lint'], ['-s', '--stdio', 'listen for and compile scripts over stdio'], ['-e', '--eval', 'compile a string from the command line'], ['-r', '--require [FILE*]', 'require a library before executing your script'], ['-b', '--bare', 'compile without the top-level function wrapper'], ['-t', '--tokens', 'print the tokens that the lexer produces'], ['-n', '--nodes', 'print the parse tree that Jison produces'], ['--nodejs [ARGS]', 'pass options through to the "node" binary'], ['-v', '--version', 'display CoffeeScript version'], ['-h', '--help', 'display this help message']];
opts = {};
sources = [];
contents = [];
@@ -51,7 +51,7 @@
}
process.ARGV = process.argv = process.argv.slice(0, 2).concat(opts.literals);
process.argv[0] = 'coffee';
process.execPath = process.mainModule.filename;
process.execPath = require.main.filename;
return compileScripts();
};
compileScripts = function() {

View File

@@ -167,10 +167,10 @@
return Base;
})();
exports.Block = Block = (function() {
__extends(Block, Base);
function Block(nodes) {
this.expressions = compact(flatten(nodes || []));
}
__extends(Block, Base);
Block.prototype.children = ['expressions'];
Block.prototype.push = function(node) {
this.expressions.push(node);
@@ -319,10 +319,10 @@
return Block;
})();
exports.Literal = Literal = (function() {
__extends(Literal, Base);
function Literal(value) {
this.value = value;
}
__extends(Literal, Base);
Literal.prototype.makeReturn = function() {
if (this.isStatement()) {
return this;
@@ -366,12 +366,12 @@
return Literal;
})();
exports.Return = Return = (function() {
__extends(Return, Base);
function Return(expr) {
if (expr && !expr.unwrap().isUndefined) {
this.expression = expr;
}
}
__extends(Return, Base);
Return.prototype.children = ['expression'];
Return.prototype.isStatement = YES;
Return.prototype.makeReturn = THIS;
@@ -391,6 +391,7 @@
return Return;
})();
exports.Value = Value = (function() {
__extends(Value, Base);
function Value(base, props, tag) {
if (!props && base instanceof Value) {
return base;
@@ -402,7 +403,6 @@
}
return this;
}
__extends(Value, Base);
Value.prototype.children = ['base', 'properties'];
Value.prototype.push = function(prop) {
this.properties.push(prop);
@@ -536,10 +536,10 @@
return Value;
})();
exports.Comment = Comment = (function() {
__extends(Comment, Base);
function Comment(comment) {
this.comment = comment;
}
__extends(Comment, Base);
Comment.prototype.isStatement = YES;
Comment.prototype.makeReturn = THIS;
Comment.prototype.compileNode = function(o, level) {
@@ -553,6 +553,7 @@
return Comment;
})();
exports.Call = Call = (function() {
__extends(Call, Base);
function Call(variable, args, soak) {
this.args = args != null ? args : [];
this.soak = soak;
@@ -560,7 +561,6 @@
this.isSuper = variable === 'super';
this.variable = this.isSuper ? null : variable;
}
__extends(Call, Base);
Call.prototype.children = ['variable', 'args'];
Call.prototype.newInstance = function() {
var base;
@@ -720,11 +720,11 @@
return Call;
})();
exports.Extends = Extends = (function() {
__extends(Extends, Base);
function Extends(child, parent) {
this.child = child;
this.parent = parent;
}
__extends(Extends, Base);
Extends.prototype.children = ['child', 'parent'];
Extends.prototype.compile = function(o) {
utility('hasProp');
@@ -733,13 +733,13 @@
return Extends;
})();
exports.Access = Access = (function() {
__extends(Access, Base);
function Access(name, tag) {
this.name = name;
this.name.asKey = true;
this.proto = tag === 'proto' ? '.prototype' : '';
this.soak = tag === 'soak';
}
__extends(Access, Base);
Access.prototype.children = ['name'];
Access.prototype.compile = function(o) {
var name;
@@ -750,10 +750,10 @@
return Access;
})();
exports.Index = Index = (function() {
__extends(Index, Base);
function Index(index) {
this.index = index;
}
__extends(Index, Base);
Index.prototype.children = ['index'];
Index.prototype.compile = function(o) {
return (this.proto ? '.prototype' : '') + ("[" + (this.index.compile(o, LEVEL_PAREN)) + "]");
@@ -764,8 +764,8 @@
return Index;
})();
exports.Range = Range = (function() {
Range.prototype.children = ['from', 'to'];
__extends(Range, Base);
Range.prototype.children = ['from', 'to'];
function Range(from, to, tag) {
this.from = from;
this.to = to;
@@ -789,7 +789,7 @@
}
};
Range.prototype.compileNode = function(o) {
var compare, cond, idx, incr, step, vars;
var cond, condPart, idx, step, stepPart, stepvar, varPart;
this.compileVariables(o);
if (!o.index) {
return this.compileArray(o);
@@ -799,23 +799,35 @@
}
idx = del(o, 'index');
step = del(o, 'step');
vars = ("" + idx + " = " + this.from) + (this.to !== this.toVar ? ", " + this.to : '');
if (step) {
stepvar = o.scope.freeVariable("step");
}
varPart = ("" + idx + " = " + this.from) + (this.to !== this.toVar ? ", " + this.to : '') + (step ? ", " + stepvar + " = " + (step.compile(o)) : '');
cond = "" + this.fromVar + " <= " + this.toVar;
compare = "" + cond + " ? " + idx + " <" + this.equals + " " + this.toVar + " : " + idx + " >" + this.equals + " " + this.toVar;
incr = step ? "" + idx + " += " + (step.compile(o)) : "" + cond + " ? " + idx + "++ : " + idx + "--";
return "" + vars + "; " + compare + "; " + incr;
condPart = "" + cond + " ? " + idx + " <" + this.equals + " " + this.toVar + " : " + idx + " >" + this.equals + " " + this.toVar;
stepPart = step ? "" + idx + " += " + stepvar : "" + cond + " ? " + idx + "++ : " + idx + "--";
return "" + varPart + "; " + condPart + "; " + stepPart;
};
Range.prototype.compileSimple = function(o) {
var from, idx, step, to, _ref2;
var condPart, from, idx, step, stepPart, stepvar, to, varPart, _ref2;
_ref2 = [+this.fromNum, +this.toNum], from = _ref2[0], to = _ref2[1];
idx = del(o, 'index');
step = del(o, 'step');
step && (step = "" + idx + " += " + (step.compile(o)));
if (from <= to) {
return "" + idx + " = " + from + "; " + idx + " <" + this.equals + " " + to + "; " + (step || ("" + idx + "++"));
} else {
return "" + idx + " = " + from + "; " + idx + " >" + this.equals + " " + to + "; " + (step || ("" + idx + "--"));
if (step) {
stepvar = o.scope.freeVariable("step");
}
varPart = "" + idx + " = " + from;
if (step) {
varPart += ", " + stepvar + " = " + (step.compile(o));
}
condPart = from <= to ? "" + idx + " <" + this.equals + " " + to : "" + idx + " >" + this.equals + " " + to;
if (step) {
stepPart = "" + idx + " += " + stepvar;
}
if (!step) {
stepPart = (from <= to ? "" + idx + "++" : "" + idx + "--");
}
return "" + varPart + "; " + condPart + "; " + stepPart;
};
Range.prototype.compileArray = function(o) {
var body, cond, i, idt, post, pre, range, result, vars, _i, _ref2, _ref3, _results;
@@ -848,8 +860,8 @@
return Range;
})();
exports.Slice = Slice = (function() {
Slice.prototype.children = ['range'];
__extends(Slice, Base);
Slice.prototype.children = ['range'];
function Slice(range) {
this.range = range;
Slice.__super__.constructor.call(this);
@@ -867,11 +879,11 @@
return Slice;
})();
exports.Obj = Obj = (function() {
__extends(Obj, Base);
function Obj(props, generated) {
this.generated = generated != null ? generated : false;
this.objects = this.properties = props || [];
}
__extends(Obj, Base);
Obj.prototype.children = ['properties'];
Obj.prototype.compileNode = function(o) {
var i, idt, indent, join, lastNoncom, node, obj, prop, props, _i, _len;
@@ -935,10 +947,10 @@
return Obj;
})();
exports.Arr = Arr = (function() {
__extends(Arr, Base);
function Arr(objs) {
this.objects = objs || [];
}
__extends(Arr, Base);
Arr.prototype.children = ['objects'];
Arr.prototype.filterImplicitObjects = Call.prototype.filterImplicitObjects;
Arr.prototype.compileNode = function(o) {
@@ -980,6 +992,7 @@
return Arr;
})();
exports.Class = Class = (function() {
__extends(Class, Base);
function Class(variable, parent, body) {
this.variable = variable;
this.parent = parent;
@@ -987,7 +1000,6 @@
this.boundFuncs = [];
this.body.classBody = true;
}
__extends(Class, Base);
Class.prototype.children = ['variable', 'parent', 'body'];
Class.prototype.determineName = function() {
var decl, tail;
@@ -1020,47 +1032,52 @@
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
bvar = _ref2[_i];
bname = bvar.compile(o);
_results.push(this.ctor.body.unshift(new Literal("this." + bname + " = " + (utility('bind')) + "(this." + bname + ", this);")));
_results.push(this.ctor.body.unshift(new Literal("this." + bname + " = " + (utility('bind')) + "(this." + bname + ", this)")));
}
return _results;
}
};
Class.prototype.addProperties = function(node, name) {
var assign, base, func, props, _results;
Class.prototype.addProperties = function(node, name, o) {
var assign, base, exprs, func, props;
props = node.base.properties.slice(0);
_results = [];
while (assign = props.shift()) {
if (assign instanceof Assign) {
base = assign.variable.base;
delete assign.context;
func = assign.value;
if (base.value === 'constructor') {
if (this.ctor) {
throw new Error('cannot define more than one constructor in a class');
}
if (func.bound) {
throw new Error('cannot define a constructor as a bound function');
}
if (func instanceof Code) {
assign = this.ctor = func;
exprs = (function() {
var _results;
_results = [];
while (assign = props.shift()) {
if (assign instanceof Assign) {
base = assign.variable.base;
delete assign.context;
func = assign.value;
if (base.value === 'constructor') {
if (this.ctor) {
throw new Error('cannot define more than one constructor in a class');
}
if (func.bound) {
throw new Error('cannot define a constructor as a bound function');
}
if (func instanceof Code) {
assign = this.ctor = func;
} else {
this.externalCtor = o.scope.freeVariable('class');
assign = new Assign(new Literal(this.externalCtor), func);
}
} else {
assign = this.ctor = new Assign(new Value(new Literal(name)), func);
}
} else {
if (!assign.variable["this"]) {
assign.variable = new Value(new Literal(name), [new Access(base, 'proto')]);
}
if (func instanceof Code && func.bound) {
this.boundFuncs.push(base);
func.bound = false;
if (!assign.variable["this"]) {
assign.variable = new Value(new Literal(name), [new Access(base, 'proto')]);
}
if (func instanceof Code && func.bound) {
this.boundFuncs.push(base);
func.bound = false;
}
}
}
_results.push(assign);
}
_results.push(assign);
}
return _results;
return _results;
}).call(this);
return compact(exprs);
};
Class.prototype.walkBody = function(name) {
Class.prototype.walkBody = function(name, o) {
return this.traverseChildren(false, __bind(function(child) {
var exps, i, node, _len, _ref2;
if (child instanceof Class) {
@@ -1071,7 +1088,7 @@
for (i = 0, _len = _ref2.length; i < _len; i++) {
node = _ref2[i];
if (node instanceof Value && node.isObject(true)) {
exps[i] = this.addProperties(node, name);
exps[i] = this.addProperties(node, name, o);
}
}
return child.expressions = exps = flatten(exps);
@@ -1082,7 +1099,10 @@
if (!this.ctor) {
this.ctor = new Code;
if (this.parent) {
this.ctor.body.push(new Call('super', [new Splat(new Literal('arguments'))]));
this.ctor.body.push(new Literal("" + name + ".__super__.constructor.apply(this, arguments)"));
}
if (this.externalCtor) {
this.ctor.body.push(new Literal("" + this.externalCtor + ".apply(this, arguments)"));
}
this.body.expressions.unshift(this.ctor);
}
@@ -1096,10 +1116,13 @@
name = decl || this.name || '_Class';
lname = new Literal(name);
this.setContext(name);
this.walkBody(name);
this.walkBody(name, o);
this.ensureConstructor(name);
if (this.parent) {
this.body.expressions.splice(1, 0, new Extends(lname, this.parent));
this.body.expressions.unshift(new Extends(lname, this.parent));
}
if (!(this.ctor instanceof Code)) {
this.body.expressions.unshift(this.ctor);
}
this.body.expressions.push(lname);
this.addBoundFunctions(o);
@@ -1112,13 +1135,13 @@
return Class;
})();
exports.Assign = Assign = (function() {
__extends(Assign, Base);
function Assign(variable, value, context, options) {
this.variable = variable;
this.value = value;
this.context = context;
this.param = options && options.param;
}
__extends(Assign, Base);
Assign.prototype.METHOD_DEF = /^(?:(\S+)\.prototype\.|\S+?)?\b([$A-Za-z_][$\w\x7f-\uffff]*)$/;
Assign.prototype.children = ['variable', 'value'];
Assign.prototype.assigns = function(name) {
@@ -1291,6 +1314,7 @@
return Assign;
})();
exports.Code = Code = (function() {
__extends(Code, Base);
function Code(params, body, tag) {
this.params = params || [];
this.body = body || new Block;
@@ -1299,7 +1323,6 @@
this.context = 'this';
}
}
__extends(Code, Base);
Code.prototype.children = ['params', 'body'];
Code.prototype.isStatement = function() {
return !!this.ctor;
@@ -1402,12 +1425,12 @@
return Code;
})();
exports.Param = Param = (function() {
__extends(Param, Base);
function Param(name, value, splat) {
this.name = name;
this.value = value;
this.splat = splat;
}
__extends(Param, Base);
Param.prototype.children = ['name', 'value'];
Param.prototype.compile = function(o) {
return this.name.compile(o, LEVEL_LIST);
@@ -1438,8 +1461,8 @@
return Param;
})();
exports.Splat = Splat = (function() {
Splat.prototype.children = ['name'];
__extends(Splat, Base);
Splat.prototype.children = ['name'];
Splat.prototype.isAssignable = YES;
function Splat(name) {
this.name = name.compile ? name : new Literal(name);
@@ -1494,11 +1517,11 @@
return Splat;
})();
exports.While = While = (function() {
__extends(While, Base);
function While(condition, options) {
this.condition = (options != null ? options.invert : void 0) ? condition.invert() : condition;
this.guard = options != null ? options.guard : void 0;
}
__extends(While, Base);
While.prototype.children = ['condition', 'guard', 'body'];
While.prototype.isStatement = YES;
While.prototype.makeReturn = function() {
@@ -1555,6 +1578,7 @@
})();
exports.Op = Op = (function() {
var CONVERSIONS, INVERSIONS;
__extends(Op, Base);
function Op(op, first, second, flip) {
var call;
if (op === 'in') {
@@ -1579,7 +1603,6 @@
this.flip = !!flip;
return this;
}
__extends(Op, Base);
CONVERSIONS = {
'==': '===',
'!=': '!==',
@@ -1695,11 +1718,11 @@
return Op;
})();
exports.In = In = (function() {
__extends(In, Base);
function In(object, array) {
this.object = object;
this.array = array;
}
__extends(In, Base);
In.prototype.children = ['object', 'array'];
In.prototype.invert = NEGATE;
In.prototype.compileNode = function(o) {
@@ -1753,13 +1776,13 @@
return In;
})();
exports.Try = Try = (function() {
__extends(Try, Base);
function Try(attempt, error, recovery, ensure) {
this.attempt = attempt;
this.error = error;
this.recovery = recovery;
this.ensure = ensure;
}
__extends(Try, Base);
Try.prototype.children = ['attempt', 'recovery', 'ensure'];
Try.prototype.isStatement = YES;
Try.prototype.jumps = function(o) {
@@ -1785,10 +1808,10 @@
return Try;
})();
exports.Throw = Throw = (function() {
__extends(Throw, Base);
function Throw(expression) {
this.expression = expression;
}
__extends(Throw, Base);
Throw.prototype.children = ['expression'];
Throw.prototype.isStatement = YES;
Throw.prototype.jumps = NO;
@@ -1799,10 +1822,10 @@
return Throw;
})();
exports.Existence = Existence = (function() {
__extends(Existence, Base);
function Existence(expression) {
this.expression = expression;
}
__extends(Existence, Base);
Existence.prototype.children = ['expression'];
Existence.prototype.invert = NEGATE;
Existence.prototype.compileNode = function(o) {
@@ -1818,10 +1841,10 @@
return Existence;
})();
exports.Parens = Parens = (function() {
__extends(Parens, Base);
function Parens(body) {
this.body = body;
}
__extends(Parens, Base);
Parens.prototype.children = ['body'];
Parens.prototype.unwrap = function() {
return this.body;
@@ -1850,6 +1873,7 @@
return Parens;
})();
exports.For = For = (function() {
__extends(For, Base);
function For(body, source) {
var _ref2;
this.source = source.source, this.guard = source.guard, this.step = source.step, this.name = source.name, this.index = source.index;
@@ -1872,7 +1896,6 @@
}
this.returns = false;
}
__extends(For, Base);
For.prototype.children = ['body', 'source', 'guard', 'step'];
For.prototype.isStatement = YES;
For.prototype.jumps = While.prototype.jumps;
@@ -1881,7 +1904,7 @@
return this;
};
For.prototype.compileNode = function(o) {
var body, defPart, forPart, guardPart, idt1, index, ivar, lastJumps, lvar, name, namePart, ref, resultPart, returnResult, rvar, scope, source, stepPart, svar, varPart, _ref2;
var body, defPart, forPart, forVarPart, guardPart, idt1, index, ivar, lastJumps, lvar, name, namePart, ref, resultPart, returnResult, rvar, scope, source, stepPart, stepvar, svar, varPart, _ref2;
body = Block.wrap([this.body]);
lastJumps = (_ref2 = last(body.expressions)) != null ? _ref2.jumps() : void 0;
if (lastJumps && lastJumps instanceof Return) {
@@ -1905,6 +1928,9 @@
rvar = scope.freeVariable('results');
}
ivar = (this.range ? name : index) || scope.freeVariable('i');
if (this.step && !this.range) {
stepvar = scope.freeVariable("step");
}
if (this.pattern) {
name = ivar;
}
@@ -1928,8 +1954,9 @@
}
if (!this.object) {
lvar = scope.freeVariable('len');
stepPart = this.step ? "" + ivar + " += " + (this.step.compile(o, LEVEL_OP)) : "" + ivar + "++";
forPart = "" + ivar + " = 0, " + lvar + " = " + svar + ".length; " + ivar + " < " + lvar + "; " + stepPart;
forVarPart = ("" + ivar + " = 0, " + lvar + " = " + svar + ".length") + (this.step ? ", " + stepvar + " = " + (this.step.compile(o, LEVEL_OP)) : '');
stepPart = this.step ? "" + ivar + " += " + stepvar : "" + ivar + "++";
forPart = "" + forVarPart + "; " + ivar + " < " + lvar + "; " + stepPart;
}
}
if (this.returns) {
@@ -1990,12 +2017,12 @@
return For;
})();
exports.Switch = Switch = (function() {
__extends(Switch, Base);
function Switch(subject, cases, otherwise) {
this.subject = subject;
this.cases = cases;
this.otherwise = otherwise;
}
__extends(Switch, Base);
Switch.prototype.children = ['subject', 'cases', 'otherwise'];
Switch.prototype.isStatement = YES;
Switch.prototype.jumps = function(o) {
@@ -2062,6 +2089,7 @@
return Switch;
})();
exports.If = If = (function() {
__extends(If, Base);
function If(condition, body, options) {
this.body = body;
if (options == null) {
@@ -2072,7 +2100,6 @@
this.isChain = false;
this.soak = options.soak;
}
__extends(If, Base);
If.prototype.children = ['condition', 'body', 'elseBody'];
If.prototype.bodyNode = function() {
var _ref2;

View File

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

View File

@@ -21,7 +21,7 @@ else if require.registerExtension
require.registerExtension '.coffee', (content) -> compile content
# The current CoffeeScript version number.
exports.VERSION = '1.1.0'
exports.VERSION = '1.1.1'
# Words that cannot be used as identifiers in CoffeeScript code
exports.RESERVED = RESERVED

View File

@@ -1,6 +1,6 @@
# The `coffee` utility. Handles command-line compilation of CoffeeScript
# into various forms: saved into `.js` files or printed to stdout, piped to
# [JSLint](http://javascriptlint.com/) or recompiled every time the source is
# [JavaScript Lint](http://javascriptlint.com/) or recompiled every time the source is
# saved, printed as a token stream or as the syntax tree, or launch an
# interactive REPL.
@@ -32,7 +32,7 @@ SWITCHES = [
['-j', '--join [FILE]', 'concatenate the scripts before compiling']
['-w', '--watch', 'watch scripts for changes, and recompile']
['-p', '--print', 'print the compiled JavaScript to stdout']
['-l', '--lint', 'pipe the compiled JavaScript through JSLint']
['-l', '--lint', 'pipe the compiled JavaScript through JavaScript Lint']
['-s', '--stdio', 'listen for and compile scripts over stdio']
['-e', '--eval', 'compile a string from the command line']
['-r', '--require [FILE*]', 'require a library before executing your script']
@@ -67,7 +67,7 @@ exports.run = ->
opts.literals = sources.splice(1).concat opts.literals
process.ARGV = process.argv = process.argv.slice(0, 2).concat opts.literals
process.argv[0] = 'coffee'
process.execPath = process.mainModule.filename
process.execPath = require.main.filename
compileScripts()
# Asynchronously read in each CoffeeScript in a list of source files and

View File

@@ -405,7 +405,7 @@ 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 =>
result = do =>
if ifn = @base.unfoldSoak o
Array::push.apply ifn.body.properties, @properties
return ifn
@@ -640,26 +640,29 @@ exports.Range = class Range extends Base
# needed to iterate over the values in the range. Used by comprehensions.
compileNode: (o) ->
@compileVariables o
return @compileArray(o) unless o.index
return @compileSimple(o) if @fromNum and @toNum
return @compileArray(o) unless o.index
return @compileSimple(o) if @fromNum and @toNum
idx = del o, 'index'
step = del o, 'step'
vars = "#{idx} = #{@from}" + if @to isnt @toVar then ", #{@to}" else ''
stepvar = o.scope.freeVariable "step" if step
varPart = "#{idx} = #{@from}" + ( if @to isnt @toVar then ", #{@to}" else '' ) + if step then ", #{stepvar} = #{step.compile(o)}" else ''
cond = "#{@fromVar} <= #{@toVar}"
compare = "#{cond} ? #{idx} <#{@equals} #{@toVar} : #{idx} >#{@equals} #{@toVar}"
incr = if step then "#{idx} += #{step.compile(o)}" else "#{cond} ? #{idx}++ : #{idx}--"
"#{vars}; #{compare}; #{incr}"
condPart = "#{cond} ? #{idx} <#{@equals} #{@toVar} : #{idx} >#{@equals} #{@toVar}"
stepPart = if step then "#{idx} += #{stepvar}" else "#{cond} ? #{idx}++ : #{idx}--"
"#{varPart}; #{condPart}; #{stepPart}"
# Compile a simple range comprehension, with integers.
compileSimple: (o) ->
[from, to] = [+@fromNum, +@toNum]
idx = del o, 'index'
step = del o, 'step'
step and= "#{idx} += #{step.compile(o)}"
if from <= to
"#{idx} = #{from}; #{idx} <#{@equals} #{to}; #{step or "#{idx}++"}"
else
"#{idx} = #{from}; #{idx} >#{@equals} #{to}; #{step or "#{idx}--"}"
stepvar = o.scope.freeVariable "step" if step
varPart = "#{idx} = #{from}"
varPart += ", #{stepvar} = #{step.compile(o)}" if step
condPart = if from <= to then "#{idx} <#{@equals} #{to}" else "#{idx} >#{@equals} #{to}"
stepPart = "#{idx} += #{stepvar}" if step
stepPart = ( if from <= to then "#{idx}++" else "#{idx}--" ) if not step
"#{varPart}; #{condPart}; #{stepPart}"
# When used as a value, expand the range into the equivalent array.
compileArray: (o) ->
@@ -813,13 +816,13 @@ exports.Class = class Class extends Base
if @boundFuncs.length
for bvar in @boundFuncs
bname = bvar.compile o
@ctor.body.unshift new Literal "this.#{bname} = #{utility 'bind'}(this.#{bname}, this);"
@ctor.body.unshift new Literal "this.#{bname} = #{utility 'bind'}(this.#{bname}, this)"
# Merge the properties from a top-level object as prototypal properties
# on the class.
addProperties: (node, name) ->
addProperties: (node, name, o) ->
props = node.base.properties.slice 0
while assign = props.shift()
exprs = while assign = props.shift()
if assign instanceof Assign
base = assign.variable.base
delete assign.context
@@ -832,7 +835,8 @@ exports.Class = class Class extends Base
if func instanceof Code
assign = @ctor = func
else
assign = @ctor = new Assign(new Value(new Literal name), func)
@externalCtor = o.scope.freeVariable 'class'
assign = new Assign new Literal(@externalCtor), func
else
unless assign.variable.this
assign.variable = new Value(new Literal(name), [new Access(base, 'proto')])
@@ -840,15 +844,16 @@ exports.Class = class Class extends Base
@boundFuncs.push base
func.bound = no
assign
compact exprs
# Walk the body of the class, looking for prototype properties to be converted.
walkBody: (name) ->
walkBody: (name, o) ->
@traverseChildren false, (child) =>
return false if child instanceof Class
if child instanceof Block
for node, i in exps = child.expressions
if node instanceof Value and node.isObject(true)
exps[i] = @addProperties node, name
exps[i] = @addProperties node, name, o
child.expressions = exps = flatten exps
# Make sure that a constructor is defined for the class, and properly
@@ -856,7 +861,8 @@ exports.Class = class Class extends Base
ensureConstructor: (name) ->
if not @ctor
@ctor = new Code
@ctor.body.push new Call 'super', [new Splat new Literal 'arguments'] if @parent
@ctor.body.push new Literal "#{name}.__super__.constructor.apply(this, arguments)" if @parent
@ctor.body.push new Literal "#{@externalCtor}.apply(this, arguments)" if @externalCtor
@body.expressions.unshift @ctor
@ctor.ctor = @ctor.name = name
@ctor.klass = null
@@ -871,9 +877,10 @@ exports.Class = class Class extends Base
lname = new Literal name
@setContext name
@walkBody name
@walkBody name, o
@ensureConstructor name
@body.expressions.splice 1, 0, new Extends(lname, @parent) if @parent
@body.expressions.unshift new Extends lname, @parent if @parent
@body.expressions.unshift @ctor unless @ctor instanceof Code
@body.expressions.push lname
@addBoundFunctions o
@@ -1492,50 +1499,53 @@ exports.For = class For extends Base
# comprehensions. Some of the generated code can be shared in common, and
# some cannot.
compileNode: (o) ->
body = Block.wrap [@body]
lastJumps = last(body.expressions)?.jumps()
@returns = no if lastJumps and lastJumps instanceof Return
source = if @range then @source.base else @source
scope = o.scope
name = @name and @name.compile o, LEVEL_LIST
index = @index and @index.compile o, LEVEL_LIST
body = Block.wrap [@body]
lastJumps = last(body.expressions)?.jumps()
@returns = no if lastJumps and lastJumps instanceof Return
source = if @range then @source.base else @source
scope = o.scope
name = @name and @name.compile o, LEVEL_LIST
index = @index and @index.compile o, LEVEL_LIST
scope.find(name, immediate: yes) if name and not @pattern
scope.find(index, immediate: yes) if index
rvar = scope.freeVariable 'results' if @returns
ivar = (if @range then name else index) or scope.freeVariable 'i'
name = ivar if @pattern
varPart = ''
guardPart = ''
defPart = ''
idt1 = @tab + TAB
rvar = scope.freeVariable 'results' if @returns
ivar = (if @range then name else index) or scope.freeVariable 'i'
# 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
name = ivar if @pattern
varPart = ''
guardPart = ''
defPart = ''
idt1 = @tab + TAB
if @range
forPart = source.compile merge(o, {index: ivar, @step})
else
svar = @source.compile o, LEVEL_LIST
svar = @source.compile o, LEVEL_LIST
if (name or @own) and not IDENTIFIER.test svar
defPart = "#{@tab}#{ref = scope.freeVariable 'ref'} = #{svar};\n"
svar = ref
defPart = "#{@tab}#{ref = scope.freeVariable 'ref'} = #{svar};\n"
svar = ref
if name and not @pattern
namePart = "#{name} = #{svar}[#{ivar}]"
namePart = "#{name} = #{svar}[#{ivar}]"
unless @object
lvar = scope.freeVariable 'len'
stepPart = if @step then "#{ivar} += #{ @step.compile(o, LEVEL_OP) }" else "#{ivar}++"
forPart = "#{ivar} = 0, #{lvar} = #{svar}.length; #{ivar} < #{lvar}; #{stepPart}"
lvar = scope.freeVariable 'len'
forVarPart = "#{ivar} = 0, #{lvar} = #{svar}.length" + if @step then ", #{stepvar} = #{@step.compile(o, LEVEL_OP)}" else ''
stepPart = if @step then "#{ivar} += #{stepvar}" else "#{ivar}++"
forPart = "#{forVarPart}; #{ivar} < #{lvar}; #{stepPart}"
if @returns
resultPart = "#{@tab}#{rvar} = [];\n"
returnResult = "\n#{@tab}return #{rvar};"
body = Push.wrap rvar, body
resultPart = "#{@tab}#{rvar} = [];\n"
returnResult = "\n#{@tab}return #{rvar};"
body = Push.wrap rvar, body
if @guard
body = Block.wrap [new If @guard, body]
body = Block.wrap [new If @guard, body]
if @pattern
body.expressions.unshift new Assign @name, new Literal "#{svar}[#{ivar}]"
defPart += @pluckDirectCall o, body
varPart = "\n#{idt1}#{namePart};" if namePart
defPart += @pluckDirectCall o, body
varPart = "\n#{idt1}#{namePart};" if namePart
if @object
forPart = "#{ivar} in #{svar}"
guardPart = "\n#{idt1}if (!#{utility('hasProp')}.call(#{svar}, #{ivar})) continue;" if @own
body = body.compile merge(o, indent: idt1), LEVEL_TOP
body = '\n' + body + '\n' if body
forPart = "#{ivar} in #{svar}"
guardPart = "\n#{idt1}if (!#{utility('hasProp')}.call(#{svar}, #{ivar})) continue;" if @own
body = body.compile merge(o, indent: idt1), LEVEL_TOP
body = '\n' + body + '\n' if body
"""
#{defPart}#{resultPart or ''}#{@tab}for (#{forPart}) {#{guardPart}#{varPart}#{body}#{@tab}}#{returnResult or ''}
"""

View File

@@ -278,8 +278,7 @@ test "classes with value'd constructors", ->
counter = 0
classMaker = ->
counter++
inner = counter
inner = ++counter
->
@value = inner
@@ -289,10 +288,10 @@ test "classes with value'd constructors", ->
class Two
constructor: classMaker()
ok (new One).value is 1
ok (new Two).value is 2
ok (new One).value is 1
ok (new Two).value is 2
eq (new One).value, 1
eq (new Two).value, 2
eq (new One).value, 1
eq (new Two).value, 2
test "exectuable class bodies", ->
@@ -438,12 +437,42 @@ test "`new` works against bare function", ->
Date
test "a subclass should be able to set its constructor to an external function", ->
test "#1182: a subclass should be able to set its constructor to an external function", ->
ctor = ->
@val = 1
class A
class B extends A
constructor: ctor
eq (new B).val, 1
eq (new B).val, 1
test "#1182: external constructors continued", ->
ctor = ->
class A
class B extends A
method: ->
constructor: ctor
ok B::method
test "#1313: misplaced __extends", ->
nonce = {}
class A
class B extends A
prop: nonce
constructor: ->
eq nonce, B::prop
test "#1182: execution order needs to be considered as well", ->
counter = 0
makeFn = (n) -> eq n, ++counter; ->
class B extends (makeFn 1)
@B: makeFn 2
constructor: makeFn 3
test "#1182: external constructors with bound functions", ->
fn = ->
{one: 1}
class B
class A
constructor: fn
method: => this instanceof A
ok (new A).method.call(new B)

View File

@@ -407,3 +407,24 @@ test "issue #1124: don't assign a variable in two scopes", ->
lista = [1, 2, 3, 4, 5]
listb = (_i + 1 for _i in lista)
arrayEq [2, 3, 4, 5, 6], listb
test "#1326: `by` value is uncached", ->
a = [0,1,2]
fi = gi = hi = 0
f = -> ++fi
g = -> ++gi
h = -> ++hi
forCompile = []
rangeCompileSimple = []
#exercises For.compile
for v,i in a by f() then forCompile.push i
#exercises Range.compileSimple
rangeCompileSimple = (i for i in [0..2] by g())
arrayEq a, forCompile
arrayEq a, rangeCompileSimple
#exercises Range.compile
eq "#{i for i in [0..2] by h()}", '0,1,2'