RelationalNode.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. "use strict";
  2. var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
  3. Object.defineProperty(exports, "__esModule", {
  4. value: true
  5. });
  6. exports.createRelationalNode = void 0;
  7. var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
  8. var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
  9. var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
  10. var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
  11. var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
  12. var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
  13. var _operators = require("../operators.js");
  14. var _string = require("../../utils/string.js");
  15. var _customs = require("../../utils/customs.js");
  16. var _latex = require("../../utils/latex.js");
  17. var _factory = require("../../utils/factory.js");
  18. function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2["default"])(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2["default"])(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2["default"])(this, result); }; }
  19. function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
  20. var name = 'RelationalNode';
  21. var dependencies = ['Node'];
  22. var createRelationalNode = /* #__PURE__ */(0, _factory.factory)(name, dependencies, function (_ref) {
  23. var Node = _ref.Node;
  24. var operatorMap = {
  25. equal: '==',
  26. unequal: '!=',
  27. smaller: '<',
  28. larger: '>',
  29. smallerEq: '<=',
  30. largerEq: '>='
  31. };
  32. var RelationalNode = /*#__PURE__*/function (_Node) {
  33. (0, _inherits2["default"])(RelationalNode, _Node);
  34. var _super = _createSuper(RelationalNode);
  35. /**
  36. * A node representing a chained conditional expression, such as 'x > y > z'
  37. *
  38. * @param {String[]} conditionals
  39. * An array of conditional operators used to compare the parameters
  40. * @param {Node[]} params
  41. * The parameters that will be compared
  42. *
  43. * @constructor RelationalNode
  44. * @extends {Node}
  45. */
  46. function RelationalNode(conditionals, params) {
  47. var _this;
  48. (0, _classCallCheck2["default"])(this, RelationalNode);
  49. _this = _super.call(this);
  50. if (!Array.isArray(conditionals)) {
  51. throw new TypeError('Parameter conditionals must be an array');
  52. }
  53. if (!Array.isArray(params)) {
  54. throw new TypeError('Parameter params must be an array');
  55. }
  56. if (conditionals.length !== params.length - 1) {
  57. throw new TypeError('Parameter params must contain exactly one more element ' + 'than parameter conditionals');
  58. }
  59. _this.conditionals = conditionals;
  60. _this.params = params;
  61. return _this;
  62. }
  63. (0, _createClass2["default"])(RelationalNode, [{
  64. key: "type",
  65. get: function get() {
  66. return name;
  67. }
  68. }, {
  69. key: "isRelationalNode",
  70. get: function get() {
  71. return true;
  72. }
  73. /**
  74. * Compile a node into a JavaScript function.
  75. * This basically pre-calculates as much as possible and only leaves open
  76. * calculations which depend on a dynamic scope with variables.
  77. * @param {Object} math Math.js namespace with functions and constants.
  78. * @param {Object} argNames An object with argument names as key and `true`
  79. * as value. Used in the SymbolNode to optimize
  80. * for arguments from user assigned functions
  81. * (see FunctionAssignmentNode) or special symbols
  82. * like `end` (see IndexNode).
  83. * @return {function} Returns a function which can be called like:
  84. * evalNode(scope: Object, args: Object, context: *)
  85. */
  86. }, {
  87. key: "_compile",
  88. value: function _compile(math, argNames) {
  89. var self = this;
  90. var compiled = this.params.map(function (p) {
  91. return p._compile(math, argNames);
  92. });
  93. return function evalRelationalNode(scope, args, context) {
  94. var evalLhs;
  95. var evalRhs = compiled[0](scope, args, context);
  96. for (var i = 0; i < self.conditionals.length; i++) {
  97. evalLhs = evalRhs;
  98. evalRhs = compiled[i + 1](scope, args, context);
  99. var condFn = (0, _customs.getSafeProperty)(math, self.conditionals[i]);
  100. if (!condFn(evalLhs, evalRhs)) {
  101. return false;
  102. }
  103. }
  104. return true;
  105. };
  106. }
  107. /**
  108. * Execute a callback for each of the child nodes of this node
  109. * @param {function(child: Node, path: string, parent: Node)} callback
  110. */
  111. }, {
  112. key: "forEach",
  113. value: function forEach(callback) {
  114. var _this2 = this;
  115. this.params.forEach(function (n, i) {
  116. return callback(n, 'params[' + i + ']', _this2);
  117. }, this);
  118. }
  119. /**
  120. * Create a new RelationalNode whose children are the results of calling
  121. * the provided callback function for each child of the original node.
  122. * @param {function(child: Node, path: string, parent: Node): Node} callback
  123. * @returns {RelationalNode} Returns a transformed copy of the node
  124. */
  125. }, {
  126. key: "map",
  127. value: function map(callback) {
  128. var _this3 = this;
  129. return new RelationalNode(this.conditionals.slice(), this.params.map(function (n, i) {
  130. return _this3._ifNode(callback(n, 'params[' + i + ']', _this3));
  131. }, this));
  132. }
  133. /**
  134. * Create a clone of this node, a shallow copy
  135. * @return {RelationalNode}
  136. */
  137. }, {
  138. key: "clone",
  139. value: function clone() {
  140. return new RelationalNode(this.conditionals, this.params);
  141. }
  142. /**
  143. * Get string representation.
  144. * @param {Object} options
  145. * @return {string} str
  146. */
  147. }, {
  148. key: "_toString",
  149. value: function _toString(options) {
  150. var parenthesis = options && options.parenthesis ? options.parenthesis : 'keep';
  151. var precedence = (0, _operators.getPrecedence)(this, parenthesis, options && options.implicit);
  152. var paramStrings = this.params.map(function (p, index) {
  153. var paramPrecedence = (0, _operators.getPrecedence)(p, parenthesis, options && options.implicit);
  154. return parenthesis === 'all' || paramPrecedence !== null && paramPrecedence <= precedence ? '(' + p.toString(options) + ')' : p.toString(options);
  155. });
  156. var ret = paramStrings[0];
  157. for (var i = 0; i < this.conditionals.length; i++) {
  158. ret += ' ' + operatorMap[this.conditionals[i]];
  159. ret += ' ' + paramStrings[i + 1];
  160. }
  161. return ret;
  162. }
  163. /**
  164. * Get a JSON representation of the node
  165. * @returns {Object}
  166. */
  167. }, {
  168. key: "toJSON",
  169. value: function toJSON() {
  170. return {
  171. mathjs: name,
  172. conditionals: this.conditionals,
  173. params: this.params
  174. };
  175. }
  176. /**
  177. * Instantiate a RelationalNode from its JSON representation
  178. * @param {Object} json
  179. * An object structured like
  180. * `{"mathjs": "RelationalNode", "conditionals": ..., "params": ...}`,
  181. * where mathjs is optional
  182. * @returns {RelationalNode}
  183. */
  184. }, {
  185. key: "toHTML",
  186. value:
  187. /**
  188. * Get HTML representation
  189. * @param {Object} options
  190. * @return {string} str
  191. */
  192. function toHTML(options) {
  193. var parenthesis = options && options.parenthesis ? options.parenthesis : 'keep';
  194. var precedence = (0, _operators.getPrecedence)(this, parenthesis, options && options.implicit);
  195. var paramStrings = this.params.map(function (p, index) {
  196. var paramPrecedence = (0, _operators.getPrecedence)(p, parenthesis, options && options.implicit);
  197. return parenthesis === 'all' || paramPrecedence !== null && paramPrecedence <= precedence ? '<span class="math-parenthesis math-round-parenthesis">(</span>' + p.toHTML(options) + '<span class="math-parenthesis math-round-parenthesis">)</span>' : p.toHTML(options);
  198. });
  199. var ret = paramStrings[0];
  200. for (var i = 0; i < this.conditionals.length; i++) {
  201. ret += '<span class="math-operator math-binary-operator ' + 'math-explicit-binary-operator">' + (0, _string.escape)(operatorMap[this.conditionals[i]]) + '</span>' + paramStrings[i + 1];
  202. }
  203. return ret;
  204. }
  205. /**
  206. * Get LaTeX representation
  207. * @param {Object} options
  208. * @return {string} str
  209. */
  210. }, {
  211. key: "_toTex",
  212. value: function _toTex(options) {
  213. var parenthesis = options && options.parenthesis ? options.parenthesis : 'keep';
  214. var precedence = (0, _operators.getPrecedence)(this, parenthesis, options && options.implicit);
  215. var paramStrings = this.params.map(function (p, index) {
  216. var paramPrecedence = (0, _operators.getPrecedence)(p, parenthesis, options && options.implicit);
  217. return parenthesis === 'all' || paramPrecedence !== null && paramPrecedence <= precedence ? '\\left(' + p.toTex(options) + '\right)' : p.toTex(options);
  218. });
  219. var ret = paramStrings[0];
  220. for (var i = 0; i < this.conditionals.length; i++) {
  221. ret += _latex.latexOperators[this.conditionals[i]] + paramStrings[i + 1];
  222. }
  223. return ret;
  224. }
  225. }], [{
  226. key: "fromJSON",
  227. value: function fromJSON(json) {
  228. return new RelationalNode(json.conditionals, json.params);
  229. }
  230. }]);
  231. return RelationalNode;
  232. }(Node);
  233. (0, _defineProperty2["default"])(RelationalNode, "name", name);
  234. return RelationalNode;
  235. }, {
  236. isClass: true,
  237. isNode: true
  238. });
  239. exports.createRelationalNode = createRelationalNode;