resolve.js 4.5 KB

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