@@ -2,8 +2,69 @@ const acorn = require('acorn');
2
2
3
3
function evaluate ( node , env ) {
4
4
switch ( node . type ) {
5
- case 'Literal' :
6
5
// TODO: 补全作业代码
6
+ // 作为叶子节点的字面量和变量直接返回它们的值
7
+ case 'Literal' :
8
+ return node . value ;
9
+ case 'Identifier' :
10
+ return env [ node . name ] ;
11
+ // 数组,对象
12
+ case 'ArrayExpression' :
13
+ return node . elements . map ( e => evaluate ( e , env ) ) ;
14
+ case 'ObjectExpression' :
15
+ return node . properties . reduce ( ( obj , prop ) => ( {
16
+ ...obj ,
17
+ [ prop . key . name ] : evaluate ( prop . value , env ) ,
18
+ } ) , { } ) ;
19
+ // 一些运算相关的表达式((懒得枚举运算符所以直接用eval了嘤~
20
+ case 'BinaryExpression' :
21
+ return eval ( evaluate ( node . left , env ) + node . operator + evaluate ( node . right , env ) ) ;
22
+ case 'UnaryExpression' :
23
+ return eval ( node . operator + evaluate ( node . argument , env ) ) ;
24
+ // 这里有个短路
25
+ case 'LogicalExpression' :
26
+ return node . operator === '&&' ?
27
+ evaluate ( node . left , env ) && evaluate ( node . right , env ) :
28
+ evaluate ( node . left , env ) || evaluate ( node . right , env ) ;
29
+ case 'ConditionalExpression' :
30
+ return evaluate ( node . test , env ) ?
31
+ evaluate ( node . consequent , env ) :
32
+ evaluate ( node . alternate , env ) ;
33
+ // 取对象成员
34
+ case 'MemberExpression' :
35
+ return evaluate ( node . object , env ) [ node . computed ? evaluate ( node . property , env ) : node . property . name ] ;
36
+ // mark,赋值相关的好像不能在环境里直接取变量的值?比如`a = 5, a++, a++`
37
+ // 大概是要先去父级作用域查询,查询不到时再在本作用域新建这个变量?
38
+ case 'UpdateExpression' :
39
+ let value = evaluate ( node . argument , env ) ;
40
+ if ( node . prefix ) { a
41
+ return node . operator === '++' ? ++ value : -- value ;
42
+ } else {
43
+ return node . operator === '++' ? value ++ : value -- ;
44
+ }
45
+ case 'AssignmentExpression' :
46
+ return env [ node . left . name ] = evaluate ( node . right , env ) ;
47
+ // 逗号都要算一遍,只返回最后一个值
48
+ case 'SequenceExpression' :
49
+ return node . expressions . reduce ( ( _ , expression ) =>
50
+ evaluate ( expression , env ) , undefined ) ;
51
+ // 函数及作用域相关
52
+ case 'FunctionExpression' :
53
+ return function ( ...args ) {
54
+ return evaluate ( node . body , {
55
+ ...env ,
56
+ ...node . params . reduce ( ( params , param , index ) => ( { ...params , [ param . name ] : args [ index ] } ) , { } ) ,
57
+ } ) ;
58
+ } ;
59
+ case 'ArrowFunctionExpression' :
60
+ return function ( ...args ) {
61
+ return evaluate ( node . body , {
62
+ ...env ,
63
+ ...node . params . reduce ( ( params , param , index ) => ( { ...params , [ param . name ] : args [ index ] } ) , { } ) ,
64
+ } ) ;
65
+ }
66
+ case 'CallExpression' :
67
+ return evaluate ( node . callee , env ) ( ...node . arguments . map ( arg => evaluate ( arg , env ) ) ) ;
7
68
}
8
69
9
70
throw new Error ( `Unsupported Syntax ${ node . type } at Location ${ node . start } :${ node . end } ` ) ;
@@ -16,4 +77,6 @@ function customerEval(code, env = {}) {
16
77
return evaluate ( node , env )
17
78
}
18
79
19
- module . exports = customerEval
80
+ module . exports = customerEval
81
+
82
+ customerEval ( "(n => ((x => n = x)(n + 2), (y => n + y)(3)))(1)" ) ;
0 commit comments