UNPKG

@readable-js/core

Version:

ReadableJS is a toolkit for teachers to craft small demos that can be explored interactively.

135 lines (134 loc) 5.83 kB
import { is } from './enode-type-check'; // not suer this work, maybe it can be refactored // need to evaluate value at some point.. function generateReadableValue(left, right, options) { // not sure when that is used if ((right === null || right === void 0 ? void 0 : right.type) === "FunctionExpression") { console.warn('generateReadableValue unknown path'); return "this function"; } if (!!left && is.Identifier(left) && (options === null || options === void 0 ? void 0 : options.replaceVar)) { return (`##replace-${left.name}##`); } return generateReadableExpression(right); } // equivalent to truthy function function formatBinary(node, verbiage, negation) { let isOrNotText = ''; // ignore if undefined if (negation === true) { isOrNotText = " is not"; } else if (negation === false) { isOrNotText = " is"; } return generateReadableExpression(node["left"]) + isOrNotText + verbiage + generateReadableExpression(node["right"]); } const converter = { "AssignmentExpression": (e, options) => { // note: he evaluate the expression on the right `foo = 1 + bar`, 1+bar is evaluated, I need to put a marker somewhere const map = new Map([ ['=', (e) => `set ${ge(e['left'])} to ${generateReadableValue(e['left'], e['right'], options)}`], ['+=', (e) => `add ${ge(e['right'])} to ${ge(e['left'])} and set ${ge(e['left'])} to ${generateReadableValue(e['left'], e['right'])}`], ['-=', (e) => `subtract ${ge(e['right'])} from ${ge(e['left'])} and set ${ge(e['left'])} to ${generateReadableValue(e['left'], e['right'])}`], ['*=', (e) => `multiply ${ge(e['left'])} by ${ge(e['right'])} and set ${ge(e['left'])} to ${generateReadableValue(e['left'], e['right'])}`], ['/=', (e) => `divide ${ge(e['left'])} to ${ge(e['right'])} and set ${ge(e['left'])} to ${generateReadableValue(e['left'], e['right'])}`], ['%=', (e) => `divide ${ge(e['left'])} to ${ge(e['right'])} and set ${ge(e['left'])} to the remainder: ${generateReadableValue(e['left'], e['right'])}`], ['**=', (e) => ``], ['<<=', (e) => ``], ['>>=', (e) => ``], ['>>>=', (e) => ``], ['|=', (e) => ``], ['^=', (e) => ``], ['&=', (e) => ``], ]); return map.get(e.operator)(e); }, "BinaryExpression": (e) => { const map = new Map([ ['==', (e) => formatBinary(e, " equal to ")], ['!=', (e) => formatBinary(e, " different ")], ['===', (e) => formatBinary(e, " strict equal to ")], ['!==', (e) => formatBinary(e, " strict different ")], ['<', (e) => formatBinary(e, " less than ")], ['<=', (e) => formatBinary(e, " less than or equal to ")], ['>', (e) => formatBinary(e, " greater than ")], ['>=', (e) => formatBinary(e, " greater than or equal to ")], ['<<', (e) => ''], ['>>', (e) => ''], ['>>>', (e) => ''], ['+', (e) => formatBinary(e, " plus ")], ['-', (e) => formatBinary(e, " minus ")], ['*', (e) => formatBinary(e, " times ")], ['/', (e) => formatBinary(e, " divided by ")], ['%', (e) => formatBinary(e, " modulo ")], ['**', (e) => ''], ['|', (e) => formatBinary(e, " bitwise-or ")], ['^', (e) => formatBinary(e, " bitwise-and ")], ['&', (e) => ''], ['in', (e) => ''], ['instanceof', (e) => ''], ]); return map.get(e.operator)(e); }, "ObjectExpression": (e) => "an object", "CallExpression": (e) => { if (e.callee.type === "Identifier" || e.callee.type === "MemberExpression") { } if (is.Identifier(e.callee)) { return `Call the function ${generateReadableExpression(e.callee)}`; // ignored compile thing, probably something missing with else } else if (is.MemberExpression(e.callee)) { if (is.Super(e.callee.object)) { return 'super'; // that's new } else { // is Expression return generateReadableExpression(e.callee.object); // ignored compile thing, probably something missing with else } } else if (is.ExpressionWithProperty(e.callee)) { return e.callee.property.name; } else { throw new Error(`Unknown CallExpression of type: ${e.callee.type}`); } }, "MemberExpression": (e) => { if (is.Super(e.object)) { return 'super'; } else { // is Expression // strange, we don't process this as in CallExpression return generateReadableExpression(e.object) + '.' + generateReadableExpression(e.property); // can be PrivateIdentifier too } }, "Literal": (e) => e.value + '', "Identifier": (e) => e.name, "VariableDeclarator": (e) => { if (is.FunctionExpression(e.init)) { return 'this function'; } else { return generateReadableExpression(e.id); } }, "FunctionExpression": (e) => 'this function' }; export function generateReadableExpression(exp, options) { if (!exp) { return ''; } if (converter.hasOwnProperty(exp.type)) { return converter[exp.type](exp, options); } else { console.warn(`Not found converter for: ${exp.type}`); return ''; } } const ge = generateReadableExpression;