function visiter(node) {
if (node.type === 'CallExpression') {
return ['call', visiter(node.callee), ...node.arguments.map(arg => visiter(arg))];
} else if (node.type === 'Identifier') {
return ['name', node.name];
} else if (node.type === 'Literal') {
return ['const', node.raw];
} else if (node.type === 'BinaryExpression' || node.type === 'LogicalExpression') {
return ['call', ['name', node.operator], visiter(node.left), visiter(node.right)];
} else if (node.type === 'ConditionalExpression') {
return [
'call',
['name', '?:'],
visiter(node.test),
visiter(node.consequent),
visiter(node.alternate),
];
} else if (node.type === 'UnaryExpression' || node.type === 'UpdateExpression') {
const op = node.prefix ? node.operator + '@' : '@' + node.operator;
return ['call', ['name', op], visiter(node.argument)];
} else if (node.type === 'MemberExpression') {
if (node.property.type === 'Identifier') {
return ['call', ['name', '.' + node.property.name], visiter(node.object)];
} else if (node.property.type === 'Literal') {
return ['call', ['name', '[]'], visiter(node.property)];
} else {
throw new Error(`Unexpected MemberExpression property type: "${node.property.type}"`);
}
throw new Error(`Member property is not identifier`);
} else {
throw new Error(`Unexpected node type: "${node.type}"`);
}
}