UNPKG

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