mirror of
https://github.com/jashkenas/coffeescript.git
synced 2022-11-09 12:23:24 -05:00
1662 lines
73 KiB
HTML
1662 lines
73 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="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} = require <span class="string">'jison'</span></pre></div></div>
|
|
|
|
</li>
|
|
|
|
|
|
<li id="section-3">
|
|
<div class="annotation">
|
|
|
|
<div class="pilwrap for-h2">
|
|
<a class="pilcrow" href="#section-3">¶</a>
|
|
</div>
|
|
<h2>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="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="function"><span class="title">o</span></span> = (patternString, action, options) ->
|
|
patternString = patternString.replace <span class="regexp">/\s{2,}/g</span>, <span class="string">' '</span>
|
|
patternCount = patternString.split(<span class="string">' '</span>).length
|
|
<span class="keyword">return</span> [patternString, <span class="string">'$$ = $1;'</span>, options] <span class="keyword">unless</span> action
|
|
action = <span class="keyword">if</span> match = unwrap.exec action <span class="keyword">then</span> match[<span class="number">1</span>] <span class="keyword">else</span> <span class="string">"(<span class="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="regexp">/\bnew /g</span>, <span class="string">'$&yy.'</span>
|
|
action = action.replace <span class="regexp">/\b(?:Block\.wrap|extend)\b/g</span>, <span class="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="function"><span class="title">addLocationDataFn</span></span> = (first, last) ->
|
|
<span class="keyword">if</span> <span class="keyword">not</span> last
|
|
<span class="string">"yy.addLocationDataFn(@<span class="subst">#{first}</span>)"</span>
|
|
<span class="keyword">else</span>
|
|
<span class="string">"yy.addLocationDataFn(@<span class="subst">#{first}</span>, @<span class="subst">#{last}</span>)"</span>
|
|
|
|
action = action.replace <span class="regexp">/LOC\(([0-9]*)\)/g</span>, addLocationDataFn(<span class="string">'$1'</span>)
|
|
action = action.replace <span class="regexp">/LOC\(([0-9]*),\s*([0-9]*)\)/g</span>, addLocationDataFn(<span class="string">'$1'</span>, <span class="string">'$2'</span>)
|
|
|
|
[patternString, <span class="string">"$$ = <span class="subst">#{addLocationDataFn(<span class="number">1</span>, patternCount)}</span>(<span class="subst">#{action}</span>);"</span>, options]</pre></div></div>
|
|
|
|
</li>
|
|
|
|
|
|
<li id="section-9">
|
|
<div class="annotation">
|
|
|
|
<div class="pilwrap for-h2">
|
|
<a class="pilcrow" href="#section-9">¶</a>
|
|
</div>
|
|
<h2>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>"Expression UNLESS Expression"</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> Root: [
|
|
o <span class="string">''</span>, -> <span class="keyword">new</span> Block
|
|
o <span class="string">'Body'</span>
|
|
o <span class="string">'Block TERMINATOR'</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> Body: [
|
|
o <span class="string">'Line'</span>, -> Block.wrap [$<span class="number">1</span>]
|
|
o <span class="string">'Body TERMINATOR Line'</span>, -> $<span class="number">1.</span>push $<span class="number">3</span>
|
|
o <span class="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> Line: [
|
|
o <span class="string">'Expression'</span>
|
|
o <span class="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> Statement: [
|
|
o <span class="string">'Return'</span>
|
|
o <span class="string">'Comment'</span>
|
|
o <span class="string">'STATEMENT'</span>, -> <span class="keyword">new</span> Literal $<span class="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> Expression: [
|
|
o <span class="string">'Value'</span>
|
|
o <span class="string">'Invocation'</span>
|
|
o <span class="string">'Code'</span>
|
|
o <span class="string">'Operation'</span>
|
|
o <span class="string">'Assign'</span>
|
|
o <span class="string">'If'</span>
|
|
o <span class="string">'Try'</span>
|
|
o <span class="string">'While'</span>
|
|
o <span class="string">'For'</span>
|
|
o <span class="string">'Switch'</span>
|
|
o <span class="string">'Class'</span>
|
|
o <span class="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> Block: [
|
|
o <span class="string">'INDENT OUTDENT'</span>, -> <span class="keyword">new</span> Block
|
|
o <span class="string">'INDENT Body OUTDENT'</span>, -> $<span class="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> Identifier: [
|
|
o <span class="string">'IDENTIFIER'</span>, -> <span class="keyword">new</span> Literal $<span class="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> AlphaNumeric: [
|
|
o <span class="string">'NUMBER'</span>, -> <span class="keyword">new</span> Literal $<span class="number">1</span>
|
|
o <span class="string">'STRING'</span>, -> <span class="keyword">new</span> Literal $<span class="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> Literal: [
|
|
o <span class="string">'AlphaNumeric'</span>
|
|
o <span class="string">'JS'</span>, -> <span class="keyword">new</span> Literal $<span class="number">1</span>
|
|
o <span class="string">'REGEX'</span>, -> <span class="keyword">new</span> Literal $<span class="number">1</span>
|
|
o <span class="string">'DEBUGGER'</span>, -> <span class="keyword">new</span> Literal $<span class="number">1</span>
|
|
o <span class="string">'UNDEFINED'</span>, -> <span class="keyword">new</span> Undefined
|
|
o <span class="string">'NULL'</span>, -> <span class="keyword">new</span> Null
|
|
o <span class="string">'BOOL'</span>, -> <span class="keyword">new</span> Bool $<span class="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> Assign: [
|
|
o <span class="string">'Assignable = Expression'</span>, -> <span class="keyword">new</span> Assign $<span class="number">1</span>, $<span class="number">3</span>
|
|
o <span class="string">'Assignable = TERMINATOR Expression'</span>, -> <span class="keyword">new</span> Assign $<span class="number">1</span>, $<span class="number">4</span>
|
|
o <span class="string">'Assignable = INDENT Expression OUTDENT'</span>, -> <span class="keyword">new</span> Assign $<span class="number">1</span>, $<span class="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> AssignObj: [
|
|
o 'ObjAssignable', -> new Value $1
|
|
o 'ObjAssignable : Expression', -> new Assign LOC(1)(new Value($1)), $3, 'object'
|
|
o 'ObjAssignable :
|
|
INDENT Expression OUTDENT', -> new Assign LOC(1)(new Value($1)), $4, 'object'
|
|
o 'Comment'
|
|
]
|
|
|
|
ObjAssignable: [
|
|
o 'Identifier'
|
|
o 'AlphaNumeric'
|
|
o 'ThisProperty'
|
|
]</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> Return: [
|
|
o <span class="string">'RETURN Expression'</span>, -> <span class="keyword">new</span> Return $<span class="number">2</span>
|
|
o <span class="string">'RETURN'</span>, -> <span class="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> Comment: [
|
|
o <span class="string">'HERECOMMENT'</span>, -> <span class="keyword">new</span> Comment $<span class="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> Code: [
|
|
o <span class="string">'PARAM_START ParamList PARAM_END FuncGlyph Block'</span>, -> <span class="keyword">new</span> Code $<span class="number">2</span>, $<span class="number">5</span>, $<span class="number">4</span>
|
|
o <span class="string">'FuncGlyph Block'</span>, -> <span class="keyword">new</span> Code [], $<span class="number">2</span>, $<span class="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> FuncGlyph: [
|
|
o <span class="string">'->'</span>, -> <span class="string">'func'</span>
|
|
o <span class="string">'=>'</span>, -> <span class="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> OptComma: [
|
|
o <span class="string">''</span>
|
|
o <span class="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> ParamList: [
|
|
o <span class="string">''</span>, -> []
|
|
o <span class="string">'Param'</span>, -> [$<span class="number">1</span>]
|
|
o <span class="string">'ParamList , Param'</span>, -> $<span class="number">1.</span>concat $<span class="number">3</span>
|
|
o <span class="string">'ParamList OptComma TERMINATOR Param'</span>, -> $<span class="number">1.</span>concat $<span class="number">4</span>
|
|
o <span class="string">'ParamList OptComma INDENT ParamList OptComma OUTDENT'</span>, -> $<span class="number">1.</span>concat $<span class="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> Param: [
|
|
o <span class="string">'ParamVar'</span>, -> <span class="keyword">new</span> Param $<span class="number">1</span>
|
|
o <span class="string">'ParamVar ...'</span>, -> <span class="keyword">new</span> Param $<span class="number">1</span>, <span class="literal">null</span>, <span class="literal">on</span>
|
|
o <span class="string">'ParamVar = Expression'</span>, -> <span class="keyword">new</span> Param $<span class="number">1</span>, $<span class="number">3</span>
|
|
]</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> ParamVar: [
|
|
o <span class="string">'Identifier'</span>
|
|
o <span class="string">'ThisProperty'</span>
|
|
o <span class="string">'Array'</span>
|
|
o <span class="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> Splat: [
|
|
o <span class="string">'Expression ...'</span>, -> <span class="keyword">new</span> Splat $<span class="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> SimpleAssignable: [
|
|
o <span class="string">'Identifier'</span>, -> <span class="keyword">new</span> Value $<span class="number">1</span>
|
|
o <span class="string">'Value Accessor'</span>, -> $<span class="number">1.</span>add $<span class="number">2</span>
|
|
o <span class="string">'Invocation Accessor'</span>, -> <span class="keyword">new</span> Value $<span class="number">1</span>, [].concat $<span class="number">2</span>
|
|
o <span class="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> Assignable: [
|
|
o <span class="string">'SimpleAssignable'</span>
|
|
o <span class="string">'Array'</span>, -> <span class="keyword">new</span> Value $<span class="number">1</span>
|
|
o <span class="string">'Object'</span>, -> <span class="keyword">new</span> Value $<span class="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> Value: [
|
|
o <span class="string">'Assignable'</span>
|
|
o <span class="string">'Literal'</span>, -> <span class="keyword">new</span> Value $<span class="number">1</span>
|
|
o <span class="string">'Parenthetical'</span>, -> <span class="keyword">new</span> Value $<span class="number">1</span>
|
|
o <span class="string">'Range'</span>, -> <span class="keyword">new</span> Value $<span class="number">1</span>
|
|
o <span class="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> Accessor: [
|
|
o <span class="string">'. Identifier'</span>, -> <span class="keyword">new</span> Access $<span class="number">2</span>
|
|
o <span class="string">'?. Identifier'</span>, -> <span class="keyword">new</span> Access $<span class="number">2</span>, <span class="string">'soak'</span>
|
|
o <span class="string">':: Identifier'</span>, -> [LOC(<span class="number">1</span>)(<span class="keyword">new</span> Access <span class="keyword">new</span> Literal(<span class="string">'prototype'</span>)), LOC(<span class="number">2</span>)(<span class="keyword">new</span> Access $<span class="number">2</span>)]
|
|
o <span class="string">'?:: Identifier'</span>, -> [LOC(<span class="number">1</span>)(<span class="keyword">new</span> Access <span class="keyword">new</span> Literal(<span class="string">'prototype'</span>), <span class="string">'soak'</span>), LOC(<span class="number">2</span>)(<span class="keyword">new</span> Access $<span class="number">2</span>)]
|
|
o <span class="string">'::'</span>, -> <span class="keyword">new</span> Access <span class="keyword">new</span> Literal <span class="string">'prototype'</span>
|
|
o <span class="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> Index: [
|
|
o <span class="string">'INDEX_START IndexValue INDEX_END'</span>, -> $<span class="number">2</span>
|
|
o <span class="string">'INDEX_SOAK Index'</span>, -> extend $<span class="number">2</span>, soak : <span class="literal">yes</span>
|
|
]
|
|
|
|
IndexValue: [
|
|
o <span class="string">'Expression'</span>, -> <span class="keyword">new</span> Index $<span class="number">1</span>
|
|
o <span class="string">'Slice'</span>, -> <span class="keyword">new</span> Slice $<span class="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> Object: [
|
|
o <span class="string">'{ AssignList OptComma }'</span>, -> <span class="keyword">new</span> Obj $<span class="number">2</span>, $<span class="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> AssignList: [
|
|
o <span class="string">''</span>, -> []
|
|
o <span class="string">'AssignObj'</span>, -> [$<span class="number">1</span>]
|
|
o <span class="string">'AssignList , AssignObj'</span>, -> $<span class="number">1.</span>concat $<span class="number">3</span>
|
|
o <span class="string">'AssignList OptComma TERMINATOR AssignObj'</span>, -> $<span class="number">1.</span>concat $<span class="number">4</span>
|
|
o <span class="string">'AssignList OptComma INDENT AssignList OptComma OUTDENT'</span>, -> $<span class="number">1.</span>concat $<span class="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> Class: [
|
|
o <span class="string">'CLASS'</span>, -> <span class="keyword">new</span> Class
|
|
o <span class="string">'CLASS Block'</span>, -> <span class="keyword">new</span> Class <span class="literal">null</span>, <span class="literal">null</span>, $<span class="number">2</span>
|
|
o <span class="string">'CLASS EXTENDS Expression'</span>, -> <span class="keyword">new</span> Class <span class="literal">null</span>, $<span class="number">3</span>
|
|
o <span class="string">'CLASS EXTENDS Expression Block'</span>, -> <span class="keyword">new</span> Class <span class="literal">null</span>, $<span class="number">3</span>, $<span class="number">4</span>
|
|
o <span class="string">'CLASS SimpleAssignable'</span>, -> <span class="keyword">new</span> Class $<span class="number">2</span>
|
|
o <span class="string">'CLASS SimpleAssignable Block'</span>, -> <span class="keyword">new</span> Class $<span class="number">2</span>, <span class="literal">null</span>, $<span class="number">3</span>
|
|
o <span class="string">'CLASS SimpleAssignable EXTENDS Expression'</span>, -> <span class="keyword">new</span> Class $<span class="number">2</span>, $<span class="number">4</span>
|
|
o <span class="string">'CLASS SimpleAssignable EXTENDS Expression Block'</span>, -> <span class="keyword">new</span> Class $<span class="number">2</span>, $<span class="number">4</span>, $<span class="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> Invocation: [
|
|
o <span class="string">'Value OptFuncExist Arguments'</span>, -> <span class="keyword">new</span> Call $<span class="number">1</span>, $<span class="number">3</span>, $<span class="number">2</span>
|
|
o <span class="string">'Invocation OptFuncExist Arguments'</span>, -> <span class="keyword">new</span> Call $<span class="number">1</span>, $<span class="number">3</span>, $<span class="number">2</span>
|
|
o <span class="string">'SUPER'</span>, -> <span class="keyword">new</span> Call <span class="string">'super'</span>, [<span class="keyword">new</span> Splat <span class="keyword">new</span> Literal <span class="string">'arguments'</span>]
|
|
o <span class="string">'SUPER Arguments'</span>, -> <span class="keyword">new</span> Call <span class="string">'super'</span>, $<span class="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> OptFuncExist: [
|
|
o <span class="string">''</span>, -> <span class="literal">no</span>
|
|
o <span class="string">'FUNC_EXIST'</span>, -> <span class="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> Arguments: [
|
|
o <span class="string">'CALL_START CALL_END'</span>, -> []
|
|
o <span class="string">'CALL_START ArgList OptComma CALL_END'</span>, -> $<span class="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> This: [
|
|
o <span class="string">'THIS'</span>, -> <span class="keyword">new</span> Value <span class="keyword">new</span> Literal <span class="string">'this'</span>
|
|
o <span class="string">'@'</span>, -> <span class="keyword">new</span> Value <span class="keyword">new</span> Literal <span class="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> ThisProperty: [
|
|
o <span class="string">'@ Identifier'</span>, -> <span class="keyword">new</span> Value LOC(<span class="number">1</span>)(<span class="keyword">new</span> Literal(<span class="string">'this'</span>)), [LOC(<span class="number">2</span>)(<span class="keyword">new</span> Access($<span class="number">2</span>))], <span class="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> Array: [
|
|
o <span class="string">'[ ]'</span>, -> <span class="keyword">new</span> Arr []
|
|
o <span class="string">'[ ArgList OptComma ]'</span>, -> <span class="keyword">new</span> Arr $<span class="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> RangeDots: [
|
|
o <span class="string">'..'</span>, -> <span class="string">'inclusive'</span>
|
|
o <span class="string">'...'</span>, -> <span class="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> Range: [
|
|
o <span class="string">'[ Expression RangeDots Expression ]'</span>, -> <span class="keyword">new</span> Range $<span class="number">2</span>, $<span class="number">4</span>, $<span class="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> Slice: [
|
|
o <span class="string">'Expression RangeDots Expression'</span>, -> <span class="keyword">new</span> Range $<span class="number">1</span>, $<span class="number">3</span>, $<span class="number">2</span>
|
|
o <span class="string">'Expression RangeDots'</span>, -> <span class="keyword">new</span> Range $<span class="number">1</span>, <span class="literal">null</span>, $<span class="number">2</span>
|
|
o <span class="string">'RangeDots Expression'</span>, -> <span class="keyword">new</span> Range <span class="literal">null</span>, $<span class="number">2</span>, $<span class="number">1</span>
|
|
o <span class="string">'RangeDots'</span>, -> <span class="keyword">new</span> Range <span class="literal">null</span>, <span class="literal">null</span>, $<span class="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> ArgList: [
|
|
o <span class="string">'Arg'</span>, -> [$<span class="number">1</span>]
|
|
o <span class="string">'ArgList , Arg'</span>, -> $<span class="number">1.</span>concat $<span class="number">3</span>
|
|
o <span class="string">'ArgList OptComma TERMINATOR Arg'</span>, -> $<span class="number">1.</span>concat $<span class="number">4</span>
|
|
o <span class="string">'INDENT ArgList OptComma OUTDENT'</span>, -> $<span class="number">2</span>
|
|
o <span class="string">'ArgList OptComma INDENT ArgList OptComma OUTDENT'</span>, -> $<span class="number">1.</span>concat $<span class="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> Arg: [
|
|
o <span class="string">'Expression'</span>
|
|
o <span class="string">'Splat'</span>
|
|
]</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> SimpleArgs: [
|
|
o <span class="string">'Expression'</span>
|
|
o <span class="string">'SimpleArgs , Expression'</span>, -> [].concat $<span class="number">1</span>, $<span class="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> Try: [
|
|
o <span class="string">'TRY Block'</span>, -> <span class="keyword">new</span> Try $<span class="number">2</span>
|
|
o <span class="string">'TRY Block Catch'</span>, -> <span class="keyword">new</span> Try $<span class="number">2</span>, $<span class="number">3</span>[<span class="number">0</span>], $<span class="number">3</span>[<span class="number">1</span>]
|
|
o <span class="string">'TRY Block FINALLY Block'</span>, -> <span class="keyword">new</span> Try $<span class="number">2</span>, <span class="literal">null</span>, <span class="literal">null</span>, $<span class="number">4</span>
|
|
o <span class="string">'TRY Block Catch FINALLY Block'</span>, -> <span class="keyword">new</span> Try $<span class="number">2</span>, $<span class="number">3</span>[<span class="number">0</span>], $<span class="number">3</span>[<span class="number">1</span>], $<span class="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> Catch: [
|
|
o <span class="string">'CATCH Identifier Block'</span>, -> [$<span class="number">2</span>, $<span class="number">3</span>]
|
|
o <span class="string">'CATCH Object Block'</span>, -> [LOC(<span class="number">2</span>)(<span class="keyword">new</span> Value($<span class="number">2</span>)), $<span class="number">3</span>]
|
|
o <span class="string">'CATCH Block'</span>, -> [<span class="literal">null</span>, $<span class="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> Throw: [
|
|
o <span class="string">'THROW Expression'</span>, -> <span class="keyword">new</span> Throw $<span class="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> Parenthetical: [
|
|
o <span class="string">'( Body )'</span>, -> <span class="keyword">new</span> Parens $<span class="number">2</span>
|
|
o <span class="string">'( INDENT Body OUTDENT )'</span>, -> <span class="keyword">new</span> Parens $<span class="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> WhileSource: [
|
|
o <span class="string">'WHILE Expression'</span>, -> <span class="keyword">new</span> While $<span class="number">2</span>
|
|
o <span class="string">'WHILE Expression WHEN Expression'</span>, -> <span class="keyword">new</span> While $<span class="number">2</span>, guard: $<span class="number">4</span>
|
|
o <span class="string">'UNTIL Expression'</span>, -> <span class="keyword">new</span> While $<span class="number">2</span>, invert: <span class="literal">true</span>
|
|
o <span class="string">'UNTIL Expression WHEN Expression'</span>, -> <span class="keyword">new</span> While $<span class="number">2</span>, invert: <span class="literal">true</span>, guard: $<span class="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> While: [
|
|
o <span class="string">'WhileSource Block'</span>, -> $<span class="number">1.</span>addBody $<span class="number">2</span>
|
|
o <span class="string">'Statement WhileSource'</span>, -> $<span class="number">2.</span>addBody LOC(<span class="number">1</span>) Block.wrap([$<span class="number">1</span>])
|
|
o <span class="string">'Expression WhileSource'</span>, -> $<span class="number">2.</span>addBody LOC(<span class="number">1</span>) Block.wrap([$<span class="number">1</span>])
|
|
o <span class="string">'Loop'</span>, -> $<span class="number">1</span>
|
|
]
|
|
|
|
Loop: [
|
|
o <span class="string">'LOOP Block'</span>, -> <span class="keyword">new</span> While(LOC(<span class="number">1</span>) <span class="keyword">new</span> Literal <span class="string">'true'</span>).addBody $<span class="number">2</span>
|
|
o <span class="string">'LOOP Expression'</span>, -> <span class="keyword">new</span> While(LOC(<span class="number">1</span>) <span class="keyword">new</span> Literal <span class="string">'true'</span>).addBody LOC(<span class="number">2</span>) Block.wrap [$<span class="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> For: [
|
|
o <span class="string">'Statement ForBody'</span>, -> <span class="keyword">new</span> For $<span class="number">1</span>, $<span class="number">2</span>
|
|
o <span class="string">'Expression ForBody'</span>, -> <span class="keyword">new</span> For $<span class="number">1</span>, $<span class="number">2</span>
|
|
o <span class="string">'ForBody Block'</span>, -> <span class="keyword">new</span> For $<span class="number">2</span>, $<span class="number">1</span>
|
|
]
|
|
|
|
ForBody: [
|
|
o <span class="string">'FOR Range'</span>, -> source: LOC(<span class="number">2</span>) <span class="keyword">new</span> Value($<span class="number">2</span>)
|
|
o <span class="string">'ForStart ForSource'</span>, -> $<span class="number">2.</span>own = $<span class="number">1.</span>own; $<span class="number">2.</span>name = $<span class="number">1</span>[<span class="number">0</span>]; $<span class="number">2.</span>index = $<span class="number">1</span>[<span class="number">1</span>]; $<span class="number">2</span>
|
|
]
|
|
|
|
ForStart: [
|
|
o <span class="string">'FOR ForVariables'</span>, -> $<span class="number">2</span>
|
|
o <span class="string">'FOR OWN ForVariables'</span>, -> $<span class="number">3.</span>own = <span class="literal">yes</span>; $<span class="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> ForValue: [
|
|
o <span class="string">'Identifier'</span>
|
|
o <span class="string">'ThisProperty'</span>
|
|
o <span class="string">'Array'</span>, -> <span class="keyword">new</span> Value $<span class="number">1</span>
|
|
o <span class="string">'Object'</span>, -> <span class="keyword">new</span> Value $<span class="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> ForVariables: [
|
|
o <span class="string">'ForValue'</span>, -> [$<span class="number">1</span>]
|
|
o <span class="string">'ForValue , ForValue'</span>, -> [$<span class="number">1</span>, $<span class="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> ForSource: [
|
|
o <span class="string">'FORIN Expression'</span>, -> source: $<span class="number">2</span>
|
|
o <span class="string">'FOROF Expression'</span>, -> source: $<span class="number">2</span>, object: <span class="literal">yes</span>
|
|
o <span class="string">'FORIN Expression WHEN Expression'</span>, -> source: $<span class="number">2</span>, guard: $<span class="number">4</span>
|
|
o <span class="string">'FOROF Expression WHEN Expression'</span>, -> source: $<span class="number">2</span>, guard: $<span class="number">4</span>, object: <span class="literal">yes</span>
|
|
o <span class="string">'FORIN Expression BY Expression'</span>, -> source: $<span class="number">2</span>, step: $<span class="number">4</span>
|
|
o <span class="string">'FORIN Expression WHEN Expression BY Expression'</span>, -> source: $<span class="number">2</span>, guard: $<span class="number">4</span>, step: $<span class="number">6</span>
|
|
o <span class="string">'FORIN Expression BY Expression WHEN Expression'</span>, -> source: $<span class="number">2</span>, step: $<span class="number">4</span>, guard: $<span class="number">6</span>
|
|
]
|
|
|
|
Switch: [
|
|
o <span class="string">'SWITCH Expression INDENT Whens OUTDENT'</span>, -> <span class="keyword">new</span> Switch $<span class="number">2</span>, $<span class="number">4</span>
|
|
o <span class="string">'SWITCH Expression INDENT Whens ELSE Block OUTDENT'</span>, -> <span class="keyword">new</span> Switch $<span class="number">2</span>, $<span class="number">4</span>, $<span class="number">6</span>
|
|
o <span class="string">'SWITCH INDENT Whens OUTDENT'</span>, -> <span class="keyword">new</span> Switch <span class="literal">null</span>, $<span class="number">3</span>
|
|
o <span class="string">'SWITCH INDENT Whens ELSE Block OUTDENT'</span>, -> <span class="keyword">new</span> Switch <span class="literal">null</span>, $<span class="number">3</span>, $<span class="number">5</span>
|
|
]
|
|
|
|
Whens: [
|
|
o <span class="string">'When'</span>
|
|
o <span class="string">'Whens When'</span>, -> $<span class="number">1.</span>concat $<span class="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> When: [
|
|
o <span class="string">'LEADING_WHEN SimpleArgs Block'</span>, -> [[$<span class="number">2</span>, $<span class="number">3</span>]]
|
|
o <span class="string">'LEADING_WHEN SimpleArgs Block TERMINATOR'</span>, -> [[$<span class="number">2</span>, $<span class="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> IfBlock: [
|
|
o <span class="string">'IF Expression Block'</span>, -> <span class="keyword">new</span> If $<span class="number">2</span>, $<span class="number">3</span>, type: $<span class="number">1</span>
|
|
o <span class="string">'IfBlock ELSE IF Expression Block'</span>, -> $<span class="number">1.</span>addElse <span class="keyword">new</span> If $<span class="number">4</span>, $<span class="number">5</span>, type: $<span class="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> If: [
|
|
o <span class="string">'IfBlock'</span>
|
|
o <span class="string">'IfBlock ELSE Block'</span>, -> $<span class="number">1.</span>addElse $<span class="number">3</span>
|
|
o <span class="string">'Statement POST_IF Expression'</span>, -> <span class="keyword">new</span> If $<span class="number">3</span>, LOC(<span class="number">1</span>)(Block.wrap [$<span class="number">1</span>]), type: $<span class="number">2</span>, statement: <span class="literal">true</span>
|
|
o <span class="string">'Expression POST_IF Expression'</span>, -> <span class="keyword">new</span> If $<span class="number">3</span>, LOC(<span class="number">1</span>)(Block.wrap [$<span class="number">1</span>]), type: $<span class="number">2</span>, statement: <span class="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> Operation: [
|
|
o <span class="string">'UNARY Expression'</span>, -> <span class="keyword">new</span> Op $<span class="number">1</span> , $<span class="number">2</span>
|
|
o <span class="string">'- Expression'</span>, (-> <span class="keyword">new</span> Op <span class="string">'-'</span>, $<span class="number">2</span>), prec: <span class="string">'UNARY'</span>
|
|
o <span class="string">'+ Expression'</span>, (-> <span class="keyword">new</span> Op <span class="string">'+'</span>, $<span class="number">2</span>), prec: <span class="string">'UNARY'</span>
|
|
|
|
o <span class="string">'-- SimpleAssignable'</span>, -> <span class="keyword">new</span> Op <span class="string">'--'</span>, $<span class="number">2</span>
|
|
o <span class="string">'++ SimpleAssignable'</span>, -> <span class="keyword">new</span> Op <span class="string">'++'</span>, $<span class="number">2</span>
|
|
o <span class="string">'SimpleAssignable --'</span>, -> <span class="keyword">new</span> Op <span class="string">'--'</span>, $<span class="number">1</span>, <span class="literal">null</span>, <span class="literal">true</span>
|
|
o <span class="string">'SimpleAssignable ++'</span>, -> <span class="keyword">new</span> Op <span class="string">'++'</span>, $<span class="number">1</span>, <span class="literal">null</span>, <span class="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 'Expression ?', -> new Existence $1
|
|
|
|
o 'Expression + Expression', -> new Op '+' , $1, $3
|
|
o 'Expression - Expression', -> new Op '-' , $1, $3
|
|
|
|
o 'Expression MATH Expression', -> new Op $2, $1, $3
|
|
o 'Expression SHIFT Expression', -> new Op $2, $1, $3
|
|
o 'Expression COMPARE Expression', -> new Op $2, $1, $3
|
|
o 'Expression LOGIC Expression', -> new Op $2, $1, $3
|
|
o 'Expression RELATION Expression', ->
|
|
if $2.charAt(0) is '!'
|
|
new Op($2[1..], $1, $3).invert()
|
|
else
|
|
new Op $2, $1, $3
|
|
|
|
o 'SimpleAssignable COMPOUND_ASSIGN
|
|
Expression', -> new Assign $1, $3, $2
|
|
o 'SimpleAssignable COMPOUND_ASSIGN
|
|
INDENT Expression OUTDENT', -> new Assign $1, $4, $2
|
|
o 'SimpleAssignable COMPOUND_ASSIGN TERMINATOR
|
|
Expression', -> new Assign $1, $4, $2
|
|
o 'SimpleAssignable EXTENDS Expression', -> new Extends $1, $3
|
|
]</pre></div></div>
|
|
|
|
</li>
|
|
|
|
|
|
<li id="section-67">
|
|
<div class="annotation">
|
|
|
|
<div class="pilwrap for-h2">
|
|
<a class="pilcrow" href="#section-67">¶</a>
|
|
</div>
|
|
<h2>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>2 + (3 * 4)</code></pre>
|
|
<p>And not:
|
|
|
|
</p>
|
|
<pre><code>(2 + 3) * 4</code></pre>
|
|
|
|
</div>
|
|
|
|
<div class="content"><div class='highlight'><pre>operators = [
|
|
[<span class="string">'left'</span>, <span class="string">'.'</span>, <span class="string">'?.'</span>, <span class="string">'::'</span>, <span class="string">'?::'</span>]
|
|
[<span class="string">'left'</span>, <span class="string">'CALL_START'</span>, <span class="string">'CALL_END'</span>]
|
|
[<span class="string">'nonassoc'</span>, <span class="string">'++'</span>, <span class="string">'--'</span>]
|
|
[<span class="string">'left'</span>, <span class="string">'?'</span>]
|
|
[<span class="string">'right'</span>, <span class="string">'UNARY'</span>]
|
|
[<span class="string">'left'</span>, <span class="string">'MATH'</span>]
|
|
[<span class="string">'left'</span>, <span class="string">'+'</span>, <span class="string">'-'</span>]
|
|
[<span class="string">'left'</span>, <span class="string">'SHIFT'</span>]
|
|
[<span class="string">'left'</span>, <span class="string">'RELATION'</span>]
|
|
[<span class="string">'left'</span>, <span class="string">'COMPARE'</span>]
|
|
[<span class="string">'left'</span>, <span class="string">'LOGIC'</span>]
|
|
[<span class="string">'nonassoc'</span>, <span class="string">'INDENT'</span>, <span class="string">'OUTDENT'</span>]
|
|
[<span class="string">'right'</span>, <span class="string">'='</span>, <span class="string">':'</span>, <span class="string">'COMPOUND_ASSIGN'</span>, <span class="string">'RETURN'</span>, <span class="string">'THROW'</span>, <span class="string">'EXTENDS'</span>]
|
|
[<span class="string">'right'</span>, <span class="string">'FORIN'</span>, <span class="string">'FOROF'</span>, <span class="string">'BY'</span>, <span class="string">'WHEN'</span>]
|
|
[<span class="string">'right'</span>, <span class="string">'IF'</span>, <span class="string">'ELSE'</span>, <span class="string">'FOR'</span>, <span class="string">'WHILE'</span>, <span class="string">'UNTIL'</span>, <span class="string">'LOOP'</span>, <span class="string">'SUPER'</span>, <span class="string">'CLASS'</span>]
|
|
[<span class="string">'right'</span>, <span class="string">'POST_IF'</span>]
|
|
]</pre></div></div>
|
|
|
|
</li>
|
|
|
|
|
|
<li id="section-70">
|
|
<div class="annotation">
|
|
|
|
<div class="pilwrap for-h2">
|
|
<a class="pilcrow" href="#section-70">¶</a>
|
|
</div>
|
|
<h2>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="keyword">for</span> name, alternatives <span class="keyword">of</span> grammar
|
|
grammar[name] = <span class="keyword">for</span> alt <span class="keyword">in</span> alternatives
|
|
<span class="keyword">for</span> token <span class="keyword">in</span> alt[<span class="number">0</span>].split <span class="string">' '</span>
|
|
tokens.push token <span class="keyword">unless</span> grammar[token]
|
|
alt[<span class="number">1</span>] = <span class="string">"return <span class="subst">#{alt[<span class="number">1</span>]}</span>"</span> <span class="keyword">if</span> name <span class="keyword">is</span> <span class="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>exports.parser = <span class="keyword">new</span> Parser
|
|
tokens : tokens.join <span class="string">' '</span>
|
|
bnf : grammar
|
|
operators : operators.reverse()
|
|
startSymbol : <span class="string">'Root'</span></pre></div></div>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</div>
|
|
</body>
|
|
</html>
|