@thi.ng/sexpr
Version:
Extensible S-Expression parser & runtime infrastructure
74 lines (73 loc) • 1.57 kB
JavaScript
import { DEFAULT_SYNTAX } from "./api.js";
function* tokenize(src, opts) {
const {
scopes: rawScopes,
whiteSpace,
string,
comment
} = {
...DEFAULT_SYNTAX,
...opts
};
const scopes = rawScopes.reduce((acc, x) => acc.concat(x), []).join("");
let token = "";
let isString = false;
let isComment = false;
let tokenLine = 0;
let tokenCol = 0;
let line = 0;
let col = -1;
const $ = (value) => ({
value,
line: tokenLine,
col: tokenCol
});
for (let c of src) {
if (c === "\n") {
line++;
col = -1;
} else {
col++;
}
if (isComment) {
if (c === "\n") isComment = false;
} else if (!isString) {
if (whiteSpace.test(c)) {
token && (yield $(token));
token = "";
} else if (scopes.indexOf(c) !== -1) {
token && (yield $(token));
tokenLine = line;
tokenCol = col;
yield $(c);
token = "";
tokenCol++;
} else if (c === string) {
token && (yield $(token));
tokenLine = line;
tokenCol = col;
token = '"';
isString = true;
} else if (c === comment) {
isComment = true;
} else {
if (!token) {
tokenLine = line;
tokenCol = col;
}
token += c;
}
} else if (c === string && token[token.length - 1] !== "\\") {
token += '"';
yield $(token);
token = "";
isString = false;
} else {
token += c;
}
}
token && (yield $(token));
}
export {
tokenize
};