meriyah 4.5.0 → 6.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/CHANGELOG.md +415 -445
  2. package/README.md +52 -34
  3. package/dist/meriyah.cjs +9203 -8807
  4. package/dist/meriyah.min.mjs +1 -0
  5. package/dist/{meriyah.esm.js → meriyah.mjs} +9203 -8807
  6. package/dist/meriyah.umd.js +9203 -8807
  7. package/dist/meriyah.umd.min.js +1 -1
  8. package/dist/src/chars.d.ts +135 -135
  9. package/dist/src/common.d.ts +225 -200
  10. package/dist/src/common.d.ts.map +1 -1
  11. package/dist/src/errors.d.ts +197 -187
  12. package/dist/src/errors.d.ts.map +1 -1
  13. package/dist/src/estree.d.ts +524 -507
  14. package/dist/src/estree.d.ts.map +1 -1
  15. package/dist/src/lexer/charClassifier.d.ts +24 -24
  16. package/dist/src/lexer/charClassifier.d.ts.map +1 -1
  17. package/dist/src/lexer/comments.d.ts +14 -14
  18. package/dist/src/lexer/common.d.ts +25 -26
  19. package/dist/src/lexer/common.d.ts.map +1 -1
  20. package/dist/src/lexer/decodeHTML.d.ts +1 -1
  21. package/dist/src/lexer/decodeHTML.d.ts.map +1 -1
  22. package/dist/src/lexer/identifier.d.ts +8 -8
  23. package/dist/src/lexer/identifier.d.ts.map +1 -1
  24. package/dist/src/lexer/index.d.ts +9 -9
  25. package/dist/src/lexer/index.d.ts.map +1 -1
  26. package/dist/src/lexer/jsx.d.ts +6 -6
  27. package/dist/src/lexer/jsx.d.ts.map +1 -1
  28. package/dist/src/lexer/numeric.d.ts +5 -5
  29. package/dist/src/lexer/numeric.d.ts.map +1 -1
  30. package/dist/src/lexer/regexp.d.ts +3 -3
  31. package/dist/src/lexer/regexp.d.ts.map +1 -1
  32. package/dist/src/lexer/scan.d.ts +6 -6
  33. package/dist/src/lexer/scan.d.ts.map +1 -1
  34. package/dist/src/lexer/string.d.ts +12 -12
  35. package/dist/src/lexer/string.d.ts.map +1 -1
  36. package/dist/src/lexer/template.d.ts +4 -4
  37. package/dist/src/lexer/template.d.ts.map +1 -1
  38. package/dist/src/meriyah.d.ts +7 -7
  39. package/dist/src/meriyah.d.ts.map +1 -1
  40. package/dist/src/parser.d.ts +119 -118
  41. package/dist/src/parser.d.ts.map +1 -1
  42. package/dist/src/token.d.ts +167 -167
  43. package/dist/src/token.d.ts.map +1 -1
  44. package/dist/src/unicode.d.ts +5 -5
  45. package/package.json +44 -48
  46. package/dist/meriyah.amd.js +0 -8854
  47. package/dist/meriyah.amd.min.js +0 -1
  48. package/dist/meriyah.cjs.js +0 -8852
  49. package/dist/meriyah.cjs.min.js +0 -1
  50. package/dist/meriyah.esm.min.js +0 -1
  51. package/dist/meriyah.esm.min.mjs +0 -1
  52. package/dist/meriyah.esm.mjs +0 -8846
  53. package/dist/meriyah.iife.js +0 -8857
  54. package/dist/meriyah.iife.min.js +0 -1
  55. package/dist/meriyah.min.cjs +0 -1
  56. package/dist/meriyah.system.js +0 -8860
  57. package/dist/meriyah.system.min.js +0 -1
  58. package/dist/meriyah.umd.cjs +0 -8858
  59. package/dist/meriyah.umd.es5.js +0 -8927
  60. package/dist/meriyah.umd.es5.min.js +0 -1
  61. package/dist/meriyah.umd.min.cjs +0 -1
  62. package/src/chars.ts +0 -155
  63. package/src/common.ts +0 -841
  64. package/src/errors.ts +0 -419
  65. package/src/estree.ts +0 -817
  66. package/src/lexer/charClassifier.ts +0 -449
  67. package/src/lexer/comments.ts +0 -178
  68. package/src/lexer/common.ts +0 -140
  69. package/src/lexer/decodeHTML.ts +0 -2186
  70. package/src/lexer/identifier.ts +0 -196
  71. package/src/lexer/index.ts +0 -32
  72. package/src/lexer/jsx.ts +0 -126
  73. package/src/lexer/numeric.ts +0 -259
  74. package/src/lexer/regexp.ts +0 -156
  75. package/src/lexer/scan.ts +0 -655
  76. package/src/lexer/string.ts +0 -242
  77. package/src/lexer/template.ts +0 -108
  78. package/src/meriyah.ts +0 -29
  79. package/src/parser.ts +0 -9210
  80. package/src/token.ts +0 -307
  81. package/src/unicode.ts +0 -36
@@ -1,196 +0,0 @@
1
- import { ParserState, Context } from '../common';
2
- import { Token, descKeywordTable } from '../token';
3
- import { Chars } from '../chars';
4
- import { advanceChar, consumeMultiUnitCodePoint, fromCodePoint, toHex } from './common';
5
- import { CharTypes, CharFlags, isIdentifierPart, isIdentifierStart, isIdPart } from './charClassifier';
6
- import { report, reportScannerError, Errors } from '../errors';
7
-
8
- /**
9
- * Scans identifier
10
- *
11
- * @param parser Parser object
12
- * @param context Context masks
13
- */
14
- export function scanIdentifier(parser: ParserState, context: Context, isValidAsKeyword: 0 | 1): Token {
15
- while (isIdPart[advanceChar(parser)]) {}
16
- parser.tokenValue = parser.source.slice(parser.tokenPos, parser.index);
17
-
18
- return parser.currentChar !== Chars.Backslash && parser.currentChar <= 0x7e
19
- ? descKeywordTable[parser.tokenValue] || Token.Identifier
20
- : scanIdentifierSlowCase(parser, context, 0, isValidAsKeyword);
21
- }
22
-
23
- /**
24
- * Scans unicode identifier
25
- *
26
- * @param parser Parser object
27
- * @param context Context masks
28
- */
29
- export function scanUnicodeIdentifier(parser: ParserState, context: Context): Token {
30
- const cookedChar = scanIdentifierUnicodeEscape(parser);
31
- if (!isIdentifierPart(cookedChar)) report(parser, Errors.InvalidUnicodeEscapeSequence);
32
- parser.tokenValue = fromCodePoint(cookedChar);
33
- return scanIdentifierSlowCase(parser, context, /* hasEscape */ 1, CharTypes[cookedChar] & CharFlags.KeywordCandidate);
34
- }
35
-
36
- /**
37
- * Scans identifier slow case
38
- *
39
- * @param parser Parser object
40
- * @param context Context masks
41
- * @param hasEscape True if contains a unicode sequence
42
- * @param isValidAsKeyword
43
- */
44
- export function scanIdentifierSlowCase(
45
- parser: ParserState,
46
- context: Context,
47
- hasEscape: 0 | 1,
48
- isValidAsKeyword: number
49
- ): Token {
50
- let start = parser.index;
51
-
52
- while (parser.index < parser.end) {
53
- if (parser.currentChar === Chars.Backslash) {
54
- parser.tokenValue += parser.source.slice(start, parser.index);
55
- hasEscape = 1;
56
- const code = scanIdentifierUnicodeEscape(parser);
57
- if (!isIdentifierPart(code)) report(parser, Errors.InvalidUnicodeEscapeSequence);
58
- isValidAsKeyword = isValidAsKeyword && CharTypes[code] & CharFlags.KeywordCandidate;
59
- parser.tokenValue += fromCodePoint(code);
60
- start = parser.index;
61
- } else if (isIdentifierPart(parser.currentChar) || consumeMultiUnitCodePoint(parser, parser.currentChar)) {
62
- advanceChar(parser);
63
- } else {
64
- break;
65
- }
66
- }
67
-
68
- if (parser.index <= parser.end) {
69
- parser.tokenValue += parser.source.slice(start, parser.index);
70
- }
71
-
72
- const length = parser.tokenValue.length;
73
-
74
- if (isValidAsKeyword && length >= 2 && length <= 11) {
75
- const token: Token | undefined = descKeywordTable[parser.tokenValue];
76
- if (token === void 0) return Token.Identifier;
77
- if (!hasEscape) return token;
78
-
79
- if (token === Token.AwaitKeyword) {
80
- // await is only reserved word in async functions or modules
81
- if ((context & (Context.Module | Context.InAwaitContext)) === 0) {
82
- return token;
83
- }
84
- return Token.EscapedReserved;
85
- }
86
-
87
- if (context & Context.Strict) {
88
- if (token === Token.StaticKeyword) {
89
- return Token.EscapedFutureReserved;
90
- }
91
- if ((token & Token.FutureReserved) === Token.FutureReserved) {
92
- return Token.EscapedFutureReserved;
93
- }
94
- if ((token & Token.Reserved) === Token.Reserved) {
95
- if (context & Context.AllowEscapedKeyword && (context & Context.InGlobal) === 0) {
96
- return token;
97
- } else {
98
- return Token.EscapedReserved;
99
- }
100
- }
101
- return Token.AnyIdentifier;
102
- }
103
- if (
104
- context & Context.AllowEscapedKeyword &&
105
- (context & Context.InGlobal) === 0 &&
106
- (token & Token.Reserved) === Token.Reserved
107
- )
108
- return token;
109
- if (token === Token.YieldKeyword) {
110
- return context & Context.AllowEscapedKeyword
111
- ? Token.AnyIdentifier
112
- : context & Context.InYieldContext
113
- ? Token.EscapedReserved
114
- : token;
115
- }
116
-
117
- // async is not reserved; it can be used as a variable name
118
- // or statement label without restriction
119
- if (token === Token.AsyncKeyword) {
120
- // Escaped "async" such as \u0061sync can only be identifier
121
- // not as "async" keyword
122
- return Token.AnyIdentifier;
123
- }
124
- if ((token & Token.FutureReserved) === Token.FutureReserved) {
125
- return token;
126
- }
127
- return Token.EscapedReserved;
128
- }
129
- return Token.Identifier;
130
- }
131
-
132
- /**
133
- * Scans private name
134
- *
135
- * @param parser Parser object
136
- */
137
- export function scanPrivateIdentifier(parser: ParserState): Token {
138
- if (!isIdentifierStart(advanceChar(parser))) report(parser, Errors.MissingPrivateIdentifier);
139
- return Token.PrivateField;
140
- }
141
-
142
- /**
143
- * Scans unicode identifier
144
- *
145
- * @param parser Parser object
146
- */
147
- export function scanIdentifierUnicodeEscape(parser: ParserState): number {
148
- // Check for Unicode escape of the form '\uXXXX'
149
- // and return code point value if valid Unicode escape is found.
150
- if (parser.source.charCodeAt(parser.index + 1) !== Chars.LowerU) {
151
- report(parser, Errors.InvalidUnicodeEscapeSequence);
152
- }
153
- parser.currentChar = parser.source.charCodeAt((parser.index += 2));
154
- return scanUnicodeEscape(parser);
155
- }
156
-
157
- /**
158
- * Scans unicode escape value
159
- *
160
- * @param parser Parser object
161
- */
162
- export function scanUnicodeEscape(parser: ParserState): number {
163
- // Accept both \uxxxx and \u{xxxxxx}
164
- let codePoint = 0;
165
- const char = parser.currentChar;
166
- // First handle a delimited Unicode escape, e.g. \u{1F4A9}
167
- if (char === Chars.LeftBrace) {
168
- const begin = parser.index - 2;
169
- while (CharTypes[advanceChar(parser)] & CharFlags.Hex) {
170
- codePoint = (codePoint << 4) | toHex(parser.currentChar);
171
- if (codePoint > Chars.NonBMPMax) reportScannerError(begin, parser.line, parser.index + 1, Errors.UnicodeOverflow);
172
- }
173
-
174
- // At least 4 characters have to be read
175
- if ((parser.currentChar as number) !== Chars.RightBrace) {
176
- reportScannerError(begin, parser.line, parser.index - 1, Errors.InvalidHexEscapeSequence);
177
- }
178
- advanceChar(parser); // consumes '}'
179
- return codePoint;
180
- }
181
-
182
- if ((CharTypes[char] & CharFlags.Hex) === 0) report(parser, Errors.InvalidHexEscapeSequence); // first one is mandatory
183
-
184
- const char2 = parser.source.charCodeAt(parser.index + 1);
185
- if ((CharTypes[char2] & CharFlags.Hex) === 0) report(parser, Errors.InvalidHexEscapeSequence);
186
- const char3 = parser.source.charCodeAt(parser.index + 2);
187
- if ((CharTypes[char3] & CharFlags.Hex) === 0) report(parser, Errors.InvalidHexEscapeSequence);
188
- const char4 = parser.source.charCodeAt(parser.index + 3);
189
- if ((CharTypes[char4] & CharFlags.Hex) === 0) report(parser, Errors.InvalidHexEscapeSequence);
190
-
191
- codePoint = (toHex(char) << 12) | (toHex(char2) << 8) | (toHex(char3) << 4) | toHex(char4);
192
-
193
- parser.currentChar = parser.source.charCodeAt((parser.index += 4));
194
-
195
- return codePoint;
196
- }
@@ -1,32 +0,0 @@
1
- export { scanSingleToken, nextToken, TokenLookup } from './scan';
2
- export {
3
- skipMultiLineComment,
4
- skipSingleLineComment,
5
- skipHashBang,
6
- skipSingleHTMLComment,
7
- CommentType
8
- } from './comments';
9
- export {
10
- advanceChar,
11
- consumeMultiUnitCodePoint,
12
- isExoticECMAScriptWhitespace,
13
- fromCodePoint,
14
- toHex,
15
- consumeLineFeed,
16
- scanNewLine,
17
- LexerState,
18
- NumberKind,
19
- convertTokenType
20
- } from './common';
21
- export { CharTypes, CharFlags, isIdentifierStart, isIdentifierPart } from './charClassifier';
22
- export {
23
- scanIdentifier,
24
- scanIdentifierSlowCase,
25
- scanUnicodeIdentifier,
26
- scanPrivateIdentifier,
27
- scanUnicodeEscape
28
- } from './identifier';
29
- export { scanString } from './string';
30
- export { scanNumber } from './numeric';
31
- export { scanTemplate, scanTemplateTail } from './template';
32
- export { scanRegularExpression } from './regexp';
package/src/lexer/jsx.ts DELETED
@@ -1,126 +0,0 @@
1
- import { CharFlags, CharTypes } from './charClassifier';
2
- import { Chars } from '../chars';
3
- import { Token } from '../token';
4
- import { ParserState, Context } from '../common';
5
- import { report, Errors } from '../errors';
6
- import { advanceChar, LexerState, TokenLookup, scanSingleToken, scanNewLine, consumeLineFeed } from './';
7
- import { decodeHTMLStrict } from './decodeHTML';
8
-
9
- /**
10
- * Scans JSX attribute value
11
- *
12
- * @param parser The parser instance
13
- * @param context Context masks
14
- */
15
- export function scanJSXAttributeValue(parser: ParserState, context: Context): Token {
16
- parser.startPos = parser.tokenPos = parser.index;
17
- parser.startColumn = parser.colPos = parser.column;
18
- parser.startLine = parser.linePos = parser.line;
19
- parser.token =
20
- CharTypes[parser.currentChar] & CharFlags.StringLiteral
21
- ? scanJSXString(parser, context)
22
- : scanSingleToken(parser, context, LexerState.None);
23
- return parser.token;
24
- }
25
-
26
- /**
27
- * Scans JSX string
28
- *
29
- * @param parser The parser object
30
- */
31
- export function scanJSXString(parser: ParserState, context: Context): Token {
32
- const quote = parser.currentChar;
33
- let char = advanceChar(parser);
34
- const start = parser.index;
35
- while (char !== quote) {
36
- if (parser.index >= parser.end) report(parser, Errors.UnterminatedString);
37
- char = advanceChar(parser);
38
- }
39
-
40
- // check for unterminated string
41
- if (char !== quote) report(parser, Errors.UnterminatedString);
42
- parser.tokenValue = parser.source.slice(start, parser.index);
43
- advanceChar(parser); // skip the quote
44
- if (context & Context.OptionsRaw) parser.tokenRaw = parser.source.slice(parser.tokenPos, parser.index);
45
- return Token.StringLiteral;
46
- }
47
-
48
- /**
49
- * Scans JSX token
50
- *
51
- * @param parser The parser object
52
- */
53
- export function scanJSXToken(parser: ParserState, context: Context): Token {
54
- parser.startPos = parser.tokenPos = parser.index;
55
- parser.startColumn = parser.colPos = parser.column;
56
- parser.startLine = parser.linePos = parser.line;
57
-
58
- if (parser.index >= parser.end) return (parser.token = Token.EOF);
59
-
60
- const token = TokenLookup[parser.source.charCodeAt(parser.index)];
61
-
62
- switch (token) {
63
- // '<'
64
- case Token.LessThan: {
65
- advanceChar(parser);
66
- if (parser.currentChar === Chars.Slash) {
67
- advanceChar(parser);
68
- parser.token = Token.JSXClose;
69
- } else {
70
- parser.token = Token.LessThan;
71
- }
72
-
73
- break;
74
- }
75
- // '{'
76
- case Token.LeftBrace: {
77
- advanceChar(parser);
78
- parser.token = Token.LeftBrace;
79
- break;
80
- }
81
- default: {
82
- let state = LexerState.None;
83
-
84
- while (parser.index < parser.end) {
85
- const type = CharTypes[parser.source.charCodeAt(parser.index)];
86
-
87
- if (type & CharFlags.CarriageReturn) {
88
- state |= LexerState.NewLine | LexerState.LastIsCR;
89
- scanNewLine(parser);
90
- } else if (type & CharFlags.LineFeed) {
91
- consumeLineFeed(parser, state);
92
- state = (state & ~LexerState.LastIsCR) | LexerState.NewLine;
93
- } else {
94
- advanceChar(parser);
95
- }
96
-
97
- if (CharTypes[parser.currentChar] & CharFlags.JSXToken) break;
98
- }
99
-
100
- const raw = parser.source.slice(parser.tokenPos, parser.index);
101
- if (context & Context.OptionsRaw) parser.tokenRaw = raw;
102
- parser.tokenValue = decodeHTMLStrict(raw);
103
- parser.token = Token.JSXText;
104
- }
105
- }
106
-
107
- return parser.token;
108
- }
109
-
110
- /**
111
- * Scans JSX identifier
112
- *
113
- * @param parser The parser instance
114
- */
115
- export function scanJSXIdentifier(parser: ParserState): Token {
116
- if ((parser.token & Token.IsIdentifier) === Token.IsIdentifier) {
117
- const { index } = parser;
118
- let char = parser.currentChar;
119
- while (CharTypes[char] & (CharFlags.Hyphen | CharFlags.IdentifierPart)) {
120
- char = advanceChar(parser);
121
- }
122
- parser.tokenValue += parser.source.slice(index, parser.index);
123
- }
124
- parser.token = Token.Identifier;
125
- return parser.token;
126
- }
@@ -1,259 +0,0 @@
1
- import { ParserState, Context, Flags } from '../common';
2
- import { Token } from '../token';
3
- import { advanceChar, toHex, NumberKind } from './common';
4
- import { CharTypes, CharFlags, isIdentifierStart } from './charClassifier';
5
- import { Chars } from '../chars';
6
- import { report, Errors, reportScannerError } from '../errors';
7
-
8
- /**
9
- * Scans numeric literal
10
- *
11
- * @param parser Parser object
12
- * @param context Context masks
13
- * @param isFloat
14
- */
15
- export function scanNumber(parser: ParserState, context: Context, kind: NumberKind): Token {
16
- // DecimalLiteral ::
17
- // DecimalIntegerLiteral . DecimalDigits_opt
18
- // . DecimalDigits
19
- let char = parser.currentChar;
20
- let value: any = 0;
21
- let digit = 9;
22
- let atStart = kind & NumberKind.Float ? 0 : 1;
23
- let digits = 0;
24
- let allowSeparator: 0 | 1 = 0;
25
-
26
- if (kind & NumberKind.Float) {
27
- value = '.' + scanDecimalDigitsOrSeparator(parser, char);
28
- char = parser.currentChar;
29
- // It is a Syntax Error if the MV is not an integer. (dot decimalDigits)
30
- if (char === Chars.LowerN) report(parser, Errors.InvalidBigInt);
31
- } else {
32
- if (char === Chars.Zero) {
33
- char = advanceChar(parser);
34
-
35
- // Hex
36
- if ((char | 32) === Chars.LowerX) {
37
- kind = NumberKind.Hex | NumberKind.ValidBigIntKind;
38
- char = advanceChar(parser); // skips 'X', 'x'
39
- while (CharTypes[char] & (CharFlags.Hex | CharFlags.Underscore)) {
40
- if (char === Chars.Underscore) {
41
- if (!allowSeparator) report(parser, Errors.ContinuousNumericSeparator);
42
- allowSeparator = 0;
43
- char = advanceChar(parser);
44
- continue;
45
- }
46
- allowSeparator = 1;
47
- value = value * 0x10 + toHex(char);
48
- digits++;
49
- char = advanceChar(parser);
50
- }
51
-
52
- if (digits === 0 || !allowSeparator) {
53
- report(parser, digits === 0 ? Errors.MissingHexDigits : Errors.TrailingNumericSeparator);
54
- }
55
- // Octal
56
- } else if ((char | 32) === Chars.LowerO) {
57
- kind = NumberKind.Octal | NumberKind.ValidBigIntKind;
58
- char = advanceChar(parser); // skips 'X', 'x'
59
- while (CharTypes[char] & (CharFlags.Octal | CharFlags.Underscore)) {
60
- if (char === Chars.Underscore) {
61
- if (!allowSeparator) {
62
- report(parser, Errors.ContinuousNumericSeparator);
63
- }
64
- allowSeparator = 0;
65
- char = advanceChar(parser);
66
- continue;
67
- }
68
- allowSeparator = 1;
69
- value = value * 8 + (char - Chars.Zero);
70
- digits++;
71
- char = advanceChar(parser);
72
- }
73
- if (digits === 0 || !allowSeparator) {
74
- report(parser, digits === 0 ? Errors.Unexpected : Errors.TrailingNumericSeparator);
75
- }
76
- } else if ((char | 32) === Chars.LowerB) {
77
- kind = NumberKind.Binary | NumberKind.ValidBigIntKind;
78
- char = advanceChar(parser); // skips 'B', 'b'
79
- while (CharTypes[char] & (CharFlags.Binary | CharFlags.Underscore)) {
80
- if (char === Chars.Underscore) {
81
- if (!allowSeparator) {
82
- report(parser, Errors.ContinuousNumericSeparator);
83
- }
84
- allowSeparator = 0;
85
- char = advanceChar(parser);
86
- continue;
87
- }
88
- allowSeparator = 1;
89
- value = value * 2 + (char - Chars.Zero);
90
- digits++;
91
- char = advanceChar(parser);
92
- }
93
- if (digits === 0 || !allowSeparator) {
94
- report(parser, digits === 0 ? Errors.Unexpected : Errors.TrailingNumericSeparator);
95
- }
96
- } else if (CharTypes[char] & CharFlags.Octal) {
97
- // Octal integer literals are not permitted in strict mode code
98
- if (context & Context.Strict) report(parser, Errors.StrictOctalEscape);
99
- kind = NumberKind.ImplicitOctal;
100
- while (CharTypes[char] & CharFlags.Decimal) {
101
- if (CharTypes[char] & CharFlags.ImplicitOctalDigits) {
102
- kind = NumberKind.NonOctalDecimal;
103
- atStart = 0;
104
- break;
105
- }
106
- value = value * 8 + (char - Chars.Zero);
107
- char = advanceChar(parser);
108
- }
109
- } else if (CharTypes[char] & CharFlags.ImplicitOctalDigits) {
110
- if (context & Context.Strict) report(parser, Errors.StrictOctalEscape);
111
- parser.flags |= Flags.Octals;
112
- kind = NumberKind.NonOctalDecimal;
113
- } else if (char === Chars.Underscore) {
114
- report(parser, Errors.Unexpected);
115
- }
116
- }
117
-
118
- // Parse decimal digits and allow trailing fractional part
119
- if (kind & NumberKind.DecimalNumberKind) {
120
- if (atStart) {
121
- while (digit >= 0 && CharTypes[char] & (CharFlags.Decimal | CharFlags.Underscore)) {
122
- if (char === Chars.Underscore) {
123
- char = advanceChar(parser);
124
- if (char === Chars.Underscore || kind & NumberKind.NonOctalDecimal) {
125
- reportScannerError(
126
- parser.index,
127
- parser.line,
128
- parser.index + 1 /* skips `_` */,
129
- Errors.ContinuousNumericSeparator
130
- );
131
- }
132
- allowSeparator = 1;
133
- continue;
134
- }
135
- allowSeparator = 0;
136
- value = 10 * value + (char - Chars.Zero);
137
- char = advanceChar(parser);
138
- --digit;
139
- }
140
-
141
- if (allowSeparator) {
142
- reportScannerError(
143
- parser.index,
144
- parser.line,
145
- parser.index + 1 /* skips `_` */,
146
- Errors.TrailingNumericSeparator
147
- );
148
- }
149
-
150
- if (digit >= 0 && !isIdentifierStart(char) && char !== Chars.Period) {
151
- // Most numbers are pure decimal integers without fractional component
152
- // or exponential notation. Handle that with optimized code.
153
- parser.tokenValue = value;
154
- if (context & Context.OptionsRaw) parser.tokenRaw = parser.source.slice(parser.tokenPos, parser.index);
155
- return Token.NumericLiteral;
156
- }
157
- }
158
-
159
- value += scanDecimalDigitsOrSeparator(parser, char);
160
-
161
- char = parser.currentChar;
162
-
163
- // Consume any decimal dot and fractional component.
164
- if (char === Chars.Period) {
165
- if (advanceChar(parser) === Chars.Underscore) report(parser, Errors.Unexpected);
166
- kind = NumberKind.Float;
167
- value += '.' + scanDecimalDigitsOrSeparator(parser, parser.currentChar);
168
- char = parser.currentChar;
169
- }
170
- }
171
- }
172
- const end = parser.index;
173
-
174
- let isBigInt: 0 | 1 = 0;
175
-
176
- if (char === Chars.LowerN && kind & NumberKind.ValidBigIntKind) {
177
- isBigInt = 1;
178
- char = advanceChar(parser);
179
- } else {
180
- // Consume any exponential notation.
181
- if ((char | 32) === Chars.LowerE) {
182
- char = advanceChar(parser);
183
-
184
- // '-', '+'
185
- if (CharTypes[char] & CharFlags.Exponent) char = advanceChar(parser);
186
-
187
- const { index } = parser;
188
-
189
- // Exponential notation must contain at least one digit
190
- if ((CharTypes[char] & CharFlags.Decimal) === 0) report(parser, Errors.MissingExponent);
191
-
192
- // Consume exponential digits
193
- value += parser.source.substring(end, index) + scanDecimalDigitsOrSeparator(parser, char);
194
-
195
- char = parser.currentChar;
196
- }
197
- }
198
-
199
- // The source character immediately following a numeric literal must
200
- // not be an identifier start or a decimal digit
201
- if ((parser.index < parser.end && CharTypes[char] & CharFlags.Decimal) || isIdentifierStart(char)) {
202
- report(parser, Errors.IDStartAfterNumber);
203
- }
204
-
205
- if (isBigInt) {
206
- parser.tokenRaw = parser.source.slice(parser.tokenPos, parser.index);
207
- parser.tokenValue = BigInt(value);
208
- return Token.BigIntLiteral;
209
- }
210
-
211
- parser.tokenValue =
212
- kind & (NumberKind.ImplicitOctal | NumberKind.Binary | NumberKind.Hex | NumberKind.Octal)
213
- ? value
214
- : kind & NumberKind.NonOctalDecimal
215
- ? parseFloat(parser.source.substring(parser.tokenPos, parser.index))
216
- : +value;
217
-
218
- if (context & Context.OptionsRaw) parser.tokenRaw = parser.source.slice(parser.tokenPos, parser.index);
219
-
220
- return Token.NumericLiteral;
221
- }
222
-
223
- /**
224
- * Scans numeric literal and skip underscore '_' if it exist
225
- *
226
- * @param parser Parser object
227
- * @param char Code point
228
- */
229
- export function scanDecimalDigitsOrSeparator(parser: ParserState, char: number): string {
230
- let allowSeparator: 0 | 1 = 0;
231
- let start = parser.index;
232
- let ret = '';
233
- while (CharTypes[char] & (CharFlags.Decimal | CharFlags.Underscore)) {
234
- if (char === Chars.Underscore) {
235
- const { index } = parser;
236
- char = advanceChar(parser);
237
- if (char === Chars.Underscore) {
238
- reportScannerError(
239
- parser.index,
240
- parser.line,
241
- parser.index + 1 /* skips `_` */,
242
- Errors.ContinuousNumericSeparator
243
- );
244
- }
245
- allowSeparator = 1;
246
- ret += parser.source.substring(start, index);
247
- start = parser.index;
248
- continue;
249
- }
250
- allowSeparator = 0;
251
- char = advanceChar(parser);
252
- }
253
-
254
- if (allowSeparator) {
255
- reportScannerError(parser.index, parser.line, parser.index + 1 /* skips `_` */, Errors.TrailingNumericSeparator);
256
- }
257
-
258
- return ret + parser.source.substring(start, parser.index);
259
- }