Skip to content

Instantly share code, notes, and snippets.

@cevek
Created October 16, 2016 08:22
Show Gist options
  • Select an option

  • Save cevek/7c6b113a257765bdb8548cb20c3da841 to your computer and use it in GitHub Desktop.

Select an option

Save cevek/7c6b113a257765bdb8548cb20c3da841 to your computer and use it in GitHub Desktop.
function isWhiteSpace(cp) {
return (cp === 0x20) || (cp === 0x09) || (cp === 0x0B) || (cp === 0x0C) || (cp === 0xA0) ||
(cp >= 0x1680 && [0x1680, 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007, 0x2008, 0x2009, 0x200A, 0x202F, 0x205F, 0x3000, 0xFEFF].indexOf(cp) >= 0);
}
function isLineTerminator(cp) {
return (cp === 0x0A) || (cp === 0x0D) || (cp === 0x2028) || (cp === 0x2029);
}
// const globMap = new Uint8Array(256 * 256);
const globMap = new Array(256 * 256).fill(0);
// 5 - white space
// 10 - nextExpression
// 15 - line terminator
const nextNewExpressionStartSymbols = '%^&*/-+([;:?,<>=|';
for (let i = 0; i < nextNewExpressionStartSymbols.length; i++) {
const sym = nextNewExpressionStartSymbols[i];
globMap[sym.charCodeAt(0)] = 10;
}
for (let i = 0; i < globMap.length; i++) {
globMap[i] = isWhiteSpace(i) ? 5 : globMap[i];
globMap[i] = isLineTerminator(i) ? 15 : globMap[i];
}
function parseStr(code, ret) {
"use strict";
let i = -1;
let nextExpressionStart = true;
let x = 0;
let startS = 0;
let type = 0;
let tokens = [];
let strSym = 0;
let nextX = 0;
let prevWasAst = false;
let classMarker = false;
const len = code.length;
main: while (i++ < len) {
// let ssym = codeD[i];
x = code.charCodeAt(i);
// type = globMap[x];
// continue;
// string
if (x === 34/*'*/ || x === 39/*"*/ || x === 96/*`*/) {
strSym = x;
startS = i;
nextExpressionStart = false;
while (i++ < len) {
x = code.charCodeAt(i);
if (x === 92 /*\*/) {
i++;
continue;
}
if (x === strSym) {
ret && tokens.push(["st", code.substring(startS, i + 1)]);
continue main;
}
}
}
// /
else if (x === 47 /*/*/) {
nextX = code.charCodeAt(i + 1);
// line comment //
if (nextX === 47/*/*/) {
startS = i;
i++;
while (i < len && globMap[code.charCodeAt(++i)] !== 15/*line terminator*/);
ret && tokens.push(["lc", code.substring(startS, i + 1)]);
continue;
}
// block comment /*
if (nextX === 42/* * */) {
startS = i;
i++;
prevWasAst = false;
while (i++ < len) {
x = code.charCodeAt(i);
if (x === 42/* * */) {
prevWasAst = true;
continue;
}
if (prevWasAst) {
if (x === 47/*/*/) {
ret && tokens.push(["bc", code.substring(startS, i + 1)]);
continue main;
}
prevWasAst = false;
}
}
}
// start regexp
if (nextExpressionStart) {
startS = i;
classMarker = false;
while (i++ < len) {
// let sym = codeD[i];
x = code.charCodeAt(i);
if (x === 92 /*\*/) {
x = code[i++];
} else if (classMarker) {
if (x === 93/*]*/) {
classMarker = false;
}
} else {
if (x === 47 /*/*/) {
// todo: flags
ret && tokens.push(["re", code.substring(startS, i + 1)]);
continue main;
} else if (x === 91 /*[*/) {
classMarker = true;
}
}
}
}
}
// if next expression start
else if ((type = globMap[x]) === 10 /* next exrp */) {
nextExpressionStart = true;
}
// non white space
else if (type !== 5 /* space */) {
nextExpressionStart = false;
}
}
/*
for (let i = 0; i < code.length; i++) {
x = code.charCodeAt(i);
}
*/
// tokens.map(t => console.log(t[0], '"' + t[1] + '"'));
// console.log(tokens.map(t => t[0] + ' "' + t[1].substr(0, 100) + '"').join('\n'));
// console.log(tokens);
return tokens;
}
function test() {
//abc
/**/
/1/
}
parseStr('//a\n"b"');
if (typeof module == 'object') {
module.exports = parseStr;
}
function x(){
"use strict";
console.profile('prof');
for (let i = 0; i < 300; i++) {
parseStr('//flow\n/*1*/"1"`1`,/[\\1]/');
}
console.profileEnd('prof');
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment