-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathjsjs.js
58 lines (54 loc) · 1.42 KB
/
jsjs.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
54
55
56
57
58
const babylon = require("babylon");
//节点处理者
const Handler = {
File(node, scope) {
evaluate(node.program, scope);
},
Program(node, scope) {
for(let exec of node.body) {
evaluate(exec, scope);
}
},
ExpressionStatement(node, scope) {
evaluate(node.expression, scope);
},
CallExpression(node, scope) {
//参数
let params = [];
for(let param of node.arguments) {
params.push(Handler.NumericLiteral(param));
}
//函数体
let func = evaluate(node.callee, scope);
//执行
func.apply(null, params);
},
MemberExpression(node, scope) {
const {object, property} = node;
let objectValue = evaluate(object, scope);
let propertyValue = property.name;
let func = objectValue[propertyValue];
return func.bind(objectValue);
},
//获取变量值
Identifier(node, scope) {
return scope[node.name];
},
NumericLiteral(node, scope) {
return node.value;
}
};
//执行入口
function evaluate(node, scope) {
let handler = Handler[node.type];
if (!handler) {
throw `no ${node.type} type handler`;
}
return handler(node, scope);
}
//执行代码
const code = 'console.log("hello world")';
// 解析AST语法树
const ast = babylon.parse(code);
// 需要传入执行上下文
evaluate(ast, {console});