-
Notifications
You must be signed in to change notification settings - Fork 12
/
interpreter.ts
66 lines (62 loc) · 1.85 KB
/
interpreter.ts
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
import { Parser, ParserError } from "./parser";
import { Tokenize } from "./tokenizer";
import { GetByField, IsUnion, TuplifyUnion } from "./utils";
type PushError<Errors extends any[], AST> = AST extends ParserError<infer E>
? [...Errors, E]
: [];
export type Interpret<
Obj extends Record<any, any>,
AST,
Errors extends string[] = []
> = AST extends ParserError<infer Err>
? Err
: AST extends {
type: "Identifier";
value: infer Ident;
}
? Obj[Ident]
: AST extends {
type: "DotAccess";
value: infer Ident;
children: infer Children;
}
? Ident extends { type: "Identifier"; value: infer IdentName }
? Interpret<Obj[IdentName], Children, PushError<Errors, Children>>
: Interpret<Obj, Children, PushError<Errors, Children>>
: AST extends {
type: "ArrayAccess";
value: infer Ident;
index: infer Index;
children: infer Children;
}
? Ident extends { type: "Identifier"; value: infer IdentName }
? Interpret<Obj[IdentName][Index], Children, PushError<Errors, Children>>
: Ident extends ParserError<string>
? Interpret<Obj[Index], Ident, PushError<Errors, Ident>>
: Interpret<Obj[Index], Children, PushError<Errors, Ident>>
: AST extends {
type: "WhereClause";
value: infer FilterBy;
}
? Interpret<
IsUnion<GetByField<Obj, FilterBy>> extends true
? TuplifyUnion<GetByField<Obj, FilterBy>>
: GetByField<Obj, FilterBy>,
{},
PushError<Errors, FilterBy>
>
: Errors extends []
? Obj
: Errors;
type Toks = Tokenize<"comments[].$where(name:anurag)">;
type AST = Parser<Toks>;
type Demo = Interpret<
{
comments: [
{ id: "uid1"; name: "anurag"; content: "this is a comments" },
{ id: "uid2"; name: "anurag"; content: "type level parser" },
{ id: "uid3"; name: "jhon"; content: "ts ftw" }
];
},
AST
>;