1 | import { isAccessorNode, isIndexNode, isNode, isSymbolNode } from '../../utils/is.js';
|
2 | import { getSafeProperty, setSafeProperty } from '../../utils/customs.js';
|
3 | import { factory } from '../../utils/factory.js';
|
4 | import { accessFactory } from './utils/access.js';
|
5 | import { assignFactory } from './utils/assign.js';
|
6 | import { getPrecedence } from '../operators.js';
|
7 | var name = 'AssignmentNode';
|
8 | var dependencies = ['subset', '?matrix',
|
9 | 'Node'];
|
10 | export var createAssignmentNode = factory(name, dependencies, (_ref) => {
|
11 | var {
|
12 | subset,
|
13 | matrix,
|
14 | Node
|
15 | } = _ref;
|
16 | var access = accessFactory({
|
17 | subset
|
18 | });
|
19 | var assign = assignFactory({
|
20 | subset,
|
21 | matrix
|
22 | });
|
23 | |
24 |
|
25 |
|
26 |
|
27 |
|
28 |
|
29 |
|
30 |
|
31 |
|
32 |
|
33 |
|
34 |
|
35 |
|
36 |
|
37 |
|
38 |
|
39 |
|
40 |
|
41 |
|
42 |
|
43 |
|
44 |
|
45 |
|
46 |
|
47 |
|
48 |
|
49 |
|
50 | function AssignmentNode(object, index, value) {
|
51 | if (!(this instanceof AssignmentNode)) {
|
52 | throw new SyntaxError('Constructor must be called with the new operator');
|
53 | }
|
54 |
|
55 | this.object = object;
|
56 | this.index = value ? index : null;
|
57 | this.value = value || index;
|
58 |
|
59 | if (!isSymbolNode(object) && !isAccessorNode(object)) {
|
60 | throw new TypeError('SymbolNode or AccessorNode expected as "object"');
|
61 | }
|
62 |
|
63 | if (isSymbolNode(object) && object.name === 'end') {
|
64 | throw new Error('Cannot assign to symbol "end"');
|
65 | }
|
66 |
|
67 | if (this.index && !isIndexNode(this.index)) {
|
68 |
|
69 | throw new TypeError('IndexNode expected as "index"');
|
70 | }
|
71 |
|
72 | if (!isNode(this.value)) {
|
73 | throw new TypeError('Node expected as "value"');
|
74 | }
|
75 |
|
76 |
|
77 | Object.defineProperty(this, 'name', {
|
78 | get: function () {
|
79 | if (this.index) {
|
80 | return this.index.isObjectProperty() ? this.index.getObjectProperty() : '';
|
81 | } else {
|
82 | return this.object.name || '';
|
83 | }
|
84 | }.bind(this),
|
85 | set: function set() {
|
86 | throw new Error('Cannot assign a new name, name is read-only');
|
87 | }
|
88 | });
|
89 | }
|
90 |
|
91 | AssignmentNode.prototype = new Node();
|
92 | AssignmentNode.prototype.type = 'AssignmentNode';
|
93 | AssignmentNode.prototype.isAssignmentNode = true;
|
94 | |
95 |
|
96 |
|
97 |
|
98 |
|
99 |
|
100 |
|
101 |
|
102 |
|
103 |
|
104 |
|
105 |
|
106 |
|
107 |
|
108 | AssignmentNode.prototype._compile = function (math, argNames) {
|
109 | var evalObject = this.object._compile(math, argNames);
|
110 |
|
111 | var evalIndex = this.index ? this.index._compile(math, argNames) : null;
|
112 |
|
113 | var evalValue = this.value._compile(math, argNames);
|
114 |
|
115 | var name = this.object.name;
|
116 |
|
117 | if (!this.index) {
|
118 |
|
119 | if (!isSymbolNode(this.object)) {
|
120 | throw new TypeError('SymbolNode expected as object');
|
121 | }
|
122 |
|
123 | return function evalAssignmentNode(scope, args, context) {
|
124 | return setSafeProperty(scope, name, evalValue(scope, args, context));
|
125 | };
|
126 | } else if (this.index.isObjectProperty()) {
|
127 |
|
128 | var prop = this.index.getObjectProperty();
|
129 | return function evalAssignmentNode(scope, args, context) {
|
130 | var object = evalObject(scope, args, context);
|
131 | var value = evalValue(scope, args, context);
|
132 | return setSafeProperty(object, prop, value);
|
133 | };
|
134 | } else if (isSymbolNode(this.object)) {
|
135 |
|
136 | return function evalAssignmentNode(scope, args, context) {
|
137 | var childObject = evalObject(scope, args, context);
|
138 | var value = evalValue(scope, args, context);
|
139 | var index = evalIndex(scope, args, childObject);
|
140 |
|
141 | setSafeProperty(scope, name, assign(childObject, index, value));
|
142 | return value;
|
143 | };
|
144 | } else {
|
145 |
|
146 |
|
147 |
|
148 |
|
149 |
|
150 | var evalParentObject = this.object.object._compile(math, argNames);
|
151 |
|
152 | if (this.object.index.isObjectProperty()) {
|
153 | var parentProp = this.object.index.getObjectProperty();
|
154 | return function evalAssignmentNode(scope, args, context) {
|
155 | var parent = evalParentObject(scope, args, context);
|
156 | var childObject = getSafeProperty(parent, parentProp);
|
157 | var index = evalIndex(scope, args, childObject);
|
158 |
|
159 | var value = evalValue(scope, args, context);
|
160 | setSafeProperty(parent, parentProp, assign(childObject, index, value));
|
161 | return value;
|
162 | };
|
163 | } else {
|
164 |
|
165 | var evalParentIndex = this.object.index._compile(math, argNames);
|
166 |
|
167 | return function evalAssignmentNode(scope, args, context) {
|
168 | var parent = evalParentObject(scope, args, context);
|
169 | var parentIndex = evalParentIndex(scope, args, parent);
|
170 |
|
171 | var childObject = access(parent, parentIndex);
|
172 | var index = evalIndex(scope, args, childObject);
|
173 |
|
174 | var value = evalValue(scope, args, context);
|
175 | assign(parent, parentIndex, assign(childObject, index, value));
|
176 | return value;
|
177 | };
|
178 | }
|
179 | }
|
180 | };
|
181 | |
182 |
|
183 |
|
184 |
|
185 |
|
186 |
|
187 | AssignmentNode.prototype.forEach = function (callback) {
|
188 | callback(this.object, 'object', this);
|
189 |
|
190 | if (this.index) {
|
191 | callback(this.index, 'index', this);
|
192 | }
|
193 |
|
194 | callback(this.value, 'value', this);
|
195 | };
|
196 | |
197 |
|
198 |
|
199 |
|
200 |
|
201 |
|
202 |
|
203 |
|
204 | AssignmentNode.prototype.map = function (callback) {
|
205 | var object = this._ifNode(callback(this.object, 'object', this));
|
206 |
|
207 | var index = this.index ? this._ifNode(callback(this.index, 'index', this)) : null;
|
208 |
|
209 | var value = this._ifNode(callback(this.value, 'value', this));
|
210 |
|
211 | return new AssignmentNode(object, index, value);
|
212 | };
|
213 | |
214 |
|
215 |
|
216 |
|
217 |
|
218 |
|
219 | AssignmentNode.prototype.clone = function () {
|
220 | return new AssignmentNode(this.object, this.index, this.value);
|
221 | };
|
222 | |
223 |
|
224 |
|
225 |
|
226 |
|
227 |
|
228 |
|
229 |
|
230 | function needParenthesis(node, parenthesis) {
|
231 | if (!parenthesis) {
|
232 | parenthesis = 'keep';
|
233 | }
|
234 |
|
235 | var precedence = getPrecedence(node, parenthesis);
|
236 | var exprPrecedence = getPrecedence(node.value, parenthesis);
|
237 | return parenthesis === 'all' || exprPrecedence !== null && exprPrecedence <= precedence;
|
238 | }
|
239 | |
240 |
|
241 |
|
242 |
|
243 |
|
244 |
|
245 |
|
246 | AssignmentNode.prototype._toString = function (options) {
|
247 | var object = this.object.toString(options);
|
248 | var index = this.index ? this.index.toString(options) : '';
|
249 | var value = this.value.toString(options);
|
250 |
|
251 | if (needParenthesis(this, options && options.parenthesis)) {
|
252 | value = '(' + value + ')';
|
253 | }
|
254 |
|
255 | return object + index + ' = ' + value;
|
256 | };
|
257 | |
258 |
|
259 |
|
260 |
|
261 |
|
262 |
|
263 | AssignmentNode.prototype.toJSON = function () {
|
264 | return {
|
265 | mathjs: 'AssignmentNode',
|
266 | object: this.object,
|
267 | index: this.index,
|
268 | value: this.value
|
269 | };
|
270 | };
|
271 | |
272 |
|
273 |
|
274 |
|
275 |
|
276 |
|
277 |
|
278 |
|
279 |
|
280 | AssignmentNode.fromJSON = function (json) {
|
281 | return new AssignmentNode(json.object, json.index, json.value);
|
282 | };
|
283 | |
284 |
|
285 |
|
286 |
|
287 |
|
288 |
|
289 |
|
290 | AssignmentNode.prototype.toHTML = function (options) {
|
291 | var object = this.object.toHTML(options);
|
292 | var index = this.index ? this.index.toHTML(options) : '';
|
293 | var value = this.value.toHTML(options);
|
294 |
|
295 | if (needParenthesis(this, options && options.parenthesis)) {
|
296 | value = '<span class="math-paranthesis math-round-parenthesis">(</span>' + value + '<span class="math-paranthesis math-round-parenthesis">)</span>';
|
297 | }
|
298 |
|
299 | return object + index + '<span class="math-operator math-assignment-operator math-variable-assignment-operator math-binary-operator">=</span>' + value;
|
300 | };
|
301 | |
302 |
|
303 |
|
304 |
|
305 |
|
306 |
|
307 |
|
308 | AssignmentNode.prototype._toTex = function (options) {
|
309 | var object = this.object.toTex(options);
|
310 | var index = this.index ? this.index.toTex(options) : '';
|
311 | var value = this.value.toTex(options);
|
312 |
|
313 | if (needParenthesis(this, options && options.parenthesis)) {
|
314 | value = "\\left(".concat(value, "\\right)");
|
315 | }
|
316 |
|
317 | return object + index + ':=' + value;
|
318 | };
|
319 |
|
320 | return AssignmentNode;
|
321 | }, {
|
322 | isClass: true,
|
323 | isNode: true
|
324 | }); |
\ | No newline at end of file |