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.
- package/CHANGELOG.md +415 -445
- package/README.md +52 -34
- package/dist/meriyah.cjs +9203 -8807
- package/dist/meriyah.min.mjs +1 -0
- package/dist/{meriyah.esm.js → meriyah.mjs} +9203 -8807
- package/dist/meriyah.umd.js +9203 -8807
- package/dist/meriyah.umd.min.js +1 -1
- package/dist/src/chars.d.ts +135 -135
- package/dist/src/common.d.ts +225 -200
- package/dist/src/common.d.ts.map +1 -1
- package/dist/src/errors.d.ts +197 -187
- package/dist/src/errors.d.ts.map +1 -1
- package/dist/src/estree.d.ts +524 -507
- package/dist/src/estree.d.ts.map +1 -1
- package/dist/src/lexer/charClassifier.d.ts +24 -24
- package/dist/src/lexer/charClassifier.d.ts.map +1 -1
- package/dist/src/lexer/comments.d.ts +14 -14
- package/dist/src/lexer/common.d.ts +25 -26
- package/dist/src/lexer/common.d.ts.map +1 -1
- package/dist/src/lexer/decodeHTML.d.ts +1 -1
- package/dist/src/lexer/decodeHTML.d.ts.map +1 -1
- package/dist/src/lexer/identifier.d.ts +8 -8
- package/dist/src/lexer/identifier.d.ts.map +1 -1
- package/dist/src/lexer/index.d.ts +9 -9
- package/dist/src/lexer/index.d.ts.map +1 -1
- package/dist/src/lexer/jsx.d.ts +6 -6
- package/dist/src/lexer/jsx.d.ts.map +1 -1
- package/dist/src/lexer/numeric.d.ts +5 -5
- package/dist/src/lexer/numeric.d.ts.map +1 -1
- package/dist/src/lexer/regexp.d.ts +3 -3
- package/dist/src/lexer/regexp.d.ts.map +1 -1
- package/dist/src/lexer/scan.d.ts +6 -6
- package/dist/src/lexer/scan.d.ts.map +1 -1
- package/dist/src/lexer/string.d.ts +12 -12
- package/dist/src/lexer/string.d.ts.map +1 -1
- package/dist/src/lexer/template.d.ts +4 -4
- package/dist/src/lexer/template.d.ts.map +1 -1
- package/dist/src/meriyah.d.ts +7 -7
- package/dist/src/meriyah.d.ts.map +1 -1
- package/dist/src/parser.d.ts +119 -118
- package/dist/src/parser.d.ts.map +1 -1
- package/dist/src/token.d.ts +167 -167
- package/dist/src/token.d.ts.map +1 -1
- package/dist/src/unicode.d.ts +5 -5
- package/package.json +44 -48
- package/dist/meriyah.amd.js +0 -8854
- package/dist/meriyah.amd.min.js +0 -1
- package/dist/meriyah.cjs.js +0 -8852
- package/dist/meriyah.cjs.min.js +0 -1
- package/dist/meriyah.esm.min.js +0 -1
- package/dist/meriyah.esm.min.mjs +0 -1
- package/dist/meriyah.esm.mjs +0 -8846
- package/dist/meriyah.iife.js +0 -8857
- package/dist/meriyah.iife.min.js +0 -1
- package/dist/meriyah.min.cjs +0 -1
- package/dist/meriyah.system.js +0 -8860
- package/dist/meriyah.system.min.js +0 -1
- package/dist/meriyah.umd.cjs +0 -8858
- package/dist/meriyah.umd.es5.js +0 -8927
- package/dist/meriyah.umd.es5.min.js +0 -1
- package/dist/meriyah.umd.min.cjs +0 -1
- package/src/chars.ts +0 -155
- package/src/common.ts +0 -841
- package/src/errors.ts +0 -419
- package/src/estree.ts +0 -817
- package/src/lexer/charClassifier.ts +0 -449
- package/src/lexer/comments.ts +0 -178
- package/src/lexer/common.ts +0 -140
- package/src/lexer/decodeHTML.ts +0 -2186
- package/src/lexer/identifier.ts +0 -196
- package/src/lexer/index.ts +0 -32
- package/src/lexer/jsx.ts +0 -126
- package/src/lexer/numeric.ts +0 -259
- package/src/lexer/regexp.ts +0 -156
- package/src/lexer/scan.ts +0 -655
- package/src/lexer/string.ts +0 -242
- package/src/lexer/template.ts +0 -108
- package/src/meriyah.ts +0 -29
- package/src/parser.ts +0 -9210
- package/src/token.ts +0 -307
- package/src/unicode.ts +0 -36
package/src/lexer/identifier.ts
DELETED
|
@@ -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
|
-
}
|
package/src/lexer/index.ts
DELETED
|
@@ -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
|
-
}
|
package/src/lexer/numeric.ts
DELETED
|
@@ -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
|
-
}
|