summaryrefslogtreecommitdiff
path: root/src/lang/ks-lang/index.ts
diff options
context:
space:
mode:
authorKai Stevenson <kai@kaistevenson.com>2025-11-04 20:53:14 -0800
committerKai Stevenson <kai@kaistevenson.com>2025-11-04 20:53:30 -0800
commitb8fd8f0672c289ff43e501f430b76de1c7b0440a (patch)
tree57cf1f50700649189406ccfd50b7c430d5547c3c /src/lang/ks-lang/index.ts
parentf9f52cd6081036fa98e86a537c925f7a8e924df7 (diff)
constrained args for createFn
Diffstat (limited to 'src/lang/ks-lang/index.ts')
-rw-r--r--src/lang/ks-lang/index.ts40
1 files changed, 25 insertions, 15 deletions
diff --git a/src/lang/ks-lang/index.ts b/src/lang/ks-lang/index.ts
index c9c7405..e5a78b9 100644
--- a/src/lang/ks-lang/index.ts
+++ b/src/lang/ks-lang/index.ts
@@ -14,19 +14,29 @@ export type TransformArgs<Args extends readonly ASTNode[]> = {
[Idx in keyof Args]: any;
};
-export const createFn = <Program extends string>(
- program: Program
-): Evaluate<Parse<Lex<Program>>> extends [infer ProgramFn extends FnPrim]
- ? <const Args extends TransformArgs<ProgramFn["args"]>>(
- ...args: Args
- ) => CallFn<ProgramFn, Args, EmptyStackFrame>
- : EvalError<"Cannot create a function from a program that does not eval to a function"> => {
- const [programFn] = evaluate(parse(lex(program))) as Array<FnPrim>;
- if (!programFn.fn) {
- throw new Error(
- "Cannot create a function from a program that does not eval to a function"
- );
- }
+export type AssertArgs<
+ Args extends readonly ASTNode[],
+ ArgsConstraint extends readonly any[]
+> = TransformArgs<Args> extends ArgsConstraint ? ArgsConstraint : never;
- return ((...args: any[]) => callFn(programFn, args, emptyStackFrame)) as any;
-};
+export const createFn =
+ <ArgsConstraint extends any[]>() =>
+ <Program extends string>(
+ program: Program
+ ): Evaluate<Parse<Lex<Program>>> extends [infer ProgramFn extends FnPrim]
+ ? TransformArgs<ProgramFn["args"]> extends ArgsConstraint
+ ? <const Args extends ArgsConstraint>(
+ ...args: Args
+ ) => CallFn<ProgramFn, Args, EmptyStackFrame>
+ : EvalError<`Program's args do not extend args constraint`>
+ : EvalError<"Cannot create a function from a program that does not eval to a function"> => {
+ const [programFn] = evaluate(parse(lex(program))) as Array<FnPrim>;
+ if (!programFn.fn) {
+ throw new Error(
+ "Cannot create a function from a program that does not eval to a function"
+ );
+ }
+
+ return ((...args: any[]) =>
+ callFn(programFn, args, emptyStackFrame)) as any;
+ };