Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 39 additions & 5 deletions homework/1/rename.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,46 @@ const traverse = require('../../common/traverse');
function transform(root, originName, targetName) {
// 遍历所有节点
return traverse((node, ctx, next) => {

// TODO: 作业代码写在这里
if (node.type === 'xxx') {
switch(node.type)
{
case 'VariableDeclaration':
{
let variableDeclarator = node.declarations[0];
if (variableDeclarator.id.name === originName) {
variableDeclarator.id.name = targetName;
}
}
break;
case 'FunctionDeclaration':
{
if (node.id.name === originName) {
node.id.name = targetName;
}
}
break;
// case 'ObjectExpression':
// if (node.properties[0].key.name === originName) {
// node.properties[0].key.name = targetName;
// }
// break;
case 'BinaryExpression':
{
if (node.left.name === originName) {
node.left.name = targetName;
}
if (node.right.name === originName) {
node.right.name = targetName;
}
}
break;
case 'MemberExpression':
{
if (!node.object.object && node.object.name === originName) {
node.object.name = targetName;
}
}
break;
}

// 继续往下遍历
return next(node, ctx)
})(root);
}
Expand Down
10 changes: 10 additions & 0 deletions homework/1/sourceCode.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
function foo() {
foo: while(true) {
var foo = {
foo: foo.foo.foo[foo + foo]
};
break foo;
}
}

module.exports = foo;
7 changes: 7 additions & 0 deletions homework/1/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
const rename = require('./rename')
const sourceCode = require('./sourceCode')


let result = rename(sourceCode, 'foo', 'bar');

console.log(result);
124 changes: 122 additions & 2 deletions homework/2/eval.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,129 @@
const acorn = require('acorn');

function evaluate(node, env) {
switch (node.type) {
switch (node.type)
{
case 'Literal':
// TODO: 补全作业代码
return node.value;
case 'Identifier':
return env[node.name];
case 'BinaryExpression':
{
switch(node.operator)
{
case '+':
return evaluate(node.left, env) + evaluate(node.right, env);
case '-':
return evaluate(node.left, env) - evaluate(node.right, env);
case '*':
return evaluate(node.left, env) * evaluate(node.right, env);
case '/':
return evaluate(node.left, env) / evaluate(node.right, env);
case '**':
return evaluate(node.left, env) ** evaluate(node.right, env);
case '%':
return evaluate(node.left, env) % evaluate(node.right, env);
case '>':
return evaluate(node.left, env) > evaluate(node.right, env);
case '<':
return evaluate(node.left, env) < evaluate(node.right, env);
case '>=':
return evaluate(node.left, env) >= evaluate(node.right, env);
case '<=':
return evaluate(node.left, env) <= evaluate(node.right, env);
case '==':
return evaluate(node.left, env) == evaluate(node.right, env);
case '===':
return evaluate(node.left, env) === evaluate(node.right, env);
case '!==':
return evaluate(node.left, env) !== evaluate(node.right, env);
case '&':
return evaluate(node.left, env) & evaluate(node.right, env);
case '|':
return evaluate(node.left, env) | evaluate(node.right, env);
case '^':
return evaluate(node.left, env) ^ evaluate(node.right, env);
case '<<':
return evaluate(node.left, env) << evaluate(node.right, env);
case '>>':
return evaluate(node.left, env) >> evaluate(node.right, env);
case '>>>':
return evaluate(node.left, env) >>> evaluate(node.right, env);
case 'instanceof':
return evaluate(node.left, env) instanceof evaluate(node.right, env);
}
}
case 'LogicalExpression':
{
switch(node.operator)
{
case '&&':
return evaluate(node.left, env) && evaluate(node.right, env);
case '||':
return evaluate(node.left, env) || evaluate(node.right, env);
}
}
case 'UnaryExpression': {
switch(node.operator)
{
case '!':
return !evaluate(node.argument, env);
case '~':
return ~evaluate(node.argument, env);
case 'typeof':
return typeof evaluate(node.argument, env);
}
}
case 'UpdateExpression': {
const flag = node.prefix;
const argument = node.argument;
switch(node.operator)
{
case '++':
{
if (flag) {
return ++evaluate(argument, env);
} else {
return evaluate(argument, env)++;
}
}
case '--':
{
if (flag) {
return --evaluate(argument, env);
} else {
return evaluate(argument, env)--;
}
}
}
}
case 'ConditionalExpression':
{
if (evaluate(node.test, env)) {
return evaluate(node.consequent, env);
} else {
return evaluate(node.alternate, env);
}
}
case 'CallExpression': {
const c = evaluate(node.callee, env);
const args = node.arguments.map(arg => evaluate(arg, env));
return c(...args);
}
case 'ObjectExpression':
return node.properties.reduce((preProperty, curProperty) => (
{...preProperty, [curProperty.key.name] : evaluate(curProperty.value, env)}), {});
case 'ArrayExpression':
return node.elements.map((element) => evaluate(element, env));
case 'BlockStatement':
return node.body.reduce((preStatement, curStatement) => evaluate(curStatement, env), undefined);
case 'ArrowFunctionStatement':
return (...args) => {
return evaluate(node.body, {
...env,
...node.params.reduce((preParam, curParam, curIdx)=>({...preParam, [curParam.name]: args[curIdx]}), {})
})
}
}

throw new Error(`Unsupported Syntax ${node.type} at Location ${node.start}:${node.end}`);
Expand Down
3 changes: 3 additions & 0 deletions homework/2/sourceCode.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
const foo = '({ a: 1 + 2 + 3, b: 4 + 5, c: [1, 2, 3] })';

module.exports = foo;
6 changes: 6 additions & 0 deletions homework/2/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
const customerEval = require('./eval')


const result = customerEval('((x,y)=>x+y)(2,3)');

console.log(result);