slige-mirror/compiler/util.ts
2025-02-04 15:06:19 +01:00

64 lines
1.7 KiB
TypeScript

export function todo<T>(...args: unknown[]): T {
const argsStr = args.map((a) => JSON.stringify(a)).join(", ");
class NotImplemented extends Error {
constructor() {
super(`todo(${argsStr})`);
this.name = "NotImplemented";
}
}
throw new NotImplemented();
}
export function exhausted<T>(...args: never[]): T {
const argsStr = args.map((a) => JSON.stringify(a)).join(", ");
class Unexhausted extends Error {
constructor() {
super(`exhausted(${argsStr})`);
this.name = "Unexhausted";
}
}
throw new Unexhausted();
}
export type Res<V, E> = Ok<V> | Err<E>;
export type Ok<V> = { ok: true; val: V };
export type Err<E> = { ok: false; val: E };
export const Ok = <V>(val: V): Ok<V> => ({ ok: true, val });
export const Err = <E>(val: E): Err<E> => ({ ok: false, val });
export const Res = { Ok, Err } as const;
export type ControlFlow<
R = undefined,
V = undefined,
> = Break<R> | Continue<V>;
export type Break<R> = { break: true; val: R };
export type Continue<V> = { break: false; val: V };
export const ControlFlow = {
Break: <R>(val: R): Break<R> => ({ break: true, val }),
Continue: <V>(val: V): Continue<V> => ({ break: false, val }),
} as const;
export const range = (length: number) => (new Array(length).fill(0));
export const strictEq = <T>(a: T, b: T): boolean => a === b;
export function arrayEq<T>(
a: T[],
b: T[],
elemCmp: (a: T, b: T) => boolean = strictEq,
): boolean {
if (a.length !== b.length) {
return false;
}
for (let i = 0; i < a.length; ++i) {
if (!elemCmp(a[i], b[i])) {
return false;
}
}
return true;
}