diff options
author | Minteck <nekostarfan@gmail.com> | 2021-08-24 14:41:48 +0200 |
---|---|---|
committer | Minteck <nekostarfan@gmail.com> | 2021-08-24 14:41:48 +0200 |
commit | d25e11bee6ca5ca523884da132d18e1400e077b9 (patch) | |
tree | 8af39fde19f7ed640a60fb397c7edd647dff1c4c /node_modules/meriyah/src/lexer/scan.ts | |
download | kartik-iridium-d25e11bee6ca5ca523884da132d18e1400e077b9.tar.gz kartik-iridium-d25e11bee6ca5ca523884da132d18e1400e077b9.tar.bz2 kartik-iridium-d25e11bee6ca5ca523884da132d18e1400e077b9.zip |
Initial commit
Diffstat (limited to 'node_modules/meriyah/src/lexer/scan.ts')
-rw-r--r-- | node_modules/meriyah/src/lexer/scan.ts | 655 |
1 files changed, 655 insertions, 0 deletions
diff --git a/node_modules/meriyah/src/lexer/scan.ts b/node_modules/meriyah/src/lexer/scan.ts new file mode 100644 index 0000000..25063e7 --- /dev/null +++ b/node_modules/meriyah/src/lexer/scan.ts @@ -0,0 +1,655 @@ +import { Chars } from '../chars'; +import { Token } from '../token'; +import { ParserState, Context, Flags } from '../common'; +import { report, Errors } from '../errors'; +import { unicodeLookup } from '../unicode'; +import { + advanceChar, + LexerState, + isExoticECMAScriptWhitespace, + NumberKind, + fromCodePoint, + consumeLineFeed, + scanNewLine, + convertTokenType +} from './common'; +import { skipSingleLineComment, skipMultiLineComment, skipSingleHTMLComment, CommentType } from './comments'; +import { scanRegularExpression } from './regexp'; +import { scanTemplate } from './template'; +import { scanNumber } from './numeric'; +import { scanString } from './string'; +import { scanIdentifier, scanUnicodeIdentifier, scanIdentifierSlowCase, scanPrivateIdentifier } from './identifier'; + +/* + * OneChar: 40, 41, 44, 58, 59, 63, 91, 93, 123, 125, 126: + * '(', ')', ',', ':', ';', '?', '[', ']', '{', '}', '~' + * PrivateField: 35: '#', + * Identifier: 36, 65..90, 92, 95, 97..122: '$', 'A'..'Z', '_', '\'', 'a'..'z' + * Period: 46: '.' + * StringLiteral: 34, 39: '"', `'` + * NumericLiteral: 48, 49..57: '0'..'9' + * WhiteSpace: 9, 11, 12, 32: '\t', '\v', '\f', ' ' + * LineFeed: 10: '\n' + * CarriageReturn: 13: '\r' + * Template: 96: '`' + */ + +export const TokenLookup = [ + /* 0 - Null */ Token.Illegal, + /* 1 - Start of Heading */ Token.Illegal, + /* 2 - Start of Text */ Token.Illegal, + /* 3 - End of Text */ Token.Illegal, + /* 4 - End of Transm. */ Token.Illegal, + /* 5 - Enquiry */ Token.Illegal, + /* 6 - Acknowledgment */ Token.Illegal, + /* 7 - Bell */ Token.Illegal, + /* 8 - Backspace */ Token.Illegal, + /* 9 - Horizontal Tab */ Token.WhiteSpace, + /* 10 - Line Feed */ Token.LineFeed, + /* 11 - Vertical Tab */ Token.WhiteSpace, + /* 12 - Form Feed */ Token.WhiteSpace, + /* 13 - Carriage Return */ Token.CarriageReturn, + /* 14 - Shift Out */ Token.Illegal, + /* 15 - Shift In */ Token.Illegal, + /* 16 - Data Line Escape */ Token.Illegal, + /* 17 - Device Control 1 */ Token.Illegal, + /* 18 - Device Control 2 */ Token.Illegal, + /* 19 - Device Control 3 */ Token.Illegal, + /* 20 - Device Control 4 */ Token.Illegal, + /* 21 - Negative Ack. */ Token.Illegal, + /* 22 - Synchronous Idle */ Token.Illegal, + /* 23 - End of Transmit */ Token.Illegal, + /* 24 - Cancel */ Token.Illegal, + /* 25 - End of Medium */ Token.Illegal, + /* 26 - Substitute */ Token.Illegal, + /* 27 - Escape */ Token.Illegal, + /* 28 - File Separator */ Token.Illegal, + /* 29 - Group Separator */ Token.Illegal, + /* 30 - Record Separator */ Token.Illegal, + /* 31 - Unit Separator */ Token.Illegal, + /* 32 - Space */ Token.WhiteSpace, + /* 33 - ! */ Token.Negate, + /* 34 - " */ Token.StringLiteral, + /* 35 - # */ Token.PrivateField, + /* 36 - $ */ Token.Identifier, + /* 37 - % */ Token.Modulo, + /* 38 - & */ Token.BitwiseAnd, + /* 39 - ' */ Token.StringLiteral, + /* 40 - ( */ Token.LeftParen, + /* 41 - ) */ Token.RightParen, + /* 42 - * */ Token.Multiply, + /* 43 - + */ Token.Add, + /* 44 - , */ Token.Comma, + /* 45 - - */ Token.Subtract, + /* 46 - . */ Token.Period, + /* 47 - / */ Token.Divide, + /* 48 - 0 */ Token.NumericLiteral, + /* 49 - 1 */ Token.NumericLiteral, + /* 50 - 2 */ Token.NumericLiteral, + /* 51 - 3 */ Token.NumericLiteral, + /* 52 - 4 */ Token.NumericLiteral, + /* 53 - 5 */ Token.NumericLiteral, + /* 54 - 6 */ Token.NumericLiteral, + /* 55 - 7 */ Token.NumericLiteral, + /* 56 - 8 */ Token.NumericLiteral, + /* 57 - 9 */ Token.NumericLiteral, + /* 58 - : */ Token.Colon, + /* 59 - ; */ Token.Semicolon, + /* 60 - < */ Token.LessThan, + /* 61 - = */ Token.Assign, + /* 62 - > */ Token.GreaterThan, + /* 63 - ? */ Token.QuestionMark, + /* 64 - @ */ Token.Decorator, + /* 65 - A */ Token.Identifier, + /* 66 - B */ Token.Identifier, + /* 67 - C */ Token.Identifier, + /* 68 - D */ Token.Identifier, + /* 69 - E */ Token.Identifier, + /* 70 - F */ Token.Identifier, + /* 71 - G */ Token.Identifier, + /* 72 - H */ Token.Identifier, + /* 73 - I */ Token.Identifier, + /* 74 - J */ Token.Identifier, + /* 75 - K */ Token.Identifier, + /* 76 - L */ Token.Identifier, + /* 77 - M */ Token.Identifier, + /* 78 - N */ Token.Identifier, + /* 79 - O */ Token.Identifier, + /* 80 - P */ Token.Identifier, + /* 81 - Q */ Token.Identifier, + /* 82 - R */ Token.Identifier, + /* 83 - S */ Token.Identifier, + /* 84 - T */ Token.Identifier, + /* 85 - U */ Token.Identifier, + /* 86 - V */ Token.Identifier, + /* 87 - W */ Token.Identifier, + /* 88 - X */ Token.Identifier, + /* 89 - Y */ Token.Identifier, + /* 90 - Z */ Token.Identifier, + /* 91 - [ */ Token.LeftBracket, + /* 92 - \ */ Token.EscapedIdentifier, + /* 93 - ] */ Token.RightBracket, + /* 94 - ^ */ Token.BitwiseXor, + /* 95 - _ */ Token.Identifier, + /* 96 - ` */ Token.Template, + /* 97 - a */ Token.Keyword, + /* 98 - b */ Token.Keyword, + /* 99 - c */ Token.Keyword, + /* 100 - d */ Token.Keyword, + /* 101 - e */ Token.Keyword, + /* 102 - f */ Token.Keyword, + /* 103 - g */ Token.Keyword, + /* 104 - h */ Token.Identifier, + /* 105 - i */ Token.Keyword, + /* 106 - j */ Token.Identifier, + /* 107 - k */ Token.Identifier, + /* 108 - l */ Token.Keyword, + /* 109 - m */ Token.Identifier, + /* 110 - n */ Token.Keyword, + /* 111 - o */ Token.Identifier, + /* 112 - p */ Token.Keyword, + /* 113 - q */ Token.Identifier, + /* 114 - r */ Token.Keyword, + /* 115 - s */ Token.Keyword, + /* 116 - t */ Token.Keyword, + /* 117 - u */ Token.Identifier, + /* 118 - v */ Token.Keyword, + /* 119 - w */ Token.Keyword, + /* 120 - x */ Token.Identifier, + /* 121 - y */ Token.Keyword, + /* 122 - z */ Token.Keyword, + /* 123 - { */ Token.LeftBrace, + /* 124 - | */ Token.BitwiseOr, + /* 125 - } */ Token.RightBrace, + /* 126 - ~ */ Token.Complement, + /* 127 - Delete */ Token.Illegal +]; + +/** + * Scans next token in the stream + * + * @param parser Parser object + * @param context Context masks + */ +export function nextToken(parser: ParserState, context: Context): void { + parser.flags = (parser.flags | Flags.NewLine) ^ Flags.NewLine; + parser.startPos = parser.index; + parser.startColumn = parser.column; + parser.startLine = parser.line; + parser.token = scanSingleToken(parser, context, LexerState.None); + if (parser.onToken && parser.token !== Token.EOF) { + const loc = { + start: { + line: parser.linePos, + column: parser.colPos + }, + end: { + line: parser.line, + column: parser.column + } + }; + parser.onToken(convertTokenType(parser.token), parser.tokenPos, parser.index, loc); + } +} + +export function scanSingleToken(parser: ParserState, context: Context, state: LexerState): Token { + const isStartOfLine = parser.index === 0; + + const source = parser.source; + + // These three are only for HTMLClose comment + let startPos = parser.index; + let startLine = parser.line; + let startColumn = parser.column; + + while (parser.index < parser.end) { + parser.tokenPos = parser.index; + parser.colPos = parser.column; + parser.linePos = parser.line; + + let char = parser.currentChar; + + if (char <= 0x7e) { + const token = TokenLookup[char]; + + switch (token) { + case Token.LeftParen: + case Token.RightParen: + case Token.LeftBrace: + case Token.RightBrace: + case Token.LeftBracket: + case Token.RightBracket: + case Token.Colon: + case Token.Semicolon: + case Token.Comma: + case Token.Complement: + case Token.Decorator: + case Token.Illegal: + advanceChar(parser); + return token; + + // Look for an identifier + case Token.Identifier: + return scanIdentifier(parser, context, /* isValidAsKeyword */ 0); + + // Look for identifier or keyword + case Token.Keyword: + return scanIdentifier(parser, context, /* isValidAsKeyword */ 1); + + // Look for a decimal number. + case Token.NumericLiteral: + return scanNumber(parser, context, NumberKind.Decimal | NumberKind.ValidBigIntKind); + + // Look for a string literal + case Token.StringLiteral: + return scanString(parser, context, char); + + // Look for a template string + case Token.Template: + return scanTemplate(parser, context); + + // Look for a escaped identifier + case Token.EscapedIdentifier: + return scanUnicodeIdentifier(parser, context); + + // `#` (private name) + case Token.PrivateField: + return scanPrivateIdentifier(parser); + + case Token.WhiteSpace: + advanceChar(parser); + break; + + case Token.CarriageReturn: + state |= LexerState.NewLine | LexerState.LastIsCR; + scanNewLine(parser); + break; + + case Token.LineFeed: + consumeLineFeed(parser, state); + state = (state & ~LexerState.LastIsCR) | LexerState.NewLine; + break; + + // `<`, `<=`, `<<`, `<<=`, `</`, `<!--` + case Token.LessThan: + let ch = advanceChar(parser); + if (parser.index < parser.end) { + if (ch === Chars.LessThan) { + if (parser.index < parser.end && advanceChar(parser) === Chars.EqualSign) { + advanceChar(parser); + return Token.ShiftLeftAssign; + } + return Token.ShiftLeft; + } else if (ch === Chars.EqualSign) { + advanceChar(parser); + return Token.LessThanOrEqual; + } + if (ch === Chars.Exclamation) { + // Treat HTML begin-comment as comment-till-end-of-line. + const index = parser.index + 1; + if ( + index + 1 < parser.end && + source.charCodeAt(index) === Chars.Hyphen && + source.charCodeAt(index + 1) == Chars.Hyphen + ) { + parser.column += 3; + parser.currentChar = source.charCodeAt((parser.index += 3)); + state = skipSingleHTMLComment( + parser, + source, + state, + context, + CommentType.HTMLOpen, + parser.tokenPos, + parser.linePos, + parser.colPos + ); + startPos = parser.tokenPos; + startLine = parser.linePos; + startColumn = parser.colPos; + continue; + } + return Token.LessThan; + } + if (ch === Chars.Slash) { + if ((context & Context.OptionsJSX) < 1) return Token.LessThan; + const index = parser.index + 1; + + // Check that it's not a comment start. + if (index < parser.end) { + ch = source.charCodeAt(index); + if (ch === Chars.Asterisk || ch === Chars.Slash) break; + } + advanceChar(parser); + return Token.JSXClose; + } + } + return Token.LessThan; + + // `=`, `==`, `===`, `=>` + case Token.Assign: { + advanceChar(parser); + + const ch = parser.currentChar; + + if (ch === Chars.EqualSign) { + if (advanceChar(parser) === Chars.EqualSign) { + advanceChar(parser); + return Token.StrictEqual; + } + return Token.LooseEqual; + } + if (ch === Chars.GreaterThan) { + advanceChar(parser); + return Token.Arrow; + } + + return Token.Assign; + } + + // `!`, `!=`, `!==` + case Token.Negate: + if (advanceChar(parser) !== Chars.EqualSign) { + return Token.Negate; + } + if (advanceChar(parser) !== Chars.EqualSign) { + return Token.LooseNotEqual; + } + advanceChar(parser); + return Token.StrictNotEqual; + + // `%`, `%=` + case Token.Modulo: + if (advanceChar(parser) !== Chars.EqualSign) return Token.Modulo; + advanceChar(parser); + return Token.ModuloAssign; + + // `*`, `**`, `*=`, `**=` + case Token.Multiply: { + advanceChar(parser); + + if (parser.index >= parser.end) return Token.Multiply; + + const ch = parser.currentChar; + + if (ch === Chars.EqualSign) { + advanceChar(parser); + return Token.MultiplyAssign; + } + + if (ch !== Chars.Asterisk) return Token.Multiply; + + if (advanceChar(parser) !== Chars.EqualSign) return Token.Exponentiate; + + advanceChar(parser); + + return Token.ExponentiateAssign; + } + + // `^`, `^=` + case Token.BitwiseXor: + if (advanceChar(parser) !== Chars.EqualSign) return Token.BitwiseXor; + advanceChar(parser); + return Token.BitwiseXorAssign; + + // `+`, `++`, `+=` + case Token.Add: { + advanceChar(parser); + + const ch = parser.currentChar; + + if (ch === Chars.Plus) { + advanceChar(parser); + return Token.Increment; + } + + if (ch === Chars.EqualSign) { + advanceChar(parser); + return Token.AddAssign; + } + + return Token.Add; + } + + // `-`, `--`, `-=`, `-->` + case Token.Subtract: { + advanceChar(parser); + + const ch = parser.currentChar; + + if (ch === Chars.Hyphen) { + advanceChar(parser); + if ((state & LexerState.NewLine || isStartOfLine) && parser.currentChar === Chars.GreaterThan) { + if ((context & Context.OptionsWebCompat) === 0) report(parser, Errors.HtmlCommentInWebCompat); + advanceChar(parser); + state = skipSingleHTMLComment( + parser, + source, + state, + context, + CommentType.HTMLClose, + startPos, + startLine, + startColumn + ); + startPos = parser.tokenPos; + startLine = parser.linePos; + startColumn = parser.colPos; + continue; + } + + return Token.Decrement; + } + + if (ch === Chars.EqualSign) { + advanceChar(parser); + return Token.SubtractAssign; + } + + return Token.Subtract; + } + + // `/`, `/=`, `/>`, '/*..*/' + case Token.Divide: { + advanceChar(parser); + if (parser.index < parser.end) { + const ch = parser.currentChar; + if (ch === Chars.Slash) { + advanceChar(parser); + state = skipSingleLineComment( + parser, + source, + state, + CommentType.Single, + parser.tokenPos, + parser.linePos, + parser.colPos + ); + startPos = parser.tokenPos; + startLine = parser.linePos; + startColumn = parser.colPos; + continue; + } + if (ch === Chars.Asterisk) { + advanceChar(parser); + state = skipMultiLineComment(parser, source, state) as LexerState; + startPos = parser.tokenPos; + startLine = parser.linePos; + startColumn = parser.colPos; + continue; + } + if (context & Context.AllowRegExp) { + return scanRegularExpression(parser, context); + } + if (ch === Chars.EqualSign) { + advanceChar(parser); + return Token.DivideAssign; + } + } + + return Token.Divide; + } + + // `.`, `...`, `.123` (numeric literal) + case Token.Period: + const next = advanceChar(parser); + if (next >= Chars.Zero && next <= Chars.Nine) + return scanNumber(parser, context, NumberKind.Float | NumberKind.Decimal); + if (next === Chars.Period) { + const index = parser.index + 1; + if (index < parser.end && source.charCodeAt(index) === Chars.Period) { + parser.column += 2; + parser.currentChar = source.charCodeAt((parser.index += 2)); + return Token.Ellipsis; + } + } + return Token.Period; + + // `|`, `||`, `|=`, `||=` + case Token.BitwiseOr: { + advanceChar(parser); + + const ch = parser.currentChar; + + if (ch === Chars.VerticalBar) { + advanceChar(parser); + + if (parser.currentChar === Chars.EqualSign) { + advanceChar(parser); + return Token.LogicalOrAssign; + } + + return Token.LogicalOr; + } + if (ch === Chars.EqualSign) { + advanceChar(parser); + return Token.BitwiseOrAssign; + } + + return Token.BitwiseOr; + } + + // `>`, `>=`, `>>`, `>>>`, `>>=`, `>>>=` + case Token.GreaterThan: { + advanceChar(parser); + + const ch = parser.currentChar; + + if (ch === Chars.EqualSign) { + advanceChar(parser); + return Token.GreaterThanOrEqual; + } + + if (ch !== Chars.GreaterThan) return Token.GreaterThan; + + advanceChar(parser); + + if (parser.index < parser.end) { + const ch = parser.currentChar; + + if (ch === Chars.GreaterThan) { + if (advanceChar(parser) === Chars.EqualSign) { + advanceChar(parser); + return Token.LogicalShiftRightAssign; + } + return Token.LogicalShiftRight; + } + if (ch === Chars.EqualSign) { + advanceChar(parser); + return Token.ShiftRightAssign; + } + } + + return Token.ShiftRight; + } + + // `&`, `&&`, `&=`, `&&=` + case Token.BitwiseAnd: { + advanceChar(parser); + + const ch = parser.currentChar; + + if (ch === Chars.Ampersand) { + advanceChar(parser); + + if (parser.currentChar === Chars.EqualSign) { + advanceChar(parser); + return Token.LogicalAndAssign; + } + + return Token.LogicalAnd; + } + + if (ch === Chars.EqualSign) { + advanceChar(parser); + return Token.BitwiseAndAssign; + } + + return Token.BitwiseAnd; + } + + // `?`, `??`, `?.`, `??=` + case Token.QuestionMark: { + let ch = advanceChar(parser); + if (ch === Chars.QuestionMark) { + advanceChar(parser); + + if (parser.currentChar === Chars.EqualSign) { + advanceChar(parser); + return Token.CoalesceAssign; + } + + return Token.Coalesce; + } + + if (ch === Chars.Period) { + const index = parser.index + 1; + // Check that it's not followed by any numbers + if (index < parser.end) { + ch = source.charCodeAt(index); + if (!(ch >= Chars.Zero && ch <= Chars.Nine)) { + advanceChar(parser); + return Token.QuestionMarkPeriod; + } + } + } + + return Token.QuestionMark; + } + + default: + // unreachable + } + } else { + if ((char ^ Chars.LineSeparator) <= 1) { + state = (state & ~LexerState.LastIsCR) | LexerState.NewLine; + scanNewLine(parser); + continue; + } + + if ((char & 0xfc00) === 0xd800 || ((unicodeLookup[(char >>> 5) + 34816] >>> char) & 31 & 1) !== 0) { + if ((char & 0xfc00) === 0xdc00) { + char = ((char & 0x3ff) << 10) | (char & 0x3ff) | 0x10000; + if (((unicodeLookup[(char >>> 5) + 0] >>> char) & 31 & 1) === 0) { + report(parser, Errors.IllegalCharacter, fromCodePoint(char)); + } + parser.index++; + parser.currentChar = char; + } + + parser.column++; + parser.tokenValue = ''; + return scanIdentifierSlowCase(parser, context, /* hasEscape */ 0, /* canBeKeyword */ 0); + } + + if (isExoticECMAScriptWhitespace(char)) { + advanceChar(parser); + continue; + } + + // Invalid ASCII code point/unit + report(parser, Errors.IllegalCharacter, fromCodePoint(char)); + } + } + return Token.EOF; +} |