Skip to content

Instantly share code, notes, and snippets.

@sgoguen
Created December 3, 2020 02:13
Show Gist options
  • Save sgoguen/4138a7961ed891635751f41c3c5b9c9b to your computer and use it in GitHub Desktop.
Save sgoguen/4138a7961ed891635751f41c3c5b9c9b to your computer and use it in GitHub Desktop.
Parses a math expression and turns it into a type
//. Define some character sets
type LowerChar = 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' |
'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't' |
'u' | 'v' | 'w' | 'x' | 'y' | 'z';
type UpperChar = `${Capitalize<LowerChar>}`
type AlphaChar = LowerChar | UpperChar;
type NumChar = '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | '0';
type IsType<T extends string, U> = T extends U ? T : never;
type CharMap<F, T extends string> =
T extends `${IsType<infer X, F>}` ? `${X}` :
T extends `${IsType<infer X, F>}${infer Y}` ?
X extends F ? Y extends CharMap<F, Y> ? `${X}${Y}` : never : never : never ;
type Word<T extends string> = CharMap<AlphaChar, T>;
type Num<T extends string> = CharMap<NumChar, T>;
type MathExp<T extends string> =
T extends `(${infer Inside})` ? MathExp<Inside>
: T extends `${infer Left} + ${infer Right}` ?
{ op: 'add', left: MathExp<Left>, right: MathExp<Right>}
: T extends `${infer Left} * ${infer Right}` ?
{ op: 'mul', left: MathExp<Left>, right: MathExp<Right>}
: T extends Num<T> ? 'const'
: T extends Word<T> ? 'var'
: T;
type Test1 = MathExp<`3 + x * 4 + 5 * 494`>
type Test2 = MathExp<`3 + x * 4 + 5 * 494 + 3 * 23 + 3 * 12 + 391 * 1238 + 381 * 1238 + 1381 * 1237 + 1238 + 1 + 1 + 1 + 1 + 1`>
// type X = {
// op: 'add';
// left: "const";
// right: {
// op: 'add';
// left: {
// op: 'mul';
// left: "var";
// right: "const";
// };
// right: {
// op: 'mul';
// left: "const";
// right: "const";
// };
// };
// }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment