// type Token = { // type: "paren", // value: 1 | -1, // } | { // type: "bracket", // value: 1 | -1, // } | { // type: "brace", // value: 1 | -1, // } | { // type: "number", // value: number, // } | { // type: "keyword", // value: (typeof KEYWORDS)[number], // } | { // type: "identifier", // value: string, // } | { // type: "string", // value: string, // } | { // type: "assignment-op", // value: "=", // } // const KEYWORDS = [ // "let", // "if", // ] as const; // const isKeyword = (str: string): str is (typeof KEYWORDS)[number] => { // return KEYWORDS.includes(str as any); // } // const isMatchNestChar = (char: string): char is "(" | ")" | "[" | "]" | "{" | "}" => { // return char === "(" || char === ")" || char === "[" || char === "]" || char === "{" || char === "}"; // } // const matchNestType = { // "(": "paren", // ")": "paren", // "[": "bracket", // "]": "bracket", // "{": "brace", // "}": "brace", // } as const // const matchNestValue = { // "(": 1, // ")": -1, // "[": 1, // "]": -1, // "{": 1, // "}": -1, // } as const // const isSkippableChar = (char: string) => { // return [" ", "\n", "\t", ";"].includes(char); // } // const isAlpha = (char: string) => { // return /^[a-z]$/.test(char); // } // const isNumeric = (char: string) => { // return /^\d$/.test(char); // } // const isAlphaNumeric = (char: string) => { // return isAlpha(char) || isNumeric(char); // } // const tokenize = (source: string) => { // const tokens: Array = []; // let src = [...source]; // while (src.length) { // const char = src[0]; // if (isMatchNestChar(char)) { // const token = {type: matchNestType[char], value: matchNestValue[char]}; // tokens.push(token); // src.shift(); // } else if (char === "=") { // const token = {type: "assignment-op", value: "="} as const; // tokens.push(token); // src.shift(); // } else { // if (isSkippableChar(char)) { // src.shift(); // } else if (isNumeric(char)) { // let num = ""; // while (src.length && isNumeric(src[0])) { // num += src.shift(); // } // const token = {type: "number" as const, value: Number(num)}; // tokens.push(token); // } else if (isAlpha(char)) { // let ident = ""; // while (src.length && isAlphaNumeric(src[0])) { // ident += src.shift(); // } // if (isKeyword(ident)) { // const token = {type: "keyword" as const, value: ident}; // tokens.push(token); // } else { // const token = {type: "identifier" as const, value: ident}; // tokens.push(token); // } // } else if (char === '"' || char === "'") { // console.log('lexing a string'); // const q = char; // src.shift(); // let s = ""; // while (src.length && src[0] !== q) { // const c = src.shift(); // console.log(`c: "${c}"`); // if (c === "\\") { // s += src.shift(); // } else { // s += c; // } // } // if (src.length) { // src.shift(); // } // const token = {type: "string" as const, value: s}; // tokens.push(token); // } else { // throw `Unrecognized character: '${char}'` // } // } // } // return tokens; // } // const code = ` // let x = 45; // let y = ( 10 ); // if (y) { // let z = (x = y); // } // let say = "Hello, \\"world\\"!"; // ` // console.log(tokenize(code));