From 490b9c94fba16f484be3bb58b8a4a4880b9396bc Mon Sep 17 00:00:00 2001 From: Kai Stevenson Date: Thu, 6 Nov 2025 00:18:26 -0800 Subject: implement recursion properly with closures --- src/lang/ts-lang/builtin/builtin.ts | 15 ---------- src/lang/ts-lang/builtin/sbuiltin.ts | 54 ++++++++++++++++++++++++++++++------ 2 files changed, 45 insertions(+), 24 deletions(-) (limited to 'src/lang/ts-lang/builtin') 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 boolean[] ? ArrayEqual : FnError<`Can only check equality of numbers or string or boolean, but got ${ToString}`>; - -export type BUILTIN_IfElse = Args extends [ - infer A, - infer B, - infer C, - infer D -] - ? FnError<`Invalid args for "if": ${ToString}`> - : Args extends [infer Cond, infer TrueVal, infer FalseVal] - ? Cond extends true - ? TrueVal - : Cond extends false - ? FalseVal - : FnError<`Condition value ${ToString} is not a boolean`> - : FnError<`Invalid args for "if": ${ToString}`>; 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 extends [ + Frame extends StackFrame, + Callstack extends readonly string[] +> = GetEvaluatedChildren extends [ infer Fn, ...infer Values extends readonly any[] ] - ? CallFn + ? CallFn : EvalError<`Invalid params for function call: ${ToString< - GetEvaluatedChildren + GetEvaluatedChildren >}`>; export type SBUILTIN_Map< Node extends ASTNode, - Frame extends StackFrame -> = GetEvaluatedChildren extends [ + Frame extends StackFrame, + Callstack extends readonly string[] +> = GetEvaluatedChildren extends [ infer Arr extends readonly any[], infer Fn extends FnPrim ] - ? { [Idx in keyof Arr]: CallFn], Frame> } + ? { + [Idx in keyof Arr]: CallFn< + Fn, + [Arr[Idx], ExtractNumber], + Frame, + Callstack + >; + } : EvalError<`Invalid params for map: ${ToString< - GetEvaluatedChildren + GetEvaluatedChildren >}`>; + +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 extends [ + infer Cond extends ASTNode, + infer TrueVal extends ASTNode, + infer FalseVal extends ASTNode + ] + ? _Evaluate extends true + ? _Evaluate + : _Evaluate extends false + ? _Evaluate + : FnError<`Condition value ${ToString} is not a boolean`> + : FnError<`Invalid args for "if": ${ToString}`> + : never; -- cgit v1.2.3-70-g09d2