UNPKG

@alu0101051420/constant-folding

Version:
129 lines (101 loc) 4.05 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>JSDoc: Source: constant-folding.js</title> <script src="scripts/prettify/prettify.js"> </script> <script src="scripts/prettify/lang-css.js"> </script> <!--[if lt IE 9]> <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script> <![endif]--> <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css"> <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css"> </head> <body> <div id="main"> <h1 class="page-title">Source: constant-folding.js</h1> <section> <article> <pre class="prettyprint source linenums"><code>const escodegen = require("escodegen"); const espree = require("espree"); const estraverse = require("estraverse"); const { isConstant, newArrayNode, newNode, getValue } = require("./utils"); "use strict"; module.exports = constantFolding; /** * A function that does constant folding onto the code it receives * @param {string} code A string containing the code to do the constant folding on * @returns {string} Returns the resulting code */ function constantFolding(code) { const t = espree.parse(code, { ecmaVersion: 6, loc: false }); estraverse.traverse(t, { leave: function (n, p) { if ( n.type == "BinaryExpression" &amp;&amp; n.left.type == "Literal" &amp;&amp; n.right.type == "Literal" ) { binaryConstantFolding(n); } if ( (n.type === "MemberExpression") &amp;&amp; (n.object.type === "ArrayExpression") &amp;&amp; (p.type !== "CallExpression") ) { let value = eval(arrayConstantFolding(n)); Object.assign(n, newNode(value)); } if ( (n.type === "CallExpression") &amp;&amp; (n.callee.object.type === "ArrayExpression") &amp;&amp; isConstant(n.arguments) &amp;&amp; isConstant(n.callee.object.elements) ) { let value = arrayConstantFolding(n.callee, n.arguments); Array.isArray(value) ? Object.assign(n, newArrayNode(value)) : Object.assign(n, newNode(value)); } } } ); return escodegen.generate(t); } /** * Does ConstantFolding on binaryExpression nodes. I.E. turns 2+3 into 5. * @param {Object} n an AST node representing a binaryExpression. */ function binaryConstantFolding(n) { n.type = "Literal"; n.value = eval(`${n.left.raw} ${n.operator} ${n.right.raw}`); n.raw = String(n.value); delete n.left; delete n.right; } /** * Does constant folding on Array operations. * @param {Object} code an AST node containing the expression statement * @param {Array} args arguments used on the function call. I.E. for [1].concat('d', 'e'), args = ['d', 'e'] * @returns {string} the resulting js code to be used by escodegen */ function arrayConstantFolding(code, args) { let result = `[${code.object.elements.map(e => getValue(e))}]`; result += code.property.type === "Literal" ? `[${getValue(code.property)}]` : `.${getValue(code.property)}`; result += (args ? `(${args.map(e => getValue(e))})` : ""); return eval(result); } </code></pre> </article> </section> </div> <nav> <h2><a href="index.html">Home</a></h2><h3>Global</h3><ul><li><a href="global.html#arrayConstantFolding">arrayConstantFolding</a></li><li><a href="global.html#binaryConstantFolding">binaryConstantFolding</a></li><li><a href="global.html#constantFolding">constantFolding</a></li><li><a href="global.html#getValue">getValue</a></li><li><a href="global.html#isConstant">isConstant</a></li><li><a href="global.html#newArrayNode">newArrayNode</a></li><li><a href="global.html#newNode">newNode</a></li></ul> </nav> <br class="clear"> <footer> Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 3.6.10</a> on Thu Mar 10 2022 14:45:42 GMT+0000 (Western European Standard Time) </footer> <script> prettyPrint(); </script> <script src="scripts/linenumber.js"> </script> </body> </html>