meriyah 5.0.0 → 6.0.1

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 (69) hide show
  1. package/CHANGELOG.md +88 -0
  2. package/README.md +38 -14
  3. package/dist/meriyah.cjs +2358 -2074
  4. package/dist/meriyah.min.mjs +1 -0
  5. package/dist/{meriyah.esm.js → meriyah.mjs} +2358 -2074
  6. package/dist/meriyah.umd.js +2358 -2074
  7. package/dist/meriyah.umd.min.js +1 -1
  8. package/dist/src/common.d.ts +71 -47
  9. package/dist/src/common.d.ts.map +1 -1
  10. package/dist/src/errors.d.ts +186 -177
  11. package/dist/src/errors.d.ts.map +1 -1
  12. package/dist/src/estree.d.ts +15 -6
  13. package/dist/src/estree.d.ts.map +1 -1
  14. package/dist/src/lexer/charClassifier.d.ts +2 -2
  15. package/dist/src/lexer/charClassifier.d.ts.map +1 -1
  16. package/dist/src/lexer/common.d.ts +1 -2
  17. package/dist/src/lexer/common.d.ts.map +1 -1
  18. package/dist/src/lexer/identifier.d.ts.map +1 -1
  19. package/dist/src/lexer/index.d.ts +1 -1
  20. package/dist/src/lexer/index.d.ts.map +1 -1
  21. package/dist/src/lexer/jsx.d.ts +2 -2
  22. package/dist/src/lexer/jsx.d.ts.map +1 -1
  23. package/dist/src/lexer/numeric.d.ts.map +1 -1
  24. package/dist/src/lexer/regexp.d.ts.map +1 -1
  25. package/dist/src/lexer/scan.d.ts.map +1 -1
  26. package/dist/src/lexer/string.d.ts +1 -1
  27. package/dist/src/lexer/string.d.ts.map +1 -1
  28. package/dist/src/lexer/template.d.ts.map +1 -1
  29. package/dist/src/parser.d.ts +72 -72
  30. package/dist/src/parser.d.ts.map +1 -1
  31. package/dist/src/token.d.ts +115 -115
  32. package/dist/src/token.d.ts.map +1 -1
  33. package/package.json +26 -35
  34. package/dist/meriyah.amd.js +0 -8964
  35. package/dist/meriyah.amd.min.js +0 -1
  36. package/dist/meriyah.cjs.js +0 -8962
  37. package/dist/meriyah.cjs.min.js +0 -1
  38. package/dist/meriyah.esm.min.js +0 -1
  39. package/dist/meriyah.esm.min.mjs +0 -1
  40. package/dist/meriyah.esm.mjs +0 -8956
  41. package/dist/meriyah.iife.js +0 -8967
  42. package/dist/meriyah.iife.min.js +0 -1
  43. package/dist/meriyah.min.cjs +0 -1
  44. package/dist/meriyah.system.js +0 -8970
  45. package/dist/meriyah.system.min.js +0 -1
  46. package/dist/meriyah.umd.cjs +0 -8968
  47. package/dist/meriyah.umd.es5.js +0 -9022
  48. package/dist/meriyah.umd.es5.min.js +0 -1
  49. package/dist/meriyah.umd.min.cjs +0 -1
  50. package/src/chars.ts +0 -155
  51. package/src/common.ts +0 -834
  52. package/src/errors.ts +0 -421
  53. package/src/estree.ts +0 -827
  54. package/src/lexer/charClassifier.ts +0 -449
  55. package/src/lexer/comments.ts +0 -178
  56. package/src/lexer/common.ts +0 -140
  57. package/src/lexer/decodeHTML.ts +0 -2184
  58. package/src/lexer/identifier.ts +0 -196
  59. package/src/lexer/index.ts +0 -32
  60. package/src/lexer/jsx.ts +0 -127
  61. package/src/lexer/numeric.ts +0 -259
  62. package/src/lexer/regexp.ts +0 -156
  63. package/src/lexer/scan.ts +0 -657
  64. package/src/lexer/string.ts +0 -242
  65. package/src/lexer/template.ts +0 -108
  66. package/src/meriyah.ts +0 -28
  67. package/src/parser.ts +0 -9358
  68. package/src/token.ts +0 -307
  69. 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;
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,127 +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.setToken(
20
- CharTypes[parser.currentChar] & CharFlags.StringLiteral
21
- ? scanJSXString(parser, context)
22
- : scanSingleToken(parser, context, LexerState.None)
23
- );
24
- return parser.getToken();
25
- }
26
-
27
- /**
28
- * Scans JSX string
29
- *
30
- * @param parser The parser object
31
- */
32
- export function scanJSXString(parser: ParserState, context: Context): Token {
33
- const quote = parser.currentChar;
34
- let char = advanceChar(parser);
35
- const start = parser.index;
36
- while (char !== quote) {
37
- if (parser.index >= parser.end) report(parser, Errors.UnterminatedString);
38
- char = advanceChar(parser);
39
- }
40
-
41
- // check for unterminated string
42
- if (char !== quote) report(parser, Errors.UnterminatedString);
43
- parser.tokenValue = parser.source.slice(start, parser.index);
44
- advanceChar(parser); // skip the quote
45
- if (context & Context.OptionsRaw) parser.tokenRaw = parser.source.slice(parser.tokenPos, parser.index);
46
- return Token.StringLiteral;
47
- }
48
-
49
- /**
50
- * Scans JSX token
51
- *
52
- * @param parser The parser object
53
- */
54
- export function scanJSXToken(parser: ParserState, context: Context): Token {
55
- parser.startPos = parser.tokenPos = parser.index;
56
- parser.startColumn = parser.colPos = parser.column;
57
- parser.startLine = parser.linePos = parser.line;
58
-
59
- if (parser.index >= parser.end) return parser.setToken(Token.EOF);
60
-
61
- const token = TokenLookup[parser.source.charCodeAt(parser.index)];
62
-
63
- switch (token) {
64
- // '<'
65
- case Token.LessThan: {
66
- advanceChar(parser);
67
- if (parser.currentChar === Chars.Slash) {
68
- advanceChar(parser);
69
- parser.setToken(Token.JSXClose);
70
- } else {
71
- parser.setToken(Token.LessThan);
72
- }
73
-
74
- break;
75
- }
76
- // '{'
77
- case Token.LeftBrace: {
78
- advanceChar(parser);
79
- parser.setToken(Token.LeftBrace);
80
- break;
81
- }
82
- default: {
83
- let state = LexerState.None;
84
-
85
- while (parser.index < parser.end) {
86
- const type = CharTypes[parser.source.charCodeAt(parser.index)];
87
-
88
- if (type & CharFlags.CarriageReturn) {
89
- state |= LexerState.NewLine | LexerState.LastIsCR;
90
- scanNewLine(parser);
91
- } else if (type & CharFlags.LineFeed) {
92
- consumeLineFeed(parser, state);
93
- state = (state & ~LexerState.LastIsCR) | LexerState.NewLine;
94
- } else {
95
- advanceChar(parser);
96
- }
97
-
98
- if (CharTypes[parser.currentChar] & CharFlags.JSXToken) break;
99
- }
100
-
101
- const raw = parser.source.slice(parser.tokenPos, parser.index);
102
- if (context & Context.OptionsRaw) parser.tokenRaw = raw;
103
- parser.tokenValue = decodeHTMLStrict(raw);
104
- parser.setToken(Token.JSXText);
105
- }
106
- }
107
-
108
- return parser.getToken();
109
- }
110
-
111
- /**
112
- * Scans JSX identifier
113
- *
114
- * @param parser The parser instance
115
- */
116
- export function scanJSXIdentifier(parser: ParserState): Token {
117
- if ((parser.getToken() & Token.IsIdentifier) === Token.IsIdentifier) {
118
- const { index } = parser;
119
- let char = parser.currentChar;
120
- while (CharTypes[char] & (CharFlags.Hyphen | CharFlags.IdentifierPart)) {
121
- char = advanceChar(parser);
122
- }
123
- parser.tokenValue += parser.source.slice(index, parser.index);
124
- }
125
- parser.setToken(Token.Identifier);
126
- return parser.getToken();
127
- }
@@ -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
- }