[Pkg-javascript-commits] [node-acorn-jsx] 190/484: Split up `parseStatement()`

Bastien Roucariès rouca at moszumanska.debian.org
Sat Aug 19 14:20:25 UTC 2017


This is an automated email from the git hooks/post-receive script.

rouca pushed a commit to branch master
in repository node-acorn-jsx.

commit 29feccf3cd70862c93d34870f5feb56ae745b9cf
Author: impinball <impinball at gmail.com>
Date:   Tue Jun 3 22:13:24 2014 -0400

    Split up `parseStatement()`
    
    It was purely interpreted by the V8 engine. Splitting it up allows the
    individual pieces to be optimized, so less is interpreted.
---
 acorn.js   | 422 +++++++++++++++++++++++++++++++++----------------------------
 index.html | 381 ++++++++++++++++++++++++++++++-------------------------
 2 files changed, 437 insertions(+), 366 deletions(-)

diff --git a/acorn.js b/acorn.js
index 7de370d..9de7353 100644
--- a/acorn.js
+++ b/acorn.js
@@ -1167,211 +1167,245 @@
     // complexity.
 
     switch (starttype) {
-    case _break: case _continue:
-      next();
-      var isBreak = starttype === _break;
-      if (eat(_semi) || canInsertSemicolon()) node.label = null;
-      else if (tokType !== _name) unexpected();
-      else {
-        node.label = parseIdent();
-        semicolon();
-      }
-
-      // Verify that there is an actual destination to break or
-      // continue to.
-      for (var i = 0; i < labels.length; ++i) {
-        var lab = labels[i];
-        if (node.label == null || lab.name === node.label.name) {
-          if (lab.kind != null && (isBreak || lab.kind === "loop")) break;
-          if (node.label && isBreak) break;
-        }
-      }
-      if (i === labels.length) raise(node.start, "Unsyntactic " + starttype.keyword);
-      return finishNode(node, isBreak ? "BreakStatement" : "ContinueStatement");
-
-    case _debugger:
-      next();
-      semicolon();
-      return finishNode(node, "DebuggerStatement");
-
-    case _do:
-      next();
-      labels.push(loopLabel);
-      node.body = parseStatement();
-      labels.pop();
-      expect(_while);
-      node.test = parseParenExpression();
-      semicolon();
-      return finishNode(node, "DoWhileStatement");
-
-      // Disambiguating between a `for` and a `for`/`in` loop is
-      // non-trivial. Basically, we have to parse the init `var`
-      // statement or expression, disallowing the `in` operator (see
-      // the second parameter to `parseExpression`), and then check
-      // whether the next token is `in`. When there is no init part
-      // (semicolon immediately after the opening parenthesis), it is
-      // a regular `for` loop.
-
-    case _for:
-      next();
-      labels.push(loopLabel);
-      expect(_parenL);
-      if (tokType === _semi) return parseFor(node, null);
-      if (tokType === _var || tokType === _let) {
-        var varKind = tokType.keyword;
-        var init = startNode();
-        next();
-        parseVar(init, true, varKind);
-        finishNode(init, "VariableDeclaration");
-        if (init.declarations.length === 1 && eat(_in))
-          return parseForIn(node, init);
-        return parseFor(node, init);
-      }
-      var init = parseExpression(false, true);
-      if (eat(_in)) {checkLVal(init); return parseForIn(node, init);}
-      return parseFor(node, init);
-
-    case _function:
-      next();
-      return parseFunction(node, true);
-
-    case _if:
-      next();
-      node.test = parseParenExpression();
-      node.consequent = parseStatement();
-      node.alternate = eat(_else) ? parseStatement() : null;
-      return finishNode(node, "IfStatement");
-
-    case _return:
-      if (!inFunction && !options.allowReturnOutsideFunction)
-        raise(tokStart, "'return' outside of function");
-      next();
-
-      // In `return` (and `break`/`continue`), the keywords with
-      // optional arguments, we eagerly look for a semicolon or the
-      // possibility to insert one.
-
-      if (eat(_semi) || canInsertSemicolon()) node.argument = null;
-      else { node.argument = parseExpression(); semicolon(); }
-      return finishNode(node, "ReturnStatement");
-
-    case _switch:
-      next();
-      node.discriminant = parseParenExpression();
-      node.cases = [];
-      expect(_braceL);
-      labels.push(switchLabel);
-
-      // Statements under must be grouped (by label) in SwitchCase
-      // nodes. `cur` is used to keep the node that we are currently
-      // adding statements to.
-
-      for (var cur, sawDefault; tokType != _braceR;) {
-        if (tokType === _case || tokType === _default) {
-          var isCase = tokType === _case;
-          if (cur) finishNode(cur, "SwitchCase");
-          node.cases.push(cur = startNode());
-          cur.consequent = [];
-          next();
-          if (isCase) cur.test = parseExpression();
-          else {
-            if (sawDefault) raise(lastStart, "Multiple default clauses"); sawDefault = true;
-            cur.test = null;
-          }
-          expect(_colon);
-        } else {
-          if (!cur) unexpected();
-          cur.consequent.push(parseStatement());
-        }
-      }
-      if (cur) finishNode(cur, "SwitchCase");
-      next(); // Closing brace
-      labels.pop();
-      return finishNode(node, "SwitchStatement");
-
-    case _throw:
-      next();
-      if (newline.test(input.slice(lastEnd, tokStart)))
-        raise(lastEnd, "Illegal newline after throw");
-      node.argument = parseExpression();
-      semicolon();
-      return finishNode(node, "ThrowStatement");
-
-    case _try:
-      next();
-      node.block = parseBlock();
-      node.handler = null;
-      if (tokType === _catch) {
-        var clause = startNode();
-        next();
-        expect(_parenL);
-        clause.param = parseIdent();
-        if (strict && isStrictBadIdWord(clause.param.name))
-          raise(clause.param.start, "Binding " + clause.param.name + " in strict mode");
-        expect(_parenR);
-        clause.guard = null;
-        clause.body = parseBlock();
-        node.handler = finishNode(clause, "CatchClause");
-      }
-      node.guardedHandlers = empty;
-      node.finalizer = eat(_finally) ? parseBlock() : null;
-      if (!node.handler && !node.finalizer)
-        raise(node.start, "Missing catch or finally clause");
-      return finishNode(node, "TryStatement");
-
-    case _const:
-    case _let:
-    case _var:
-      next();
-      parseVar(node, false, starttype.keyword);
-      semicolon();
-      return finishNode(node, "VariableDeclaration");
-
-    case _while:
-      next();
-      node.test = parseParenExpression();
-      labels.push(loopLabel);
-      node.body = parseStatement();
-      labels.pop();
-      return finishNode(node, "WhileStatement");
-
-    case _with:
-      if (strict) raise(tokStart, "'with' in strict mode");
-      next();
-      node.object = parseParenExpression();
-      node.body = parseStatement();
-      return finishNode(node, "WithStatement");
-
-    case _braceL:
-      return parseBlock();
-
-    case _semi:
-      next();
-      return finishNode(node, "EmptyStatement");
+    case _break: case _continue: return parseBreakContinueStatement(node, starttype.keyword);
+    case _debugger: return parseDebuggerStatement(node);
+    case _do: return parseDoStatement(node);
+    case _for: return parseForStatement(node);
+    case _function: return parseFunctionStatement(node);
+    case _if: return parseIfStatement(node);
+    case _return: return parseReturnStatement(node);
+    case _switch: return parseSwitchStatement(node);
+    case _throw: return parseThrowStatement(node);
+    case _try: return parseTryStatement(node);
+    case _var: case _let: case _const: return parseVarStatement(node, starttype.keyword);
+    case _while: return parseWhileStatement(node);
+    case _with: return parseWithStatement(node);
+    case _braceL: return parseBlock(); // no point creating a function for this
+    case _semi: return parseEmptyStatement(node);
 
       // 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.
-
     default:
       var maybeName = tokVal, expr = parseExpression();
-      if (starttype === _name && expr.type === "Identifier" && eat(_colon)) {
-        for (var i = 0; i < labels.length; ++i)
-          if (labels[i].name === maybeName) raise(expr.start, "Label '" + maybeName + "' is already declared");
-        var kind = tokType.isLoop ? "loop" : tokType === _switch ? "switch" : null;
-        labels.push({name: maybeName, kind: kind});
-        node.body = parseStatement();
-        labels.pop();
-        node.label = expr;
-        return finishNode(node, "LabeledStatement");
+      if (starttype === _name && expr.type === "Identifier" && eat(_colon))
+        return parseLabeledStatement(node, maybeName, expr);
+      else return parseExpressionStatement(node, expr);
+    }
+  }
+  
+  function parseBreakContinueStatement(node, keyword) {
+    var isBreak = keyword == "break";
+    next();
+    if (eat(_semi) || canInsertSemicolon()) node.label = null;
+    else if (tokType !== _name) unexpected();
+    else {
+      node.label = parseIdent();
+      semicolon();
+    }
+
+    // Verify that there is an actual destination to break or
+    // continue to.
+    for (var i = 0; i < labels.length; ++i) {
+      var lab = labels[i];
+      if (node.label == null || lab.name === node.label.name) {
+        if (lab.kind != null && (isBreak || lab.kind === "loop")) break;
+        if (node.label && isBreak) break;
+      }
+    }
+    if (i === labels.length) raise(node.start, "Unsyntactic " + keyword);
+    return finishNode(node, isBreak ? "BreakStatement" : "ContinueStatement");
+  }
+  
+  function parseDebuggerStatement(node) {
+    next();
+    semicolon();
+    return finishNode(node, "DebuggerStatement");
+  }
+  
+  function parseDoStatement(node) {
+    next();
+    labels.push(loopLabel);
+    node.body = parseStatement();
+    labels.pop();
+    expect(_while);
+    node.test = parseParenExpression();
+    semicolon();
+    return finishNode(node, "DoWhileStatement");
+  }
+  
+  // Disambiguating between a `for` and a `for`/`in` loop is
+  // non-trivial. Basically, we have to parse the init `var`
+  // statement or expression, disallowing the `in` operator (see
+  // the second parameter to `parseExpression`), and then check
+  // whether the next token is `in`. When there is no init part
+  // (semicolon immediately after the opening parenthesis), it is
+  // a regular `for` loop.
+  
+  function parseForStatement(node) {
+    next();
+    labels.push(loopLabel);
+    expect(_parenL);
+    if (tokType === _semi) return parseFor(node, null);
+    if (tokType === _var || tokType === _let) {
+      var init = startNode(), varKind = tokType.keyword;
+      next();
+      parseVar(init, true, varKind);
+      finishNode(init, "VariableDeclaration");
+      if (init.declarations.length === 1 && eat(_in))
+        return parseForIn(node, init);
+      return parseFor(node, init);
+    }
+    var init = parseExpression(false, true);
+    if (eat(_in)) {checkLVal(init); return parseForIn(node, init);}
+    return parseFor(node, init);
+  }
+  
+  function parseFunctionStatement(node) {
+    next();
+    return parseFunction(node, true);
+  }
+  
+  function parseIfStatement(node) {
+    next();
+    node.test = parseParenExpression();
+    node.consequent = parseStatement();
+    node.alternate = eat(_else) ? parseStatement() : null;
+    return finishNode(node, "IfStatement");
+  }
+  
+  function parseReturnStatement(node) {
+    if (!inFunction && !options.allowReturnOutsideFunction)
+      raise(tokStart, "'return' outside of function");
+    next();
+
+    // In `return` (and `break`/`continue`), the keywords with
+    // optional arguments, we eagerly look for a semicolon or the
+    // possibility to insert one.
+
+    if (eat(_semi) || canInsertSemicolon()) node.argument = null;
+    else { node.argument = parseExpression(); semicolon(); }
+    return finishNode(node, "ReturnStatement");
+  }
+  
+  function parseSwitchStatement(node) {
+    next();
+    node.discriminant = parseParenExpression();
+    node.cases = [];
+    expect(_braceL);
+    labels.push(switchLabel);
+
+    // Statements under must be grouped (by label) in SwitchCase
+    // nodes. `cur` is used to keep the node that we are currently
+    // adding statements to.
+
+    for (var cur, sawDefault; tokType != _braceR;) {
+      if (tokType === _case || tokType === _default) {
+        var isCase = tokType === _case;
+        if (cur) finishNode(cur, "SwitchCase");
+        node.cases.push(cur = startNode());
+        cur.consequent = [];
+        next();
+        if (isCase) cur.test = parseExpression();
+        else {
+          if (sawDefault) raise(lastStart, "Multiple default clauses"); sawDefault = true;
+          cur.test = null;
+        }
+        expect(_colon);
       } else {
-        node.expression = expr;
-        semicolon();
-        return finishNode(node, "ExpressionStatement");
+        if (!cur) unexpected();
+        cur.consequent.push(parseStatement());
       }
     }
+    if (cur) finishNode(cur, "SwitchCase");
+    next(); // Closing brace
+    labels.pop();
+    return finishNode(node, "SwitchStatement");
+  }
+  
+  function parseThrowStatement(node) {
+    next();
+    if (newline.test(input.slice(lastEnd, tokStart)))
+      raise(lastEnd, "Illegal newline after throw");
+    node.argument = parseExpression();
+    semicolon();
+    return finishNode(node, "ThrowStatement");next();
+    if (newline.test(input.slice(lastEnd, tokStart)))
+      raise(lastEnd, "Illegal newline after throw");
+    node.argument = parseExpression();
+    semicolon();
+    return finishNode(node, "ThrowStatement");
+  }
+  
+  function parseTryStatement(node) {
+    next();
+    node.block = parseBlock();
+    node.handler = null;
+    if (tokType === _catch) {
+      var clause = startNode();
+      next();
+      expect(_parenL);
+      clause.param = parseIdent();
+      if (strict && isStrictBadIdWord(clause.param.name))
+        raise(clause.param.start, "Binding " + clause.param.name + " in strict mode");
+      expect(_parenR);
+      clause.guard = null;
+      clause.body = parseBlock();
+      node.handler = finishNode(clause, "CatchClause");
+    }
+    node.guardedHandlers = empty;
+    node.finalizer = eat(_finally) ? parseBlock() : null;
+    if (!node.handler && !node.finalizer)
+      raise(node.start, "Missing catch or finally clause");
+    return finishNode(node, "TryStatement");
+  }
+  
+  function parseVarStatement(node, kind) {
+    next();
+    parseVar(node, false, kind);
+    semicolon();
+    return finishNode(node, "VariableDeclaration");
+  }
+  
+  function parseWhileStatement(node) {
+    next();
+    node.test = parseParenExpression();
+    labels.push(loopLabel);
+    node.body = parseStatement();
+    labels.pop();
+    return finishNode(node, "WhileStatement");
+  }
+  
+  function parseWithStatement(node) {
+    if (strict) raise(tokStart, "'with' in strict mode");
+    next();
+    node.object = parseParenExpression();
+    node.body = parseStatement();
+    return finishNode(node, "WithStatement");
+  }
+  
+  function parseEmptyStatement(node) {
+    next();
+    return finishNode(node, "EmptyStatement");
+  }
+  
+  function parseLabeledStatement(node, maybeName, expr) {
+    for (var i = 0; i < labels.length; ++i)
+      if (labels[i].name === maybeName) raise(expr.start, "Label '" + maybeName + "' is already declared");
+    var kind = tokType.isLoop ? "loop" : tokType === _switch ? "switch" : null;
+    labels.push({name: maybeName, kind: kind});
+    node.body = parseStatement();
+    labels.pop();
+    node.label = expr;
+    return finishNode(node, "LabeledStatement");
+  }
+  
+  function parseExpressionStatement(node, expr) {
+    node.expression = expr;
+    semicolon();
+    return finishNode(node, "ExpressionStatement");
   }
 
   // Used for constructs like `switch` and `if` that insist on
diff --git a/index.html b/index.html
index 187bf39..1092860 100644
--- a/index.html
+++ b/index.html
@@ -832,192 +832,229 @@ does not help.</p>             </td>             <td class="code">
     <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-97">             <td class="docs">               <div class="pilwrap">                 <a class="pilcrow" href="#section-97">¶</a>     [...]
 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-98">             <td class="docs">               <div class="pilwrap">                 <a class="pilcrow" href="#section-98">¶</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"><</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 [...]
-        <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  [...]
-          <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">&&</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">"loop"</span><span class="p">))</span> <span cl [...]
-          <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="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">"Unsyntactic "</span> <span class="o">+</span> <span class="nx">starttype</span><span cl [...]
-      <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">"BreakStatement"</span> <span class="o">:</span> <span class="s2">"ContinueStatement"</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="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">"DebuggerStatement"</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="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="k">return</span> <span class="nx">parseBreakContinueStatement</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="nx">starttype</span><span class="p">.</span><span class="nx">keyword</span><span class="p">);</span>
+    <span class="k">case</span> <span class="nx">_debugger</span><span class="o">:</span> <span class="k">return</span> <span class="nx">parseDebuggerStatement</span><span class="p">(</span><span class="nx">node</span><span class="p">);</span>
+    <span class="k">case</span> <span class="nx">_do</span><span class="o">:</span> <span class="k">return</span> <span class="nx">parseDoStatement</span><span class="p">(</span><span class="nx">node</span><span class="p">);</span>
+    <span class="k">case</span> <span class="nx">_for</span><span class="o">:</span> <span class="k">return</span> <span class="nx">parseForStatement</span><span class="p">(</span><span class="nx">node</span><span class="p">);</span>
+    <span class="k">case</span> <span class="nx">_function</span><span class="o">:</span> <span class="k">return</span> <span class="nx">parseFunctionStatement</span><span class="p">(</span><span class="nx">node</span><span class="p">);</span>
+    <span class="k">case</span> <span class="nx">_if</span><span class="o">:</span> <span class="k">return</span> <span class="nx">parseIfStatement</span><span class="p">(</span><span class="nx">node</span><span class="p">);</span>
+    <span class="k">case</span> <span class="nx">_return</span><span class="o">:</span> <span class="k">return</span> <span class="nx">parseReturnStatement</span><span class="p">(</span><span class="nx">node</span><span class="p">);</span>
+    <span class="k">case</span> <span class="nx">_switch</span><span class="o">:</span> <span class="k">return</span> <span class="nx">parseSwitchStatement</span><span class="p">(</span><span class="nx">node</span><span class="p">);</span>
+    <span class="k">case</span> <span class="nx">_throw</span><span class="o">:</span> <span class="k">return</span> <span class="nx">parseThrowStatement</span><span class="p">(</span><span class="nx">node</span><span class="p">);</span>
+    <span class="k">case</span> <span class="nx">_try</span><span class="o">:</span> <span class="k">return</span> <span class="nx">parseTryStatement</span><span class="p">(</span><span class="nx">node</span><span class="p">);</span>
+    <span class="k">case</span> <span class="nx">_var</span><span class="o">:</span> <span class="k">case</span> <span class="nx">_let</span><span class="o">:</span> <span class="k">case</span> <span class="nx">_const</span><span class="o">:</span> <span class="k">return</span> <span class="nx">parseVarStatement</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="nx">starttype</span><span class="p">.</span><span class="nx">keyword</span><span c [...]
+    <span class="k">case</span> <span class="nx">_while</span><span class="o">:</span> <span class="k">return</span> <span class="nx">parseWhileStatement</span><span class="p">(</span><span class="nx">node</span><span class="p">);</span>
+    <span class="k">case</span> <span class="nx">_with</span><span class="o">:</span> <span class="k">return</span> <span class="nx">parseWithStatement</span><span class="p">(</span><span class="nx">node</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="c1">// no point creating a function for this</span>
+    <span class="k">case</span> <span class="nx">_semi</span><span class="o">:</span> <span class="k">return</span> <span class="nx">parseEmptyStatement</span><span class="p">(</span><span class="nx">node</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">¶</a>               </div>        [...]
+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">&&</span> <span class="nx">expr</span><span class="p">.</span><span class="nx">type</span> <span class="o">===</span> <span class="s2">"Identifier"</span> <span class="o">&&</span> <span class="nx">eat</span><span class="p">(</span><span class="nx">_colon</span><span class="p">))</span>
+        <span class="k">return</span> <span class="nx">parseLabeledStatement</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="nx">maybeName</span><span class="p">,</span> <span class="nx">expr</span><span class="p">);</span>
+      <span class="k">else</span> <span class="k">return</span> <span class="nx">parseExpressionStatement</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="nx">expr</span><span class="p">);</span>
+    <span class="p">}</span>
+  <span class="p">}</span>
+  
+  <span class="kd">function</span> <span class="nx">parseBreakContinueStatement</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="nx">keyword</span><span class="p">)</span> <span class="p">{</span>
+    <span class="kd">var</span> <span class="nx">isBreak</span> <span class="o">=</span> <span class="nx">keyword</span> <span class="o">==</span> <span class="s2">"break"</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">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="k">return</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">"DoWhileStatement"</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">¶</a>               </div>               <p>D [...]
+    <span class="p">}</span></pre></div>             </td>           </tr>                               <tr id="section-99">             <td class="docs">               <div class="pilwrap">                 <a class="pilcrow" href="#section-99">¶</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"><</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=" [...]
+      <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 cl [...]
+        <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">&&</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">"loop"</span><span class="p">))</span> <span clas [...]
+        <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="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">"Unsyntactic "</span> <span class="o">+</span> <span class="nx">keyword</span><span class= [...]
+    <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">"BreakStatement"</span> <span class="o">:</span> <span class="s2">"ContinueStatement"</span><span class="p">);</span>
+  <span class="p">}</span>
+  
+  <span class="kd">function</span> <span class="nx">parseDebuggerStatement</span><span class="p">(</span><span class="nx">node</span><span class="p">)</span> <span class="p">{</span>
+    <span class="nx">next</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">"DebuggerStatement"</span><span class="p">);</span>
+  <span class="p">}</span>
+  
+  <span class="kd">function</span> <span class="nx">parseDoStatement</span><span class="p">(</span><span class="nx">node</span><span class="p">)</span> <span class="p">{</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">"DoWhileStatement"</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">¶</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>
+a regular <code>for</code> loop.</p>             </td>             <td class="code">               <div class="highlight"><pre>  
+  <span class="kd">function</span> <span class="nx">parseForStatement</span><span class="p">(</span><span class="nx">node</span><span class="p">)</span> <span class="p">{</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="o">||</span> <span class="nx">tokType</span> <span class="o">===</span> <span class="nx">_let</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">varKind</span> <span class="o">=</span> <span class="nx">tokType</span><span class="p">.</span><span class="nx">keyword</span><span class="p">;</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="o">||</span> <span class="nx">tokType</span> <span class="o">===</span> <span class="nx">_let</span><span class="p">)</span> <span class="p">{</span>
-        <span class="kd">var</span> <span class="nx">varKind</span> <span class="o">=</span> <span class="nx">tokType</span><span class="p">.</span><span class="nx">keyword</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="nx">varKind</span><span class="p">);</span>
-        <span class="nx">finishNode</span><span class="p">(</span><span class="nx">init</span><span class="p">,</span> <span class="s2">"VariableDeclaration"</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">&&</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="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="nx">varKind</span><span class="p">);</span>
+      <span class="nx">finishNode</span><span class="p">(</span><span class="nx">init</span><span class="p">,</span> <span class="s2">"VariableDeclaration"</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">&&</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="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">"IfStatement"</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="o">&&</span> <span class="o">!</span><span class="nx">options</span><span class="p">.</span><span class="nx">allowReturnOutsideFunction</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">"'return' outside of function"</span><span class="p">);</span>
-      <span class="nx">next</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">¶</a>               </div>               <p>In <code>return</code> (and <code>break</code>/<code>continue</code>), the keywords with
+    <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="p">}</span>
+  
+  <span class="kd">function</span> <span class="nx">parseFunctionStatement</span><span class="p">(</span><span class="nx">node</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="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="p">}</span>
+  
+  <span class="kd">function</span> <span class="nx">parseIfStatement</span><span class="p">(</span><span class="nx">node</span><span class="p">)</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">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">"IfStatement"</span><span class="p">);</span>
+  <span class="p">}</span>
+  
+  <span class="kd">function</span> <span class="nx">parseReturnStatement</span><span class="p">(</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="o">!</span><span class="nx">inFunction</span> <span class="o">&&</span> <span class="o">!</span><span class="nx">options</span><span class="p">.</span><span class="nx">allowReturnOutsideFunction</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">"'return' outside of function"</span><span class="p">);</span>
+    <span class="nx">next</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">¶</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 [...]
-      <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">"ReturnStatement"</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-101">             <td class="docs">               <div class="pilwrap">                 <a class="pilcrow" href="#section-101">¶</a>               </div>               <p>Statements under must be grouped (by label) in SwitchCase
+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 c [...]
+    <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">"ReturnStatement"</span><span class="p">);</span>
+  <span class="p">}</span>
+  
+  <span class="kd">function</span> <span class="nx">parseSwitchStatement</span><span class="p">(</span><span class="nx">node</span><span class="p">)</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">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-102">             <td class="docs">               <div class="pilwrap">                 <a class="pilcrow" href="#section-102">¶</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">"SwitchCase"</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">"Multiple default clauses"</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">"SwitchCase"</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">"SwitchStatement"</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">"Illegal newline after throw"</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="k">return</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">"ThrowStatement"</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">handler</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">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>
+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">"SwitchCase"</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="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">&&</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">"Binding "</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">" in strict mod [...]
-        <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">handler</span> <span class="o">=</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">clause</span><span class="p">,</span> <span class="s2">"CatchClause"</span><span class="p">);</span>
-      <span class="p">}</span>
-      <span class="nx">node</span><span class="p">.</span><span class="nx">guardedHandlers</span> <span class="o">=</span> <span class="nx">empty</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">handler</span> <span class="o">&&</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">"Missing catch or finally clause"</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">"TryStatement"</span><span class="p">);</span>
-
-    <span class="k">case</span> <span class="nx">_const</span><span class="o">:</span>
-    <span class="k">case</span> <span class="nx">_let</span><span class="o">:</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">parseVar</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="nx">starttype</span><span class="p">.</span><span class="nx">keyword</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">"VariableDeclaration"</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">"WhileStatement"</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">"'with' in strict mode"</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">"WithStatement"</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">"EmptyStatement"</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">¶</a>               </div>               <p>I [...]
-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">&&</span> <span class="nx">expr</span><span class="p">.</span><span class="nx">type</span> <span class="o">===</span> <span class="s2">"Identifier"</span> <span class="o">&&</span> <span class="nx">eat</span><span class="p">(</span><span class="nx">_colon</span><span class="p">))</span> <span class="p" [...]
-        <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"><</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">"Label '"</span> <span c [...]
-        <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">"loop"</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">"switch"</span> <span class="o">:</span> <span class="kc">null</span><span class=" [...]
-        <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">labels</span><span class="p">.</span><span class="nx">pop</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">"LabeledStatement"</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">"Multiple default clauses"</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="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">"ExpressionStatement"</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">"SwitchCase"</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">"SwitchStatement"</span><span class="p">);</span>
+  <span class="p">}</span>
+  
+  <span class="kd">function</span> <span class="nx">parseThrowStatement</span><span class="p">(</span><span class="nx">node</span><span class="p">)</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">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">"Illegal newline after throw"</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="k">return</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">"ThrowStatement"</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">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">"Illegal newline after throw"</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="k">return</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">"ThrowStatement"</span><span class="p">);</span>
+  <span class="p">}</span>
+  
+  <span class="kd">function</span> <span class="nx">parseTryStatement</span><span class="p">(</span><span class="nx">node</span><span class="p">)</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">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">handler</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">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">&&</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">"Binding "</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">" in strict mode& [...]
+      <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">handler</span> <span class="o">=</span> <span class="nx">finishNode</span><span class="p">(</span><span class="nx">clause</span><span class="p">,</span> <span class="s2">"CatchClause"</span><span class="p">);</span>
+    <span class="p">}</span>
+    <span class="nx">node</span><span class="p">.</span><span class="nx">guardedHandlers</span> <span class="o">=</span> <span class="nx">empty</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">handler</span> <span class="o">&&</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">"Missing catch or finally clause"</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">"TryStatement"</span><span class="p">);</span>
+  <span class="p">}</span>
+  
+  <span class="kd">function</span> <span class="nx">parseVarStatement</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="nx">kind</span><span class="p">)</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">node</span><span class="p">,</span> <span class="kc">false</span><span class="p">,</span> <span class="nx">kind</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">"VariableDeclaration"</span><span class="p">);</span>
+  <span class="p">}</span>
+  
+  <span class="kd">function</span> <span class="nx">parseWhileStatement</span><span class="p">(</span><span class="nx">node</span><span class="p">)</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">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">"WhileStatement"</span><span class="p">);</span>
+  <span class="p">}</span>
+  
+  <span class="kd">function</span> <span class="nx">parseWithStatement</span><span class="p">(</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">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">"'with' in strict mode"</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">"WithStatement"</span><span class="p">);</span>
+  <span class="p">}</span>
+  
+  <span class="kd">function</span> <span class="nx">parseEmptyStatement</span><span class="p">(</span><span class="nx">node</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="nx">finishNode</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="s2">"EmptyStatement"</span><span class="p">);</span>
+  <span class="p">}</span>
+  
+  <span class="kd">function</span> <span class="nx">parseLabeledStatement</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="nx">maybeName</span><span class="p">,</span> <span class="nx">expr</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"><</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">"Label '"</span> <span class [...]
+    <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">"loop"</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">"switch"</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">labels</span><span class="p">.</span><span class="nx">pop</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">"LabeledStatement"</span><span class="p">);</span>
+  <span class="p">}</span>
+  
+  <span class="kd">function</span> <span class="nx">parseExpressionStatement</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="nx">expr</span><span class="p">)</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">"ExpressionStatement"</span><span class="p">);</span>
   <span class="p">}</span></pre></div>             </td>           </tr>                               <tr id="section-103">             <td class="docs">               <div class="pilwrap">                 <a class="pilcrow" href="#section-103">¶</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>

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/node-acorn-jsx.git



More information about the Pkg-javascript-commits mailing list