-
Notifications
You must be signed in to change notification settings - Fork 0
/
jgen.js
53 lines (48 loc) · 1.95 KB
/
jgen.js
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
export class DSLInterpreter {
constructor(customOperators = {}) {
this.operators = {
...customOperators
};
}
isOperator(json) {
return json && typeof json === 'object' && Object.keys(this.operators).includes(Object.keys(json)[0]);
}
compile(json) {
if (Array.isArray(json)) {
let compiledList = json.map(item => this.compile(item));
return (context) => {
return compiledList.map(compiledItem => typeof compiledItem === 'function' ? compiledItem(context) : compiledItem);
};
} else if (this.isOperator(json)) {
const operatorName = Object.keys(json)[0];
let paramsArray = Array.isArray(json[operatorName]) ? json[operatorName] : [json[operatorName]];
for (let i = 0; i < paramsArray.length; i++) {
paramsArray[i] = this.compile(paramsArray[i]);
}
return (context) => {
let executedParams = paramsArray.map(param => typeof param === 'function' ? param(context) : param);
return this.operators[operatorName].call(this, context, executedParams);
};
} else if (typeof json === 'object') { // Check and compile nested operators within normal JSON
const compiledJson = {};
for (let key in json) {
compiledJson[key] = this.compile(json[key]);
}
return (context) => {
const result = {};
for (let key in compiledJson) {
result[key] = typeof compiledJson[key] === 'function' ? compiledJson[key](context) : compiledJson[key];
}
return result;
};
} else {
return json;
}
}
run(compiledClosure, context) {
if (typeof compiledClosure === 'function') {
return compiledClosure(context);
}
return compiledClosure;
}
}