mathjs 5.0.0 → 5.0.4
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of mathjs might be problematic. Click here for more details.
- package/HISTORY.md +48 -1
- package/README.md +2 -1
- package/dist/math.js +20114 -20090
- package/dist/math.min.js +7 -7
- package/dist/math.min.map +1 -1
- package/docs/core/configuration.md +1 -1
- package/docs/datatypes/numbers.md +1 -1
- package/docs/datatypes/units.md +1 -1
- package/docs/expressions/algebra.md +25 -1
- package/docs/getting_started.md +2 -2
- package/docs/reference/functions/format.md +2 -2
- package/docs/reference/functions/qr.md +2 -1
- package/docs/reference/functions/rationalize.md +13 -10
- package/docs/reference/functions/stirlingS2.md +1 -1
- package/docs/reference/functions/typeof.md +13 -13
- package/examples/advanced/add_new_datatypes/MyType.js +0 -10
- package/examples/advanced/add_new_datatypes/index.js +2 -6
- package/examples/browser/rocket_trajectory_optimization.html +2 -2
- package/lib/constants.js +3 -1
- package/lib/core/function/import.js +15 -2
- package/lib/core/typed.js +1 -1
- package/lib/expression/node/FunctionNode.js +5 -4
- package/lib/expression/parse.js +429 -466
- package/lib/function/algebra/decomposition/qr.js +1 -1
- package/lib/function/algebra/rationalize.js +41 -45
- package/lib/function/algebra/simplify/resolve.js +1 -1
- package/lib/function/algebra/simplify/simplifyCore.js +3 -3
- package/lib/function/algebra/simplify/util.js +1 -1
- package/lib/function/algebra/simplify.js +5 -0
- package/lib/function/combinatorics/stirlingS2.js +1 -1
- package/lib/function/probability/combinations.js +11 -10
- package/lib/function/probability/gamma.js +5 -13
- package/lib/function/probability/permutations.js +2 -12
- package/lib/function/probability/product.js +19 -0
- package/lib/function/string/format.js +2 -2
- package/lib/function/utils/typeof.js +13 -13
- package/lib/index.js +5 -1
- package/lib/type/bignumber/BigNumber.js +6 -2
- package/lib/type/matrix/utils/algorithm13.js +0 -2
- package/lib/type/unit/Unit.js +2 -2
- package/lib/utils/array.js +27 -19
- package/lib/utils/bignumber/formatter.js +3 -2
- package/lib/utils/number.js +15 -10
- package/lib/version.js +1 -1
- package/package.json +13 -8
- package/src/constants.js +3 -1
- package/src/core/function/import.js +15 -2
- package/src/core/typed.js +1 -1
- package/src/expression/node/FunctionNode.js +3 -4
- package/src/expression/parse.js +432 -470
- package/src/function/algebra/decomposition/qr.js +1 -1
- package/src/function/algebra/rationalize.js +41 -43
- package/src/function/algebra/simplify/resolve.js +1 -1
- package/src/function/algebra/simplify/simplifyCore.js +3 -3
- package/src/function/algebra/simplify/util.js +1 -1
- package/src/function/algebra/simplify.js +5 -0
- package/src/function/combinatorics/stirlingS2.js +1 -1
- package/src/function/probability/combinations.js +10 -8
- package/src/function/probability/gamma.js +5 -13
- package/src/function/probability/permutations.js +2 -11
- package/src/function/probability/product.js +17 -0
- package/src/function/string/format.js +2 -2
- package/src/function/utils/typeof.js +13 -13
- package/src/index.js +5 -1
- package/src/type/bignumber/BigNumber.js +2 -1
- package/src/type/matrix/utils/algorithm13.js +0 -2
- package/src/type/unit/Unit.js +2 -2
- package/src/utils/array.js +31 -23
- package/src/utils/bignumber/formatter.js +3 -2
- package/src/utils/number.js +15 -10
- package/src/version.js +1 -1
package/lib/expression/parse.js
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
'use strict';
|
2
2
|
|
3
|
+
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
|
4
|
+
|
3
5
|
var ArgumentsError = require('../error/ArgumentsError');
|
4
6
|
var deepMap = require('../utils/collection/deepMap');
|
5
7
|
|
@@ -59,19 +61,18 @@ function factory(type, config, load, typed) {
|
|
59
61
|
}
|
60
62
|
|
61
63
|
// pass extra nodes
|
62
|
-
extraNodes = options && options.nodes ? options.nodes : {};
|
64
|
+
var extraNodes = options && options.nodes ? options.nodes : {};
|
63
65
|
|
64
66
|
if (typeof expr === 'string') {
|
65
67
|
// parse a single expression
|
66
|
-
|
67
|
-
return parseStart();
|
68
|
+
|
69
|
+
return parseStart(expr, extraNodes);
|
68
70
|
} else if (Array.isArray(expr) || expr instanceof type.Matrix) {
|
69
71
|
// parse an array or matrix with expressions
|
70
72
|
return deepMap(expr, function (elem) {
|
71
73
|
if (typeof elem !== 'string') throw new TypeError('String expected');
|
72
74
|
|
73
|
-
|
74
|
-
return parseStart();
|
75
|
+
return parseStart(elem, extraNodes);
|
75
76
|
});
|
76
77
|
} else {
|
77
78
|
// oops
|
@@ -149,101 +150,68 @@ function factory(type, config, load, typed) {
|
|
149
150
|
|
150
151
|
var NUMERIC_CONSTANTS = ['NaN', 'Infinity'];
|
151
152
|
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
/**
|
164
|
-
* Get the first character from the expression.
|
165
|
-
* The character is stored into the char c. If the end of the expression is
|
166
|
-
* reached, the function puts an empty string in c.
|
167
|
-
* @private
|
168
|
-
*/
|
169
|
-
function first() {
|
170
|
-
index = 0;
|
171
|
-
c = expression.charAt(0);
|
172
|
-
nestingLevel = 0;
|
173
|
-
conditionalLevel = null;
|
153
|
+
function initialState() {
|
154
|
+
return {
|
155
|
+
extraNodes: {}, // current extra nodes, must be careful not to mutate
|
156
|
+
expression: '', // current expression
|
157
|
+
comment: '', // last parsed comment
|
158
|
+
index: 0, // current index in expr
|
159
|
+
token: '', // current token
|
160
|
+
tokenType: TOKENTYPE.NULL, // type of the token
|
161
|
+
nestingLevel: 0, // level of nesting inside parameters, used to ignore newline characters
|
162
|
+
conditionalLevel: null // when a conditional is being parsed, the level of the conditional is stored here
|
163
|
+
};
|
174
164
|
}
|
175
165
|
|
176
166
|
/**
|
177
|
-
*
|
178
|
-
*
|
179
|
-
*
|
167
|
+
* View upto `length` characters of the expression starting at the current character.
|
168
|
+
*
|
169
|
+
* @param {State} state
|
170
|
+
* @param {number} [length=1] Number of characters to view
|
171
|
+
* @returns {string}
|
180
172
|
* @private
|
181
173
|
*/
|
182
|
-
function
|
183
|
-
index
|
184
|
-
c = expression.charAt(index);
|
174
|
+
function currentString(state, length) {
|
175
|
+
return state.expression.substr(state.index, length);
|
185
176
|
}
|
186
177
|
|
187
178
|
/**
|
188
|
-
*
|
189
|
-
*
|
179
|
+
* View the current character. Returns '' if end of expression is reached.
|
180
|
+
*
|
181
|
+
* @param {State} state
|
182
|
+
* @returns {string}
|
190
183
|
* @private
|
191
184
|
*/
|
192
|
-
function
|
193
|
-
return
|
185
|
+
function currentCharacter(state) {
|
186
|
+
return currentString(state, 1);
|
194
187
|
}
|
195
188
|
|
196
189
|
/**
|
197
|
-
*
|
198
|
-
*
|
190
|
+
* Get the next character from the expression.
|
191
|
+
* The character is stored into the char c. If the end of the expression is
|
192
|
+
* reached, the function puts an empty string in c.
|
199
193
|
* @private
|
200
194
|
*/
|
201
|
-
function
|
202
|
-
|
195
|
+
function next(state) {
|
196
|
+
state.index++;
|
203
197
|
}
|
204
198
|
|
205
199
|
/**
|
206
|
-
* Preview the
|
200
|
+
* Preview the previous character from the expression.
|
207
201
|
* @return {string} cNext
|
208
202
|
* @private
|
209
203
|
*/
|
210
|
-
function
|
211
|
-
return expression.charAt(index
|
212
|
-
}
|
213
|
-
|
214
|
-
/**
|
215
|
-
* Save the current token state so we can rewind later if necessary.
|
216
|
-
* @private
|
217
|
-
*/
|
218
|
-
function pushTokenState() {
|
219
|
-
tokenStates.push({
|
220
|
-
tokenType: tokenType,
|
221
|
-
token: token,
|
222
|
-
comment: comment,
|
223
|
-
index: index,
|
224
|
-
c: c
|
225
|
-
});
|
226
|
-
}
|
227
|
-
|
228
|
-
/**
|
229
|
-
* Rewind the parser by one token by restoring the last saved token state
|
230
|
-
* @private
|
231
|
-
*/
|
232
|
-
function popTokenState() {
|
233
|
-
var restoredState = tokenStates.pop();
|
234
|
-
tokenType = restoredState.tokenType;
|
235
|
-
token = restoredState.token;
|
236
|
-
comment = restoredState.comment;
|
237
|
-
index = restoredState.index;
|
238
|
-
c = restoredState.c;
|
204
|
+
function prevCharacter(state) {
|
205
|
+
return state.expression.charAt(state.index - 1);
|
239
206
|
}
|
240
207
|
|
241
208
|
/**
|
242
|
-
*
|
209
|
+
* Preview the next character from the expression.
|
210
|
+
* @return {string} cNext
|
243
211
|
* @private
|
244
212
|
*/
|
245
|
-
function
|
246
|
-
|
213
|
+
function nextCharacter(state) {
|
214
|
+
return state.expression.charAt(state.index + 1);
|
247
215
|
}
|
248
216
|
|
249
217
|
/**
|
@@ -251,125 +219,123 @@ function factory(type, config, load, typed) {
|
|
251
219
|
* The token and token type are available as token and tokenType
|
252
220
|
* @private
|
253
221
|
*/
|
254
|
-
function getToken() {
|
255
|
-
tokenType = TOKENTYPE.NULL;
|
256
|
-
token = '';
|
257
|
-
comment = '';
|
222
|
+
function getToken(state) {
|
223
|
+
state.tokenType = TOKENTYPE.NULL;
|
224
|
+
state.token = '';
|
225
|
+
state.comment = '';
|
258
226
|
|
259
227
|
// skip over whitespaces
|
260
228
|
// space, tab, and newline when inside parameters
|
261
|
-
while (parse.isWhitespace(
|
262
|
-
next();
|
229
|
+
while (parse.isWhitespace(currentCharacter(state), state.nestingLevel)) {
|
230
|
+
next(state);
|
263
231
|
}
|
264
232
|
|
265
233
|
// skip comment
|
266
|
-
if (
|
267
|
-
while (
|
268
|
-
comment +=
|
269
|
-
next();
|
234
|
+
if (currentCharacter(state) === '#') {
|
235
|
+
while (currentCharacter(state) !== '\n' && currentCharacter(state) !== '') {
|
236
|
+
state.comment += currentCharacter(state);
|
237
|
+
next(state);
|
270
238
|
}
|
271
239
|
}
|
272
240
|
|
273
241
|
// check for end of expression
|
274
|
-
if (
|
242
|
+
if (currentCharacter(state) === '') {
|
275
243
|
// token is still empty
|
276
|
-
tokenType = TOKENTYPE.DELIMITER;
|
244
|
+
state.tokenType = TOKENTYPE.DELIMITER;
|
277
245
|
return;
|
278
246
|
}
|
279
247
|
|
280
248
|
// check for new line character
|
281
|
-
if (
|
282
|
-
tokenType = TOKENTYPE.DELIMITER;
|
283
|
-
token =
|
284
|
-
next();
|
249
|
+
if (currentCharacter(state) === '\n' && !state.nestingLevel) {
|
250
|
+
state.tokenType = TOKENTYPE.DELIMITER;
|
251
|
+
state.token = currentCharacter(state);
|
252
|
+
next(state);
|
285
253
|
return;
|
286
254
|
}
|
287
255
|
|
288
|
-
|
289
|
-
var c2 =
|
290
|
-
var c3 =
|
256
|
+
var c1 = currentCharacter(state);
|
257
|
+
var c2 = currentString(state, 2);
|
258
|
+
var c3 = currentString(state, 3);
|
291
259
|
if (c3.length === 3 && DELIMITERS[c3]) {
|
292
|
-
tokenType = TOKENTYPE.DELIMITER;
|
293
|
-
token = c3;
|
294
|
-
next();
|
295
|
-
next();
|
296
|
-
next();
|
260
|
+
state.tokenType = TOKENTYPE.DELIMITER;
|
261
|
+
state.token = c3;
|
262
|
+
next(state);
|
263
|
+
next(state);
|
264
|
+
next(state);
|
297
265
|
return;
|
298
266
|
}
|
299
267
|
|
300
268
|
// check for delimiters consisting of 2 characters
|
301
269
|
if (c2.length === 2 && DELIMITERS[c2]) {
|
302
|
-
tokenType = TOKENTYPE.DELIMITER;
|
303
|
-
token = c2;
|
304
|
-
next();
|
305
|
-
next();
|
270
|
+
state.tokenType = TOKENTYPE.DELIMITER;
|
271
|
+
state.token = c2;
|
272
|
+
next(state);
|
273
|
+
next(state);
|
306
274
|
return;
|
307
275
|
}
|
308
276
|
|
309
277
|
// check for delimiters consisting of 1 character
|
310
|
-
if (DELIMITERS[
|
311
|
-
tokenType = TOKENTYPE.DELIMITER;
|
312
|
-
token =
|
313
|
-
next();
|
278
|
+
if (DELIMITERS[c1]) {
|
279
|
+
state.tokenType = TOKENTYPE.DELIMITER;
|
280
|
+
state.token = c1;
|
281
|
+
next(state);
|
314
282
|
return;
|
315
283
|
}
|
316
284
|
|
317
285
|
// check for a number
|
318
|
-
if (parse.isDigitDot(
|
319
|
-
tokenType = TOKENTYPE.NUMBER;
|
286
|
+
if (parse.isDigitDot(c1)) {
|
287
|
+
state.tokenType = TOKENTYPE.NUMBER;
|
320
288
|
|
321
289
|
// get number, can have a single dot
|
322
|
-
if (
|
323
|
-
token +=
|
324
|
-
next();
|
290
|
+
if (currentCharacter(state) === '.') {
|
291
|
+
state.token += currentCharacter(state);
|
292
|
+
next(state);
|
325
293
|
|
326
|
-
if (!parse.isDigit(
|
294
|
+
if (!parse.isDigit(currentCharacter(state))) {
|
327
295
|
// this is no number, it is just a dot (can be dot notation)
|
328
|
-
tokenType = TOKENTYPE.DELIMITER;
|
296
|
+
state.tokenType = TOKENTYPE.DELIMITER;
|
329
297
|
}
|
330
298
|
} else {
|
331
|
-
while (parse.isDigit(
|
332
|
-
token +=
|
333
|
-
next();
|
299
|
+
while (parse.isDigit(currentCharacter(state))) {
|
300
|
+
state.token += currentCharacter(state);
|
301
|
+
next(state);
|
334
302
|
}
|
335
|
-
if (parse.isDecimalMark(
|
336
|
-
token +=
|
337
|
-
next();
|
303
|
+
if (parse.isDecimalMark(currentCharacter(state), nextCharacter(state))) {
|
304
|
+
state.token += currentCharacter(state);
|
305
|
+
next(state);
|
338
306
|
}
|
339
307
|
}
|
340
|
-
while (parse.isDigit(c)) {
|
341
|
-
token += c;
|
342
|
-
next();
|
343
|
-
}
|
344
308
|
|
309
|
+
while (parse.isDigit(currentCharacter(state))) {
|
310
|
+
state.token += currentCharacter(state);
|
311
|
+
next(state);
|
312
|
+
}
|
345
313
|
// check for exponential notation like "2.3e-4", "1.23e50" or "2e+4"
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
next();
|
314
|
+
if (currentCharacter(state) === 'E' || currentCharacter(state) === 'e') {
|
315
|
+
if (parse.isDigit(nextCharacter(state)) || nextCharacter(state) === '-' || nextCharacter(state) === '+') {
|
316
|
+
state.token += currentCharacter(state);
|
317
|
+
next(state);
|
318
|
+
|
319
|
+
if (currentCharacter(state) === '+' || currentCharacter(state) === '-') {
|
320
|
+
state.token += currentCharacter(state);
|
321
|
+
next(state);
|
355
322
|
}
|
356
|
-
|
357
323
|
// Scientific notation MUST be followed by an exponent
|
358
|
-
if (!parse.isDigit(
|
359
|
-
throw createSyntaxError('Digit expected, got "' +
|
324
|
+
if (!parse.isDigit(currentCharacter(state))) {
|
325
|
+
throw createSyntaxError(state, 'Digit expected, got "' + currentCharacter(state) + '"');
|
360
326
|
}
|
361
327
|
|
362
|
-
while (parse.isDigit(
|
363
|
-
token +=
|
364
|
-
next();
|
328
|
+
while (parse.isDigit(currentCharacter(state))) {
|
329
|
+
state.token += currentCharacter(state);
|
330
|
+
next(state);
|
365
331
|
}
|
366
332
|
|
367
|
-
if (parse.isDecimalMark(
|
368
|
-
throw createSyntaxError('Digit expected, got "' +
|
333
|
+
if (parse.isDecimalMark(currentCharacter(state), nextCharacter(state))) {
|
334
|
+
throw createSyntaxError(state, 'Digit expected, got "' + currentCharacter(state) + '"');
|
369
335
|
}
|
370
|
-
} else if (
|
371
|
-
next();
|
372
|
-
throw createSyntaxError('Digit expected, got "' +
|
336
|
+
} else if (nextCharacter(state) === '.') {
|
337
|
+
next(state);
|
338
|
+
throw createSyntaxError(state, 'Digit expected, got "' + currentCharacter(state) + '"');
|
373
339
|
}
|
374
340
|
}
|
375
341
|
|
@@ -377,53 +343,53 @@ function factory(type, config, load, typed) {
|
|
377
343
|
}
|
378
344
|
|
379
345
|
// check for variables, functions, named operators
|
380
|
-
if (parse.isAlpha(
|
381
|
-
while (parse.isAlpha(
|
382
|
-
token +=
|
383
|
-
next();
|
346
|
+
if (parse.isAlpha(currentCharacter(state), prevCharacter(state), nextCharacter(state))) {
|
347
|
+
while (parse.isAlpha(currentCharacter(state), prevCharacter(state), nextCharacter(state)) || parse.isDigit(currentCharacter(state))) {
|
348
|
+
state.token += currentCharacter(state);
|
349
|
+
next(state);
|
384
350
|
}
|
385
351
|
|
386
|
-
if (NAMED_DELIMITERS.hasOwnProperty(token)) {
|
387
|
-
tokenType = TOKENTYPE.DELIMITER;
|
352
|
+
if (NAMED_DELIMITERS.hasOwnProperty(state.token)) {
|
353
|
+
state.tokenType = TOKENTYPE.DELIMITER;
|
388
354
|
} else {
|
389
|
-
tokenType = TOKENTYPE.SYMBOL;
|
355
|
+
state.tokenType = TOKENTYPE.SYMBOL;
|
390
356
|
}
|
391
357
|
|
392
358
|
return;
|
393
359
|
}
|
394
360
|
|
395
361
|
// something unknown is found, wrong characters -> a syntax error
|
396
|
-
tokenType = TOKENTYPE.UNKNOWN;
|
397
|
-
while (
|
398
|
-
token +=
|
399
|
-
next();
|
362
|
+
state.tokenType = TOKENTYPE.UNKNOWN;
|
363
|
+
while (currentCharacter(state) !== '') {
|
364
|
+
state.token += currentCharacter(state);
|
365
|
+
next(state);
|
400
366
|
}
|
401
|
-
throw createSyntaxError('Syntax error in part "' + token + '"');
|
367
|
+
throw createSyntaxError(state, 'Syntax error in part "' + state.token + '"');
|
402
368
|
}
|
403
369
|
|
404
370
|
/**
|
405
371
|
* Get next token and skip newline tokens
|
406
372
|
*/
|
407
|
-
function getTokenSkipNewline() {
|
373
|
+
function getTokenSkipNewline(state) {
|
408
374
|
do {
|
409
|
-
getToken();
|
410
|
-
} while (token === '\n'); // eslint-disable-line no-unmodified-loop-condition
|
375
|
+
getToken(state);
|
376
|
+
} while (state.token === '\n'); // eslint-disable-line no-unmodified-loop-condition
|
411
377
|
}
|
412
378
|
|
413
379
|
/**
|
414
380
|
* Open parameters.
|
415
|
-
* New line characters will be ignored until closeParams() is called
|
381
|
+
* New line characters will be ignored until closeParams(state) is called
|
416
382
|
*/
|
417
|
-
function openParams() {
|
418
|
-
nestingLevel++;
|
383
|
+
function openParams(state) {
|
384
|
+
state.nestingLevel++;
|
419
385
|
}
|
420
386
|
|
421
387
|
/**
|
422
388
|
* Close parameters.
|
423
389
|
* New line characters will no longer be ignored
|
424
390
|
*/
|
425
|
-
function closeParams() {
|
426
|
-
nestingLevel--;
|
391
|
+
function closeParams(state) {
|
392
|
+
state.nestingLevel--;
|
427
393
|
}
|
428
394
|
|
429
395
|
/**
|
@@ -523,24 +489,23 @@ function factory(type, config, load, typed) {
|
|
523
489
|
* @return {Node} node
|
524
490
|
* @private
|
525
491
|
*/
|
526
|
-
function parseStart() {
|
527
|
-
|
528
|
-
|
492
|
+
function parseStart(expression, extraNodes) {
|
493
|
+
var state = initialState();
|
494
|
+
_extends(state, { expression: expression, extraNodes: extraNodes });
|
495
|
+
getToken(state);
|
529
496
|
|
530
|
-
|
531
|
-
|
532
|
-
var node = parseBlock();
|
497
|
+
var node = parseBlock(state);
|
533
498
|
|
534
499
|
// check for garbage at the end of the expression
|
535
500
|
// an expression ends with a empty character '' and tokenType DELIMITER
|
536
|
-
if (token !== '') {
|
537
|
-
if (tokenType === TOKENTYPE.DELIMITER) {
|
501
|
+
if (state.token !== '') {
|
502
|
+
if (state.tokenType === TOKENTYPE.DELIMITER) {
|
538
503
|
// user entered a not existing operator like "//"
|
539
504
|
|
540
505
|
// TODO: give hints for aliases, for example with "<>" give as hint " did you mean !== ?"
|
541
|
-
throw createError('Unexpected operator ' + token);
|
506
|
+
throw createError(state, 'Unexpected operator ' + state.token);
|
542
507
|
} else {
|
543
|
-
throw createSyntaxError('Unexpected part "' + token + '"');
|
508
|
+
throw createSyntaxError(state, 'Unexpected part "' + state.token + '"');
|
544
509
|
}
|
545
510
|
}
|
546
511
|
|
@@ -554,33 +519,33 @@ function factory(type, config, load, typed) {
|
|
554
519
|
* @return {Node} node
|
555
520
|
* @private
|
556
521
|
*/
|
557
|
-
function parseBlock() {
|
522
|
+
function parseBlock(state) {
|
558
523
|
var node = void 0;
|
559
524
|
var blocks = [];
|
560
525
|
var visible = void 0;
|
561
526
|
|
562
|
-
if (token !== '' && token !== '\n' && token !== ';') {
|
563
|
-
node = parseAssignment();
|
564
|
-
node.comment = comment;
|
527
|
+
if (state.token !== '' && state.token !== '\n' && state.token !== ';') {
|
528
|
+
node = parseAssignment(state);
|
529
|
+
node.comment = state.comment;
|
565
530
|
}
|
566
531
|
|
567
532
|
// TODO: simplify this loop
|
568
|
-
while (token === '\n' || token === ';') {
|
533
|
+
while (state.token === '\n' || state.token === ';') {
|
569
534
|
// eslint-disable-line no-unmodified-loop-condition
|
570
535
|
if (blocks.length === 0 && node) {
|
571
|
-
visible = token !== ';';
|
536
|
+
visible = state.token !== ';';
|
572
537
|
blocks.push({
|
573
538
|
node: node,
|
574
539
|
visible: visible
|
575
540
|
});
|
576
541
|
}
|
577
542
|
|
578
|
-
getToken();
|
579
|
-
if (token !== '\n' && token !== ';' && token !== '') {
|
580
|
-
node = parseAssignment();
|
581
|
-
node.comment = comment;
|
543
|
+
getToken(state);
|
544
|
+
if (state.token !== '\n' && state.token !== ';' && state.token !== '') {
|
545
|
+
node = parseAssignment(state);
|
546
|
+
node.comment = state.comment;
|
582
547
|
|
583
|
-
visible = token !== ';';
|
548
|
+
visible = state.token !== ';';
|
584
549
|
blocks.push({
|
585
550
|
node: node,
|
586
551
|
visible: visible
|
@@ -593,7 +558,7 @@ function factory(type, config, load, typed) {
|
|
593
558
|
} else {
|
594
559
|
if (!node) {
|
595
560
|
node = new ConstantNode(undefined);
|
596
|
-
node.comment = comment;
|
561
|
+
node.comment = state.comment;
|
597
562
|
}
|
598
563
|
|
599
564
|
return node;
|
@@ -608,25 +573,25 @@ function factory(type, config, load, typed) {
|
|
608
573
|
* @return {Node} node
|
609
574
|
* @private
|
610
575
|
*/
|
611
|
-
function parseAssignment() {
|
576
|
+
function parseAssignment(state) {
|
612
577
|
var name = void 0,
|
613
578
|
args = void 0,
|
614
579
|
value = void 0,
|
615
580
|
valid = void 0;
|
616
581
|
|
617
|
-
var node = parseConditional();
|
582
|
+
var node = parseConditional(state);
|
618
583
|
|
619
|
-
if (token === '=') {
|
584
|
+
if (state.token === '=') {
|
620
585
|
if (type.isSymbolNode(node)) {
|
621
586
|
// parse a variable assignment like 'a = 2/3'
|
622
587
|
name = node.name;
|
623
|
-
getTokenSkipNewline();
|
624
|
-
value = parseAssignment();
|
588
|
+
getTokenSkipNewline(state);
|
589
|
+
value = parseAssignment(state);
|
625
590
|
return new AssignmentNode(new SymbolNode(name), value);
|
626
591
|
} else if (type.isAccessorNode(node)) {
|
627
592
|
// parse a matrix subset assignment like 'A[1,2] = 4'
|
628
|
-
getTokenSkipNewline();
|
629
|
-
value = parseAssignment();
|
593
|
+
getTokenSkipNewline(state);
|
594
|
+
value = parseAssignment(state);
|
630
595
|
return new AssignmentNode(node.object, node.index, value);
|
631
596
|
} else if (type.isFunctionNode(node) && type.isSymbolNode(node.fn)) {
|
632
597
|
// parse function assignment like 'f(x) = x^2'
|
@@ -643,13 +608,13 @@ function factory(type, config, load, typed) {
|
|
643
608
|
});
|
644
609
|
|
645
610
|
if (valid) {
|
646
|
-
getTokenSkipNewline();
|
647
|
-
value = parseAssignment();
|
611
|
+
getTokenSkipNewline(state);
|
612
|
+
value = parseAssignment(state);
|
648
613
|
return new FunctionAssignmentNode(name, args, value);
|
649
614
|
}
|
650
615
|
}
|
651
616
|
|
652
|
-
throw createSyntaxError('Invalid left hand side of assignment operator =');
|
617
|
+
throw createSyntaxError(state, 'Invalid left hand side of assignment operator =');
|
653
618
|
}
|
654
619
|
|
655
620
|
return node;
|
@@ -665,31 +630,31 @@ function factory(type, config, load, typed) {
|
|
665
630
|
* @return {Node} node
|
666
631
|
* @private
|
667
632
|
*/
|
668
|
-
function parseConditional() {
|
669
|
-
var node = parseLogicalOr();
|
633
|
+
function parseConditional(state) {
|
634
|
+
var node = parseLogicalOr(state);
|
670
635
|
|
671
|
-
while (token === '?') {
|
636
|
+
while (state.token === '?') {
|
672
637
|
// eslint-disable-line no-unmodified-loop-condition
|
673
638
|
// set a conditional level, the range operator will be ignored as long
|
674
|
-
// as conditionalLevel === nestingLevel.
|
675
|
-
var prev = conditionalLevel;
|
676
|
-
conditionalLevel = nestingLevel;
|
677
|
-
getTokenSkipNewline();
|
639
|
+
// as conditionalLevel === state.nestingLevel.
|
640
|
+
var prev = state.conditionalLevel;
|
641
|
+
state.conditionalLevel = state.nestingLevel;
|
642
|
+
getTokenSkipNewline(state);
|
678
643
|
|
679
644
|
var condition = node;
|
680
|
-
var trueExpr = parseAssignment();
|
645
|
+
var trueExpr = parseAssignment(state);
|
681
646
|
|
682
|
-
if (token !== ':') throw createSyntaxError('False part of conditional expression expected');
|
647
|
+
if (state.token !== ':') throw createSyntaxError(state, 'False part of conditional expression expected');
|
683
648
|
|
684
|
-
conditionalLevel = null;
|
685
|
-
getTokenSkipNewline();
|
649
|
+
state.conditionalLevel = null;
|
650
|
+
getTokenSkipNewline(state);
|
686
651
|
|
687
|
-
var falseExpr = parseAssignment(); // Note: check for conditional operator again, right associativity
|
652
|
+
var falseExpr = parseAssignment(state); // Note: check for conditional operator again, right associativity
|
688
653
|
|
689
654
|
node = new ConditionalNode(condition, trueExpr, falseExpr);
|
690
655
|
|
691
656
|
// restore the previous conditional level
|
692
|
-
conditionalLevel = prev;
|
657
|
+
state.conditionalLevel = prev;
|
693
658
|
}
|
694
659
|
|
695
660
|
return node;
|
@@ -700,13 +665,13 @@ function factory(type, config, load, typed) {
|
|
700
665
|
* @return {Node} node
|
701
666
|
* @private
|
702
667
|
*/
|
703
|
-
function parseLogicalOr() {
|
704
|
-
var node = parseLogicalXor();
|
668
|
+
function parseLogicalOr(state) {
|
669
|
+
var node = parseLogicalXor(state);
|
705
670
|
|
706
|
-
while (token === 'or') {
|
671
|
+
while (state.token === 'or') {
|
707
672
|
// eslint-disable-line no-unmodified-loop-condition
|
708
|
-
getTokenSkipNewline();
|
709
|
-
node = new OperatorNode('or', 'or', [node, parseLogicalXor()]);
|
673
|
+
getTokenSkipNewline(state);
|
674
|
+
node = new OperatorNode('or', 'or', [node, parseLogicalXor(state)]);
|
710
675
|
}
|
711
676
|
|
712
677
|
return node;
|
@@ -717,13 +682,13 @@ function factory(type, config, load, typed) {
|
|
717
682
|
* @return {Node} node
|
718
683
|
* @private
|
719
684
|
*/
|
720
|
-
function parseLogicalXor() {
|
721
|
-
var node = parseLogicalAnd();
|
685
|
+
function parseLogicalXor(state) {
|
686
|
+
var node = parseLogicalAnd(state);
|
722
687
|
|
723
|
-
while (token === 'xor') {
|
688
|
+
while (state.token === 'xor') {
|
724
689
|
// eslint-disable-line no-unmodified-loop-condition
|
725
|
-
getTokenSkipNewline();
|
726
|
-
node = new OperatorNode('xor', 'xor', [node, parseLogicalAnd()]);
|
690
|
+
getTokenSkipNewline(state);
|
691
|
+
node = new OperatorNode('xor', 'xor', [node, parseLogicalAnd(state)]);
|
727
692
|
}
|
728
693
|
|
729
694
|
return node;
|
@@ -734,13 +699,13 @@ function factory(type, config, load, typed) {
|
|
734
699
|
* @return {Node} node
|
735
700
|
* @private
|
736
701
|
*/
|
737
|
-
function parseLogicalAnd() {
|
738
|
-
var node = parseBitwiseOr();
|
702
|
+
function parseLogicalAnd(state) {
|
703
|
+
var node = parseBitwiseOr(state);
|
739
704
|
|
740
|
-
while (token === 'and') {
|
705
|
+
while (state.token === 'and') {
|
741
706
|
// eslint-disable-line no-unmodified-loop-condition
|
742
|
-
getTokenSkipNewline();
|
743
|
-
node = new OperatorNode('and', 'and', [node, parseBitwiseOr()]);
|
707
|
+
getTokenSkipNewline(state);
|
708
|
+
node = new OperatorNode('and', 'and', [node, parseBitwiseOr(state)]);
|
744
709
|
}
|
745
710
|
|
746
711
|
return node;
|
@@ -751,13 +716,13 @@ function factory(type, config, load, typed) {
|
|
751
716
|
* @return {Node} node
|
752
717
|
* @private
|
753
718
|
*/
|
754
|
-
function parseBitwiseOr() {
|
755
|
-
var node = parseBitwiseXor();
|
719
|
+
function parseBitwiseOr(state) {
|
720
|
+
var node = parseBitwiseXor(state);
|
756
721
|
|
757
|
-
while (token === '|') {
|
722
|
+
while (state.token === '|') {
|
758
723
|
// eslint-disable-line no-unmodified-loop-condition
|
759
|
-
getTokenSkipNewline();
|
760
|
-
node = new OperatorNode('|', 'bitOr', [node, parseBitwiseXor()]);
|
724
|
+
getTokenSkipNewline(state);
|
725
|
+
node = new OperatorNode('|', 'bitOr', [node, parseBitwiseXor(state)]);
|
761
726
|
}
|
762
727
|
|
763
728
|
return node;
|
@@ -768,13 +733,13 @@ function factory(type, config, load, typed) {
|
|
768
733
|
* @return {Node} node
|
769
734
|
* @private
|
770
735
|
*/
|
771
|
-
function parseBitwiseXor() {
|
772
|
-
var node = parseBitwiseAnd();
|
736
|
+
function parseBitwiseXor(state) {
|
737
|
+
var node = parseBitwiseAnd(state);
|
773
738
|
|
774
|
-
while (token === '^|') {
|
739
|
+
while (state.token === '^|') {
|
775
740
|
// eslint-disable-line no-unmodified-loop-condition
|
776
|
-
getTokenSkipNewline();
|
777
|
-
node = new OperatorNode('^|', 'bitXor', [node, parseBitwiseAnd()]);
|
741
|
+
getTokenSkipNewline(state);
|
742
|
+
node = new OperatorNode('^|', 'bitXor', [node, parseBitwiseAnd(state)]);
|
778
743
|
}
|
779
744
|
|
780
745
|
return node;
|
@@ -785,13 +750,13 @@ function factory(type, config, load, typed) {
|
|
785
750
|
* @return {Node} node
|
786
751
|
* @private
|
787
752
|
*/
|
788
|
-
function parseBitwiseAnd() {
|
789
|
-
var node = parseRelational();
|
753
|
+
function parseBitwiseAnd(state) {
|
754
|
+
var node = parseRelational(state);
|
790
755
|
|
791
|
-
while (token === '&') {
|
756
|
+
while (state.token === '&') {
|
792
757
|
// eslint-disable-line no-unmodified-loop-condition
|
793
|
-
getTokenSkipNewline();
|
794
|
-
node = new OperatorNode('&', 'bitAnd', [node, parseRelational()]);
|
758
|
+
getTokenSkipNewline(state);
|
759
|
+
node = new OperatorNode('&', 'bitAnd', [node, parseRelational(state)]);
|
795
760
|
}
|
796
761
|
|
797
762
|
return node;
|
@@ -802,14 +767,14 @@ function factory(type, config, load, typed) {
|
|
802
767
|
* @return {Node} node
|
803
768
|
* @private
|
804
769
|
*/
|
805
|
-
function parseRelational() {
|
770
|
+
function parseRelational(state) {
|
806
771
|
var node = void 0,
|
807
772
|
operators = void 0,
|
808
773
|
name = void 0,
|
809
774
|
fn = void 0,
|
810
775
|
params = void 0;
|
811
776
|
|
812
|
-
node = parseShift();
|
777
|
+
node = parseShift(state);
|
813
778
|
|
814
779
|
operators = {
|
815
780
|
'==': 'equal',
|
@@ -819,12 +784,12 @@ function factory(type, config, load, typed) {
|
|
819
784
|
'<=': 'smallerEq',
|
820
785
|
'>=': 'largerEq'
|
821
786
|
};
|
822
|
-
while (operators.hasOwnProperty(token)) {
|
823
|
-
name = token;
|
787
|
+
while (operators.hasOwnProperty(state.token)) {
|
788
|
+
name = state.token;
|
824
789
|
fn = operators[name];
|
825
790
|
|
826
|
-
getTokenSkipNewline();
|
827
|
-
params = [node, parseShift()];
|
791
|
+
getTokenSkipNewline(state);
|
792
|
+
params = [node, parseShift(state)];
|
828
793
|
node = new OperatorNode(name, fn, params);
|
829
794
|
}
|
830
795
|
|
@@ -836,14 +801,14 @@ function factory(type, config, load, typed) {
|
|
836
801
|
* @return {Node} node
|
837
802
|
* @private
|
838
803
|
*/
|
839
|
-
function parseShift() {
|
804
|
+
function parseShift(state) {
|
840
805
|
var node = void 0,
|
841
806
|
operators = void 0,
|
842
807
|
name = void 0,
|
843
808
|
fn = void 0,
|
844
809
|
params = void 0;
|
845
810
|
|
846
|
-
node = parseConversion();
|
811
|
+
node = parseConversion(state);
|
847
812
|
|
848
813
|
operators = {
|
849
814
|
'<<': 'leftShift',
|
@@ -851,12 +816,12 @@ function factory(type, config, load, typed) {
|
|
851
816
|
'>>>': 'rightLogShift'
|
852
817
|
};
|
853
818
|
|
854
|
-
while (operators.hasOwnProperty(token)) {
|
855
|
-
name = token;
|
819
|
+
while (operators.hasOwnProperty(state.token)) {
|
820
|
+
name = state.token;
|
856
821
|
fn = operators[name];
|
857
822
|
|
858
|
-
getTokenSkipNewline();
|
859
|
-
params = [node, parseConversion()];
|
823
|
+
getTokenSkipNewline(state);
|
824
|
+
params = [node, parseConversion(state)];
|
860
825
|
node = new OperatorNode(name, fn, params);
|
861
826
|
}
|
862
827
|
|
@@ -868,32 +833,32 @@ function factory(type, config, load, typed) {
|
|
868
833
|
* @return {Node} node
|
869
834
|
* @private
|
870
835
|
*/
|
871
|
-
function parseConversion() {
|
836
|
+
function parseConversion(state) {
|
872
837
|
var node = void 0,
|
873
838
|
operators = void 0,
|
874
839
|
name = void 0,
|
875
840
|
fn = void 0,
|
876
841
|
params = void 0;
|
877
842
|
|
878
|
-
node = parseRange();
|
843
|
+
node = parseRange(state);
|
879
844
|
|
880
845
|
operators = {
|
881
846
|
'to': 'to',
|
882
847
|
'in': 'to' // alias of 'to'
|
883
848
|
};
|
884
849
|
|
885
|
-
while (operators.hasOwnProperty(token)) {
|
886
|
-
name = token;
|
850
|
+
while (operators.hasOwnProperty(state.token)) {
|
851
|
+
name = state.token;
|
887
852
|
fn = operators[name];
|
888
853
|
|
889
|
-
getTokenSkipNewline();
|
854
|
+
getTokenSkipNewline(state);
|
890
855
|
|
891
|
-
if (name === 'in' && token === '') {
|
856
|
+
if (name === 'in' && state.token === '') {
|
892
857
|
// end of expression -> this is the unit 'in' ('inch')
|
893
858
|
node = new OperatorNode('*', 'multiply', [node, new SymbolNode('in')], true);
|
894
859
|
} else {
|
895
860
|
// operator 'a to b' or 'a in b'
|
896
|
-
params = [node, parseRange()];
|
861
|
+
params = [node, parseRange(state)];
|
897
862
|
node = new OperatorNode(name, fn, params);
|
898
863
|
}
|
899
864
|
}
|
@@ -906,33 +871,33 @@ function factory(type, config, load, typed) {
|
|
906
871
|
* @return {Node} node
|
907
872
|
* @private
|
908
873
|
*/
|
909
|
-
function parseRange() {
|
874
|
+
function parseRange(state) {
|
910
875
|
var node = void 0;
|
911
876
|
var params = [];
|
912
877
|
|
913
|
-
if (token === ':') {
|
878
|
+
if (state.token === ':') {
|
914
879
|
// implicit start=1 (one-based)
|
915
880
|
node = new ConstantNode(1);
|
916
881
|
} else {
|
917
882
|
// explicit start
|
918
|
-
node = parseAddSubtract();
|
883
|
+
node = parseAddSubtract(state);
|
919
884
|
}
|
920
885
|
|
921
|
-
if (token === ':' && conditionalLevel !== nestingLevel) {
|
886
|
+
if (state.token === ':' && state.conditionalLevel !== state.nestingLevel) {
|
922
887
|
// we ignore the range operator when a conditional operator is being processed on the same level
|
923
888
|
params.push(node);
|
924
889
|
|
925
890
|
// parse step and end
|
926
|
-
while (token === ':' && params.length < 3) {
|
891
|
+
while (state.token === ':' && params.length < 3) {
|
927
892
|
// eslint-disable-line no-unmodified-loop-condition
|
928
|
-
getTokenSkipNewline();
|
893
|
+
getTokenSkipNewline(state);
|
929
894
|
|
930
|
-
if (token === ')' || token === ']' || token === ',' || token === '') {
|
895
|
+
if (state.token === ')' || state.token === ']' || state.token === ',' || state.token === '') {
|
931
896
|
// implicit end
|
932
897
|
params.push(new SymbolNode('end'));
|
933
898
|
} else {
|
934
899
|
// explicit end
|
935
|
-
params.push(parseAddSubtract());
|
900
|
+
params.push(parseAddSubtract(state));
|
936
901
|
}
|
937
902
|
}
|
938
903
|
|
@@ -954,25 +919,25 @@ function factory(type, config, load, typed) {
|
|
954
919
|
* @return {Node} node
|
955
920
|
* @private
|
956
921
|
*/
|
957
|
-
function parseAddSubtract() {
|
922
|
+
function parseAddSubtract(state) {
|
958
923
|
var node = void 0,
|
959
924
|
operators = void 0,
|
960
925
|
name = void 0,
|
961
926
|
fn = void 0,
|
962
927
|
params = void 0;
|
963
928
|
|
964
|
-
node = parseMultiplyDivide();
|
929
|
+
node = parseMultiplyDivide(state);
|
965
930
|
|
966
931
|
operators = {
|
967
932
|
'+': 'add',
|
968
933
|
'-': 'subtract'
|
969
934
|
};
|
970
|
-
while (operators.hasOwnProperty(token)) {
|
971
|
-
name = token;
|
935
|
+
while (operators.hasOwnProperty(state.token)) {
|
936
|
+
name = state.token;
|
972
937
|
fn = operators[name];
|
973
938
|
|
974
|
-
getTokenSkipNewline();
|
975
|
-
params = [node, parseMultiplyDivide()];
|
939
|
+
getTokenSkipNewline(state);
|
940
|
+
params = [node, parseMultiplyDivide(state)];
|
976
941
|
node = new OperatorNode(name, fn, params);
|
977
942
|
}
|
978
943
|
|
@@ -984,14 +949,14 @@ function factory(type, config, load, typed) {
|
|
984
949
|
* @return {Node} node
|
985
950
|
* @private
|
986
951
|
*/
|
987
|
-
function parseMultiplyDivide() {
|
952
|
+
function parseMultiplyDivide(state) {
|
988
953
|
var node = void 0,
|
989
954
|
last = void 0,
|
990
955
|
operators = void 0,
|
991
956
|
name = void 0,
|
992
957
|
fn = void 0;
|
993
958
|
|
994
|
-
node = parseImplicitMultiplication();
|
959
|
+
node = parseImplicitMultiplication(state);
|
995
960
|
last = node;
|
996
961
|
|
997
962
|
operators = {
|
@@ -1004,14 +969,14 @@ function factory(type, config, load, typed) {
|
|
1004
969
|
};
|
1005
970
|
|
1006
971
|
while (true) {
|
1007
|
-
if (operators.hasOwnProperty(token)) {
|
972
|
+
if (operators.hasOwnProperty(state.token)) {
|
1008
973
|
// explicit operators
|
1009
|
-
name = token;
|
974
|
+
name = state.token;
|
1010
975
|
fn = operators[name];
|
1011
976
|
|
1012
|
-
getTokenSkipNewline();
|
977
|
+
getTokenSkipNewline(state);
|
1013
978
|
|
1014
|
-
last = parseImplicitMultiplication();
|
979
|
+
last = parseImplicitMultiplication(state);
|
1015
980
|
node = new OperatorNode(name, fn, [node, last]);
|
1016
981
|
} else {
|
1017
982
|
break;
|
@@ -1026,21 +991,21 @@ function factory(type, config, load, typed) {
|
|
1026
991
|
* @return {Node} node
|
1027
992
|
* @private
|
1028
993
|
*/
|
1029
|
-
function parseImplicitMultiplication() {
|
994
|
+
function parseImplicitMultiplication(state) {
|
1030
995
|
var node = void 0,
|
1031
996
|
last = void 0;
|
1032
997
|
|
1033
|
-
node = parseRule2();
|
998
|
+
node = parseRule2(state);
|
1034
999
|
last = node;
|
1035
1000
|
|
1036
1001
|
while (true) {
|
1037
|
-
if (tokenType === TOKENTYPE.SYMBOL || token === 'in' && type.isConstantNode(node) || tokenType === TOKENTYPE.NUMBER && !type.isConstantNode(last) && (!type.isOperatorNode(last) || last.op === '!') || token === '(') {
|
1002
|
+
if (state.tokenType === TOKENTYPE.SYMBOL || state.token === 'in' && type.isConstantNode(node) || state.tokenType === TOKENTYPE.NUMBER && !type.isConstantNode(last) && (!type.isOperatorNode(last) || last.op === '!') || state.token === '(') {
|
1038
1003
|
// parse implicit multiplication
|
1039
1004
|
//
|
1040
1005
|
// symbol: implicit multiplication like '2a', '(2+3)a', 'a b'
|
1041
1006
|
// number: implicit multiplication like '(2+3)2'
|
1042
1007
|
// parenthesis: implicit multiplication like '2(3+4)', '(3+4)(1+2)'
|
1043
|
-
last = parseRule2();
|
1008
|
+
last = parseRule2(state);
|
1044
1009
|
node = new OperatorNode('*', 'multiply', [node, last], true /* implicit */);
|
1045
1010
|
} else {
|
1046
1011
|
break;
|
@@ -1057,43 +1022,41 @@ function factory(type, config, load, typed) {
|
|
1057
1022
|
* @return {Node} node
|
1058
1023
|
* @private
|
1059
1024
|
*/
|
1060
|
-
function parseRule2() {
|
1061
|
-
var node =
|
1062
|
-
|
1063
|
-
|
1064
|
-
node = parseUnary();
|
1065
|
-
last = node;
|
1025
|
+
function parseRule2(state) {
|
1026
|
+
var node = parseUnary(state);
|
1027
|
+
var last = node;
|
1028
|
+
var tokenStates = [];
|
1066
1029
|
|
1067
1030
|
while (true) {
|
1068
1031
|
// Match the "number /" part of the pattern "number / number symbol"
|
1069
|
-
if (token === '/' && type.isConstantNode(last)) {
|
1032
|
+
if (state.token === '/' && type.isConstantNode(last)) {
|
1070
1033
|
// Look ahead to see if the next token is a number
|
1071
|
-
|
1072
|
-
getTokenSkipNewline();
|
1034
|
+
tokenStates.push(_extends({}, state));
|
1035
|
+
getTokenSkipNewline(state);
|
1073
1036
|
|
1074
1037
|
// Match the "number / number" part of the pattern
|
1075
|
-
if (tokenType === TOKENTYPE.NUMBER) {
|
1038
|
+
if (state.tokenType === TOKENTYPE.NUMBER) {
|
1076
1039
|
// Look ahead again
|
1077
|
-
|
1078
|
-
getTokenSkipNewline();
|
1040
|
+
tokenStates.push(_extends({}, state));
|
1041
|
+
getTokenSkipNewline(state);
|
1079
1042
|
|
1080
1043
|
// Match the "symbol" part of the pattern, or a left parenthesis
|
1081
|
-
if (tokenType === TOKENTYPE.SYMBOL || token === '(') {
|
1044
|
+
if (state.tokenType === TOKENTYPE.SYMBOL || state.token === '(') {
|
1082
1045
|
// We've matched the pattern "number / number symbol".
|
1083
1046
|
// Rewind once and build the "number / number" node; the symbol will be consumed later
|
1084
|
-
|
1085
|
-
|
1086
|
-
last = parseUnary();
|
1047
|
+
_extends(state, tokenStates.pop());
|
1048
|
+
tokenStates.pop();
|
1049
|
+
last = parseUnary(state);
|
1087
1050
|
node = new OperatorNode('/', 'divide', [node, last]);
|
1088
1051
|
} else {
|
1089
1052
|
// Not a match, so rewind
|
1090
|
-
|
1091
|
-
|
1053
|
+
tokenStates.pop();
|
1054
|
+
_extends(state, tokenStates.pop());
|
1092
1055
|
break;
|
1093
1056
|
}
|
1094
1057
|
} else {
|
1095
1058
|
// Not a match, so rewind
|
1096
|
-
|
1059
|
+
_extends(state, tokenStates.pop());
|
1097
1060
|
break;
|
1098
1061
|
}
|
1099
1062
|
} else {
|
@@ -1109,7 +1072,7 @@ function factory(type, config, load, typed) {
|
|
1109
1072
|
* @return {Node} node
|
1110
1073
|
* @private
|
1111
1074
|
*/
|
1112
|
-
function parseUnary() {
|
1075
|
+
function parseUnary(state) {
|
1113
1076
|
var name = void 0,
|
1114
1077
|
params = void 0,
|
1115
1078
|
fn = void 0;
|
@@ -1120,17 +1083,17 @@ function factory(type, config, load, typed) {
|
|
1120
1083
|
'not': 'not'
|
1121
1084
|
};
|
1122
1085
|
|
1123
|
-
if (operators.hasOwnProperty(token)) {
|
1124
|
-
fn = operators[token];
|
1125
|
-
name = token;
|
1086
|
+
if (operators.hasOwnProperty(state.token)) {
|
1087
|
+
fn = operators[state.token];
|
1088
|
+
name = state.token;
|
1126
1089
|
|
1127
|
-
getTokenSkipNewline();
|
1128
|
-
params = [parseUnary()];
|
1090
|
+
getTokenSkipNewline(state);
|
1091
|
+
params = [parseUnary(state)];
|
1129
1092
|
|
1130
1093
|
return new OperatorNode(name, fn, params);
|
1131
1094
|
}
|
1132
1095
|
|
1133
|
-
return parsePow();
|
1096
|
+
return parsePow(state);
|
1134
1097
|
}
|
1135
1098
|
|
1136
1099
|
/**
|
@@ -1139,20 +1102,20 @@ function factory(type, config, load, typed) {
|
|
1139
1102
|
* @return {Node} node
|
1140
1103
|
* @private
|
1141
1104
|
*/
|
1142
|
-
function parsePow() {
|
1105
|
+
function parsePow(state) {
|
1143
1106
|
var node = void 0,
|
1144
1107
|
name = void 0,
|
1145
1108
|
fn = void 0,
|
1146
1109
|
params = void 0;
|
1147
1110
|
|
1148
|
-
node = parseLeftHandOperators();
|
1111
|
+
node = parseLeftHandOperators(state);
|
1149
1112
|
|
1150
|
-
if (token === '^' || token === '.^') {
|
1151
|
-
name = token;
|
1113
|
+
if (state.token === '^' || state.token === '.^') {
|
1114
|
+
name = state.token;
|
1152
1115
|
fn = name === '^' ? 'pow' : 'dotPow';
|
1153
1116
|
|
1154
|
-
getTokenSkipNewline();
|
1155
|
-
params = [node, parseUnary()]; // Go back to unary, we can have '2^-3'
|
1117
|
+
getTokenSkipNewline(state);
|
1118
|
+
params = [node, parseUnary(state)]; // Go back to unary, we can have '2^-3'
|
1156
1119
|
node = new OperatorNode(name, fn, params);
|
1157
1120
|
}
|
1158
1121
|
|
@@ -1164,29 +1127,29 @@ function factory(type, config, load, typed) {
|
|
1164
1127
|
* @return {Node} node
|
1165
1128
|
* @private
|
1166
1129
|
*/
|
1167
|
-
function parseLeftHandOperators() {
|
1130
|
+
function parseLeftHandOperators(state) {
|
1168
1131
|
var node = void 0,
|
1169
1132
|
operators = void 0,
|
1170
1133
|
name = void 0,
|
1171
1134
|
fn = void 0,
|
1172
1135
|
params = void 0;
|
1173
1136
|
|
1174
|
-
node = parseCustomNodes();
|
1137
|
+
node = parseCustomNodes(state);
|
1175
1138
|
|
1176
1139
|
operators = {
|
1177
1140
|
'!': 'factorial',
|
1178
1141
|
'\'': 'ctranspose'
|
1179
1142
|
};
|
1180
1143
|
|
1181
|
-
while (operators.hasOwnProperty(token)) {
|
1182
|
-
name = token;
|
1144
|
+
while (operators.hasOwnProperty(state.token)) {
|
1145
|
+
name = state.token;
|
1183
1146
|
fn = operators[name];
|
1184
1147
|
|
1185
|
-
getToken();
|
1148
|
+
getToken(state);
|
1186
1149
|
params = [node];
|
1187
1150
|
|
1188
1151
|
node = new OperatorNode(name, fn, params);
|
1189
|
-
node = parseAccessors(node);
|
1152
|
+
node = parseAccessors(state, node);
|
1190
1153
|
}
|
1191
1154
|
|
1192
1155
|
return node;
|
@@ -1220,37 +1183,37 @@ function factory(type, config, load, typed) {
|
|
1220
1183
|
* @return {Node} node
|
1221
1184
|
* @private
|
1222
1185
|
*/
|
1223
|
-
function parseCustomNodes() {
|
1186
|
+
function parseCustomNodes(state) {
|
1224
1187
|
var params = [];
|
1225
1188
|
|
1226
|
-
if (tokenType === TOKENTYPE.SYMBOL && extraNodes.hasOwnProperty(token)) {
|
1227
|
-
var CustomNode = extraNodes[token];
|
1189
|
+
if (state.tokenType === TOKENTYPE.SYMBOL && state.extraNodes.hasOwnProperty(state.token)) {
|
1190
|
+
var CustomNode = state.extraNodes[state.token];
|
1228
1191
|
|
1229
|
-
getToken();
|
1192
|
+
getToken(state);
|
1230
1193
|
|
1231
1194
|
// parse parameters
|
1232
|
-
if (token === '(') {
|
1195
|
+
if (state.token === '(') {
|
1233
1196
|
params = [];
|
1234
1197
|
|
1235
|
-
openParams();
|
1236
|
-
getToken();
|
1198
|
+
openParams(state);
|
1199
|
+
getToken(state);
|
1237
1200
|
|
1238
|
-
if (token !== ')') {
|
1239
|
-
params.push(parseAssignment());
|
1201
|
+
if (state.token !== ')') {
|
1202
|
+
params.push(parseAssignment(state));
|
1240
1203
|
|
1241
1204
|
// parse a list with parameters
|
1242
|
-
while (token === ',') {
|
1205
|
+
while (state.token === ',') {
|
1243
1206
|
// eslint-disable-line no-unmodified-loop-condition
|
1244
|
-
getToken();
|
1245
|
-
params.push(parseAssignment());
|
1207
|
+
getToken(state);
|
1208
|
+
params.push(parseAssignment(state));
|
1246
1209
|
}
|
1247
1210
|
}
|
1248
1211
|
|
1249
|
-
if (token !== ')') {
|
1250
|
-
throw createSyntaxError('Parenthesis ) expected');
|
1212
|
+
if (state.token !== ')') {
|
1213
|
+
throw createSyntaxError(state, 'Parenthesis ) expected');
|
1251
1214
|
}
|
1252
|
-
closeParams();
|
1253
|
-
getToken();
|
1215
|
+
closeParams(state);
|
1216
|
+
getToken(state);
|
1254
1217
|
}
|
1255
1218
|
|
1256
1219
|
// create a new custom node
|
@@ -1258,7 +1221,7 @@ function factory(type, config, load, typed) {
|
|
1258
1221
|
return new CustomNode(params);
|
1259
1222
|
}
|
1260
1223
|
|
1261
|
-
return parseSymbol();
|
1224
|
+
return parseSymbol(state);
|
1262
1225
|
}
|
1263
1226
|
|
1264
1227
|
/**
|
@@ -1266,14 +1229,14 @@ function factory(type, config, load, typed) {
|
|
1266
1229
|
* @return {Node} node
|
1267
1230
|
* @private
|
1268
1231
|
*/
|
1269
|
-
function parseSymbol() {
|
1232
|
+
function parseSymbol(state) {
|
1270
1233
|
var node = void 0,
|
1271
1234
|
name = void 0;
|
1272
1235
|
|
1273
|
-
if (tokenType === TOKENTYPE.SYMBOL || tokenType === TOKENTYPE.DELIMITER && token in NAMED_DELIMITERS) {
|
1274
|
-
name = token;
|
1236
|
+
if (state.tokenType === TOKENTYPE.SYMBOL || state.tokenType === TOKENTYPE.DELIMITER && state.token in NAMED_DELIMITERS) {
|
1237
|
+
name = state.token;
|
1275
1238
|
|
1276
|
-
getToken();
|
1239
|
+
getToken(state);
|
1277
1240
|
|
1278
1241
|
if (CONSTANTS.hasOwnProperty(name)) {
|
1279
1242
|
// true, false, null, ...
|
@@ -1286,11 +1249,11 @@ function factory(type, config, load, typed) {
|
|
1286
1249
|
}
|
1287
1250
|
|
1288
1251
|
// parse function parameters and matrix index
|
1289
|
-
node = parseAccessors(node);
|
1252
|
+
node = parseAccessors(state, node);
|
1290
1253
|
return node;
|
1291
1254
|
}
|
1292
1255
|
|
1293
|
-
return parseString();
|
1256
|
+
return parseString(state);
|
1294
1257
|
}
|
1295
1258
|
|
1296
1259
|
/**
|
@@ -1306,35 +1269,35 @@ function factory(type, config, load, typed) {
|
|
1306
1269
|
* @return {Node} node
|
1307
1270
|
* @private
|
1308
1271
|
*/
|
1309
|
-
function parseAccessors(node, types) {
|
1272
|
+
function parseAccessors(state, node, types) {
|
1310
1273
|
var params = void 0;
|
1311
1274
|
|
1312
|
-
while ((token === '(' || token === '[' || token === '.') && (!types || types.indexOf(token) !== -1)) {
|
1275
|
+
while ((state.token === '(' || state.token === '[' || state.token === '.') && (!types || types.indexOf(state.token) !== -1)) {
|
1313
1276
|
// eslint-disable-line no-unmodified-loop-condition
|
1314
1277
|
params = [];
|
1315
1278
|
|
1316
|
-
if (token === '(') {
|
1279
|
+
if (state.token === '(') {
|
1317
1280
|
if (type.isSymbolNode(node) || type.isAccessorNode(node)) {
|
1318
1281
|
// function invocation like fn(2, 3) or obj.fn(2, 3)
|
1319
|
-
openParams();
|
1320
|
-
getToken();
|
1282
|
+
openParams(state);
|
1283
|
+
getToken(state);
|
1321
1284
|
|
1322
|
-
if (token !== ')') {
|
1323
|
-
params.push(parseAssignment());
|
1285
|
+
if (state.token !== ')') {
|
1286
|
+
params.push(parseAssignment(state));
|
1324
1287
|
|
1325
1288
|
// parse a list with parameters
|
1326
|
-
while (token === ',') {
|
1289
|
+
while (state.token === ',') {
|
1327
1290
|
// eslint-disable-line no-unmodified-loop-condition
|
1328
|
-
getToken();
|
1329
|
-
params.push(parseAssignment());
|
1291
|
+
getToken(state);
|
1292
|
+
params.push(parseAssignment(state));
|
1330
1293
|
}
|
1331
1294
|
}
|
1332
1295
|
|
1333
|
-
if (token !== ')') {
|
1334
|
-
throw createSyntaxError('Parenthesis ) expected');
|
1296
|
+
if (state.token !== ')') {
|
1297
|
+
throw createSyntaxError(state, 'Parenthesis ) expected');
|
1335
1298
|
}
|
1336
|
-
closeParams();
|
1337
|
-
getToken();
|
1299
|
+
closeParams(state);
|
1300
|
+
getToken(state);
|
1338
1301
|
|
1339
1302
|
node = new FunctionNode(node, params);
|
1340
1303
|
} else {
|
@@ -1343,38 +1306,38 @@ function factory(type, config, load, typed) {
|
|
1343
1306
|
// with correct precedence
|
1344
1307
|
return node;
|
1345
1308
|
}
|
1346
|
-
} else if (token === '[') {
|
1309
|
+
} else if (state.token === '[') {
|
1347
1310
|
// index notation like variable[2, 3]
|
1348
|
-
openParams();
|
1349
|
-
getToken();
|
1311
|
+
openParams(state);
|
1312
|
+
getToken(state);
|
1350
1313
|
|
1351
|
-
if (token !== ']') {
|
1352
|
-
params.push(parseAssignment());
|
1314
|
+
if (state.token !== ']') {
|
1315
|
+
params.push(parseAssignment(state));
|
1353
1316
|
|
1354
1317
|
// parse a list with parameters
|
1355
|
-
while (token === ',') {
|
1318
|
+
while (state.token === ',') {
|
1356
1319
|
// eslint-disable-line no-unmodified-loop-condition
|
1357
|
-
getToken();
|
1358
|
-
params.push(parseAssignment());
|
1320
|
+
getToken(state);
|
1321
|
+
params.push(parseAssignment(state));
|
1359
1322
|
}
|
1360
1323
|
}
|
1361
1324
|
|
1362
|
-
if (token !== ']') {
|
1363
|
-
throw createSyntaxError('Parenthesis ] expected');
|
1325
|
+
if (state.token !== ']') {
|
1326
|
+
throw createSyntaxError(state, 'Parenthesis ] expected');
|
1364
1327
|
}
|
1365
|
-
closeParams();
|
1366
|
-
getToken();
|
1328
|
+
closeParams(state);
|
1329
|
+
getToken(state);
|
1367
1330
|
|
1368
1331
|
node = new AccessorNode(node, new IndexNode(params));
|
1369
1332
|
} else {
|
1370
1333
|
// dot notation like variable.prop
|
1371
|
-
getToken();
|
1334
|
+
getToken(state);
|
1372
1335
|
|
1373
|
-
if (tokenType !== TOKENTYPE.SYMBOL) {
|
1374
|
-
throw createSyntaxError('Property name expected after dot');
|
1336
|
+
if (state.tokenType !== TOKENTYPE.SYMBOL) {
|
1337
|
+
throw createSyntaxError(state, 'Property name expected after dot');
|
1375
1338
|
}
|
1376
|
-
params.push(new ConstantNode(token));
|
1377
|
-
getToken();
|
1339
|
+
params.push(new ConstantNode(state.token));
|
1340
|
+
getToken(state);
|
1378
1341
|
|
1379
1342
|
var dotNotation = true;
|
1380
1343
|
node = new AccessorNode(node, new IndexNode(params, dotNotation));
|
@@ -1390,49 +1353,49 @@ function factory(type, config, load, typed) {
|
|
1390
1353
|
* @return {Node} node
|
1391
1354
|
* @private
|
1392
1355
|
*/
|
1393
|
-
function parseString() {
|
1356
|
+
function parseString(state) {
|
1394
1357
|
var node = void 0,
|
1395
1358
|
str = void 0;
|
1396
1359
|
|
1397
|
-
if (token === '"') {
|
1398
|
-
str = parseStringToken();
|
1360
|
+
if (state.token === '"') {
|
1361
|
+
str = parseStringToken(state);
|
1399
1362
|
|
1400
1363
|
// create constant
|
1401
1364
|
node = new ConstantNode(str);
|
1402
1365
|
|
1403
1366
|
// parse index parameters
|
1404
|
-
node = parseAccessors(node);
|
1367
|
+
node = parseAccessors(state, node);
|
1405
1368
|
|
1406
1369
|
return node;
|
1407
1370
|
}
|
1408
1371
|
|
1409
|
-
return parseMatrix();
|
1372
|
+
return parseMatrix(state);
|
1410
1373
|
}
|
1411
1374
|
|
1412
1375
|
/**
|
1413
1376
|
* Parse a string surrounded by double quotes "..."
|
1414
1377
|
* @return {string}
|
1415
1378
|
*/
|
1416
|
-
function parseStringToken() {
|
1379
|
+
function parseStringToken(state) {
|
1417
1380
|
var str = '';
|
1418
1381
|
|
1419
|
-
while (
|
1420
|
-
if (
|
1382
|
+
while (currentCharacter(state) !== '' && currentCharacter(state) !== '"') {
|
1383
|
+
if (currentCharacter(state) === '\\') {
|
1421
1384
|
// escape character, immediately process the next
|
1422
1385
|
// character to prevent stopping at a next '\"'
|
1423
|
-
str +=
|
1424
|
-
next();
|
1386
|
+
str += currentCharacter(state);
|
1387
|
+
next(state);
|
1425
1388
|
}
|
1426
1389
|
|
1427
|
-
str +=
|
1428
|
-
next();
|
1390
|
+
str += currentCharacter(state);
|
1391
|
+
next(state);
|
1429
1392
|
}
|
1430
1393
|
|
1431
|
-
getToken();
|
1432
|
-
if (token !== '"') {
|
1433
|
-
throw createSyntaxError('End of string " expected');
|
1394
|
+
getToken(state);
|
1395
|
+
if (state.token !== '"') {
|
1396
|
+
throw createSyntaxError(state, 'End of string " expected');
|
1434
1397
|
}
|
1435
|
-
getToken();
|
1398
|
+
getToken(state);
|
1436
1399
|
|
1437
1400
|
return JSON.parse('"' + str + '"'); // unescape escaped characters
|
1438
1401
|
}
|
@@ -1442,87 +1405,87 @@ function factory(type, config, load, typed) {
|
|
1442
1405
|
* @return {Node} node
|
1443
1406
|
* @private
|
1444
1407
|
*/
|
1445
|
-
function parseMatrix() {
|
1408
|
+
function parseMatrix(state) {
|
1446
1409
|
var array = void 0,
|
1447
1410
|
params = void 0,
|
1448
1411
|
rows = void 0,
|
1449
1412
|
cols = void 0;
|
1450
1413
|
|
1451
|
-
if (token === '[') {
|
1414
|
+
if (state.token === '[') {
|
1452
1415
|
// matrix [...]
|
1453
|
-
openParams();
|
1454
|
-
getToken();
|
1416
|
+
openParams(state);
|
1417
|
+
getToken(state);
|
1455
1418
|
|
1456
|
-
if (token !== ']') {
|
1419
|
+
if (state.token !== ']') {
|
1457
1420
|
// this is a non-empty matrix
|
1458
|
-
var row = parseRow();
|
1421
|
+
var row = parseRow(state);
|
1459
1422
|
|
1460
|
-
if (token === ';') {
|
1423
|
+
if (state.token === ';') {
|
1461
1424
|
// 2 dimensional array
|
1462
1425
|
rows = 1;
|
1463
1426
|
params = [row];
|
1464
1427
|
|
1465
1428
|
// the rows of the matrix are separated by dot-comma's
|
1466
|
-
while (token === ';') {
|
1429
|
+
while (state.token === ';') {
|
1467
1430
|
// eslint-disable-line no-unmodified-loop-condition
|
1468
|
-
getToken();
|
1431
|
+
getToken(state);
|
1469
1432
|
|
1470
|
-
params[rows] = parseRow();
|
1433
|
+
params[rows] = parseRow(state);
|
1471
1434
|
rows++;
|
1472
1435
|
}
|
1473
1436
|
|
1474
|
-
if (token !== ']') {
|
1475
|
-
throw createSyntaxError('End of matrix ] expected');
|
1437
|
+
if (state.token !== ']') {
|
1438
|
+
throw createSyntaxError(state, 'End of matrix ] expected');
|
1476
1439
|
}
|
1477
|
-
closeParams();
|
1478
|
-
getToken();
|
1440
|
+
closeParams(state);
|
1441
|
+
getToken(state);
|
1479
1442
|
|
1480
1443
|
// check if the number of columns matches in all rows
|
1481
1444
|
cols = params[0].items.length;
|
1482
1445
|
for (var r = 1; r < rows; r++) {
|
1483
1446
|
if (params[r].items.length !== cols) {
|
1484
|
-
throw createError('Column dimensions mismatch ' + '(' + params[r].items.length + ' !== ' + cols + ')');
|
1447
|
+
throw createError(state, 'Column dimensions mismatch ' + '(' + params[r].items.length + ' !== ' + cols + ')');
|
1485
1448
|
}
|
1486
1449
|
}
|
1487
1450
|
|
1488
1451
|
array = new ArrayNode(params);
|
1489
1452
|
} else {
|
1490
1453
|
// 1 dimensional vector
|
1491
|
-
if (token !== ']') {
|
1492
|
-
throw createSyntaxError('End of matrix ] expected');
|
1454
|
+
if (state.token !== ']') {
|
1455
|
+
throw createSyntaxError(state, 'End of matrix ] expected');
|
1493
1456
|
}
|
1494
|
-
closeParams();
|
1495
|
-
getToken();
|
1457
|
+
closeParams(state);
|
1458
|
+
getToken(state);
|
1496
1459
|
|
1497
1460
|
array = row;
|
1498
1461
|
}
|
1499
1462
|
} else {
|
1500
1463
|
// this is an empty matrix "[ ]"
|
1501
|
-
closeParams();
|
1502
|
-
getToken();
|
1464
|
+
closeParams(state);
|
1465
|
+
getToken(state);
|
1503
1466
|
array = new ArrayNode([]);
|
1504
1467
|
}
|
1505
1468
|
|
1506
|
-
return parseAccessors(array);
|
1469
|
+
return parseAccessors(state, array);
|
1507
1470
|
}
|
1508
1471
|
|
1509
|
-
return parseObject();
|
1472
|
+
return parseObject(state);
|
1510
1473
|
}
|
1511
1474
|
|
1512
1475
|
/**
|
1513
1476
|
* Parse a single comma-separated row from a matrix, like 'a, b, c'
|
1514
1477
|
* @return {ArrayNode} node
|
1515
1478
|
*/
|
1516
|
-
function parseRow() {
|
1517
|
-
var params = [parseAssignment()];
|
1479
|
+
function parseRow(state) {
|
1480
|
+
var params = [parseAssignment(state)];
|
1518
1481
|
var len = 1;
|
1519
1482
|
|
1520
|
-
while (token === ',') {
|
1483
|
+
while (state.token === ',') {
|
1521
1484
|
// eslint-disable-line no-unmodified-loop-condition
|
1522
|
-
getToken();
|
1485
|
+
getToken(state);
|
1523
1486
|
|
1524
1487
|
// parse expression
|
1525
|
-
params[len] = parseAssignment();
|
1488
|
+
params[len] = parseAssignment(state);
|
1526
1489
|
len++;
|
1527
1490
|
}
|
1528
1491
|
|
@@ -1534,50 +1497,50 @@ function factory(type, config, load, typed) {
|
|
1534
1497
|
* @return {Node} node
|
1535
1498
|
* @private
|
1536
1499
|
*/
|
1537
|
-
function parseObject() {
|
1538
|
-
if (token === '{') {
|
1500
|
+
function parseObject(state) {
|
1501
|
+
if (state.token === '{') {
|
1539
1502
|
var key = void 0;
|
1540
1503
|
|
1541
1504
|
var properties = {};
|
1542
1505
|
do {
|
1543
|
-
getToken();
|
1506
|
+
getToken(state);
|
1544
1507
|
|
1545
|
-
if (token !== '}') {
|
1508
|
+
if (state.token !== '}') {
|
1546
1509
|
// parse key
|
1547
|
-
if (token === '"') {
|
1548
|
-
key = parseStringToken();
|
1549
|
-
} else if (tokenType === TOKENTYPE.SYMBOL) {
|
1550
|
-
key = token;
|
1551
|
-
getToken();
|
1510
|
+
if (state.token === '"') {
|
1511
|
+
key = parseStringToken(state);
|
1512
|
+
} else if (state.tokenType === TOKENTYPE.SYMBOL) {
|
1513
|
+
key = state.token;
|
1514
|
+
getToken(state);
|
1552
1515
|
} else {
|
1553
|
-
throw createSyntaxError('Symbol or string expected as object key');
|
1516
|
+
throw createSyntaxError(state, 'Symbol or string expected as object key');
|
1554
1517
|
}
|
1555
1518
|
|
1556
1519
|
// parse key/value separator
|
1557
|
-
if (token !== ':') {
|
1558
|
-
throw createSyntaxError('Colon : expected after object key');
|
1520
|
+
if (state.token !== ':') {
|
1521
|
+
throw createSyntaxError(state, 'Colon : expected after object key');
|
1559
1522
|
}
|
1560
|
-
getToken();
|
1523
|
+
getToken(state);
|
1561
1524
|
|
1562
1525
|
// parse key
|
1563
|
-
properties[key] = parseAssignment();
|
1526
|
+
properties[key] = parseAssignment(state);
|
1564
1527
|
}
|
1565
|
-
} while (token === ','); // eslint-disable-line no-unmodified-loop-condition
|
1528
|
+
} while (state.token === ','); // eslint-disable-line no-unmodified-loop-condition
|
1566
1529
|
|
1567
|
-
if (token !== '}') {
|
1568
|
-
throw createSyntaxError('Comma , or bracket } expected after object value');
|
1530
|
+
if (state.token !== '}') {
|
1531
|
+
throw createSyntaxError(state, 'Comma , or bracket } expected after object value');
|
1569
1532
|
}
|
1570
|
-
getToken();
|
1533
|
+
getToken(state);
|
1571
1534
|
|
1572
1535
|
var node = new ObjectNode(properties);
|
1573
1536
|
|
1574
1537
|
// parse index parameters
|
1575
|
-
node = parseAccessors(node);
|
1538
|
+
node = parseAccessors(state, node);
|
1576
1539
|
|
1577
1540
|
return node;
|
1578
1541
|
}
|
1579
1542
|
|
1580
|
-
return parseNumber();
|
1543
|
+
return parseNumber(state);
|
1581
1544
|
}
|
1582
1545
|
|
1583
1546
|
/**
|
@@ -1585,18 +1548,18 @@ function factory(type, config, load, typed) {
|
|
1585
1548
|
* @return {Node} node
|
1586
1549
|
* @private
|
1587
1550
|
*/
|
1588
|
-
function parseNumber() {
|
1551
|
+
function parseNumber(state) {
|
1589
1552
|
var numberStr = void 0;
|
1590
1553
|
|
1591
|
-
if (tokenType === TOKENTYPE.NUMBER) {
|
1554
|
+
if (state.tokenType === TOKENTYPE.NUMBER) {
|
1592
1555
|
// this is a number
|
1593
|
-
numberStr = token;
|
1594
|
-
getToken();
|
1556
|
+
numberStr = state.token;
|
1557
|
+
getToken(state);
|
1595
1558
|
|
1596
1559
|
return new ConstantNode(numeric(numberStr, config.number));
|
1597
1560
|
}
|
1598
1561
|
|
1599
|
-
return parseParentheses();
|
1562
|
+
return parseParentheses(state);
|
1600
1563
|
}
|
1601
1564
|
|
1602
1565
|
/**
|
@@ -1604,29 +1567,29 @@ function factory(type, config, load, typed) {
|
|
1604
1567
|
* @return {Node} node
|
1605
1568
|
* @private
|
1606
1569
|
*/
|
1607
|
-
function parseParentheses() {
|
1570
|
+
function parseParentheses(state) {
|
1608
1571
|
var node = void 0;
|
1609
1572
|
|
1610
1573
|
// check if it is a parenthesized expression
|
1611
|
-
if (token === '(') {
|
1574
|
+
if (state.token === '(') {
|
1612
1575
|
// parentheses (...)
|
1613
|
-
openParams();
|
1614
|
-
getToken();
|
1576
|
+
openParams(state);
|
1577
|
+
getToken(state);
|
1615
1578
|
|
1616
|
-
node = parseAssignment(); // start again
|
1579
|
+
node = parseAssignment(state); // start again
|
1617
1580
|
|
1618
|
-
if (token !== ')') {
|
1619
|
-
throw createSyntaxError('Parenthesis ) expected');
|
1581
|
+
if (state.token !== ')') {
|
1582
|
+
throw createSyntaxError(state, 'Parenthesis ) expected');
|
1620
1583
|
}
|
1621
|
-
closeParams();
|
1622
|
-
getToken();
|
1584
|
+
closeParams(state);
|
1585
|
+
getToken(state);
|
1623
1586
|
|
1624
1587
|
node = new ParenthesisNode(node);
|
1625
|
-
node = parseAccessors(node);
|
1588
|
+
node = parseAccessors(state, node);
|
1626
1589
|
return node;
|
1627
1590
|
}
|
1628
1591
|
|
1629
|
-
return parseEnd();
|
1592
|
+
return parseEnd(state);
|
1630
1593
|
}
|
1631
1594
|
|
1632
1595
|
/**
|
@@ -1634,14 +1597,14 @@ function factory(type, config, load, typed) {
|
|
1634
1597
|
* @return {Node} res
|
1635
1598
|
* @private
|
1636
1599
|
*/
|
1637
|
-
function parseEnd() {
|
1638
|
-
if (token === '') {
|
1600
|
+
function parseEnd(state) {
|
1601
|
+
if (state.token === '') {
|
1639
1602
|
// syntax error or unexpected end of expression
|
1640
|
-
throw createSyntaxError('Unexpected end of expression');
|
1641
|
-
} else if (token === "'") {
|
1642
|
-
throw createSyntaxError('Value expected. Note: strings must be enclosed by double quotes');
|
1603
|
+
throw createSyntaxError(state, 'Unexpected end of expression');
|
1604
|
+
} else if (state.token === "'") {
|
1605
|
+
throw createSyntaxError(state, 'Value expected. Note: strings must be enclosed by double quotes');
|
1643
1606
|
} else {
|
1644
|
-
throw createSyntaxError('Value expected');
|
1607
|
+
throw createSyntaxError(state, 'Value expected');
|
1645
1608
|
}
|
1646
1609
|
}
|
1647
1610
|
|
@@ -1658,11 +1621,11 @@ function factory(type, config, load, typed) {
|
|
1658
1621
|
|
1659
1622
|
/**
|
1660
1623
|
* Shortcut for getting the current col value (one based)
|
1661
|
-
* Returns the column (position) where the last token starts
|
1624
|
+
* Returns the column (position) where the last state.token starts
|
1662
1625
|
* @private
|
1663
1626
|
*/
|
1664
|
-
function col() {
|
1665
|
-
return index - token.length + 1;
|
1627
|
+
function col(state) {
|
1628
|
+
return state.index - state.token.length + 1;
|
1666
1629
|
}
|
1667
1630
|
|
1668
1631
|
/**
|
@@ -1671,8 +1634,8 @@ function factory(type, config, load, typed) {
|
|
1671
1634
|
* @return {SyntaxError} instantiated error
|
1672
1635
|
* @private
|
1673
1636
|
*/
|
1674
|
-
function createSyntaxError(message) {
|
1675
|
-
var c = col();
|
1637
|
+
function createSyntaxError(state, message) {
|
1638
|
+
var c = col(state);
|
1676
1639
|
var error = new SyntaxError(message + ' (char ' + c + ')');
|
1677
1640
|
error['char'] = c;
|
1678
1641
|
|
@@ -1685,8 +1648,8 @@ function factory(type, config, load, typed) {
|
|
1685
1648
|
* @return {Error} instantiated error
|
1686
1649
|
* @private
|
1687
1650
|
*/
|
1688
|
-
function createError(message) {
|
1689
|
-
var c = col();
|
1651
|
+
function createError(state, message) {
|
1652
|
+
var c = col(state);
|
1690
1653
|
var error = new SyntaxError(message + ' (char ' + c + ')');
|
1691
1654
|
error['char'] = c;
|
1692
1655
|
|