()
| 1568 | // the end of the source string. A token may be a string, number, `null` |
| 1569 | // literal, or Boolean literal. |
| 1570 | var lex = function () { |
| 1571 | var source = Source, length = source.length, value, begin, position, isSigned, charCode; |
| 1572 | while (Index < length) { |
| 1573 | charCode = source.charCodeAt(Index); |
| 1574 | switch (charCode) { |
| 1575 | case 9: case 10: case 13: case 32: |
| 1576 | // Skip whitespace tokens, including tabs, carriage returns, line |
| 1577 | // feeds, and space characters. |
| 1578 | Index++; |
| 1579 | break; |
| 1580 | case 123: case 125: case 91: case 93: case 58: case 44: |
| 1581 | // Parse a punctuator token (`{`, `}`, `[`, `]`, `:`, or `,`) at |
| 1582 | // the current position. |
| 1583 | value = charIndexBuggy ? source.charAt(Index) : source[Index]; |
| 1584 | Index++; |
| 1585 | return value; |
| 1586 | case 34: |
| 1587 | // `"` delimits a JSON string; advance to the next character and |
| 1588 | // begin parsing the string. String tokens are prefixed with the |
| 1589 | // sentinel `@` character to distinguish them from punctuators and |
| 1590 | // end-of-string tokens. |
| 1591 | for (value = "@", Index++; Index < length;) { |
| 1592 | charCode = source.charCodeAt(Index); |
| 1593 | if (charCode < 32) { |
| 1594 | // Unescaped ASCII control characters (those with a code unit |
| 1595 | // less than the space character) are not permitted. |
| 1596 | abort(); |
| 1597 | } else if (charCode == 92) { |
| 1598 | // A reverse solidus (`\`) marks the beginning of an escaped |
| 1599 | // control character (including `"`, `\`, and `/`) or Unicode |
| 1600 | // escape sequence. |
| 1601 | charCode = source.charCodeAt(++Index); |
| 1602 | switch (charCode) { |
| 1603 | case 92: case 34: case 47: case 98: case 116: case 110: case 102: case 114: |
| 1604 | // Revive escaped control characters. |
| 1605 | value += Unescapes[charCode]; |
| 1606 | Index++; |
| 1607 | break; |
| 1608 | case 117: |
| 1609 | // `\u` marks the beginning of a Unicode escape sequence. |
| 1610 | // Advance to the first character and validate the |
| 1611 | // four-digit code point. |
| 1612 | begin = ++Index; |
| 1613 | for (position = Index + 4; Index < position; Index++) { |
| 1614 | charCode = source.charCodeAt(Index); |
| 1615 | // A valid sequence comprises four hexdigits (case- |
| 1616 | // insensitive) that form a single hexadecimal value. |
| 1617 | if (!(charCode >= 48 && charCode <= 57 || charCode >= 97 && charCode <= 102 || charCode >= 65 && charCode <= 70)) { |
| 1618 | // Invalid Unicode escape sequence. |
| 1619 | abort(); |
| 1620 | } |
| 1621 | } |
| 1622 | // Revive the escaped character. |
| 1623 | value += fromCharCode("0x" + source.slice(begin, Index)); |
| 1624 | break; |
| 1625 | default: |
| 1626 | // Invalid escape sequence. |
| 1627 | abort(); |
no test coverage detected