Skip to content

Instantly share code, notes, and snippets.

@lxsmnsyc
Created November 30, 2020 07:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lxsmnsyc/e335a6f42cfd506e8610cae5a64148b7 to your computer and use it in GitHub Desktop.
Save lxsmnsyc/e335a6f42cfd506e8610cae5a64148b7 to your computer and use it in GitHub Desktop.
Brainfuck-to-JS Compiler using only TypeScript's type system
type Collect<T, O extends string, C extends string, S extends string, R extends any[] = []> =
T extends `${C}${infer Rest}`
? Collect<Rest, Rest, C, S, [any, ...R]>
: `${S}(${R['length']});${Compile<O>}`;
type Compile<T> =
T extends `+${infer Rest}`
? Collect<T, Rest, '+', 'c'>
:
T extends `-${infer Rest}`
? Collect<T, Rest, '-', 'd'>
:
T extends `<${infer Rest}`
? Collect<T, Rest, '<', 'e'>
:
T extends `>${infer Rest}`
? Collect<T, Rest, '>', 'f'>
:
T extends `[${infer Rest}`
? `do{${Compile<Rest>}`
:
T extends `]${infer Rest}`
? `}while(a[b]);${Compile<Rest>}`
:
T extends `.${infer Rest}`
? `g();${Compile<Rest>}`
: T;
type Minify<T> =
T extends ` ${infer A}`
? Minify<A>
:
T extends `${infer A} `
? Minify<A>
:
T extends `\n${infer A}`
? Minify<A>
:
T extends `${infer A}\n`
? Minify<A>
:
T extends `${infer A} ${infer B}`
? Minify<`${Minify<A>}${Minify<B>}`>
:
T extends `${infer A}\n${infer B}`
? Minify<`${Minify<A>}${Minify<B>}`>
: T;
type Header = `a=[],b=2000,c=(v)=>{a[b]+=v},d=(v)=>{a[b]-=v},e=(v)=>b-=v,f=(v)=>b+=v,g=()=>console.log(b);`
type Brainfuck<T extends string> = `${Header}${Compile<Minify<T>>}`;
type Result = Brainfuck<'>>[-]<<[->>+<<]'>;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment