1
0
Fork 0
mirror of https://github.com/jashkenas/coffeescript.git synced 2022-11-09 12:23:24 -05:00

2.0.0-beta4 docs

This commit is contained in:
Geoffrey Booth 2017-08-03 18:18:31 -07:00
parent 27f21a34e2
commit e3c2c0397a
12 changed files with 4437 additions and 1684 deletions

View file

@ -315,6 +315,8 @@ we need to recompile it to get a source map for <code>prepareStackTrace</code>.<
<div class="content"><div class='highlight'><pre> generateSourceMap = options.sourceMap <span class="hljs-keyword">or</span> options.inlineMap <span class="hljs-keyword">or</span> <span class="hljs-keyword">not</span> options.filename?
filename = options.filename <span class="hljs-keyword">or</span> <span class="hljs-string">'&lt;anonymous&gt;'</span>
checkShebangLine filename, code
sources[filename] = code
map = <span class="hljs-keyword">new</span> SourceMap <span class="hljs-keyword">if</span> generateSourceMap
@ -540,13 +542,11 @@ directly as a “Jison lexer”.</p>
@yylineno = @yylloc.first_line
<span class="hljs-keyword">else</span>
tag = <span class="hljs-string">''</span>
tag
setInput: <span class="hljs-function"><span class="hljs-params">(tokens)</span> -&gt;</span>
parser.tokens = tokens
@pos = <span class="hljs-number">0</span>
upcomingInput: <span class="hljs-function">-&gt;</span>
<span class="hljs-string">""</span></pre></div></div>
upcomingInput: <span class="hljs-function">-&gt;</span> <span class="hljs-string">''</span></pre></div></div>
</li>
@ -757,7 +757,20 @@ positions.</p>
<span class="hljs-keyword">break</span> <span class="hljs-keyword">if</span> frame.getFunction() <span class="hljs-keyword">is</span> exports.run
<span class="hljs-string">" at <span class="hljs-subst">#{formatSourcePosition frame, getSourceMapping}</span>"</span>
<span class="hljs-string">"<span class="hljs-subst">#{err.toString()}</span>\n<span class="hljs-subst">#{frames.join <span class="hljs-string">'\n'</span>}</span>\n"</span></pre></div></div>
<span class="hljs-string">"<span class="hljs-subst">#{err.toString()}</span>\n<span class="hljs-subst">#{frames.join <span class="hljs-string">'\n'</span>}</span>\n"</span>
<span class="hljs-function">
<span class="hljs-title">checkShebangLine</span> = <span class="hljs-params">(file, input)</span> -&gt;</span>
firstLine = input.split(<span class="hljs-regexp">/$/m</span>)[<span class="hljs-number">0</span>]
rest = firstLine?.match(<span class="hljs-regexp">/^#!\s*([^\s]+\s*)(.*)/</span>)
args = rest?[<span class="hljs-number">2</span>]?.split(<span class="hljs-regexp">/\s/</span>).filter (s) -&gt; s <span class="hljs-keyword">isnt</span> <span class="hljs-string">''</span>
<span class="hljs-keyword">if</span> args?.length &gt; <span class="hljs-number">1</span>
<span class="hljs-built_in">console</span>.error <span class="hljs-string">'''
The script to be run begins with a shebang line with more than one
argument. This script will fail on platforms such as Linux which only
allow a single argument.
'''</span>
<span class="hljs-built_in">console</span>.error <span class="hljs-string">"The shebang line was: '<span class="hljs-subst">#{firstLine}</span>' in file '<span class="hljs-subst">#{file}</span>'"</span>
<span class="hljs-built_in">console</span>.error <span class="hljs-string">"The arguments were: <span class="hljs-subst">#{JSON.stringify args}</span>"</span></pre></div></div>
</li>

View file

@ -180,7 +180,7 @@ useWinPathSep = path.sep <span class="hljs-keyword">is</span> <span class="hljs
</div>
<div class="content"><div class='highlight'><pre>BANNER = <span class="hljs-string">'''
Usage: coffee [options] path/to/script.coffee -- [args]
Usage: coffee [options] path/to/script.coffee [args]
If called without options, `coffee` will run your script.
'''</span></pre></div></div>
@ -260,7 +260,21 @@ Many flags cause us to divert before compiling anything. Flags passed after
<div class="content"><div class='highlight'><pre>exports.run = <span class="hljs-function">-&gt;</span>
optionParser = buildCSOptionParser()
parseOptions()</pre></div></div>
<span class="hljs-keyword">try</span> parseOptions()
<span class="hljs-keyword">catch</span> err
<span class="hljs-built_in">console</span>.error <span class="hljs-string">"option parsing error: <span class="hljs-subst">#{err.message}</span>"</span>
process.exit <span class="hljs-number">1</span>
<span class="hljs-keyword">if</span> (<span class="hljs-keyword">not</span> opts.doubleDashed) <span class="hljs-keyword">and</span> (opts.arguments[<span class="hljs-number">1</span>] <span class="hljs-keyword">is</span> <span class="hljs-string">'--'</span>)
printWarn <span class="hljs-string">'''
coffee was invoked with '--' as the second positional argument, which is
now deprecated. To pass '--' as an argument to a script to run, put an
additional '--' before the path to your script.
'--' will be removed from the argument list.
'''</span>
printWarn <span class="hljs-string">"The positional arguments were: <span class="hljs-subst">#{JSON.stringify opts.arguments}</span>"</span>
opts.arguments = [opts.arguments[<span class="hljs-number">0</span>]].concat opts.arguments[<span class="hljs-number">2.</span>.]</pre></div></div>
</li>
@ -842,6 +856,9 @@ the <code>node</code> binary, preserving the other options.</p>
cwd: process.cwd()
env: process.env
stdio: [<span class="hljs-number">0</span>, <span class="hljs-number">1</span>, <span class="hljs-number">2</span>]
<span class="hljs-keyword">for</span> signal <span class="hljs-keyword">in</span> [<span class="hljs-string">'SIGINT'</span>, <span class="hljs-string">'SIGTERM'</span>]
process.<span class="hljs-literal">on</span> signal, <span class="hljs-keyword">do</span> (signal) -&gt;
-&gt; p.kill signal
p.<span class="hljs-literal">on</span> <span class="hljs-string">'exit'</span>, <span class="hljs-function"><span class="hljs-params">(code)</span> -&gt;</span> process.exit code</pre></div></div>
</li>

View file

@ -209,8 +209,8 @@ previous nonterminal.</p>
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">o</span> = <span class="hljs-params">(patternString, action, options)</span> -&gt;</span>
patternString = patternString.replace <span class="hljs-regexp">/\s{2,}/g</span>, <span class="hljs-string">' '</span>
patternCount = patternString.split(<span class="hljs-string">' '</span>).length
<span class="hljs-keyword">return</span> [patternString, <span class="hljs-string">'$$ = $1;'</span>, options] <span class="hljs-keyword">unless</span> action
action = <span class="hljs-keyword">if</span> match = unwrap.exec action <span class="hljs-keyword">then</span> match[<span class="hljs-number">1</span>] <span class="hljs-keyword">else</span> <span class="hljs-string">"(<span class="hljs-subst">#{action}</span>())"</span></pre></div></div>
<span class="hljs-keyword">if</span> action
action = <span class="hljs-keyword">if</span> match = unwrap.exec action <span class="hljs-keyword">then</span> match[<span class="hljs-number">1</span>] <span class="hljs-keyword">else</span> <span class="hljs-string">"(<span class="hljs-subst">#{action}</span>())"</span></pre></div></div>
</li>
@ -225,8 +225,8 @@ previous nonterminal.</p>
</div>
<div class="content"><div class='highlight'><pre> action = action.replace <span class="hljs-regexp">/\bnew /g</span>, <span class="hljs-string">'$&amp;yy.'</span>
action = action.replace <span class="hljs-regexp">/\b(?:Block\.wrap|extend)\b/g</span>, <span class="hljs-string">'yy.$&amp;'</span></pre></div></div>
<div class="content"><div class='highlight'><pre> action = action.replace <span class="hljs-regexp">/\bnew /g</span>, <span class="hljs-string">'$&amp;yy.'</span>
action = action.replace <span class="hljs-regexp">/\b(?:Block\.wrap|extend)\b/g</span>, <span class="hljs-string">'yy.$&amp;'</span></pre></div></div>
</li>
@ -237,22 +237,23 @@ previous nonterminal.</p>
<div class="pilwrap ">
<a class="pilcrow" href="#section-8">&#182;</a>
</div>
<p>Returns a function which adds location data to the first parameter passed
in, and returns the parameter. If the parameter is not a node, it will
just be passed through unaffected.</p>
<p>Returns strings of functions to add to <code>parser.js</code> which add extra data
that nodes may have, such as comments or location data. Location data
is added to the first parameter passed in, and the parameter is returned.
If the parameter is not a node, it will just be passed through unaffected.</p>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-function"> <span class="hljs-title">addLocationDataFn</span> = <span class="hljs-params">(first, last)</span> -&gt;</span>
<span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> last
<span class="hljs-string">"yy.addLocationDataFn(@<span class="hljs-subst">#{first}</span>)"</span>
<span class="hljs-keyword">else</span>
<span class="hljs-string">"yy.addLocationDataFn(@<span class="hljs-subst">#{first}</span>, @<span class="hljs-subst">#{last}</span>)"</span>
<div class="content"><div class='highlight'><pre><span class="hljs-function"> <span class="hljs-title">getAddDataToNodeFunctionString</span> = <span class="hljs-params">(first, last)</span> -&gt;</span>
<span class="hljs-string">"yy.addDataToNode(yy, @<span class="hljs-subst">#{first}</span><span class="hljs-subst">#{<span class="hljs-keyword">if</span> last <span class="hljs-keyword">then</span> <span class="hljs-string">", @<span class="hljs-subst">#{last}</span>"</span> <span class="hljs-keyword">else</span> <span class="hljs-string">''</span>}</span>)"</span>
action = action.replace <span class="hljs-regexp">/LOC\(([0-9]*)\)/g</span>, addLocationDataFn(<span class="hljs-string">'$1'</span>)
action = action.replace <span class="hljs-regexp">/LOC\(([0-9]*),\s*([0-9]*)\)/g</span>, addLocationDataFn(<span class="hljs-string">'$1'</span>, <span class="hljs-string">'$2'</span>)
action = action.replace <span class="hljs-regexp">/LOC\(([0-9]*)\)/g</span>, getAddDataToNodeFunctionString(<span class="hljs-string">'$1'</span>)
action = action.replace <span class="hljs-regexp">/LOC\(([0-9]*),\s*([0-9]*)\)/g</span>, getAddDataToNodeFunctionString(<span class="hljs-string">'$1'</span>, <span class="hljs-string">'$2'</span>)
performActionFunctionString = <span class="hljs-string">"$$ = <span class="hljs-subst">#{getAddDataToNodeFunctionString(<span class="hljs-number">1</span>, patternCount)}</span>(<span class="hljs-subst">#{action}</span>);"</span>
<span class="hljs-keyword">else</span>
performActionFunctionString = <span class="hljs-string">'$$ = $1;'</span>
[patternString, <span class="hljs-string">"$$ = <span class="hljs-subst">#{addLocationDataFn(<span class="hljs-number">1</span>, patternCount)}</span>(<span class="hljs-subst">#{action}</span>);"</span>, options]</pre></div></div>
[patternString, performActionFunctionString, options]</pre></div></div>
</li>
@ -380,7 +381,6 @@ grammar.</p>
<div class="content"><div class='highlight'><pre> Statement: [
o <span class="hljs-string">'Return'</span>
o <span class="hljs-string">'Comment'</span>
o <span class="hljs-string">'STATEMENT'</span>, <span class="hljs-function">-&gt;</span> <span class="hljs-keyword">new</span> StatementLiteral $<span class="hljs-number">1</span>
o <span class="hljs-string">'Import'</span>
o <span class="hljs-string">'Export'</span>
@ -404,7 +404,6 @@ them somewhat circular.</p>
<div class="content"><div class='highlight'><pre> Expression: [
o <span class="hljs-string">'Value'</span>
o <span class="hljs-string">'Invocation'</span>
o <span class="hljs-string">'Code'</span>
o <span class="hljs-string">'Operation'</span>
o <span class="hljs-string">'Assign'</span>
@ -500,11 +499,11 @@ through and printed to JavaScript.</p>
o <span class="hljs-string">'AlphaNumeric'</span>
o <span class="hljs-string">'JS'</span>, <span class="hljs-function">-&gt;</span> <span class="hljs-keyword">new</span> PassthroughLiteral $<span class="hljs-number">1</span>
o <span class="hljs-string">'Regex'</span>
o <span class="hljs-string">'UNDEFINED'</span>, <span class="hljs-function">-&gt;</span> <span class="hljs-keyword">new</span> UndefinedLiteral
o <span class="hljs-string">'NULL'</span>, <span class="hljs-function">-&gt;</span> <span class="hljs-keyword">new</span> NullLiteral
o <span class="hljs-string">'UNDEFINED'</span>, <span class="hljs-function">-&gt;</span> <span class="hljs-keyword">new</span> UndefinedLiteral $<span class="hljs-number">1</span>
o <span class="hljs-string">'NULL'</span>, <span class="hljs-function">-&gt;</span> <span class="hljs-keyword">new</span> NullLiteral $<span class="hljs-number">1</span>
o <span class="hljs-string">'BOOL'</span>, <span class="hljs-function">-&gt;</span> <span class="hljs-keyword">new</span> BooleanLiteral $<span class="hljs-number">1</span>
o <span class="hljs-string">'INFINITY'</span>, <span class="hljs-function">-&gt;</span> <span class="hljs-keyword">new</span> InfinityLiteral $<span class="hljs-number">1</span>
o <span class="hljs-string">'NAN'</span>, <span class="hljs-function">-&gt;</span> <span class="hljs-keyword">new</span> NaNLiteral
o <span class="hljs-string">'NAN'</span>, <span class="hljs-function">-&gt;</span> <span class="hljs-keyword">new</span> NaNLiteral $<span class="hljs-number">1</span>
]</pre></div></div>
</li>
@ -553,7 +552,6 @@ the ordinary <strong>Assign</strong> is that these allow numbers and strings as
o <span class="hljs-string">'SimpleObjAssignable =
INDENT Expression OUTDENT'</span>, <span class="hljs-function">-&gt;</span> <span class="hljs-keyword">new</span> Assign LOC(<span class="hljs-number">1</span>)(<span class="hljs-keyword">new</span> Value $<span class="hljs-number">1</span>), $<span class="hljs-number">4</span>, <span class="hljs-literal">null</span>,
operatorToken: LOC(<span class="hljs-number">2</span>)(<span class="hljs-keyword">new</span> Literal $<span class="hljs-number">2</span>)
o <span class="hljs-string">'Comment'</span>
]
SimpleObjAssignable: [
@ -582,7 +580,9 @@ the ordinary <strong>Assign</strong> is that these allow numbers and strings as
<div class="content"><div class='highlight'><pre> ObjRestValue: [
o <span class="hljs-string">'SimpleObjAssignable ...'</span>, <span class="hljs-function">-&gt;</span> <span class="hljs-keyword">new</span> Splat <span class="hljs-keyword">new</span> Value $<span class="hljs-number">1</span>
o <span class="hljs-string">'... SimpleObjAssignable'</span>, <span class="hljs-function">-&gt;</span> <span class="hljs-keyword">new</span> Splat <span class="hljs-keyword">new</span> Value $<span class="hljs-number">2</span>
o <span class="hljs-string">'ObjSpreadExpr ...'</span>, <span class="hljs-function">-&gt;</span> <span class="hljs-keyword">new</span> Splat $<span class="hljs-number">1</span>
o <span class="hljs-string">'... ObjSpreadExpr'</span>, <span class="hljs-function">-&gt;</span> <span class="hljs-keyword">new</span> Splat $<span class="hljs-number">2</span>
]
ObjSpreadExpr: [
@ -591,14 +591,19 @@ the ordinary <strong>Assign</strong> is that these allow numbers and strings as
o <span class="hljs-string">'Parenthetical'</span>
o <span class="hljs-string">'Super'</span>
o <span class="hljs-string">'This'</span>
o <span class="hljs-string">'SUPER Arguments'</span>, <span class="hljs-function">-&gt;</span> <span class="hljs-keyword">new</span> SuperCall LOC(<span class="hljs-number">1</span>)(<span class="hljs-keyword">new</span> Super), $<span class="hljs-number">2</span>
o <span class="hljs-string">'SUPER Arguments'</span>, <span class="hljs-function">-&gt;</span> <span class="hljs-keyword">new</span> SuperCall LOC(<span class="hljs-number">1</span>)(<span class="hljs-keyword">new</span> Super), $<span class="hljs-number">2</span>, <span class="hljs-literal">no</span>, $<span class="hljs-number">1</span>
o <span class="hljs-string">'SimpleObjAssignable Arguments'</span>, <span class="hljs-function">-&gt;</span> <span class="hljs-keyword">new</span> Call (<span class="hljs-keyword">new</span> Value $<span class="hljs-number">1</span>), $<span class="hljs-number">2</span>
o <span class="hljs-string">'ObjSpreadExpr Arguments'</span>, <span class="hljs-function">-&gt;</span> <span class="hljs-keyword">new</span> Call $<span class="hljs-number">1</span>, $<span class="hljs-number">2</span>
]
ObjSpreadIdentifier: [
o <span class="hljs-string">'SimpleObjAssignable . Property'</span>, <span class="hljs-function">-&gt;</span> (<span class="hljs-keyword">new</span> Value $<span class="hljs-number">1</span>).add(<span class="hljs-keyword">new</span> Access $<span class="hljs-number">3</span>)
o <span class="hljs-string">'SimpleObjAssignable INDEX_START IndexValue INDEX_END'</span>, <span class="hljs-function">-&gt;</span> (<span class="hljs-keyword">new</span> Value $<span class="hljs-number">1</span>).add($<span class="hljs-number">3</span>)
o <span class="hljs-string">'SimpleObjAssignable ObjSpreadAccessor'</span>, <span class="hljs-function">-&gt;</span> (<span class="hljs-keyword">new</span> Value $<span class="hljs-number">1</span>).add $<span class="hljs-number">2</span>
o <span class="hljs-string">'ObjSpreadExpr ObjSpreadAccessor'</span>, <span class="hljs-function">-&gt;</span> (<span class="hljs-keyword">new</span> Value $<span class="hljs-number">1</span>).add $<span class="hljs-number">2</span>
]
ObjSpreadAccessor: [
o <span class="hljs-string">'. Property'</span>, <span class="hljs-function">-&gt;</span> <span class="hljs-keyword">new</span> Access $<span class="hljs-number">2</span>
o <span class="hljs-string">'INDEX_START IndexValue INDEX_END'</span>, <span class="hljs-function">-&gt;</span> $<span class="hljs-number">2</span>
]</pre></div></div>
</li>
@ -616,6 +621,7 @@ the ordinary <strong>Assign</strong> is that these allow numbers and strings as
<div class="content"><div class='highlight'><pre> Return: [
o <span class="hljs-string">'RETURN Expression'</span>, <span class="hljs-function">-&gt;</span> <span class="hljs-keyword">new</span> Return $<span class="hljs-number">2</span>
o <span class="hljs-string">'RETURN INDENT Object OUTDENT'</span>, <span class="hljs-function">-&gt;</span> <span class="hljs-keyword">new</span> Return <span class="hljs-keyword">new</span> Value $<span class="hljs-number">3</span>
o <span class="hljs-string">'RETURN'</span>, <span class="hljs-function">-&gt;</span> <span class="hljs-keyword">new</span> Return
]
@ -638,23 +644,6 @@ the ordinary <strong>Assign</strong> is that these allow numbers and strings as
<div class="pilwrap ">
<a class="pilcrow" href="#section-24">&#182;</a>
</div>
<p>A block comment.</p>
</div>
<div class="content"><div class='highlight'><pre> Comment: [
o <span class="hljs-string">'HERECOMMENT'</span>, <span class="hljs-function">-&gt;</span> <span class="hljs-keyword">new</span> Comment $<span class="hljs-number">1</span>
]</pre></div></div>
</li>
<li id="section-25">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-25">&#182;</a>
</div>
<p>The <strong>Code</strong> node is the function literal. Its defined by an indented block
of <strong>Block</strong> preceded by a function arrow, with an optional parameter list.</p>
@ -668,11 +657,11 @@ of <strong>Block</strong> preceded by a function arrow, with an optional paramet
</li>
<li id="section-26">
<li id="section-25">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-26">&#182;</a>
<a class="pilcrow" href="#section-25">&#182;</a>
</div>
<p>CoffeeScript has two different symbols for functions. <code>-&gt;</code> is for ordinary
functions, and <code>=&gt;</code> is for functions bound to the current value of <em>this</em>.</p>
@ -680,18 +669,18 @@ functions, and <code>=&gt;</code> is for functions bound to the current value of
</div>
<div class="content"><div class='highlight'><pre> FuncGlyph: [
o <span class="hljs-string">'-&gt;'</span>, <span class="hljs-function">-&gt;</span> <span class="hljs-string">'func'</span>
o <span class="hljs-string">'=&gt;'</span>, <span class="hljs-function">-&gt;</span> <span class="hljs-string">'boundfunc'</span>
o <span class="hljs-string">'-&gt;'</span>, <span class="hljs-function">-&gt;</span> <span class="hljs-keyword">new</span> FuncGlyph $<span class="hljs-number">1</span>
o <span class="hljs-string">'=&gt;'</span>, <span class="hljs-function">-&gt;</span> <span class="hljs-keyword">new</span> FuncGlyph $<span class="hljs-number">1</span>
]</pre></div></div>
</li>
<li id="section-27">
<li id="section-26">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-27">&#182;</a>
<a class="pilcrow" href="#section-26">&#182;</a>
</div>
<p>An optional, trailing comma.</p>
@ -705,11 +694,11 @@ functions, and <code>=&gt;</code> is for functions bound to the current value of
</li>
<li id="section-28">
<li id="section-27">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-28">&#182;</a>
<a class="pilcrow" href="#section-27">&#182;</a>
</div>
<p>The list of parameters that a function accepts can be of any length.</p>
@ -726,11 +715,11 @@ functions, and <code>=&gt;</code> is for functions bound to the current value of
</li>
<li id="section-29">
<li id="section-28">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-29">&#182;</a>
<a class="pilcrow" href="#section-28">&#182;</a>
</div>
<p>A single parameter in a function definition can be ordinary, or a splat
that hoovers up the remaining arguments.</p>
@ -740,6 +729,7 @@ that hoovers up the remaining arguments.</p>
<div class="content"><div class='highlight'><pre> Param: [
o <span class="hljs-string">'ParamVar'</span>, <span class="hljs-function">-&gt;</span> <span class="hljs-keyword">new</span> Param $<span class="hljs-number">1</span>
o <span class="hljs-string">'ParamVar ...'</span>, <span class="hljs-function">-&gt;</span> <span class="hljs-keyword">new</span> Param $<span class="hljs-number">1</span>, <span class="hljs-literal">null</span>, <span class="hljs-literal">on</span>
o <span class="hljs-string">'... ParamVar'</span>, <span class="hljs-function">-&gt;</span> <span class="hljs-keyword">new</span> Param $<span class="hljs-number">2</span>, <span class="hljs-literal">null</span>, <span class="hljs-literal">on</span>
o <span class="hljs-string">'ParamVar = Expression'</span>, <span class="hljs-function">-&gt;</span> <span class="hljs-keyword">new</span> Param $<span class="hljs-number">1</span>, $<span class="hljs-number">3</span>
o <span class="hljs-string">'...'</span>, <span class="hljs-function">-&gt;</span> <span class="hljs-keyword">new</span> Expansion
]</pre></div></div>
@ -747,11 +737,11 @@ that hoovers up the remaining arguments.</p>
</li>
<li id="section-30">
<li id="section-29">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-30">&#182;</a>
<a class="pilcrow" href="#section-29">&#182;</a>
</div>
<p>Function Parameters</p>
@ -767,11 +757,11 @@ that hoovers up the remaining arguments.</p>
</li>
<li id="section-31">
<li id="section-30">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-31">&#182;</a>
<a class="pilcrow" href="#section-30">&#182;</a>
</div>
<p>A splat that occurs outside of a parameter list.</p>
@ -779,6 +769,26 @@ that hoovers up the remaining arguments.</p>
<div class="content"><div class='highlight'><pre> Splat: [
o <span class="hljs-string">'Expression ...'</span>, <span class="hljs-function">-&gt;</span> <span class="hljs-keyword">new</span> Splat $<span class="hljs-number">1</span>
o <span class="hljs-string">'... Expression'</span>, <span class="hljs-function">-&gt;</span> <span class="hljs-keyword">new</span> Splat $<span class="hljs-number">2</span>
]</pre></div></div>
</li>
<li id="section-31">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-31">&#182;</a>
</div>
<p>Variables and properties that can be assigned to.</p>
</div>
<div class="content"><div class='highlight'><pre> SimpleAssignable: [
o <span class="hljs-string">'Identifier'</span>, <span class="hljs-function">-&gt;</span> <span class="hljs-keyword">new</span> Value $<span class="hljs-number">1</span>
o <span class="hljs-string">'Value Accessor'</span>, <span class="hljs-function">-&gt;</span> $<span class="hljs-number">1.</span>add $<span class="hljs-number">2</span>
o <span class="hljs-string">'ThisProperty'</span>
]</pre></div></div>
</li>
@ -790,26 +800,6 @@ that hoovers up the remaining arguments.</p>
<div class="pilwrap ">
<a class="pilcrow" href="#section-32">&#182;</a>
</div>
<p>Variables and properties that can be assigned to.</p>
</div>
<div class="content"><div class='highlight'><pre> SimpleAssignable: [
o <span class="hljs-string">'Identifier'</span>, <span class="hljs-function">-&gt;</span> <span class="hljs-keyword">new</span> Value $<span class="hljs-number">1</span>
o <span class="hljs-string">'Value Accessor'</span>, <span class="hljs-function">-&gt;</span> $<span class="hljs-number">1.</span>add $<span class="hljs-number">2</span>
o <span class="hljs-string">'Invocation Accessor'</span>, <span class="hljs-function">-&gt;</span> <span class="hljs-keyword">new</span> Value $<span class="hljs-number">1</span>, [].concat $<span class="hljs-number">2</span>
o <span class="hljs-string">'ThisProperty'</span>
]</pre></div></div>
</li>
<li id="section-33">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-33">&#182;</a>
</div>
<p>Everything that can be assigned to.</p>
</div>
@ -823,11 +813,11 @@ that hoovers up the remaining arguments.</p>
</li>
<li id="section-34">
<li id="section-33">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-34">&#182;</a>
<a class="pilcrow" href="#section-33">&#182;</a>
</div>
<p>The types of things that can be treated as values assigned to, invoked
as functions, indexed into, named as a class, etc.</p>
@ -839,8 +829,27 @@ as functions, indexed into, named as a class, etc.</p>
o <span class="hljs-string">'Literal'</span>, <span class="hljs-function">-&gt;</span> <span class="hljs-keyword">new</span> Value $<span class="hljs-number">1</span>
o <span class="hljs-string">'Parenthetical'</span>, <span class="hljs-function">-&gt;</span> <span class="hljs-keyword">new</span> Value $<span class="hljs-number">1</span>
o <span class="hljs-string">'Range'</span>, <span class="hljs-function">-&gt;</span> <span class="hljs-keyword">new</span> Value $<span class="hljs-number">1</span>
o <span class="hljs-string">'Invocation'</span>, <span class="hljs-function">-&gt;</span> <span class="hljs-keyword">new</span> Value $<span class="hljs-number">1</span>
o <span class="hljs-string">'This'</span>
o <span class="hljs-string">'Super'</span>
o <span class="hljs-string">'Super'</span>, <span class="hljs-function">-&gt;</span> <span class="hljs-keyword">new</span> Value $<span class="hljs-number">1</span>
]</pre></div></div>
</li>
<li id="section-34">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-34">&#182;</a>
</div>
<p>A <code>super</code>-based expression that can be used as a value.</p>
</div>
<div class="content"><div class='highlight'><pre> Super: [
o <span class="hljs-string">'SUPER . Property'</span>, <span class="hljs-function">-&gt;</span> <span class="hljs-keyword">new</span> Super LOC(<span class="hljs-number">3</span>)(<span class="hljs-keyword">new</span> Access $<span class="hljs-number">3</span>), [], <span class="hljs-literal">no</span>, $<span class="hljs-number">1</span>
o <span class="hljs-string">'SUPER INDEX_START Expression INDEX_END'</span>, <span class="hljs-function">-&gt;</span> <span class="hljs-keyword">new</span> Super LOC(<span class="hljs-number">3</span>)(<span class="hljs-keyword">new</span> Index $<span class="hljs-number">3</span>), [], <span class="hljs-literal">no</span>, $<span class="hljs-number">1</span>
]</pre></div></div>
</li>
@ -852,24 +861,6 @@ as functions, indexed into, named as a class, etc.</p>
<div class="pilwrap ">
<a class="pilcrow" href="#section-35">&#182;</a>
</div>
<p>A <code>super</code>-based expression that can be used as a value.</p>
</div>
<div class="content"><div class='highlight'><pre> Super: [
o <span class="hljs-string">'SUPER . Property'</span>, <span class="hljs-function">-&gt;</span> <span class="hljs-keyword">new</span> Super LOC(<span class="hljs-number">3</span>) <span class="hljs-keyword">new</span> Access $<span class="hljs-number">3</span>
o <span class="hljs-string">'SUPER INDEX_START Expression INDEX_END'</span>, <span class="hljs-function">-&gt;</span> <span class="hljs-keyword">new</span> Super LOC(<span class="hljs-number">3</span>) <span class="hljs-keyword">new</span> Index $<span class="hljs-number">3</span>
]</pre></div></div>
</li>
<li id="section-36">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-36">&#182;</a>
</div>
<p>The general group of accessors into an object, by property, by prototype
or by array index or slice.</p>
@ -887,11 +878,11 @@ or by array index or slice.</p>
</li>
<li id="section-37">
<li id="section-36">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-37">&#182;</a>
<a class="pilcrow" href="#section-36">&#182;</a>
</div>
<p>Indexing into an object or array using bracket notation.</p>
@ -899,7 +890,7 @@ or by array index or slice.</p>
<div class="content"><div class='highlight'><pre> Index: [
o <span class="hljs-string">'INDEX_START IndexValue INDEX_END'</span>, <span class="hljs-function">-&gt;</span> $<span class="hljs-number">2</span>
o <span class="hljs-string">'INDEX_SOAK Index'</span>, <span class="hljs-function">-&gt;</span> extend $<span class="hljs-number">2</span>, soak : <span class="hljs-literal">yes</span>
o <span class="hljs-string">'INDEX_SOAK Index'</span>, <span class="hljs-function">-&gt;</span> extend $<span class="hljs-number">2</span>, soak: <span class="hljs-literal">yes</span>
]
IndexValue: [
@ -910,11 +901,11 @@ or by array index or slice.</p>
</li>
<li id="section-38">
<li id="section-37">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-38">&#182;</a>
<a class="pilcrow" href="#section-37">&#182;</a>
</div>
<p>In CoffeeScript, an object literal is simply a list of assignments.</p>
@ -927,11 +918,11 @@ or by array index or slice.</p>
</li>
<li id="section-39">
<li id="section-38">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-39">&#182;</a>
<a class="pilcrow" href="#section-38">&#182;</a>
</div>
<p>Assignment of properties within an object literal can be separated by
comma, as in JavaScript, or simply by newline.</p>
@ -949,11 +940,11 @@ comma, as in JavaScript, or simply by newline.</p>
</li>
<li id="section-40">
<li id="section-39">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-40">&#182;</a>
<a class="pilcrow" href="#section-39">&#182;</a>
</div>
<p>Class definitions have optional bodies of prototype property assignments,
and optional references to the superclass.</p>
@ -1038,11 +1029,11 @@ and optional references to the superclass.</p>
</li>
<li id="section-41">
<li id="section-40">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-41">&#182;</a>
<a class="pilcrow" href="#section-40">&#182;</a>
</div>
<p>Ordinary function invocation, or a chained series of calls.</p>
@ -1051,18 +1042,17 @@ and optional references to the superclass.</p>
<div class="content"><div class='highlight'><pre> Invocation: [
o <span class="hljs-string">'Value OptFuncExist String'</span>, <span class="hljs-function">-&gt;</span> <span class="hljs-keyword">new</span> TaggedTemplateCall $<span class="hljs-number">1</span>, $<span class="hljs-number">3</span>, $<span class="hljs-number">2</span>
o <span class="hljs-string">'Value OptFuncExist Arguments'</span>, <span class="hljs-function">-&gt;</span> <span class="hljs-keyword">new</span> Call $<span class="hljs-number">1</span>, $<span class="hljs-number">3</span>, $<span class="hljs-number">2</span>
o <span class="hljs-string">'Invocation OptFuncExist Arguments'</span>, <span class="hljs-function">-&gt;</span> <span class="hljs-keyword">new</span> Call $<span class="hljs-number">1</span>, $<span class="hljs-number">3</span>, $<span class="hljs-number">2</span>
o <span class="hljs-string">'SUPER OptFuncExist Arguments'</span>, <span class="hljs-function">-&gt;</span> <span class="hljs-keyword">new</span> SuperCall LOC(<span class="hljs-number">1</span>)(<span class="hljs-keyword">new</span> Super), $<span class="hljs-number">3</span>, $<span class="hljs-number">2</span>
o <span class="hljs-string">'SUPER OptFuncExist Arguments'</span>, <span class="hljs-function">-&gt;</span> <span class="hljs-keyword">new</span> SuperCall LOC(<span class="hljs-number">1</span>)(<span class="hljs-keyword">new</span> Super), $<span class="hljs-number">3</span>, $<span class="hljs-number">2</span>, $<span class="hljs-number">1</span>
]</pre></div></div>
</li>
<li id="section-42">
<li id="section-41">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-42">&#182;</a>
<a class="pilcrow" href="#section-41">&#182;</a>
</div>
<p>An optional existence check on a function.</p>
@ -1076,11 +1066,11 @@ and optional references to the superclass.</p>
</li>
<li id="section-43">
<li id="section-42">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-43">&#182;</a>
<a class="pilcrow" href="#section-42">&#182;</a>
</div>
<p>The list of arguments to a function call.</p>
@ -1094,19 +1084,36 @@ and optional references to the superclass.</p>
</li>
<li id="section-44">
<li id="section-43">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-44">&#182;</a>
<a class="pilcrow" href="#section-43">&#182;</a>
</div>
<p>A reference to the <em>this</em> current object.</p>
</div>
<div class="content"><div class='highlight'><pre> This: [
o <span class="hljs-string">'THIS'</span>, <span class="hljs-function">-&gt;</span> <span class="hljs-keyword">new</span> Value <span class="hljs-keyword">new</span> ThisLiteral
o <span class="hljs-string">'@'</span>, <span class="hljs-function">-&gt;</span> <span class="hljs-keyword">new</span> Value <span class="hljs-keyword">new</span> ThisLiteral
o <span class="hljs-string">'THIS'</span>, <span class="hljs-function">-&gt;</span> <span class="hljs-keyword">new</span> Value <span class="hljs-keyword">new</span> ThisLiteral $<span class="hljs-number">1</span>
o <span class="hljs-string">'@'</span>, <span class="hljs-function">-&gt;</span> <span class="hljs-keyword">new</span> Value <span class="hljs-keyword">new</span> ThisLiteral $<span class="hljs-number">1</span>
]</pre></div></div>
</li>
<li id="section-44">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-44">&#182;</a>
</div>
<p>A reference to a property on <em>this</em>.</p>
</div>
<div class="content"><div class='highlight'><pre> ThisProperty: [
o <span class="hljs-string">'@ Property'</span>, <span class="hljs-function">-&gt;</span> <span class="hljs-keyword">new</span> Value LOC(<span class="hljs-number">1</span>)(<span class="hljs-keyword">new</span> ThisLiteral $<span class="hljs-number">1</span>), [LOC(<span class="hljs-number">2</span>)(<span class="hljs-keyword">new</span> Access($<span class="hljs-number">2</span>))], <span class="hljs-string">'this'</span>
]</pre></div></div>
</li>
@ -1118,23 +1125,6 @@ and optional references to the superclass.</p>
<div class="pilwrap ">
<a class="pilcrow" href="#section-45">&#182;</a>
</div>
<p>A reference to a property on <em>this</em>.</p>
</div>
<div class="content"><div class='highlight'><pre> ThisProperty: [
o <span class="hljs-string">'@ Property'</span>, <span class="hljs-function">-&gt;</span> <span class="hljs-keyword">new</span> Value LOC(<span class="hljs-number">1</span>)(<span class="hljs-keyword">new</span> ThisLiteral), [LOC(<span class="hljs-number">2</span>)(<span class="hljs-keyword">new</span> Access($<span class="hljs-number">2</span>))], <span class="hljs-string">'this'</span>
]</pre></div></div>
</li>
<li id="section-46">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-46">&#182;</a>
</div>
<p>The array literal.</p>
</div>
@ -1147,11 +1137,11 @@ and optional references to the superclass.</p>
</li>
<li id="section-47">
<li id="section-46">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-47">&#182;</a>
<a class="pilcrow" href="#section-46">&#182;</a>
</div>
<p>Inclusive and exclusive range dots.</p>
@ -1165,11 +1155,11 @@ and optional references to the superclass.</p>
</li>
<li id="section-48">
<li id="section-47">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-48">&#182;</a>
<a class="pilcrow" href="#section-47">&#182;</a>
</div>
<p>The CoffeeScript range literal.</p>
@ -1182,11 +1172,11 @@ and optional references to the superclass.</p>
</li>
<li id="section-49">
<li id="section-48">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-49">&#182;</a>
<a class="pilcrow" href="#section-48">&#182;</a>
</div>
<p>Array slice literals.</p>
@ -1202,11 +1192,11 @@ and optional references to the superclass.</p>
</li>
<li id="section-50">
<li id="section-49">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-50">&#182;</a>
<a class="pilcrow" href="#section-49">&#182;</a>
</div>
<p>The <strong>ArgList</strong> is both the list of objects passed into a function call,
as well as the contents of an array literal
@ -1225,11 +1215,11 @@ as well as the contents of an array literal
</li>
<li id="section-51">
<li id="section-50">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-51">&#182;</a>
<a class="pilcrow" href="#section-50">&#182;</a>
</div>
<p>Valid arguments are Blocks or Splats.</p>
@ -1244,11 +1234,11 @@ as well as the contents of an array literal
</li>
<li id="section-52">
<li id="section-51">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-52">&#182;</a>
<a class="pilcrow" href="#section-51">&#182;</a>
</div>
<p>Just simple, comma-separated, required arguments (no fancy syntax). We need
this to be separate from the <strong>ArgList</strong> for use in <strong>Switch</strong> blocks, where
@ -1264,11 +1254,11 @@ having the newlines wouldnt make sense.</p>
</li>
<li id="section-53">
<li id="section-52">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-53">&#182;</a>
<a class="pilcrow" href="#section-52">&#182;</a>
</div>
<p>The variants of <em>try/catch/finally</em> exception handling blocks.</p>
@ -1284,11 +1274,11 @@ having the newlines wouldnt make sense.</p>
</li>
<li id="section-54">
<li id="section-53">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-54">&#182;</a>
<a class="pilcrow" href="#section-53">&#182;</a>
</div>
<p>A catch clause names its error and runs a block of code.</p>
@ -1303,11 +1293,11 @@ having the newlines wouldnt make sense.</p>
</li>
<li id="section-55">
<li id="section-54">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-55">&#182;</a>
<a class="pilcrow" href="#section-54">&#182;</a>
</div>
<p>Throw an exception object.</p>
@ -1315,16 +1305,17 @@ having the newlines wouldnt make sense.</p>
<div class="content"><div class='highlight'><pre> Throw: [
o <span class="hljs-string">'THROW Expression'</span>, <span class="hljs-function">-&gt;</span> <span class="hljs-keyword">new</span> Throw $<span class="hljs-number">2</span>
o <span class="hljs-string">'THROW INDENT Object OUTDENT'</span>, <span class="hljs-function">-&gt;</span> <span class="hljs-keyword">new</span> Throw <span class="hljs-keyword">new</span> Value $<span class="hljs-number">3</span>
]</pre></div></div>
</li>
<li id="section-56">
<li id="section-55">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-56">&#182;</a>
<a class="pilcrow" href="#section-55">&#182;</a>
</div>
<p>Parenthetical expressions. Note that the <strong>Parenthetical</strong> is a <strong>Value</strong>,
not an <strong>Expression</strong>, so if you need to use an expression in a place
@ -1341,11 +1332,11 @@ the trick.</p>
</li>
<li id="section-57">
<li id="section-56">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-57">&#182;</a>
<a class="pilcrow" href="#section-56">&#182;</a>
</div>
<p>The condition portion of a while loop.</p>
@ -1361,11 +1352,11 @@ the trick.</p>
</li>
<li id="section-58">
<li id="section-57">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-58">&#182;</a>
<a class="pilcrow" href="#section-57">&#182;</a>
</div>
<p>The while loop can either be normal, with a block of expressions to execute,
or postfix, with a single expression. There is no do..while.</p>
@ -1387,11 +1378,11 @@ or postfix, with a single expression. There is no do..while.</p>
</li>
<li id="section-59">
<li id="section-58">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-59">&#182;</a>
<a class="pilcrow" href="#section-58">&#182;</a>
</div>
<p>Array, object, and range comprehensions, at the most generic level.
Comprehensions can either be normal, with a block of expressions to execute,
@ -1419,11 +1410,11 @@ or postfix, with a single expression.</p>
</li>
<li id="section-60">
<li id="section-59">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-60">&#182;</a>
<a class="pilcrow" href="#section-59">&#182;</a>
</div>
<p>An array of all accepted values for a variable inside the loop.
This enables support for pattern matching.</p>
@ -1440,11 +1431,11 @@ This enables support for pattern matching.</p>
</li>
<li id="section-61">
<li id="section-60">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-61">&#182;</a>
<a class="pilcrow" href="#section-60">&#182;</a>
</div>
<p>An array or range comprehension has variables for the current element
and (optional) reference to the current index. Or, <em>key, value</em>, in the case
@ -1460,11 +1451,11 @@ of object comprehensions.</p>
</li>
<li id="section-62">
<li id="section-61">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-62">&#182;</a>
<a class="pilcrow" href="#section-61">&#182;</a>
</div>
<p>The source of a comprehension is an array or object with an optional guard
clause. If its an array comprehension, you can also choose to step through
@ -1499,11 +1490,11 @@ in fixed-size increments.</p>
</li>
<li id="section-63">
<li id="section-62">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-63">&#182;</a>
<a class="pilcrow" href="#section-62">&#182;</a>
</div>
<p>An individual <strong>When</strong> clause, with action.</p>
@ -1517,11 +1508,11 @@ in fixed-size increments.</p>
</li>
<li id="section-64">
<li id="section-63">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-64">&#182;</a>
<a class="pilcrow" href="#section-63">&#182;</a>
</div>
<p>The most basic form of <em>if</em> is a condition and an action. The following
if-related rules are broken up along these lines in order to avoid
@ -1537,11 +1528,11 @@ ambiguity.</p>
</li>
<li id="section-65">
<li id="section-64">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-65">&#182;</a>
<a class="pilcrow" href="#section-64">&#182;</a>
</div>
<p>The full complement of <em>if</em> expressions, including postfix one-liner
<em>if</em> and <em>unless</em>.</p>
@ -1558,11 +1549,11 @@ ambiguity.</p>
</li>
<li id="section-66">
<li id="section-65">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-66">&#182;</a>
<a class="pilcrow" href="#section-65">&#182;</a>
</div>
<p>Arithmetic and logical operators, working on one or more operands.
Here they are grouped by order of precedence. The actual precedence rules
@ -1589,11 +1580,11 @@ rules are necessary.</p>
</li>
<li id="section-67">
<li id="section-66">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-67">&#182;</a>
<a class="pilcrow" href="#section-66">&#182;</a>
</div>
<p><a href="http://coffeescript.org/#existential-operator">The existential operator</a>.</p>
@ -1631,13 +1622,25 @@ rules are necessary.</p>
</li>
<li id="section-67">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-67">&#182;</a>
</div>
<h2 id="precedence">Precedence</h2>
</div>
</li>
<li id="section-68">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-68">&#182;</a>
</div>
<h2 id="precedence">Precedence</h2>
</div>
@ -1650,18 +1653,6 @@ rules are necessary.</p>
<div class="pilwrap ">
<a class="pilcrow" href="#section-69">&#182;</a>
</div>
</div>
</li>
<li id="section-70">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-70">&#182;</a>
</div>
<p>Operators at the top of this list have higher precedence than the ones lower
down. Following these rules is what makes <code>2 + 3 * 4</code> parse as:</p>
<pre><code><span class="hljs-number">2</span> + (<span class="hljs-number">3</span> * <span class="hljs-number">4</span>)
@ -1701,13 +1692,25 @@ down. Following these rules is what makes <code>2 + 3 * 4</code> parse as:</p>
</li>
<li id="section-70">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-70">&#182;</a>
</div>
<h2 id="wrapping-up">Wrapping Up</h2>
</div>
</li>
<li id="section-71">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-71">&#182;</a>
</div>
<h2 id="wrapping-up">Wrapping Up</h2>
</div>
@ -1720,18 +1723,6 @@ down. Following these rules is what makes <code>2 + 3 * 4</code> parse as:</p>
<div class="pilwrap ">
<a class="pilcrow" href="#section-72">&#182;</a>
</div>
</div>
</li>
<li id="section-73">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-73">&#182;</a>
</div>
<p>Finally, now that we have our <strong>grammar</strong> and our <strong>operators</strong>, we can create
our <strong>Jison.Parser</strong>. We do this by processing all of our rules, recording all
terminals (every symbol which does not appear as the name of a rule above)
@ -1750,11 +1741,11 @@ as “tokens”.</p>
</li>
<li id="section-74">
<li id="section-73">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-74">&#182;</a>
<a class="pilcrow" href="#section-73">&#182;</a>
</div>
<p>Initialize the <strong>Parser</strong> with our list of terminal <strong>tokens</strong>, our <strong>grammar</strong>
rules, and the name of the root. Reverse the operators because Jison orders

View file

@ -382,7 +382,10 @@ If <code>last</code> is not provided, this will simply return <code>first</code>
first_line: first.first_line
first_column: first.first_column
last_line: last.last_line
last_column: last.last_column</pre></div></div>
last_column: last.last_column
<span class="hljs-function">
<span class="hljs-title">buildLocationHash</span> = <span class="hljs-params">(loc)</span> -&gt;</span>
<span class="hljs-string">"<span class="hljs-subst">#{loc.first_line}</span>x<span class="hljs-subst">#{loc.first_column}</span>-<span class="hljs-subst">#{loc.last_line}</span>x<span class="hljs-subst">#{loc.last_column}</span>"</span></pre></div></div>
</li>
@ -399,12 +402,8 @@ The object is returned either way.</p>
</div>
<div class="content"><div class='highlight'><pre>exports.addLocationDataFn = <span class="hljs-function"><span class="hljs-params">(first, last)</span> -&gt;</span>
(obj) -&gt;
<span class="hljs-keyword">if</span> ((<span class="hljs-keyword">typeof</span> obj) <span class="hljs-keyword">is</span> <span class="hljs-string">'object'</span>) <span class="hljs-keyword">and</span> (!!obj[<span class="hljs-string">'updateLocationDataIfMissing'</span>])
obj.updateLocationDataIfMissing buildLocationData(first, last)
<span class="hljs-keyword">return</span> obj</pre></div></div>
<div class="content"><div class='highlight'><pre>exports.addDataToNode = <span class="hljs-function"><span class="hljs-params">(parserState, first, last)</span> -&gt;</span>
(obj) -&gt;</pre></div></div>
</li>
@ -415,6 +414,56 @@ The object is returned either way.</p>
<div class="pilwrap ">
<a class="pilcrow" href="#section-16">&#182;</a>
</div>
<p>Add location data</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> obj?.updateLocationDataIfMissing? <span class="hljs-keyword">and</span> first?
obj.updateLocationDataIfMissing buildLocationData(first, last)</pre></div></div>
</li>
<li id="section-17">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-17">&#182;</a>
</div>
<p>Add comments data</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">unless</span> parserState.tokenComments
parserState.tokenComments = {}
<span class="hljs-keyword">for</span> token <span class="hljs-keyword">in</span> parserState.parser.tokens <span class="hljs-keyword">when</span> token.comments
tokenHash = buildLocationHash token[<span class="hljs-number">2</span>]
<span class="hljs-keyword">unless</span> parserState.tokenComments[tokenHash]?
parserState.tokenComments[tokenHash] = token.comments
<span class="hljs-keyword">else</span>
parserState.tokenComments[tokenHash].push token.comments...
<span class="hljs-keyword">if</span> obj.locationData?
objHash = buildLocationHash obj.locationData
<span class="hljs-keyword">if</span> parserState.tokenComments[objHash]?
attachCommentsToNode parserState.tokenComments[objHash], obj
obj
exports.attachCommentsToNode = attachCommentsToNode = <span class="hljs-function"><span class="hljs-params">(comments, node)</span> -&gt;</span>
<span class="hljs-keyword">return</span> <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> comments? <span class="hljs-keyword">or</span> comments.length <span class="hljs-keyword">is</span> <span class="hljs-number">0</span>
node.comments ?= []
node.comments.push comments...</pre></div></div>
</li>
<li id="section-18">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-18">&#182;</a>
</div>
<p>Convert jison location data to a string.
<code>obj</code> can be a token, or a locationData.</p>
@ -433,11 +482,11 @@ The object is returned either way.</p>
</li>
<li id="section-17">
<li id="section-19">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-17">&#182;</a>
<a class="pilcrow" href="#section-19">&#182;</a>
</div>
<p>A <code>.coffee.md</code> compatible version of <code>basename</code>, that returns the file sans-extension.</p>
@ -456,11 +505,11 @@ The object is returned either way.</p>
</li>
<li id="section-18">
<li id="section-20">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-18">&#182;</a>
<a class="pilcrow" href="#section-20">&#182;</a>
</div>
<p>Determine if a filename represents a CoffeeScript file.</p>
@ -471,11 +520,11 @@ The object is returned either way.</p>
</li>
<li id="section-19">
<li id="section-21">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-19">&#182;</a>
<a class="pilcrow" href="#section-21">&#182;</a>
</div>
<p>Determine if a filename represents a Literate CoffeeScript file.</p>
@ -486,11 +535,11 @@ The object is returned either way.</p>
</li>
<li id="section-20">
<li id="section-22">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-20">&#182;</a>
<a class="pilcrow" href="#section-22">&#182;</a>
</div>
<p>Throws a SyntaxError from a given location.
The errors <code>toString</code> will return an error message following the “standard”
@ -507,11 +556,11 @@ marker showing where the error is.</p>
</li>
<li id="section-21">
<li id="section-23">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-21">&#182;</a>
<a class="pilcrow" href="#section-23">&#182;</a>
</div>
<p>Instead of showing the compilers stacktrace, show our custom error message
(this is useful when the error bubbles up in Node.js applications that
@ -526,11 +575,11 @@ compile CoffeeScript for example).</p>
</li>
<li id="section-22">
<li id="section-24">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-22">&#182;</a>
<a class="pilcrow" href="#section-24">&#182;</a>
</div>
<p>Update a compiler SyntaxError with source code information if it didnt have
it already.</p>
@ -542,11 +591,11 @@ it already.</p>
</li>
<li id="section-23">
<li id="section-25">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-23">&#182;</a>
<a class="pilcrow" href="#section-25">&#182;</a>
</div>
<p>Avoid screwing up the <code>stack</code> property of other errors (i.e. possible bugs).</p>
@ -572,11 +621,11 @@ it already.</p>
</li>
<li id="section-24">
<li id="section-26">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-24">&#182;</a>
<a class="pilcrow" href="#section-26">&#182;</a>
</div>
<p>Show only the first line on multi-line errors.</p>
@ -588,11 +637,11 @@ it already.</p>
</li>
<li id="section-25">
<li id="section-27">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-25">&#182;</a>
<a class="pilcrow" href="#section-27">&#182;</a>
</div>
<p>Check to see if were running on a color-enabled TTY.</p>

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -157,8 +157,8 @@ command-line arguments in <code>src/command.coffee</code>.</p>
</div>
<div class="content"><div class='highlight'><pre> constructor: <span class="hljs-function"><span class="hljs-params">(rules, @banner)</span> -&gt;</span>
@rules = buildRules rules</pre></div></div>
<div class="content"><div class='highlight'><pre> constructor: <span class="hljs-function"><span class="hljs-params">(ruleDeclarations, @banner)</span> -&gt;</span>
@rules = buildRules ruleDeclarations</pre></div></div>
</li>
@ -178,20 +178,7 @@ youre responsible for interpreting the options object.</p>
</div>
<div class="content"><div class='highlight'><pre> parse: <span class="hljs-function"><span class="hljs-params">(args)</span> -&gt;</span>
options = arguments: []
skippingArgument = <span class="hljs-literal">no</span>
originalArgs = args
args = normalizeArguments args
<span class="hljs-keyword">for</span> arg, i <span class="hljs-keyword">in</span> args
<span class="hljs-keyword">if</span> skippingArgument
skippingArgument = <span class="hljs-literal">no</span>
<span class="hljs-keyword">continue</span>
<span class="hljs-keyword">if</span> arg <span class="hljs-keyword">is</span> <span class="hljs-string">'--'</span>
pos = originalArgs.indexOf <span class="hljs-string">'--'</span>
options.arguments = options.arguments.concat originalArgs[(pos + <span class="hljs-number">1</span>)..]
<span class="hljs-keyword">break</span>
isOption = !!(arg.match(LONG_FLAG) <span class="hljs-keyword">or</span> arg.match(SHORT_FLAG))</pre></div></div>
<div class="content"><div class='highlight'><pre> parse: <span class="hljs-function"><span class="hljs-params">(args)</span> -&gt;</span></pre></div></div>
</li>
@ -202,27 +189,18 @@ youre responsible for interpreting the options object.</p>
<div class="pilwrap ">
<a class="pilcrow" href="#section-5">&#182;</a>
</div>
<p>the CS option parser is a little odd; options after the first
non-option argument are treated as non-option arguments themselves</p>
<p>The CoffeeScript option parser is a little odd; options after the first
non-option argument are treated as non-option arguments themselves.
Optional arguments are normalized by expanding merged flags into multiple
flags. This allows you to have <code>-wl</code> be the same as <code>--watch --lint</code>.
Note that executable scripts with a shebang (<code>#!</code>) line should use the
line <code>#!/usr/bin/env coffee</code>, or <code>#!/absolute/path/to/coffee</code>, without a
<code>--</code> argument after, because that will fail on Linux (see #3946).</p>
</div>
<div class="content"><div class='highlight'><pre> seenNonOptionArg = options.arguments.length &gt; <span class="hljs-number">0</span>
<span class="hljs-keyword">unless</span> seenNonOptionArg
matchedRule = <span class="hljs-literal">no</span>
<span class="hljs-keyword">for</span> rule <span class="hljs-keyword">in</span> @rules
<span class="hljs-keyword">if</span> rule.shortFlag <span class="hljs-keyword">is</span> arg <span class="hljs-keyword">or</span> rule.longFlag <span class="hljs-keyword">is</span> arg
value = <span class="hljs-literal">true</span>
<span class="hljs-keyword">if</span> rule.hasArgument
skippingArgument = <span class="hljs-literal">yes</span>
value = args[i + <span class="hljs-number">1</span>]
options[rule.name] = <span class="hljs-keyword">if</span> rule.isList <span class="hljs-keyword">then</span> (options[rule.name] <span class="hljs-keyword">or</span> []).concat value <span class="hljs-keyword">else</span> value
matchedRule = <span class="hljs-literal">yes</span>
<span class="hljs-keyword">break</span>
<span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Error <span class="hljs-string">"unrecognized option: <span class="hljs-subst">#{arg}</span>"</span> <span class="hljs-keyword">if</span> isOption <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> matchedRule
<span class="hljs-keyword">if</span> seenNonOptionArg <span class="hljs-keyword">or</span> <span class="hljs-keyword">not</span> isOption
options.arguments.push arg
options</pre></div></div>
<div class="content"><div class='highlight'><pre> {rules, positional} = normalizeArguments args, @rules.flagDict
options = {}</pre></div></div>
</li>
@ -233,20 +211,27 @@ non-option argument are treated as non-option arguments themselves</p>
<div class="pilwrap ">
<a class="pilcrow" href="#section-6">&#182;</a>
</div>
<p>Return the help text for this <strong>OptionParser</strong>, listing and describing all
of the valid options, for <code>--help</code> and such.</p>
<p>The <code>argument</code> field is added to the rule instance non-destructively by
<code>normalizeArguments</code>.</p>
</div>
<div class="content"><div class='highlight'><pre> help: <span class="hljs-function">-&gt;</span>
lines = []
lines.unshift <span class="hljs-string">"<span class="hljs-subst">#{@banner}</span>\n"</span> <span class="hljs-keyword">if</span> @banner
<span class="hljs-keyword">for</span> rule <span class="hljs-keyword">in</span> @rules
spaces = <span class="hljs-number">15</span> - rule.longFlag.length
spaces = <span class="hljs-keyword">if</span> spaces &gt; <span class="hljs-number">0</span> <span class="hljs-keyword">then</span> repeat <span class="hljs-string">' '</span>, spaces <span class="hljs-keyword">else</span> <span class="hljs-string">''</span>
letPart = <span class="hljs-keyword">if</span> rule.shortFlag <span class="hljs-keyword">then</span> rule.shortFlag + <span class="hljs-string">', '</span> <span class="hljs-keyword">else</span> <span class="hljs-string">' '</span>
lines.push <span class="hljs-string">' '</span> + letPart + rule.longFlag + spaces + rule.description
<span class="hljs-string">"\n<span class="hljs-subst">#{ lines.join(<span class="hljs-string">'\n'</span>) }</span>\n"</span></pre></div></div>
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">for</span> {hasArgument, argument, isList, name} <span class="hljs-keyword">in</span> rules
<span class="hljs-keyword">if</span> hasArgument
<span class="hljs-keyword">if</span> isList
options[name] ?= []
options[name].push argument
<span class="hljs-keyword">else</span>
options[name] = argument
<span class="hljs-keyword">else</span>
options[name] = <span class="hljs-literal">true</span>
<span class="hljs-keyword">if</span> positional[<span class="hljs-number">0</span>] <span class="hljs-keyword">is</span> <span class="hljs-string">'--'</span>
options.doubleDashed = <span class="hljs-literal">yes</span>
positional = positional[<span class="hljs-number">1.</span>.]
options.arguments = positional
options</pre></div></div>
</li>
@ -257,10 +242,21 @@ of the valid options, for <code>--help</code> and such.</p>
<div class="pilwrap ">
<a class="pilcrow" href="#section-7">&#182;</a>
</div>
<h2 id="helpers">Helpers</h2>
<p>Return the help text for this <strong>OptionParser</strong>, listing and describing all
of the valid options, for <code>--help</code> and such.</p>
</div>
<div class="content"><div class='highlight'><pre> help: <span class="hljs-function">-&gt;</span>
lines = []
lines.unshift <span class="hljs-string">"<span class="hljs-subst">#{@banner}</span>\n"</span> <span class="hljs-keyword">if</span> @banner
<span class="hljs-keyword">for</span> rule <span class="hljs-keyword">in</span> @rules.ruleList
spaces = <span class="hljs-number">15</span> - rule.longFlag.length
spaces = <span class="hljs-keyword">if</span> spaces &gt; <span class="hljs-number">0</span> <span class="hljs-keyword">then</span> repeat <span class="hljs-string">' '</span>, spaces <span class="hljs-keyword">else</span> <span class="hljs-string">''</span>
letPart = <span class="hljs-keyword">if</span> rule.shortFlag <span class="hljs-keyword">then</span> rule.shortFlag + <span class="hljs-string">', '</span> <span class="hljs-keyword">else</span> <span class="hljs-string">' '</span>
lines.push <span class="hljs-string">' '</span> + letPart + rule.longFlag + spaces + rule.description
<span class="hljs-string">"\n<span class="hljs-subst">#{ lines.join(<span class="hljs-string">'\n'</span>) }</span>\n"</span></pre></div></div>
</li>
@ -270,6 +266,7 @@ of the valid options, for <code>--help</code> and such.</p>
<div class="pilwrap ">
<a class="pilcrow" href="#section-8">&#182;</a>
</div>
<h2 id="helpers">Helpers</h2>
</div>
@ -282,15 +279,9 @@ of the valid options, for <code>--help</code> and such.</p>
<div class="pilwrap ">
<a class="pilcrow" href="#section-9">&#182;</a>
</div>
<p>Regex matchers for option flags.</p>
</div>
<div class="content"><div class='highlight'><pre>LONG_FLAG = <span class="hljs-regexp">/^(--\w[\w\-]*)/</span>
SHORT_FLAG = <span class="hljs-regexp">/^(-\w)$/</span>
MULTI_FLAG = <span class="hljs-regexp">/^-(\w{2,})/</span>
OPTIONAL = <span class="hljs-regexp">/\[(\w+(\*?))\]/</span></pre></div></div>
</li>
@ -300,15 +291,13 @@ OPTIONAL = <span class="hljs-regexp">/\[(\w+(\*?))\]/</span></pre></div></div>
<div class="pilwrap ">
<a class="pilcrow" href="#section-10">&#182;</a>
</div>
<p>Build and return the list of option rules. If the optional <em>short-flag</em> is
unspecified, leave it out by padding with <code>null</code>.</p>
<p>Regex matchers for option flags on the command line and their rules.</p>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">buildRules</span> = <span class="hljs-params">(rules)</span> -&gt;</span>
<span class="hljs-keyword">for</span> tuple <span class="hljs-keyword">in</span> rules
tuple.unshift <span class="hljs-literal">null</span> <span class="hljs-keyword">if</span> tuple.length &lt; <span class="hljs-number">3</span>
buildRule tuple...</pre></div></div>
<div class="content"><div class='highlight'><pre>LONG_FLAG = <span class="hljs-regexp">/^(--\w[\w\-]*)/</span>
SHORT_FLAG = <span class="hljs-regexp">/^(-\w)$/</span>
MULTI_FLAG = <span class="hljs-regexp">/^-(\w{2,})/</span></pre></div></div>
</li>
@ -319,22 +308,12 @@ unspecified, leave it out by padding with <code>null</code>.</p>
<div class="pilwrap ">
<a class="pilcrow" href="#section-11">&#182;</a>
</div>
<p>Build a rule from a <code>-o</code> short flag, a <code>--output [DIR]</code> long flag, and the
description of what the option does.</p>
<p>Matches the long flag part of a rule for an option with an argument. Not
applied to anything in process.argv.</p>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">buildRule</span> = <span class="hljs-params">(shortFlag, longFlag, description, options = {})</span> -&gt;</span>
match = longFlag.match(OPTIONAL)
longFlag = longFlag.match(LONG_FLAG)[<span class="hljs-number">1</span>]
{
name: longFlag.substr <span class="hljs-number">2</span>
shortFlag: shortFlag
longFlag: longFlag
description: description
hasArgument: !!(match <span class="hljs-keyword">and</span> match[<span class="hljs-number">1</span>])
isList: !!(match <span class="hljs-keyword">and</span> match[<span class="hljs-number">2</span>])
}</pre></div></div>
<div class="content"><div class='highlight'><pre>OPTIONAL = <span class="hljs-regexp">/\[(\w+(\*?))\]/</span></pre></div></div>
</li>
@ -345,20 +324,156 @@ description of what the option does.</p>
<div class="pilwrap ">
<a class="pilcrow" href="#section-12">&#182;</a>
</div>
<p>Normalize arguments by expanding merged flags into multiple flags. This allows
you to have <code>-wl</code> be the same as <code>--watch --lint</code>.</p>
<p>Build and return the list of option rules. If the optional <em>short-flag</em> is
unspecified, leave it out by padding with <code>null</code>.</p>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">normalizeArguments</span> = <span class="hljs-params">(args)</span> -&gt;</span>
args = args[..]
result = []
<span class="hljs-keyword">for</span> arg <span class="hljs-keyword">in</span> args
<span class="hljs-keyword">if</span> match = arg.match MULTI_FLAG
result.push <span class="hljs-string">'-'</span> + l <span class="hljs-keyword">for</span> l <span class="hljs-keyword">in</span> match[<span class="hljs-number">1</span>].split <span class="hljs-string">''</span>
<span class="hljs-keyword">else</span>
result.push arg
result</pre></div></div>
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">buildRules</span> = <span class="hljs-params">(ruleDeclarations)</span> -&gt;</span>
ruleList = <span class="hljs-keyword">for</span> tuple <span class="hljs-keyword">in</span> ruleDeclarations
tuple.unshift <span class="hljs-literal">null</span> <span class="hljs-keyword">if</span> tuple.length &lt; <span class="hljs-number">3</span>
buildRule tuple...
flagDict = {}
<span class="hljs-keyword">for</span> rule <span class="hljs-keyword">in</span> ruleList</pre></div></div>
</li>
<li id="section-13">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-13">&#182;</a>
</div>
<p><code>shortFlag</code> is null if not provided in the rule.</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">for</span> flag <span class="hljs-keyword">in</span> [rule.shortFlag, rule.longFlag] <span class="hljs-keyword">when</span> flag?
<span class="hljs-keyword">if</span> flagDict[flag]?
<span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Error <span class="hljs-string">"flag <span class="hljs-subst">#{flag}</span> for switch <span class="hljs-subst">#{rule.name}</span>
was already declared for switch <span class="hljs-subst">#{flagDict[flag].name}</span>"</span>
flagDict[flag] = rule
{ruleList, flagDict}</pre></div></div>
</li>
<li id="section-14">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-14">&#182;</a>
</div>
<p>Build a rule from a <code>-o</code> short flag, a <code>--output [DIR]</code> long flag, and the
description of what the option does.</p>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">buildRule</span> = <span class="hljs-params">(shortFlag, longFlag, description)</span> -&gt;</span>
match = longFlag.match(OPTIONAL)
shortFlag = shortFlag?.match(SHORT_FLAG)[<span class="hljs-number">1</span>]
longFlag = longFlag.match(LONG_FLAG)[<span class="hljs-number">1</span>]
{
name: longFlag.replace <span class="hljs-regexp">/^--/</span>, <span class="hljs-string">''</span>
shortFlag: shortFlag
longFlag: longFlag
description: description
hasArgument: !!(match <span class="hljs-keyword">and</span> match[<span class="hljs-number">1</span>])
isList: !!(match <span class="hljs-keyword">and</span> match[<span class="hljs-number">2</span>])
}
<span class="hljs-function">
<span class="hljs-title">normalizeArguments</span> = <span class="hljs-params">(args, flagDict)</span> -&gt;</span>
rules = []
positional = []
needsArgOpt = <span class="hljs-literal">null</span>
<span class="hljs-keyword">for</span> arg, argIndex <span class="hljs-keyword">in</span> args</pre></div></div>
</li>
<li id="section-15">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-15">&#182;</a>
</div>
<p>If the previous argument given to the script was an option that uses the
next command-line argument as its argument, create copy of the options
rule with an <code>argument</code> field.</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> needsArgOpt?
withArg = Object.assign {}, needsArgOpt.rule, {argument: arg}
rules.push withArg
needsArgOpt = <span class="hljs-literal">null</span>
<span class="hljs-keyword">continue</span>
multiFlags = arg.match(MULTI_FLAG)?[<span class="hljs-number">1</span>]
.split(<span class="hljs-string">''</span>)
.map (flagName) -&gt; <span class="hljs-string">"-<span class="hljs-subst">#{flagName}</span>"</span>
<span class="hljs-keyword">if</span> multiFlags?
multiOpts = multiFlags.map (flag) -&gt;
rule = flagDict[flag]
<span class="hljs-keyword">unless</span> rule?
<span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Error <span class="hljs-string">"unrecognized option <span class="hljs-subst">#{flag}</span> in multi-flag <span class="hljs-subst">#{arg}</span>"</span>
{rule, flag}</pre></div></div>
</li>
<li id="section-16">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-16">&#182;</a>
</div>
<p>Only the last flag in a multi-flag may have an argument.</p>
</div>
<div class="content"><div class='highlight'><pre> [innerOpts..., lastOpt] = multiOpts
<span class="hljs-keyword">for</span> {rule, flag} <span class="hljs-keyword">in</span> innerOpts
<span class="hljs-keyword">if</span> rule.hasArgument
<span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Error <span class="hljs-string">"cannot use option <span class="hljs-subst">#{flag}</span> in multi-flag <span class="hljs-subst">#{arg}</span> except
as the last option, because it needs an argument"</span>
rules.push rule
<span class="hljs-keyword">if</span> lastOpt.rule.hasArgument
needsArgOpt = lastOpt
<span class="hljs-keyword">else</span>
rules.push lastOpt.rule
<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> ([LONG_FLAG, SHORT_FLAG].some (pat) -&gt; arg.match(pat)?)
singleRule = flagDict[arg]
<span class="hljs-keyword">unless</span> singleRule?
<span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Error <span class="hljs-string">"unrecognized option <span class="hljs-subst">#{arg}</span>"</span>
<span class="hljs-keyword">if</span> singleRule.hasArgument
needsArgOpt = {rule: singleRule, flag: arg}
<span class="hljs-keyword">else</span>
rules.push singleRule
<span class="hljs-keyword">else</span></pre></div></div>
</li>
<li id="section-17">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-17">&#182;</a>
</div>
<p>This is a positional argument.</p>
</div>
<div class="content"><div class='highlight'><pre> positional = args[argIndex..]
<span class="hljs-keyword">break</span>
<span class="hljs-keyword">if</span> needsArgOpt?
<span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Error <span class="hljs-string">"value required for <span class="hljs-subst">#{needsArgOpt.flag}</span>, but it was the last
argument provided"</span>
{rules, positional}</pre></div></div>
</li>

View file

@ -125,6 +125,8 @@ nodeREPL = <span class="hljs-built_in">require</span> <span class="hljs-string">
CoffeeScript = <span class="hljs-built_in">require</span> <span class="hljs-string">'./'</span>
{merge, updateSyntaxError} = <span class="hljs-built_in">require</span> <span class="hljs-string">'./helpers'</span>
sawSIGINT = <span class="hljs-literal">no</span>
replDefaults =
prompt: <span class="hljs-string">'coffee&gt; '</span>,
historyFile: <span class="hljs-keyword">do</span> -&gt;
@ -193,7 +195,7 @@ Unwrap that too.</p>
</div>
<div class="content"><div class='highlight'><pre> {Block, Assign, Value, Literal} = <span class="hljs-built_in">require</span> <span class="hljs-string">'./nodes'</span>
<div class="content"><div class='highlight'><pre> {Block, Assign, Value, Literal, Call, Code} = <span class="hljs-built_in">require</span> <span class="hljs-string">'./nodes'</span>
<span class="hljs-keyword">try</span></pre></div></div>
@ -225,9 +227,7 @@ Unwrap that too.</p>
</div>
<div class="content"><div class='highlight'><pre> referencedVars = (
token[<span class="hljs-number">1</span>] <span class="hljs-keyword">for</span> token <span class="hljs-keyword">in</span> tokens <span class="hljs-keyword">when</span> token[<span class="hljs-number">0</span>] <span class="hljs-keyword">is</span> <span class="hljs-string">'IDENTIFIER'</span>
)</pre></div></div>
<div class="content"><div class='highlight'><pre> referencedVars = (token[<span class="hljs-number">1</span>] <span class="hljs-keyword">for</span> token <span class="hljs-keyword">in</span> tokens <span class="hljs-keyword">when</span> token[<span class="hljs-number">0</span>] <span class="hljs-keyword">is</span> <span class="hljs-string">'IDENTIFIER'</span>)</pre></div></div>
</li>
@ -253,16 +253,11 @@ Unwrap that too.</p>
<div class="pilwrap ">
<a class="pilcrow" href="#section-9">&#182;</a>
</div>
<p>Add assignment to <code>_</code> variable to force the input to be an expression.</p>
<p>Add assignment to <code>__</code> variable to force the input to be an expression.</p>
</div>
<div class="content"><div class='highlight'><pre> ast = <span class="hljs-keyword">new</span> Block [
<span class="hljs-keyword">new</span> Assign (<span class="hljs-keyword">new</span> Value <span class="hljs-keyword">new</span> Literal <span class="hljs-string">'__'</span>), ast, <span class="hljs-string">'='</span>
]
js = ast.compile {bare: <span class="hljs-literal">yes</span>, locals: Object.keys(context), referencedVars}
cb <span class="hljs-literal">null</span>, runInContext js, context, filename
<span class="hljs-keyword">catch</span> err</pre></div></div>
<div class="content"><div class='highlight'><pre> ast = <span class="hljs-keyword">new</span> Block [<span class="hljs-keyword">new</span> Assign (<span class="hljs-keyword">new</span> Value <span class="hljs-keyword">new</span> Literal <span class="hljs-string">'__'</span>), ast, <span class="hljs-string">'='</span>]</pre></div></div>
</li>
@ -273,6 +268,60 @@ Unwrap that too.</p>
<div class="pilwrap ">
<a class="pilcrow" href="#section-10">&#182;</a>
</div>
<p>Wrap the expression in a closure to support top-level <code>await</code></p>
</div>
<div class="content"><div class='highlight'><pre> ast = <span class="hljs-keyword">new</span> Code [], ast
isAsync = ast.isAsync</pre></div></div>
</li>
<li id="section-11">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-11">&#182;</a>
</div>
<p>Invoke the wrapping closure</p>
</div>
<div class="content"><div class='highlight'><pre> ast = <span class="hljs-keyword">new</span> Block [<span class="hljs-keyword">new</span> Call ast]
js = ast.compile {bare: <span class="hljs-literal">yes</span>, locals: Object.keys(context), referencedVars, sharedScope: <span class="hljs-literal">yes</span>}
result = runInContext js, context, filename</pre></div></div>
</li>
<li id="section-12">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-12">&#182;</a>
</div>
<p>Await an async result, if necessary</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> isAsync
result = <span class="hljs-keyword">await</span> result
cb <span class="hljs-literal">null</span>, result <span class="hljs-keyword">unless</span> sawSIGINT
sawSIGINT = <span class="hljs-literal">false</span>
<span class="hljs-keyword">else</span>
cb <span class="hljs-literal">null</span>, result
<span class="hljs-keyword">catch</span> err</pre></div></div>
</li>
<li id="section-13">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-13">&#182;</a>
</div>
<p>ASTs <code>compile</code> does not add source code information to syntax errors.</p>
</div>
@ -292,11 +341,11 @@ Unwrap that too.</p>
</li>
<li id="section-11">
<li id="section-14">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-11">&#182;</a>
<a class="pilcrow" href="#section-14">&#182;</a>
</div>
<p>Node 0.11.12 changed API, prompt is now _prompt.</p>
@ -313,11 +362,11 @@ Unwrap that too.</p>
</li>
<li id="section-12">
<li id="section-15">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-12">&#182;</a>
<a class="pilcrow" href="#section-15">&#182;</a>
</div>
<p>Proxy nodes line listener</p>
@ -338,11 +387,11 @@ Unwrap that too.</p>
</li>
<li id="section-13">
<li id="section-16">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-13">&#182;</a>
<a class="pilcrow" href="#section-16">&#182;</a>
</div>
<p>Handle Ctrl-v</p>
@ -355,11 +404,11 @@ Unwrap that too.</p>
</li>
<li id="section-14">
<li id="section-17">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-14">&#182;</a>
<a class="pilcrow" href="#section-17">&#182;</a>
</div>
<p>allow arbitrarily switching between modes any time before multiple lines are entered</p>
@ -374,11 +423,11 @@ Unwrap that too.</p>
</li>
<li id="section-15">
<li id="section-18">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-15">&#182;</a>
<a class="pilcrow" href="#section-18">&#182;</a>
</div>
<p>no-op unless the current line is empty</p>
@ -389,11 +438,11 @@ Unwrap that too.</p>
</li>
<li id="section-16">
<li id="section-19">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-16">&#182;</a>
<a class="pilcrow" href="#section-19">&#182;</a>
</div>
<p>eval, print, loop</p>
@ -408,11 +457,11 @@ Unwrap that too.</p>
</li>
<li id="section-17">
<li id="section-20">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-17">&#182;</a>
<a class="pilcrow" href="#section-20">&#182;</a>
</div>
<p>XXX: multiline hack</p>
@ -430,11 +479,11 @@ Unwrap that too.</p>
</li>
<li id="section-18">
<li id="section-21">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-18">&#182;</a>
<a class="pilcrow" href="#section-21">&#182;</a>
</div>
<p>Store and load command history from a file</p>
@ -447,11 +496,11 @@ Unwrap that too.</p>
</li>
<li id="section-19">
<li id="section-22">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-19">&#182;</a>
<a class="pilcrow" href="#section-22">&#182;</a>
</div>
<p>Get file info and at most maxSize of command history</p>
@ -463,11 +512,11 @@ Unwrap that too.</p>
</li>
<li id="section-20">
<li id="section-23">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-20">&#182;</a>
<a class="pilcrow" href="#section-23">&#182;</a>
</div>
<p>Read last <code>size</code> bytes from the file</p>
@ -481,11 +530,11 @@ Unwrap that too.</p>
</li>
<li id="section-21">
<li id="section-24">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-21">&#182;</a>
<a class="pilcrow" href="#section-24">&#182;</a>
</div>
<p>Set the history on the interpreter</p>
@ -496,11 +545,11 @@ Unwrap that too.</p>
</li>
<li id="section-22">
<li id="section-25">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-22">&#182;</a>
<a class="pilcrow" href="#section-25">&#182;</a>
</div>
<p>If the history file was truncated we should pop off a potential partial line</p>
@ -511,11 +560,11 @@ Unwrap that too.</p>
</li>
<li id="section-23">
<li id="section-26">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-23">&#182;</a>
<a class="pilcrow" href="#section-26">&#182;</a>
</div>
<p>Shift off the final blank newline</p>
@ -533,29 +582,43 @@ Unwrap that too.</p>
</li>
<li id="section-24">
<li id="section-27">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-24">&#182;</a>
<a class="pilcrow" href="#section-27">&#182;</a>
</div>
<p>Save the latest command in the file</p>
</div>
<div class="content"><div class='highlight'><pre> fs.writeSync fd, <span class="hljs-string">"<span class="hljs-subst">#{code}</span>\n"</span>
lastLine = code
lastLine = code</pre></div></div>
</li>
<li id="section-28">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-28">&#182;</a>
</div>
<p>XXX: The SIGINT event from REPLServer is undocumented, so this is a bit fragile</p>
</div>
<div class="content"><div class='highlight'><pre> repl.<span class="hljs-literal">on</span> <span class="hljs-string">'SIGINT'</span>, <span class="hljs-function">-&gt;</span> sawSIGINT = <span class="hljs-literal">yes</span>
repl.<span class="hljs-literal">on</span> <span class="hljs-string">'exit'</span>, <span class="hljs-function">-&gt;</span> fs.closeSync fd</pre></div></div>
</li>
<li id="section-25">
<li id="section-29">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-25">&#182;</a>
<a class="pilcrow" href="#section-29">&#182;</a>
</div>
<p>Add a command to show the history stack</p>
@ -572,11 +635,11 @@ Unwrap that too.</p>
</li>
<li id="section-26">
<li id="section-30">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-26">&#182;</a>
<a class="pilcrow" href="#section-30">&#182;</a>
</div>
<p>Node 0.11 changed API, a command such as .help is now stored as help</p>
@ -605,11 +668,11 @@ Unwrap that too.</p>
</li>
<li id="section-27">
<li id="section-31">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-27">&#182;</a>
<a class="pilcrow" href="#section-31">&#182;</a>
</div>
<p>Adapt help inherited from the node REPL</p>

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

View file

@ -306,7 +306,7 @@ td code {
white-space: nowrap;
}
h2, h3 {
h2, h3, h4 {
margin-top: 1.3em;
margin-bottom: 0.6em;
font-family: 'Alegreya Sans';
@ -314,7 +314,7 @@ h2, h3 {
h2 {
font-weight: 800;
}
h3, h2 time {
h3, h4, h2 time {
font-weight: 400;
}
@ -574,6 +574,17 @@ textarea {
</li>
<li class="nav-item">
<a href="#usage" class="nav-link" data-action="sidebar-nav">Usage</a>
<ul class="nav">
<li class="nav-item">
<a href="#cli" class="nav-link" data-action="sidebar-nav">Command Line</a>
</li>
<li class="nav-item">
<a href="#es2015plus-output" class="nav-link" data-action="sidebar-nav">ES2015+ Output</a>
</li>
<li class="nav-item">
<a href="#nodejs-usage" class="nav-link" data-action="sidebar-nav">Node.js</a>
</li>
</ul>
</li>
<li class="nav-item">
<a href="#language" class="nav-link" data-action="sidebar-nav">Language Reference</a>
@ -658,6 +669,9 @@ textarea {
</li>
</ul>
</li>
<li class="nav-item">
<a href="#type-annotations" class="nav-link" data-action="sidebar-nav">Type Annotations</a>
</li>
<li class="nav-item">
<a href="#literate" class="nav-link" data-action="sidebar-nav">Literate CoffeeScript</a>
</li>
@ -734,6 +748,9 @@ textarea {
<li class="nav-item">
<a href="#breaking-changes-literate-coffeescript" class="nav-link" data-action="sidebar-nav">Literate CoffeeScript Parsing</a>
</li>
<li class="nav-item">
<a href="#breaking-changes-argument-parsing-and-shebang-lines" class="nav-link" data-action="sidebar-nav">Argument Parsing and <code>#!</code> Lines</a>
</li>
</ul>
</li>
<li class="nav-item">
@ -761,7 +778,7 @@ textarea {
<section id="overview">
<p><strong>CoffeeScript is a little language that compiles into JavaScript.</strong> Underneath that awkward Java-esque patina, JavaScript has always had a gorgeous heart. CoffeeScript is an attempt to expose the good parts of JavaScript in a simple way.</p>
<p>The golden rule of CoffeeScript is: <em>“Its just JavaScript.”</em> The code compiles one-to-one into the equivalent JS, and there is no interpretation at runtime. You can use any existing JavaScript library seamlessly from CoffeeScript (and vice-versa). The compiled output is readable, pretty-printed, and tends to run as fast or faster than the equivalent handwritten JavaScript.</p>
<p><strong>Latest Version:</strong> <a href="https://github.com/jashkenas/coffeescript/tarball/2.0.0-beta3">2.0.0-beta3</a></p>
<p><strong>Latest Version:</strong> <a href="https://github.com/jashkenas/coffeescript/tarball/2.0.0-beta4">2.0.0-beta4</a></p>
<blockquote class="uneditable-code-block"><pre><code class="language-bash">npm install -g coffeescript@next
</code></pre>
</blockquote>
@ -801,22 +818,27 @@ cubes = (math.cube num for num in list)
</textarea>
</div>
<div class="col-md-6 javascript-output-column">
<textarea class="javascript-output" id="overview-js">var cubes, list, math, num, number, opposite, race, square;
<textarea class="javascript-output" id="overview-js">// Assignment:
var cubes, list, math, num, number, opposite, race, square;
number = 42;
opposite = true;
if (opposite) {
// Conditions:
number = -42;
}
// Functions:
square = function(x) {
return x * x;
};
// Arrays:
list = [1, 2, 3, 4, 5];
// Objects:
math = {
root: Math.sqrt,
square: square,
@ -825,14 +847,17 @@ math = {
}
};
// Splats:
race = function(winner, ...runners) {
return print(winner, runners);
};
if (typeof elvis !== "undefined" && elvis !== null) {
// Existence:
alert("I knew it!");
}
// Array comprehensions:
cubes = (function() {
var i, len, results;
results = [];
@ -858,7 +883,7 @@ cubes = (function() {
<section id="coffeescript-2">
<h2>CoffeeScript 2</h2>
<h3>Whats New In CoffeeScript 2?</h3>
<p>The biggest change in CoffeeScript 2 is that now the CoffeeScript compiler produces modern, ES2015+ JavaScript. A CoffeeScript <code>=&gt;</code> becomes an ES <code>=&gt;</code>, a CoffeeScript <code>class</code> becomes an ES <code>class</code> and so on. With the exception of modules (<code>import</code> and <code>export</code> statements), all the ES2015+ features that CoffeeScript supports can run natively in Node 7.6+, meaning that Node can run CoffeeScripts output without any further processing required. You can <a href="http://coffeescript.org/v2/test.html">run the tests in your browser</a> to see if your browser can do the same; Chrome has supported all features since version 55.</p>
<p>The biggest change in CoffeeScript 2 is that now the CoffeeScript compiler produces modern, ES2015+ JavaScript. A CoffeeScript <code>=&gt;</code> becomes an ES <code>=&gt;</code>, a CoffeeScript <code>class</code> becomes an ES <code>class</code> and so on. With the exception of <a href="#modules">modules</a> (<code>import</code> and <code>export</code> statements) and <a href="#jsx">JSX</a>, all the ES2015+ features that CoffeeScript supports can run natively in Node 7.6+, meaning that Node can run CoffeeScripts output without any further processing required. You can <a href="http://coffeescript.org/v2/test.html">run the tests in your browser</a> to see if your browser can do the same; Chrome has supported all features since version 55.</p>
<p>Support for ES2015+ syntax is important to ensure compatibility with frameworks that assume ES2015. Now that CoffeeScript compiles classes to the ES <code>class</code> keyword, its possible to <code>extend</code> an ES class; that wasnt possible in CoffeeScript 1. Parity in how language features work is also important on its own; CoffeeScript “is just JavaScript,” and so things like <a href="#breaking-changes-default-values">function parameter default values</a> should behave the same in CoffeeScript as in JavaScript.</p>
<p>Many ES2015+ features have been backported to CoffeeScript 1.11 and 1.12, including <a href="#modules">modules</a>, <a href="#generator-iteration"><code>for…of</code></a>, and <a href="#tagged-template-literals">tagged template literals</a>. Major new features unique to CoffeeScript 2 are support for ES2017s <a href="#async-functions">async functions</a> and for <a href="#jsx">JSX</a>. More details are in the <a href="#changelog">changelog</a>.</p>
<p>There are very few <a href="#breaking-changes">breaking changes from CoffeeScript 1.x to 2</a>; we hope the upgrade process is smooth for most projects.</p>
@ -882,6 +907,9 @@ cubes = (function() {
</section>
<section id="usage">
<h2>Usage</h2>
<section id="cli">
<h3>Command Line</h3>
<p>Once installed, you should have access to the <code>coffee</code> command, which can execute scripts, compile <code>.coffee</code> files into <code>.js</code>, and provide an interactive REPL. The <code>coffee</code> command takes the following options:</p>
<table>
<thead>
@ -957,7 +985,7 @@ cubes = (function() {
</tr>
</tbody>
</table>
<h3>Examples:</h3>
<h4>Examples:</h4>
<ul>
<li>Compile a directory tree of <code>.coffee</code> files in <code>src</code> into a parallel tree of <code>.js</code> files in <code>lib</code>:<br>
<code>coffee --compile --output lib/ src/</code></li>
@ -972,15 +1000,21 @@ cubes = (function() {
<li>Start the CoffeeScript REPL (<code>Ctrl-D</code> to exit, <code>Ctrl-V</code>for multi-line):<br>
<code>coffee</code></li>
</ul>
<h3>ES2015+ Output</h3>
</section>
<section id="es2015plus-output">
<h3>ES2015+ Output</h3>
<p>CoffeeScript 2 outputs the latest ES2015+ syntax. If youre looking for a single tool that takes CoffeeScript input and generates JavaScript output that runs in any JavaScript runtime, assuming you opt out of certain newer features, stick to <a href="/v1/">CoffeeScript 1.x</a>. CoffeeScript 2 <a href="#breaking-changes">breaks compatibility</a> with certain CoffeeScript 1.x features in order to conform with the ES2015+ specifications, and generate more idiomatic output (a CoffeeScript <code>=&gt;</code> becomes an ES <code>=&gt;</code>; a CoffeeScript <code>class</code> becomes an ES <code>class</code>; and so on).</p>
<p>Since the CoffeeScript 2 compiler outputs ES2015+ syntax, it is your responsibility to either ensure that your target JavaScript runtime(s) support all these features, or that you pass the output through another transpiler like <a href="http://babeljs.io/">Babel</a>, <a href="https://github.com/rollup/rollup">Rollup</a> or <a href="https://github.com/google/traceur-compiler">Traceur Compiler</a>. In general, <a href="http://node.green/">CoffeeScript 2s output is supported as is by Node.js 7.6+</a>, except for modules and JSX which require transpilation.</p>
<p>There are many great task runners for setting up JavaScript build chains, such as <a href="http://gulpjs.com/">Gulp</a>, <a href="https://webpack.github.io/">Webpack</a>, <a href="https://gruntjs.com/">Grunt</a> and <a href="http://broccolijs.com/">Broccoli</a>. If youre looking for a very minimal solution to get started, you can use <a href="https://babeljs.io/docs/plugins/preset-env/">babel-preset-env</a> and the command line:</p>
<blockquote class="uneditable-code-block"><pre><code class="language-bash">npm install --global coffeescript@next
npm install --save-dev coffeescript@next babel-cli babel-preset-env
coffee --print *.coffee | babel --presets env &gt; app.js
coffee --<span class="built_in">print</span> *.coffee | babel --presets env &gt; app.js
</code></pre>
</blockquote><h3>Node.js</h3>
</blockquote>
</section>
<section id="nodejs-usage">
<h3>Node.js</h3>
<p>If youd like to use Node.js CommonJS to <code>require</code> CoffeeScript files, e.g. <code>require './app.coffee'</code>, you must first “register” CoffeeScript as an extension:</p>
<blockquote class="uneditable-code-block"><pre><code class="language-coffee"><span class="built_in">require</span> <span class="string">'coffeescript/register'</span>
@ -1000,6 +1034,7 @@ eval CoffeeScript.compile <span class="string">'console.log "Mmmmm, I could real
<li><code>options.header</code>, boolean: if true, output the <code>Generated by CoffeeScript</code> header.</li>
</ul>
</section>
</section>
<section id="language">
<h2>Language Reference</h2>
@ -1264,44 +1299,35 @@ output = `${turtle.name} wears an ${turtle.mask} mask. Watch out for his ${turtl
</section>
<section id="comments">
<h2>Comments</h2>
<p>In CoffeeScript, comments are denoted by the <code>#</code> character. Everything from a <code>#</code> to the end of the line is ignored by the compiler, and will be excluded from the JavaScript output.</p>
<p>In CoffeeScript, comments are denoted by the <code>#</code> character to the end of a line, or from <code>###</code> to the next appearance of <code>###</code>. Comments are ignored by the compiler, though the compiler makes its best effort at reinserting your comments into the output JavaScript after compilation.</p>
<aside class="code-example container-fluid bg-ribbed-dark" data-example="comment">
<div class="row">
<div class="col-md-6 coffeescript-input-column">
<textarea class="coffeescript-input" id="comment-coffee">code = 2 * 617 # The code is 1234
</textarea>
</div>
<div class="col-md-6 javascript-output-column">
<textarea class="javascript-output" id="comment-js">var code;
code = 2 * 617;
</textarea>
</div>
</div>
</aside>
<p>Sometimes youd like to pass a block comment through to the generated JavaScript. For example, when you need to embed a licensing header at the top of a file. Block comments, which mirror the syntax for block strings, are preserved in the generated output.</p>
<aside class="code-example container-fluid bg-ribbed-dark" data-example="block_comment">
<div class="row">
<div class="col-md-6 coffeescript-input-column">
<textarea class="coffeescript-input" id="block_comment-coffee">###
SkinnyMochaHalfCaffScript Compiler v1.0
<textarea class="coffeescript-input" id="comment-coffee">###
Fortune Cookie Reader v1.0
Released under the MIT License
###
sayFortune = (fortune) ->
console.log fortune # in bed!
</textarea>
</div>
<div class="col-md-6 javascript-output-column">
<textarea class="javascript-output" id="block_comment-js">
/*
SkinnyMochaHalfCaffScript Compiler v1.0
<textarea class="javascript-output" id="comment-js">/*
Fortune Cookie Reader v1.0
Released under the MIT License
*/
*/
var sayFortune;
sayFortune = function(fortune) {
return console.log(fortune); // in bed!
};
</textarea>
</div>
</div>
</aside>
<p>Inline <code>###</code> comments make <a href="#type-annotations">type annotations</a> possible.</p>
</section>
<section id="lexical-scope">
@ -1535,7 +1561,8 @@ eat food for food in foods when food isnt 'chocolate'
</textarea>
</div>
<div class="col-md-6 javascript-output-column">
<textarea class="javascript-output" id="array_comprehensions-js">var courses, dish, food, foods, i, j, k, l, len, len1, len2, ref;
<textarea class="javascript-output" id="array_comprehensions-js">// Eat lunch.
var courses, dish, food, foods, i, j, k, l, len, len1, len2, ref;
ref = ['toast', 'cheese', 'wine'];
for (j = 0, len = ref.length; j < len; j++) {
@ -1543,6 +1570,7 @@ for (j = 0, len = ref.length; j < len; j++) {
eat(food);
}
// Fine five course dining.
courses = ['greens', 'caviar', 'truffles', 'roast', 'cake'];
for (i = k = 0, len1 = courses.length; k < len1; i = ++k) {
@ -1550,6 +1578,7 @@ for (i = k = 0, len1 = courses.length; k < len1; i = ++k) {
menu(i + 1, dish);
}
// Health conscious meal.
foods = ['broccoli', 'spinach', 'chocolate'];
for (l = 0, len2 = foods.length; l < len2; l++) {
@ -1657,7 +1686,8 @@ lyrics = while num -= 1
</textarea>
</div>
<div class="col-md-6 javascript-output-column">
<textarea class="javascript-output" id="while-js">var lyrics, num;
<textarea class="javascript-output" id="while-js">// Econ 101
var lyrics, num;
if (this.studyingEconomics) {
while (supply > demand) {
@ -1668,6 +1698,7 @@ if (this.studyingEconomics) {
}
}
// Nursery Rhyme
num = 6;
lyrics = (function() {
@ -1871,7 +1902,8 @@ globals = (name for name of window)[0...10]
</textarea>
</div>
<div class="col-md-6 javascript-output-column">
<textarea class="javascript-output" id="expressions_comprehension-js">var globals, name;
<textarea class="javascript-output" id="expressions_comprehension-js">// The first ten global properties.
var globals, name;
globals = ((function() {
var results;
@ -1953,9 +1985,9 @@ tabs.selectTabAtIndex((tabs.currentIndex - count) %% tabs.length)
<div class="col-md-6 javascript-output-column">
<textarea class="javascript-output" id="modulo-js">var modulo = function(a, b) { return (+a % (b = +b) + b) % b; };
-7 % 5 === -2;
-7 % 5 === -2; // The remainder of 7 / 5
modulo(-7, 5) === 3;
modulo(-7, 5) === 3; // n %% 5 is always between 0 and 4
tabs.selectTabAtIndex(modulo(tabs.currentIndex - count, tabs.length));
</textarea>
@ -2279,6 +2311,7 @@ theSwitch = 0;
<textarea class="javascript-output" id="multiple_return_values-js">var city, forecast, temp, weatherReport;
weatherReport = function(location) {
// Make an Ajax request to fetch the weather...
return [location, 72, "Mostly Sunny"];
};
@ -2597,7 +2630,9 @@ countdown 3
</textarea>
</div>
<div class="col-md-6 javascript-output-column">
<textarea class="javascript-output" id="async-js">var countdown, say, sleep;
<textarea class="javascript-output" id="async-js">// Your browser must support async/await and speech synthesis
// to run this example.
var countdown, say, sleep;
sleep = function(ms) {
return new Promise(function(resolve) {
@ -2614,7 +2649,7 @@ countdown = async function(seconds) {
var i, j, ref;
for (i = j = ref = seconds; ref <= 1 ? j <= 1 : j >= 1; i = ref <= 1 ? ++j : --j) {
say(i);
await sleep(1000);
await sleep(1000); // wait one second
}
return say("Blastoff!");
};
@ -2867,6 +2902,8 @@ grade = (function() {
return 'A';
}
})();
// grade == 'C'
</textarea>
</div>
</div>
@ -2944,21 +2981,21 @@ healthy = (200 > cholesterol && cholesterol > 60);
<aside class="code-example container-fluid bg-ribbed-dark" data-example="heregexes">
<div class="row">
<div class="col-md-6 coffeescript-input-column">
<textarea class="coffeescript-input" id="heregexes-coffee">OPERATOR = /// ^ (
?: [-=]> # function
| [-+*/%<>&|^!?=]= # compound assign / compare
| >>>=? # zero-fill right shift
| ([-+:])\1 # doubles
| ([&|<>])\2=? # logic / shift
| \?\. # soak access
| \.{2,3} # range or splat
) ///
<textarea class="coffeescript-input" id="heregexes-coffee">NUMBER = ///
^ 0b[01]+ | # binary
^ 0o[0-7]+ | # octal
^ 0x[\da-f]+ | # hex
^ \d*\.?\d+ (?:e[+-]?\d+)? # decimal
///i
</textarea>
</div>
<div class="col-md-6 javascript-output-column">
<textarea class="javascript-output" id="heregexes-js">var OPERATOR;
<textarea class="javascript-output" id="heregexes-js">var NUMBER;
OPERATOR = /^(?:[-=]>|[-+*\/%<>&|^!?=]=|>>>=?|([-+:])\1|([&|<>])\2=?|\?\.|\.{2,3})/;
NUMBER = /^0b[01]+|^0o[0-7]+|^0x[\da-f]+|^\d*\.?\d+(?:e[+-]?\d+)?/i; // binary
// octal
// hex
// decimal
</textarea>
</div>
</div>
@ -3244,10 +3281,41 @@ renderStarRating = function({rating, maxStars}) {
</div>
</aside>
<p>Older plugins or forks of CoffeeScript supported JSX syntax and referred to it as CSX or CJSX. They also often used a <code>.cjsx</code> file extension, but this is no longer necessary; regalar <code>.coffee</code> will do.</p>
<p>Older plugins or forks of CoffeeScript supported JSX syntax and referred to it as CSX or CJSX. They also often used a <code>.cjsx</code> file extension, but this is no longer necessary; regular <code>.coffee</code> will do.</p>
</section>
</section>
<section id="type-annotations">
<h2>Type Annotations</h2>
<p>Static type checking can be achieved in CoffeeScript by using <a href="https://flow.org/">Flow</a>s <a href="https://flow.org/en/docs/types/comments/">Comment Types syntax</a>:</p>
<aside class="code-example container-fluid bg-ribbed-dark" data-example="type_annotations">
<div class="row">
<div class="col-md-6 coffeescript-input-column">
<textarea class="coffeescript-input" id="type_annotations-coffee"># @flow
fn = (str ###: string ###, num ###: number ###) ###: string ### ->
str + num
</textarea>
</div>
<div class="col-md-6 javascript-output-column">
<textarea class="javascript-output" id="type_annotations-js">// @flow
var fn;
fn = function(str/*: string */, num/*: number */)/*: string */ {
return str + num;
};
</textarea>
</div>
</div>
</aside>
<p>CoffeeScript does not do any type checking itself; the JavaScript output you see above needs to get passed to Flow for it to validate your code. We expect most people will use a <a href="#es2015plus-output">build tool</a> for this, but heres how to do it the simplest way possible using the <a href="#cli">CoffeeScript</a> and <a href="https://flow.org/en/docs/usage/">Flow</a> command-line tools, assuming youve already <a href="https://flow.org/en/docs/install/">installed Flow</a> and the <a href="#installation">latest CoffeeScript</a> in your project folder:</p>
<blockquote class="uneditable-code-block"><pre><code class="language-bash">coffee --bare --no-header --compile app.coffee &amp;&amp; npm run flow
</code></pre>
</blockquote><p><code>--bare</code> and <code>--no-header</code> are important because Flow requires the first line of the file to be the comment <code>// @flow</code>. If you configure your build chain to compile CoffeeScript and pass the result to Flow in-memory, you can get better performance than this example; and a proper build tool should be able to watch your CoffeeScript files and recompile and type-check them for you on save.</p>
<p>If you know of another way to achieve static type checking with CoffeeScript, please <a href="https://github.com/jashkenas/coffeescript/issues/new">create an issue</a> and let us know.</p>
</section>
<section id="literate">
<h2>Literate CoffeeScript</h2>
<p>Besides being used as an ordinary programming language, CoffeeScript may also be written in “literate” mode. If you name your file with a <code>.litcoffee</code> extension, you can write it as a Markdown document — a document that also happens to be executable CoffeeScript code. The compiler will treat any indented blocks (Markdowns way of indicating source code) as executable code, and ignore the rest as comments. Code blocks must also be separated from comments by at least one blank line.</p>
@ -3376,7 +3444,7 @@ The CoffeeScript logo is available in SVG for use in presentations.</li>
</section>
<section id="annotated-source">
<h2>Annotated Source</h2>
<p>You can browse the CoffeeScript 2.0.0-beta3 source in readable, annotated form <a href="http://coffeescript.org/v2/annotated-source/">here</a>. You can also jump directly to a particular source file:</p>
<p>You can browse the CoffeeScript 2.0.0-beta4 source in readable, annotated form <a href="http://coffeescript.org/v2/annotated-source/">here</a>. You can also jump directly to a particular source file:</p>
<ul>
<li><a href="http://coffeescript.org/v2/annotated-source/grammar.html">Grammar Rules — src/grammar</a></li>
<li><a href="http://coffeescript.org/v2/annotated-source/lexer.html">Lexing Tokens — src/lexer</a></li>
@ -3506,7 +3574,7 @@ outer = function() {
return inner();
};
outer(1, 2);
outer(1, 2); // Returns '' in CoffeeScript 1.x, '1, 2' in CoffeeScript 2
</textarea>
</div>
</div>
@ -3538,7 +3606,7 @@ f = function(a = 1) {
return a;
};
f(null);
f(null); // Returns 1 in CoffeeScript 1.x, null in CoffeeScript 2
</textarea>
</div>
</div>
@ -3565,7 +3633,7 @@ a # Equals 1 in CoffeeScript 1.x, null in CoffeeScript 2
a: null
});
a;
a; // Equals 1 in CoffeeScript 1.x, null in CoffeeScript 2
</textarea>
</div>
</div>
@ -3619,7 +3687,7 @@ f = function*() {
<blockquote class="uneditable-code-block"><pre><code class="language-coffee"><span class="class"><span class="keyword">class</span> <span class="title">B</span> <span class="keyword">extends</span> <span class="title">A</span></span>
constructor: <span class="function">-&gt;</span> <span class="keyword">this</span> <span class="comment"># Throws a compiler error</span>
</code></pre>
</blockquote><p>ES2015 classes dont allow bound (fat arrow) methods. The CoffeeScript compiler goes through some contortions to preserve support for them, but one thing that cant be accomodated is calling a bound method before it is bound:</p>
</blockquote><p>ES2015 classes dont allow bound (fat arrow) methods. The CoffeeScript compiler goes through some contortions to preserve support for them, but one thing that cant be accommodated is calling a bound method before it is bound:</p>
<blockquote class="uneditable-code-block"><pre><code class="language-coffee"><span class="class"><span class="keyword">class</span> <span class="title">Base</span></span>
constructor: <span class="function">-&gt;</span>
@onClick() <span class="comment"># This works</span>
@ -3726,7 +3794,8 @@ B.prototype.foo = -> A::foo.apply this, arguments
</textarea>
</div>
<div class="col-md-6 javascript-output-column">
<textarea class="javascript-output" id="breaking_change_super_in_non-class_methods_refactor_with_apply-js">var A, B, extend, hasProp;
<textarea class="javascript-output" id="breaking_change_super_in_non-class_methods_refactor_with_apply-js">// Helper functions
var A, B, extend, hasProp;
hasProp = {}.hasOwnProperty;
@ -3787,7 +3856,7 @@ B = class B extends A {
</section>
<section id="breaking-changes-jsx-and-the-less-than-and-greater-than-operators">
<h3>JSX and the <code>&lt;</code> and <code>&gt;</code> Operators</h3>
<h3>JSX and the <code>&lt;</code> and <code>&gt;</code> operators</h3>
<p>With the addition of <a href="#jsx">JSX</a>, the <code>&lt;</code> and <code>&gt;</code> characters serve as both the “less than” and “greater than” operators and as the delimiters for XML tags, like <code>&lt;div&gt;</code>. For best results, in general you should always wrap the operators in spaces to distinguish them from XML tags: <code>i &lt; len</code>, not <code>i&lt;len</code>. The compiler tries to be forgiving when it can be sure what you intend, but always putting spaces around the “less than” and “greater than” operators will remove ambiguity.</p>
</section>
@ -3797,10 +3866,59 @@ B = class B extends A {
<p>Code blocks should also now maintain a consistent indentation level—so an indentation of one tab (or whatever you consider to be a tab stop, like 2 spaces or 4 spaces) should be treated as your codes “left margin,” with all code in the file relative to that column.</p>
<p>Code blocks that you want to be part of the commentary, and not executed, must have at least one line (ideally the first line of the block) completely unindented.</p>
</section>
<section id="breaking-changes-argument-parsing-and-shebang-lines">
<h3>Argument parsing and shebang (<code>#!</code>) lines</h3>
<p>In CoffeeScript 1.x, <code>--</code> was required after the path and filename of the script to be run, but before any arguments passed to that script. This convention is now deprecated. So instead of:</p>
<blockquote class="uneditable-code-block"><pre><code class="language-bash">coffee [options] path/to/script.coffee -- [args]
</code></pre>
</blockquote><p>Now you would just type:</p>
<blockquote class="uneditable-code-block"><pre><code class="language-bash">coffee [options] path/to/script.coffee [args]
</code></pre>
</blockquote><p>The deprecated version will still work, but it will print a warning before running the script.</p>
<p>On non-Windows platforms, a <code>.coffee</code> file can be made executable by adding a shebang (<code>#!</code>) line at the top of the file and marking the file as executable. For example:</p>
<blockquote class="uneditable-code-block"><pre><code class="language-coffee"><span class="comment">#!/usr/bin/env coffee</span>
x = <span class="number">2</span> + <span class="number">2</span>
<span class="built_in">console</span>.log x
</code></pre>
</blockquote><p>If this were saved as <code>executable.coffee</code>, it could be made executable and run:</p>
<blockquote class="uneditable-code-block"><pre><code class="language-bash">▶ chmod +x ./executable.coffee
▶ ./executable.coffee
4
</code></pre>
</blockquote><p>In CoffeeScript 1.x, this used to fail when trying to pass arguments to the script. Some users on OS X worked around the problem by using <code>#!/usr/bin/env coffee --</code> as the first line of the file. That didnt work on Linux, however, which cannot parse shebang lines with more than a single argument. While such scripts will still run on OS X, CoffeeScript will now display a warning before compiling or evaluating files that begin with a too-long shebang line. Now that CoffeeScript 2 supports passing arguments without needing <code>--</code>, we recommend simply changing the shebang lines in such scripts to just <code>#!/usr/bin/env coffee</code>.</p>
</section>
</section>
<section id="changelog">
<h2>Changelog</h2>
<div class="anchor" id="2.0.0-beta4"></div>
<h2 class="header">
<a href="https://github.com/jashkenas/coffeescript/compare/2.0.0-beta3...2.0.0-beta4">2.0.0-beta4</a>
<span class="timestamp"> &mdash; <time datetime="2017-08-03">August 3, 2017</time></span>
</h2><ul>
<li>This release includes <a href="#1.12.7">all the changes from 1.12.6 to 1.12.7</a>.</li>
<li><a href="#comments">Line comments</a> (starting with <code>#</code>) are now output in the generated JavaScript.</li>
<li><a href="#comments">Block comments</a> (delimited by <code>###</code>) are now allowed anywhere, including inline where they previously werent possible. This provides support for <a href="#type-annotations">static type annotations</a> using Flows comments-based syntax.</li>
<li>Spread syntax (<code>...</code> for objects) is now supported in JSX tags: <code>&lt;div {props...} /&gt;</code>.</li>
<li>Argument parsing for scripts run via <code>coffee</code> is improved. See <a href="#breaking-changes-argument-parsing-and-shebang-lines">breaking changes</a>.</li>
<li>CLI: Propagate <code>SIGINT</code> and <code>SIGTERM</code> signals when node is forked.</li>
<li><code>await</code> in the REPL is now allowed without requiring a wrapper function.</li>
<li><code>do super</code> is now allowed, and other accesses of <code>super</code> like <code>super.x.y</code> or <code>super['x'].y</code> now work.</li>
<li>Splat/spread syntax triple dots are now allowed on either the left or the right (so <code>props...</code> or <code>...props</code> are both valid).</li>
<li>Tagged template literals are recognized as callable functions.</li>
<li>Bugfixes for object spread syntax in nested properties.</li>
<li>Bugfixes for destructured function parameter default values.</li>
</ul>
<div class="anchor" id="1.12.7"></div>
<h2 class="header">
<a href="https://github.com/jashkenas/coffeescript/compare/1.12.6...1.12.7">1.12.7</a>
<span class="timestamp"> &mdash; <time datetime="2017-07-16">July 16, 2017</time></span>
</h2><ul>
<li>Fix regressions in 1.12.6 related to chained function calls and indented <code>return</code> and <code>throw</code> arguments.</li>
<li>The REPL no longer warns about assigning to <code>_</code>.</li>
</ul>
<div class="anchor" id="2.0.0-beta3"></div>
<h2 class="header">
<a href="https://github.com/jashkenas/coffeescript/compare/2.0.0-beta2...2.0.0-beta3">2.0.0-beta3</a>

File diff suppressed because it is too large Load diff