diff options
| author | Kai Stevenson <kai@kaistevenson.com> | 2025-11-06 00:18:26 -0800 |
|---|---|---|
| committer | Kai Stevenson <kai@kaistevenson.com> | 2025-11-06 20:28:00 -0800 |
| commit | 490b9c94fba16f484be3bb58b8a4a4880b9396bc (patch) | |
| tree | a94bd52ca129828fe284ee96651018613e42f6c6 /src/lang/ks-lang/index.ts | |
| parent | d8a969e231135978c4dd1fa67559101f506ad6f3 (diff) | |
implement recursion properly with closures
Diffstat (limited to 'src/lang/ks-lang/index.ts')
| -rw-r--r-- | src/lang/ks-lang/index.ts | 24 |
1 files changed, 17 insertions, 7 deletions
diff --git a/src/lang/ks-lang/index.ts b/src/lang/ks-lang/index.ts index e5a78b9..772c9c9 100644 --- a/src/lang/ks-lang/index.ts +++ b/src/lang/ks-lang/index.ts @@ -23,13 +23,23 @@ 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"> => { + ): Evaluate<Parse<Lex<Program>>> extends infer E + ? E 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`> + : E extends readonly [ + readonly [infer Prim extends FnPrim, infer StackFrame, infer Name] + ] + ? TransformArgs<Prim["args"]> extends ArgsConstraint + ? <const Args extends ArgsConstraint>( + ...args: Args + ) => CallFn<E[0], 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"> + : never => { const [programFn] = evaluate(parse(lex(program))) as Array<FnPrim>; if (!programFn.fn) { throw new Error( |
