rpncalc-v4/script/token.mjs

68 lines
2.0 KiB
JavaScript

const tokens = (stream) => {
let toks = [];
let currTok = {val:"", type:"str"};
let stringmode = false;
for (let i = 0; i < stream.length; i++) {
if (stringmode) {
if (stream[i] === '`') {
toks.push(currTok);
stringmode = false;
currTok = {val:"", type:"str"};
} else {
currTok.val += stream[i];
}
} else if (stream[i] === '`') {
if (currTok.val !== "") {
toks.push(currTok);
}
stringmode = true;
currTok = {val:"", type:"string"};
} else if ("()';\"".includes(stream[i])) {
if (currTok.val !== "") {
toks.push(currTok);
}
toks.push({val:stream[i], type:"syntax"});
currTok = {val:"", type:"str"};
} else if (stream[i] === "-") {
if (stream[i+1] === ">") {
if (currTok.val !== "") {
toks.push(currTok);
}
toks.push({val:"->", type:"syntax"});
i++;
currTok = {val:"", type:"str"};
} else {
currTok.val += "-";
}
} else if (/\s/.test(stream[i])) {
if (currTok.val !== "") {
toks.push(currTok);
}
currTok = {val:"", type:"str"};
} else {
currTok.val += stream[i];
}
}
if (currTok.val !== "") {
toks.push(currTok);
}
return toks;
}
const classify = (tokens) => {
return tokens.map(tok => {
if (tok.type === "str") {
if (!isNaN(tok.val)) {
return {val:Number(tok.val), type:"num"};
} else {
return {name:tok.val, type:"ident"};
}
} else {
return tok;
}
});
}
export const tokenize = (stream) => {
return classify(tokens(stream));
}