Skip to content

Instantly share code, notes, and snippets.

@reverofevil
Created January 26, 2025 00:15
Show Gist options
  • Save reverofevil/406ddd68c7f06c486e7ce6039b90f1d5 to your computer and use it in GitHub Desktop.
Save reverofevil/406ddd68c7f06c486e7ce6039b90f1d5 to your computer and use it in GitHub Desktop.
namespace Example1 {
type Sig<I, O> = (input: I) => O;
declare const imm: (int: number) => Sig<[], [number]>;
declare const add: () => Sig<[number, number], [number]>;
interface Builder<Stack> {
$: <I extends any[], O extends any[]>(
instr: Stack extends [...I, ...any[]] ? Sig<I, O> : never
) => Builder<Stack extends [...I, ...infer R] ? [...O, ...R] : never>
}
declare const b: Builder<[]>;
const test = () => b
.$(imm(1))
.$(imm(2))
.$(add())
.$(imm(4))
.$(add())
}
namespace Example2 {
type AddFn<Stack extends any[], N extends string, P extends any[], I extends any[], O extends any[]> =
Stack extends [...I, ...infer R]
? { [K in N]: (...args: P) => Builder<[...O, ...R]> }
: {}
type Builder<Stack extends any[]> =
& AddFn<Stack, 'imm', [number], [], [number]>
& AddFn<Stack, 'add', [], [number, number], [number]>
declare const b: Builder<[]>;
const test = () => b
.imm(1)
.imm(2)
.add()
.imm(3)
.add()
}
namespace Example3 {
type Unwrap<T> = T extends infer R ? {[K in keyof R]: R[K]} : never;
type Apply<F, R> = F extends { args: unknown; result: unknown; } ? (F & {args: R})["result"] : never
interface Arr { args: unknown; result: Unwrap<this["args"][]> }
type R1 = Apply<Arr, number>
interface Pair1<L> { args: unknown; result: [L, this["args"]] }
interface Pair { args: unknown; result: Pair1<this["args"]> }
type R2 = Apply<Apply<Pair, string>, number>
}
namespace Example4 {
interface A { a: this }
interface B { b: this }
declare const t: A & B;
const test1 = () => t.a.b.a.b;
type Builder<T extends string> = { [K in T]: Builder<T> }
declare const r: Builder<'o' | 'a' | 'c' | 'l'>;
const test2 = () => r.c.o.c.a.c.o.l.a;
type Builder2<T extends string> = { [K in T]: Builder2<T> }
interface Bibuilder<K extends string> {
end: Builder2<K>;
add: <L extends string>(l: L) => Bibuilder<K | L>;
}
declare const bb: Bibuilder<never>;
const b = bb.add('o').add('a').add('c').add('l').end;
const r2 = b.c.o.c.a.c.o.l.a;
}
namespace Example5 {
type Apply<F, R> = F extends { args: unknown; result: unknown; } ? (F & {args: R})["result"] : never
interface Args<T> { args: T }
interface Fix {
args: unknown;
// @ts-ignore
result: (this["args"] & Args<this>)["result"]
}
interface FooAux<T> { $: 'a', value: T }
// @ts-ignore
interface Foo { args: unknown; result: FooAux<this["args"]["result"]> }
// @ts-ignore
type R = Apply<Fix, Foo>
declare const r: R;
// only up to 32
const a = r.value.value.value.value.value.value.value.value.value.value.value.value.value
.value.value.value.value.value.value.value.value.value.value.value.value.value
.value.value.value.value.value.x
}
namespace Example6 {
type Unwrap<T> = T extends infer R ? {[K in keyof R]: R[K]} : never;
type Presence<K, V, Stack> = V extends [[...infer I], ...any[]]
? Stack extends [...I, ...any[]]
? K
: never
: never
type Builder<Stack, T> = {
[K in keyof T as Presence<K, T[K], Stack>]: T[K] extends [[...infer I], [...infer O], [...infer P]]
? Stack extends [...I, ...infer R]
? (...args: P) => Builder<[...O, ...R], T>
: never
: never
}
interface Bibuilder<T> {
end: Builder<[], T>;
add: <N extends string>(key: N) =>
<I extends any[], O extends any[]>() =>
<P extends any[]>(handler: (...args: P) => string) =>
Bibuilder<Unwrap<T & { [K in N]: [I, O, P] }>>
}
declare const make: <K>() => Bibuilder<K>
const defineAsm = make<{}>();
const asm = defineAsm
.add('imm')<[], [number]>()<[number]>((p) => '')
.add('add')<[number, number], [number]>()<[]>(() => '')
.end;
const codegen = () => asm
.imm(1)
.imm(2)
.add()
.imm(3)
.add()
}
// type Unwrap<T> = T extends infer R ? {[K in keyof R]: R[K]} : never;
// type Apply<F, R> = F extends { args: unknown; result: unknown; } ? (F & {args: R})["result"] : never
// interface Fn<B, N extends string> {
// args: unknown;
// result: { [K in N]: B }
// }
// interface AddFn<R, N extends string, P extends any[], I extends any[], O extends any[]> {
// args: unknown;
// result: Fn<{}, N, P, I, O>
// }
// type Builder1 = AddFn<AddFn<{}, 'imm', [number], [], [number]>, 'add', [], [number, number], [number]>
// type Builder<Stack> = Apply<Builder1, Stack>
// declare const b: Builder<[]>;
// const res = b
// .imm(1)
// .imm(2)
// .add()
// .imm(3)
// .add()
// type AddFn<Stack extends any[], N extends string, P extends any[], I extends any[], O extends any[]> =
// Stack extends [...I, ...infer R]
// ? { [K in N]: (...args: P) => Builder<[...O, ...R]> }
// : {}
// interface Bibuilder<T> {
// end: T;
// add: <N extends string>(key: N) =>
// <I extends any[], O extends any[]>() =>
// <P extends any[]>(handler: (...args: P) => string) =>
// Bibuilder<Unwrap<T & AddFn<>>>
// }
type Unwrap<T> = T extends infer R ? {[K in keyof R]: R[K]} : never;
type Presence<K, V, Stack> = V extends [[...infer I], ...any[]]
? Stack extends [...I, ...any[]]
? K
: never
: never
type Builder<Stack, T> = {
[K in keyof T as Presence<K, T[K], Stack>]: T[K] extends [[...infer I], [...infer O], [...infer P]]
? Stack extends [...I, ...infer R]
? (...args: P) => Builder<[...O, ...R], T>
: never
: never
} & {
[K in "end" as (Stack extends [] ? "end" : never)]: () => string;
}
interface Bibuilder<T> {
end: <S extends any[] = []>() => Builder<S, T>;
add: <N extends string>(key: N) =>
<I extends any[], O extends any[], P extends any[]>(handler: (...args: P) => string) =>
Bibuilder<Unwrap<T & { [K in N]: [I, O, P] }>>
}
declare const make: <K>() => Bibuilder<K>
const defineAsm = make<{}>();
const asm = defineAsm
.add('imm')<[], [number], [number]>((p) => `01${p}`)
.add('add')<[number, number], [number], []>(() => `10`)
.add('drop')<[any], [], []>(() => `11`)
.end;
const codegen = () => asm()
.imm(1)
.imm(2)
.add()
.imm(3)
.add()
.drop()
.end()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment