babel/index.html
Marijn Haverbeke 48bbcd9437 Restore nonasciiwhitespace regexp
It won't make any difference except in really strange code.
2012-10-19 10:10:53 +02:00

1177 lines
280 KiB
HTML

<!DOCTYPE html> <html> <head> <title>acorn.js</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <link rel="stylesheet" media="all" href="docco.css" /> </head> <body> <div id="container"> <div id="background"></div> <table cellpadding="0" cellspacing="0"> <thead> <tr> <th class="docs"> <h1> acorn.js </h1> </th> <th class="code"> </th> </tr> </thead> <tbody> <tr id="section-1"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-1">&#182;</a> </div> <p>Acorn is a tiny, fast JavaScript parser written in JavaScript.</p>
<p>Acorn was written by Marijn Haverbeke and released under an MIT
license. The Unicode regexps (for identifiers and whitespace) were
taken from <a href="http://esprima.org">Esprima</a> by Ariya Hidayat.</p>
<p>Git repositories for Acorn are available at</p>
<pre><code>http://marijnhaverbeke.nl/git/acorn
https://github.com/marijnh/acorn.git
</code></pre>
<p>Please use the <a href="https://github.com/marijnh/acorn/issues">github bug tracker</a> to report issues.</p> </td> <td class="code"> <div class="highlight"><pre><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">exports</span><span class="p">)</span> <span class="p">{</span>
<span class="s2">&quot;use strict&quot;</span><span class="p">;</span>
<span class="nx">exports</span><span class="p">.</span><span class="nx">version</span> <span class="o">=</span> <span class="s2">&quot;0.0.1&quot;</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-2"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-2">&#182;</a> </div> <p>The main exported interface (under <code>window.acorn</code> when in the
browser) is a <code>parse</code> function that takes a code string and
returns an abstract syntax tree as specified by <a href="https://developer.mozilla.org/en-US/docs/SpiderMonkey/Parser_API">Mozilla parser
API</a>, with the caveat that the SpiderMonkey-specific syntax
(<code>let</code>, <code>yield</code>, inline XML, etc) is not recognized.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">options</span><span class="p">,</span> <span class="nx">input</span><span class="p">,</span> <span class="nx">inputLen</span><span class="p">,</span> <span class="nx">sourceFile</span><span class="p">;</span>
<span class="nx">exports</span><span class="p">.</span><span class="nx">parse</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">inpt</span><span class="p">,</span> <span class="nx">opts</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">input</span> <span class="o">=</span> <span class="nb">String</span><span class="p">(</span><span class="nx">inpt</span><span class="p">);</span> <span class="nx">inputLen</span> <span class="o">=</span> <span class="nx">input</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span>
<span class="nx">options</span> <span class="o">=</span> <span class="nx">opts</span> <span class="o">||</span> <span class="p">{};</span>
<span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">opt</span> <span class="k">in</span> <span class="nx">defaultOptions</span><span class="p">)</span> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">options</span><span class="p">.</span><span class="nx">hasOwnProperty</span><span class="p">(</span><span class="nx">opt</span><span class="p">))</span>
<span class="nx">options</span><span class="p">[</span><span class="nx">opt</span><span class="p">]</span> <span class="o">=</span> <span class="nx">defaultOptions</span><span class="p">[</span><span class="nx">opt</span><span class="p">];</span>
<span class="nx">sourceFile</span> <span class="o">=</span> <span class="nx">options</span><span class="p">.</span><span class="nx">sourceFile</span> <span class="o">||</span> <span class="kc">null</span><span class="p">;</span>
<span class="k">return</span> <span class="nx">parseTopLevel</span><span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">program</span><span class="p">);</span>
<span class="p">};</span></pre></div> </td> </tr> <tr id="section-3"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-3">&#182;</a> </div> <p>A second optional argument can be given to further configure
the parser process. These options are recognized:</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">defaultOptions</span> <span class="o">=</span> <span class="nx">exports</span><span class="p">.</span><span class="nx">defaultOptions</span> <span class="o">=</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-4"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-4">&#182;</a> </div> <p><code>ecmaVersion</code> indicates the ECMAScript version to parse. Must
be either 3 or 5. This
influences support for strict mode, the set of reserved words, and
support for getters and setter.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">ecmaVersion</span><span class="o">:</span> <span class="mi">5</span><span class="p">,</span></pre></div> </td> </tr> <tr id="section-5"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-5">&#182;</a> </div> <p>Turn on <code>strictSemicolons</code> to prevent the parser from doing
automatic semicolon insertion.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">strictSemicolons</span><span class="o">:</span> <span class="kc">false</span><span class="p">,</span></pre></div> </td> </tr> <tr id="section-6"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-6">&#182;</a> </div> <p>When <code>allowTrailingCommas</code> is false, the parser will not allow
trailing commas in array and object literals.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">allowTrailingCommas</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span></pre></div> </td> </tr> <tr id="section-7"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-7">&#182;</a> </div> <p>By default, reserved words are not enforced. Enable
<code>forbidReserved</code> to enforce them.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">forbidReserved</span><span class="o">:</span> <span class="kc">false</span><span class="p">,</span></pre></div> </td> </tr> <tr id="section-8"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-8">&#182;</a> </div> <p>When <code>trackComments</code> is turned on, the parser will attach
<code>commentsBefore</code> and <code>commentsAfter</code> properties to AST nodes
holding arrays of strings. A single comment may appear in both
a <code>commentsBefore</code> and <code>commentsAfter</code> array (of the nodes
after and before it), but never twice in the before (or after)
array of different nodes.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">trackComments</span><span class="o">:</span> <span class="kc">false</span><span class="p">,</span></pre></div> </td> </tr> <tr id="section-9"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-9">&#182;</a> </div> <p>When <code>locations</code> is on, <code>loc</code> properties holding objects with
<code>start</code> and <code>end</code> properties in <code>{line, column}</code> form (with
line being 1-based and column 0-based) will be attached to the
nodes.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">locations</span><span class="o">:</span> <span class="kc">false</span><span class="p">,</span></pre></div> </td> </tr> <tr id="section-10"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-10">&#182;</a> </div> <p>Nodes have their start and end characters offsets recorded in
<code>start</code> and <code>end</code> properties (directly on the node, rather than
the <code>loc</code> object, which holds line/column data. To also add a
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=745678">semi-standardized</a> <code>range</code> property holding a <code>[start,
end]</code> array with the same numbers, set the <code>ranges</code> option to
<code>true</code>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">ranges</span><span class="o">:</span> <span class="kc">false</span><span class="p">,</span></pre></div> </td> </tr> <tr id="section-11"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-11">&#182;</a> </div> <p>It is possible to parse multiple files into a single AST by
passing the tree produced by parsing the first file as
<code>program</code> option in subsequent parses. This will add the
toplevel forms of the parsed file to the <code>Program</code> (top) node
of an existing parse tree.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">program</span><span class="o">:</span> <span class="kc">null</span><span class="p">,</span></pre></div> </td> </tr> <tr id="section-12"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-12">&#182;</a> </div> <p>When <code>location</code> is on, you can pass this to record the source
file in every node's <code>loc</code> object.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">sourceFile</span><span class="o">:</span> <span class="kc">null</span>
<span class="p">};</span></pre></div> </td> </tr> <tr id="section-13"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-13">&#182;</a> </div> <p>The <code>getLineInfo</code> function is mostly useful when the
<code>locations</code> option is off (for performance reasons) and you
want to find the line/column position for a given character
offset. <code>input</code> should be the code string that the offset refers
into.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">getLineInfo</span> <span class="o">=</span> <span class="nx">exports</span><span class="p">.</span><span class="nx">getLineInfo</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">input</span><span class="p">,</span> <span class="nx">offset</span><span class="p">)</span> <span class="p">{</span>
<span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">line</span> <span class="o">=</span> <span class="mi">1</span><span class="p">,</span> <span class="nx">cur</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;;)</span> <span class="p">{</span>
<span class="nx">lineBreak</span><span class="p">.</span><span class="nx">lastIndex</span> <span class="o">=</span> <span class="nx">cur</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">match</span> <span class="o">=</span> <span class="nx">lineBreak</span><span class="p">.</span><span class="nx">exec</span><span class="p">(</span><span class="nx">input</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">match</span> <span class="o">&amp;&amp;</span> <span class="nx">match</span><span class="p">.</span><span class="nx">index</span> <span class="o">&lt;</span> <span class="nx">offset</span><span class="p">)</span> <span class="p">{</span>
<span class="o">++</span><span class="nx">line</span><span class="p">;</span>
<span class="nx">cur</span> <span class="o">=</span> <span class="nx">match</span><span class="p">.</span><span class="nx">index</span> <span class="o">+</span> <span class="nx">match</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nx">length</span><span class="p">;</span>
<span class="p">}</span> <span class="k">else</span> <span class="k">break</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">return</span> <span class="p">{</span><span class="nx">line</span><span class="o">:</span> <span class="nx">line</span><span class="p">,</span> <span class="nx">column</span><span class="o">:</span> <span class="nx">offset</span> <span class="o">-</span> <span class="nx">cur</span><span class="p">};</span>
<span class="p">};</span></pre></div> </td> </tr> <tr id="section-14"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-14">&#182;</a> </div> <p>Acorn is organized as a tokenizer and a recursive-descent parser.
Both use (closure-)global variables to keep their state and
communicate. We already saw the <code>options</code>, <code>input</code>, and
<code>inputLen</code> variables above (set in <code>parse</code>).</p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-15"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-15">&#182;</a> </div> <p>The current position of the tokenizer in the input.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">tokPos</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-16"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-16">&#182;</a> </div> <p>The start and end offsets of the current token.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">tokStart</span><span class="p">,</span> <span class="nx">tokEnd</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-17"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-17">&#182;</a> </div> <p>When <code>options.locations</code> is true, these hold objects
containing the tokens start and end line/column pairs.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">tokStartLoc</span><span class="p">,</span> <span class="nx">tokEndLoc</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-18"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-18">&#182;</a> </div> <p>The type and value of the current token. Token types are objects,
named by variables against which they can be compared, and
holding properties that describe them (indicating, for example,
the precedence of an infix operator, and the original name of a
keyword token). The kind of value that's held in <code>tokVal</code> depends
on the type of the token. For literals, it is the literal value,
for operators, the operator name, and so on.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">tokType</span><span class="p">,</span> <span class="nx">tokVal</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-19"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-19">&#182;</a> </div> <p>These are used to hold arrays of comments when
<code>options.trackComments</code> is true.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">tokCommentsBefore</span><span class="p">,</span> <span class="nx">tokCommentsAfter</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-20"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-20">&#182;</a> </div> <p>Interal state for the tokenizer. To distinguish between division
operators and regular expressions, it remembers whether the last
token was one that is allowed to be followed by an expression.
(If it is, a slash is probably a regexp, if it isn't it's a
division operator. See the <code>parseStatement</code> function for a
caveat.)</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">tokRegexpAllowed</span><span class="p">,</span> <span class="nx">tokComments</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-21"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-21">&#182;</a> </div> <p>When <code>options.locations</code> is true, these are used to keep
track of the current line, and know when a new line has been
entered. See the <code>curLineLoc</code> function.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">tokCurLine</span><span class="p">,</span> <span class="nx">tokLineStart</span><span class="p">,</span> <span class="nx">tokLineStartNext</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-22"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-22">&#182;</a> </div> <p>These store the position of the previous token, which is useful
when finishing a node and assigning its <code>end</code> position.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">lastStart</span><span class="p">,</span> <span class="nx">lastEnd</span><span class="p">,</span> <span class="nx">lastEndLoc</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-23"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-23">&#182;</a> </div> <p>This is the parser's state. <code>inFunction</code> is used to reject
<code>return</code> statements outside of functions, <code>labels</code> to verify that
<code>break</code> and <code>continue</code> have somewhere to jump to, and <code>strict</code>
indicates whether strict mode is on.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">inFunction</span><span class="p">,</span> <span class="nx">labels</span><span class="p">,</span> <span class="nx">strict</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-24"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-24">&#182;</a> </div> <p>This function is used to raise exceptions on parse errors. It
takes either a <code>{line, column}</code> object or an offset integer (into
the current <code>input</code>) as <code>pos</code> argument. It attaches the position
to the end of the error message, and then raises a <code>SyntaxError</code>
with that message.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">raise</span><span class="p">(</span><span class="nx">pos</span><span class="p">,</span> <span class="nx">message</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="k">typeof</span> <span class="nx">pos</span> <span class="o">==</span> <span class="s2">&quot;number&quot;</span><span class="p">)</span> <span class="nx">pos</span> <span class="o">=</span> <span class="nx">getLineInfo</span><span class="p">(</span><span class="nx">input</span><span class="p">,</span> <span class="nx">pos</span><span class="p">);</span>
<span class="nx">message</span> <span class="o">+=</span> <span class="s2">&quot; (&quot;</span> <span class="o">+</span> <span class="nx">pos</span><span class="p">.</span><span class="nx">line</span> <span class="o">+</span> <span class="s2">&quot;:&quot;</span> <span class="o">+</span> <span class="nx">pos</span><span class="p">.</span><span class="nx">column</span> <span class="o">+</span> <span class="s2">&quot;)&quot;</span><span class="p">;</span>
<span class="k">throw</span> <span class="k">new</span> <span class="nx">SyntaxError</span><span class="p">(</span><span class="nx">message</span><span class="p">);</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-25"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-25">&#182;</a> </div> <h2>Token types</h2> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-26"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-26">&#182;</a> </div> <p>The assignment of fine-grained, information-carrying type objects
allows the tokenizer to store the information it has about a
token in a way that is very cheap for the parser to look up.</p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-27"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-27">&#182;</a> </div> <p>All token type variables start with an underscore, to make them
easy to recognize.</p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-28"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-28">&#182;</a> </div> <p>These are the general types. The <code>type</code> property is only used to
make them recognizeable when debugging.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">_num</span> <span class="o">=</span> <span class="p">{</span><span class="nx">type</span><span class="o">:</span> <span class="s2">&quot;num&quot;</span><span class="p">},</span> <span class="nx">_regexp</span> <span class="o">=</span> <span class="p">{</span><span class="nx">type</span><span class="o">:</span> <span class="s2">&quot;regexp&quot;</span><span class="p">},</span> <span class="nx">_string</span> <span class="o">=</span> <span class="p">{</span><span class="nx">type</span><span class="o">:</span> <span class="s2">&quot;string&quot;</span><span class="p">};</span>
<span class="kd">var</span> <span class="nx">_name</span> <span class="o">=</span> <span class="p">{</span><span class="nx">type</span><span class="o">:</span> <span class="s2">&quot;name&quot;</span><span class="p">},</span> <span class="nx">_eof</span> <span class="o">=</span> <span class="p">{</span><span class="nx">type</span><span class="o">:</span> <span class="s2">&quot;eof&quot;</span><span class="p">};</span></pre></div> </td> </tr> <tr id="section-29"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-29">&#182;</a> </div> <p>Keyword tokens. The <code>keyword</code> property (also used in keyword-like
operators) indicates that the token originated from an
identifier-like word, which is used when parsing property names.</p>
<p>The <code>beforeExpr</code> property is used to disambiguate between regular
expressions and divisions. It is set on all token types that can
be followed by an expression (thus, a slash after them would be a
regular expression).</p>
<p><code>isLoop</code> marks a keyword as starting a loop, which is important
to know when parsing a label, in order to allow or disallow
continue jumps to that label.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">_break</span> <span class="o">=</span> <span class="p">{</span><span class="nx">keyword</span><span class="o">:</span> <span class="s2">&quot;break&quot;</span><span class="p">},</span> <span class="nx">_case</span> <span class="o">=</span> <span class="p">{</span><span class="nx">keyword</span><span class="o">:</span> <span class="s2">&quot;case&quot;</span><span class="p">,</span> <span class="nx">beforeExpr</span><span class="o">:</span> <span class="kc">true</span><span class="p">},</span> <span class="nx">_catch</span> <span class="o">=</span> <span class="p">{</span><span class="nx">keyword</span><span class="o">:</span> <span class="s2">&quot;catch&quot;</span><span class="p">};</span>
<span class="kd">var</span> <span class="nx">_continue</span> <span class="o">=</span> <span class="p">{</span><span class="nx">keyword</span><span class="o">:</span> <span class="s2">&quot;continue&quot;</span><span class="p">},</span> <span class="nx">_debugger</span> <span class="o">=</span> <span class="p">{</span><span class="nx">keyword</span><span class="o">:</span> <span class="s2">&quot;debugger&quot;</span><span class="p">},</span> <span class="nx">_default</span> <span class="o">=</span> <span class="p">{</span><span class="nx">keyword</span><span class="o">:</span> <span class="s2">&quot;default&quot;</span><span class="p">};</span>
<span class="kd">var</span> <span class="nx">_do</span> <span class="o">=</span> <span class="p">{</span><span class="nx">keyword</span><span class="o">:</span> <span class="s2">&quot;do&quot;</span><span class="p">,</span> <span class="nx">isLoop</span><span class="o">:</span> <span class="kc">true</span><span class="p">},</span> <span class="nx">_else</span> <span class="o">=</span> <span class="p">{</span><span class="nx">keyword</span><span class="o">:</span> <span class="s2">&quot;else&quot;</span><span class="p">,</span> <span class="nx">beforeExpr</span><span class="o">:</span> <span class="kc">true</span><span class="p">};</span>
<span class="kd">var</span> <span class="nx">_finally</span> <span class="o">=</span> <span class="p">{</span><span class="nx">keyword</span><span class="o">:</span> <span class="s2">&quot;finally&quot;</span><span class="p">},</span> <span class="nx">_for</span> <span class="o">=</span> <span class="p">{</span><span class="nx">keyword</span><span class="o">:</span> <span class="s2">&quot;for&quot;</span><span class="p">,</span> <span class="nx">isLoop</span><span class="o">:</span> <span class="kc">true</span><span class="p">},</span> <span class="nx">_function</span> <span class="o">=</span> <span class="p">{</span><span class="nx">keyword</span><span class="o">:</span> <span class="s2">&quot;function&quot;</span><span class="p">};</span>
<span class="kd">var</span> <span class="nx">_if</span> <span class="o">=</span> <span class="p">{</span><span class="nx">keyword</span><span class="o">:</span> <span class="s2">&quot;if&quot;</span><span class="p">},</span> <span class="nx">_return</span> <span class="o">=</span> <span class="p">{</span><span class="nx">keyword</span><span class="o">:</span> <span class="s2">&quot;return&quot;</span><span class="p">,</span> <span class="nx">beforeExpr</span><span class="o">:</span> <span class="kc">true</span><span class="p">},</span> <span class="nx">_switch</span> <span class="o">=</span> <span class="p">{</span><span class="nx">keyword</span><span class="o">:</span> <span class="s2">&quot;switch&quot;</span><span class="p">};</span>
<span class="kd">var</span> <span class="nx">_throw</span> <span class="o">=</span> <span class="p">{</span><span class="nx">keyword</span><span class="o">:</span> <span class="s2">&quot;throw&quot;</span><span class="p">,</span> <span class="nx">beforeExpr</span><span class="o">:</span> <span class="kc">true</span><span class="p">},</span> <span class="nx">_try</span> <span class="o">=</span> <span class="p">{</span><span class="nx">keyword</span><span class="o">:</span> <span class="s2">&quot;try&quot;</span><span class="p">},</span> <span class="nx">_var</span> <span class="o">=</span> <span class="p">{</span><span class="nx">keyword</span><span class="o">:</span> <span class="s2">&quot;var&quot;</span><span class="p">};</span>
<span class="kd">var</span> <span class="nx">_while</span> <span class="o">=</span> <span class="p">{</span><span class="nx">keyword</span><span class="o">:</span> <span class="s2">&quot;while&quot;</span><span class="p">,</span> <span class="nx">isLoop</span><span class="o">:</span> <span class="kc">true</span><span class="p">},</span> <span class="nx">_with</span> <span class="o">=</span> <span class="p">{</span><span class="nx">keyword</span><span class="o">:</span> <span class="s2">&quot;with&quot;</span><span class="p">},</span> <span class="nx">_new</span> <span class="o">=</span> <span class="p">{</span><span class="nx">keyword</span><span class="o">:</span> <span class="s2">&quot;new&quot;</span><span class="p">,</span> <span class="nx">beforeExpr</span><span class="o">:</span> <span class="kc">true</span><span class="p">};</span>
<span class="kd">var</span> <span class="nx">_this</span> <span class="o">=</span> <span class="p">{</span><span class="nx">keyword</span><span class="o">:</span> <span class="s2">&quot;this&quot;</span><span class="p">};</span></pre></div> </td> </tr> <tr id="section-30"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-30">&#182;</a> </div> <p>The keywords that denote values.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">_null</span> <span class="o">=</span> <span class="p">{</span><span class="nx">keyword</span><span class="o">:</span> <span class="s2">&quot;null&quot;</span><span class="p">,</span> <span class="nx">atomValue</span><span class="o">:</span> <span class="kc">null</span><span class="p">},</span> <span class="nx">_true</span> <span class="o">=</span> <span class="p">{</span><span class="nx">keyword</span><span class="o">:</span> <span class="s2">&quot;true&quot;</span><span class="p">,</span> <span class="nx">atomValue</span><span class="o">:</span> <span class="kc">true</span><span class="p">};</span>
<span class="kd">var</span> <span class="nx">_false</span> <span class="o">=</span> <span class="p">{</span><span class="nx">keyword</span><span class="o">:</span> <span class="s2">&quot;false&quot;</span><span class="p">,</span> <span class="nx">atomValue</span><span class="o">:</span> <span class="kc">false</span><span class="p">};</span></pre></div> </td> </tr> <tr id="section-31"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-31">&#182;</a> </div> <p>Some keywords are treated as regular operators. <code>in</code> sometimes
(when parsing <code>for</code>) needs to be tested against specifically, so
we assign a variable name to it for quick comparing.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">_in</span> <span class="o">=</span> <span class="p">{</span><span class="nx">keyword</span><span class="o">:</span> <span class="s2">&quot;in&quot;</span><span class="p">,</span> <span class="nx">binop</span><span class="o">:</span> <span class="mi">7</span><span class="p">,</span> <span class="nx">beforeExpr</span><span class="o">:</span> <span class="kc">true</span><span class="p">};</span></pre></div> </td> </tr> <tr id="section-32"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-32">&#182;</a> </div> <p>Map keyword names to token types.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">keywordTypes</span> <span class="o">=</span> <span class="p">{</span><span class="s2">&quot;break&quot;</span><span class="o">:</span> <span class="nx">_break</span><span class="p">,</span> <span class="s2">&quot;case&quot;</span><span class="o">:</span> <span class="nx">_case</span><span class="p">,</span> <span class="s2">&quot;catch&quot;</span><span class="o">:</span> <span class="nx">_catch</span><span class="p">,</span>
<span class="s2">&quot;continue&quot;</span><span class="o">:</span> <span class="nx">_continue</span><span class="p">,</span> <span class="s2">&quot;debugger&quot;</span><span class="o">:</span> <span class="nx">_debugger</span><span class="p">,</span> <span class="s2">&quot;default&quot;</span><span class="o">:</span> <span class="nx">_default</span><span class="p">,</span>
<span class="s2">&quot;do&quot;</span><span class="o">:</span> <span class="nx">_do</span><span class="p">,</span> <span class="s2">&quot;else&quot;</span><span class="o">:</span> <span class="nx">_else</span><span class="p">,</span> <span class="s2">&quot;finally&quot;</span><span class="o">:</span> <span class="nx">_finally</span><span class="p">,</span> <span class="s2">&quot;for&quot;</span><span class="o">:</span> <span class="nx">_for</span><span class="p">,</span>
<span class="s2">&quot;function&quot;</span><span class="o">:</span> <span class="nx">_function</span><span class="p">,</span> <span class="s2">&quot;if&quot;</span><span class="o">:</span> <span class="nx">_if</span><span class="p">,</span> <span class="s2">&quot;return&quot;</span><span class="o">:</span> <span class="nx">_return</span><span class="p">,</span> <span class="s2">&quot;switch&quot;</span><span class="o">:</span> <span class="nx">_switch</span><span class="p">,</span>
<span class="s2">&quot;throw&quot;</span><span class="o">:</span> <span class="nx">_throw</span><span class="p">,</span> <span class="s2">&quot;try&quot;</span><span class="o">:</span> <span class="nx">_try</span><span class="p">,</span> <span class="s2">&quot;var&quot;</span><span class="o">:</span> <span class="nx">_var</span><span class="p">,</span> <span class="s2">&quot;while&quot;</span><span class="o">:</span> <span class="nx">_while</span><span class="p">,</span> <span class="s2">&quot;with&quot;</span><span class="o">:</span> <span class="nx">_with</span><span class="p">,</span>
<span class="s2">&quot;null&quot;</span><span class="o">:</span> <span class="nx">_null</span><span class="p">,</span> <span class="s2">&quot;true&quot;</span><span class="o">:</span> <span class="nx">_true</span><span class="p">,</span> <span class="s2">&quot;false&quot;</span><span class="o">:</span> <span class="nx">_false</span><span class="p">,</span> <span class="s2">&quot;new&quot;</span><span class="o">:</span> <span class="nx">_new</span><span class="p">,</span> <span class="s2">&quot;in&quot;</span><span class="o">:</span> <span class="nx">_in</span><span class="p">,</span>
<span class="s2">&quot;instanceof&quot;</span><span class="o">:</span> <span class="p">{</span><span class="nx">keyword</span><span class="o">:</span> <span class="s2">&quot;instanceof&quot;</span><span class="p">,</span> <span class="nx">binop</span><span class="o">:</span> <span class="mi">7</span><span class="p">},</span> <span class="s2">&quot;this&quot;</span><span class="o">:</span> <span class="nx">_this</span><span class="p">,</span>
<span class="s2">&quot;typeof&quot;</span><span class="o">:</span> <span class="p">{</span><span class="nx">keyword</span><span class="o">:</span> <span class="s2">&quot;typeof&quot;</span><span class="p">,</span> <span class="nx">prefix</span><span class="o">:</span> <span class="kc">true</span><span class="p">},</span>
<span class="s2">&quot;void&quot;</span><span class="o">:</span> <span class="p">{</span><span class="nx">keyword</span><span class="o">:</span> <span class="s2">&quot;void&quot;</span><span class="p">,</span> <span class="nx">prefix</span><span class="o">:</span> <span class="kc">true</span><span class="p">},</span>
<span class="s2">&quot;delete&quot;</span><span class="o">:</span> <span class="p">{</span><span class="nx">keyword</span><span class="o">:</span> <span class="s2">&quot;delete&quot;</span><span class="p">,</span> <span class="nx">prefix</span><span class="o">:</span> <span class="kc">true</span><span class="p">}};</span></pre></div> </td> </tr> <tr id="section-33"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-33">&#182;</a> </div> <p>Punctuation token types. Again, the <code>type</code> property is purely for debugging.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">_bracketL</span> <span class="o">=</span> <span class="p">{</span><span class="nx">type</span><span class="o">:</span> <span class="s2">&quot;[&quot;</span><span class="p">,</span> <span class="nx">beforeExpr</span><span class="o">:</span> <span class="kc">true</span><span class="p">},</span> <span class="nx">_bracketR</span> <span class="o">=</span> <span class="p">{</span><span class="nx">type</span><span class="o">:</span> <span class="s2">&quot;]&quot;</span><span class="p">},</span> <span class="nx">_braceL</span> <span class="o">=</span> <span class="p">{</span><span class="nx">type</span><span class="o">:</span> <span class="s2">&quot;{&quot;</span><span class="p">,</span> <span class="nx">beforeExpr</span><span class="o">:</span> <span class="kc">true</span><span class="p">};</span>
<span class="kd">var</span> <span class="nx">_braceR</span> <span class="o">=</span> <span class="p">{</span><span class="nx">type</span><span class="o">:</span> <span class="s2">&quot;}&quot;</span><span class="p">},</span> <span class="nx">_parenL</span> <span class="o">=</span> <span class="p">{</span><span class="nx">type</span><span class="o">:</span> <span class="s2">&quot;(&quot;</span><span class="p">,</span> <span class="nx">beforeExpr</span><span class="o">:</span> <span class="kc">true</span><span class="p">},</span> <span class="nx">_parenR</span> <span class="o">=</span> <span class="p">{</span><span class="nx">type</span><span class="o">:</span> <span class="s2">&quot;)&quot;</span><span class="p">};</span>
<span class="kd">var</span> <span class="nx">_comma</span> <span class="o">=</span> <span class="p">{</span><span class="nx">type</span><span class="o">:</span> <span class="s2">&quot;,&quot;</span><span class="p">,</span> <span class="nx">beforeExpr</span><span class="o">:</span> <span class="kc">true</span><span class="p">},</span> <span class="nx">_semi</span> <span class="o">=</span> <span class="p">{</span><span class="nx">type</span><span class="o">:</span> <span class="s2">&quot;;&quot;</span><span class="p">,</span> <span class="nx">beforeExpr</span><span class="o">:</span> <span class="kc">true</span><span class="p">};</span>
<span class="kd">var</span> <span class="nx">_colon</span> <span class="o">=</span> <span class="p">{</span><span class="nx">type</span><span class="o">:</span> <span class="s2">&quot;:&quot;</span><span class="p">,</span> <span class="nx">beforeExpr</span><span class="o">:</span> <span class="kc">true</span><span class="p">},</span> <span class="nx">_dot</span> <span class="o">=</span> <span class="p">{</span><span class="nx">type</span><span class="o">:</span> <span class="s2">&quot;.&quot;</span><span class="p">},</span> <span class="nx">_question</span> <span class="o">=</span> <span class="p">{</span><span class="nx">type</span><span class="o">:</span> <span class="s2">&quot;?&quot;</span><span class="p">,</span> <span class="nx">beforeExpr</span><span class="o">:</span> <span class="kc">true</span><span class="p">};</span></pre></div> </td> </tr> <tr id="section-34"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-34">&#182;</a> </div> <p>Operators. These carry several kinds of properties to help the
parser use them properly (the presence of these properties is
what categorizes them as operators).</p>
<p><code>binop</code>, when present, specifies that this operator is a binary
operator, and will refer to its precedence.</p>
<p><code>prefix</code> and <code>postfix</code> mark the operator as a prefix or postfix
unary operator. <code>isUpdate</code> specifies that the node produced by
the operator should be of type UpdateExpression rather than
simply UnaryExpression (<code>++</code> and <code>--</code>).</p>
<p><code>isAssign</code> marks all of <code>=</code>, <code>+=</code>, <code>-=</code> etcetera, which act as
binary operators with a very low precedence, that should result
in AssignmentExpression nodes.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">_slash</span> <span class="o">=</span> <span class="p">{</span><span class="nx">binop</span><span class="o">:</span> <span class="mi">10</span><span class="p">,</span> <span class="nx">beforeExpr</span><span class="o">:</span> <span class="kc">true</span><span class="p">},</span> <span class="nx">_eq</span> <span class="o">=</span> <span class="p">{</span><span class="nx">isAssign</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span> <span class="nx">beforeExpr</span><span class="o">:</span> <span class="kc">true</span><span class="p">};</span>
<span class="kd">var</span> <span class="nx">_assign</span> <span class="o">=</span> <span class="p">{</span><span class="nx">isAssign</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span> <span class="nx">beforeExpr</span><span class="o">:</span> <span class="kc">true</span><span class="p">},</span> <span class="nx">_plusmin</span> <span class="o">=</span> <span class="p">{</span><span class="nx">binop</span><span class="o">:</span> <span class="mi">9</span><span class="p">,</span> <span class="nx">prefix</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span> <span class="nx">beforeExpr</span><span class="o">:</span> <span class="kc">true</span><span class="p">};</span>
<span class="kd">var</span> <span class="nx">_incdec</span> <span class="o">=</span> <span class="p">{</span><span class="nx">postfix</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span> <span class="nx">prefix</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span> <span class="nx">isUpdate</span><span class="o">:</span> <span class="kc">true</span><span class="p">},</span> <span class="nx">_prefix</span> <span class="o">=</span> <span class="p">{</span><span class="nx">prefix</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span> <span class="nx">beforeExpr</span><span class="o">:</span> <span class="kc">true</span><span class="p">};</span>
<span class="kd">var</span> <span class="nx">_bin1</span> <span class="o">=</span> <span class="p">{</span><span class="nx">binop</span><span class="o">:</span> <span class="mi">1</span><span class="p">,</span> <span class="nx">beforeExpr</span><span class="o">:</span> <span class="kc">true</span><span class="p">},</span> <span class="nx">_bin2</span> <span class="o">=</span> <span class="p">{</span><span class="nx">binop</span><span class="o">:</span> <span class="mi">2</span><span class="p">,</span> <span class="nx">beforeExpr</span><span class="o">:</span> <span class="kc">true</span><span class="p">};</span>
<span class="kd">var</span> <span class="nx">_bin3</span> <span class="o">=</span> <span class="p">{</span><span class="nx">binop</span><span class="o">:</span> <span class="mi">3</span><span class="p">,</span> <span class="nx">beforeExpr</span><span class="o">:</span> <span class="kc">true</span><span class="p">},</span> <span class="nx">_bin4</span> <span class="o">=</span> <span class="p">{</span><span class="nx">binop</span><span class="o">:</span> <span class="mi">4</span><span class="p">,</span> <span class="nx">beforeExpr</span><span class="o">:</span> <span class="kc">true</span><span class="p">};</span>
<span class="kd">var</span> <span class="nx">_bin5</span> <span class="o">=</span> <span class="p">{</span><span class="nx">binop</span><span class="o">:</span> <span class="mi">5</span><span class="p">,</span> <span class="nx">beforeExpr</span><span class="o">:</span> <span class="kc">true</span><span class="p">},</span> <span class="nx">_bin6</span> <span class="o">=</span> <span class="p">{</span><span class="nx">binop</span><span class="o">:</span> <span class="mi">6</span><span class="p">,</span> <span class="nx">beforeExpr</span><span class="o">:</span> <span class="kc">true</span><span class="p">};</span>
<span class="kd">var</span> <span class="nx">_bin7</span> <span class="o">=</span> <span class="p">{</span><span class="nx">binop</span><span class="o">:</span> <span class="mi">7</span><span class="p">,</span> <span class="nx">beforeExpr</span><span class="o">:</span> <span class="kc">true</span><span class="p">},</span> <span class="nx">_bin8</span> <span class="o">=</span> <span class="p">{</span><span class="nx">binop</span><span class="o">:</span> <span class="mi">8</span><span class="p">,</span> <span class="nx">beforeExpr</span><span class="o">:</span> <span class="kc">true</span><span class="p">};</span>
<span class="kd">var</span> <span class="nx">_bin10</span> <span class="o">=</span> <span class="p">{</span><span class="nx">binop</span><span class="o">:</span> <span class="mi">10</span><span class="p">,</span> <span class="nx">beforeExpr</span><span class="o">:</span> <span class="kc">true</span><span class="p">};</span></pre></div> </td> </tr> <tr id="section-35"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-35">&#182;</a> </div> <p>This is a trick taken from Esprima. It turns out that, on
non-Chrome browsers, to check whether a string is in a set, a
predicate containing a big ugly <code>switch</code> statement is faster than
a regular expression, and on Chrome the two are about on par.
This function uses <code>eval</code> (non-lexical) to produce such a
predicate from a space-separated string of words.</p>
<p>It starts by sorting the words by length.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">makePredicate</span><span class="p">(</span><span class="nx">words</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">words</span> <span class="o">=</span> <span class="nx">words</span><span class="p">.</span><span class="nx">split</span><span class="p">(</span><span class="s2">&quot; &quot;</span><span class="p">);</span>
<span class="kd">var</span> <span class="nx">f</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span><span class="p">,</span> <span class="nx">cats</span> <span class="o">=</span> <span class="p">[];</span>
<span class="nx">out</span><span class="o">:</span> <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="nx">words</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="o">++</span><span class="nx">i</span><span class="p">)</span> <span class="p">{</span>
<span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">j</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">j</span> <span class="o">&lt;</span> <span class="nx">cats</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="o">++</span><span class="nx">j</span><span class="p">)</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">cats</span><span class="p">[</span><span class="nx">j</span><span class="p">][</span><span class="mi">0</span><span class="p">].</span><span class="nx">length</span> <span class="o">==</span> <span class="nx">words</span><span class="p">[</span><span class="nx">i</span><span class="p">].</span><span class="nx">length</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">cats</span><span class="p">[</span><span class="nx">j</span><span class="p">].</span><span class="nx">push</span><span class="p">(</span><span class="nx">words</span><span class="p">[</span><span class="nx">i</span><span class="p">]);</span>
<span class="k">continue</span> <span class="nx">out</span><span class="p">;</span>
<span class="p">}</span>
<span class="nx">cats</span><span class="p">.</span><span class="nx">push</span><span class="p">([</span><span class="nx">words</span><span class="p">[</span><span class="nx">i</span><span class="p">]]);</span>
<span class="p">}</span>
<span class="kd">function</span> <span class="nx">compareTo</span><span class="p">(</span><span class="nx">arr</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">arr</span><span class="p">.</span><span class="nx">length</span> <span class="o">==</span> <span class="mi">1</span><span class="p">)</span> <span class="k">return</span> <span class="nx">f</span> <span class="o">+=</span> <span class="s2">&quot;return str === &quot;</span> <span class="o">+</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">(</span><span class="nx">arr</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span> <span class="o">+</span> <span class="s2">&quot;;&quot;</span><span class="p">;</span>
<span class="nx">f</span> <span class="o">+=</span> <span class="s2">&quot;switch(str){&quot;</span><span class="p">;</span>
<span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="nx">arr</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="o">++</span><span class="nx">i</span><span class="p">)</span> <span class="nx">f</span> <span class="o">+=</span> <span class="s2">&quot;case &quot;</span> <span class="o">+</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">(</span><span class="nx">arr</span><span class="p">[</span><span class="nx">i</span><span class="p">])</span> <span class="o">+</span> <span class="s2">&quot;:&quot;</span><span class="p">;</span>
<span class="nx">f</span> <span class="o">+=</span> <span class="s2">&quot;return true}return false;&quot;</span><span class="p">;</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-36"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-36">&#182;</a> </div> <p>When there are more than three length categories, an outer
switch first dispatches on the lengths, to save on comparisons.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span> <span class="p">(</span><span class="nx">cats</span><span class="p">.</span><span class="nx">length</span> <span class="o">&gt;</span> <span class="mi">3</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">cats</span><span class="p">.</span><span class="nx">sort</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">a</span><span class="p">,</span> <span class="nx">b</span><span class="p">)</span> <span class="p">{</span><span class="k">return</span> <span class="nx">b</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="nx">a</span><span class="p">.</span><span class="nx">length</span><span class="p">;});</span>
<span class="nx">f</span> <span class="o">+=</span> <span class="s2">&quot;switch(str.length){&quot;</span><span class="p">;</span>
<span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="nx">cats</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="o">++</span><span class="nx">i</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">cat</span> <span class="o">=</span> <span class="nx">cats</span><span class="p">[</span><span class="nx">i</span><span class="p">];</span>
<span class="nx">f</span> <span class="o">+=</span> <span class="s2">&quot;case &quot;</span> <span class="o">+</span> <span class="nx">cat</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nx">length</span> <span class="o">+</span> <span class="s2">&quot;:&quot;</span><span class="p">;</span>
<span class="nx">compareTo</span><span class="p">(</span><span class="nx">cat</span><span class="p">);</span>
<span class="p">}</span>
<span class="nx">f</span> <span class="o">+=</span> <span class="s2">&quot;}&quot;</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-37"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-37">&#182;</a> </div> <p>Otherwise, simply generate a flat <code>switch</code> statement.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="nx">compareTo</span><span class="p">(</span><span class="nx">words</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">return</span> <span class="k">new</span> <span class="nb">Function</span><span class="p">(</span><span class="s2">&quot;str&quot;</span><span class="p">,</span> <span class="nx">f</span><span class="p">);</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-38"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-38">&#182;</a> </div> <p>The ECMAScript 3 reserved word list.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">isReservedWord3</span> <span class="o">=</span> <span class="nx">makePredicate</span><span class="p">(</span><span class="s2">&quot;abstract boolean byte char class double enum export extends final float goto implements import int interface long native package private protected public short static super synchronized throws transient volatile&quot;</span><span class="p">);</span></pre></div> </td> </tr> <tr id="section-39"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-39">&#182;</a> </div> <p>ECMAScript 5 reserved words.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">isReservedWord5</span> <span class="o">=</span> <span class="nx">makePredicate</span><span class="p">(</span><span class="s2">&quot;class enum extends super const export import&quot;</span><span class="p">);</span></pre></div> </td> </tr> <tr id="section-40"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-40">&#182;</a> </div> <p>The additional reserved words in strict mode.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">isStrictReservedWord</span> <span class="o">=</span> <span class="nx">makePredicate</span><span class="p">(</span><span class="s2">&quot;implements interface let package private protected public static yield&quot;</span><span class="p">);</span></pre></div> </td> </tr> <tr id="section-41"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-41">&#182;</a> </div> <p>The forbidden variable names in strict mode.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">isStrictBadIdWord</span> <span class="o">=</span> <span class="nx">makePredicate</span><span class="p">(</span><span class="s2">&quot;eval arguments&quot;</span><span class="p">);</span></pre></div> </td> </tr> <tr id="section-42"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-42">&#182;</a> </div> <p>And the keywords.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">isKeyword</span> <span class="o">=</span> <span class="nx">makePredicate</span><span class="p">(</span><span class="s2">&quot;break case catch continue debugger default do else finally for function if return switch throw try var while with null true false instanceof typeof void delete new in this&quot;</span><span class="p">);</span></pre></div> </td> </tr> <tr id="section-43"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-43">&#182;</a> </div> <h2>Character categories</h2> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-44"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-44">&#182;</a> </div> <p>Big ugly regular expressions that match characters in the
whitespace, identifier, and identifier-start categories. These
are only applied when a character is found to actually have a
code point above 128.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">nonASCIIwhitespace</span> <span class="o">=</span> <span class="sr">/[\u1680\u180e\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]/</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">nonASCIIidentifierStartChars</span> <span class="o">=</span> <span class="s2">&quot;\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05d0-\u05ea\u05f0-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u08a0\u08a2-\u08ac\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0977\u0979-\u097f\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c33\u0c35-\u0c39\u0c3d\u0c58\u0c59\u0c60\u0c61\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d60\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f4\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f0\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1877\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191c\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19c1-\u19c7\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1ce9-\u1cec\u1cee-\u1cf1\u1cf5\u1cf6\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2119-\u211d\u2124\u2126\u2128\u212a-\u212d\u212f-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u2e2f\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309d-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312d\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fcc\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua697\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua78e\ua790-\ua793\ua7a0-\ua7aa\ua7f8-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa80-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uabc0-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc&quot;</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">nonASCIIidentifierChars</span> <span class="o">=</span> <span class="s2">&quot;\u0371-\u0374\u0483-\u0487\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u0620-\u0649\u0672-\u06d3\u06e7-\u06e8\u06fb-\u06fc\u0730-\u074a\u0800-\u0814\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0840-\u0857\u08e4-\u08fe\u0900-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962-\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09d7\u09df-\u09e0\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a66-\u0a71\u0a75\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2-\u0ae3\u0ae6-\u0aef\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b56\u0b57\u0b5f-\u0b60\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c01-\u0c03\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62-\u0c63\u0c66-\u0c6f\u0c82\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2-\u0ce3\u0ce6-\u0cef\u0d02\u0d03\u0d46-\u0d48\u0d57\u0d62-\u0d63\u0d66-\u0d6f\u0d82\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0df2\u0df3\u0e34-\u0e3a\u0e40-\u0e45\u0e50-\u0e59\u0eb4-\u0eb9\u0ec8-\u0ecd\u0ed0-\u0ed9\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f41-\u0f47\u0f71-\u0f84\u0f86-\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u1000-\u1029\u1040-\u1049\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f-\u109d\u135d-\u135f\u170e-\u1710\u1720-\u1730\u1740-\u1750\u1772\u1773\u1780-\u17b2\u17dd\u17e0-\u17e9\u180b-\u180d\u1810-\u1819\u1920-\u192b\u1930-\u193b\u1951-\u196d\u19b0-\u19c0\u19c8-\u19c9\u19d0-\u19d9\u1a00-\u1a15\u1a20-\u1a53\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1b46-\u1b4b\u1b50-\u1b59\u1b6b-\u1b73\u1bb0-\u1bb9\u1be6-\u1bf3\u1c00-\u1c22\u1c40-\u1c49\u1c5b-\u1c7d\u1cd0-\u1cd2\u1d00-\u1dbe\u1e01-\u1f15\u200c\u200d\u203f\u2040\u2054\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2d81-\u2d96\u2de0-\u2dff\u3021-\u3028\u3099\u309a\ua640-\ua66d\ua674-\ua67d\ua69f\ua6f0-\ua6f1\ua7f8-\ua800\ua806\ua80b\ua823-\ua827\ua880-\ua881\ua8b4-\ua8c4\ua8d0-\ua8d9\ua8f3-\ua8f7\ua900-\ua909\ua926-\ua92d\ua930-\ua945\ua980-\ua983\ua9b3-\ua9c0\uaa00-\uaa27\uaa40-\uaa41\uaa4c-\uaa4d\uaa50-\uaa59\uaa7b\uaae0-\uaae9\uaaf2-\uaaf3\uabc0-\uabe1\uabec\uabed\uabf0-\uabf9\ufb20-\ufb28\ufe00-\ufe0f\ufe20-\ufe26\ufe33\ufe34\ufe4d-\ufe4f\uff10-\uff19\uff3f&quot;</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">nonASCIIidentifierStart</span> <span class="o">=</span> <span class="k">new</span> <span class="nb">RegExp</span><span class="p">(</span><span class="s2">&quot;[&quot;</span> <span class="o">+</span> <span class="nx">nonASCIIidentifierStartChars</span> <span class="o">+</span> <span class="s2">&quot;]&quot;</span><span class="p">);</span>
<span class="kd">var</span> <span class="nx">nonASCIIidentifier</span> <span class="o">=</span> <span class="k">new</span> <span class="nb">RegExp</span><span class="p">(</span><span class="s2">&quot;[&quot;</span> <span class="o">+</span> <span class="nx">nonASCIIidentifierStartChars</span> <span class="o">+</span> <span class="nx">nonASCIIidentifierChars</span> <span class="o">+</span> <span class="s2">&quot;]&quot;</span><span class="p">);</span></pre></div> </td> </tr> <tr id="section-45"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-45">&#182;</a> </div> <p>Whether a single character denotes a newline.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">newline</span> <span class="o">=</span> <span class="sr">/[\n\r\u2028\u2029]/</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-46"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-46">&#182;</a> </div> <p>Matches a whole line break (where CRLF is considered a single
line break). Used to count lines.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">lineBreak</span> <span class="o">=</span> <span class="sr">/\r\n|[\n\r\u2028\u2029]/g</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-47"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-47">&#182;</a> </div> <p>Test whether a given character code starts an identifier.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">isIdentifierStart</span><span class="p">(</span><span class="nx">code</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">code</span> <span class="o">&lt;</span> <span class="mi">65</span><span class="p">)</span> <span class="k">return</span> <span class="nx">code</span> <span class="o">===</span> <span class="mi">36</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">code</span> <span class="o">&lt;</span> <span class="mi">91</span><span class="p">)</span> <span class="k">return</span> <span class="kc">true</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">code</span> <span class="o">&lt;</span> <span class="mi">97</span><span class="p">)</span> <span class="k">return</span> <span class="nx">code</span> <span class="o">===</span> <span class="mi">95</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">code</span> <span class="o">&lt;</span> <span class="mi">123</span><span class="p">)</span><span class="k">return</span> <span class="kc">true</span><span class="p">;</span>
<span class="k">return</span> <span class="nx">code</span> <span class="o">&gt;=</span> <span class="mh">0xaa</span> <span class="o">&amp;&amp;</span> <span class="nx">nonASCIIidentifierStart</span><span class="p">.</span><span class="nx">test</span><span class="p">(</span><span class="nb">String</span><span class="p">.</span><span class="nx">fromCharCode</span><span class="p">(</span><span class="nx">code</span><span class="p">));</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-48"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-48">&#182;</a> </div> <p>Test whether a given character is part of an identifier.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">isIdentifierChar</span><span class="p">(</span><span class="nx">code</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">code</span> <span class="o">&lt;</span> <span class="mi">48</span><span class="p">)</span> <span class="k">return</span> <span class="nx">code</span> <span class="o">===</span> <span class="mi">36</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">code</span> <span class="o">&lt;</span> <span class="mi">58</span><span class="p">)</span> <span class="k">return</span> <span class="kc">true</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">code</span> <span class="o">&lt;</span> <span class="mi">65</span><span class="p">)</span> <span class="k">return</span> <span class="kc">false</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">code</span> <span class="o">&lt;</span> <span class="mi">91</span><span class="p">)</span> <span class="k">return</span> <span class="kc">true</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">code</span> <span class="o">&lt;</span> <span class="mi">97</span><span class="p">)</span> <span class="k">return</span> <span class="nx">code</span> <span class="o">===</span> <span class="mi">95</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">code</span> <span class="o">&lt;</span> <span class="mi">123</span><span class="p">)</span><span class="k">return</span> <span class="kc">true</span><span class="p">;</span>
<span class="k">return</span> <span class="nx">code</span> <span class="o">&gt;=</span> <span class="mh">0xaa</span> <span class="o">&amp;&amp;</span> <span class="nx">nonASCIIidentifier</span><span class="p">.</span><span class="nx">test</span><span class="p">(</span><span class="nb">String</span><span class="p">.</span><span class="nx">fromCharCode</span><span class="p">(</span><span class="nx">code</span><span class="p">));</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-49"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-49">&#182;</a> </div> <h2>Tokenizer</h2> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-50"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-50">&#182;</a> </div> <p>These are used when <code>options.locations</code> is on, in order to track
the current line number and start of line offset, in order to set
<code>tokStartLoc</code> and <code>tokEndLoc</code>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">nextLineStart</span><span class="p">()</span> <span class="p">{</span>
<span class="nx">lineBreak</span><span class="p">.</span><span class="nx">lastIndex</span> <span class="o">=</span> <span class="nx">tokLineStart</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">match</span> <span class="o">=</span> <span class="nx">lineBreak</span><span class="p">.</span><span class="nx">exec</span><span class="p">(</span><span class="nx">input</span><span class="p">);</span>
<span class="k">return</span> <span class="nx">match</span> <span class="o">?</span> <span class="nx">match</span><span class="p">.</span><span class="nx">index</span> <span class="o">+</span> <span class="nx">match</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nx">length</span> <span class="o">:</span> <span class="nx">input</span><span class="p">.</span><span class="nx">length</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span>
<span class="p">}</span>
<span class="kd">function</span> <span class="nx">curLineLoc</span><span class="p">()</span> <span class="p">{</span>
<span class="k">while</span> <span class="p">(</span><span class="nx">tokLineStartNext</span> <span class="o">&lt;=</span> <span class="nx">tokPos</span><span class="p">)</span> <span class="p">{</span>
<span class="o">++</span><span class="nx">tokCurLine</span><span class="p">;</span>
<span class="nx">tokLineStart</span> <span class="o">=</span> <span class="nx">tokLineStartNext</span><span class="p">;</span>
<span class="nx">tokLineStartNext</span> <span class="o">=</span> <span class="nx">nextLineStart</span><span class="p">();</span>
<span class="p">}</span>
<span class="k">return</span> <span class="p">{</span><span class="nx">line</span><span class="o">:</span> <span class="nx">tokCurLine</span><span class="p">,</span> <span class="nx">column</span><span class="o">:</span> <span class="nx">tokPos</span> <span class="o">-</span> <span class="nx">tokLineStart</span><span class="p">};</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-51"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-51">&#182;</a> </div> <p>Reset the token state. Used at the start of a parse.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">initTokenState</span><span class="p">()</span> <span class="p">{</span>
<span class="nx">tokCurLine</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
<span class="nx">tokPos</span> <span class="o">=</span> <span class="nx">tokLineStart</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="nx">tokLineStartNext</span> <span class="o">=</span> <span class="nx">nextLineStart</span><span class="p">();</span>
<span class="nx">tokRegexpAllowed</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
<span class="nx">tokComments</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span>
<span class="nx">skipSpace</span><span class="p">();</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-52"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-52">&#182;</a> </div> <p>Called at the end of every token. Sets <code>tokEnd</code>, <code>tokVal</code>,
<code>tokCommentsAfter</code>, and <code>tokRegexpAllowed</code>, and skips the space
after the token, so that the next one's <code>tokStart</code> will point at
the right position.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">finishToken</span><span class="p">(</span><span class="nx">type</span><span class="p">,</span> <span class="nx">val</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">tokEnd</span> <span class="o">=</span> <span class="nx">tokPos</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">locations</span><span class="p">)</span> <span class="nx">tokEndLoc</span> <span class="o">=</span> <span class="nx">curLineLoc</span><span class="p">();</span>
<span class="nx">tokType</span> <span class="o">=</span> <span class="nx">type</span><span class="p">;</span>
<span class="nx">skipSpace</span><span class="p">();</span>
<span class="nx">tokVal</span> <span class="o">=</span> <span class="nx">val</span><span class="p">;</span>
<span class="nx">tokCommentsAfter</span> <span class="o">=</span> <span class="nx">tokComments</span><span class="p">;</span>
<span class="nx">tokRegexpAllowed</span> <span class="o">=</span> <span class="nx">type</span><span class="p">.</span><span class="nx">beforeExpr</span><span class="p">;</span>
<span class="p">}</span>
<span class="kd">function</span> <span class="nx">skipBlockComment</span><span class="p">()</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">end</span> <span class="o">=</span> <span class="nx">input</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="s2">&quot;*/&quot;</span><span class="p">,</span> <span class="nx">tokPos</span> <span class="o">+=</span> <span class="mi">2</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">end</span> <span class="o">===</span> <span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="nx">raise</span><span class="p">(</span><span class="nx">tokPos</span> <span class="o">-</span> <span class="mi">2</span><span class="p">,</span> <span class="s2">&quot;Unterminated comment&quot;</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">trackComments</span><span class="p">)</span>
<span class="p">(</span><span class="nx">tokComments</span> <span class="o">||</span> <span class="p">(</span><span class="nx">tokComments</span> <span class="o">=</span> <span class="p">[])).</span><span class="nx">push</span><span class="p">(</span><span class="nx">input</span><span class="p">.</span><span class="nx">slice</span><span class="p">(</span><span class="nx">tokPos</span><span class="p">,</span> <span class="nx">end</span><span class="p">));</span>
<span class="nx">tokPos</span> <span class="o">=</span> <span class="nx">end</span> <span class="o">+</span> <span class="mi">2</span><span class="p">;</span>
<span class="p">}</span>
<span class="kd">function</span> <span class="nx">skipLineComment</span><span class="p">()</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">start</span> <span class="o">=</span> <span class="nx">tokPos</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">ch</span> <span class="o">=</span> <span class="nx">input</span><span class="p">.</span><span class="nx">charCodeAt</span><span class="p">(</span><span class="nx">tokPos</span><span class="o">+=</span><span class="mi">2</span><span class="p">);</span>
<span class="k">while</span> <span class="p">(</span><span class="nx">tokPos</span> <span class="o">&lt;</span> <span class="nx">inputLen</span> <span class="o">&amp;&amp;</span> <span class="nx">ch</span> <span class="o">!==</span> <span class="mi">10</span> <span class="o">&amp;&amp;</span> <span class="nx">ch</span> <span class="o">!==</span> <span class="mi">13</span> <span class="o">&amp;&amp;</span> <span class="nx">ch</span> <span class="o">!==</span> <span class="mi">8232</span> <span class="o">&amp;&amp;</span> <span class="nx">ch</span> <span class="o">!==</span> <span class="mi">8329</span><span class="p">)</span> <span class="p">{</span>
<span class="o">++</span><span class="nx">tokPos</span><span class="p">;</span>
<span class="nx">ch</span> <span class="o">=</span> <span class="nx">input</span><span class="p">.</span><span class="nx">charCodeAt</span><span class="p">(</span><span class="nx">tokPos</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">(</span><span class="nx">tokComments</span> <span class="o">||</span> <span class="p">(</span><span class="nx">tokComments</span> <span class="o">=</span> <span class="p">[])).</span><span class="nx">push</span><span class="p">(</span><span class="nx">input</span><span class="p">.</span><span class="nx">slice</span><span class="p">(</span><span class="nx">start</span><span class="p">,</span> <span class="nx">tokPos</span><span class="p">));</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-53"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-53">&#182;</a> </div> <p>Called at the start of the parse and after every token. Skips
whitespace and comments, and, if <code>options.trackComments</code> is on,
will store all skipped comments in <code>tokComments</code>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">skipSpace</span><span class="p">()</span> <span class="p">{</span>
<span class="nx">tokComments</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span>
<span class="k">while</span> <span class="p">(</span><span class="nx">tokPos</span> <span class="o">&lt;</span> <span class="nx">inputLen</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">ch</span> <span class="o">=</span> <span class="nx">input</span><span class="p">.</span><span class="nx">charCodeAt</span><span class="p">(</span><span class="nx">tokPos</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">ch</span> <span class="o">===</span> <span class="mi">47</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// &#39;/&#39;</span>
<span class="kd">var</span> <span class="nx">next</span> <span class="o">=</span> <span class="nx">input</span><span class="p">.</span><span class="nx">charCodeAt</span><span class="p">(</span><span class="nx">tokPos</span><span class="o">+</span><span class="mi">1</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">next</span> <span class="o">===</span> <span class="mi">42</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// &#39;*&#39;</span>
<span class="nx">skipBlockComment</span><span class="p">();</span>
<span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">next</span> <span class="o">===</span> <span class="mi">47</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// &#39;/&#39;</span>
<span class="nx">skipLineComment</span><span class="p">();</span>
<span class="p">}</span> <span class="k">else</span> <span class="k">break</span><span class="p">;</span>
<span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">ch</span> <span class="o">&lt;</span> <span class="mi">14</span> <span class="o">&amp;&amp;</span> <span class="nx">ch</span> <span class="o">&gt;</span> <span class="mi">8</span><span class="p">)</span> <span class="p">{</span>
<span class="o">++</span><span class="nx">tokPos</span><span class="p">;</span>
<span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">ch</span> <span class="o">===</span> <span class="mi">32</span> <span class="o">||</span> <span class="nx">ch</span> <span class="o">===</span> <span class="mi">160</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// &#39; &#39;, &#39;\xa0&#39;</span>
<span class="o">++</span><span class="nx">tokPos</span><span class="p">;</span>
<span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">ch</span> <span class="o">&gt;=</span> <span class="mi">5760</span> <span class="o">&amp;&amp;</span> <span class="nx">nonASCIIwhitespace</span><span class="p">.</span><span class="nx">test</span><span class="p">(</span><span class="nb">String</span><span class="p">.</span><span class="nx">fromCharCode</span><span class="p">(</span><span class="nx">ch</span><span class="p">)))</span> <span class="p">{</span>
<span class="o">++</span><span class="nx">tokPos</span><span class="p">;</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="k">break</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-54"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-54">&#182;</a> </div> <h3>Token reading</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-55"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-55">&#182;</a> </div> <p>This is the function that is called to fetch the next token. It
is somewhat obscure, because it works in character codes rather
than characters, and because operator parsing has been inlined
into it.</p>
<p>All in the name of speed.</p>
<p>The <code>forceRegexp</code> parameter is used in the one case where the
<code>tokRegexpAllowed</code> trick does not work. See <code>parseStatement</code>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">readToken</span><span class="p">(</span><span class="nx">forceRegexp</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">tokStart</span> <span class="o">=</span> <span class="nx">tokPos</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">locations</span><span class="p">)</span> <span class="nx">tokStartLoc</span> <span class="o">=</span> <span class="nx">curLineLoc</span><span class="p">();</span>
<span class="nx">tokCommentsBefore</span> <span class="o">=</span> <span class="nx">tokComments</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">forceRegexp</span><span class="p">)</span> <span class="k">return</span> <span class="nx">readRegexp</span><span class="p">();</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">tokPos</span> <span class="o">&gt;=</span> <span class="nx">inputLen</span><span class="p">)</span> <span class="k">return</span> <span class="nx">finishToken</span><span class="p">(</span><span class="nx">_eof</span><span class="p">);</span>
<span class="kd">var</span> <span class="nx">code</span> <span class="o">=</span> <span class="nx">input</span><span class="p">.</span><span class="nx">charCodeAt</span><span class="p">(</span><span class="nx">tokPos</span><span class="p">);</span></pre></div> </td> </tr> <tr id="section-56"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-56">&#182;</a> </div> <p>Identifier or keyword. '\uXXXX' sequences are allowed in
identifiers, so '\' also dispatches to that.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span> <span class="p">(</span><span class="nx">isIdentifierStart</span><span class="p">(</span><span class="nx">code</span><span class="p">)</span> <span class="o">||</span> <span class="nx">code</span> <span class="o">===</span> <span class="mi">92</span> <span class="cm">/* &#39;\&#39; */</span><span class="p">)</span> <span class="k">return</span> <span class="nx">readWord</span><span class="p">();</span>
<span class="kd">var</span> <span class="nx">next</span> <span class="o">=</span> <span class="nx">input</span><span class="p">.</span><span class="nx">charCodeAt</span><span class="p">(</span><span class="nx">tokPos</span><span class="o">+</span><span class="mi">1</span><span class="p">);</span>
<span class="k">switch</span><span class="p">(</span><span class="nx">code</span><span class="p">)</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-57"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-57">&#182;</a> </div> <p>The interpretation of a dot depends on whether it is followed
by a digit.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">case</span> <span class="mi">46</span><span class="o">:</span> <span class="c1">// &#39;.&#39;</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">next</span> <span class="o">&gt;=</span> <span class="mi">48</span> <span class="o">&amp;&amp;</span> <span class="nx">next</span> <span class="o">&lt;=</span> <span class="mi">57</span><span class="p">)</span> <span class="k">return</span> <span class="nx">readNumber</span><span class="p">(</span><span class="nb">String</span><span class="p">.</span><span class="nx">fromCharCode</span><span class="p">(</span><span class="nx">code</span><span class="p">));</span>
<span class="o">++</span><span class="nx">tokPos</span><span class="p">;</span>
<span class="k">return</span> <span class="nx">finishToken</span><span class="p">(</span><span class="nx">_dot</span><span class="p">);</span></pre></div> </td> </tr> <tr id="section-58"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-58">&#182;</a> </div> <p>Punctuation tokens.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">case</span> <span class="mi">40</span><span class="o">:</span> <span class="o">++</span><span class="nx">tokPos</span><span class="p">;</span> <span class="k">return</span> <span class="nx">finishToken</span><span class="p">(</span><span class="nx">_parenL</span><span class="p">);</span>
<span class="k">case</span> <span class="mi">41</span><span class="o">:</span> <span class="o">++</span><span class="nx">tokPos</span><span class="p">;</span> <span class="k">return</span> <span class="nx">finishToken</span><span class="p">(</span><span class="nx">_parenR</span><span class="p">);</span>
<span class="k">case</span> <span class="mi">59</span><span class="o">:</span> <span class="o">++</span><span class="nx">tokPos</span><span class="p">;</span> <span class="k">return</span> <span class="nx">finishToken</span><span class="p">(</span><span class="nx">_semi</span><span class="p">);</span>
<span class="k">case</span> <span class="mi">44</span><span class="o">:</span> <span class="o">++</span><span class="nx">tokPos</span><span class="p">;</span> <span class="k">return</span> <span class="nx">finishToken</span><span class="p">(</span><span class="nx">_comma</span><span class="p">);</span>
<span class="k">case</span> <span class="mi">91</span><span class="o">:</span> <span class="o">++</span><span class="nx">tokPos</span><span class="p">;</span> <span class="k">return</span> <span class="nx">finishToken</span><span class="p">(</span><span class="nx">_bracketL</span><span class="p">);</span>
<span class="k">case</span> <span class="mi">93</span><span class="o">:</span> <span class="o">++</span><span class="nx">tokPos</span><span class="p">;</span> <span class="k">return</span> <span class="nx">finishToken</span><span class="p">(</span><span class="nx">_bracketR</span><span class="p">);</span>
<span class="k">case</span> <span class="mi">123</span><span class="o">:</span> <span class="o">++</span><span class="nx">tokPos</span><span class="p">;</span> <span class="k">return</span> <span class="nx">finishToken</span><span class="p">(</span><span class="nx">_braceL</span><span class="p">);</span>
<span class="k">case</span> <span class="mi">125</span><span class="o">:</span> <span class="o">++</span><span class="nx">tokPos</span><span class="p">;</span> <span class="k">return</span> <span class="nx">finishToken</span><span class="p">(</span><span class="nx">_braceR</span><span class="p">);</span>
<span class="k">case</span> <span class="mi">58</span><span class="o">:</span> <span class="o">++</span><span class="nx">tokPos</span><span class="p">;</span> <span class="k">return</span> <span class="nx">finishToken</span><span class="p">(</span><span class="nx">_colon</span><span class="p">);</span>
<span class="k">case</span> <span class="mi">63</span><span class="o">:</span> <span class="o">++</span><span class="nx">tokPos</span><span class="p">;</span> <span class="k">return</span> <span class="nx">finishToken</span><span class="p">(</span><span class="nx">_question</span><span class="p">);</span></pre></div> </td> </tr> <tr id="section-59"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-59">&#182;</a> </div> <p>'0x' is a hexadecimal number.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">case</span> <span class="mi">48</span><span class="o">:</span> <span class="c1">// &#39;0&#39;</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">next</span> <span class="o">===</span> <span class="mi">120</span> <span class="o">||</span> <span class="nx">next</span> <span class="o">===</span> <span class="mi">88</span><span class="p">)</span> <span class="k">return</span> <span class="nx">readHexNumber</span><span class="p">();</span></pre></div> </td> </tr> <tr id="section-60"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-60">&#182;</a> </div> <p>Anything else beginning with a digit is an integer, octal
number, or float.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">case</span> <span class="mi">49</span><span class="o">:</span> <span class="k">case</span> <span class="mi">50</span><span class="o">:</span> <span class="k">case</span> <span class="mi">51</span><span class="o">:</span> <span class="k">case</span> <span class="mi">52</span><span class="o">:</span> <span class="k">case</span> <span class="mi">53</span><span class="o">:</span> <span class="k">case</span> <span class="mi">54</span><span class="o">:</span> <span class="k">case</span> <span class="mi">55</span><span class="o">:</span> <span class="k">case</span> <span class="mi">56</span><span class="o">:</span> <span class="k">case</span> <span class="mi">57</span><span class="o">:</span> <span class="c1">// 1-9</span>
<span class="k">return</span> <span class="nx">readNumber</span><span class="p">(</span><span class="nb">String</span><span class="p">.</span><span class="nx">fromCharCode</span><span class="p">(</span><span class="nx">code</span><span class="p">));</span></pre></div> </td> </tr> <tr id="section-61"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-61">&#182;</a> </div> <p>Quotes produce strings.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">case</span> <span class="mi">34</span><span class="o">:</span> <span class="k">case</span> <span class="mi">39</span><span class="o">:</span> <span class="c1">// &#39;&quot;&#39;, &quot;&#39;&quot;</span>
<span class="k">return</span> <span class="nx">readString</span><span class="p">(</span><span class="nx">code</span><span class="p">);</span></pre></div> </td> </tr> <tr id="section-62"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-62">&#182;</a> </div> <p>Operators are parsed inline in tiny state machines. '=' (61) is
often referred to. <code>finishOp</code> simply skips the amount of
characters it is given as second argument, and returns a token
of the type given by its first argument.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">case</span> <span class="mi">47</span><span class="o">:</span> <span class="c1">// &#39;/&#39;</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">tokRegexpAllowed</span><span class="p">)</span> <span class="p">{</span><span class="o">++</span><span class="nx">tokPos</span><span class="p">;</span> <span class="k">return</span> <span class="nx">readRegexp</span><span class="p">();}</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">next</span> <span class="o">===</span> <span class="mi">61</span><span class="p">)</span> <span class="k">return</span> <span class="nx">finishOp</span><span class="p">(</span><span class="nx">_assign</span><span class="p">,</span> <span class="mi">2</span><span class="p">);</span>
<span class="k">return</span> <span class="nx">finishOp</span><span class="p">(</span><span class="nx">_slash</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
<span class="k">case</span> <span class="mi">37</span><span class="o">:</span> <span class="k">case</span> <span class="mi">42</span><span class="o">:</span> <span class="c1">// &#39;%*&#39;</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">next</span> <span class="o">===</span> <span class="mi">61</span><span class="p">)</span> <span class="k">return</span> <span class="nx">finishOp</span><span class="p">(</span><span class="nx">_assign</span><span class="p">,</span> <span class="mi">2</span><span class="p">);</span>
<span class="k">return</span> <span class="nx">finishOp</span><span class="p">(</span><span class="nx">_bin10</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
<span class="k">case</span> <span class="mi">124</span><span class="o">:</span> <span class="k">case</span> <span class="mi">38</span><span class="o">:</span> <span class="c1">// &#39;|&amp;&#39;</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">next</span> <span class="o">===</span> <span class="nx">code</span><span class="p">)</span> <span class="k">return</span> <span class="nx">finishOp</span><span class="p">(</span><span class="nx">code</span> <span class="o">===</span> <span class="mi">124</span> <span class="o">?</span> <span class="nx">_bin1</span> <span class="o">:</span> <span class="nx">_bin2</span><span class="p">,</span> <span class="mi">2</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">next</span> <span class="o">===</span> <span class="mi">61</span><span class="p">)</span> <span class="k">return</span> <span class="nx">finishOp</span><span class="p">(</span><span class="nx">_assign</span><span class="p">,</span> <span class="mi">2</span><span class="p">);</span>
<span class="k">return</span> <span class="nx">finishOp</span><span class="p">(</span><span class="nx">code</span> <span class="o">===</span> <span class="mi">124</span> <span class="o">?</span> <span class="nx">_bin3</span> <span class="o">:</span> <span class="nx">_bin5</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
<span class="k">case</span> <span class="mi">94</span><span class="o">:</span> <span class="c1">// &#39;^&#39;</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">next</span> <span class="o">===</span> <span class="mi">61</span><span class="p">)</span> <span class="k">return</span> <span class="nx">finishOp</span><span class="p">(</span><span class="nx">_assign</span><span class="p">,</span> <span class="mi">2</span><span class="p">);</span>
<span class="k">return</span> <span class="nx">finishOp</span><span class="p">(</span><span class="nx">_bin4</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
<span class="k">case</span> <span class="mi">43</span><span class="o">:</span> <span class="k">case</span> <span class="mi">45</span><span class="o">:</span> <span class="c1">// &#39;+-&#39;</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">next</span> <span class="o">===</span> <span class="nx">code</span><span class="p">)</span> <span class="k">return</span> <span class="nx">finishOp</span><span class="p">(</span><span class="nx">_incdec</span><span class="p">,</span> <span class="mi">2</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">next</span> <span class="o">===</span> <span class="mi">61</span><span class="p">)</span> <span class="k">return</span> <span class="nx">finishOp</span><span class="p">(</span><span class="nx">_assign</span><span class="p">,</span> <span class="mi">2</span><span class="p">);</span>
<span class="k">return</span> <span class="nx">finishOp</span><span class="p">(</span><span class="nx">_plusmin</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
<span class="k">case</span> <span class="mi">60</span><span class="o">:</span> <span class="k">case</span> <span class="mi">62</span><span class="o">:</span> <span class="c1">// &#39;&lt;&gt;&#39;</span>
<span class="kd">var</span> <span class="nx">size</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">next</span> <span class="o">===</span> <span class="nx">code</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">size</span> <span class="o">=</span> <span class="nx">code</span> <span class="o">===</span> <span class="mi">62</span> <span class="o">&amp;&amp;</span> <span class="nx">input</span><span class="p">.</span><span class="nx">charCodeAt</span><span class="p">(</span><span class="nx">tokPos</span><span class="o">+</span><span class="mi">2</span><span class="p">)</span> <span class="o">===</span> <span class="mi">62</span> <span class="o">?</span> <span class="mi">3</span> <span class="o">:</span> <span class="mi">2</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">input</span><span class="p">.</span><span class="nx">charCodeAt</span><span class="p">(</span><span class="nx">tokPos</span> <span class="o">+</span> <span class="nx">size</span><span class="p">)</span> <span class="o">===</span> <span class="mi">61</span><span class="p">)</span> <span class="k">return</span> <span class="nx">finishOp</span><span class="p">(</span><span class="nx">_assign</span><span class="p">,</span> <span class="nx">size</span> <span class="o">+</span> <span class="mi">1</span><span class="p">);</span>
<span class="k">return</span> <span class="nx">finishOp</span><span class="p">(</span><span class="nx">_bin8</span><span class="p">,</span> <span class="nx">size</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">next</span> <span class="o">===</span> <span class="mi">61</span><span class="p">)</span>
<span class="nx">size</span> <span class="o">=</span> <span class="nx">input</span><span class="p">.</span><span class="nx">charCodeAt</span><span class="p">(</span><span class="nx">tokPos</span><span class="o">+</span><span class="mi">2</span><span class="p">)</span> <span class="o">===</span> <span class="mi">61</span> <span class="o">?</span> <span class="mi">3</span> <span class="o">:</span> <span class="mi">2</span><span class="p">;</span>
<span class="k">return</span> <span class="nx">finishOp</span><span class="p">(</span><span class="nx">_bin7</span><span class="p">,</span> <span class="nx">size</span><span class="p">);</span>
<span class="k">case</span> <span class="mi">61</span><span class="o">:</span> <span class="k">case</span> <span class="mi">33</span><span class="o">:</span> <span class="c1">// &#39;=!&#39;</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">next</span> <span class="o">===</span> <span class="mi">61</span><span class="p">)</span> <span class="k">return</span> <span class="nx">finishOp</span><span class="p">(</span><span class="nx">_bin6</span><span class="p">,</span> <span class="nx">input</span><span class="p">.</span><span class="nx">charCodeAt</span><span class="p">(</span><span class="nx">tokPos</span><span class="o">+</span><span class="mi">2</span><span class="p">)</span> <span class="o">===</span> <span class="mi">61</span> <span class="o">?</span> <span class="mi">3</span> <span class="o">:</span> <span class="mi">2</span><span class="p">);</span>
<span class="k">return</span> <span class="nx">finishOp</span><span class="p">(</span><span class="nx">code</span> <span class="o">===</span> <span class="mi">61</span> <span class="o">?</span> <span class="nx">_eq</span> <span class="o">:</span> <span class="nx">_prefix</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
<span class="k">case</span> <span class="mi">126</span><span class="o">:</span> <span class="c1">// &#39;~&#39;</span>
<span class="k">return</span> <span class="nx">finishOp</span><span class="p">(</span><span class="nx">_prefix</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-63"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-63">&#182;</a> </div> <p>If we are here, we either found a non-ASCII identifier
character, or something that's entirely disallowed.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">ch</span> <span class="o">=</span> <span class="nb">String</span><span class="p">.</span><span class="nx">fromCharCode</span><span class="p">(</span><span class="nx">code</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">ch</span> <span class="o">===</span> <span class="s2">&quot;\\&quot;</span> <span class="o">||</span> <span class="nx">nonASCIIidentifierStart</span><span class="p">.</span><span class="nx">test</span><span class="p">(</span><span class="nx">ch</span><span class="p">))</span> <span class="k">return</span> <span class="nx">readWord</span><span class="p">();</span>
<span class="nx">raise</span><span class="p">(</span><span class="nx">tokPos</span><span class="p">,</span> <span class="s2">&quot;Unexpected character &#39;&quot;</span> <span class="o">+</span> <span class="nx">ch</span> <span class="o">+</span> <span class="s2">&quot;&#39;&quot;</span><span class="p">);</span>
<span class="p">}</span>
<span class="kd">function</span> <span class="nx">finishOp</span><span class="p">(</span><span class="nx">type</span><span class="p">,</span> <span class="nx">size</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">str</span> <span class="o">=</span> <span class="nx">input</span><span class="p">.</span><span class="nx">slice</span><span class="p">(</span><span class="nx">tokPos</span><span class="p">,</span> <span class="nx">tokPos</span> <span class="o">+</span> <span class="nx">size</span><span class="p">);</span>
<span class="nx">tokPos</span> <span class="o">+=</span> <span class="nx">size</span><span class="p">;</span>
<span class="nx">finishToken</span><span class="p">(</span><span class="nx">type</span><span class="p">,</span> <span class="nx">str</span><span class="p">);</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-64"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-64">&#182;</a> </div> <p>Parse a regular expression. Some context-awareness is necessary,
since a '/' inside a '[]' set does not end the expression.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">readRegexp</span><span class="p">()</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">content</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span><span class="p">,</span> <span class="nx">escaped</span><span class="p">,</span> <span class="nx">inClass</span><span class="p">,</span> <span class="nx">start</span> <span class="o">=</span> <span class="nx">tokPos</span><span class="p">;</span>
<span class="k">for</span> <span class="p">(;;)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">tokPos</span> <span class="o">&gt;=</span> <span class="nx">inputLen</span><span class="p">)</span> <span class="nx">raise</span><span class="p">(</span><span class="nx">start</span><span class="p">,</span> <span class="s2">&quot;Unterminated regular expression&quot;</span><span class="p">);</span>
<span class="kd">var</span> <span class="nx">ch</span> <span class="o">=</span> <span class="nx">input</span><span class="p">.</span><span class="nx">charAt</span><span class="p">(</span><span class="nx">tokPos</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">newline</span><span class="p">.</span><span class="nx">test</span><span class="p">(</span><span class="nx">ch</span><span class="p">))</span> <span class="nx">raise</span><span class="p">(</span><span class="nx">start</span><span class="p">,</span> <span class="s2">&quot;Unterminated regular expression&quot;</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">escaped</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">ch</span> <span class="o">===</span> <span class="s2">&quot;[&quot;</span><span class="p">)</span> <span class="nx">inClass</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
<span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">ch</span> <span class="o">===</span> <span class="s2">&quot;]&quot;</span> <span class="o">&amp;&amp;</span> <span class="nx">inClass</span><span class="p">)</span> <span class="nx">inClass</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
<span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">ch</span> <span class="o">===</span> <span class="s2">&quot;/&quot;</span> <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="nx">inClass</span><span class="p">)</span> <span class="k">break</span><span class="p">;</span>
<span class="nx">escaped</span> <span class="o">=</span> <span class="nx">ch</span> <span class="o">===</span> <span class="s2">&quot;\\&quot;</span><span class="p">;</span>
<span class="p">}</span> <span class="k">else</span> <span class="nx">escaped</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
<span class="o">++</span><span class="nx">tokPos</span><span class="p">;</span>
<span class="p">}</span>
<span class="kd">var</span> <span class="nx">content</span> <span class="o">=</span> <span class="nx">input</span><span class="p">.</span><span class="nx">slice</span><span class="p">(</span><span class="nx">start</span><span class="p">,</span> <span class="nx">tokPos</span><span class="p">);</span>
<span class="o">++</span><span class="nx">tokPos</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-65"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-65">&#182;</a> </div> <p>Need to use <code>readWord1</code> because '\uXXXX' sequences are allowed
here (don't ask).</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">mods</span> <span class="o">=</span> <span class="nx">readWord1</span><span class="p">();</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">mods</span> <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="sr">/^[gmsiy]*$/</span><span class="p">.</span><span class="nx">test</span><span class="p">(</span><span class="nx">mods</span><span class="p">))</span> <span class="nx">raise</span><span class="p">(</span><span class="nx">start</span><span class="p">,</span> <span class="s2">&quot;Invalid regexp flag&quot;</span><span class="p">);</span>
<span class="k">return</span> <span class="nx">finishToken</span><span class="p">(</span><span class="nx">_regexp</span><span class="p">,</span> <span class="k">new</span> <span class="nb">RegExp</span><span class="p">(</span><span class="nx">content</span><span class="p">,</span> <span class="nx">mods</span><span class="p">));</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-66"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-66">&#182;</a> </div> <p>Read an integer in the given radix. Return null if zero digits
were read, the integer value otherwise. When <code>len</code> is given, this
will return <code>null</code> unless the integer has exactly <code>len</code> digits.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">readInt</span><span class="p">(</span><span class="nx">radix</span><span class="p">,</span> <span class="nx">len</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">start</span> <span class="o">=</span> <span class="nx">tokPos</span><span class="p">,</span> <span class="nx">total</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="k">for</span> <span class="p">(;;)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">code</span> <span class="o">=</span> <span class="nx">input</span><span class="p">.</span><span class="nx">charCodeAt</span><span class="p">(</span><span class="nx">tokPos</span><span class="p">),</span> <span class="nx">val</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">code</span> <span class="o">&gt;=</span> <span class="mi">97</span><span class="p">)</span> <span class="nx">val</span> <span class="o">=</span> <span class="nx">code</span> <span class="o">-</span> <span class="mi">97</span> <span class="o">+</span> <span class="mi">10</span><span class="p">;</span> <span class="c1">// a</span>
<span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">code</span> <span class="o">&gt;=</span> <span class="mi">65</span><span class="p">)</span> <span class="nx">val</span> <span class="o">=</span> <span class="nx">code</span> <span class="o">-</span> <span class="mi">65</span> <span class="o">+</span> <span class="mi">10</span><span class="p">;</span> <span class="c1">// A</span>
<span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">code</span> <span class="o">&gt;=</span> <span class="mi">48</span> <span class="o">&amp;&amp;</span> <span class="nx">code</span> <span class="o">&lt;=</span> <span class="mi">57</span><span class="p">)</span> <span class="nx">val</span> <span class="o">=</span> <span class="nx">code</span> <span class="o">-</span> <span class="mi">48</span><span class="p">;</span> <span class="c1">// 0-9</span>
<span class="k">else</span> <span class="nx">val</span> <span class="o">=</span> <span class="kc">Infinity</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">val</span> <span class="o">&gt;=</span> <span class="nx">radix</span><span class="p">)</span> <span class="k">break</span><span class="p">;</span>
<span class="o">++</span><span class="nx">tokPos</span><span class="p">;</span>
<span class="nx">total</span> <span class="o">=</span> <span class="nx">total</span> <span class="o">*</span> <span class="nx">radix</span> <span class="o">+</span> <span class="nx">val</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">tokPos</span> <span class="o">===</span> <span class="nx">start</span> <span class="o">||</span> <span class="nx">len</span> <span class="o">!=</span> <span class="kc">null</span> <span class="o">&amp;&amp;</span> <span class="nx">tokPos</span> <span class="o">-</span> <span class="nx">start</span> <span class="o">!==</span> <span class="nx">len</span><span class="p">)</span> <span class="k">return</span> <span class="kc">null</span><span class="p">;</span>
<span class="k">return</span> <span class="nx">total</span><span class="p">;</span>
<span class="p">}</span>
<span class="kd">function</span> <span class="nx">readHexNumber</span><span class="p">()</span> <span class="p">{</span>
<span class="nx">tokPos</span> <span class="o">+=</span> <span class="mi">2</span><span class="p">;</span> <span class="c1">// 0x</span>
<span class="kd">var</span> <span class="nx">val</span> <span class="o">=</span> <span class="nx">readInt</span><span class="p">(</span><span class="mi">16</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">val</span> <span class="o">==</span> <span class="kc">null</span><span class="p">)</span> <span class="nx">raise</span><span class="p">(</span><span class="nx">tokStart</span> <span class="o">+</span> <span class="mi">2</span><span class="p">,</span> <span class="s2">&quot;Expected hexadecimal number&quot;</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">isIdentifierStart</span><span class="p">(</span><span class="nx">input</span><span class="p">.</span><span class="nx">charCodeAt</span><span class="p">(</span><span class="nx">tokPos</span><span class="p">)))</span> <span class="nx">raise</span><span class="p">(</span><span class="nx">tokPos</span><span class="p">,</span> <span class="s2">&quot;Identifier directly after number&quot;</span><span class="p">);</span>
<span class="k">return</span> <span class="nx">finishToken</span><span class="p">(</span><span class="nx">_num</span><span class="p">,</span> <span class="nx">val</span><span class="p">);</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-67"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-67">&#182;</a> </div> <p>Read an integer, octal integer, or floating-point number.</p> </td> <td class="code"> <div class="highlight"><pre>
<span class="kd">function</span> <span class="nx">readNumber</span><span class="p">(</span><span class="nx">ch</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">start</span> <span class="o">=</span> <span class="nx">tokPos</span><span class="p">,</span> <span class="nx">isFloat</span> <span class="o">=</span> <span class="nx">ch</span> <span class="o">===</span> <span class="s2">&quot;.&quot;</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">isFloat</span> <span class="o">&amp;&amp;</span> <span class="nx">readInt</span><span class="p">(</span><span class="mi">10</span><span class="p">)</span> <span class="o">==</span> <span class="kc">null</span><span class="p">)</span> <span class="nx">raise</span><span class="p">(</span><span class="nx">start</span><span class="p">,</span> <span class="s2">&quot;Invalid number&quot;</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">isFloat</span> <span class="o">||</span> <span class="nx">input</span><span class="p">.</span><span class="nx">charAt</span><span class="p">(</span><span class="nx">tokPos</span><span class="p">)</span> <span class="o">===</span> <span class="s2">&quot;.&quot;</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">next</span> <span class="o">=</span> <span class="nx">input</span><span class="p">.</span><span class="nx">charAt</span><span class="p">(</span><span class="o">++</span><span class="nx">tokPos</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">next</span> <span class="o">===</span> <span class="s2">&quot;-&quot;</span> <span class="o">||</span> <span class="nx">next</span> <span class="o">===</span> <span class="s2">&quot;+&quot;</span><span class="p">)</span> <span class="o">++</span><span class="nx">tokPos</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">readInt</span><span class="p">(</span><span class="mi">10</span><span class="p">)</span> <span class="o">===</span> <span class="kc">null</span> <span class="o">&amp;&amp;</span> <span class="nx">ch</span> <span class="o">===</span> <span class="s2">&quot;.&quot;</span><span class="p">)</span> <span class="nx">raise</span><span class="p">(</span><span class="nx">start</span><span class="p">,</span> <span class="s2">&quot;Invalid number&quot;</span><span class="p">);</span>
<span class="nx">isFloat</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">if</span> <span class="p">(</span><span class="sr">/e/i</span><span class="p">.</span><span class="nx">test</span><span class="p">(</span><span class="nx">input</span><span class="p">.</span><span class="nx">charAt</span><span class="p">(</span><span class="nx">tokPos</span><span class="p">)))</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">next</span> <span class="o">=</span> <span class="nx">input</span><span class="p">.</span><span class="nx">charAt</span><span class="p">(</span><span class="o">++</span><span class="nx">tokPos</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">next</span> <span class="o">===</span> <span class="s2">&quot;-&quot;</span> <span class="o">||</span> <span class="nx">next</span> <span class="o">===</span> <span class="s2">&quot;+&quot;</span><span class="p">)</span> <span class="o">++</span><span class="nx">tokPos</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">readInt</span><span class="p">(</span><span class="mi">10</span><span class="p">)</span> <span class="o">===</span> <span class="kc">null</span><span class="p">)</span> <span class="nx">raise</span><span class="p">(</span><span class="nx">start</span><span class="p">,</span> <span class="s2">&quot;Invalid number&quot;</span><span class="p">)</span>
<span class="nx">isFloat</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">isIdentifierStart</span><span class="p">(</span><span class="nx">input</span><span class="p">.</span><span class="nx">charCodeAt</span><span class="p">(</span><span class="nx">tokPos</span><span class="p">)))</span> <span class="nx">raise</span><span class="p">(</span><span class="nx">tokPos</span><span class="p">,</span> <span class="s2">&quot;Identifier directly after number&quot;</span><span class="p">);</span>
<span class="kd">var</span> <span class="nx">str</span> <span class="o">=</span> <span class="nx">input</span><span class="p">.</span><span class="nx">slice</span><span class="p">(</span><span class="nx">start</span><span class="p">,</span> <span class="nx">tokPos</span><span class="p">),</span> <span class="nx">val</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">isFloat</span><span class="p">)</span> <span class="nx">val</span> <span class="o">=</span> <span class="nb">parseFloat</span><span class="p">(</span><span class="nx">str</span><span class="p">);</span>
<span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">ch</span> <span class="o">!==</span> <span class="s2">&quot;0&quot;</span> <span class="o">||</span> <span class="nx">str</span><span class="p">.</span><span class="nx">length</span> <span class="o">===</span> <span class="mi">1</span><span class="p">)</span> <span class="nx">val</span> <span class="o">=</span> <span class="nb">parseInt</span><span class="p">(</span><span class="nx">str</span><span class="p">,</span> <span class="mi">10</span><span class="p">);</span>
<span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="sr">/[89]/</span><span class="p">.</span><span class="nx">test</span><span class="p">(</span><span class="nx">str</span><span class="p">)</span> <span class="o">||</span> <span class="nx">strict</span><span class="p">)</span> <span class="nx">raise</span><span class="p">(</span><span class="nx">start</span><span class="p">,</span> <span class="s2">&quot;Invalid number&quot;</span><span class="p">);</span>
<span class="k">else</span> <span class="nx">val</span> <span class="o">=</span> <span class="nb">parseInt</span><span class="p">(</span><span class="nx">str</span><span class="p">,</span> <span class="mi">8</span><span class="p">);</span>
<span class="k">return</span> <span class="nx">finishToken</span><span class="p">(</span><span class="nx">_num</span><span class="p">,</span> <span class="nx">val</span><span class="p">);</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-68"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-68">&#182;</a> </div> <p>Read a string value, interpreting backslash-escapes.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">readString</span><span class="p">(</span><span class="nx">quote</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">tokPos</span><span class="o">++</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">str</span> <span class="o">=</span> <span class="p">[];</span>
<span class="k">for</span> <span class="p">(;;)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">tokPos</span> <span class="o">&gt;=</span> <span class="nx">inputLen</span><span class="p">)</span> <span class="nx">raise</span><span class="p">(</span><span class="nx">tokStart</span><span class="p">,</span> <span class="s2">&quot;Unterminated string constant&quot;</span><span class="p">);</span>
<span class="kd">var</span> <span class="nx">ch</span> <span class="o">=</span> <span class="nx">input</span><span class="p">.</span><span class="nx">charCodeAt</span><span class="p">(</span><span class="nx">tokPos</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">ch</span> <span class="o">===</span> <span class="nx">quote</span><span class="p">)</span> <span class="p">{</span>
<span class="o">++</span><span class="nx">tokPos</span><span class="p">;</span>
<span class="k">return</span> <span class="nx">finishToken</span><span class="p">(</span><span class="nx">_string</span><span class="p">,</span> <span class="nb">String</span><span class="p">.</span><span class="nx">fromCharCode</span><span class="p">.</span><span class="nx">apply</span><span class="p">(</span><span class="kc">null</span><span class="p">,</span> <span class="nx">str</span><span class="p">));</span>
<span class="p">}</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">ch</span> <span class="o">===</span> <span class="mi">92</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// &#39;\&#39;</span>
<span class="nx">ch</span> <span class="o">=</span> <span class="nx">input</span><span class="p">.</span><span class="nx">charCodeAt</span><span class="p">(</span><span class="o">++</span><span class="nx">tokPos</span><span class="p">);</span>
<span class="kd">var</span> <span class="nx">octal</span> <span class="o">=</span> <span class="sr">/^[0-7]+/</span><span class="p">.</span><span class="nx">exec</span><span class="p">(</span><span class="nx">input</span><span class="p">.</span><span class="nx">slice</span><span class="p">(</span><span class="nx">tokPos</span><span class="p">,</span> <span class="nx">tokPos</span> <span class="o">+</span> <span class="mi">3</span><span class="p">));</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">octal</span><span class="p">)</span> <span class="nx">octal</span> <span class="o">=</span> <span class="nx">octal</span><span class="p">[</span><span class="mi">0</span><span class="p">];</span>
<span class="k">while</span> <span class="p">(</span><span class="nx">octal</span> <span class="o">&amp;&amp;</span> <span class="nb">parseInt</span><span class="p">(</span><span class="nx">octal</span><span class="p">,</span> <span class="mi">8</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">255</span><span class="p">)</span> <span class="nx">octal</span> <span class="o">=</span> <span class="nx">octal</span><span class="p">.</span><span class="nx">slice</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="nx">octal</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="mi">1</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">octal</span> <span class="o">===</span> <span class="s2">&quot;0&quot;</span><span class="p">)</span> <span class="nx">octal</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span>
<span class="o">++</span><span class="nx">tokPos</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">octal</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">strict</span><span class="p">)</span> <span class="nx">raise</span><span class="p">(</span><span class="nx">tokPos</span> <span class="o">-</span> <span class="mi">2</span><span class="p">,</span> <span class="s2">&quot;Octal literal in strict mode&quot;</span><span class="p">);</span>
<span class="nx">str</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nb">parseInt</span><span class="p">(</span><span class="nx">octal</span><span class="p">,</span> <span class="mi">8</span><span class="p">));</span>
<span class="nx">tokPos</span> <span class="o">+=</span> <span class="nx">octal</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="mi">1</span><span class="p">;</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="k">switch</span> <span class="p">(</span><span class="nx">ch</span><span class="p">)</span> <span class="p">{</span>
<span class="k">case</span> <span class="mi">110</span><span class="o">:</span> <span class="nx">str</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="mi">10</span><span class="p">);</span> <span class="k">break</span><span class="p">;</span> <span class="c1">// &#39;n&#39; -&gt; &#39;\n&#39;</span>
<span class="k">case</span> <span class="mi">114</span><span class="o">:</span> <span class="nx">str</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="mi">13</span><span class="p">);</span> <span class="k">break</span><span class="p">;</span> <span class="c1">// &#39;r&#39; -&gt; &#39;\r&#39;</span>
<span class="k">case</span> <span class="mi">120</span><span class="o">:</span> <span class="nx">str</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">readHexChar</span><span class="p">(</span><span class="mi">2</span><span class="p">));</span> <span class="k">break</span><span class="p">;</span> <span class="c1">// &#39;x&#39;</span>
<span class="k">case</span> <span class="mi">117</span><span class="o">:</span> <span class="nx">str</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">readHexChar</span><span class="p">(</span><span class="mi">4</span><span class="p">));</span> <span class="k">break</span><span class="p">;</span> <span class="c1">// &#39;u&#39;</span>
<span class="k">case</span> <span class="mi">85</span><span class="o">:</span> <span class="nx">str</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">readHexChar</span><span class="p">(</span><span class="mi">8</span><span class="p">));</span> <span class="k">break</span><span class="p">;</span> <span class="c1">// &#39;U&#39;</span>
<span class="k">case</span> <span class="mi">116</span><span class="o">:</span> <span class="nx">str</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="mi">9</span><span class="p">);</span> <span class="k">break</span><span class="p">;</span> <span class="c1">// &#39;t&#39; -&gt; &#39;\t&#39;</span>
<span class="k">case</span> <span class="mi">98</span><span class="o">:</span> <span class="nx">str</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="mi">8</span><span class="p">);</span> <span class="k">break</span><span class="p">;</span> <span class="c1">// &#39;b&#39; -&gt; &#39;\b&#39;</span>
<span class="k">case</span> <span class="mi">118</span><span class="o">:</span> <span class="nx">str</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="mi">11</span><span class="p">);</span> <span class="k">break</span><span class="p">;</span> <span class="c1">// &#39;v&#39; -&gt; &#39;\u000b&#39;</span>
<span class="k">case</span> <span class="mi">102</span><span class="o">:</span> <span class="nx">str</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="mi">12</span><span class="p">);</span> <span class="k">break</span><span class="p">;</span> <span class="c1">// &#39;f&#39; -&gt; &#39;\f&#39;</span>
<span class="k">case</span> <span class="mi">48</span><span class="o">:</span> <span class="nx">str</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span> <span class="k">break</span><span class="p">;</span> <span class="c1">// 0 -&gt; &#39;\0&#39;</span>
<span class="k">case</span> <span class="mi">13</span><span class="o">:</span> <span class="k">if</span> <span class="p">(</span><span class="nx">input</span><span class="p">.</span><span class="nx">charCodeAt</span><span class="p">(</span><span class="nx">tokPos</span><span class="p">)</span> <span class="o">===</span> <span class="mi">10</span><span class="p">)</span> <span class="o">++</span><span class="nx">tokPos</span><span class="p">;</span> <span class="c1">// &#39;\r\n&#39;</span>
<span class="k">case</span> <span class="mi">10</span><span class="o">:</span> <span class="k">break</span><span class="p">;</span> <span class="c1">// &#39; \n&#39;</span>
<span class="k">default</span><span class="o">:</span> <span class="nx">str</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">ch</span><span class="p">);</span> <span class="k">break</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">ch</span> <span class="o">===</span> <span class="mi">13</span> <span class="o">||</span> <span class="nx">ch</span> <span class="o">===</span> <span class="mi">10</span> <span class="o">||</span> <span class="nx">ch</span> <span class="o">===</span> <span class="mi">8232</span> <span class="o">||</span> <span class="nx">ch</span> <span class="o">===</span> <span class="mi">8329</span><span class="p">)</span> <span class="nx">raise</span><span class="p">(</span><span class="nx">tokStart</span><span class="p">,</span> <span class="s2">&quot;Unterminated string constant&quot;</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">ch</span> <span class="o">!==</span> <span class="mi">92</span><span class="p">)</span> <span class="nx">str</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">ch</span><span class="p">);</span> <span class="c1">// &#39;\&#39;</span>
<span class="o">++</span><span class="nx">tokPos</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-69"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-69">&#182;</a> </div> <p>Used to read character escape sequences ('\x', '\u', '\U').</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">readHexChar</span><span class="p">(</span><span class="nx">len</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">n</span> <span class="o">=</span> <span class="nx">readInt</span><span class="p">(</span><span class="mi">16</span><span class="p">,</span> <span class="nx">len</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">n</span> <span class="o">===</span> <span class="kc">null</span><span class="p">)</span> <span class="nx">raise</span><span class="p">(</span><span class="nx">tokStart</span><span class="p">,</span> <span class="s2">&quot;Bad character escape sequence&quot;</span><span class="p">);</span>
<span class="k">return</span> <span class="nx">n</span><span class="p">;</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-70"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-70">&#182;</a> </div> <p>Used to signal to callers of <code>readWord1</code> whether the word
contained any escape sequences. This is needed because words with
escape sequences must not be interpreted as keywords.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">containsEsc</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-71"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-71">&#182;</a> </div> <p>Read an identifier, and return it as a string. Sets <code>containsEsc</code>
to whether the word contained a '\u' escape.</p>
<p>Only builds up the word character-by-character when it actually
containeds an escape, as a micro-optimization.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">readWord1</span><span class="p">()</span> <span class="p">{</span>
<span class="nx">containsEsc</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">word</span><span class="p">,</span> <span class="nx">first</span> <span class="o">=</span> <span class="kc">true</span><span class="p">,</span> <span class="nx">start</span> <span class="o">=</span> <span class="nx">tokPos</span><span class="p">;</span>
<span class="k">for</span> <span class="p">(;;)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">ch</span> <span class="o">=</span> <span class="nx">input</span><span class="p">.</span><span class="nx">charCodeAt</span><span class="p">(</span><span class="nx">tokPos</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">isIdentifierChar</span><span class="p">(</span><span class="nx">ch</span><span class="p">))</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">containsEsc</span><span class="p">)</span> <span class="nx">word</span> <span class="o">+=</span> <span class="nx">input</span><span class="p">.</span><span class="nx">charAt</span><span class="p">(</span><span class="nx">tokPos</span><span class="p">);</span>
<span class="o">++</span><span class="nx">tokPos</span><span class="p">;</span>
<span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">ch</span> <span class="o">===</span> <span class="mi">92</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// &quot;\&quot;</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">containsEsc</span><span class="p">)</span> <span class="nx">word</span> <span class="o">=</span> <span class="nx">input</span><span class="p">.</span><span class="nx">slice</span><span class="p">(</span><span class="nx">start</span><span class="p">,</span> <span class="nx">tokPos</span><span class="p">);</span>
<span class="nx">containsEsc</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">input</span><span class="p">.</span><span class="nx">charCodeAt</span><span class="p">(</span><span class="o">++</span><span class="nx">tokPos</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">117</span><span class="p">)</span> <span class="c1">// &quot;u&quot;</span>
<span class="nx">raise</span><span class="p">(</span><span class="nx">tokPos</span><span class="p">,</span> <span class="s2">&quot;Expecting Unicode escape sequence \\uXXXX&quot;</span><span class="p">);</span>
<span class="o">++</span><span class="nx">tokPos</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">esc</span> <span class="o">=</span> <span class="nx">readHexChar</span><span class="p">(</span><span class="mi">4</span><span class="p">);</span>
<span class="kd">var</span> <span class="nx">escStr</span> <span class="o">=</span> <span class="nb">String</span><span class="p">.</span><span class="nx">fromCharCode</span><span class="p">(</span><span class="nx">esc</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">escStr</span><span class="p">)</span> <span class="nx">raise</span><span class="p">(</span><span class="nx">tokPos</span> <span class="o">-</span> <span class="mi">1</span><span class="p">,</span> <span class="s2">&quot;Invalid Unicode escape&quot;</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="p">(</span><span class="nx">first</span> <span class="o">?</span> <span class="nx">isIdentifierStart</span><span class="p">(</span><span class="nx">esc</span><span class="p">)</span> <span class="o">:</span> <span class="nx">isIdentifierChar</span><span class="p">(</span><span class="nx">esc</span><span class="p">)))</span>
<span class="nx">raise</span><span class="p">(</span><span class="nx">tokPos</span> <span class="o">-</span> <span class="mi">4</span><span class="p">,</span> <span class="s2">&quot;Invalid Unicode escape&quot;</span><span class="p">);</span>
<span class="nx">word</span> <span class="o">+=</span> <span class="nx">escStr</span><span class="p">;</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="k">break</span><span class="p">;</span>
<span class="p">}</span>
<span class="nx">first</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">return</span> <span class="nx">containsEsc</span> <span class="o">?</span> <span class="nx">word</span> <span class="o">:</span> <span class="nx">input</span><span class="p">.</span><span class="nx">slice</span><span class="p">(</span><span class="nx">start</span><span class="p">,</span> <span class="nx">tokPos</span><span class="p">);</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-72"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-72">&#182;</a> </div> <p>Read an identifier or keyword token. Will check for reserved
words when necessary.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">readWord</span><span class="p">()</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">word</span> <span class="o">=</span> <span class="nx">readWord1</span><span class="p">();</span>
<span class="kd">var</span> <span class="nx">type</span> <span class="o">=</span> <span class="nx">_name</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">containsEsc</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">isKeyword</span><span class="p">(</span><span class="nx">word</span><span class="p">))</span> <span class="nx">type</span> <span class="o">=</span> <span class="nx">keywordTypes</span><span class="p">[</span><span class="nx">word</span><span class="p">];</span>
<span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">forbidReserved</span> <span class="o">&amp;&amp;</span>
<span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">ecmaVersion</span> <span class="o">===</span> <span class="mi">3</span> <span class="o">?</span> <span class="nx">isReservedWord3</span> <span class="o">:</span> <span class="nx">isReservedWord5</span><span class="p">)(</span><span class="nx">word</span><span class="p">)</span> <span class="o">||</span>
<span class="nx">strict</span> <span class="o">&amp;&amp;</span> <span class="nx">isStrictReservedWord</span><span class="p">(</span><span class="nx">word</span><span class="p">))</span>
<span class="nx">raise</span><span class="p">(</span><span class="nx">tokStart</span><span class="p">,</span> <span class="s2">&quot;The keyword &#39;&quot;</span> <span class="o">+</span> <span class="nx">word</span> <span class="o">+</span> <span class="s2">&quot;&#39; is reserved&quot;</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">return</span> <span class="nx">finishToken</span><span class="p">(</span><span class="nx">type</span><span class="p">,</span> <span class="nx">word</span><span class="p">);</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-73"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-73">&#182;</a> </div> <h2>Parser</h2> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-74"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-74">&#182;</a> </div> <p>A recursive descent parser operates by defining functions for all
syntactic elements, and recursively calling those, each function
advancing the input stream and returning an AST node. Precedence
of constructs (for example, the fact that <code>!x[1]</code> means <code>!(x[1])</code>
instead of <code>(!x)[1]</code> is handled by the fact that the parser
function that parses unary prefix operators is called first, and
in turn calls the function that parses <code>[]</code> subscripts — that
way, it'll receive the node for <code>x[1]</code> already parsed, and wraps
<em>that</em> in the unary operator node.</p>
<p>Acorn uses an <a href="http://en.wikipedia.org/wiki/Operator-precedence_parser">operator precedence parser</a> to handle binary
operator precedence, because it is much more compact than using
the technique outlined above, which uses different, nesting
functions to specify precedence, for all of the ten binary
precedence levels that JavaScript defines.</p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-75"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-75">&#182;</a> </div> <h3>Parser utilities</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-76"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-76">&#182;</a> </div> <p>Continue to the next token.</p> </td> <td class="code"> <div class="highlight"><pre>
<span class="kd">function</span> <span class="nx">next</span><span class="p">()</span> <span class="p">{</span>
<span class="nx">lastStart</span> <span class="o">=</span> <span class="nx">tokStart</span><span class="p">;</span>
<span class="nx">lastEnd</span> <span class="o">=</span> <span class="nx">tokEnd</span><span class="p">;</span>
<span class="nx">lastEndLoc</span> <span class="o">=</span> <span class="nx">tokEndLoc</span><span class="p">;</span>
<span class="nx">readToken</span><span class="p">();</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-77"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-77">&#182;</a> </div> <p>Enter strict mode. Re-reads the next token to please pedantic
tests ("use strict"; 010; -- should fail).</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">setStrict</span><span class="p">(</span><span class="nx">strct</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">strict</span> <span class="o">=</span> <span class="nx">strct</span><span class="p">;</span>
<span class="nx">tokPos</span> <span class="o">=</span> <span class="nx">lastEnd</span><span class="p">;</span>
<span class="nx">skipSpace</span><span class="p">();</span>
<span class="nx">readToken</span><span class="p">();</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-78"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-78">&#182;</a> </div> <p>Start an AST node, attaching a start offset and optionally a
<code>commentsBefore</code> property to it.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">startNode</span><span class="p">()</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">node</span> <span class="o">=</span> <span class="p">{</span><span class="nx">type</span><span class="o">:</span> <span class="kc">null</span><span class="p">,</span> <span class="nx">start</span><span class="o">:</span> <span class="nx">tokStart</span><span class="p">,</span> <span class="nx">end</span><span class="o">:</span> <span class="kc">null</span><span class="p">};</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">trackComments</span> <span class="o">&amp;&amp;</span> <span class="nx">tokCommentsBefore</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">commentsBefore</span> <span class="o">=</span> <span class="nx">tokCommentsBefore</span><span class="p">;</span>
<span class="nx">tokCommentsBefore</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">locations</span><span class="p">)</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">loc</span> <span class="o">=</span> <span class="p">{</span><span class="nx">start</span><span class="o">:</span> <span class="nx">tokStartLoc</span><span class="p">,</span> <span class="nx">end</span><span class="o">:</span> <span class="kc">null</span><span class="p">,</span> <span class="nx">source</span><span class="o">:</span> <span class="nx">sourceFile</span><span class="p">};</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">ranges</span><span class="p">)</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">range</span> <span class="o">=</span> <span class="p">[</span><span class="nx">tokStart</span><span class="p">,</span> <span class="mi">0</span><span class="p">];</span>
<span class="k">return</span> <span class="nx">node</span><span class="p">;</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-79"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-79">&#182;</a> </div> <p>Start a node whose start offset/comments information should be
based on the start of another node. For example, a binary
operator node is only started after its left-hand side has
already been parsed.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">startNodeFrom</span><span class="p">(</span><span class="nx">other</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">node</span> <span class="o">=</span> <span class="p">{</span><span class="nx">type</span><span class="o">:</span> <span class="kc">null</span><span class="p">,</span> <span class="nx">start</span><span class="o">:</span> <span class="nx">other</span><span class="p">.</span><span class="nx">start</span><span class="p">};</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">other</span><span class="p">.</span><span class="nx">commentsBefore</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">commentsBefore</span> <span class="o">=</span> <span class="nx">other</span><span class="p">.</span><span class="nx">commentsBefore</span><span class="p">;</span>
<span class="nx">other</span><span class="p">.</span><span class="nx">commentsBefore</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">locations</span><span class="p">)</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">loc</span> <span class="o">=</span> <span class="p">{</span><span class="nx">start</span><span class="o">:</span> <span class="nx">other</span><span class="p">.</span><span class="nx">loc</span><span class="p">.</span><span class="nx">start</span><span class="p">,</span> <span class="nx">end</span><span class="o">:</span> <span class="kc">null</span><span class="p">,</span> <span class="nx">source</span><span class="o">:</span> <span class="nx">other</span><span class="p">.</span><span class="nx">loc</span><span class="p">.</span><span class="nx">source</span><span class="p">};</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">ranges</span><span class="p">)</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">range</span> <span class="o">=</span> <span class="p">[</span><span class="nx">other</span><span class="p">.</span><span class="nx">range</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="mi">0</span><span class="p">];</span>
<span class="k">return</span> <span class="nx">node</span><span class="p">;</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-80"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-80">&#182;</a> </div> <p>Finish an AST node, adding <code>type</code>, <code>end</code>, and <code>commentsAfter</code>
properties.</p>
<p>We keep track of the last node that we finished, in order
'bubble' <code>commentsAfter</code> properties up to the biggest node. I.e.
in '`1 + 1 // foo', the comment should be attached to the binary
operator node, not the second literal node.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">lastFinishedNode</span><span class="p">;</span>
<span class="kd">function</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="nx">type</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">type</span> <span class="o">=</span> <span class="nx">type</span><span class="p">;</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">end</span> <span class="o">=</span> <span class="nx">lastEnd</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">trackComments</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">tokCommentsAfter</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">commentsAfter</span> <span class="o">=</span> <span class="nx">tokCommentsAfter</span><span class="p">;</span>
<span class="nx">tokCommentsAfter</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span>
<span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">lastFinishedNode</span> <span class="o">&amp;&amp;</span> <span class="nx">lastFinishedNode</span><span class="p">.</span><span class="nx">end</span> <span class="o">===</span> <span class="nx">lastEnd</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">commentsAfter</span> <span class="o">=</span> <span class="nx">lastFinishedNode</span><span class="p">.</span><span class="nx">commentsAfter</span><span class="p">;</span>
<span class="nx">lastFinishedNode</span><span class="p">.</span><span class="nx">commentsAfter</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span>
<span class="p">}</span>
<span class="nx">lastFinishedNode</span> <span class="o">=</span> <span class="nx">node</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">locations</span><span class="p">)</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">loc</span><span class="p">.</span><span class="nx">end</span> <span class="o">=</span> <span class="nx">lastEndLoc</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">ranges</span><span class="p">)</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">range</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="nx">lastEnd</span><span class="p">;</span>
<span class="k">return</span> <span class="nx">node</span><span class="p">;</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-81"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-81">&#182;</a> </div> <p>Test whether a statement node is the string literal <code>"use strict"</code>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">isUseStrict</span><span class="p">(</span><span class="nx">stmt</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">options</span><span class="p">.</span><span class="nx">ecmaVersion</span> <span class="o">&gt;=</span> <span class="mi">5</span> <span class="o">&amp;&amp;</span> <span class="nx">stmt</span><span class="p">.</span><span class="nx">type</span> <span class="o">===</span> <span class="s2">&quot;ExpressionStatement&quot;</span> <span class="o">&amp;&amp;</span>
<span class="nx">stmt</span><span class="p">.</span><span class="nx">expression</span><span class="p">.</span><span class="nx">type</span> <span class="o">===</span> <span class="s2">&quot;Literal&quot;</span> <span class="o">&amp;&amp;</span> <span class="nx">stmt</span><span class="p">.</span><span class="nx">expression</span><span class="p">.</span><span class="nx">value</span> <span class="o">===</span> <span class="s2">&quot;use strict&quot;</span><span class="p">;</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-82"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-82">&#182;</a> </div> <p>Predicate that tests whether the next token is of the given
type, and if yes, consumes it as a side effect.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">eat</span><span class="p">(</span><span class="nx">type</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">tokType</span> <span class="o">===</span> <span class="nx">type</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">next</span><span class="p">();</span>
<span class="k">return</span> <span class="kc">true</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-83"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-83">&#182;</a> </div> <p>Test whether a semicolon can be inserted at the current position.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">canInsertSemicolon</span><span class="p">()</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">tokType</span> <span class="o">===</span> <span class="nx">_eof</span> <span class="o">||</span> <span class="nx">tokType</span> <span class="o">===</span> <span class="nx">_braceR</span> <span class="o">||</span>
<span class="o">!</span><span class="nx">options</span><span class="p">.</span><span class="nx">strictSemicolons</span> <span class="o">&amp;&amp;</span>
<span class="nx">newline</span><span class="p">.</span><span class="nx">test</span><span class="p">(</span><span class="nx">input</span><span class="p">.</span><span class="nx">slice</span><span class="p">(</span><span class="nx">lastEnd</span><span class="p">,</span> <span class="nx">tokStart</span><span class="p">));</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-84"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-84">&#182;</a> </div> <p>Consume a semicolon, or, failing that, see if we are allowed to
pretend that there is a semicolon at this position.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">semicolon</span><span class="p">()</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">eat</span><span class="p">(</span><span class="nx">_semi</span><span class="p">)</span> <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="nx">canInsertSemicolon</span><span class="p">())</span> <span class="nx">unexpected</span><span class="p">();</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-85"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-85">&#182;</a> </div> <p>Expect a token of a given type. If found, consume it, otherwise,
raise an unexpected token error.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">expect</span><span class="p">(</span><span class="nx">type</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">tokType</span> <span class="o">===</span> <span class="nx">type</span><span class="p">)</span> <span class="nx">next</span><span class="p">();</span>
<span class="k">else</span> <span class="nx">unexpected</span><span class="p">();</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-86"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-86">&#182;</a> </div> <p>Raise an unexpected token error.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">unexpected</span><span class="p">()</span> <span class="p">{</span>
<span class="nx">raise</span><span class="p">(</span><span class="nx">tokStart</span><span class="p">,</span> <span class="s2">&quot;Unexpected token&quot;</span><span class="p">);</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-87"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-87">&#182;</a> </div> <p>Verify that a node is an lval — something that can be assigned
to.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">checkLVal</span><span class="p">(</span><span class="nx">expr</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">expr</span><span class="p">.</span><span class="nx">type</span> <span class="o">!==</span> <span class="s2">&quot;Identifier&quot;</span> <span class="o">&amp;&amp;</span> <span class="nx">expr</span><span class="p">.</span><span class="nx">type</span> <span class="o">!==</span> <span class="s2">&quot;MemberExpression&quot;</span><span class="p">)</span>
<span class="nx">raise</span><span class="p">(</span><span class="nx">expr</span><span class="p">.</span><span class="nx">start</span><span class="p">,</span> <span class="s2">&quot;Assigning to rvalue&quot;</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">strict</span> <span class="o">&amp;&amp;</span> <span class="nx">expr</span><span class="p">.</span><span class="nx">type</span> <span class="o">===</span> <span class="s2">&quot;Identifier&quot;</span> <span class="o">&amp;&amp;</span> <span class="nx">isStrictBadIdWord</span><span class="p">(</span><span class="nx">expr</span><span class="p">.</span><span class="nx">name</span><span class="p">))</span>
<span class="nx">raise</span><span class="p">(</span><span class="nx">expr</span><span class="p">.</span><span class="nx">start</span><span class="p">,</span> <span class="s2">&quot;Assigning to &quot;</span> <span class="o">+</span> <span class="nx">expr</span><span class="p">.</span><span class="nx">name</span> <span class="o">+</span> <span class="s2">&quot; in strict mode&quot;</span><span class="p">);</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-88"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-88">&#182;</a> </div> <h3>Statement parsing</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-89"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-89">&#182;</a> </div> <p>Parse a program. Initializes the parser, reads any number of
statements, and wraps them in a Program node. Optionally takes a
<code>program</code> argument. If present, the statements will be appended
to its body instead of creating a new node.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">parseTopLevel</span><span class="p">(</span><span class="nx">program</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">initTokenState</span><span class="p">();</span>
<span class="nx">lastStart</span> <span class="o">=</span> <span class="nx">lastEnd</span> <span class="o">=</span> <span class="nx">tokPos</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">locations</span><span class="p">)</span> <span class="nx">lastEndLoc</span> <span class="o">=</span> <span class="nx">curLineLoc</span><span class="p">();</span>
<span class="nx">inFunction</span> <span class="o">=</span> <span class="nx">strict</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span>
<span class="nx">labels</span> <span class="o">=</span> <span class="p">[];</span>
<span class="nx">readToken</span><span class="p">();</span>
<span class="kd">var</span> <span class="nx">node</span> <span class="o">=</span> <span class="nx">program</span> <span class="o">||</span> <span class="nx">startNode</span><span class="p">(),</span> <span class="nx">first</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">program</span><span class="p">)</span> <span class="nx">node</span><span class="p">.</span><span class="nx">body</span> <span class="o">=</span> <span class="p">[];</span>
<span class="k">while</span> <span class="p">(</span><span class="nx">tokType</span> <span class="o">!==</span> <span class="nx">_eof</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">stmt</span> <span class="o">=</span> <span class="nx">parseStatement</span><span class="p">();</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">stmt</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">first</span> <span class="o">&amp;&amp;</span> <span class="nx">isUseStrict</span><span class="p">(</span><span class="nx">stmt</span><span class="p">))</span> <span class="nx">setStrict</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span>
<span class="nx">first</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">return</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">&quot;Program&quot;</span><span class="p">);</span>
<span class="p">};</span>
<span class="kd">var</span> <span class="nx">loopLabel</span> <span class="o">=</span> <span class="p">{</span><span class="nx">kind</span><span class="o">:</span> <span class="s2">&quot;loop&quot;</span><span class="p">},</span> <span class="nx">switchLabel</span> <span class="o">=</span> <span class="p">{</span><span class="nx">kind</span><span class="o">:</span> <span class="s2">&quot;switch&quot;</span><span class="p">};</span></pre></div> </td> </tr> <tr id="section-90"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-90">&#182;</a> </div> <p>Parse a single statement.</p>
<p>If expecting a statement and finding a slash operator, parse a
regular expression literal. This is to handle cases like
<code>if (foo) /blah/.exec(foo);</code>, where looking at the previous token
does not help.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">parseStatement</span><span class="p">()</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">tokType</span> <span class="o">===</span> <span class="nx">_slash</span><span class="p">)</span>
<span class="nx">readToken</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span>
<span class="kd">var</span> <span class="nx">starttype</span> <span class="o">=</span> <span class="nx">tokType</span><span class="p">,</span> <span class="nx">node</span> <span class="o">=</span> <span class="nx">startNode</span><span class="p">();</span></pre></div> </td> </tr> <tr id="section-91"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-91">&#182;</a> </div> <p>Most types of statements are recognized by the keyword they
start with. Many are trivial to parse, some require a bit of
complexity.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">switch</span> <span class="p">(</span><span class="nx">starttype</span><span class="p">)</span> <span class="p">{</span>
<span class="k">case</span> <span class="nx">_break</span><span class="o">:</span> <span class="k">case</span> <span class="nx">_continue</span><span class="o">:</span>
<span class="nx">next</span><span class="p">();</span>
<span class="kd">var</span> <span class="nx">isBreak</span> <span class="o">=</span> <span class="nx">starttype</span> <span class="o">===</span> <span class="nx">_break</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">eat</span><span class="p">(</span><span class="nx">_semi</span><span class="p">)</span> <span class="o">||</span> <span class="nx">canInsertSemicolon</span><span class="p">())</span> <span class="nx">node</span><span class="p">.</span><span class="nx">label</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span>
<span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">tokType</span> <span class="o">!==</span> <span class="nx">_name</span><span class="p">)</span> <span class="nx">unexpected</span><span class="p">();</span>
<span class="k">else</span> <span class="p">{</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">label</span> <span class="o">=</span> <span class="nx">parseIdent</span><span class="p">();</span>
<span class="nx">semicolon</span><span class="p">();</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-92"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-92">&#182;</a> </div> <p>Verify that there is an actual destination to break or
continue to.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="nx">labels</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="o">++</span><span class="nx">i</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">lab</span> <span class="o">=</span> <span class="nx">labels</span><span class="p">[</span><span class="nx">i</span><span class="p">];</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">node</span><span class="p">.</span><span class="nx">label</span> <span class="o">==</span> <span class="kc">null</span> <span class="o">||</span> <span class="nx">lab</span><span class="p">.</span><span class="nx">name</span> <span class="o">===</span> <span class="nx">node</span><span class="p">.</span><span class="nx">label</span><span class="p">.</span><span class="nx">name</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">lab</span><span class="p">.</span><span class="nx">kind</span> <span class="o">!=</span> <span class="kc">null</span> <span class="o">&amp;&amp;</span> <span class="p">(</span><span class="nx">isBreak</span> <span class="o">||</span> <span class="nx">lab</span><span class="p">.</span><span class="nx">kind</span> <span class="o">===</span> <span class="s2">&quot;loop&quot;</span><span class="p">))</span> <span class="k">break</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">node</span><span class="p">.</span><span class="nx">label</span> <span class="o">&amp;&amp;</span> <span class="nx">isBreak</span><span class="p">)</span> <span class="k">break</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">i</span> <span class="o">===</span> <span class="nx">labels</span><span class="p">.</span><span class="nx">length</span><span class="p">)</span> <span class="nx">raise</span><span class="p">(</span><span class="nx">node</span><span class="p">.</span><span class="nx">start</span><span class="p">,</span> <span class="s2">&quot;Unsyntactic &quot;</span> <span class="o">+</span> <span class="nx">starttype</span><span class="p">.</span><span class="nx">keyword</span><span class="p">);</span>
<span class="k">return</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="nx">isBreak</span> <span class="o">?</span> <span class="s2">&quot;BreakStatement&quot;</span> <span class="o">:</span> <span class="s2">&quot;ContinueStatement&quot;</span><span class="p">);</span>
<span class="k">case</span> <span class="nx">_debugger</span><span class="o">:</span>
<span class="nx">next</span><span class="p">();</span>
<span class="k">return</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">&quot;DebuggerStatement&quot;</span><span class="p">);</span>
<span class="k">case</span> <span class="nx">_do</span><span class="o">:</span>
<span class="nx">next</span><span class="p">();</span>
<span class="nx">labels</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">loopLabel</span><span class="p">);</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">body</span> <span class="o">=</span> <span class="nx">parseStatement</span><span class="p">();</span>
<span class="nx">labels</span><span class="p">.</span><span class="nx">pop</span><span class="p">();</span>
<span class="nx">expect</span><span class="p">(</span><span class="nx">_while</span><span class="p">);</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">test</span> <span class="o">=</span> <span class="nx">parseParenExpression</span><span class="p">();</span>
<span class="nx">semicolon</span><span class="p">();</span>
<span class="k">return</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">&quot;DoWhileStatement&quot;</span><span class="p">);</span></pre></div> </td> </tr> <tr id="section-93"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-93">&#182;</a> </div> <p>Disambiguating between a <code>for</code> and a <code>for</code>/<code>in</code> loop is
non-trivial. Basically, we have to parse the init <code>var</code>
statement or expression, disallowing the <code>in</code> operator (see
the second parameter to <code>parseExpression</code>), and then check
whether the next token is <code>in</code>. When there is no init part
(semicolon immediately after the opening parenthesis), it is
a regular <code>for</code> loop.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">case</span> <span class="nx">_for</span><span class="o">:</span>
<span class="nx">next</span><span class="p">();</span>
<span class="nx">labels</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">loopLabel</span><span class="p">);</span>
<span class="nx">expect</span><span class="p">(</span><span class="nx">_parenL</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">tokType</span> <span class="o">===</span> <span class="nx">_semi</span><span class="p">)</span> <span class="k">return</span> <span class="nx">parseFor</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="kc">null</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">tokType</span> <span class="o">===</span> <span class="nx">_var</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">init</span> <span class="o">=</span> <span class="nx">startNode</span><span class="p">();</span>
<span class="nx">next</span><span class="p">();</span>
<span class="nx">parseVar</span><span class="p">(</span><span class="nx">init</span><span class="p">,</span> <span class="kc">true</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">init</span><span class="p">.</span><span class="nx">declarations</span><span class="p">.</span><span class="nx">length</span> <span class="o">===</span> <span class="mi">1</span> <span class="o">&amp;&amp;</span> <span class="nx">eat</span><span class="p">(</span><span class="nx">_in</span><span class="p">))</span>
<span class="k">return</span> <span class="nx">parseForIn</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="nx">init</span><span class="p">);</span>
<span class="k">return</span> <span class="nx">parseFor</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="nx">init</span><span class="p">);</span>
<span class="p">}</span>
<span class="kd">var</span> <span class="nx">init</span> <span class="o">=</span> <span class="nx">parseExpression</span><span class="p">(</span><span class="kc">false</span><span class="p">,</span> <span class="kc">true</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">eat</span><span class="p">(</span><span class="nx">_in</span><span class="p">))</span> <span class="p">{</span><span class="nx">checkLVal</span><span class="p">(</span><span class="nx">init</span><span class="p">);</span> <span class="k">return</span> <span class="nx">parseForIn</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="nx">init</span><span class="p">);}</span>
<span class="k">return</span> <span class="nx">parseFor</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="nx">init</span><span class="p">);</span>
<span class="k">case</span> <span class="nx">_function</span><span class="o">:</span>
<span class="nx">next</span><span class="p">();</span>
<span class="k">return</span> <span class="nx">parseFunction</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="kc">true</span><span class="p">);</span>
<span class="k">case</span> <span class="nx">_if</span><span class="o">:</span>
<span class="nx">next</span><span class="p">();</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">test</span> <span class="o">=</span> <span class="nx">parseParenExpression</span><span class="p">();</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">consequent</span> <span class="o">=</span> <span class="nx">parseStatement</span><span class="p">();</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">alternate</span> <span class="o">=</span> <span class="nx">eat</span><span class="p">(</span><span class="nx">_else</span><span class="p">)</span> <span class="o">?</span> <span class="nx">parseStatement</span><span class="p">()</span> <span class="o">:</span> <span class="kc">null</span><span class="p">;</span>
<span class="k">return</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">&quot;IfStatement&quot;</span><span class="p">);</span>
<span class="k">case</span> <span class="nx">_return</span><span class="o">:</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">inFunction</span><span class="p">)</span> <span class="nx">raise</span><span class="p">(</span><span class="nx">tokStart</span><span class="p">,</span> <span class="s2">&quot;&#39;return&#39; outside of function&quot;</span><span class="p">);</span>
<span class="nx">next</span><span class="p">();</span></pre></div> </td> </tr> <tr id="section-94"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-94">&#182;</a> </div> <p>In <code>return</code> (and <code>break</code>/<code>continue</code>), the keywords with
optional arguments, we eagerly look for a semicolon or the
possibility to insert one.</p> </td> <td class="code"> <div class="highlight"><pre>
<span class="k">if</span> <span class="p">(</span><span class="nx">eat</span><span class="p">(</span><span class="nx">_semi</span><span class="p">)</span> <span class="o">||</span> <span class="nx">canInsertSemicolon</span><span class="p">())</span> <span class="nx">node</span><span class="p">.</span><span class="nx">argument</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span>
<span class="k">else</span> <span class="p">{</span> <span class="nx">node</span><span class="p">.</span><span class="nx">argument</span> <span class="o">=</span> <span class="nx">parseExpression</span><span class="p">();</span> <span class="nx">semicolon</span><span class="p">();</span> <span class="p">}</span>
<span class="k">return</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">&quot;ReturnStatement&quot;</span><span class="p">);</span>
<span class="k">case</span> <span class="nx">_switch</span><span class="o">:</span>
<span class="nx">next</span><span class="p">();</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">discriminant</span> <span class="o">=</span> <span class="nx">parseParenExpression</span><span class="p">();</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">cases</span> <span class="o">=</span> <span class="p">[];</span>
<span class="nx">expect</span><span class="p">(</span><span class="nx">_braceL</span><span class="p">);</span>
<span class="nx">labels</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">switchLabel</span><span class="p">);</span></pre></div> </td> </tr> <tr id="section-95"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-95">&#182;</a> </div> <p>Statements under must be grouped (by label) in SwitchCase
nodes. <code>cur</code> is used to keep the node that we are currently
adding statements to.</p> </td> <td class="code"> <div class="highlight"><pre>
<span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">cur</span><span class="p">,</span> <span class="nx">sawDefault</span><span class="p">;</span> <span class="nx">tokType</span> <span class="o">!=</span> <span class="nx">_braceR</span><span class="p">;)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">tokType</span> <span class="o">===</span> <span class="nx">_case</span> <span class="o">||</span> <span class="nx">tokType</span> <span class="o">===</span> <span class="nx">_default</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">isCase</span> <span class="o">=</span> <span class="nx">tokType</span> <span class="o">===</span> <span class="nx">_case</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">cur</span><span class="p">)</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">cur</span><span class="p">,</span> <span class="s2">&quot;SwitchCase&quot;</span><span class="p">);</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">cases</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">cur</span> <span class="o">=</span> <span class="nx">startNode</span><span class="p">());</span>
<span class="nx">cur</span><span class="p">.</span><span class="nx">consequent</span> <span class="o">=</span> <span class="p">[];</span>
<span class="nx">next</span><span class="p">();</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">isCase</span><span class="p">)</span> <span class="nx">cur</span><span class="p">.</span><span class="nx">test</span> <span class="o">=</span> <span class="nx">parseExpression</span><span class="p">();</span>
<span class="k">else</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">sawDefault</span><span class="p">)</span> <span class="nx">raise</span><span class="p">(</span><span class="nx">lastStart</span><span class="p">,</span> <span class="s2">&quot;Multiple default clauses&quot;</span><span class="p">);</span> <span class="nx">sawDefault</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
<span class="nx">cur</span><span class="p">.</span><span class="nx">test</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span>
<span class="p">}</span>
<span class="nx">expect</span><span class="p">(</span><span class="nx">_colon</span><span class="p">);</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">cur</span><span class="p">)</span> <span class="nx">unexpected</span><span class="p">();</span>
<span class="nx">cur</span><span class="p">.</span><span class="nx">consequent</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">parseStatement</span><span class="p">());</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">cur</span><span class="p">)</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">cur</span><span class="p">,</span> <span class="s2">&quot;SwitchCase&quot;</span><span class="p">);</span>
<span class="nx">next</span><span class="p">();</span> <span class="c1">// Closing brace</span>
<span class="nx">labels</span><span class="p">.</span><span class="nx">pop</span><span class="p">();</span>
<span class="k">return</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">&quot;SwitchStatement&quot;</span><span class="p">);</span>
<span class="k">case</span> <span class="nx">_throw</span><span class="o">:</span>
<span class="nx">next</span><span class="p">();</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">newline</span><span class="p">.</span><span class="nx">test</span><span class="p">(</span><span class="nx">input</span><span class="p">.</span><span class="nx">slice</span><span class="p">(</span><span class="nx">lastEnd</span><span class="p">,</span> <span class="nx">tokStart</span><span class="p">)))</span>
<span class="nx">raise</span><span class="p">(</span><span class="nx">lastEnd</span><span class="p">,</span> <span class="s2">&quot;Illegal newline after throw&quot;</span><span class="p">);</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">argument</span> <span class="o">=</span> <span class="nx">parseExpression</span><span class="p">();</span>
<span class="k">return</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">&quot;ThrowStatement&quot;</span><span class="p">);</span>
<span class="k">case</span> <span class="nx">_try</span><span class="o">:</span>
<span class="nx">next</span><span class="p">();</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">block</span> <span class="o">=</span> <span class="nx">parseBlock</span><span class="p">();</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">handlers</span> <span class="o">=</span> <span class="p">[];</span>
<span class="k">while</span> <span class="p">(</span><span class="nx">tokType</span> <span class="o">===</span> <span class="nx">_catch</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">clause</span> <span class="o">=</span> <span class="nx">startNode</span><span class="p">();</span>
<span class="nx">next</span><span class="p">();</span>
<span class="nx">expect</span><span class="p">(</span><span class="nx">_parenL</span><span class="p">);</span>
<span class="nx">clause</span><span class="p">.</span><span class="nx">param</span> <span class="o">=</span> <span class="nx">parseIdent</span><span class="p">();</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">strict</span> <span class="o">&amp;&amp;</span> <span class="nx">isStrictBadIdWord</span><span class="p">(</span><span class="nx">clause</span><span class="p">.</span><span class="nx">param</span><span class="p">.</span><span class="nx">name</span><span class="p">))</span>
<span class="nx">raise</span><span class="p">(</span><span class="nx">clause</span><span class="p">.</span><span class="nx">param</span><span class="p">.</span><span class="nx">start</span><span class="p">,</span> <span class="s2">&quot;Binding &quot;</span> <span class="o">+</span> <span class="nx">clause</span><span class="p">.</span><span class="nx">param</span><span class="p">.</span><span class="nx">name</span> <span class="o">+</span> <span class="s2">&quot; in strict mode&quot;</span><span class="p">);</span>
<span class="nx">expect</span><span class="p">(</span><span class="nx">_parenR</span><span class="p">);</span>
<span class="nx">clause</span><span class="p">.</span><span class="nx">guard</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span>
<span class="nx">clause</span><span class="p">.</span><span class="nx">body</span> <span class="o">=</span> <span class="nx">parseBlock</span><span class="p">();</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">handlers</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">finishNode</span><span class="p">(</span><span class="nx">clause</span><span class="p">,</span> <span class="s2">&quot;CatchClause&quot;</span><span class="p">));</span>
<span class="p">}</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">finalizer</span> <span class="o">=</span> <span class="nx">eat</span><span class="p">(</span><span class="nx">_finally</span><span class="p">)</span> <span class="o">?</span> <span class="nx">parseBlock</span><span class="p">()</span> <span class="o">:</span> <span class="kc">null</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">node</span><span class="p">.</span><span class="nx">handlers</span><span class="p">.</span><span class="nx">length</span> <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="nx">node</span><span class="p">.</span><span class="nx">finalizer</span><span class="p">)</span>
<span class="nx">raise</span><span class="p">(</span><span class="nx">node</span><span class="p">.</span><span class="nx">start</span><span class="p">,</span> <span class="s2">&quot;Missing catch or finally clause&quot;</span><span class="p">);</span>
<span class="k">return</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">&quot;TryStatement&quot;</span><span class="p">);</span>
<span class="k">case</span> <span class="nx">_var</span><span class="o">:</span>
<span class="nx">next</span><span class="p">();</span>
<span class="nx">node</span> <span class="o">=</span> <span class="nx">parseVar</span><span class="p">(</span><span class="nx">node</span><span class="p">);</span>
<span class="nx">semicolon</span><span class="p">();</span>
<span class="k">return</span> <span class="nx">node</span><span class="p">;</span>
<span class="k">case</span> <span class="nx">_while</span><span class="o">:</span>
<span class="nx">next</span><span class="p">();</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">test</span> <span class="o">=</span> <span class="nx">parseParenExpression</span><span class="p">();</span>
<span class="nx">labels</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">loopLabel</span><span class="p">);</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">body</span> <span class="o">=</span> <span class="nx">parseStatement</span><span class="p">();</span>
<span class="nx">labels</span><span class="p">.</span><span class="nx">pop</span><span class="p">();</span>
<span class="k">return</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">&quot;WhileStatement&quot;</span><span class="p">);</span>
<span class="k">case</span> <span class="nx">_with</span><span class="o">:</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">strict</span><span class="p">)</span> <span class="nx">raise</span><span class="p">(</span><span class="nx">tokStart</span><span class="p">,</span> <span class="s2">&quot;&#39;with&#39; in strict mode&quot;</span><span class="p">);</span>
<span class="nx">next</span><span class="p">();</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">object</span> <span class="o">=</span> <span class="nx">parseParenExpression</span><span class="p">();</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">body</span> <span class="o">=</span> <span class="nx">parseStatement</span><span class="p">();</span>
<span class="k">return</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">&quot;WithStatement&quot;</span><span class="p">);</span>
<span class="k">case</span> <span class="nx">_braceL</span><span class="o">:</span>
<span class="k">return</span> <span class="nx">parseBlock</span><span class="p">();</span>
<span class="k">case</span> <span class="nx">_semi</span><span class="o">:</span>
<span class="nx">next</span><span class="p">();</span>
<span class="k">return</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">&quot;EmptyStatement&quot;</span><span class="p">);</span></pre></div> </td> </tr> <tr id="section-96"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-96">&#182;</a> </div> <p>If the statement does not start with a statement keyword or a
brace, it's an ExpressionStatement or LabeledStatement. We
simply start parsing an expression, and afterwards, if the
next token is a colon and the expression was a simple
Identifier node, we switch to interpreting it as a label.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">default</span><span class="o">:</span>
<span class="kd">var</span> <span class="nx">maybeName</span> <span class="o">=</span> <span class="nx">tokVal</span><span class="p">,</span> <span class="nx">expr</span> <span class="o">=</span> <span class="nx">parseExpression</span><span class="p">();</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">starttype</span> <span class="o">===</span> <span class="nx">_name</span> <span class="o">&amp;&amp;</span> <span class="nx">expr</span><span class="p">.</span><span class="nx">type</span> <span class="o">===</span> <span class="s2">&quot;Identifier&quot;</span> <span class="o">&amp;&amp;</span> <span class="nx">eat</span><span class="p">(</span><span class="nx">_colon</span><span class="p">))</span> <span class="p">{</span>
<span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="nx">labels</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="o">++</span><span class="nx">i</span><span class="p">)</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">labels</span><span class="p">[</span><span class="nx">i</span><span class="p">].</span><span class="nx">name</span> <span class="o">===</span> <span class="nx">maybeName</span><span class="p">)</span> <span class="nx">raise</span><span class="p">(</span><span class="nx">expr</span><span class="p">.</span><span class="nx">start</span><span class="p">,</span> <span class="s2">&quot;Label &#39;&quot;</span> <span class="o">+</span> <span class="nx">maybeName</span> <span class="o">+</span> <span class="s2">&quot;&#39; is already declared&quot;</span><span class="p">);</span>
<span class="kd">var</span> <span class="nx">kind</span> <span class="o">=</span> <span class="nx">tokType</span><span class="p">.</span><span class="nx">isLoop</span> <span class="o">?</span> <span class="s2">&quot;loop&quot;</span> <span class="o">:</span> <span class="nx">tokType</span> <span class="o">===</span> <span class="nx">_switch</span> <span class="o">?</span> <span class="s2">&quot;switch&quot;</span> <span class="o">:</span> <span class="kc">null</span><span class="p">;</span>
<span class="nx">labels</span><span class="p">.</span><span class="nx">push</span><span class="p">({</span><span class="nx">name</span><span class="o">:</span> <span class="nx">maybeName</span><span class="p">,</span> <span class="nx">kind</span><span class="o">:</span> <span class="nx">kind</span><span class="p">});</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">body</span> <span class="o">=</span> <span class="nx">parseStatement</span><span class="p">();</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">label</span> <span class="o">=</span> <span class="nx">expr</span><span class="p">;</span>
<span class="k">return</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">&quot;LabeledStatement&quot;</span><span class="p">);</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">expression</span> <span class="o">=</span> <span class="nx">expr</span><span class="p">;</span>
<span class="nx">semicolon</span><span class="p">();</span>
<span class="k">return</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">&quot;ExpressionStatement&quot;</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-97"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-97">&#182;</a> </div> <p>Used for constructs like <code>switch</code> and <code>if</code> that insist on
parentheses around their expression.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">parseParenExpression</span><span class="p">()</span> <span class="p">{</span>
<span class="nx">expect</span><span class="p">(</span><span class="nx">_parenL</span><span class="p">);</span>
<span class="kd">var</span> <span class="nx">val</span> <span class="o">=</span> <span class="nx">parseExpression</span><span class="p">();</span>
<span class="nx">expect</span><span class="p">(</span><span class="nx">_parenR</span><span class="p">);</span>
<span class="k">return</span> <span class="nx">val</span><span class="p">;</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-98"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-98">&#182;</a> </div> <p>Parse a semicolon-enclosed block of statements, handling <code>"use
strict"</code> declarations when <code>allowStrict</code> is true (used for
function bodies).</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">parseBlock</span><span class="p">(</span><span class="nx">allowStrict</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">node</span> <span class="o">=</span> <span class="nx">startNode</span><span class="p">(),</span> <span class="nx">first</span> <span class="o">=</span> <span class="kc">true</span><span class="p">,</span> <span class="nx">strict</span> <span class="o">=</span> <span class="kc">false</span><span class="p">,</span> <span class="nx">oldStrict</span><span class="p">;</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">body</span> <span class="o">=</span> <span class="p">[];</span>
<span class="nx">expect</span><span class="p">(</span><span class="nx">_braceL</span><span class="p">);</span>
<span class="k">while</span> <span class="p">(</span><span class="o">!</span><span class="nx">eat</span><span class="p">(</span><span class="nx">_braceR</span><span class="p">))</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">stmt</span> <span class="o">=</span> <span class="nx">parseStatement</span><span class="p">();</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">stmt</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">first</span> <span class="o">&amp;&amp;</span> <span class="nx">isUseStrict</span><span class="p">(</span><span class="nx">stmt</span><span class="p">))</span> <span class="p">{</span>
<span class="nx">oldStrict</span> <span class="o">=</span> <span class="nx">strict</span><span class="p">;</span>
<span class="nx">setStrict</span><span class="p">(</span><span class="nx">strict</span> <span class="o">=</span> <span class="kc">true</span><span class="p">);</span>
<span class="p">}</span>
<span class="nx">first</span> <span class="o">=</span> <span class="kc">false</span>
<span class="p">}</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">strict</span> <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="nx">oldStrict</span><span class="p">)</span> <span class="nx">setStrict</span><span class="p">(</span><span class="kc">false</span><span class="p">);</span>
<span class="k">return</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">&quot;BlockStatement&quot;</span><span class="p">);</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-99"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-99">&#182;</a> </div> <p>Parse a regular <code>for</code> loop. The disambiguation code in
<code>parseStatement</code> will already have parsed the init statement or
expression.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">parseFor</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="nx">init</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">init</span> <span class="o">=</span> <span class="nx">init</span><span class="p">;</span>
<span class="nx">expect</span><span class="p">(</span><span class="nx">_semi</span><span class="p">);</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">test</span> <span class="o">=</span> <span class="nx">tokType</span> <span class="o">===</span> <span class="nx">_semi</span> <span class="o">?</span> <span class="kc">null</span> <span class="o">:</span> <span class="nx">parseExpression</span><span class="p">();</span>
<span class="nx">expect</span><span class="p">(</span><span class="nx">_semi</span><span class="p">);</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">update</span> <span class="o">=</span> <span class="nx">tokType</span> <span class="o">===</span> <span class="nx">_parenR</span> <span class="o">?</span> <span class="kc">null</span> <span class="o">:</span> <span class="nx">parseExpression</span><span class="p">();</span>
<span class="nx">expect</span><span class="p">(</span><span class="nx">_parenR</span><span class="p">);</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">body</span> <span class="o">=</span> <span class="nx">parseStatement</span><span class="p">();</span>
<span class="nx">labels</span><span class="p">.</span><span class="nx">pop</span><span class="p">();</span>
<span class="k">return</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">&quot;ForStatement&quot;</span><span class="p">);</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-100"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-100">&#182;</a> </div> <p>Parse a <code>for</code>/<code>in</code> loop.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">parseForIn</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="nx">init</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">left</span> <span class="o">=</span> <span class="nx">init</span><span class="p">;</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">right</span> <span class="o">=</span> <span class="nx">parseExpression</span><span class="p">();</span>
<span class="nx">expect</span><span class="p">(</span><span class="nx">_parenR</span><span class="p">);</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">body</span> <span class="o">=</span> <span class="nx">parseStatement</span><span class="p">();</span>
<span class="nx">labels</span><span class="p">.</span><span class="nx">pop</span><span class="p">();</span>
<span class="k">return</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">&quot;ForInStatement&quot;</span><span class="p">);</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-101"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-101">&#182;</a> </div> <p>Parse a list of variable declarations.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">parseVar</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="nx">noIn</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">declarations</span> <span class="o">=</span> <span class="p">[];</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">kind</span> <span class="o">=</span> <span class="s2">&quot;var&quot;</span><span class="p">;</span>
<span class="k">for</span> <span class="p">(;;)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">decl</span> <span class="o">=</span> <span class="nx">startNode</span><span class="p">();</span>
<span class="nx">decl</span><span class="p">.</span><span class="nx">id</span> <span class="o">=</span> <span class="nx">parseIdent</span><span class="p">();</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">strict</span> <span class="o">&amp;&amp;</span> <span class="nx">isStrictBadIdWord</span><span class="p">(</span><span class="nx">decl</span><span class="p">.</span><span class="nx">id</span><span class="p">.</span><span class="nx">name</span><span class="p">))</span>
<span class="nx">raise</span><span class="p">(</span><span class="nx">decl</span><span class="p">.</span><span class="nx">id</span><span class="p">.</span><span class="nx">start</span><span class="p">,</span> <span class="s2">&quot;Binding &quot;</span> <span class="o">+</span> <span class="nx">decl</span><span class="p">.</span><span class="nx">id</span><span class="p">.</span><span class="nx">name</span> <span class="o">+</span> <span class="s2">&quot; in strict mode&quot;</span><span class="p">);</span>
<span class="nx">decl</span><span class="p">.</span><span class="nx">init</span> <span class="o">=</span> <span class="nx">eat</span><span class="p">(</span><span class="nx">_eq</span><span class="p">)</span> <span class="o">?</span> <span class="nx">parseExpression</span><span class="p">(</span><span class="kc">true</span><span class="p">,</span> <span class="nx">noIn</span><span class="p">)</span> <span class="o">:</span> <span class="kc">null</span><span class="p">;</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">declarations</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">finishNode</span><span class="p">(</span><span class="nx">decl</span><span class="p">,</span> <span class="s2">&quot;VariableDeclarator&quot;</span><span class="p">));</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">eat</span><span class="p">(</span><span class="nx">_comma</span><span class="p">))</span> <span class="k">break</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">return</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">&quot;VariableDeclaration&quot;</span><span class="p">);</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-102"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-102">&#182;</a> </div> <h3>Expression parsing</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-103"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-103">&#182;</a> </div> <p>These nest, from the most general expression type at the top to
'atomic', nondivisible expression types at the bottom. Most of
the functions will simply let the function(s) below them parse,
and, <em>if</em> the syntactic construct they handle is present, wrap
the AST node that the inner parser gave them in another node.</p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-104"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-104">&#182;</a> </div> <p>Parse a full expression. The arguments are used to forbid comma
sequences (in argument lists, array literals, or object literals)
or the <code>in</code> operator (in for loops initalization expressions).</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">parseExpression</span><span class="p">(</span><span class="nx">noComma</span><span class="p">,</span> <span class="nx">noIn</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">expr</span> <span class="o">=</span> <span class="nx">parseMaybeAssign</span><span class="p">(</span><span class="nx">noIn</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">noComma</span> <span class="o">&amp;&amp;</span> <span class="nx">tokType</span> <span class="o">===</span> <span class="nx">_comma</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">node</span> <span class="o">=</span> <span class="nx">startNodeFrom</span><span class="p">(</span><span class="nx">expr</span><span class="p">);</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">expressions</span> <span class="o">=</span> <span class="p">[</span><span class="nx">expr</span><span class="p">];</span>
<span class="k">while</span> <span class="p">(</span><span class="nx">eat</span><span class="p">(</span><span class="nx">_comma</span><span class="p">))</span> <span class="nx">node</span><span class="p">.</span><span class="nx">expressions</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">parseMaybeAssign</span><span class="p">(</span><span class="nx">noIn</span><span class="p">));</span>
<span class="k">return</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">&quot;SequenceExpression&quot;</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">return</span> <span class="nx">expr</span><span class="p">;</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-105"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-105">&#182;</a> </div> <p>Parse an assignment expression. This includes applications of
operators like <code>+=</code>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">parseMaybeAssign</span><span class="p">(</span><span class="nx">noIn</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">left</span> <span class="o">=</span> <span class="nx">parseMaybeConditional</span><span class="p">(</span><span class="nx">noIn</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">tokType</span><span class="p">.</span><span class="nx">isAssign</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">node</span> <span class="o">=</span> <span class="nx">startNodeFrom</span><span class="p">(</span><span class="nx">left</span><span class="p">);</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">operator</span> <span class="o">=</span> <span class="nx">tokVal</span><span class="p">;</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">left</span> <span class="o">=</span> <span class="nx">left</span><span class="p">;</span>
<span class="nx">next</span><span class="p">();</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">right</span> <span class="o">=</span> <span class="nx">parseMaybeAssign</span><span class="p">(</span><span class="nx">noIn</span><span class="p">);</span>
<span class="nx">checkLVal</span><span class="p">(</span><span class="nx">left</span><span class="p">);</span>
<span class="k">return</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">&quot;AssignmentExpression&quot;</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">return</span> <span class="nx">left</span><span class="p">;</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-106"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-106">&#182;</a> </div> <p>Parse a ternary conditional (<code>?:</code>) operator.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">parseMaybeConditional</span><span class="p">(</span><span class="nx">noIn</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">expr</span> <span class="o">=</span> <span class="nx">parseExprOps</span><span class="p">(</span><span class="nx">noIn</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">eat</span><span class="p">(</span><span class="nx">_question</span><span class="p">))</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">node</span> <span class="o">=</span> <span class="nx">startNodeFrom</span><span class="p">(</span><span class="nx">expr</span><span class="p">);</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">test</span> <span class="o">=</span> <span class="nx">expr</span><span class="p">;</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">consequent</span> <span class="o">=</span> <span class="nx">parseExpression</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span>
<span class="nx">expect</span><span class="p">(</span><span class="nx">_colon</span><span class="p">);</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">alternate</span> <span class="o">=</span> <span class="nx">parseExpression</span><span class="p">(</span><span class="kc">true</span><span class="p">,</span> <span class="nx">noIn</span><span class="p">);</span>
<span class="k">return</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">&quot;ConditionalExpression&quot;</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">return</span> <span class="nx">expr</span><span class="p">;</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-107"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-107">&#182;</a> </div> <p>Start the precedence parser.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">parseExprOps</span><span class="p">(</span><span class="nx">noIn</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">parseExprOp</span><span class="p">(</span><span class="nx">parseMaybeUnary</span><span class="p">(</span><span class="nx">noIn</span><span class="p">),</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="nx">noIn</span><span class="p">);</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-108"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-108">&#182;</a> </div> <p>Parse binary operators with the operator precedence parsing
algorithm. <code>left</code> is the left-hand side of the operator.
<code>minPrec</code> provides context that allows the function to stop and
defer further parser to one of its callers when it encounters an
operator that has a lower precedence than the set it is parsing.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">parseExprOp</span><span class="p">(</span><span class="nx">left</span><span class="p">,</span> <span class="nx">minPrec</span><span class="p">,</span> <span class="nx">noIn</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">prec</span> <span class="o">=</span> <span class="nx">tokType</span><span class="p">.</span><span class="nx">binop</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">prec</span> <span class="o">!=</span> <span class="kc">null</span> <span class="o">&amp;&amp;</span> <span class="p">(</span><span class="o">!</span><span class="nx">noIn</span> <span class="o">||</span> <span class="nx">tokType</span> <span class="o">!==</span> <span class="nx">_in</span><span class="p">))</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">prec</span> <span class="o">&gt;</span> <span class="nx">minPrec</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">node</span> <span class="o">=</span> <span class="nx">startNodeFrom</span><span class="p">(</span><span class="nx">left</span><span class="p">);</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">left</span> <span class="o">=</span> <span class="nx">left</span><span class="p">;</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">operator</span> <span class="o">=</span> <span class="nx">tokVal</span><span class="p">;</span>
<span class="nx">next</span><span class="p">();</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">right</span> <span class="o">=</span> <span class="nx">parseExprOp</span><span class="p">(</span><span class="nx">parseMaybeUnary</span><span class="p">(</span><span class="nx">noIn</span><span class="p">),</span> <span class="nx">prec</span><span class="p">,</span> <span class="nx">noIn</span><span class="p">);</span>
<span class="kd">var</span> <span class="nx">node</span> <span class="o">=</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="sr">/&amp;&amp;|\|\|/</span><span class="p">.</span><span class="nx">test</span><span class="p">(</span><span class="nx">node</span><span class="p">.</span><span class="nx">operator</span><span class="p">)</span> <span class="o">?</span> <span class="s2">&quot;LogicalExpression&quot;</span> <span class="o">:</span> <span class="s2">&quot;BinaryExpression&quot;</span><span class="p">);</span>
<span class="k">return</span> <span class="nx">parseExprOp</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="nx">minPrec</span><span class="p">,</span> <span class="nx">noIn</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="k">return</span> <span class="nx">left</span><span class="p">;</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-109"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-109">&#182;</a> </div> <p>Parse unary operators, both prefix and postfix.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">parseMaybeUnary</span><span class="p">(</span><span class="nx">noIn</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">tokType</span><span class="p">.</span><span class="nx">prefix</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">node</span> <span class="o">=</span> <span class="nx">startNode</span><span class="p">(),</span> <span class="nx">update</span> <span class="o">=</span> <span class="nx">tokType</span><span class="p">.</span><span class="nx">isUpdate</span><span class="p">;</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">operator</span> <span class="o">=</span> <span class="nx">tokVal</span><span class="p">;</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">prefix</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
<span class="nx">next</span><span class="p">();</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">argument</span> <span class="o">=</span> <span class="nx">parseMaybeUnary</span><span class="p">(</span><span class="nx">noIn</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">update</span><span class="p">)</span> <span class="nx">checkLVal</span><span class="p">(</span><span class="nx">node</span><span class="p">.</span><span class="nx">argument</span><span class="p">);</span>
<span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">strict</span> <span class="o">&amp;&amp;</span> <span class="nx">node</span><span class="p">.</span><span class="nx">operator</span> <span class="o">===</span> <span class="s2">&quot;delete&quot;</span> <span class="o">&amp;&amp;</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">argument</span><span class="p">.</span><span class="nx">type</span> <span class="o">===</span> <span class="s2">&quot;Identifier&quot;</span><span class="p">)</span>
<span class="nx">raise</span><span class="p">(</span><span class="nx">node</span><span class="p">.</span><span class="nx">start</span><span class="p">,</span> <span class="s2">&quot;Deleting local variable in strict mode&quot;</span><span class="p">);</span>
<span class="k">return</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="nx">update</span> <span class="o">?</span> <span class="s2">&quot;UpdateExpression&quot;</span> <span class="o">:</span> <span class="s2">&quot;UnaryExpression&quot;</span><span class="p">);</span>
<span class="p">}</span>
<span class="kd">var</span> <span class="nx">expr</span> <span class="o">=</span> <span class="nx">parseExprSubscripts</span><span class="p">();</span>
<span class="k">while</span> <span class="p">(</span><span class="nx">tokType</span><span class="p">.</span><span class="nx">postfix</span> <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="nx">canInsertSemicolon</span><span class="p">())</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">node</span> <span class="o">=</span> <span class="nx">startNodeFrom</span><span class="p">(</span><span class="nx">expr</span><span class="p">);</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">operator</span> <span class="o">=</span> <span class="nx">tokVal</span><span class="p">;</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">prefix</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">argument</span> <span class="o">=</span> <span class="nx">expr</span><span class="p">;</span>
<span class="nx">checkLVal</span><span class="p">(</span><span class="nx">expr</span><span class="p">);</span>
<span class="nx">next</span><span class="p">();</span>
<span class="nx">expr</span> <span class="o">=</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">&quot;UpdateExpression&quot;</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">return</span> <span class="nx">expr</span><span class="p">;</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-110"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-110">&#182;</a> </div> <p>Parse call, dot, and <code>[]</code>-subscript expressions.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">parseExprSubscripts</span><span class="p">()</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">parseSubscripts</span><span class="p">(</span><span class="nx">parseExprAtom</span><span class="p">());</span>
<span class="p">}</span>
<span class="kd">function</span> <span class="nx">parseSubscripts</span><span class="p">(</span><span class="nx">base</span><span class="p">,</span> <span class="nx">noCalls</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">eat</span><span class="p">(</span><span class="nx">_dot</span><span class="p">))</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">node</span> <span class="o">=</span> <span class="nx">startNodeFrom</span><span class="p">(</span><span class="nx">base</span><span class="p">);</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">object</span> <span class="o">=</span> <span class="nx">base</span><span class="p">;</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">property</span> <span class="o">=</span> <span class="nx">parseIdent</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">computed</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
<span class="k">return</span> <span class="nx">parseSubscripts</span><span class="p">(</span><span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">&quot;MemberExpression&quot;</span><span class="p">),</span> <span class="nx">noCalls</span><span class="p">);</span>
<span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">eat</span><span class="p">(</span><span class="nx">_bracketL</span><span class="p">))</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">node</span> <span class="o">=</span> <span class="nx">startNodeFrom</span><span class="p">(</span><span class="nx">base</span><span class="p">);</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">object</span> <span class="o">=</span> <span class="nx">base</span><span class="p">;</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">property</span> <span class="o">=</span> <span class="nx">parseExpression</span><span class="p">();</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">computed</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
<span class="nx">expect</span><span class="p">(</span><span class="nx">_bracketR</span><span class="p">);</span>
<span class="k">return</span> <span class="nx">parseSubscripts</span><span class="p">(</span><span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">&quot;MemberExpression&quot;</span><span class="p">),</span> <span class="nx">noCalls</span><span class="p">);</span>
<span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">noCalls</span> <span class="o">&amp;&amp;</span> <span class="nx">eat</span><span class="p">(</span><span class="nx">_parenL</span><span class="p">))</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">node</span> <span class="o">=</span> <span class="nx">startNodeFrom</span><span class="p">(</span><span class="nx">base</span><span class="p">);</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">callee</span> <span class="o">=</span> <span class="nx">base</span><span class="p">;</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">arguments</span> <span class="o">=</span> <span class="nx">parseExprList</span><span class="p">(</span><span class="nx">_parenR</span><span class="p">,</span> <span class="kc">false</span><span class="p">);</span>
<span class="k">return</span> <span class="nx">parseSubscripts</span><span class="p">(</span><span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">&quot;CallExpression&quot;</span><span class="p">),</span> <span class="nx">noCalls</span><span class="p">);</span>
<span class="p">}</span> <span class="k">else</span> <span class="k">return</span> <span class="nx">base</span><span class="p">;</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-111"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-111">&#182;</a> </div> <p>Parse an atomic expression — either a single token that is an
expression, an expression started by a keyword like <code>function</code> or
<code>new</code>, or an expression wrapped in punctuation like <code>()</code>, <code>[]</code>,
or <code>{}</code>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">parseExprAtom</span><span class="p">()</span> <span class="p">{</span>
<span class="k">switch</span> <span class="p">(</span><span class="nx">tokType</span><span class="p">)</span> <span class="p">{</span>
<span class="k">case</span> <span class="nx">_this</span><span class="o">:</span>
<span class="kd">var</span> <span class="nx">node</span> <span class="o">=</span> <span class="nx">startNode</span><span class="p">();</span>
<span class="nx">next</span><span class="p">();</span>
<span class="k">return</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">&quot;ThisExpression&quot;</span><span class="p">);</span>
<span class="k">case</span> <span class="nx">_name</span><span class="o">:</span>
<span class="k">return</span> <span class="nx">parseIdent</span><span class="p">();</span>
<span class="k">case</span> <span class="nx">_num</span><span class="o">:</span> <span class="k">case</span> <span class="nx">_string</span><span class="o">:</span> <span class="k">case</span> <span class="nx">_regexp</span><span class="o">:</span>
<span class="kd">var</span> <span class="nx">node</span> <span class="o">=</span> <span class="nx">startNode</span><span class="p">();</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">value</span> <span class="o">=</span> <span class="nx">tokVal</span><span class="p">;</span>
<span class="nx">next</span><span class="p">();</span>
<span class="k">return</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">&quot;Literal&quot;</span><span class="p">);</span>
<span class="k">case</span> <span class="nx">_null</span><span class="o">:</span> <span class="k">case</span> <span class="nx">_true</span><span class="o">:</span> <span class="k">case</span> <span class="nx">_false</span><span class="o">:</span>
<span class="kd">var</span> <span class="nx">node</span> <span class="o">=</span> <span class="nx">startNode</span><span class="p">();</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">value</span> <span class="o">=</span> <span class="nx">tokType</span><span class="p">.</span><span class="nx">atomValue</span><span class="p">;</span>
<span class="nx">next</span><span class="p">();</span>
<span class="k">return</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">&quot;Literal&quot;</span><span class="p">);</span>
<span class="k">case</span> <span class="nx">_parenL</span><span class="o">:</span>
<span class="nx">next</span><span class="p">();</span>
<span class="kd">var</span> <span class="nx">val</span> <span class="o">=</span> <span class="nx">parseExpression</span><span class="p">();</span>
<span class="nx">expect</span><span class="p">(</span><span class="nx">_parenR</span><span class="p">);</span>
<span class="k">return</span> <span class="nx">val</span><span class="p">;</span>
<span class="k">case</span> <span class="nx">_bracketL</span><span class="o">:</span>
<span class="kd">var</span> <span class="nx">node</span> <span class="o">=</span> <span class="nx">startNode</span><span class="p">();</span>
<span class="nx">next</span><span class="p">();</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">elements</span> <span class="o">=</span> <span class="nx">parseExprList</span><span class="p">(</span><span class="nx">_bracketR</span><span class="p">,</span> <span class="kc">true</span><span class="p">,</span> <span class="kc">true</span><span class="p">);</span>
<span class="k">return</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">&quot;ArrayExpression&quot;</span><span class="p">);</span>
<span class="k">case</span> <span class="nx">_braceL</span><span class="o">:</span>
<span class="k">return</span> <span class="nx">parseObj</span><span class="p">();</span>
<span class="k">case</span> <span class="nx">_function</span><span class="o">:</span>
<span class="kd">var</span> <span class="nx">node</span> <span class="o">=</span> <span class="nx">startNode</span><span class="p">();</span>
<span class="nx">next</span><span class="p">();</span>
<span class="k">return</span> <span class="nx">parseFunction</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="kc">false</span><span class="p">);</span>
<span class="k">case</span> <span class="nx">_new</span><span class="o">:</span>
<span class="k">return</span> <span class="nx">parseNew</span><span class="p">();</span>
<span class="k">default</span><span class="o">:</span>
<span class="nx">unexpected</span><span class="p">();</span>
<span class="p">}</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-112"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-112">&#182;</a> </div> <p>New's precedence is slightly tricky. It must allow its argument
to be a <code>[]</code> or dot subscript expression, but not a call — at
least, not without wrapping it in parentheses. Thus, it uses the </p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">parseNew</span><span class="p">()</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">node</span> <span class="o">=</span> <span class="nx">startNode</span><span class="p">();</span>
<span class="nx">next</span><span class="p">();</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">callee</span> <span class="o">=</span> <span class="nx">parseSubscripts</span><span class="p">(</span><span class="nx">parseExprAtom</span><span class="p">(</span><span class="kc">false</span><span class="p">),</span> <span class="kc">true</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">eat</span><span class="p">(</span><span class="nx">_parenL</span><span class="p">))</span> <span class="nx">node</span><span class="p">.</span><span class="nx">arguments</span> <span class="o">=</span> <span class="nx">parseExprList</span><span class="p">(</span><span class="nx">_parenR</span><span class="p">,</span> <span class="kc">false</span><span class="p">);</span>
<span class="k">else</span> <span class="nx">node</span><span class="p">.</span><span class="nx">arguments</span> <span class="o">=</span> <span class="p">[];</span>
<span class="k">return</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">&quot;NewExpression&quot;</span><span class="p">);</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-113"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-113">&#182;</a> </div> <p>Parse an object literal.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">parseObj</span><span class="p">()</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">node</span> <span class="o">=</span> <span class="nx">startNode</span><span class="p">(),</span> <span class="nx">first</span> <span class="o">=</span> <span class="kc">true</span><span class="p">,</span> <span class="nx">sawGetSet</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">properties</span> <span class="o">=</span> <span class="p">[];</span>
<span class="nx">next</span><span class="p">();</span>
<span class="k">while</span> <span class="p">(</span><span class="o">!</span><span class="nx">eat</span><span class="p">(</span><span class="nx">_braceR</span><span class="p">))</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">first</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">expect</span><span class="p">(</span><span class="nx">_comma</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">allowTrailingCommas</span> <span class="o">&amp;&amp;</span> <span class="nx">eat</span><span class="p">(</span><span class="nx">_braceR</span><span class="p">))</span> <span class="k">break</span><span class="p">;</span>
<span class="p">}</span> <span class="k">else</span> <span class="nx">first</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">prop</span> <span class="o">=</span> <span class="p">{</span><span class="nx">key</span><span class="o">:</span> <span class="nx">parsePropertyName</span><span class="p">()},</span> <span class="nx">isGetSet</span> <span class="o">=</span> <span class="kc">false</span><span class="p">,</span> <span class="nx">kind</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">eat</span><span class="p">(</span><span class="nx">_colon</span><span class="p">))</span> <span class="p">{</span>
<span class="nx">prop</span><span class="p">.</span><span class="nx">value</span> <span class="o">=</span> <span class="nx">parseExpression</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span>
<span class="nx">kind</span> <span class="o">=</span> <span class="nx">prop</span><span class="p">.</span><span class="nx">kind</span> <span class="o">=</span> <span class="s2">&quot;init&quot;</span><span class="p">;</span>
<span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">ecmaVersion</span> <span class="o">&gt;=</span> <span class="mi">5</span> <span class="o">&amp;&amp;</span> <span class="nx">prop</span><span class="p">.</span><span class="nx">key</span><span class="p">.</span><span class="nx">type</span> <span class="o">===</span> <span class="s2">&quot;Identifier&quot;</span> <span class="o">&amp;&amp;</span>
<span class="p">(</span><span class="nx">prop</span><span class="p">.</span><span class="nx">key</span><span class="p">.</span><span class="nx">name</span> <span class="o">===</span> <span class="s2">&quot;get&quot;</span> <span class="o">||</span> <span class="nx">prop</span><span class="p">.</span><span class="nx">key</span><span class="p">.</span><span class="nx">name</span> <span class="o">===</span> <span class="s2">&quot;set&quot;</span><span class="p">))</span> <span class="p">{</span>
<span class="nx">isGetSet</span> <span class="o">=</span> <span class="nx">sawGetSet</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
<span class="nx">kind</span> <span class="o">=</span> <span class="nx">prop</span><span class="p">.</span><span class="nx">kind</span> <span class="o">=</span> <span class="nx">prop</span><span class="p">.</span><span class="nx">key</span><span class="p">.</span><span class="nx">name</span><span class="p">;</span>
<span class="nx">prop</span><span class="p">.</span><span class="nx">key</span> <span class="o">=</span> <span class="nx">parsePropertyName</span><span class="p">();</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">tokType</span> <span class="o">===</span> <span class="nx">_parenL</span><span class="p">)</span> <span class="nx">unexpected</span><span class="p">();</span>
<span class="nx">prop</span><span class="p">.</span><span class="nx">value</span> <span class="o">=</span> <span class="nx">parseFunction</span><span class="p">(</span><span class="nx">startNode</span><span class="p">(),</span> <span class="kc">false</span><span class="p">);</span>
<span class="p">}</span> <span class="k">else</span> <span class="nx">unexpected</span><span class="p">();</span></pre></div> </td> </tr> <tr id="section-114"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-114">&#182;</a> </div> <p>getters and setters are not allowed to clash — either with
each other or with an init property — and in strict mode,
init properties are also not allowed to be repeated.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span> <span class="p">(</span><span class="nx">prop</span><span class="p">.</span><span class="nx">key</span><span class="p">.</span><span class="nx">type</span> <span class="o">===</span> <span class="s2">&quot;Identifier&quot;</span> <span class="o">&amp;&amp;</span> <span class="p">(</span><span class="nx">strict</span> <span class="o">||</span> <span class="nx">sawGetSet</span><span class="p">))</span> <span class="p">{</span>
<span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="nx">node</span><span class="p">.</span><span class="nx">properties</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="o">++</span><span class="nx">i</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">other</span> <span class="o">=</span> <span class="nx">node</span><span class="p">.</span><span class="nx">properties</span><span class="p">[</span><span class="nx">i</span><span class="p">];</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">other</span><span class="p">.</span><span class="nx">key</span><span class="p">.</span><span class="nx">name</span> <span class="o">===</span> <span class="nx">prop</span><span class="p">.</span><span class="nx">key</span><span class="p">.</span><span class="nx">name</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">conflict</span> <span class="o">=</span> <span class="nx">kind</span> <span class="o">==</span> <span class="nx">other</span><span class="p">.</span><span class="nx">kind</span> <span class="o">||</span> <span class="nx">isGetSet</span> <span class="o">&amp;&amp;</span> <span class="nx">other</span><span class="p">.</span><span class="nx">kind</span> <span class="o">===</span> <span class="s2">&quot;init&quot;</span> <span class="o">||</span>
<span class="nx">kind</span> <span class="o">===</span> <span class="s2">&quot;init&quot;</span> <span class="o">&amp;&amp;</span> <span class="p">(</span><span class="nx">other</span><span class="p">.</span><span class="nx">kind</span> <span class="o">===</span> <span class="s2">&quot;get&quot;</span> <span class="o">||</span> <span class="nx">other</span><span class="p">.</span><span class="nx">kind</span> <span class="o">===</span> <span class="s2">&quot;set&quot;</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">conflict</span> <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="nx">strict</span> <span class="o">&amp;&amp;</span> <span class="nx">kind</span> <span class="o">===</span> <span class="s2">&quot;init&quot;</span> <span class="o">&amp;&amp;</span> <span class="nx">other</span><span class="p">.</span><span class="nx">kind</span> <span class="o">===</span> <span class="s2">&quot;init&quot;</span><span class="p">)</span> <span class="nx">conflict</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">conflict</span><span class="p">)</span> <span class="nx">raise</span><span class="p">(</span><span class="nx">prop</span><span class="p">.</span><span class="nx">key</span><span class="p">.</span><span class="nx">start</span><span class="p">,</span> <span class="s2">&quot;Redefinition of property&quot;</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">properties</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">prop</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">return</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">&quot;ObjectExpression&quot;</span><span class="p">);</span>
<span class="p">}</span>
<span class="kd">function</span> <span class="nx">parsePropertyName</span><span class="p">()</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">tokType</span> <span class="o">===</span> <span class="nx">_num</span> <span class="o">||</span> <span class="nx">tokType</span> <span class="o">===</span> <span class="nx">_string</span><span class="p">)</span> <span class="k">return</span> <span class="nx">parseExprAtom</span><span class="p">();</span>
<span class="k">return</span> <span class="nx">parseIdent</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-115"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-115">&#182;</a> </div> <p>Parse a function declaration or literal (depending on the
<code>isStatement</code> parameter).</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">parseFunction</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="nx">isStatement</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">tokType</span> <span class="o">===</span> <span class="nx">_name</span><span class="p">)</span> <span class="nx">node</span><span class="p">.</span><span class="nx">id</span> <span class="o">=</span> <span class="nx">parseIdent</span><span class="p">();</span>
<span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">isStatement</span><span class="p">)</span> <span class="nx">unexpected</span><span class="p">();</span>
<span class="k">else</span> <span class="nx">node</span><span class="p">.</span><span class="nx">id</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">params</span> <span class="o">=</span> <span class="p">[];</span>
<span class="kd">var</span> <span class="nx">first</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
<span class="nx">expect</span><span class="p">(</span><span class="nx">_parenL</span><span class="p">);</span>
<span class="k">while</span> <span class="p">(</span><span class="o">!</span><span class="nx">eat</span><span class="p">(</span><span class="nx">_parenR</span><span class="p">))</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">first</span><span class="p">)</span> <span class="nx">expect</span><span class="p">(</span><span class="nx">_comma</span><span class="p">);</span> <span class="k">else</span> <span class="nx">first</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">params</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">parseIdent</span><span class="p">());</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-116"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-116">&#182;</a> </div> <p>Start a new scope with regard to labels and the <code>inFunction</code>
flag (restore them to their old value afterwards).</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">oldInFunc</span> <span class="o">=</span> <span class="nx">inFunction</span><span class="p">,</span> <span class="nx">oldLabels</span> <span class="o">=</span> <span class="nx">labels</span><span class="p">;</span>
<span class="nx">inFunction</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span> <span class="nx">labels</span> <span class="o">=</span> <span class="p">[];</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">body</span> <span class="o">=</span> <span class="nx">parseBlock</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span>
<span class="nx">inFunction</span> <span class="o">=</span> <span class="nx">oldInFunc</span><span class="p">;</span> <span class="nx">labels</span> <span class="o">=</span> <span class="nx">oldLabels</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-117"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-117">&#182;</a> </div> <p>If this is a strict mode function, verify that argument names
are not repeated, and it does not try to bind the words <code>eval</code>
or <code>arguments</code>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span> <span class="p">(</span><span class="nx">strict</span> <span class="o">||</span> <span class="nx">node</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">length</span> <span class="o">&amp;&amp;</span> <span class="nx">isUseStrict</span><span class="p">(</span><span class="nx">node</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">body</span><span class="p">[</span><span class="mi">0</span><span class="p">]))</span> <span class="p">{</span>
<span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="nx">node</span><span class="p">.</span><span class="nx">id</span> <span class="o">?</span> <span class="o">-</span><span class="mi">1</span> <span class="o">:</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="nx">node</span><span class="p">.</span><span class="nx">params</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="o">++</span><span class="nx">i</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">id</span> <span class="o">=</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="mi">0</span> <span class="o">?</span> <span class="nx">node</span><span class="p">.</span><span class="nx">id</span> <span class="o">:</span> <span class="nx">node</span><span class="p">.</span><span class="nx">params</span><span class="p">[</span><span class="nx">i</span><span class="p">];</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">isStrictReservedWord</span><span class="p">(</span><span class="nx">id</span><span class="p">.</span><span class="nx">name</span><span class="p">)</span> <span class="o">||</span> <span class="nx">isStrictBadIdWord</span><span class="p">(</span><span class="nx">id</span><span class="p">.</span><span class="nx">name</span><span class="p">))</span>
<span class="nx">raise</span><span class="p">(</span><span class="nx">id</span><span class="p">.</span><span class="nx">start</span><span class="p">,</span> <span class="s2">&quot;Defining &#39;&quot;</span> <span class="o">+</span> <span class="nx">id</span><span class="p">.</span><span class="nx">name</span> <span class="o">+</span> <span class="s2">&quot;&#39; in strict mode&quot;</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">i</span> <span class="o">&gt;=</span> <span class="mi">0</span><span class="p">)</span> <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">j</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">j</span> <span class="o">&lt;</span> <span class="nx">i</span><span class="p">;</span> <span class="o">++</span><span class="nx">j</span><span class="p">)</span> <span class="k">if</span> <span class="p">(</span><span class="nx">id</span><span class="p">.</span><span class="nx">name</span> <span class="o">===</span> <span class="nx">node</span><span class="p">.</span><span class="nx">params</span><span class="p">[</span><span class="nx">j</span><span class="p">].</span><span class="nx">name</span><span class="p">)</span>
<span class="nx">raise</span><span class="p">(</span><span class="nx">id</span><span class="p">.</span><span class="nx">start</span><span class="p">,</span> <span class="s2">&quot;Argument name clash in strict mode&quot;</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="k">return</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="nx">isStatement</span> <span class="o">?</span> <span class="s2">&quot;FunctionDeclaration&quot;</span> <span class="o">:</span> <span class="s2">&quot;FunctionExpression&quot;</span><span class="p">);</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-118"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-118">&#182;</a> </div> <p>Parses a comma-separated list of expressions, and returns them as
an array. <code>close</code> is the token type that ends the list, and
<code>allowEmpty</code> can be turned on to allow subsequent commas with
nothing in between them to be parsed as <code>null</code> (which is needed
for array literals).</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">parseExprList</span><span class="p">(</span><span class="nx">close</span><span class="p">,</span> <span class="nx">allowTrailingComma</span><span class="p">,</span> <span class="nx">allowEmpty</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">elts</span> <span class="o">=</span> <span class="p">[],</span> <span class="nx">first</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
<span class="k">while</span> <span class="p">(</span><span class="o">!</span><span class="nx">eat</span><span class="p">(</span><span class="nx">close</span><span class="p">))</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">first</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">expect</span><span class="p">(</span><span class="nx">_comma</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">allowTrailingComma</span> <span class="o">&amp;&amp;</span> <span class="nx">options</span><span class="p">.</span><span class="nx">allowTrailingCommas</span> <span class="o">&amp;&amp;</span> <span class="nx">eat</span><span class="p">(</span><span class="nx">close</span><span class="p">))</span> <span class="k">break</span><span class="p">;</span>
<span class="p">}</span> <span class="k">else</span> <span class="nx">first</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">allowEmpty</span> <span class="o">&amp;&amp;</span> <span class="nx">tokType</span> <span class="o">===</span> <span class="nx">_comma</span><span class="p">)</span> <span class="nx">elts</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="kc">null</span><span class="p">);</span>
<span class="k">else</span> <span class="nx">elts</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">parseExpression</span><span class="p">(</span><span class="kc">true</span><span class="p">));</span>
<span class="p">}</span>
<span class="k">return</span> <span class="nx">elts</span><span class="p">;</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-119"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-119">&#182;</a> </div> <p>Parse the next token as an identifier. If <code>liberal</code> is true (used
when parsing properties), it will also convert keywords into
identifiers.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">parseIdent</span><span class="p">(</span><span class="nx">liberal</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">node</span> <span class="o">=</span> <span class="nx">startNode</span><span class="p">();</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">name</span> <span class="o">=</span> <span class="nx">tokType</span> <span class="o">===</span> <span class="nx">_name</span> <span class="o">?</span> <span class="nx">tokVal</span> <span class="o">:</span> <span class="p">(</span><span class="nx">liberal</span> <span class="o">&amp;&amp;</span> <span class="nx">tokType</span><span class="p">.</span><span class="nx">keyword</span><span class="p">)</span> <span class="o">||</span> <span class="nx">unexpected</span><span class="p">();</span>
<span class="nx">next</span><span class="p">();</span>
<span class="k">return</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">&quot;Identifier&quot;</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">})(</span><span class="k">typeof</span> <span class="nx">exports</span> <span class="o">===</span> <span class="s2">&quot;undefined&quot;</span> <span class="o">?</span> <span class="p">(</span><span class="nb">window</span><span class="p">.</span><span class="nx">acorn</span> <span class="o">=</span> <span class="p">{})</span> <span class="o">:</span> <span class="nx">exports</span><span class="p">);</span>
</pre></div> </td> </tr> </tbody> </table> </div> </body> </html>