Skip to content

Commit 34616dc

Browse files
homework2 超纲挑战
1 parent 0888b5d commit 34616dc

File tree

1 file changed

+13
-6
lines changed

1 file changed

+13
-6
lines changed

homework/2/eval.js

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
11
const acorn = require('acorn');
22

3+
// 查找某变量所在的父级环境
4+
function findEnv(name, env) {
5+
return env[name] ? env : env.fa && findEnv(name, env.fa);
6+
}
7+
38
function evaluate(node, env) {
49
switch (node.type) {
510
// TODO: 补全作业代码
611
// 作为叶子节点的字面量和变量直接返回它们的值
712
case 'Literal':
813
return node.value;
914
case 'Identifier':
10-
return env[node.name];
15+
return findEnv(node.name, env)[node.name];
1116
// 数组,对象
1217
case 'ArrayExpression':
1318
return node.elements.map(e => evaluate(e, env));
@@ -37,29 +42,30 @@ function evaluate(node, env) {
3742
// 大概是要先去父级作用域查询,查询不到时再在本作用域新建这个变量?
3843
case 'UpdateExpression':
3944
let value = evaluate(node.argument, env);
40-
if (node.prefix) {a
45+
if (node.prefix) {
4146
return node.operator === '++' ? ++value : --value;
4247
} else {
4348
return node.operator === '++' ? value++ : value--;
4449
}
4550
case 'AssignmentExpression':
46-
return env[node.left.name] = evaluate(node.right, env);
51+
let protoEnv = findEnv(node.left.name, env);
52+
return protoEnv ? protoEnv[node.left.name] = evaluate(node.right, env) : env[node.left.name] = evaluate(node.right, env);
4753
// 逗号都要算一遍,只返回最后一个值
4854
case 'SequenceExpression':
4955
return node.expressions.reduce((_, expression) =>
50-
evaluate(expression, env), undefined);
56+
evaluate(expression, env), undefined);
5157
// 函数及作用域相关
5258
case 'FunctionExpression':
5359
return function (...args) {
5460
return evaluate(node.body, {
55-
...env,
61+
fa: env,
5662
...node.params.reduce((params, param, index) => ({...params, [param.name]: args[index]}), {}),
5763
});
5864
};
5965
case 'ArrowFunctionExpression':
6066
return function (...args) {
6167
return evaluate(node.body, {
62-
...env,
68+
fa: env,
6369
...node.params.reduce((params, param, index) => ({...params, [param.name]: args[index]}), {}),
6470
});
6571
}
@@ -74,6 +80,7 @@ function customerEval(code, env = {}) {
7480
const node = acorn.parseExpressionAt(code, 0, {
7581
ecmaVersion: 6
7682
})
83+
env.fa = null;
7784
return evaluate(node, env)
7885
}
7986

0 commit comments

Comments
 (0)