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
|
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>
>}`>;
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;
|