mirror of
https://github.com/jashkenas/coffeescript.git
synced 2022-11-09 12:23:24 -05:00
1600 lines
89 KiB
HTML
1600 lines
89 KiB
HTML
<!DOCTYPE html>
|
||
|
||
<html>
|
||
<head>
|
||
<title>grammar.coffee</title>
|
||
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
||
<meta name="viewport" content="width=device-width, target-densitydpi=160dpi, initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">
|
||
<link rel="stylesheet" media="all" href="docco.css" />
|
||
</head>
|
||
<body>
|
||
<div id="container">
|
||
<div id="background"></div>
|
||
|
||
<ul id="jump_to">
|
||
<li>
|
||
<a class="large" href="javascript:void(0);">Jump To …</a>
|
||
<a class="small" href="javascript:void(0);">+</a>
|
||
<div id="jump_wrapper">
|
||
<div id="jump_page">
|
||
|
||
|
||
<a class="source" href="browser.html">
|
||
browser.coffee
|
||
</a>
|
||
|
||
|
||
<a class="source" href="cake.html">
|
||
cake.coffee
|
||
</a>
|
||
|
||
|
||
<a class="source" href="coffee-script.html">
|
||
coffee-script.coffee
|
||
</a>
|
||
|
||
|
||
<a class="source" href="command.html">
|
||
command.coffee
|
||
</a>
|
||
|
||
|
||
<a class="source" href="grammar.html">
|
||
grammar.coffee
|
||
</a>
|
||
|
||
|
||
<a class="source" href="helpers.html">
|
||
helpers.coffee
|
||
</a>
|
||
|
||
|
||
<a class="source" href="index.html">
|
||
index.coffee
|
||
</a>
|
||
|
||
|
||
<a class="source" href="lexer.html">
|
||
lexer.coffee
|
||
</a>
|
||
|
||
|
||
<a class="source" href="nodes.html">
|
||
nodes.coffee
|
||
</a>
|
||
|
||
|
||
<a class="source" href="optparse.html">
|
||
optparse.coffee
|
||
</a>
|
||
|
||
|
||
<a class="source" href="register.html">
|
||
register.coffee
|
||
</a>
|
||
|
||
|
||
<a class="source" href="repl.html">
|
||
repl.coffee
|
||
</a>
|
||
|
||
|
||
<a class="source" href="rewriter.html">
|
||
rewriter.coffee
|
||
</a>
|
||
|
||
|
||
<a class="source" href="scope.html">
|
||
scope.litcoffee
|
||
</a>
|
||
|
||
|
||
<a class="source" href="sourcemap.html">
|
||
sourcemap.litcoffee
|
||
</a>
|
||
|
||
</div>
|
||
</li>
|
||
</ul>
|
||
|
||
<ul class="sections">
|
||
|
||
<li id="title">
|
||
<div class="annotation">
|
||
<h1>grammar.coffee</h1>
|
||
</div>
|
||
</li>
|
||
|
||
|
||
|
||
<li id="section-1">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-1">¶</a>
|
||
</div>
|
||
<p>The CoffeeScript parser is generated by <a href="http://github.com/zaach/jison">Jison</a>
|
||
from this grammar file. Jison is a bottom-up parser generator, similar in
|
||
style to <a href="http://www.gnu.org/software/bison">Bison</a>, implemented in JavaScript.
|
||
It can recognize <a href="http://en.wikipedia.org/wiki/LR_grammar">LALR(1), LR(0), SLR(1), and LR(1)</a>
|
||
type grammars. To create the Jison parser, we list the pattern to match
|
||
on the left-hand side, and the action to take (usually the creation of syntax
|
||
tree nodes) on the right. As the parser runs, it
|
||
shifts tokens from our token stream, from left to right, and
|
||
<a href="http://en.wikipedia.org/wiki/Bottom-up_parsing">attempts to match</a>
|
||
the token sequence against the rules below. When a match can be made, it
|
||
reduces into the <a href="http://en.wikipedia.org/wiki/Terminal_and_nonterminal_symbols">nonterminal</a>
|
||
(the enclosing name at the top), and we proceed from there.</p>
|
||
<p>If you run the <code>cake build:parser</code> command, Jison constructs a parse table
|
||
from our rules and saves it into <code>lib/parser.js</code>.</p>
|
||
|
||
</div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-2">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-2">¶</a>
|
||
</div>
|
||
<p>The only dependency is on the <strong>Jison.Parser</strong>.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre>{Parser} = <span class="hljs-built_in">require</span> <span class="hljs-string">'jison'</span></pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-3">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-3">¶</a>
|
||
</div>
|
||
<h2 id="jison-dsl">Jison DSL</h2>
|
||
|
||
</div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-4">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-4">¶</a>
|
||
</div>
|
||
|
||
</div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-5">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-5">¶</a>
|
||
</div>
|
||
<p>Since we’re going to be wrapped in a function by Jison in any case, if our
|
||
action immediately returns a value, we can optimize by removing the function
|
||
wrapper and just returning the value directly.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre>unwrap = <span class="hljs-regexp">/^function\s*\(\)\s*\{\s*return\s*([\s\S]*);\s*\}/</span></pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-6">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-6">¶</a>
|
||
</div>
|
||
<p>Our handy DSL for Jison grammar generation, thanks to
|
||
<a href="http://github.com/creationix">Tim Caswell</a>. For every rule in the grammar,
|
||
we pass the pattern-defining string, the action to run, and extra options,
|
||
optionally. If no action is specified, we simply pass the value of the
|
||
previous nonterminal.</p>
|
||
|
||
</div>
|
||
|
||
<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> -></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>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-7">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-7">¶</a>
|
||
</div>
|
||
<p>All runtime functions we need are defined on “yy”</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> action = action.replace <span class="hljs-regexp">/\bnew /g</span>, <span class="hljs-string">'$&yy.'</span>
|
||
action = action.replace <span class="hljs-regexp">/\b(?:Block\.wrap|extend)\b/g</span>, <span class="hljs-string">'yy.$&'</span></pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-8">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-8">¶</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>
|
||
|
||
</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> -></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>
|
||
|
||
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>)
|
||
|
||
[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>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-9">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-9">¶</a>
|
||
</div>
|
||
<h2 id="grammatical-rules">Grammatical Rules</h2>
|
||
|
||
</div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-10">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-10">¶</a>
|
||
</div>
|
||
|
||
</div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-11">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-11">¶</a>
|
||
</div>
|
||
<p>In all of the rules that follow, you’ll see the name of the nonterminal as
|
||
the key to a list of alternative matches. With each match’s action, the
|
||
dollar-sign variables are provided by Jison as references to the value of
|
||
their numeric position, so in this rule:</p>
|
||
<pre><code><span class="hljs-string">"Expression UNLESS Expression"</span>
|
||
</code></pre><p><code>$1</code> would be the value of the first <code>Expression</code>, <code>$2</code> would be the token
|
||
for the <code>UNLESS</code> terminal, and <code>$3</code> would be the value of the second
|
||
<code>Expression</code>.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre>grammar =</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-12">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-12">¶</a>
|
||
</div>
|
||
<p>The <strong>Root</strong> is the top-level node in the syntax tree. Since we parse bottom-up,
|
||
all parsing must end here.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">Root</span>: [
|
||
o <span class="hljs-string">''</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Block
|
||
o <span class="hljs-string">'Body'</span>
|
||
]</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-13">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-13">¶</a>
|
||
</div>
|
||
<p>Any list of statements and expressions, separated by line breaks or semicolons.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">Body</span>: [
|
||
o <span class="hljs-string">'Line'</span>,<span class="hljs-function"> -></span> Block.wrap [$<span class="hljs-number">1</span>]
|
||
o <span class="hljs-string">'Body TERMINATOR Line'</span>,<span class="hljs-function"> -></span> $<span class="hljs-number">1.</span>push $<span class="hljs-number">3</span>
|
||
o <span class="hljs-string">'Body TERMINATOR'</span>
|
||
]</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-14">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-14">¶</a>
|
||
</div>
|
||
<p>Block and statements, which make up a line in a body.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">Line</span>: [
|
||
o <span class="hljs-string">'Expression'</span>
|
||
o <span class="hljs-string">'Statement'</span>
|
||
]</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-15">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-15">¶</a>
|
||
</div>
|
||
<p>Pure statements which cannot be expressions.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">Statement</span>: [
|
||
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"> -></span> <span class="hljs-keyword">new</span> Literal $<span class="hljs-number">1</span>
|
||
]</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-16">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-16">¶</a>
|
||
</div>
|
||
<p>All the different types of expressions in our language. The basic unit of
|
||
CoffeeScript is the <strong>Expression</strong> — everything that can be an expression
|
||
is one. Blocks serve as the building blocks of many other rules, making
|
||
them somewhat circular.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">Expression</span>: [
|
||
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>
|
||
o <span class="hljs-string">'If'</span>
|
||
o <span class="hljs-string">'Try'</span>
|
||
o <span class="hljs-string">'While'</span>
|
||
o <span class="hljs-string">'For'</span>
|
||
o <span class="hljs-string">'Switch'</span>
|
||
o <span class="hljs-string">'Class'</span>
|
||
o <span class="hljs-string">'Throw'</span>
|
||
]</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-17">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-17">¶</a>
|
||
</div>
|
||
<p>An indented block of expressions. Note that the <a href="rewriter.html">Rewriter</a>
|
||
will convert some postfix forms into blocks for us, by adjusting the
|
||
token stream.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">Block</span>: [
|
||
o <span class="hljs-string">'INDENT OUTDENT'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Block
|
||
o <span class="hljs-string">'INDENT Body OUTDENT'</span>,<span class="hljs-function"> -></span> $<span class="hljs-number">2</span>
|
||
]</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-18">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-18">¶</a>
|
||
</div>
|
||
<p>A literal identifier, a variable name or property.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">Identifier</span>: [
|
||
o <span class="hljs-string">'IDENTIFIER'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Literal $<span class="hljs-number">1</span>
|
||
]</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-19">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-19">¶</a>
|
||
</div>
|
||
<p>Alphanumerics are separated from the other <strong>Literal</strong> matchers because
|
||
they can also serve as keys in object literals.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">AlphaNumeric</span>: [
|
||
o <span class="hljs-string">'NUMBER'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Literal $<span class="hljs-number">1</span>
|
||
o <span class="hljs-string">'STRING'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Literal $<span class="hljs-number">1</span>
|
||
]</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-20">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-20">¶</a>
|
||
</div>
|
||
<p>All of our immediate values. Generally these can be passed straight
|
||
through and printed to JavaScript.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">Literal</span>: [
|
||
o <span class="hljs-string">'AlphaNumeric'</span>
|
||
o <span class="hljs-string">'JS'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Literal $<span class="hljs-number">1</span>
|
||
o <span class="hljs-string">'REGEX'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Literal $<span class="hljs-number">1</span>
|
||
o <span class="hljs-string">'DEBUGGER'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Literal $<span class="hljs-number">1</span>
|
||
o <span class="hljs-string">'UNDEFINED'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Undefined
|
||
o <span class="hljs-string">'NULL'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Null
|
||
o <span class="hljs-string">'BOOL'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Bool $<span class="hljs-number">1</span>
|
||
]</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-21">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-21">¶</a>
|
||
</div>
|
||
<p>Assignment of a variable, property, or index to a value.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">Assign</span>: [
|
||
o <span class="hljs-string">'Assignable = Expression'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Assign $<span class="hljs-number">1</span>, $<span class="hljs-number">3</span>
|
||
o <span class="hljs-string">'Assignable = TERMINATOR Expression'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Assign $<span class="hljs-number">1</span>, $<span class="hljs-number">4</span>
|
||
o <span class="hljs-string">'Assignable = INDENT Expression OUTDENT'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Assign $<span class="hljs-number">1</span>, $<span class="hljs-number">4</span>
|
||
]</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-22">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-22">¶</a>
|
||
</div>
|
||
<p>Assignment when it happens within an object literal. The difference from
|
||
the ordinary <strong>Assign</strong> is that these allow numbers and strings as keys.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">AssignObj</span>: [
|
||
o <span class="hljs-string">'ObjAssignable'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Value $<span class="hljs-number">1</span>
|
||
o <span class="hljs-string">'ObjAssignable : Expression'</span>,<span class="hljs-function"> -></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">3</span>, <span class="hljs-string">'object'</span>
|
||
o <span class="hljs-string">'ObjAssignable :
|
||
INDENT Expression OUTDENT'</span>,<span class="hljs-function"> -></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-string">'object'</span>
|
||
o <span class="hljs-string">'Comment'</span>
|
||
]
|
||
|
||
<span class="hljs-attribute">ObjAssignable</span>: [
|
||
o <span class="hljs-string">'Identifier'</span>
|
||
o <span class="hljs-string">'AlphaNumeric'</span>
|
||
o <span class="hljs-string">'ThisProperty'</span>
|
||
]</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-23">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-23">¶</a>
|
||
</div>
|
||
<p>A return statement from a function body.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">Return</span>: [
|
||
o <span class="hljs-string">'RETURN Expression'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Return $<span class="hljs-number">2</span>
|
||
o <span class="hljs-string">'RETURN'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Return
|
||
]</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-24">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-24">¶</a>
|
||
</div>
|
||
<p>A block comment.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">Comment</span>: [
|
||
o <span class="hljs-string">'HERECOMMENT'</span>,<span class="hljs-function"> -></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">¶</a>
|
||
</div>
|
||
<p>The <strong>Code</strong> node is the function literal. It’s defined by an indented block
|
||
of <strong>Block</strong> preceded by a function arrow, with an optional parameter
|
||
list.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">Code</span>: [
|
||
o <span class="hljs-string">'PARAM_START ParamList PARAM_END FuncGlyph Block'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Code $<span class="hljs-number">2</span>, $<span class="hljs-number">5</span>, $<span class="hljs-number">4</span>
|
||
o <span class="hljs-string">'FuncGlyph Block'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Code [], $<span class="hljs-number">2</span>, $<span class="hljs-number">1</span>
|
||
]</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-26">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-26">¶</a>
|
||
</div>
|
||
<p>CoffeeScript has two different symbols for functions. <code>-></code> is for ordinary
|
||
functions, and <code>=></code> is for functions bound to the current value of <em>this</em>.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">FuncGlyph</span>: [
|
||
o <span class="hljs-string">'->'</span>,<span class="hljs-function"> -></span> <span class="hljs-string">'func'</span>
|
||
o <span class="hljs-string">'=>'</span>,<span class="hljs-function"> -></span> <span class="hljs-string">'boundfunc'</span>
|
||
]</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-27">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-27">¶</a>
|
||
</div>
|
||
<p>An optional, trailing comma.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">OptComma</span>: [
|
||
o <span class="hljs-string">''</span>
|
||
o <span class="hljs-string">','</span>
|
||
]</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-28">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-28">¶</a>
|
||
</div>
|
||
<p>The list of parameters that a function accepts can be of any length.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">ParamList</span>: [
|
||
o <span class="hljs-string">''</span>,<span class="hljs-function"> -></span> []
|
||
o <span class="hljs-string">'Param'</span>,<span class="hljs-function"> -></span> [$<span class="hljs-number">1</span>]
|
||
o <span class="hljs-string">'ParamList , Param'</span>,<span class="hljs-function"> -></span> $<span class="hljs-number">1.</span>concat $<span class="hljs-number">3</span>
|
||
o <span class="hljs-string">'ParamList OptComma TERMINATOR Param'</span>,<span class="hljs-function"> -></span> $<span class="hljs-number">1.</span>concat $<span class="hljs-number">4</span>
|
||
o <span class="hljs-string">'ParamList OptComma INDENT ParamList OptComma OUTDENT'</span>,<span class="hljs-function"> -></span> $<span class="hljs-number">1.</span>concat $<span class="hljs-number">4</span>
|
||
]</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-29">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-29">¶</a>
|
||
</div>
|
||
<p>A single parameter in a function definition can be ordinary, or a splat
|
||
that hoovers up the remaining arguments.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">Param</span>: [
|
||
o <span class="hljs-string">'ParamVar'</span>,<span class="hljs-function"> -></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"> -></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 = Expression'</span>,<span class="hljs-function"> -></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"> -></span> <span class="hljs-keyword">new</span> Expansion
|
||
]</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-30">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-30">¶</a>
|
||
</div>
|
||
<p>Function Parameters</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">ParamVar</span>: [
|
||
o <span class="hljs-string">'Identifier'</span>
|
||
o <span class="hljs-string">'ThisProperty'</span>
|
||
o <span class="hljs-string">'Array'</span>
|
||
o <span class="hljs-string">'Object'</span>
|
||
]</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-31">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-31">¶</a>
|
||
</div>
|
||
<p>A splat that occurs outside of a parameter list.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">Splat</span>: [
|
||
o <span class="hljs-string">'Expression ...'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Splat $<span class="hljs-number">1</span>
|
||
]</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-32">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-32">¶</a>
|
||
</div>
|
||
<p>Variables and properties that can be assigned to.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">SimpleAssignable</span>: [
|
||
o <span class="hljs-string">'Identifier'</span>,<span class="hljs-function"> -></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"> -></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"> -></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">¶</a>
|
||
</div>
|
||
<p>Everything that can be assigned to.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">Assignable</span>: [
|
||
o <span class="hljs-string">'SimpleAssignable'</span>
|
||
o <span class="hljs-string">'Array'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Value $<span class="hljs-number">1</span>
|
||
o <span class="hljs-string">'Object'</span>,<span class="hljs-function"> -></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">¶</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>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">Value</span>: [
|
||
o <span class="hljs-string">'Assignable'</span>
|
||
o <span class="hljs-string">'Literal'</span>,<span class="hljs-function"> -></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"> -></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"> -></span> <span class="hljs-keyword">new</span> Value $<span class="hljs-number">1</span>
|
||
o <span class="hljs-string">'This'</span>
|
||
]</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-35">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-35">¶</a>
|
||
</div>
|
||
<p>The general group of accessors into an object, by property, by prototype
|
||
or by array index or slice.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">Accessor</span>: [
|
||
o <span class="hljs-string">'. Identifier'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Access $<span class="hljs-number">2</span>
|
||
o <span class="hljs-string">'?. Identifier'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Access $<span class="hljs-number">2</span>, <span class="hljs-string">'soak'</span>
|
||
o <span class="hljs-string">':: Identifier'</span>,<span class="hljs-function"> -></span> [LOC(<span class="hljs-number">1</span>)(<span class="hljs-keyword">new</span> Access <span class="hljs-keyword">new</span> Literal(<span class="hljs-string">'prototype'</span>)), LOC(<span class="hljs-number">2</span>)(<span class="hljs-keyword">new</span> Access $<span class="hljs-number">2</span>)]
|
||
o <span class="hljs-string">'?:: Identifier'</span>,<span class="hljs-function"> -></span> [LOC(<span class="hljs-number">1</span>)(<span class="hljs-keyword">new</span> Access <span class="hljs-keyword">new</span> Literal(<span class="hljs-string">'prototype'</span>), <span class="hljs-string">'soak'</span>), LOC(<span class="hljs-number">2</span>)(<span class="hljs-keyword">new</span> Access $<span class="hljs-number">2</span>)]
|
||
o <span class="hljs-string">'::'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Access <span class="hljs-keyword">new</span> Literal <span class="hljs-string">'prototype'</span>
|
||
o <span class="hljs-string">'Index'</span>
|
||
]</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-36">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-36">¶</a>
|
||
</div>
|
||
<p>Indexing into an object or array using bracket notation.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">Index</span>: [
|
||
o <span class="hljs-string">'INDEX_START IndexValue INDEX_END'</span>,<span class="hljs-function"> -></span> $<span class="hljs-number">2</span>
|
||
o <span class="hljs-string">'INDEX_SOAK Index'</span>,<span class="hljs-function"> -></span> extend $<span class="hljs-number">2</span>, soak : <span class="hljs-literal">yes</span>
|
||
]
|
||
|
||
<span class="hljs-attribute">IndexValue</span>: [
|
||
o <span class="hljs-string">'Expression'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Index $<span class="hljs-number">1</span>
|
||
o <span class="hljs-string">'Slice'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Slice $<span class="hljs-number">1</span>
|
||
]</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-37">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-37">¶</a>
|
||
</div>
|
||
<p>In CoffeeScript, an object literal is simply a list of assignments.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">Object</span>: [
|
||
o <span class="hljs-string">'{ AssignList OptComma }'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Obj $<span class="hljs-number">2</span>, $<span class="hljs-number">1.</span>generated
|
||
]</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-38">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-38">¶</a>
|
||
</div>
|
||
<p>Assignment of properties within an object literal can be separated by
|
||
comma, as in JavaScript, or simply by newline.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">AssignList</span>: [
|
||
o <span class="hljs-string">''</span>,<span class="hljs-function"> -></span> []
|
||
o <span class="hljs-string">'AssignObj'</span>,<span class="hljs-function"> -></span> [$<span class="hljs-number">1</span>]
|
||
o <span class="hljs-string">'AssignList , AssignObj'</span>,<span class="hljs-function"> -></span> $<span class="hljs-number">1.</span>concat $<span class="hljs-number">3</span>
|
||
o <span class="hljs-string">'AssignList OptComma TERMINATOR AssignObj'</span>,<span class="hljs-function"> -></span> $<span class="hljs-number">1.</span>concat $<span class="hljs-number">4</span>
|
||
o <span class="hljs-string">'AssignList OptComma INDENT AssignList OptComma OUTDENT'</span>,<span class="hljs-function"> -></span> $<span class="hljs-number">1.</span>concat $<span class="hljs-number">4</span>
|
||
]</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-39">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-39">¶</a>
|
||
</div>
|
||
<p>Class definitions have optional bodies of prototype property assignments,
|
||
and optional references to the superclass.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">Class</span>: [
|
||
o <span class="hljs-string">'CLASS'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Class
|
||
o <span class="hljs-string">'CLASS Block'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Class <span class="hljs-literal">null</span>, <span class="hljs-literal">null</span>, $<span class="hljs-number">2</span>
|
||
o <span class="hljs-string">'CLASS EXTENDS Expression'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Class <span class="hljs-literal">null</span>, $<span class="hljs-number">3</span>
|
||
o <span class="hljs-string">'CLASS EXTENDS Expression Block'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Class <span class="hljs-literal">null</span>, $<span class="hljs-number">3</span>, $<span class="hljs-number">4</span>
|
||
o <span class="hljs-string">'CLASS SimpleAssignable'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Class $<span class="hljs-number">2</span>
|
||
o <span class="hljs-string">'CLASS SimpleAssignable Block'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Class $<span class="hljs-number">2</span>, <span class="hljs-literal">null</span>, $<span class="hljs-number">3</span>
|
||
o <span class="hljs-string">'CLASS SimpleAssignable EXTENDS Expression'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Class $<span class="hljs-number">2</span>, $<span class="hljs-number">4</span>
|
||
o <span class="hljs-string">'CLASS SimpleAssignable EXTENDS Expression Block'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Class $<span class="hljs-number">2</span>, $<span class="hljs-number">4</span>, $<span class="hljs-number">5</span>
|
||
]</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-40">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-40">¶</a>
|
||
</div>
|
||
<p>Ordinary function invocation, or a chained series of calls.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">Invocation</span>: [
|
||
o <span class="hljs-string">'Value OptFuncExist Arguments'</span>,<span class="hljs-function"> -></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"> -></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'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Call <span class="hljs-string">'super'</span>, [<span class="hljs-keyword">new</span> Splat <span class="hljs-keyword">new</span> Literal <span class="hljs-string">'arguments'</span>]
|
||
o <span class="hljs-string">'SUPER Arguments'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Call <span class="hljs-string">'super'</span>, $<span class="hljs-number">2</span>
|
||
]</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-41">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-41">¶</a>
|
||
</div>
|
||
<p>An optional existence check on a function.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">OptFuncExist</span>: [
|
||
o <span class="hljs-string">''</span>,<span class="hljs-function"> -></span> <span class="hljs-literal">no</span>
|
||
o <span class="hljs-string">'FUNC_EXIST'</span>,<span class="hljs-function"> -></span> <span class="hljs-literal">yes</span>
|
||
]</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-42">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-42">¶</a>
|
||
</div>
|
||
<p>The list of arguments to a function call.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">Arguments</span>: [
|
||
o <span class="hljs-string">'CALL_START CALL_END'</span>,<span class="hljs-function"> -></span> []
|
||
o <span class="hljs-string">'CALL_START ArgList OptComma CALL_END'</span>,<span class="hljs-function"> -></span> $<span class="hljs-number">2</span>
|
||
]</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-43">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-43">¶</a>
|
||
</div>
|
||
<p>A reference to the <em>this</em> current object.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">This</span>: [
|
||
o <span class="hljs-string">'THIS'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Value <span class="hljs-keyword">new</span> Literal <span class="hljs-string">'this'</span>
|
||
o <span class="hljs-string">'@'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Value <span class="hljs-keyword">new</span> Literal <span class="hljs-string">'this'</span>
|
||
]</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-44">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-44">¶</a>
|
||
</div>
|
||
<p>A reference to a property on <em>this</em>.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">ThisProperty</span>: [
|
||
o <span class="hljs-string">'@ Identifier'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Value LOC(<span class="hljs-number">1</span>)(<span class="hljs-keyword">new</span> Literal(<span class="hljs-string">'this'</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>
|
||
|
||
|
||
<li id="section-45">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-45">¶</a>
|
||
</div>
|
||
<p>The array literal.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">Array</span>: [
|
||
o <span class="hljs-string">'[ ]'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Arr []
|
||
o <span class="hljs-string">'[ ArgList OptComma ]'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Arr $<span class="hljs-number">2</span>
|
||
]</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-46">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-46">¶</a>
|
||
</div>
|
||
<p>Inclusive and exclusive range dots.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">RangeDots</span>: [
|
||
o <span class="hljs-string">'..'</span>,<span class="hljs-function"> -></span> <span class="hljs-string">'inclusive'</span>
|
||
o <span class="hljs-string">'...'</span>,<span class="hljs-function"> -></span> <span class="hljs-string">'exclusive'</span>
|
||
]</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-47">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-47">¶</a>
|
||
</div>
|
||
<p>The CoffeeScript range literal.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">Range</span>: [
|
||
o <span class="hljs-string">'[ Expression RangeDots Expression ]'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Range $<span class="hljs-number">2</span>, $<span class="hljs-number">4</span>, $<span class="hljs-number">3</span>
|
||
]</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-48">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-48">¶</a>
|
||
</div>
|
||
<p>Array slice literals.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">Slice</span>: [
|
||
o <span class="hljs-string">'Expression RangeDots Expression'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Range $<span class="hljs-number">1</span>, $<span class="hljs-number">3</span>, $<span class="hljs-number">2</span>
|
||
o <span class="hljs-string">'Expression RangeDots'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Range $<span class="hljs-number">1</span>, <span class="hljs-literal">null</span>, $<span class="hljs-number">2</span>
|
||
o <span class="hljs-string">'RangeDots Expression'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Range <span class="hljs-literal">null</span>, $<span class="hljs-number">2</span>, $<span class="hljs-number">1</span>
|
||
o <span class="hljs-string">'RangeDots'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Range <span class="hljs-literal">null</span>, <span class="hljs-literal">null</span>, $<span class="hljs-number">1</span>
|
||
]</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-49">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-49">¶</a>
|
||
</div>
|
||
<p>The <strong>ArgList</strong> is both the list of objects passed into a function call,
|
||
as well as the contents of an array literal
|
||
(i.e. comma-separated expressions). Newlines work as well.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">ArgList</span>: [
|
||
o <span class="hljs-string">'Arg'</span>,<span class="hljs-function"> -></span> [$<span class="hljs-number">1</span>]
|
||
o <span class="hljs-string">'ArgList , Arg'</span>,<span class="hljs-function"> -></span> $<span class="hljs-number">1.</span>concat $<span class="hljs-number">3</span>
|
||
o <span class="hljs-string">'ArgList OptComma TERMINATOR Arg'</span>,<span class="hljs-function"> -></span> $<span class="hljs-number">1.</span>concat $<span class="hljs-number">4</span>
|
||
o <span class="hljs-string">'INDENT ArgList OptComma OUTDENT'</span>,<span class="hljs-function"> -></span> $<span class="hljs-number">2</span>
|
||
o <span class="hljs-string">'ArgList OptComma INDENT ArgList OptComma OUTDENT'</span>,<span class="hljs-function"> -></span> $<span class="hljs-number">1.</span>concat $<span class="hljs-number">4</span>
|
||
]</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-50">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-50">¶</a>
|
||
</div>
|
||
<p>Valid arguments are Blocks or Splats.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">Arg</span>: [
|
||
o <span class="hljs-string">'Expression'</span>
|
||
o <span class="hljs-string">'Splat'</span>
|
||
o <span class="hljs-string">'...'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Expansion
|
||
]</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-51">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-51">¶</a>
|
||
</div>
|
||
<p>Just simple, comma-separated, required arguments (no fancy syntax). We need
|
||
this to be separate from the <strong>ArgList</strong> for use in <strong>Switch</strong> blocks, where
|
||
having the newlines wouldn’t make sense.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">SimpleArgs</span>: [
|
||
o <span class="hljs-string">'Expression'</span>
|
||
o <span class="hljs-string">'SimpleArgs , Expression'</span>,<span class="hljs-function"> -></span> [].concat $<span class="hljs-number">1</span>, $<span class="hljs-number">3</span>
|
||
]</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-52">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-52">¶</a>
|
||
</div>
|
||
<p>The variants of <em>try/catch/finally</em> exception handling blocks.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">Try</span>: [
|
||
o <span class="hljs-string">'TRY Block'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Try $<span class="hljs-number">2</span>
|
||
o <span class="hljs-string">'TRY Block Catch'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Try $<span class="hljs-number">2</span>, $<span class="hljs-number">3</span>[<span class="hljs-number">0</span>], $<span class="hljs-number">3</span>[<span class="hljs-number">1</span>]
|
||
o <span class="hljs-string">'TRY Block FINALLY Block'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Try $<span class="hljs-number">2</span>, <span class="hljs-literal">null</span>, <span class="hljs-literal">null</span>, $<span class="hljs-number">4</span>
|
||
o <span class="hljs-string">'TRY Block Catch FINALLY Block'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Try $<span class="hljs-number">2</span>, $<span class="hljs-number">3</span>[<span class="hljs-number">0</span>], $<span class="hljs-number">3</span>[<span class="hljs-number">1</span>], $<span class="hljs-number">5</span>
|
||
]</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-53">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-53">¶</a>
|
||
</div>
|
||
<p>A catch clause names its error and runs a block of code.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">Catch</span>: [
|
||
o <span class="hljs-string">'CATCH Identifier Block'</span>,<span class="hljs-function"> -></span> [$<span class="hljs-number">2</span>, $<span class="hljs-number">3</span>]
|
||
o <span class="hljs-string">'CATCH Object Block'</span>,<span class="hljs-function"> -></span> [LOC(<span class="hljs-number">2</span>)(<span class="hljs-keyword">new</span> Value($<span class="hljs-number">2</span>)), $<span class="hljs-number">3</span>]
|
||
o <span class="hljs-string">'CATCH Block'</span>,<span class="hljs-function"> -></span> [<span class="hljs-literal">null</span>, $<span class="hljs-number">2</span>]
|
||
]</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-54">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-54">¶</a>
|
||
</div>
|
||
<p>Throw an exception object.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">Throw</span>: [
|
||
o <span class="hljs-string">'THROW Expression'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Throw $<span class="hljs-number">2</span>
|
||
]</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-55">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-55">¶</a>
|
||
</div>
|
||
<p>Parenthetical expressions. Note that the <strong>Parenthetical</strong> is a <strong>Value</strong>,
|
||
not an <strong>Expression</strong>, so if you need to use an expression in a place
|
||
where only values are accepted, wrapping it in parentheses will always do
|
||
the trick.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">Parenthetical</span>: [
|
||
o <span class="hljs-string">'( Body )'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Parens $<span class="hljs-number">2</span>
|
||
o <span class="hljs-string">'( INDENT Body OUTDENT )'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Parens $<span class="hljs-number">3</span>
|
||
]</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-56">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-56">¶</a>
|
||
</div>
|
||
<p>The condition portion of a while loop.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">WhileSource</span>: [
|
||
o <span class="hljs-string">'WHILE Expression'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> While $<span class="hljs-number">2</span>
|
||
o <span class="hljs-string">'WHILE Expression WHEN Expression'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> While $<span class="hljs-number">2</span>, <span class="hljs-attribute">guard</span>: $<span class="hljs-number">4</span>
|
||
o <span class="hljs-string">'UNTIL Expression'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> While $<span class="hljs-number">2</span>, <span class="hljs-attribute">invert</span>: <span class="hljs-literal">true</span>
|
||
o <span class="hljs-string">'UNTIL Expression WHEN Expression'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> While $<span class="hljs-number">2</span>, <span class="hljs-attribute">invert</span>: <span class="hljs-literal">true</span>, <span class="hljs-attribute">guard</span>: $<span class="hljs-number">4</span>
|
||
]</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-57">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-57">¶</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>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">While</span>: [
|
||
o <span class="hljs-string">'WhileSource Block'</span>,<span class="hljs-function"> -></span> $<span class="hljs-number">1.</span>addBody $<span class="hljs-number">2</span>
|
||
o <span class="hljs-string">'Statement WhileSource'</span>,<span class="hljs-function"> -></span> $<span class="hljs-number">2.</span>addBody LOC(<span class="hljs-number">1</span>) Block.wrap([$<span class="hljs-number">1</span>])
|
||
o <span class="hljs-string">'Expression WhileSource'</span>,<span class="hljs-function"> -></span> $<span class="hljs-number">2.</span>addBody LOC(<span class="hljs-number">1</span>) Block.wrap([$<span class="hljs-number">1</span>])
|
||
o <span class="hljs-string">'Loop'</span>,<span class="hljs-function"> -></span> $<span class="hljs-number">1</span>
|
||
]
|
||
|
||
<span class="hljs-attribute">Loop</span>: [
|
||
o <span class="hljs-string">'LOOP Block'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> While(LOC(<span class="hljs-number">1</span>) <span class="hljs-keyword">new</span> Literal <span class="hljs-string">'true'</span>).addBody $<span class="hljs-number">2</span>
|
||
o <span class="hljs-string">'LOOP Expression'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> While(LOC(<span class="hljs-number">1</span>) <span class="hljs-keyword">new</span> Literal <span class="hljs-string">'true'</span>).addBody LOC(<span class="hljs-number">2</span>) Block.wrap [$<span class="hljs-number">2</span>]
|
||
]</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-58">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-58">¶</a>
|
||
</div>
|
||
<p>Array, object, and range comprehensions, at the most generic level.
|
||
Comprehensions can either be normal, with a block of expressions to execute,
|
||
or postfix, with a single expression.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">For</span>: [
|
||
o <span class="hljs-string">'Statement ForBody'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> For $<span class="hljs-number">1</span>, $<span class="hljs-number">2</span>
|
||
o <span class="hljs-string">'Expression ForBody'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> For $<span class="hljs-number">1</span>, $<span class="hljs-number">2</span>
|
||
o <span class="hljs-string">'ForBody Block'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> For $<span class="hljs-number">2</span>, $<span class="hljs-number">1</span>
|
||
]
|
||
|
||
<span class="hljs-attribute">ForBody</span>: [
|
||
o <span class="hljs-string">'FOR Range'</span>,<span class="hljs-function"> -></span> <span class="hljs-attribute">source</span>: LOC(<span class="hljs-number">2</span>) <span class="hljs-keyword">new</span> Value($<span class="hljs-number">2</span>)
|
||
o <span class="hljs-string">'ForStart ForSource'</span>,<span class="hljs-function"> -></span> $<span class="hljs-number">2.</span>own = $<span class="hljs-number">1.</span>own; $<span class="hljs-number">2.</span>name = $<span class="hljs-number">1</span>[<span class="hljs-number">0</span>]; $<span class="hljs-number">2.</span>index = $<span class="hljs-number">1</span>[<span class="hljs-number">1</span>]; $<span class="hljs-number">2</span>
|
||
]
|
||
|
||
<span class="hljs-attribute">ForStart</span>: [
|
||
o <span class="hljs-string">'FOR ForVariables'</span>,<span class="hljs-function"> -></span> $<span class="hljs-number">2</span>
|
||
o <span class="hljs-string">'FOR OWN ForVariables'</span>,<span class="hljs-function"> -></span> $<span class="hljs-number">3.</span>own = <span class="hljs-literal">yes</span>; $<span class="hljs-number">3</span>
|
||
]</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-59">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-59">¶</a>
|
||
</div>
|
||
<p>An array of all accepted values for a variable inside the loop.
|
||
This enables support for pattern matching.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">ForValue</span>: [
|
||
o <span class="hljs-string">'Identifier'</span>
|
||
o <span class="hljs-string">'ThisProperty'</span>
|
||
o <span class="hljs-string">'Array'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Value $<span class="hljs-number">1</span>
|
||
o <span class="hljs-string">'Object'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Value $<span class="hljs-number">1</span>
|
||
]</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-60">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-60">¶</a>
|
||
</div>
|
||
<p>An array or range comprehension has variables for the current element
|
||
and (optional) reference to the current index. Or, <em>key, value</em>, in the case
|
||
of object comprehensions.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">ForVariables</span>: [
|
||
o <span class="hljs-string">'ForValue'</span>,<span class="hljs-function"> -></span> [$<span class="hljs-number">1</span>]
|
||
o <span class="hljs-string">'ForValue , ForValue'</span>,<span class="hljs-function"> -></span> [$<span class="hljs-number">1</span>, $<span class="hljs-number">3</span>]
|
||
]</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-61">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-61">¶</a>
|
||
</div>
|
||
<p>The source of a comprehension is an array or object with an optional guard
|
||
clause. If it’s an array comprehension, you can also choose to step through
|
||
in fixed-size increments.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">ForSource</span>: [
|
||
o <span class="hljs-string">'FORIN Expression'</span>,<span class="hljs-function"> -></span> <span class="hljs-attribute">source</span>: $<span class="hljs-number">2</span>
|
||
o <span class="hljs-string">'FOROF Expression'</span>,<span class="hljs-function"> -></span> <span class="hljs-attribute">source</span>: $<span class="hljs-number">2</span>, <span class="hljs-attribute">object</span>: <span class="hljs-literal">yes</span>
|
||
o <span class="hljs-string">'FORIN Expression WHEN Expression'</span>,<span class="hljs-function"> -></span> <span class="hljs-attribute">source</span>: $<span class="hljs-number">2</span>, <span class="hljs-attribute">guard</span>: $<span class="hljs-number">4</span>
|
||
o <span class="hljs-string">'FOROF Expression WHEN Expression'</span>,<span class="hljs-function"> -></span> <span class="hljs-attribute">source</span>: $<span class="hljs-number">2</span>, <span class="hljs-attribute">guard</span>: $<span class="hljs-number">4</span>, <span class="hljs-attribute">object</span>: <span class="hljs-literal">yes</span>
|
||
o <span class="hljs-string">'FORIN Expression BY Expression'</span>,<span class="hljs-function"> -></span> <span class="hljs-attribute">source</span>: $<span class="hljs-number">2</span>, <span class="hljs-attribute">step</span>: $<span class="hljs-number">4</span>
|
||
o <span class="hljs-string">'FORIN Expression WHEN Expression BY Expression'</span>,<span class="hljs-function"> -></span> <span class="hljs-attribute">source</span>: $<span class="hljs-number">2</span>, <span class="hljs-attribute">guard</span>: $<span class="hljs-number">4</span>, <span class="hljs-attribute">step</span>: $<span class="hljs-number">6</span>
|
||
o <span class="hljs-string">'FORIN Expression BY Expression WHEN Expression'</span>,<span class="hljs-function"> -></span> <span class="hljs-attribute">source</span>: $<span class="hljs-number">2</span>, <span class="hljs-attribute">step</span>: $<span class="hljs-number">4</span>, <span class="hljs-attribute">guard</span>: $<span class="hljs-number">6</span>
|
||
]
|
||
|
||
<span class="hljs-attribute">Switch</span>: [
|
||
o <span class="hljs-string">'SWITCH Expression INDENT Whens OUTDENT'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Switch $<span class="hljs-number">2</span>, $<span class="hljs-number">4</span>
|
||
o <span class="hljs-string">'SWITCH Expression INDENT Whens ELSE Block OUTDENT'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Switch $<span class="hljs-number">2</span>, $<span class="hljs-number">4</span>, $<span class="hljs-number">6</span>
|
||
o <span class="hljs-string">'SWITCH INDENT Whens OUTDENT'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Switch <span class="hljs-literal">null</span>, $<span class="hljs-number">3</span>
|
||
o <span class="hljs-string">'SWITCH INDENT Whens ELSE Block OUTDENT'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Switch <span class="hljs-literal">null</span>, $<span class="hljs-number">3</span>, $<span class="hljs-number">5</span>
|
||
]
|
||
|
||
<span class="hljs-attribute">Whens</span>: [
|
||
o <span class="hljs-string">'When'</span>
|
||
o <span class="hljs-string">'Whens When'</span>,<span class="hljs-function"> -></span> $<span class="hljs-number">1.</span>concat $<span class="hljs-number">2</span>
|
||
]</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-62">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-62">¶</a>
|
||
</div>
|
||
<p>An individual <strong>When</strong> clause, with action.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">When</span>: [
|
||
o <span class="hljs-string">'LEADING_WHEN SimpleArgs Block'</span>,<span class="hljs-function"> -></span> [[$<span class="hljs-number">2</span>, $<span class="hljs-number">3</span>]]
|
||
o <span class="hljs-string">'LEADING_WHEN SimpleArgs Block TERMINATOR'</span>,<span class="hljs-function"> -></span> [[$<span class="hljs-number">2</span>, $<span class="hljs-number">3</span>]]
|
||
]</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-63">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-63">¶</a>
|
||
</div>
|
||
<p>The most basic form of <em>if</em> is a condition and an action. The following
|
||
if-related rules are broken up along these lines in order to avoid
|
||
ambiguity.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">IfBlock</span>: [
|
||
o <span class="hljs-string">'IF Expression Block'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> If $<span class="hljs-number">2</span>, $<span class="hljs-number">3</span>, <span class="hljs-attribute">type</span>: $<span class="hljs-number">1</span>
|
||
o <span class="hljs-string">'IfBlock ELSE IF Expression Block'</span>,<span class="hljs-function"> -></span> $<span class="hljs-number">1.</span>addElse LOC(<span class="hljs-number">3</span>,<span class="hljs-number">5</span>) <span class="hljs-keyword">new</span> If $<span class="hljs-number">4</span>, $<span class="hljs-number">5</span>, <span class="hljs-attribute">type</span>: $<span class="hljs-number">3</span>
|
||
]</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-64">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-64">¶</a>
|
||
</div>
|
||
<p>The full complement of <em>if</em> expressions, including postfix one-liner
|
||
<em>if</em> and <em>unless</em>.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">If</span>: [
|
||
o <span class="hljs-string">'IfBlock'</span>
|
||
o <span class="hljs-string">'IfBlock ELSE Block'</span>,<span class="hljs-function"> -></span> $<span class="hljs-number">1.</span>addElse $<span class="hljs-number">3</span>
|
||
o <span class="hljs-string">'Statement POST_IF Expression'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> If $<span class="hljs-number">3</span>, LOC(<span class="hljs-number">1</span>)(Block.wrap [$<span class="hljs-number">1</span>]), <span class="hljs-attribute">type</span>: $<span class="hljs-number">2</span>, <span class="hljs-attribute">statement</span>: <span class="hljs-literal">true</span>
|
||
o <span class="hljs-string">'Expression POST_IF Expression'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> If $<span class="hljs-number">3</span>, LOC(<span class="hljs-number">1</span>)(Block.wrap [$<span class="hljs-number">1</span>]), <span class="hljs-attribute">type</span>: $<span class="hljs-number">2</span>, <span class="hljs-attribute">statement</span>: <span class="hljs-literal">true</span>
|
||
]</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-65">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-65">¶</a>
|
||
</div>
|
||
<p>Arithmetic and logical operators, working on one or more operands.
|
||
Here they are grouped by order of precedence. The actual precedence rules
|
||
are defined at the bottom of the page. It would be shorter if we could
|
||
combine most of these rules into a single generic <em>Operand OpSymbol Operand</em>
|
||
-type rule, but in order to make the precedence binding possible, separate
|
||
rules are necessary.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">Operation</span>: [
|
||
o <span class="hljs-string">'UNARY Expression'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Op $<span class="hljs-number">1</span> , $<span class="hljs-number">2</span>
|
||
o <span class="hljs-string">'UNARY_MATH Expression'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Op $<span class="hljs-number">1</span> , $<span class="hljs-number">2</span>
|
||
o <span class="hljs-string">'- Expression'</span>, (<span class="hljs-function">-></span> <span class="hljs-keyword">new</span> Op <span class="hljs-string">'-'</span>, $<span class="hljs-number">2</span>), <span class="hljs-attribute">prec</span>: <span class="hljs-string">'UNARY_MATH'</span>
|
||
o <span class="hljs-string">'+ Expression'</span>, (<span class="hljs-function">-></span> <span class="hljs-keyword">new</span> Op <span class="hljs-string">'+'</span>, $<span class="hljs-number">2</span>), <span class="hljs-attribute">prec</span>: <span class="hljs-string">'UNARY_MATH'</span>
|
||
|
||
o <span class="hljs-string">'-- SimpleAssignable'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Op <span class="hljs-string">'--'</span>, $<span class="hljs-number">2</span>
|
||
o <span class="hljs-string">'++ SimpleAssignable'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Op <span class="hljs-string">'++'</span>, $<span class="hljs-number">2</span>
|
||
o <span class="hljs-string">'SimpleAssignable --'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Op <span class="hljs-string">'--'</span>, $<span class="hljs-number">1</span>, <span class="hljs-literal">null</span>, <span class="hljs-literal">true</span>
|
||
o <span class="hljs-string">'SimpleAssignable ++'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Op <span class="hljs-string">'++'</span>, $<span class="hljs-number">1</span>, <span class="hljs-literal">null</span>, <span class="hljs-literal">true</span></pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-66">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-66">¶</a>
|
||
</div>
|
||
<p><a href="http://jashkenas.github.com/coffee-script/#existence">The existential operator</a>.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> o <span class="hljs-string">'Expression ?'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Existence $<span class="hljs-number">1</span>
|
||
|
||
o <span class="hljs-string">'Expression + Expression'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Op <span class="hljs-string">'+'</span> , $<span class="hljs-number">1</span>, $<span class="hljs-number">3</span>
|
||
o <span class="hljs-string">'Expression - Expression'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Op <span class="hljs-string">'-'</span> , $<span class="hljs-number">1</span>, $<span class="hljs-number">3</span>
|
||
|
||
o <span class="hljs-string">'Expression MATH Expression'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Op $<span class="hljs-number">2</span>, $<span class="hljs-number">1</span>, $<span class="hljs-number">3</span>
|
||
o <span class="hljs-string">'Expression ** Expression'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Op $<span class="hljs-number">2</span>, $<span class="hljs-number">1</span>, $<span class="hljs-number">3</span>
|
||
o <span class="hljs-string">'Expression SHIFT Expression'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Op $<span class="hljs-number">2</span>, $<span class="hljs-number">1</span>, $<span class="hljs-number">3</span>
|
||
o <span class="hljs-string">'Expression COMPARE Expression'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Op $<span class="hljs-number">2</span>, $<span class="hljs-number">1</span>, $<span class="hljs-number">3</span>
|
||
o <span class="hljs-string">'Expression LOGIC Expression'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Op $<span class="hljs-number">2</span>, $<span class="hljs-number">1</span>, $<span class="hljs-number">3</span>
|
||
o <span class="hljs-string">'Expression RELATION Expression'</span>,<span class="hljs-function"> -></span>
|
||
<span class="hljs-keyword">if</span> $<span class="hljs-number">2.</span>charAt(<span class="hljs-number">0</span>) <span class="hljs-keyword">is</span> <span class="hljs-string">'!'</span>
|
||
<span class="hljs-keyword">new</span> Op($<span class="hljs-number">2</span>[<span class="hljs-number">1.</span>.], $<span class="hljs-number">1</span>, $<span class="hljs-number">3</span>).invert()
|
||
<span class="hljs-keyword">else</span>
|
||
<span class="hljs-keyword">new</span> Op $<span class="hljs-number">2</span>, $<span class="hljs-number">1</span>, $<span class="hljs-number">3</span>
|
||
|
||
o <span class="hljs-string">'SimpleAssignable COMPOUND_ASSIGN
|
||
Expression'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Assign $<span class="hljs-number">1</span>, $<span class="hljs-number">3</span>, $<span class="hljs-number">2</span>
|
||
o <span class="hljs-string">'SimpleAssignable COMPOUND_ASSIGN
|
||
INDENT Expression OUTDENT'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Assign $<span class="hljs-number">1</span>, $<span class="hljs-number">4</span>, $<span class="hljs-number">2</span>
|
||
o <span class="hljs-string">'SimpleAssignable COMPOUND_ASSIGN TERMINATOR
|
||
Expression'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Assign $<span class="hljs-number">1</span>, $<span class="hljs-number">4</span>, $<span class="hljs-number">2</span>
|
||
o <span class="hljs-string">'SimpleAssignable EXTENDS Expression'</span>,<span class="hljs-function"> -></span> <span class="hljs-keyword">new</span> Extends $<span class="hljs-number">1</span>, $<span class="hljs-number">3</span>
|
||
]</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-67">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-67">¶</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">¶</a>
|
||
</div>
|
||
|
||
</div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-69">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-69">¶</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>)
|
||
</code></pre><p>And not:</p>
|
||
<pre><code>(<span class="hljs-number">2</span> + <span class="hljs-number">3</span>) * <span class="hljs-number">4</span>
|
||
</code></pre>
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre>operators = [
|
||
[<span class="hljs-string">'left'</span>, <span class="hljs-string">'.'</span>, <span class="hljs-string">'?.'</span>, <span class="hljs-string">'::'</span>, <span class="hljs-string">'?::'</span>]
|
||
[<span class="hljs-string">'left'</span>, <span class="hljs-string">'CALL_START'</span>, <span class="hljs-string">'CALL_END'</span>]
|
||
[<span class="hljs-string">'nonassoc'</span>, <span class="hljs-string">'++'</span>, <span class="hljs-string">'--'</span>]
|
||
[<span class="hljs-string">'left'</span>, <span class="hljs-string">'?'</span>]
|
||
[<span class="hljs-string">'right'</span>, <span class="hljs-string">'UNARY'</span>]
|
||
[<span class="hljs-string">'right'</span>, <span class="hljs-string">'**'</span>]
|
||
[<span class="hljs-string">'right'</span>, <span class="hljs-string">'UNARY_MATH'</span>]
|
||
[<span class="hljs-string">'left'</span>, <span class="hljs-string">'MATH'</span>]
|
||
[<span class="hljs-string">'left'</span>, <span class="hljs-string">'+'</span>, <span class="hljs-string">'-'</span>]
|
||
[<span class="hljs-string">'left'</span>, <span class="hljs-string">'SHIFT'</span>]
|
||
[<span class="hljs-string">'left'</span>, <span class="hljs-string">'RELATION'</span>]
|
||
[<span class="hljs-string">'left'</span>, <span class="hljs-string">'COMPARE'</span>]
|
||
[<span class="hljs-string">'left'</span>, <span class="hljs-string">'LOGIC'</span>]
|
||
[<span class="hljs-string">'nonassoc'</span>, <span class="hljs-string">'INDENT'</span>, <span class="hljs-string">'OUTDENT'</span>]
|
||
[<span class="hljs-string">'right'</span>, <span class="hljs-string">'='</span>, <span class="hljs-string">':'</span>, <span class="hljs-string">'COMPOUND_ASSIGN'</span>, <span class="hljs-string">'RETURN'</span>, <span class="hljs-string">'THROW'</span>, <span class="hljs-string">'EXTENDS'</span>]
|
||
[<span class="hljs-string">'right'</span>, <span class="hljs-string">'FORIN'</span>, <span class="hljs-string">'FOROF'</span>, <span class="hljs-string">'BY'</span>, <span class="hljs-string">'WHEN'</span>]
|
||
[<span class="hljs-string">'right'</span>, <span class="hljs-string">'IF'</span>, <span class="hljs-string">'ELSE'</span>, <span class="hljs-string">'FOR'</span>, <span class="hljs-string">'WHILE'</span>, <span class="hljs-string">'UNTIL'</span>, <span class="hljs-string">'LOOP'</span>, <span class="hljs-string">'SUPER'</span>, <span class="hljs-string">'CLASS'</span>]
|
||
[<span class="hljs-string">'left'</span>, <span class="hljs-string">'POST_IF'</span>]
|
||
]</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-70">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-70">¶</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">¶</a>
|
||
</div>
|
||
|
||
</div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-72">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-72">¶</a>
|
||
</div>
|
||
<p>Finally, now that we have our <strong>grammar</strong> and our <strong>operators</strong>, we can create
|
||
our <strong>Jison.Parser</strong>. We do this by processing all of our rules, recording all
|
||
terminals (every symbol which does not appear as the name of a rule above)
|
||
as “tokens”.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre>tokens = []
|
||
<span class="hljs-keyword">for</span> name, alternatives <span class="hljs-keyword">of</span> grammar
|
||
grammar[name] = <span class="hljs-keyword">for</span> alt <span class="hljs-keyword">in</span> alternatives
|
||
<span class="hljs-keyword">for</span> token <span class="hljs-keyword">in</span> alt[<span class="hljs-number">0</span>].split <span class="hljs-string">' '</span>
|
||
tokens.push token <span class="hljs-keyword">unless</span> grammar[token]
|
||
alt[<span class="hljs-number">1</span>] = <span class="hljs-string">"return <span class="hljs-subst">#{alt[<span class="hljs-number">1</span>]}</span>"</span> <span class="hljs-keyword">if</span> name <span class="hljs-keyword">is</span> <span class="hljs-string">'Root'</span>
|
||
alt</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-73">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-73">¶</a>
|
||
</div>
|
||
<p>Initialize the <strong>Parser</strong> with our list of terminal <strong>tokens</strong>, our <strong>grammar</strong>
|
||
rules, and the name of the root. Reverse the operators because Jison orders
|
||
precedence from low to high, and we have it high to low
|
||
(as in <a href="http://dinosaur.compilertools.net/yacc/index.html">Yacc</a>).</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.parser = <span class="hljs-keyword">new</span> Parser
|
||
tokens : tokens.join <span class="hljs-string">' '</span>
|
||
bnf : grammar
|
||
operators : operators.reverse()
|
||
startSymbol : <span class="hljs-string">'Root'</span></pre></div></div>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</div>
|
||
</body>
|
||
</html>
|