Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

3596 lines (3589 sloc) 225.084 kb
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Esprima: Coverage Analysis Report</title>
<link rel="stylesheet" type="text/css" href="../assets/style.css"/>
</head>
<style>
span.covered {
}
span.uncovered {
background: #FDD;
}
span.partial {
background: #FFA;
}
</style>
<body>
<div class="container">
<div class="topbar">
<ul class="nav">
<li><a href="../index.html">&larr; Home</a></li>
<li><a href="http://github.com/ariya/esprima">Code</a></li>
<li><a href="../doc/index.html">Documentation</a></li>
<li><a href="http://issues.esprima.org">Issues</a></li>
</ul>
</div>
<h1>Coverage Analysis <small>ensures systematic exercise of the parser</small></h1>
<p><strong>Note</strong>: This is not a live (in-browser) code coverage report.
The analysis is <a href="../doc/index.html#coverage">performed</a> offline
(using <a href="https://github.com/itay/node-cover">node-cover</a>).<br>
Tested revision: <a href='https://github.com/ariya/esprima/commit/eab236d'>eab236d</a>
(dated 6 May 2012 ).</p>
<pre>
<span class='covered'>/*</span>
<span class='covered'> Copyright (C) 2012 Ariya Hidayat <ariya.hidayat@gmail.com></span>
<span class='covered'> Copyright (C) 2012 Mathias Bynens <mathias@qiwi.be></span>
<span class='covered'> Copyright (C) 2012 Joost-Wim Boekesteijn <joost-wim@boekesteijn.nl></span>
<span class='covered'> Copyright (C) 2012 Kris Kowal <kris.kowal@cixar.com></span>
<span class='covered'> Copyright (C) 2012 Yusuke Suzuki <utatane.tea@gmail.com></span>
<span class='covered'> Copyright (C) 2012 Arpad Borsos <arpad.borsos@googlemail.com></span>
<span class='covered'> Copyright (C) 2011 Ariya Hidayat <ariya.hidayat@gmail.com></span>
<span class='covered'> </span>
<span class='covered'> Redistribution and use in source and binary forms, with or without</span>
<span class='covered'> modification, are permitted provided that the following conditions are met:</span>
<span class='covered'> </span>
<span class='covered'> * Redistributions of source code must retain the above copyright</span>
<span class='covered'> notice, this list of conditions and the following disclaimer.</span>
<span class='covered'> * Redistributions in binary form must reproduce the above copyright</span>
<span class='covered'> notice, this list of conditions and the following disclaimer in the</span>
<span class='covered'> documentation and/or other materials provided with the distribution.</span>
<span class='covered'> </span>
<span class='covered'> THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"</span>
<span class='covered'> AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE</span>
<span class='covered'> IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE</span>
<span class='covered'> ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY</span>
<span class='covered'> DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES</span>
<span class='covered'> (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;</span>
<span class='covered'> LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND</span>
<span class='covered'> ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT</span>
<span class='covered'> (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF</span>
<span class='covered'> THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.</span>
<span class='covered'> */</span>
<span class='covered'> </span>
<span class='covered'> /*jslint bitwise:true plusplus:true */</span>
<span class='covered'> /*global esprima:true, exports:true,</span>
<span class='covered'> throwError: true, createLiteral: true, generateStatement: true,</span>
<span class='covered'> parseAssignmentExpression: true, parseBlock: true, parseExpression: true,</span>
<span class='covered'> parseFunctionDeclaration: true, parseFunctionExpression: true,</span>
<span class='covered'> parseFunctionSourceElements: true, parseVariableIdentifier: true,</span>
<span class='covered'> parseLeftHandSideExpression: true,</span>
<span class='covered'> parseStatement: true, parseSourceElement: true */</span>
<span class='covered'> </span>
<span class='covered'> (function (exports) {</span>
<span class='covered'> 'use strict';</span>
<span class='covered'> </span>
<span class='covered'> var Token,</span>
<span class='covered'> TokenName,</span>
<span class='covered'> Syntax,</span>
<span class='covered'> PropertyKind,</span>
<span class='covered'> Messages,</span>
<span class='covered'> Regex,</span>
<span class='covered'> source,</span>
<span class='covered'> strict,</span>
<span class='covered'> index,</span>
<span class='covered'> lineNumber,</span>
<span class='covered'> lineStart,</span>
<span class='covered'> length,</span>
<span class='covered'> buffer,</span>
<span class='covered'> state,</span>
<span class='covered'> extra;</span>
<span class='covered'> </span>
<span class='covered'> Token = {</span>
<span class='covered'> BooleanLiteral: 1,</span>
<span class='covered'> EOF: 2,</span>
<span class='covered'> Identifier: 3,</span>
<span class='covered'> Keyword: 4,</span>
<span class='covered'> NullLiteral: 5,</span>
<span class='covered'> NumericLiteral: 6,</span>
<span class='covered'> Punctuator: 7,</span>
<span class='covered'> StringLiteral: 8</span>
<span class='covered'> };</span>
<span class='covered'> </span>
<span class='covered'> TokenName = {};</span>
<span class='covered'> TokenName[Token.BooleanLiteral] = 'Boolean';</span>
<span class='covered'> TokenName[Token.EOF] = '<end>';</span>
<span class='covered'> TokenName[Token.Identifier] = 'Identifier';</span>
<span class='covered'> TokenName[Token.Keyword] = 'Keyword';</span>
<span class='covered'> TokenName[Token.NullLiteral] = 'Null';</span>
<span class='covered'> TokenName[Token.NumericLiteral] = 'Numeric';</span>
<span class='covered'> TokenName[Token.Punctuator] = 'Punctuator';</span>
<span class='covered'> TokenName[Token.StringLiteral] = 'String';</span>
<span class='covered'> </span>
<span class='covered'> Syntax = {</span>
<span class='covered'> AssignmentExpression: 'AssignmentExpression',</span>
<span class='covered'> ArrayExpression: 'ArrayExpression',</span>
<span class='covered'> BlockStatement: 'BlockStatement',</span>
<span class='covered'> BinaryExpression: 'BinaryExpression',</span>
<span class='covered'> BreakStatement: 'BreakStatement',</span>
<span class='covered'> CallExpression: 'CallExpression',</span>
<span class='covered'> CatchClause: 'CatchClause',</span>
<span class='covered'> ConditionalExpression: 'ConditionalExpression',</span>
<span class='covered'> ContinueStatement: 'ContinueStatement',</span>
<span class='covered'> DoWhileStatement: 'DoWhileStatement',</span>
<span class='covered'> DebuggerStatement: 'DebuggerStatement',</span>
<span class='covered'> EmptyStatement: 'EmptyStatement',</span>
<span class='covered'> ExpressionStatement: 'ExpressionStatement',</span>
<span class='covered'> ForStatement: 'ForStatement',</span>
<span class='covered'> ForInStatement: 'ForInStatement',</span>
<span class='covered'> FunctionDeclaration: 'FunctionDeclaration',</span>
<span class='covered'> FunctionExpression: 'FunctionExpression',</span>
<span class='covered'> Identifier: 'Identifier',</span>
<span class='covered'> IfStatement: 'IfStatement',</span>
<span class='covered'> Literal: 'Literal',</span>
<span class='covered'> LabeledStatement: 'LabeledStatement',</span>
<span class='covered'> LogicalExpression: 'LogicalExpression',</span>
<span class='covered'> MemberExpression: 'MemberExpression',</span>
<span class='covered'> NewExpression: 'NewExpression',</span>
<span class='covered'> ObjectExpression: 'ObjectExpression',</span>
<span class='covered'> Program: 'Program',</span>
<span class='covered'> Property: 'Property',</span>
<span class='covered'> ReturnStatement: 'ReturnStatement',</span>
<span class='covered'> SequenceExpression: 'SequenceExpression',</span>
<span class='covered'> SwitchStatement: 'SwitchStatement',</span>
<span class='covered'> SwitchCase: 'SwitchCase',</span>
<span class='covered'> ThisExpression: 'ThisExpression',</span>
<span class='covered'> ThrowStatement: 'ThrowStatement',</span>
<span class='covered'> TryStatement: 'TryStatement',</span>
<span class='covered'> UnaryExpression: 'UnaryExpression',</span>
<span class='covered'> UpdateExpression: 'UpdateExpression',</span>
<span class='covered'> VariableDeclaration: 'VariableDeclaration',</span>
<span class='covered'> VariableDeclarator: 'VariableDeclarator',</span>
<span class='covered'> WhileStatement: 'WhileStatement',</span>
<span class='covered'> WithStatement: 'WithStatement'</span>
<span class='covered'> };</span>
<span class='covered'> </span>
<span class='covered'> PropertyKind = {</span>
<span class='covered'> Data: 1,</span>
<span class='covered'> Get: 2,</span>
<span class='covered'> Set: 4</span>
<span class='covered'> };</span>
<span class='covered'> </span>
<span class='covered'> // Error messages should be identical to V8.</span>
<span class='covered'> Messages = {</span>
<span class='covered'> UnexpectedToken: 'Unexpected token %0',</span>
<span class='covered'> UnexpectedNumber: 'Unexpected number',</span>
<span class='covered'> UnexpectedString: 'Unexpected string',</span>
<span class='covered'> UnexpectedIdentifier: 'Unexpected identifier',</span>
<span class='covered'> UnexpectedReserved: 'Unexpected reserved word',</span>
<span class='covered'> UnexpectedEOS: 'Unexpected end of input',</span>
<span class='covered'> NewlineAfterThrow: 'Illegal newline after throw',</span>
<span class='covered'> InvalidRegExp: 'Invalid regular expression',</span>
<span class='covered'> UnterminatedRegExp: 'Invalid regular expression: missing /',</span>
<span class='covered'> InvalidLHSInAssignment: 'Invalid left-hand side in assignment',</span>
<span class='covered'> InvalidLHSInForIn: 'Invalid left-hand side in for-in',</span>
<span class='covered'> NoCatchOrFinally: 'Missing catch or finally after try',</span>
<span class='covered'> UnknownLabel: 'Undefined label \'%0\'',</span>
<span class='covered'> Redeclaration: '%0 \'%1\' has already been declared',</span>
<span class='covered'> IllegalContinue: 'Illegal continue statement',</span>
<span class='covered'> IllegalBreak: 'Illegal break statement',</span>
<span class='covered'> IllegalReturn: 'Illegal return statement',</span>
<span class='covered'> StrictModeWith: 'Strict mode code may not include a with statement',</span>
<span class='covered'> StrictCatchVariable: 'Catch variable may not be eval or arguments in strict mode',</span>
<span class='covered'> StrictVarName: 'Variable name may not be eval or arguments in strict mode',</span>
<span class='covered'> StrictParamName: 'Parameter name eval or arguments is not allowed in strict mode',</span>
<span class='covered'> StrictParamDupe: 'Strict mode function may not have duplicate parameter names',</span>
<span class='covered'> StrictFunctionName: 'Function name may not be eval or arguments in strict mode',</span>
<span class='covered'> StrictOctalLiteral: 'Octal literals are not allowed in strict mode.',</span>
<span class='covered'> StrictDelete: 'Delete of an unqualified identifier in strict mode.',</span>
<span class='covered'> StrictDuplicateProperty: 'Duplicate data property in object literal not allowed in strict mode',</span>
<span class='covered'> AccessorDataProperty: 'Object literal may not have data and accessor property with the same name',</span>
<span class='covered'> AccessorGetSet: 'Object literal may not have multiple get/set accessors with the same name',</span>
<span class='covered'> StrictLHSAssignment: 'Assignment to eval or arguments is not allowed in strict mode',</span>
<span class='covered'> StrictLHSPostfix: 'Postfix increment/decrement may not have eval or arguments operand in strict mode',</span>
<span class='covered'> StrictLHSPrefix: 'Prefix increment/decrement may not have eval or arguments operand in strict mode',</span>
<span class='covered'> StrictReservedWord: 'Use of future reserved word in strict mode'</span>
<span class='covered'> };</span>
<span class='covered'> </span>
<span class='covered'> // See also tools/generate-unicode-regex.py.</span>
<span class='covered'> Regex = {</span>
<span class='covered'> NonAsciiIdentifierStart: new RegExp('[\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]'),</span>
<span class='covered'> NonAsciiIdentifierPart: new RegExp('[\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0300-\u0374\u0376\u0377\u037a-\u037d\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u0483-\u0487\u048a-\u0527\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u05d0-\u05ea\u05f0-\u05f2\u0610-\u061a\u0620-\u0669\u066e-\u06d3\u06d5-\u06dc\u06df-\u06e8\u06ea-\u06fc\u06ff\u0710-\u074a\u074d-\u07b1\u07c0-\u07f5\u07fa\u0800-\u082d\u0840-\u085b\u08a0\u08a2-\u08ac\u08e4-\u08fe\u0900-\u0963\u0966-\u096f\u0971-\u0977\u0979-\u097f\u0981-\u0983\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bc-\u09c4\u09c7\u09c8\u09cb-\u09ce\u09d7\u09dc\u09dd\u09df-\u09e3\u09e6-\u09f1\u0a01-\u0a03\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a59-\u0a5c\u0a5e\u0a66-\u0a75\u0a81-\u0a83\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abc-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ad0\u0ae0-\u0ae3\u0ae6-\u0aef\u0b01-\u0b03\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3c-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b56\u0b57\u0b5c\u0b5d\u0b5f-\u0b63\u0b66-\u0b6f\u0b71\u0b82\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd0\u0bd7\u0be6-\u0bef\u0c01-\u0c03\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c33\u0c35-\u0c39\u0c3d-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c58\u0c59\u0c60-\u0c63\u0c66-\u0c6f\u0c82\u0c83\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbc-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0cde\u0ce0-\u0ce3\u0ce6-\u0cef\u0cf1\u0cf2\u0d02\u0d03\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d-\u0d44\u0d46-\u0d48\u0d4a-\u0d4e\u0d57\u0d60-\u0d63\u0d66-\u0d6f\u0d7a-\u0d7f\u0d82\u0d83\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0df2\u0df3\u0e01-\u0e3a\u0e40-\u0e4e\u0e50-\u0e59\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb9\u0ebb-\u0ebd\u0ec0-\u0ec4\u0ec6\u0ec8-\u0ecd\u0ed0-\u0ed9\u0edc-\u0edf\u0f00\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e-\u0f47\u0f49-\u0f6c\u0f71-\u0f84\u0f86-\u0f97\u0f99-\u0fbc\u0fc6\u1000-\u1049\u1050-\u109d\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\u135d-\u135f\u1380-\u138f\u13a0-\u13f4\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f0\u1700-\u170c\u170e-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176c\u176e-\u1770\u1772\u1773\u1780-\u17d3\u17d7\u17dc\u17dd\u17e0-\u17e9\u180b-\u180d\u1810-\u1819\u1820-\u1877\u1880-\u18aa\u18b0-\u18f5\u1900-\u191c\u1920-\u192b\u1930-\u193b\u1946-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u19d0-\u19d9\u1a00-\u1a1b\u1a20-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1aa7\u1b00-\u1b4b\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1bf3\u1c00-\u1c37\u1c40-\u1c49\u1c4d-\u1c7d\u1cd0-\u1cd2\u1cd4-\u1cf6\u1d00-\u1de6\u1dfc-\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\u200c\u200d\u203f\u2040\u2054\u2071\u207f\u2090-\u209c\u20d0-\u20dc\u20e1\u20e5-\u20f0\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-\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d7f-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u2de0-\u2dff\u2e2f\u3005-\u3007\u3021-\u302f\u3031-\u3035\u3038-\u303c\u3041-\u3096\u3099\u309a\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-\ua62b\ua640-\ua66f\ua674-\ua67d\ua67f-\ua697\ua69f-\ua6f1\ua717-\ua71f\ua722-\ua788\ua78b-\ua78e\ua790-\ua793\ua7a0-\ua7aa\ua7f8-\ua827\ua840-\ua873\ua880-\ua8c4\ua8d0-\ua8d9\ua8e0-\ua8f7\ua8fb\ua900-\ua92d\ua930-\ua953\ua960-\ua97c\ua980-\ua9c0\ua9cf-\ua9d9\uaa00-\uaa36\uaa40-\uaa4d\uaa50-\uaa59\uaa60-\uaa76\uaa7a\uaa7b\uaa80-\uaac2\uaadb-\uaadd\uaae0-\uaaef\uaaf2-\uaaf6\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uabc0-\uabea\uabec\uabed\uabf0-\uabf9\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe00-\ufe0f\ufe20-\ufe26\ufe33\ufe34\ufe4d-\ufe4f\ufe70-\ufe74\ufe76-\ufefc\uff10-\uff19\uff21-\uff3a\uff3f\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc]')</span>
<span class='covered'> };</span>
<span class='covered'> </span>
<span class='covered'> // Ensure the condition is true, otherwise throw an error.</span>
<span class='covered'> // This is only to have a better contract semantic, i.e. another safety net</span>
<span class='covered'> // to catch a logic error. The condition shall be fulfilled in normal case.</span>
<span class='covered'> // Do NOT use this to enforce a certain condition on any user input.</span>
<span class='covered'> </span>
<span class='covered'> function assert(condition, message) {</span>
<span class='covered'> if (!condition) {</span>
<span class='uncovered'> throw new Error('ASSERT: ' + message);</span>
<span class='covered'> }</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> function sliceSource(from, to) {</span>
<span class='covered'> return source.slice(from, to);</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> if (typeof 'esprima'[0] === 'undefined') {</span>
<span class='uncovered'> sliceSource = function sliceArraySource(from, to) {</span>
<span class='uncovered'> return source.slice(from, to).join('');</span>
<span class='uncovered'> };</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> function isDecimalDigit(ch) {</span>
<span class='covered'> return '0123456789'.indexOf(ch) >= 0;</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> function isHexDigit(ch) {</span>
<span class='covered'> return '0123456789abcdefABCDEF'.indexOf(ch) >= 0;</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> function isOctalDigit(ch) {</span>
<span class='covered'> return '01234567'.indexOf(ch) >= 0;</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> </span>
<span class='covered'> // 7.2 White Space</span>
<span class='covered'> </span>
<span class='covered'> function isWhiteSpace(ch) {</span>
<span class='covered'> return (ch === ' ') || (ch === '\u0009') || (ch === '\u000B') ||</span>
<span class='covered'> (ch === '\u000C') || (ch === '\u00A0') ||</span>
<span class='covered'> (ch.charCodeAt(0) >= 0x1680 &&</span>
<span class='covered'> '\u1680\u180E\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\uFEFF'.indexOf(ch) >= 0);</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> // 7.3 Line Terminators</span>
<span class='covered'> </span>
<span class='covered'> function isLineTerminator(ch) {</span>
<span class='covered'> return (ch === '\n' || ch === '\r' || ch === '\u2028' || ch === '\u2029');</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> // 7.6 Identifier Names and Identifiers</span>
<span class='covered'> </span>
<span class='covered'> function isIdentifierStart(ch) {</span>
<span class='covered'> return (ch === '$') || (ch === '_') || (ch === '\\') ||</span>
<span class='covered'> (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') ||</span>
<span class='covered'> ((ch.charCodeAt(0) >= 0x80) && Regex.NonAsciiIdentifierStart.test(ch));</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> function isIdentifierPart(ch) {</span>
<span class='covered'> return (ch === '$') || (ch === '_') || (ch === '\\') ||</span>
<span class='covered'> (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') ||</span>
<span class='covered'> ((ch >= '0') && (ch <= '9')) ||</span>
<span class='covered'> ((ch.charCodeAt(0) >= 0x80) && Regex.NonAsciiIdentifierPart.test(ch));</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> // 7.6.1.2 Future Reserved Words</span>
<span class='covered'> </span>
<span class='covered'> function isFutureReservedWord(id) {</span>
<span class='covered'> switch (id) {</span>
<span class='covered'> </span>
<span class='covered'> // Future reserved words.</span>
<span class='covered'> case 'class':</span>
<span class='covered'> case 'enum':</span>
<span class='covered'> case 'export':</span>
<span class='covered'> case 'extends':</span>
<span class='covered'> case 'import':</span>
<span class='covered'> case 'super':</span>
<span class='covered'> return true;</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> return false;</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> function isStrictModeReservedWord(id) {</span>
<span class='covered'> switch (id) {</span>
<span class='covered'> </span>
<span class='covered'> // Strict Mode reserved words.</span>
<span class='covered'> case 'implements':</span>
<span class='covered'> case 'interface':</span>
<span class='covered'> case 'package':</span>
<span class='covered'> case 'private':</span>
<span class='covered'> case 'protected':</span>
<span class='covered'> case 'public':</span>
<span class='covered'> case 'static':</span>
<span class='covered'> case 'yield':</span>
<span class='covered'> case 'let':</span>
<span class='covered'> return true;</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> return false;</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> function isRestrictedWord(id) {</span>
<span class='covered'> return id === 'eval' || id === 'arguments';</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> // 7.6.1.1 Keywords</span>
<span class='covered'> </span>
<span class='covered'> function isKeyword(id) {</span>
<span class='covered'> var keyword = false;</span>
<span class='covered'> switch (id.length) {</span>
<span class='covered'> case 2:</span>
<span class='covered'> keyword = (id === 'if') || (id === 'in') || (id === 'do');</span>
<span class='covered'> break;</span>
<span class='covered'> case 3:</span>
<span class='covered'> keyword = (id === 'var') || (id === 'for') || (id === 'new') || (id === 'try');</span>
<span class='covered'> break;</span>
<span class='covered'> case 4:</span>
<span class='covered'> keyword = (id === 'this') || (id === 'else') || (id === 'case') || (id === 'void') || (id === 'with');</span>
<span class='covered'> break;</span>
<span class='covered'> case 5:</span>
<span class='covered'> keyword = (id === 'while') || (id === 'break') || (id === 'catch') || (id === 'throw');</span>
<span class='covered'> break;</span>
<span class='covered'> case 6:</span>
<span class='covered'> keyword = (id === 'return') || (id === 'typeof') || (id === 'delete') || (id === 'switch');</span>
<span class='covered'> break;</span>
<span class='covered'> case 7:</span>
<span class='covered'> keyword = (id === 'default') || (id === 'finally');</span>
<span class='covered'> break;</span>
<span class='covered'> case 8:</span>
<span class='covered'> keyword = (id === 'function') || (id === 'continue') || (id === 'debugger');</span>
<span class='covered'> break;</span>
<span class='covered'> case 10:</span>
<span class='covered'> keyword = (id === 'instanceof');</span>
<span class='covered'> break;</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> if (keyword) {</span>
<span class='covered'> return true;</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> switch (id) {</span>
<span class='covered'> // Future reserved words.</span>
<span class='covered'> // 'const' is specialized as Keyword in V8.</span>
<span class='covered'> case 'const':</span>
<span class='covered'> return true;</span>
<span class='covered'> </span>
<span class='covered'> // For compatiblity to SpiderMonkey and ES.next</span>
<span class='covered'> case 'yield':</span>
<span class='covered'> case 'let':</span>
<span class='covered'> return true;</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> if (strict && isStrictModeReservedWord(id)) {</span>
<span class='covered'> return true;</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> return isFutureReservedWord(id);</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> // Return the next character and move forward.</span>
<span class='covered'> </span>
<span class='covered'> function nextChar() {</span>
<span class='covered'> return source[index++];</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> // 7.4 Comments</span>
<span class='covered'> </span>
<span class='covered'> function skipComment() {</span>
<span class='covered'> var ch, blockComment, lineComment;</span>
<span class='covered'> </span>
<span class='covered'> blockComment = false;</span>
<span class='covered'> lineComment = false;</span>
<span class='covered'> </span>
<span class='covered'> while (index < length) {</span>
<span class='covered'> ch = source[index];</span>
<span class='covered'> </span>
<span class='covered'> if (lineComment) {</span>
<span class='covered'> ch = nextChar();</span>
<span class='covered'> if (isLineTerminator(ch)) {</span>
<span class='covered'> lineComment = false;</span>
<span class='covered'> if (ch === '\r' && source[index] === '\n') {</span>
<span class='covered'> ++index;</span>
<span class='covered'> }</span>
<span class='covered'> ++lineNumber;</span>
<span class='covered'> lineStart = index;</span>
<span class='covered'> }</span>
<span class='covered'> } else if (blockComment) {</span>
<span class='covered'> if (isLineTerminator(ch)) {</span>
<span class='covered'> if (ch === '\r' && source[index + 1] === '\n') {</span>
<span class='covered'> ++index;</span>
<span class='covered'> }</span>
<span class='covered'> ++lineNumber;</span>
<span class='covered'> ++index;</span>
<span class='covered'> lineStart = index;</span>
<span class='covered'> if (index >= length) {</span>
<span class='covered'> throwError({}, Messages.UnexpectedToken, 'ILLEGAL');</span>
<span class='covered'> }</span>
<span class='covered'> } else {</span>
<span class='covered'> ch = nextChar();</span>
<span class='covered'> if (index >= length) {</span>
<span class='covered'> throwError({}, Messages.UnexpectedToken, 'ILLEGAL');</span>
<span class='covered'> }</span>
<span class='covered'> if (ch === '*') {</span>
<span class='covered'> ch = source[index];</span>
<span class='covered'> if (ch === '/') {</span>
<span class='covered'> ++index;</span>
<span class='covered'> blockComment = false;</span>
<span class='covered'> }</span>
<span class='covered'> }</span>
<span class='covered'> }</span>
<span class='covered'> } else if (ch === '/') {</span>
<span class='covered'> ch = source[index + 1];</span>
<span class='covered'> if (ch === '/') {</span>
<span class='covered'> index += 2;</span>
<span class='covered'> lineComment = true;</span>
<span class='covered'> } else if (ch === '*') {</span>
<span class='covered'> index += 2;</span>
<span class='covered'> blockComment = true;</span>
<span class='covered'> if (index >= length) {</span>
<span class='covered'> throwError({}, Messages.UnexpectedToken, 'ILLEGAL');</span>
<span class='covered'> }</span>
<span class='covered'> } else {</span>
<span class='covered'> break;</span>
<span class='covered'> }</span>
<span class='covered'> } else if (isWhiteSpace(ch)) {</span>
<span class='covered'> ++index;</span>
<span class='covered'> } else if (isLineTerminator(ch)) {</span>
<span class='covered'> ++index;</span>
<span class='covered'> if (ch === '\r' && source[index] === '\n') {</span>
<span class='covered'> ++index;</span>
<span class='covered'> }</span>
<span class='covered'> ++lineNumber;</span>
<span class='covered'> lineStart = index;</span>
<span class='covered'> } else {</span>
<span class='covered'> break;</span>
<span class='covered'> }</span>
<span class='covered'> }</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> function scanHexEscape(prefix) {</span>
<span class='covered'> var i, len, ch, code = 0;</span>
<span class='covered'> </span>
<span class='covered'> len = (prefix === 'u') ? 4 : 2;</span>
<span class='covered'> for (i = 0; i < len; ++i) {</span>
<span class='covered'> if (index < length && isHexDigit(source[index])) {</span>
<span class='covered'> ch = nextChar();</span>
<span class='covered'> code = code * 16 + '0123456789abcdef'.indexOf(ch.toLowerCase());</span>
<span class='covered'> } else {</span>
<span class='covered'> return '';</span>
<span class='covered'> }</span>
<span class='covered'> }</span>
<span class='covered'> return String.fromCharCode(code);</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> function scanIdentifier() {</span>
<span class='covered'> var ch, start, id, restore;</span>
<span class='covered'> </span>
<span class='covered'> ch = source[index];</span>
<span class='covered'> if (!isIdentifierStart(ch)) {</span>
<span class='covered'> return;</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> start = index;</span>
<span class='covered'> if (ch === '\\') {</span>
<span class='covered'> ++index;</span>
<span class='covered'> if (source[index] !== 'u') {</span>
<span class='covered'> return;</span>
<span class='covered'> }</span>
<span class='covered'> ++index;</span>
<span class='covered'> restore = index;</span>
<span class='covered'> ch = scanHexEscape('u');</span>
<span class='covered'> if (ch) {</span>
<span class='covered'> if (ch === '\\' || !isIdentifierStart(ch)) {</span>
<span class='covered'> return;</span>
<span class='covered'> }</span>
<span class='covered'> id = ch;</span>
<span class='covered'> } else {</span>
<span class='covered'> index = restore;</span>
<span class='covered'> id = 'u';</span>
<span class='covered'> }</span>
<span class='covered'> } else {</span>
<span class='covered'> id = nextChar();</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> while (index < length) {</span>
<span class='covered'> ch = source[index];</span>
<span class='covered'> if (!isIdentifierPart(ch)) {</span>
<span class='covered'> break;</span>
<span class='covered'> }</span>
<span class='covered'> if (ch === '\\') {</span>
<span class='covered'> ++index;</span>
<span class='covered'> if (source[index] !== 'u') {</span>
<span class='covered'> return;</span>
<span class='covered'> }</span>
<span class='covered'> ++index;</span>
<span class='covered'> restore = index;</span>
<span class='covered'> ch = scanHexEscape('u');</span>
<span class='covered'> if (ch) {</span>
<span class='covered'> if (ch === '\\' || !isIdentifierPart(ch)) {</span>
<span class='covered'> return;</span>
<span class='covered'> }</span>
<span class='covered'> id += ch;</span>
<span class='covered'> } else {</span>
<span class='covered'> index = restore;</span>
<span class='covered'> id += 'u';</span>
<span class='covered'> }</span>
<span class='covered'> } else {</span>
<span class='covered'> id += nextChar();</span>
<span class='covered'> }</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> // There is no keyword or literal with only one character.</span>
<span class='covered'> // Thus, it must be an identifier.</span>
<span class='covered'> if (id.length === 1) {</span>
<span class='covered'> return {</span>
<span class='covered'> type: Token.Identifier,</span>
<span class='covered'> value: id,</span>
<span class='covered'> lineNumber: lineNumber,</span>
<span class='covered'> lineStart: lineStart,</span>
<span class='covered'> range: [start, index]</span>
<span class='covered'> };</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> if (isKeyword(id)) {</span>
<span class='covered'> return {</span>
<span class='covered'> type: Token.Keyword,</span>
<span class='covered'> value: id,</span>
<span class='covered'> lineNumber: lineNumber,</span>
<span class='covered'> lineStart: lineStart,</span>
<span class='covered'> range: [start, index]</span>
<span class='covered'> };</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> // 7.8.1 Null Literals</span>
<span class='covered'> </span>
<span class='covered'> if (id === 'null') {</span>
<span class='covered'> return {</span>
<span class='covered'> type: Token.NullLiteral,</span>
<span class='covered'> value: id,</span>
<span class='covered'> lineNumber: lineNumber,</span>
<span class='covered'> lineStart: lineStart,</span>
<span class='covered'> range: [start, index]</span>
<span class='covered'> };</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> // 7.8.2 Boolean Literals</span>
<span class='covered'> </span>
<span class='covered'> if (id === 'true' || id === 'false') {</span>
<span class='covered'> return {</span>
<span class='covered'> type: Token.BooleanLiteral,</span>
<span class='covered'> value: id,</span>
<span class='covered'> lineNumber: lineNumber,</span>
<span class='covered'> lineStart: lineStart,</span>
<span class='covered'> range: [start, index]</span>
<span class='covered'> };</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> return {</span>
<span class='covered'> type: Token.Identifier,</span>
<span class='covered'> value: id,</span>
<span class='covered'> lineNumber: lineNumber,</span>
<span class='covered'> lineStart: lineStart,</span>
<span class='covered'> range: [start, index]</span>
<span class='covered'> };</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> // 7.7 Punctuators</span>
<span class='covered'> </span>
<span class='covered'> function scanPunctuator() {</span>
<span class='covered'> var start = index,</span>
<span class='covered'> ch1 = source[index],</span>
<span class='covered'> ch2,</span>
<span class='covered'> ch3,</span>
<span class='covered'> ch4;</span>
<span class='covered'> </span>
<span class='covered'> // Check for most common single-character punctuators.</span>
<span class='covered'> </span>
<span class='covered'> if (ch1 === ';' || ch1 === '{' || ch1 === '}') {</span>
<span class='covered'> ++index;</span>
<span class='covered'> return {</span>
<span class='covered'> type: Token.Punctuator,</span>
<span class='covered'> value: ch1,</span>
<span class='covered'> lineNumber: lineNumber,</span>
<span class='covered'> lineStart: lineStart,</span>
<span class='covered'> range: [start, index]</span>
<span class='covered'> };</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> if (ch1 === ',' || ch1 === '(' || ch1 === ')') {</span>
<span class='covered'> ++index;</span>
<span class='covered'> return {</span>
<span class='covered'> type: Token.Punctuator,</span>
<span class='covered'> value: ch1,</span>
<span class='covered'> lineNumber: lineNumber,</span>
<span class='covered'> lineStart: lineStart,</span>
<span class='covered'> range: [start, index]</span>
<span class='covered'> };</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> // Dot (.) can also start a floating-point number, hence the need</span>
<span class='covered'> // to check the next character.</span>
<span class='covered'> </span>
<span class='covered'> ch2 = source[index + 1];</span>
<span class='covered'> if (ch1 === '.' && !isDecimalDigit(ch2)) {</span>
<span class='covered'> return {</span>
<span class='covered'> type: Token.Punctuator,</span>
<span class='covered'> value: nextChar(),</span>
<span class='covered'> lineNumber: lineNumber,</span>
<span class='covered'> lineStart: lineStart,</span>
<span class='covered'> range: [start, index]</span>
<span class='covered'> };</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> // Peek more characters.</span>
<span class='covered'> </span>
<span class='covered'> ch3 = source[index + 2];</span>
<span class='covered'> ch4 = source[index + 3];</span>
<span class='covered'> </span>
<span class='covered'> // 4-character punctuator: >>>=</span>
<span class='covered'> </span>
<span class='covered'> if (ch1 === '>' && ch2 === '>' && ch3 === '>') {</span>
<span class='covered'> if (ch4 === '=') {</span>
<span class='covered'> index += 4;</span>
<span class='covered'> return {</span>
<span class='covered'> type: Token.Punctuator,</span>
<span class='covered'> value: '>>>=',</span>
<span class='covered'> lineNumber: lineNumber,</span>
<span class='covered'> lineStart: lineStart,</span>
<span class='covered'> range: [start, index]</span>
<span class='covered'> };</span>
<span class='covered'> }</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> // 3-character punctuators: === !== >>> <<= >>=</span>
<span class='covered'> </span>
<span class='covered'> if (ch1 === '=' && ch2 === '=' && ch3 === '=') {</span>
<span class='covered'> index += 3;</span>
<span class='covered'> return {</span>
<span class='covered'> type: Token.Punctuator,</span>
<span class='covered'> value: '===',</span>
<span class='covered'> lineNumber: lineNumber,</span>
<span class='covered'> lineStart: lineStart,</span>
<span class='covered'> range: [start, index]</span>
<span class='covered'> };</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> if (ch1 === '!' && ch2 === '=' && ch3 === '=') {</span>
<span class='covered'> index += 3;</span>
<span class='covered'> return {</span>
<span class='covered'> type: Token.Punctuator,</span>
<span class='covered'> value: '!==',</span>
<span class='covered'> lineNumber: lineNumber,</span>
<span class='covered'> lineStart: lineStart,</span>
<span class='covered'> range: [start, index]</span>
<span class='covered'> };</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> if (ch1 === '>' && ch2 === '>' && ch3 === '>') {</span>
<span class='covered'> index += 3;</span>
<span class='covered'> return {</span>
<span class='covered'> type: Token.Punctuator,</span>
<span class='covered'> value: '>>>',</span>
<span class='covered'> lineNumber: lineNumber,</span>
<span class='covered'> lineStart: lineStart,</span>
<span class='covered'> range: [start, index]</span>
<span class='covered'> };</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> if (ch1 === '<' && ch2 === '<' && ch3 === '=') {</span>
<span class='covered'> index += 3;</span>
<span class='covered'> return {</span>
<span class='covered'> type: Token.Punctuator,</span>
<span class='covered'> value: '<<=',</span>
<span class='covered'> lineNumber: lineNumber,</span>
<span class='covered'> lineStart: lineStart,</span>
<span class='covered'> range: [start, index]</span>
<span class='covered'> };</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> if (ch1 === '>' && ch2 === '>' && ch3 === '=') {</span>
<span class='covered'> index += 3;</span>
<span class='covered'> return {</span>
<span class='covered'> type: Token.Punctuator,</span>
<span class='covered'> value: '>>=',</span>
<span class='covered'> lineNumber: lineNumber,</span>
<span class='covered'> lineStart: lineStart,</span>
<span class='covered'> range: [start, index]</span>
<span class='covered'> };</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> // 2-character punctuators: <= >= == != ++ -- << >> && ||</span>
<span class='covered'> // += -= *= %= &= |= ^= /=</span>
<span class='covered'> </span>
<span class='covered'> if (ch2 === '=') {</span>
<span class='covered'> if ('<>=!+-*%&|^/'.indexOf(ch1) >= 0) {</span>
<span class='covered'> index += 2;</span>
<span class='covered'> return {</span>
<span class='covered'> type: Token.Punctuator,</span>
<span class='covered'> value: ch1 + ch2,</span>
<span class='covered'> lineNumber: lineNumber,</span>
<span class='covered'> lineStart: lineStart,</span>
<span class='covered'> range: [start, index]</span>
<span class='covered'> };</span>
<span class='covered'> }</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> if (ch1 === ch2 && ('+-<>&|'.indexOf(ch1) >= 0)) {</span>
<span class='covered'> if ('+-<>&|'.indexOf(ch2) >= 0) {</span>
<span class='covered'> index += 2;</span>
<span class='covered'> return {</span>
<span class='covered'> type: Token.Punctuator,</span>
<span class='covered'> value: ch1 + ch2,</span>
<span class='covered'> lineNumber: lineNumber,</span>
<span class='covered'> lineStart: lineStart,</span>
<span class='covered'> range: [start, index]</span>
<span class='covered'> };</span>
<span class='covered'> }</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> // The remaining 1-character punctuators.</span>
<span class='covered'> </span>
<span class='covered'> if ('[]<>+-*%&|^!~?:=/'.indexOf(ch1) >= 0) {</span>
<span class='covered'> return {</span>
<span class='covered'> type: Token.Punctuator,</span>
<span class='covered'> value: nextChar(),</span>
<span class='covered'> lineNumber: lineNumber,</span>
<span class='covered'> lineStart: lineStart,</span>
<span class='covered'> range: [start, index]</span>
<span class='covered'> };</span>
<span class='covered'> }</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> // 7.8.3 Numeric Literals</span>
<span class='covered'> </span>
<span class='covered'> function scanNumericLiteral() {</span>
<span class='covered'> var number, start, ch;</span>
<span class='covered'> </span>
<span class='covered'> ch = source[index];</span>
<span class='covered'> assert(isDecimalDigit(ch) || (ch === '.'),</span>
<span class='covered'> 'Numeric literal must start with a decimal digit or a decimal point');</span>
<span class='covered'> </span>
<span class='covered'> start = index;</span>
<span class='covered'> number = '';</span>
<span class='covered'> if (ch !== '.') {</span>
<span class='covered'> number = nextChar();</span>
<span class='covered'> ch = source[index];</span>
<span class='covered'> </span>
<span class='covered'> // Hex number starts with '0x'.</span>
<span class='covered'> // Octal number starts with '0'.</span>
<span class='covered'> if (number === '0') {</span>
<span class='covered'> if (ch === 'x' || ch === 'X') {</span>
<span class='covered'> number += nextChar();</span>
<span class='covered'> while (index < length) {</span>
<span class='covered'> ch = source[index];</span>
<span class='covered'> if (!isHexDigit(ch)) {</span>
<span class='covered'> break;</span>
<span class='covered'> }</span>
<span class='covered'> number += nextChar();</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> if (number.length <= 2) {</span>
<span class='covered'> // only 0x</span>
<span class='covered'> throwError({}, Messages.UnexpectedToken, 'ILLEGAL');</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> if (index < length) {</span>
<span class='covered'> ch = source[index];</span>
<span class='covered'> if (isIdentifierStart(ch)) {</span>
<span class='covered'> throwError({}, Messages.UnexpectedToken, 'ILLEGAL');</span>
<span class='covered'> }</span>
<span class='covered'> }</span>
<span class='covered'> return {</span>
<span class='covered'> type: Token.NumericLiteral,</span>
<span class='covered'> value: parseInt(number, 16),</span>
<span class='covered'> lineNumber: lineNumber,</span>
<span class='covered'> lineStart: lineStart,</span>
<span class='covered'> range: [start, index]</span>
<span class='covered'> };</span>
<span class='covered'> } else if (isOctalDigit(ch)) {</span>
<span class='covered'> number += nextChar();</span>
<span class='covered'> while (index < length) {</span>
<span class='covered'> ch = source[index];</span>
<span class='covered'> if (!isOctalDigit(ch)) {</span>
<span class='covered'> break;</span>
<span class='covered'> }</span>
<span class='covered'> number += nextChar();</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> if (index < length) {</span>
<span class='covered'> ch = source[index];</span>
<span class='covered'> if (isIdentifierStart(ch) || isDecimalDigit(ch)) {</span>
<span class='covered'> throwError({}, Messages.UnexpectedToken, 'ILLEGAL');</span>
<span class='covered'> }</span>
<span class='covered'> }</span>
<span class='covered'> return {</span>
<span class='covered'> type: Token.NumericLiteral,</span>
<span class='covered'> value: parseInt(number, 8),</span>
<span class='covered'> octal: true,</span>
<span class='covered'> lineNumber: lineNumber,</span>
<span class='covered'> lineStart: lineStart,</span>
<span class='covered'> range: [start, index]</span>
<span class='covered'> };</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> // decimal number starts with '0' such as '09' is illegal.</span>
<span class='covered'> if (isDecimalDigit(ch)) {</span>
<span class='covered'> throwError({}, Messages.UnexpectedToken, 'ILLEGAL');</span>
<span class='covered'> }</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> while (index < length) {</span>
<span class='covered'> ch = source[index];</span>
<span class='covered'> if (!isDecimalDigit(ch)) {</span>
<span class='covered'> break;</span>
<span class='covered'> }</span>
<span class='covered'> number += nextChar();</span>
<span class='covered'> }</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> if (ch === '.') {</span>
<span class='covered'> number += nextChar();</span>
<span class='covered'> while (index < length) {</span>
<span class='covered'> ch = source[index];</span>
<span class='covered'> if (!isDecimalDigit(ch)) {</span>
<span class='covered'> break;</span>
<span class='covered'> }</span>
<span class='covered'> number += nextChar();</span>
<span class='covered'> }</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> if (ch === 'e' || ch === 'E') {</span>
<span class='covered'> number += nextChar();</span>
<span class='covered'> </span>
<span class='covered'> ch = source[index];</span>
<span class='covered'> if (ch === '+' || ch === '-') {</span>
<span class='covered'> number += nextChar();</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> ch = source[index];</span>
<span class='covered'> if (isDecimalDigit(ch)) {</span>
<span class='covered'> number += nextChar();</span>
<span class='covered'> while (index < length) {</span>
<span class='covered'> ch = source[index];</span>
<span class='covered'> if (!isDecimalDigit(ch)) {</span>
<span class='covered'> break;</span>
<span class='covered'> }</span>
<span class='covered'> number += nextChar();</span>
<span class='covered'> }</span>
<span class='covered'> } else {</span>
<span class='covered'> ch = 'character ' + ch;</span>
<span class='covered'> if (index >= length) {</span>
<span class='covered'> ch = '<end>';</span>
<span class='covered'> }</span>
<span class='covered'> throwError({}, Messages.UnexpectedToken, 'ILLEGAL');</span>
<span class='covered'> }</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> if (index < length) {</span>
<span class='covered'> ch = source[index];</span>
<span class='covered'> if (isIdentifierStart(ch)) {</span>
<span class='covered'> throwError({}, Messages.UnexpectedToken, 'ILLEGAL');</span>
<span class='covered'> }</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> return {</span>
<span class='covered'> type: Token.NumericLiteral,</span>
<span class='covered'> value: parseFloat(number),</span>
<span class='covered'> lineNumber: lineNumber,</span>
<span class='covered'> lineStart: lineStart,</span>
<span class='covered'> range: [start, index]</span>
<span class='covered'> };</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> // 7.8.4 String Literals</span>
<span class='covered'> </span>
<span class='covered'> function scanStringLiteral() {</span>
<span class='covered'> var str = '', quote, start, ch, code, unescaped, restore, octal = false;</span>
<span class='covered'> </span>
<span class='covered'> quote = source[index];</span>
<span class='covered'> assert((quote === '\'' || quote === '"'),</span>
<span class='covered'> 'String literal must starts with a quote');</span>
<span class='covered'> </span>
<span class='covered'> start = index;</span>
<span class='covered'> ++index;</span>
<span class='covered'> </span>
<span class='covered'> while (index < length) {</span>
<span class='covered'> ch = nextChar();</span>
<span class='covered'> </span>
<span class='covered'> if (ch === quote) {</span>
<span class='covered'> quote = '';</span>
<span class='covered'> break;</span>
<span class='covered'> } else if (ch === '\\') {</span>
<span class='covered'> ch = nextChar();</span>
<span class='covered'> if (!isLineTerminator(ch)) {</span>
<span class='covered'> switch (ch) {</span>
<span class='covered'> case 'n':</span>
<span class='covered'> str += '\n';</span>
<span class='covered'> break;</span>
<span class='covered'> case 'r':</span>
<span class='covered'> str += '\r';</span>
<span class='covered'> break;</span>
<span class='covered'> case 't':</span>
<span class='covered'> str += '\t';</span>
<span class='covered'> break;</span>
<span class='covered'> case 'u':</span>
<span class='covered'> case 'x':</span>
<span class='covered'> restore = index;</span>
<span class='covered'> unescaped = scanHexEscape(ch);</span>
<span class='covered'> if (unescaped) {</span>
<span class='covered'> str += unescaped;</span>
<span class='covered'> } else {</span>
<span class='covered'> index = restore;</span>
<span class='covered'> str += ch;</span>
<span class='covered'> }</span>
<span class='covered'> break;</span>
<span class='covered'> case 'b':</span>
<span class='covered'> str += '\b';</span>
<span class='covered'> break;</span>
<span class='covered'> case 'f':</span>
<span class='covered'> str += '\f';</span>
<span class='covered'> break;</span>
<span class='covered'> case 'v':</span>
<span class='covered'> str += '\v';</span>
<span class='covered'> break;</span>
<span class='covered'> </span>
<span class='covered'> default:</span>
<span class='covered'> if (isOctalDigit(ch)) {</span>
<span class='covered'> code = '01234567'.indexOf(ch);</span>
<span class='covered'> </span>
<span class='covered'> // \0 is not octal escape sequence</span>
<span class='covered'> if (code !== 0) {</span>
<span class='covered'> octal = true;</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> if (index < length && isOctalDigit(source[index])) {</span>
<span class='covered'> octal = true;</span>
<span class='covered'> code = code * 8 + '01234567'.indexOf(nextChar());</span>
<span class='covered'> </span>
<span class='covered'> // 3 digits are only allowed when string starts</span>
<span class='covered'> // with 0, 1, 2, 3</span>
<span class='covered'> if ('0123'.indexOf(ch) >= 0 &&</span>
<span class='covered'> index < length &&</span>
<span class='covered'> isOctalDigit(source[index])) {</span>
<span class='covered'> code = code * 8 + '01234567'.indexOf(nextChar());</span>
<span class='covered'> }</span>
<span class='covered'> }</span>
<span class='covered'> str += String.fromCharCode(code);</span>
<span class='covered'> } else {</span>
<span class='covered'> str += ch;</span>
<span class='covered'> }</span>
<span class='covered'> break;</span>
<span class='covered'> }</span>
<span class='covered'> } else {</span>
<span class='covered'> ++lineNumber;</span>
<span class='covered'> if (ch === '\r' && source[index] === '\n') {</span>
<span class='covered'> ++index;</span>
<span class='covered'> }</span>
<span class='covered'> }</span>
<span class='covered'> } else if (isLineTerminator(ch)) {</span>
<span class='covered'> break;</span>
<span class='covered'> } else {</span>
<span class='covered'> str += ch;</span>
<span class='covered'> }</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> if (quote !== '') {</span>
<span class='covered'> throwError({}, Messages.UnexpectedToken, 'ILLEGAL');</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> return {</span>
<span class='covered'> type: Token.StringLiteral,</span>
<span class='covered'> value: str,</span>
<span class='covered'> octal: octal,</span>
<span class='covered'> lineNumber: lineNumber,</span>
<span class='covered'> lineStart: lineStart,</span>
<span class='covered'> range: [start, index]</span>
<span class='covered'> };</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> function scanRegExp() {</span>
<span class='covered'> var str = '', ch, start, pattern, flags, value, classMarker = false, restore;</span>
<span class='covered'> </span>
<span class='covered'> buffer = null;</span>
<span class='covered'> skipComment();</span>
<span class='covered'> </span>
<span class='covered'> start = index;</span>
<span class='covered'> ch = source[index];</span>
<span class='covered'> assert(ch === '/', 'Regular expression literal must start with a slash');</span>
<span class='covered'> str = nextChar();</span>
<span class='covered'> </span>
<span class='covered'> while (index < length) {</span>
<span class='covered'> ch = nextChar();</span>
<span class='covered'> str += ch;</span>
<span class='covered'> if (classMarker) {</span>
<span class='covered'> if (ch === ']') {</span>
<span class='covered'> classMarker = false;</span>
<span class='covered'> }</span>
<span class='covered'> } else {</span>
<span class='covered'> if (ch === '\\') {</span>
<span class='covered'> str += nextChar();</span>
<span class='covered'> }</span>
<span class='covered'> if (ch === '/') {</span>
<span class='covered'> break;</span>
<span class='covered'> }</span>
<span class='covered'> if (ch === '[') {</span>
<span class='covered'> classMarker = true;</span>
<span class='covered'> }</span>
<span class='covered'> if (isLineTerminator(ch)) {</span>
<span class='covered'> throwError({}, Messages.UnterminatedRegExp);</span>
<span class='covered'> }</span>
<span class='covered'> }</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> if (str.length === 1) {</span>
<span class='covered'> throwError({}, Messages.UnterminatedRegExp);</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> // Exclude leading and trailing slash.</span>
<span class='covered'> pattern = str.substr(1, str.length - 2);</span>
<span class='covered'> </span>
<span class='covered'> flags = '';</span>
<span class='covered'> while (index < length) {</span>
<span class='covered'> ch = source[index];</span>
<span class='covered'> if (!isIdentifierPart(ch)) {</span>
<span class='covered'> break;</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> ++index;</span>
<span class='covered'> if (ch === '\\' && index < length) {</span>
<span class='covered'> ch = source[index];</span>
<span class='covered'> if (ch === 'u') {</span>
<span class='covered'> ++index;</span>
<span class='covered'> restore = index;</span>
<span class='covered'> ch = scanHexEscape('u');</span>
<span class='covered'> if (ch) {</span>
<span class='covered'> flags += ch;</span>
<span class='covered'> str += '\\u';</span>
<span class='covered'> for (; restore < index; ++restore) {</span>
<span class='covered'> str += source[restore];</span>
<span class='covered'> }</span>
<span class='covered'> } else {</span>
<span class='covered'> index = restore;</span>
<span class='covered'> flags += 'u';</span>
<span class='covered'> str += '\\u';</span>
<span class='covered'> }</span>
<span class='covered'> } else {</span>
<span class='covered'> str += '\\';</span>
<span class='covered'> }</span>
<span class='covered'> } else {</span>
<span class='covered'> flags += ch;</span>
<span class='covered'> str += ch;</span>
<span class='covered'> }</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> try {</span>
<span class='covered'> value = new RegExp(pattern, flags);</span>
<span class='covered'> } catch (e) {</span>
<span class='covered'> throwError({}, Messages.InvalidRegExp);</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> return {</span>
<span class='covered'> literal: str,</span>
<span class='covered'> value: value,</span>
<span class='covered'> range: [start, index]</span>
<span class='covered'> };</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> function isIdentifierName(token) {</span>
<span class='covered'> return token.type === Token.Identifier ||</span>
<span class='covered'> token.type === Token.Keyword ||</span>
<span class='covered'> token.type === Token.BooleanLiteral ||</span>
<span class='covered'> token.type === Token.NullLiteral;</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> function advance() {</span>
<span class='covered'> var ch, token;</span>
<span class='covered'> </span>
<span class='covered'> skipComment();</span>
<span class='covered'> </span>
<span class='covered'> if (index >= length) {</span>
<span class='covered'> return {</span>
<span class='covered'> type: Token.EOF,</span>
<span class='covered'> lineNumber: lineNumber,</span>
<span class='covered'> lineStart: lineStart,</span>
<span class='covered'> range: [index, index]</span>
<span class='covered'> };</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> token = scanPunctuator();</span>
<span class='covered'> if (typeof token !== 'undefined') {</span>
<span class='covered'> return token;</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> ch = source[index];</span>
<span class='covered'> </span>
<span class='covered'> if (ch === '\'' || ch === '"') {</span>
<span class='covered'> return scanStringLiteral();</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> if (ch === '.' || isDecimalDigit(ch)) {</span>
<span class='covered'> return scanNumericLiteral();</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> token = scanIdentifier();</span>
<span class='covered'> if (typeof token !== 'undefined') {</span>
<span class='covered'> return token;</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> throwError({}, Messages.UnexpectedToken, 'ILLEGAL');</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> function lex() {</span>
<span class='covered'> var token;</span>
<span class='covered'> </span>
<span class='covered'> if (buffer) {</span>
<span class='covered'> index = buffer.range[1];</span>
<span class='covered'> lineNumber = buffer.lineNumber;</span>
<span class='covered'> lineStart = buffer.lineStart;</span>
<span class='covered'> token = buffer;</span>
<span class='covered'> buffer = null;</span>
<span class='covered'> return token;</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> buffer = null;</span>
<span class='covered'> return advance();</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> function lookahead() {</span>
<span class='covered'> var pos, line, start;</span>
<span class='covered'> </span>
<span class='covered'> if (buffer !== null) {</span>
<span class='covered'> return buffer;</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> pos = index;</span>
<span class='covered'> line = lineNumber;</span>
<span class='covered'> start = lineStart;</span>
<span class='covered'> buffer = advance();</span>
<span class='covered'> index = pos;</span>
<span class='covered'> lineNumber = line;</span>
<span class='covered'> lineStart = start;</span>
<span class='covered'> </span>
<span class='covered'> return buffer;</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> // Return true if there is a line terminator before the next token.</span>
<span class='covered'> </span>
<span class='covered'> function peekLineTerminator() {</span>
<span class='covered'> var pos, line, start, found;</span>
<span class='covered'> </span>
<span class='covered'> pos = index;</span>
<span class='covered'> line = lineNumber;</span>
<span class='covered'> start = lineStart;</span>
<span class='covered'> skipComment();</span>
<span class='covered'> found = lineNumber !== line;</span>
<span class='covered'> index = pos;</span>
<span class='covered'> lineNumber = line;</span>
<span class='covered'> lineStart = start;</span>
<span class='covered'> </span>
<span class='covered'> return found;</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> // Throw an exception</span>
<span class='covered'> </span>
<span class='covered'> function throwError(token, messageFormat) {</span>
<span class='covered'> var error,</span>
<span class='covered'> args = Array.prototype.slice.call(arguments, 2),</span>
<span class='covered'> msg = messageFormat.replace(</span>
<span class='covered'> /%(\d)/g,</span>
<span class='covered'> function (whole, index) {</span>
<span class='covered'> return args[index] || '';</span>
<span class='covered'> }</span>
<span class='covered'> );</span>
<span class='covered'> </span>
<span class='covered'> if (typeof token.lineNumber === 'number') {</span>
<span class='covered'> error = new Error('Line ' + token.lineNumber + ': ' + msg);</span>
<span class='covered'> error.index = token.range[0];</span>
<span class='covered'> error.lineNumber = token.lineNumber;</span>
<span class='covered'> error.column = token.range[0] - lineStart + 1;</span>
<span class='covered'> } else {</span>
<span class='covered'> error = new Error('Line ' + lineNumber + ': ' + msg);</span>
<span class='covered'> error.index = index;</span>
<span class='covered'> error.lineNumber = lineNumber;</span>
<span class='covered'> error.column = index - lineStart + 1;</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> throw error;</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> function throwErrorTolerant() {</span>
<span class='covered'> var error;</span>
<span class='covered'> try {</span>
<span class='covered'> throwError.apply(null, arguments);</span>
<span class='covered'> } catch (e) {</span>
<span class='covered'> if (extra.errors) {</span>
<span class='covered'> extra.errors.push(e);</span>
<span class='covered'> } else {</span>
<span class='covered'> throw e;</span>
<span class='covered'> }</span>
<span class='covered'> }</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> </span>
<span class='covered'> // Throw an exception because of the token.</span>
<span class='covered'> </span>
<span class='covered'> function throwUnexpected(token) {</span>
<span class='covered'> var s;</span>
<span class='covered'> </span>
<span class='covered'> if (token.type === Token.EOF) {</span>
<span class='covered'> throwError(token, Messages.UnexpectedEOS);</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> if (token.type === Token.NumericLiteral) {</span>
<span class='covered'> throwError(token, Messages.UnexpectedNumber);</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> if (token.type === Token.StringLiteral) {</span>
<span class='covered'> throwError(token, Messages.UnexpectedString);</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> if (token.type === Token.Identifier) {</span>
<span class='covered'> throwError(token, Messages.UnexpectedIdentifier);</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> if (token.type === Token.Keyword) {</span>
<span class='covered'> if (isFutureReservedWord(token.value)) {</span>
<span class='covered'> throwError(token, Messages.UnexpectedReserved);</span>
<span class='covered'> } else if (strict && isStrictModeReservedWord(token.value)) {</span>
<span class='covered'> throwError(token, Messages.StrictReservedWord);</span>
<span class='covered'> }</span>
<span class='covered'> throwError(token, Messages.UnexpectedToken, token.value);</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> // BooleanLiteral, NullLiteral, or Punctuator.</span>
<span class='covered'> throwError(token, Messages.UnexpectedToken, token.value);</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> // Expect the next token to match the specified punctuator.</span>
<span class='covered'> // If not, an exception will be thrown.</span>
<span class='covered'> </span>
<span class='covered'> function expect(value) {</span>
<span class='covered'> var token = lex();</span>
<span class='covered'> if (token.type !== Token.Punctuator || token.value !== value) {</span>
<span class='covered'> throwUnexpected(token);</span>
<span class='covered'> }</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> // Expect the next token to match the specified keyword.</span>
<span class='covered'> // If not, an exception will be thrown.</span>
<span class='covered'> </span>
<span class='covered'> function expectKeyword(keyword) {</span>
<span class='covered'> var token = lex();</span>
<span class='covered'> if (token.type !== Token.Keyword || token.value !== keyword) {</span>
<span class='covered'> throwUnexpected(token);</span>
<span class='covered'> }</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> // Return true if the next token matches the specified punctuator.</span>
<span class='covered'> </span>
<span class='covered'> function match(value) {</span>
<span class='covered'> var token = lookahead();</span>
<span class='covered'> return token.type === Token.Punctuator && token.value === value;</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> // Return true if the next token matches the specified keyword</span>
<span class='covered'> </span>
<span class='covered'> function matchKeyword(keyword) {</span>
<span class='covered'> var token = lookahead();</span>
<span class='covered'> return token.type === Token.Keyword && token.value === keyword;</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> // Return true if the next token is an assignment operator</span>
<span class='covered'> </span>
<span class='covered'> function matchAssign() {</span>
<span class='covered'> var token = lookahead(),</span>
<span class='covered'> op = token.value;</span>
<span class='covered'> </span>
<span class='covered'> if (token.type !== Token.Punctuator) {</span>
<span class='covered'> return false;</span>
<span class='covered'> }</span>
<span class='covered'> return op === '=' ||</span>
<span class='covered'> op === '*=' ||</span>
<span class='covered'> op === '/=' ||</span>
<span class='covered'> op === '%=' ||</span>
<span class='covered'> op === '+=' ||</span>
<span class='covered'> op === '-=' ||</span>
<span class='covered'> op === '<<=' ||</span>
<span class='covered'> op === '>>=' ||</span>
<span class='covered'> op === '>>>=' ||</span>
<span class='covered'> op === '&=' ||</span>
<span class='covered'> op === '^=' ||</span>
<span class='covered'> op === '|=';</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> function consumeSemicolon() {</span>
<span class='covered'> var token, line;</span>
<span class='covered'> </span>
<span class='covered'> // Catch the very common case first.</span>
<span class='covered'> if (source[index] === ';') {</span>
<span class='covered'> lex();</span>
<span class='covered'> return;</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> line = lineNumber;</span>
<span class='covered'> skipComment();</span>
<span class='covered'> if (lineNumber !== line) {</span>
<span class='covered'> return;</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> if (match(';')) {</span>
<span class='covered'> lex();</span>
<span class='covered'> return;</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> token = lookahead();</span>
<span class='covered'> if (token.type !== Token.EOF && !match('}')) {</span>
<span class='covered'> throwUnexpected(token);</span>
<span class='covered'> }</span>
<span class='covered'> return;</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> // Return true if provided expression is LeftHandSideExpression</span>
<span class='covered'> </span>
<span class='covered'> function isLeftHandSide(expr) {</span>
<span class='covered'> switch (expr.type) {</span>
<span class='covered'> case 'AssignmentExpression':</span>
<span class='covered'> case 'BinaryExpression':</span>
<span class='covered'> case 'ConditionalExpression':</span>
<span class='covered'> case 'LogicalExpression':</span>
<span class='covered'> case 'SequenceExpression':</span>
<span class='covered'> case 'UnaryExpression':</span>
<span class='covered'> case 'UpdateExpression':</span>
<span class='covered'> return false;</span>
<span class='covered'> }</span>
<span class='covered'> return true;</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> // 11.1.4 Array Initialiser</span>
<span class='covered'> </span>
<span class='covered'> function parseArrayInitialiser() {</span>
<span class='covered'> var elements = [],</span>
<span class='covered'> undef;</span>
<span class='covered'> </span>
<span class='covered'> expect('[');</span>
<span class='covered'> </span>
<span class='covered'> while (!match(']')) {</span>
<span class='covered'> if (match(',')) {</span>
<span class='covered'> lex();</span>
<span class='covered'> elements.push(undef);</span>
<span class='covered'> } else {</span>
<span class='covered'> elements.push(parseAssignmentExpression());</span>
<span class='covered'> </span>
<span class='covered'> if (!match(']')) {</span>
<span class='covered'> expect(',');</span>
<span class='covered'> }</span>
<span class='covered'> }</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> expect(']');</span>
<span class='covered'> </span>
<span class='covered'> return {</span>
<span class='covered'> type: Syntax.ArrayExpression,</span>
<span class='covered'> elements: elements</span>
<span class='covered'> };</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> // 11.1.5 Object Initialiser</span>
<span class='covered'> </span>
<span class='covered'> function parsePropertyFunction(param, first) {</span>
<span class='covered'> var previousStrict, body;</span>
<span class='covered'> </span>
<span class='covered'> previousStrict = strict;</span>
<span class='covered'> body = parseFunctionSourceElements();</span>
<span class='covered'> if (first && strict && isRestrictedWord(param[0].name)) {</span>
<span class='covered'> throwError(first, Messages.StrictParamName);</span>
<span class='covered'> }</span>
<span class='covered'> strict = previousStrict;</span>
<span class='covered'> </span>
<span class='covered'> return {</span>
<span class='covered'> type: Syntax.FunctionExpression,</span>
<span class='covered'> id: null,</span>
<span class='covered'> params: param,</span>
<span class='covered'> body: body</span>
<span class='covered'> };</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> function parseObjectPropertyKey() {</span>
<span class='covered'> var token = lex();</span>
<span class='covered'> </span>
<span class='covered'> // Note: This function is called only from parseObjectProperty(), where</span>
<span class='covered'> // EOF and Punctuator tokens are already filtered out.</span>
<span class='covered'> </span>
<span class='covered'> if (token.type === Token.StringLiteral || token.type === Token.NumericLiteral) {</span>
<span class='covered'> if (strict && token.octal) {</span>
<span class='covered'> throwError(token, Messages.StrictOctalLiteral);</span>
<span class='covered'> }</span>
<span class='covered'> return createLiteral(token);</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> return {</span>
<span class='covered'> type: Syntax.Identifier,</span>
<span class='covered'> name: token.value</span>
<span class='covered'> };</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> function parseObjectProperty() {</span>
<span class='covered'> var token, key, id, param;</span>
<span class='covered'> </span>
<span class='covered'> token = lookahead();</span>
<span class='covered'> </span>
<span class='covered'> if (token.type === Token.Identifier) {</span>
<span class='covered'> </span>
<span class='covered'> id = parseObjectPropertyKey();</span>
<span class='covered'> </span>
<span class='covered'> // Property Assignment: Getter and Setter.</span>
<span class='covered'> </span>
<span class='covered'> if (token.value === 'get' && !match(':')) {</span>
<span class='covered'> key = parseObjectPropertyKey();</span>
<span class='covered'> expect('(');</span>
<span class='covered'> expect(')');</span>
<span class='covered'> return {</span>
<span class='covered'> type: Syntax.Property,</span>
<span class='covered'> key: key,</span>
<span class='covered'> value: parsePropertyFunction([]),</span>
<span class='covered'> kind: 'get'</span>
<span class='covered'> };</span>
<span class='covered'> } else if (token.value === 'set' && !match(':')) {</span>
<span class='covered'> key = parseObjectPropertyKey();</span>
<span class='covered'> expect('(');</span>
<span class='covered'> token = lookahead();</span>
<span class='covered'> if (token.type !== Token.Identifier) {</span>
<span class='covered'> throwUnexpected(lex());</span>
<span class='covered'> }</span>
<span class='covered'> param = [ parseVariableIdentifier() ];</span>
<span class='covered'> expect(')');</span>
<span class='covered'> return {</span>
<span class='covered'> type: Syntax.Property,</span>
<span class='covered'> key: key,</span>
<span class='covered'> value: parsePropertyFunction(param, token),</span>
<span class='covered'> kind: 'set'</span>
<span class='covered'> };</span>
<span class='covered'> } else {</span>
<span class='covered'> expect(':');</span>
<span class='covered'> return {</span>
<span class='covered'> type: Syntax.Property,</span>
<span class='covered'> key: id,</span>
<span class='covered'> value: parseAssignmentExpression(),</span>
<span class='covered'> kind: 'init'</span>
<span class='covered'> };</span>
<span class='covered'> }</span>
<span class='covered'> } else if (token.type === Token.EOF || token.type === Token.Punctuator) {</span>
<span class='covered'> throwUnexpected(token);</span>
<span class='covered'> } else {</span>
<span class='covered'> key = parseObjectPropertyKey();</span>
<span class='covered'> expect(':');</span>
<span class='covered'> return {</span>
<span class='covered'> type: Syntax.Property,</span>
<span class='covered'> key: key,</span>
<span class='covered'> value: parseAssignmentExpression(),</span>
<span class='covered'> kind: 'init'</span>
<span class='covered'> };</span>
<span class='covered'> }</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> function parseObjectInitialiser() {</span>
<span class='covered'> var token, properties = [], property, name, kind, map = {}, toString = String;</span>
<span class='covered'> </span>
<span class='covered'> expect('{');</span>
<span class='covered'> </span>
<span class='covered'> while (!match('}')) {</span>
<span class='covered'> property = parseObjectProperty();</span>
<span class='covered'> </span>
<span class='covered'> if (property.key.type === Syntax.Identifier) {</span>
<span class='covered'> name = property.key.name;</span>
<span class='covered'> } else {</span>
<span class='covered'> name = toString(property.key.value);</span>
<span class='covered'> }</span>
<span class='covered'> kind = (property.kind === 'init') ? PropertyKind.Data : (property.kind === 'get') ? PropertyKind.Get : PropertyKind.Set;</span>
<span class='covered'> if (Object.prototype.hasOwnProperty.call(map, name)) {</span>
<span class='covered'> if (map[name] === PropertyKind.Data) {</span>
<span class='covered'> if (strict && kind === PropertyKind.Data) {</span>
<span class='covered'> throwError({}, Messages.StrictDuplicateProperty);</span>
<span class='covered'> } else if (kind !== PropertyKind.Data) {</span>
<span class='covered'> throwError({}, Messages.AccessorDataProperty);</span>
<span class='covered'> }</span>
<span class='covered'> } else {</span>
<span class='covered'> if (kind === PropertyKind.Data) {</span>
<span class='covered'> throwError({}, Messages.AccessorDataProperty);</span>
<span class='covered'> } else if (map[name] & kind) {</span>
<span class='covered'> throwError({}, Messages.AccessorGetSet);</span>
<span class='covered'> }</span>
<span class='covered'> }</span>
<span class='covered'> map[name] |= kind;</span>
<span class='covered'> } else {</span>
<span class='covered'> map[name] = kind;</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> properties.push(property);</span>
<span class='covered'> </span>
<span class='covered'> if (!match('}')) {</span>
<span class='covered'> expect(',');</span>
<span class='covered'> }</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> expect('}');</span>
<span class='covered'> </span>
<span class='covered'> return {</span>
<span class='covered'> type: Syntax.ObjectExpression,</span>
<span class='covered'> properties: properties</span>
<span class='covered'> };</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> // 11.1 Primary Expressions</span>
<span class='covered'> </span>
<span class='covered'> function parsePrimaryExpression() {</span>
<span class='covered'> var expr,</span>
<span class='covered'> token = lookahead(),</span>
<span class='covered'> type = token.type;</span>
<span class='covered'> </span>
<span class='covered'> if (type === Token.Identifier) {</span>
<span class='covered'> return {</span>
<span class='covered'> type: Syntax.Identifier,</span>
<span class='covered'> name: lex().value</span>
<span class='covered'> };</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> if (type === Token.StringLiteral || type === Token.NumericLiteral) {</span>
<span class='covered'> if (strict && token.octal) {</span>
<span class='covered'> throwErrorTolerant(token, Messages.StrictOctalLiteral);</span>
<span class='covered'> }</span>
<span class='covered'> return createLiteral(lex());</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> if (type === Token.Keyword) {</span>
<span class='covered'> if (matchKeyword('this')) {</span>
<span class='covered'> lex();</span>
<span class='covered'> return {</span>
<span class='covered'> type: Syntax.ThisExpression</span>
<span class='covered'> };</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> if (matchKeyword('function')) {</span>
<span class='covered'> return parseFunctionExpression();</span>
<span class='covered'> }</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> if (type === Token.BooleanLiteral) {</span>
<span class='covered'> lex();</span>
<span class='covered'> token.value = (token.value === 'true');</span>
<span class='covered'> return createLiteral(token);</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> if (type === Token.NullLiteral) {</span>
<span class='covered'> lex();</span>
<span class='covered'> token.value = null;</span>
<span class='covered'> return createLiteral(token);</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> if (match('[')) {</span>
<span class='covered'> return parseArrayInitialiser();</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> if (match('{')) {</span>
<span class='covered'> return parseObjectInitialiser();</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> if (match('(')) {</span>
<span class='covered'> lex();</span>
<span class='covered'> state.lastParenthesized = expr = parseExpression();</span>
<span class='covered'> expect(')');</span>
<span class='covered'> return expr;</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> if (match('/') || match('/=')) {</span>
<span class='covered'> return createLiteral(scanRegExp());</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> return throwUnexpected(lex());</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> // 11.2 Left-Hand-Side Expressions</span>
<span class='covered'> </span>
<span class='covered'> function parseArguments() {</span>
<span class='covered'> var args = [];</span>
<span class='covered'> </span>
<span class='covered'> expect('(');</span>
<span class='covered'> </span>
<span class='covered'> if (!match(')')) {</span>
<span class='covered'> while (index < length) {</span>
<span class='covered'> args.push(parseAssignmentExpression());</span>
<span class='covered'> if (match(')')) {</span>
<span class='covered'> break;</span>
<span class='covered'> }</span>
<span class='covered'> expect(',');</span>
<span class='covered'> }</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> expect(')');</span>
<span class='covered'> </span>
<span class='covered'> return args;</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> function parseNonComputedProperty() {</span>
<span class='covered'> var token = lex();</span>
<span class='covered'> </span>
<span class='covered'> if (!isIdentifierName(token)) {</span>
<span class='covered'> throwUnexpected(token);</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> return {</span>
<span class='covered'> type: Syntax.Identifier,</span>
<span class='covered'> name: token.value</span>
<span class='covered'> };</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> function parseNonComputedMember(object) {</span>
<span class='covered'> return {</span>
<span class='covered'> type: Syntax.MemberExpression,</span>
<span class='covered'> computed: false,</span>
<span class='covered'> object: object,</span>
<span class='covered'> property: parseNonComputedProperty()</span>
<span class='covered'> };</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> function parseComputedMember(object) {</span>
<span class='covered'> var property, expr;</span>
<span class='covered'> </span>
<span class='covered'> expect('[');</span>
<span class='covered'> property = parseExpression();</span>
<span class='covered'> expr = {</span>
<span class='covered'> type: Syntax.MemberExpression,</span>
<span class='covered'> computed: true,</span>
<span class='covered'> object: object,</span>
<span class='covered'> property: property</span>
<span class='covered'> };</span>
<span class='covered'> expect(']');</span>
<span class='covered'> return expr;</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> function parseCallMember(object) {</span>
<span class='covered'> return {</span>
<span class='covered'> type: Syntax.CallExpression,</span>
<span class='covered'> callee: object,</span>
<span class='covered'> 'arguments': parseArguments()</span>
<span class='covered'> };</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> function parseNewExpression() {</span>
<span class='covered'> var expr;</span>
<span class='covered'> </span>
<span class='covered'> expectKeyword('new');</span>
<span class='covered'> </span>
<span class='covered'> expr = {</span>
<span class='covered'> type: Syntax.NewExpression,</span>
<span class='covered'> callee: parseLeftHandSideExpression(),</span>
<span class='covered'> 'arguments': []</span>
<span class='covered'> };</span>
<span class='covered'> </span>
<span class='covered'> if (match('(')) {</span>
<span class='covered'> expr['arguments'] = parseArguments();</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> return expr;</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> function parseLeftHandSideExpressionAllowCall() {</span>
<span class='covered'> var useNew, expr;</span>
<span class='covered'> </span>
<span class='covered'> useNew = matchKeyword('new');</span>
<span class='covered'> expr = useNew ? parseNewExpression() : parsePrimaryExpression();</span>
<span class='covered'> </span>
<span class='covered'> while (index < length) {</span>
<span class='covered'> if (match('.')) {</span>
<span class='covered'> lex();</span>
<span class='covered'> expr = parseNonComputedMember(expr);</span>
<span class='covered'> } else if (match('[')) {</span>
<span class='covered'> expr = parseComputedMember(expr);</span>
<span class='covered'> } else if (match('(')) {</span>
<span class='covered'> expr = parseCallMember(expr);</span>
<span class='covered'> } else {</span>
<span class='covered'> break;</span>
<span class='covered'> }</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> return expr;</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> function parseLeftHandSideExpression() {</span>
<span class='covered'> var useNew, expr;</span>
<span class='covered'> </span>
<span class='covered'> useNew = matchKeyword('new');</span>
<span class='covered'> expr = useNew ? parseNewExpression() : parsePrimaryExpression();</span>
<span class='covered'> </span>
<span class='covered'> while (index < length) {</span>
<span class='covered'> if (match('.')) {</span>
<span class='covered'> lex();</span>
<span class='covered'> expr = parseNonComputedMember(expr);</span>
<span class='covered'> } else if (match('[')) {</span>
<span class='covered'> expr = parseComputedMember(expr);</span>
<span class='covered'> } else {</span>
<span class='covered'> break;</span>
<span class='covered'> }</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> return expr;</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> // 11.3 Postfix Expressions</span>
<span class='covered'> </span>
<span class='covered'> function parsePostfixExpression() {</span>
<span class='covered'> var expr = parseLeftHandSideExpressionAllowCall();</span>
<span class='covered'> </span>
<span class='covered'> if ((match('++') || match('--')) && !peekLineTerminator()) {</span>
<span class='covered'> // 11.3.1, 11.3.2</span>
<span class='covered'> if (strict && expr.type === Syntax.Identifier && isRestrictedWord(expr.name)) {</span>
<span class='covered'> throwError({}, Messages.StrictLHSPostfix);</span>
<span class='covered'> }</span>
<span class='covered'> expr = {</span>
<span class='covered'> type: Syntax.UpdateExpression,</span>
<span class='covered'> operator: lex().value,</span>
<span class='covered'> argument: expr,</span>
<span class='covered'> prefix: false</span>
<span class='covered'> };</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> return expr;</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> // 11.4 Unary Operators</span>
<span class='covered'> </span>
<span class='covered'> function parseUnaryExpression() {</span>
<span class='covered'> var token, expr;</span>
<span class='covered'> </span>
<span class='covered'> if (match('++') || match('--')) {</span>
<span class='covered'> token = lex();</span>
<span class='covered'> expr = parseUnaryExpression();</span>
<span class='covered'> // 11.4.4, 11.4.5</span>
<span class='covered'> if (strict && expr.type === Syntax.Identifier && isRestrictedWord(expr.name)) {</span>
<span class='covered'> throwError({}, Messages.StrictLHSPrefix);</span>
<span class='covered'> }</span>
<span class='covered'> expr = {</span>
<span class='covered'> type: Syntax.UpdateExpression,</span>
<span class='covered'> operator: token.value,</span>
<span class='covered'> argument: expr,</span>
<span class='covered'> prefix: true</span>
<span class='covered'> };</span>
<span class='covered'> return expr;</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> if (match('+') || match('-') || match('~') || match('!')) {</span>
<span class='covered'> expr = {</span>
<span class='covered'> type: Syntax.UnaryExpression,</span>
<span class='covered'> operator: lex().value,</span>
<span class='covered'> argument: parseUnaryExpression()</span>
<span class='covered'> };</span>
<span class='covered'> return expr;</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> if (matchKeyword('delete') || matchKeyword('void') || matchKeyword('typeof')) {</span>
<span class='covered'> expr = {</span>
<span class='covered'> type: Syntax.UnaryExpression,</span>
<span class='covered'> operator: lex().value,</span>
<span class='covered'> argument: parseUnaryExpression()</span>
<span class='covered'> };</span>
<span class='covered'> if (strict && expr.operator === 'delete' && expr.argument.type === Syntax.Identifier) {</span>
<span class='covered'> throwErrorTolerant({}, Messages.StrictDelete);</span>
<span class='covered'> }</span>
<span class='covered'> return expr;</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> return parsePostfixExpression();</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> // 11.5 Multiplicative Operators</span>
<span class='covered'> </span>
<span class='covered'> function parseMultiplicativeExpression() {</span>
<span class='covered'> var expr = parseUnaryExpression();</span>
<span class='covered'> </span>
<span class='covered'> while (match('*') || match('/') || match('%')) {</span>
<span class='covered'> expr = {</span>
<span class='covered'> type: Syntax.BinaryExpression,</span>
<span class='covered'> operator: lex().value,</span>
<span class='covered'> left: expr,</span>
<span class='covered'> right: parseUnaryExpression()</span>
<span class='covered'> };</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> return expr;</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> // 11.6 Additive Operators</span>
<span class='covered'> </span>
<span class='covered'> function parseAdditiveExpression() {</span>
<span class='covered'> var expr = parseMultiplicativeExpression();</span>
<span class='covered'> </span>
<span class='covered'> while (match('+') || match('-')) {</span>
<span class='covered'> expr = {</span>
<span class='covered'> type: Syntax.BinaryExpression,</span>
<span class='covered'> operator: lex().value,</span>
<span class='covered'> left: expr,</span>
<span class='covered'> right: parseMultiplicativeExpression()</span>
<span class='covered'> };</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> return expr;</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> // 11.7 Bitwise Shift Operators</span>
<span class='covered'> </span>
<span class='covered'> function parseShiftExpression() {</span>
<span class='covered'> var expr = parseAdditiveExpression();</span>
<span class='covered'> </span>
<span class='covered'> while (match('<<') || match('>>') || match('>>>')) {</span>
<span class='covered'> expr = {</span>
<span class='covered'> type: Syntax.BinaryExpression,</span>
<span class='covered'> operator: lex().value,</span>
<span class='covered'> left: expr,</span>
<span class='covered'> right: parseAdditiveExpression()</span>
<span class='covered'> };</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> return expr;</span>
<span class='covered'> }</span>
<span class='covered'> // 11.8 Relational Operators</span>
<span class='covered'> </span>
<span class='covered'> function parseRelationalExpression() {</span>
<span class='covered'> var expr, previousAllowIn;</span>
<span class='covered'> </span>
<span class='covered'> previousAllowIn = state.allowIn;</span>
<span class='covered'> state.allowIn = true;</span>
<span class='covered'> expr = parseShiftExpression();</span>
<span class='covered'> state.allowIn = previousAllowIn;</span>
<span class='covered'> </span>
<span class='covered'> if (match('<') || match('>') || match('<=') || match('>=')) {</span>
<span class='covered'> expr = {</span>
<span class='covered'> type: Syntax.BinaryExpression,</span>
<span class='covered'> operator: lex().value,</span>
<span class='covered'> left: expr,</span>
<span class='covered'> right: parseRelationalExpression()</span>
<span class='covered'> };</span>
<span class='covered'> } else if (state.allowIn && matchKeyword('in')) {</span>
<span class='covered'> lex();</span>
<span class='covered'> expr = {</span>
<span class='covered'> type: Syntax.BinaryExpression,</span>
<span class='covered'> operator: 'in',</span>
<span class='covered'> left: expr,</span>
<span class='covered'> right: parseRelationalExpression()</span>
<span class='covered'> };</span>
<span class='covered'> } else if (matchKeyword('instanceof')) {</span>
<span class='covered'> lex();</span>
<span class='covered'> expr = {</span>
<span class='covered'> type: Syntax.BinaryExpression,</span>
<span class='covered'> operator: 'instanceof',</span>
<span class='covered'> left: expr,</span>
<span class='covered'> right: parseRelationalExpression()</span>
<span class='covered'> };</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> return expr;</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> // 11.9 Equality Operators</span>
<span class='covered'> </span>
<span class='covered'> function parseEqualityExpression() {</span>
<span class='covered'> var expr = parseRelationalExpression();</span>
<span class='covered'> </span>
<span class='covered'> while (match('==') || match('!=') || match('===') || match('!==')) {</span>
<span class='covered'> expr = {</span>
<span class='covered'> type: Syntax.BinaryExpression,</span>
<span class='covered'> operator: lex().value,</span>
<span class='covered'> left: expr,</span>
<span class='covered'> right: parseRelationalExpression()</span>
<span class='covered'> };</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> return expr;</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> // 11.10 Binary Bitwise Operators</span>
<span class='covered'> </span>
<span class='covered'> function parseBitwiseANDExpression() {</span>
<span class='covered'> var expr = parseEqualityExpression();</span>
<span class='covered'> </span>
<span class='covered'> while (match('&')) {</span>
<span class='covered'> lex();</span>
<span class='covered'> expr = {</span>
<span class='covered'> type: Syntax.BinaryExpression,</span>
<span class='covered'> operator: '&',</span>
<span class='covered'> left: expr,</span>
<span class='covered'> right: parseEqualityExpression()</span>
<span class='covered'> };</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> return expr;</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> function parseBitwiseORExpression() {</span>
<span class='covered'> var expr = parseBitwiseANDExpression();</span>
<span class='covered'> </span>
<span class='covered'> while (match('|')) {</span>
<span class='covered'> lex();</span>
<span class='covered'> expr = {</span>
<span class='covered'> type: Syntax.BinaryExpression,</span>
<span class='covered'> operator: '|',</span>
<span class='covered'> left: expr,</span>
<span class='covered'> right: parseBitwiseANDExpression()</span>
<span class='covered'> };</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> return expr;</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> function parseBitwiseXORExpression() {</span>
<span class='covered'> var expr = parseBitwiseORExpression();</span>
<span class='covered'> </span>
<span class='covered'> while (match('^')) {</span>
<span class='covered'> lex();</span>
<span class='covered'> expr = {</span>
<span class='covered'> type: Syntax.BinaryExpression,</span>
<span class='covered'> operator: '^',</span>
<span class='covered'> left: expr,</span>
<span class='covered'> right: parseBitwiseORExpression()</span>
<span class='covered'> };</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> return expr;</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> // 11.11 Binary Logical Operators</span>
<span class='covered'> </span>
<span class='covered'> function parseLogicalANDExpression() {</span>
<span class='covered'> var expr = parseBitwiseXORExpression();</span>
<span class='covered'> </span>
<span class='covered'> while (match('&&')) {</span>
<span class='covered'> lex();</span>
<span class='covered'> expr = {</span>
<span class='covered'> type: Syntax.LogicalExpression,</span>
<span class='covered'> operator: '&&',</span>
<span class='covered'> left: expr,</span>
<span class='covered'> right: parseBitwiseXORExpression()</span>
<span class='covered'> };</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> return expr;</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> function parseLogicalORExpression() {</span>
<span class='covered'> var expr = parseLogicalANDExpression();</span>
<span class='covered'> </span>
<span class='covered'> while (match('||')) {</span>
<span class='covered'> lex();</span>
<span class='covered'> expr = {</span>
<span class='covered'> type: Syntax.LogicalExpression,</span>
<span class='covered'> operator: '||',</span>
<span class='covered'> left: expr,</span>
<span class='covered'> right: parseLogicalANDExpression()</span>
<span class='covered'> };</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> return expr;</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> // 11.12 Conditional Operator</span>
<span class='covered'> </span>
<span class='covered'> function parseConditionalExpression() {</span>
<span class='covered'> var expr, previousAllowIn, consequent;</span>
<span class='covered'> </span>
<span class='covered'> expr = parseLogicalORExpression();</span>
<span class='covered'> </span>
<span class='covered'> if (match('?')) {</span>
<span class='covered'> lex();</span>
<span class='covered'> previousAllowIn = state.allowIn;</span>
<span class='covered'> state.allowIn = true;</span>
<span class='covered'> consequent = parseAssignmentExpression();</span>
<span class='covered'> state.allowIn = previousAllowIn;</span>
<span class='covered'> expect(':');</span>
<span class='covered'> </span>
<span class='covered'> expr = {</span>
<span class='covered'> type: Syntax.ConditionalExpression,</span>
<span class='covered'> test: expr,</span>
<span class='covered'> consequent: consequent,</span>
<span class='covered'> alternate: parseAssignmentExpression()</span>
<span class='covered'> };</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> return expr;</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> // 11.13 Assignment Operators</span>
<span class='covered'> </span>
<span class='covered'> function parseAssignmentExpression() {</span>
<span class='covered'> var expr;</span>
<span class='covered'> </span>
<span class='covered'> expr = parseConditionalExpression();</span>
<span class='covered'> </span>
<span class='covered'> if (matchAssign()) {</span>
<span class='covered'> // LeftHandSideExpression</span>
<span class='covered'> if (state.lastParenthesized !== expr && !isLeftHandSide(expr)) {</span>
<span class='covered'> throwError({}, Messages.InvalidLHSInAssignment);</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> // 11.13.1</span>
<span class='covered'> if (strict && expr.type === Syntax.Identifier && isRestrictedWord(expr.name)) {</span>
<span class='covered'> throwError({}, Messages.StrictLHSAssignment);</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> expr = {</span>
<span class='covered'> type: Syntax.AssignmentExpression,</span>
<span class='covered'> operator: lex().value,</span>
<span class='covered'> left: expr,</span>
<span class='covered'> right: parseAssignmentExpression()</span>
<span class='covered'> };</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> return expr;</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> // 11.14 Comma Operator</span>
<span class='covered'> </span>
<span class='covered'> function parseExpression() {</span>
<span class='covered'> var expr = parseAssignmentExpression();</span>
<span class='covered'> </span>
<span class='covered'> if (match(',')) {</span>
<span class='covered'> expr = {</span>
<span class='covered'> type: Syntax.SequenceExpression,</span>
<span class='covered'> expressions: [ expr ]</span>
<span class='covered'> };</span>
<span class='covered'> </span>
<span class='covered'> while (index < length) {</span>
<span class='covered'> if (!match(',')) {</span>
<span class='covered'> break;</span>
<span class='covered'> }</span>
<span class='covered'> lex();</span>
<span class='covered'> expr.expressions.push(parseAssignmentExpression());</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> }</span>
<span class='covered'> return expr;</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> // 12.1 Block</span>
<span class='covered'> </span>
<span class='covered'> function parseStatementList() {</span>
<span class='covered'> var list = [],</span>
<span class='covered'> statement;</span>
<span class='covered'> </span>
<span class='covered'> while (index < length) {</span>
<span class='covered'> if (match('}')) {</span>
<span class='covered'> break;</span>
<span class='covered'> }</span>
<span class='covered'> statement = parseSourceElement();</span>
<span class='covered'> if (typeof statement === 'undefined') {</span>
<span class='covered'> break;</span>
<span class='covered'> }</span>
<span class='covered'> list.push(statement);</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> return list;</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> function parseBlock() {</span>
<span class='covered'> var block;</span>
<span class='covered'> </span>
<span class='covered'> expect('{');</span>
<span class='covered'> </span>
<span class='covered'> block = parseStatementList();</span>
<span class='covered'> </span>
<span class='covered'> expect('}');</span>
<span class='covered'> </span>
<span class='covered'> return {</span>
<span class='covered'> type: Syntax.BlockStatement,</span>
<span class='covered'> body: block</span>
<span class='covered'> };</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> // 12.2 Variable Statement</span>
<span class='covered'> </span>
<span class='covered'> function parseVariableIdentifier() {</span>
<span class='covered'> var token = lex();</span>
<span class='covered'> </span>
<span class='covered'> if (token.type !== Token.Identifier) {</span>
<span class='covered'> throwUnexpected(token);</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> return {</span>
<span class='covered'> type: Syntax.Identifier,</span>
<span class='covered'> name: token.value</span>
<span class='covered'> };</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> function parseVariableDeclaration(kind) {</span>
<span class='covered'> var id = parseVariableIdentifier(),</span>
<span class='covered'> init = null;</span>
<span class='covered'> </span>
<span class='covered'> // 12.2.1</span>
<span class='covered'> if (strict && isRestrictedWord(id.name)) {</span>
<span class='covered'> throwErrorTolerant({}, Messages.StrictVarName);</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> if (kind === 'const') {</span>
<span class='covered'> expect('=');</span>
<span class='covered'> init = parseAssignmentExpression();</span>
<span class='covered'> } else if (match('=')) {</span>
<span class='covered'> lex();</span>
<span class='covered'> init = parseAssignmentExpression();</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> return {</span>
<span class='covered'> type: Syntax.VariableDeclarator,</span>
<span class='covered'> id: id,</span>
<span class='covered'> init: init</span>
<span class='covered'> };</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> function parseVariableDeclarationList(kind) {</span>
<span class='covered'> var list = [];</span>
<span class='covered'> </span>
<span class='covered'> while (index < length) {</span>
<span class='covered'> list.push(parseVariableDeclaration(kind));</span>
<span class='covered'> if (!match(',')) {</span>
<span class='covered'> break;</span>
<span class='covered'> }</span>
<span class='covered'> lex();</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> return list;</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> function parseVariableStatement() {</span>
<span class='covered'> var declarations;</span>
<span class='covered'> </span>
<span class='covered'> expectKeyword('var');</span>
<span class='covered'> </span>
<span class='covered'> declarations = parseVariableDeclarationList();</span>
<span class='covered'> </span>
<span class='covered'> consumeSemicolon();</span>
<span class='covered'> </span>
<span class='covered'> return {</span>
<span class='covered'> type: Syntax.VariableDeclaration,</span>
<span class='covered'> declarations: declarations,</span>
<span class='covered'> kind: 'var'</span>
<span class='covered'> };</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> // kind may be `const` or `let`</span>
<span class='covered'> // Both are experimental and not in the specification yet.</span>
<span class='covered'> // see http://wiki.ecmascript.org/doku.php?id=harmony:const</span>
<span class='covered'> // and http://wiki.ecmascript.org/doku.php?id=harmony:let</span>
<span class='covered'> function parseConstLetDeclaration(kind) {</span>
<span class='covered'> var declarations;</span>
<span class='covered'> </span>
<span class='covered'> expectKeyword(kind);</span>
<span class='covered'> </span>
<span class='covered'> declarations = parseVariableDeclarationList(kind);</span>
<span class='covered'> </span>
<span class='covered'> consumeSemicolon();</span>
<span class='covered'> </span>
<span class='covered'> return {</span>
<span class='covered'> type: Syntax.VariableDeclaration,</span>
<span class='covered'> declarations: declarations,</span>
<span class='covered'> kind: kind</span>
<span class='covered'> };</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> // 12.3 Empty Statement</span>
<span class='covered'> </span>
<span class='covered'> function parseEmptyStatement() {</span>
<span class='covered'> expect(';');</span>
<span class='covered'> </span>
<span class='covered'> return {</span>
<span class='covered'> type: Syntax.EmptyStatement</span>
<span class='covered'> };</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> // 12.4 Expression Statement</span>
<span class='covered'> </span>
<span class='covered'> function parseExpressionStatement() {</span>
<span class='covered'> var expr = parseExpression();</span>
<span class='covered'> </span>
<span class='covered'> consumeSemicolon();</span>
<span class='covered'> </span>
<span class='covered'> return {</span>
<span class='covered'> type: Syntax.ExpressionStatement,</span>
<span class='covered'> expression: expr</span>
<span class='covered'> };</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> // 12.5 If statement</span>
<span class='covered'> </span>
<span class='covered'> function parseIfStatement() {</span>
<span class='covered'> var test, consequent, alternate;</span>
<span class='covered'> </span>
<span class='covered'> expectKeyword('if');</span>
<span class='covered'> </span>
<span class='covered'> expect('(');</span>
<span class='covered'> </span>
<span class='covered'> test = parseExpression();</span>
<span class='covered'> </span>
<span class='covered'> expect(')');</span>
<span class='covered'> </span>
<span class='covered'> consequent = parseStatement();</span>
<span class='covered'> </span>
<span class='covered'> if (matchKeyword('else')) {</span>
<span class='covered'> lex();</span>
<span class='covered'> alternate = parseStatement();</span>
<span class='covered'> } else {</span>
<span class='covered'> alternate = null;</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> return {</span>
<span class='covered'> type: Syntax.IfStatement,</span>
<span class='covered'> test: test,</span>
<span class='covered'> consequent: consequent,</span>
<span class='covered'> alternate: alternate</span>
<span class='covered'> };</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> // 12.6 Iteration Statements</span>
<span class='covered'> </span>
<span class='covered'> function parseDoWhileStatement() {</span>
<span class='covered'> var body, test, oldInIteration;</span>
<span class='covered'> </span>
<span class='covered'> expectKeyword('do');</span>
<span class='covered'> </span>
<span class='covered'> oldInIteration = state.inIteration;</span>
<span class='covered'> state.inIteration = true;</span>
<span class='covered'> </span>
<span class='covered'> body = parseStatement();</span>
<span class='covered'> </span>
<span class='covered'> state.inIteration = oldInIteration;</span>
<span class='covered'> </span>
<span class='covered'> expectKeyword('while');</span>
<span class='covered'> </span>
<span class='covered'> expect('(');</span>
<span class='covered'> </span>
<span class='covered'> test = parseExpression();</span>
<span class='covered'> </span>
<span class='covered'> expect(')');</span>
<span class='covered'> </span>
<span class='covered'> if (match(';')) {</span>
<span class='covered'> lex();</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> return {</span>
<span class='covered'> type: Syntax.DoWhileStatement,</span>
<span class='covered'> body: body,</span>
<span class='covered'> test: test</span>
<span class='covered'> };</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> function parseWhileStatement() {</span>
<span class='covered'> var test, body, oldInIteration;</span>
<span class='covered'> </span>
<span class='covered'> expectKeyword('while');</span>
<span class='covered'> </span>
<span class='covered'> expect('(');</span>
<span class='covered'> </span>
<span class='covered'> test = parseExpression();</span>
<span class='covered'> </span>
<span class='covered'> expect(')');</span>
<span class='covered'> </span>
<span class='covered'> oldInIteration = state.inIteration;</span>
<span class='covered'> state.inIteration = true;</span>
<span class='covered'> </span>
<span class='covered'> body = parseStatement();</span>
<span class='covered'> </span>
<span class='covered'> state.inIteration = oldInIteration;</span>
<span class='covered'> </span>
<span class='covered'> return {</span>
<span class='covered'> type: Syntax.WhileStatement,</span>
<span class='covered'> test: test,</span>
<span class='covered'> body: body</span>
<span class='covered'> };</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> function parseForVariableDeclaration() {</span>
<span class='covered'> var token = lex();</span>
<span class='covered'> </span>
<span class='covered'> return {</span>
<span class='covered'> type: Syntax.VariableDeclaration,</span>
<span class='covered'> declarations: parseVariableDeclarationList(),</span>
<span class='covered'> kind: token.value</span>
<span class='covered'> };</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> function parseForStatement() {</span>
<span class='covered'> var init, test, update, left, right, body, oldInIteration;</span>
<span class='covered'> </span>
<span class='covered'> init = test = update = null;</span>
<span class='covered'> </span>
<span class='covered'> expectKeyword('for');</span>
<span class='covered'> </span>
<span class='covered'> expect('(');</span>
<span class='covered'> </span>
<span class='covered'> if (match(';')) {</span>
<span class='covered'> lex();</span>
<span class='covered'> } else {</span>
<span class='covered'> if (matchKeyword('var') || matchKeyword('let')) {</span>
<span class='covered'> state.allowIn = false;</span>
<span class='covered'> init = parseForVariableDeclaration();</span>
<span class='covered'> state.allowIn = true;</span>
<span class='covered'> </span>
<span class='covered'> if (init.declarations.length === 1 && matchKeyword('in')) {</span>
<span class='covered'> lex();</span>
<span class='covered'> left = init;</span>
<span class='covered'> right = parseExpression();</span>
<span class='covered'> init = null;</span>
<span class='covered'> }</span>
<span class='covered'> } else {</span>
<span class='covered'> state.allowIn = false;</span>
<span class='covered'> init = parseExpression();</span>
<span class='covered'> state.allowIn = true;</span>
<span class='covered'> </span>
<span class='covered'> if (matchKeyword('in')) {</span>
<span class='covered'> // LeftHandSideExpression</span>
<span class='covered'> if (matchKeyword('in') && (state.lastParenthesized !== init && !isLeftHandSide(init))) {</span>
<span class='covered'> throwError({}, Messages.InvalidLHSInForIn);</span>
<span class='covered'> }</span>
<span class='covered'> lex();</span>
<span class='covered'> left = init;</span>
<span class='covered'> right = parseExpression();</span>
<span class='covered'> init = null;</span>
<span class='covered'> }</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> if (typeof left === 'undefined') {</span>
<span class='covered'> expect(';');</span>
<span class='covered'> }</span>
<span class='covered'> }</span>
<span class='covered'> </span>
<span class='covered'> if (typeof left === 'undefined') {</span>
<span class='covered'> </span>
<span class='covered'> if (!match(';')) {&l