simple-squiggle

A restricted subset of Squiggle
Log | Files | Refs | README

resolve.js (3322B)


      1 "use strict";
      2 
      3 Object.defineProperty(exports, "__esModule", {
      4   value: true
      5 });
      6 exports.createResolve = void 0;
      7 
      8 var _map = require("../../utils/map.js");
      9 
     10 var _is = require("../../utils/is.js");
     11 
     12 var _factory = require("../../utils/factory.js");
     13 
     14 var name = 'resolve';
     15 var dependencies = ['parse', 'ConstantNode', 'FunctionNode', 'OperatorNode', 'ParenthesisNode'];
     16 var createResolve = /* #__PURE__ */(0, _factory.factory)(name, dependencies, function (_ref) {
     17   var parse = _ref.parse,
     18       ConstantNode = _ref.ConstantNode,
     19       FunctionNode = _ref.FunctionNode,
     20       OperatorNode = _ref.OperatorNode,
     21       ParenthesisNode = _ref.ParenthesisNode;
     22 
     23   /**
     24    * resolve(expr, scope) replaces variable nodes with their scoped values
     25    *
     26    * Syntax:
     27    *
     28    *     resolve(expr, scope)
     29    *
     30    * Examples:
     31    *
     32    *     math.resolve('x + y', {x:1, y:2})           // Node {1 + 2}
     33    *     math.resolve(math.parse('x+y'), {x:1, y:2}) // Node {1 + 2}
     34    *     math.simplify('x+y', {x:2, y:'x+x'}).toString()      // "6"
     35    *
     36    * See also:
     37    *
     38    *     simplify, evaluate
     39    *
     40    * @param {Node} node
     41    *     The expression tree to be simplified
     42    * @param {Object} scope
     43    *     Scope specifying variables to be resolved
     44    * @return {Node} Returns `node` with variables recursively substituted.
     45    * @throws {ReferenceError}
     46    *     If there is a cyclic dependency among the variables in `scope`,
     47    *     resolution is impossible and a ReferenceError is thrown.
     48    */
     49   function resolve(node, scope) {
     50     var within = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : new Set();
     51 
     52     // note `within`:
     53     // `within` is not documented, since it is for internal cycle
     54     // detection only
     55     if (!scope) {
     56       return node;
     57     }
     58 
     59     if (!(0, _map.isMap)(scope)) {
     60       scope = (0, _map.createMap)(scope);
     61     }
     62 
     63     if ((0, _is.isSymbolNode)(node)) {
     64       if (within.has(node.name)) {
     65         var variables = Array.from(within).join(', ');
     66         throw new ReferenceError("recursive loop of variable definitions among {".concat(variables, "}"));
     67       }
     68 
     69       var value = scope.get(node.name);
     70 
     71       if ((0, _is.isNode)(value)) {
     72         var nextWithin = new Set(within);
     73         nextWithin.add(node.name);
     74         return resolve(value, scope, nextWithin);
     75       } else if (typeof value === 'number') {
     76         return parse(String(value));
     77       } else if (value !== undefined) {
     78         return new ConstantNode(value);
     79       } else {
     80         return node;
     81       }
     82     } else if ((0, _is.isOperatorNode)(node)) {
     83       var args = node.args.map(function (arg) {
     84         return resolve(arg, scope, within);
     85       });
     86       return new OperatorNode(node.op, node.fn, args, node.implicit);
     87     } else if ((0, _is.isParenthesisNode)(node)) {
     88       return new ParenthesisNode(resolve(node.content, scope, within));
     89     } else if ((0, _is.isFunctionNode)(node)) {
     90       var _args = node.args.map(function (arg) {
     91         return resolve(arg, scope, within);
     92       });
     93 
     94       return new FunctionNode(node.name, _args);
     95     } // Otherwise just recursively resolve any children (might also work
     96     // for some of the above special cases)
     97 
     98 
     99     return node.map(function (child) {
    100       return resolve(child, scope, within);
    101     });
    102   }
    103 
    104   return resolve;
    105 });
    106 exports.createResolve = createResolve;