1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
|
import { FnError } from ".";
import { ASTNode, StackFrame } from "../core/common";
import {
CallFn,
FnPrim,
GetEvaluatedChildren,
EvalError,
_Evaluate,
} from "../core/eval";
import { ExtractNumber, ToString } from "../util";
export type SBUILTIN_Call<
Node extends ASTNode,
Frame extends StackFrame,
Callstack extends readonly string[]
> = GetEvaluatedChildren<Node, Frame, Callstack> extends [
infer Fn,
...infer Values extends readonly any[]
]
? CallFn<Fn, Values, Frame, Callstack>
: EvalError<`Invalid params for function call: ${ToString<
GetEvaluatedChildren<Node, Frame, Callstack>
>}`>;
export type SBUILTIN_Map<
Node extends ASTNode,
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,
Callstack
>;
}
: EvalError<`Invalid params for map: ${ToString<
GetEvaluatedChildren<Node, Frame, Callstack>
>}`>;
type Reduce<
Arr extends readonly any[],
Fn extends FnPrim,
Acc,
IdxLen extends readonly any[] = readonly []
> = Arr extends [infer Head, ...infer Tail]
? Reduce<
Tail,
Fn,
CallFn<Fn, [Acc, Head, IdxLen["length"]]>,
[...IdxLen, any]
>
: Acc;
export type SBUILTIN_Reduce<
Node extends ASTNode,
Frame extends StackFrame,
Callstack extends readonly string[]
> = GetEvaluatedChildren<Node, Frame, Callstack> extends [
infer Arr extends readonly any[],
infer Fn extends FnPrim,
infer Acc
]
? Reduce<Arr, Fn, Acc>
: EvalError<`Invalid params for reduce: ${ToString<
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;
|