Skip to content

Instantly share code, notes, and snippets.

@KFlash
Last active October 28, 2020 00:46
Show Gist options
  • Save KFlash/688af509a649aa8180d4cb17e7b9de81 to your computer and use it in GitHub Desktop.
Save KFlash/688af509a649aa8180d4cb17e7b9de81 to your computer and use it in GitHub Desktop.
// Note! This is developed for high performance
// Comments can be extracted / collected after 'each' comment while loop like this
'{ range: { pos: lineStart, end: pos }, type, },'
export function skipWhitespace(
parser: ParserState,
context: Context,
source: string,
cp: number,
state: WhitespaceState
): void {
let pos = parser.pos;
if (pos === 0) state |= WhitespaceState.LineStart;
loop: while (pos < parser.length) {
switch (whitespaceTbl[cp]) {
/* general whitespace */
case Char.Tab:
case Char.VerticalTab:
case Char.FormFeed:
case Char.Space:
pos++;
break;
/* line terminators */
case Char.CarriageReturn:
pos++;
state |= WhitespaceState.NewLine | WhitespaceState.LastIsCR;
break;
case Char.LineFeed:
pos++;
if (state & WhitespaceState.LastIsCR) pos++;
state = (state | 0b00000000000000000000000000000101) ^ WhitespaceState.LastIsCR;
break;
/* normal comments */
case Char.Slash: {
const next = source.charCodeAt(pos + 1);
if (next === Char.Slash) {
state = (state | WhitespaceState.LineStart) ^ WhitespaceState.LineStart;
pos += 2;
while (pos < parser.length) {
if (isLineTerminator(source.charCodeAt(pos))) {
break;
}
pos++;
}
break;
}
if (next === Char.Asterisk) {
pos += 2;
let commentClosed = false;
while (pos < parser.length) {
cp = source.charCodeAt(pos);
if (cp === Char.Asterisk && source.charCodeAt(pos + 1) === Char.Slash) {
pos += 2;
commentClosed = true;
break;
}
pos++;
if (isLineTerminator(cp)) {
parser.lastLineStart = pos;
state = (state | 0b00000000000000000000000000001101) ^ 0b00000000000000000000000000001100;
}
}
if (!commentClosed) {
// Throw
}
break;
}
break loop;
}
/* Hashbang */
case Char.Hash: {
if ((state & WhitespaceState.LineStart) === 0) break loop;
if (source.charCodeAt(pos + 1) === Char.Exclamation) {
state = (state | WhitespaceState.LineStart) ^ WhitespaceState.LineStart;
pos += 2;
while (pos < parser.length) {
if (isLineTerminator(source.charCodeAt(pos))) {
break;
}
pos++;
}
break;
}
break loop;
}
/* HTML single line comment */
case Char.LessThan:
if (context & Context.Module) break loop;
if (
source.charCodeAt(pos + 3) === Char.Hyphen &&
source.charCodeAt(pos + 2) === Char.Hyphen &&
source.charCodeAt(pos + 1) === Char.Exclamation
) {
state = (state | WhitespaceState.LineStart) ^ WhitespaceState.LineStart;
pos += 3;
while (pos < parser.length) {
if (isLineTerminator(source.charCodeAt(pos))) {
break;
}
pos++;
}
break;
}
break loop;
/* HTML close */
case Char.Hyphen:
// Break the loop rather than throwing, so we can report it as an unexpected token
// instead.
if (context & Context.Module || (state & 0b00000000000000000000000000001001) === 0) break loop;
if (source.charCodeAt(pos + 2) === Char.GreaterThan && source.charCodeAt(pos + 1) === Char.Hyphen) {
state = (state | WhitespaceState.LineStart) ^ WhitespaceState.LineStart;
pos += 2;
while (pos < parser.length) {
if (isLineTerminator(source.charCodeAt(pos))) {
break;
}
pos++;
}
break;
}
state |= WhitespaceState.LineStart;
default:
if ((cp & ~1) === Char.LineSeparator) {
pos++;
state = (state | 0b00000000000000000000000000000101) ^ WhitespaceState.LastIsCR;
continue;
}
if (isZsSpace(cp)) {
pos++;
continue;
}
break loop;
}
cp = source.charCodeAt(pos);
}
parser.pos = pos;
if (state & WhitespaceState.NewLine) parser.lineTerminator = true;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment