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/ts-lang/builtin | |
| parent | d8a969e231135978c4dd1fa67559101f506ad6f3 (diff) | |
implement recursion properly with closures
Diffstat (limited to 'src/lang/ts-lang/builtin')
| -rw-r--r-- | src/lang/ts-lang/builtin/builtin.ts | 15 | ||||
| -rw-r--r-- | src/lang/ts-lang/builtin/sbuiltin.ts | 54 |
2 files changed, 45 insertions, 24 deletions
diff --git a/src/lang/ts-lang/builtin/builtin.ts b/src/lang/ts-lang/builtin/builtin.ts index 8532072..cdd8991 100644 --- a/src/lang/ts-lang/builtin/builtin.ts +++ b/src/lang/ts-lang/builtin/builtin.ts @@ -50,18 +50,3 @@ export type BUILTIN_Eq<Args extends readonly any[]> = Args extends | readonly boolean[] ? ArrayEqual<Args> : FnError<`Can only check equality of numbers or string or boolean, but got ${ToString<Args>}`>; - -export type BUILTIN_IfElse<Args extends readonly any[]> = Args extends [ - infer A, - infer B, - infer C, - infer D -] - ? FnError<`Invalid args for "if": ${ToString<Args>}`> - : Args extends [infer Cond, infer TrueVal, infer FalseVal] - ? Cond extends true - ? TrueVal - : Cond extends false - ? FalseVal - : FnError<`Condition value ${ToString<Cond>} is not a boolean`> - : FnError<`Invalid args for "if": ${ToString<Args>}`>; diff --git a/src/lang/ts-lang/builtin/sbuiltin.ts b/src/lang/ts-lang/builtin/sbuiltin.ts index f873666..c92fd6a 100644 --- a/src/lang/ts-lang/builtin/sbuiltin.ts +++ b/src/lang/ts-lang/builtin/sbuiltin.ts @@ -1,27 +1,63 @@ +import { FnError } from "."; import { ASTNode, StackFrame } from "../core/common"; -import { CallFn, FnPrim, GetEvaluatedChildren, EvalError } from "../core/eval"; +import { + CallFn, + FnPrim, + GetEvaluatedChildren, + EvalError, + _Evaluate, +} from "../core/eval"; import { ExtractNumber, ToString } from "../util"; export type SBUILTIN_Call< Node extends ASTNode, - Frame extends StackFrame -> = GetEvaluatedChildren<Node, Frame> extends [ + Frame extends StackFrame, + Callstack extends readonly string[] +> = GetEvaluatedChildren<Node, Frame, Callstack> extends [ infer Fn, ...infer Values extends readonly any[] ] - ? CallFn<Fn, Values, Frame> + ? CallFn<Fn, Values, Frame, Callstack> : EvalError<`Invalid params for function call: ${ToString< - GetEvaluatedChildren<Node, Frame> + GetEvaluatedChildren<Node, Frame, Callstack> >}`>; export type SBUILTIN_Map< Node extends ASTNode, - Frame extends StackFrame -> = GetEvaluatedChildren<Node, Frame> extends [ + Frame extends StackFrame, + Callstack extends readonly string[] +> = GetEvaluatedChildren<Node, Frame, Callstack> extends [ infer Arr extends readonly any[], infer Fn extends FnPrim ] - ? { [Idx in keyof Arr]: CallFn<Fn, [Arr[Idx], ExtractNumber<Idx>], Frame> } + ? { + [Idx in keyof Arr]: CallFn< + Fn, + [Arr[Idx], ExtractNumber<Idx>], + Frame, + Callstack + >; + } : EvalError<`Invalid params for map: ${ToString< - GetEvaluatedChildren<Node, Frame> + GetEvaluatedChildren<Node, Frame, Callstack> >}`>; + +export type SBUILTIN_IfElse< + Node extends ASTNode, + Frame extends StackFrame, + Callstack extends readonly string[] +> = Node["children"] extends infer Children extends readonly ASTNode[] + ? Children extends [infer A, infer B, infer C, infer D] + ? FnError<`Invalid args for "if": ${ToString<Children>}`> + : Children extends [ + infer Cond extends ASTNode, + infer TrueVal extends ASTNode, + infer FalseVal extends ASTNode + ] + ? _Evaluate<Cond, Frame, Callstack> extends true + ? _Evaluate<TrueVal, Frame, Callstack> + : _Evaluate<Cond, Frame, Callstack> extends false + ? _Evaluate<FalseVal, Frame, Callstack> + : FnError<`Condition value ${ToString<Cond>} is not a boolean`> + : FnError<`Invalid args for "if": ${ToString<Children>}`> + : never; |
