nerdamer 2.0.0-rc.2 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -5
- package/dist/bundle.js +1 -1
- package/dist/bundle.js.LICENSE.txt +6 -6
- package/output/algebra/dispatch.js +1 -1
- package/output/algebra/partfrac.js +1 -1
- package/output/algebra/simplify/funcsimp.js +1 -1
- package/output/algebra/simplify/ratsimp.js +1 -1
- package/output/algebra/utils.d.ts +1 -1
- package/output/algebra/utils.js +3 -3
- package/output/api/algebra.d.ts +19 -2
- package/output/api/algebra.js +18 -2
- package/output/api/assumptions.d.ts +1 -1
- package/output/api/assumptions.js +2 -1
- package/output/api/core.d.ts +28 -7
- package/output/api/core.js +28 -2
- package/output/calculus/derivative/diff.js +1 -1
- package/output/calculus/dispatch.js +2 -2
- package/output/calculus/integrate/integrate.js +4 -4
- package/output/calculus/integrate/integrationTable.js +16 -16
- package/output/calculus/laplace/ilaplace.js +1 -1
- package/output/calculus/laplace/ilaplaceTable.js +18 -17
- package/output/calculus/laplace/laplaceTable.js +3 -2
- package/output/calculus/limit/limit.js +1 -1
- package/output/core/classes/assumption/assume.d.ts +6 -0
- package/output/core/classes/assumption/assume.js +9 -0
- package/output/core/classes/expression/CoeffObject.d.ts +1 -1
- package/output/core/classes/expression/Expression.d.ts +8 -16
- package/output/core/classes/expression/Expression.js +11 -33
- package/output/core/classes/matrix/Matrix.d.ts +2 -3
- package/output/core/classes/matrix/Matrix.js +7 -16
- package/output/core/classes/matrix/dispatch.js +1 -1
- package/output/core/classes/parser/Parser.d.ts +17 -4
- package/output/core/classes/parser/Parser.js +312 -450
- package/output/core/classes/parser/operations/functions.d.ts +3 -4
- package/output/core/classes/parser/operations/functions.js +35 -97
- package/output/core/classes/parser/operations/power.js +2 -2
- package/output/core/classes/parser/preprocess.js +14 -7
- package/output/core/classes/parser/scripting/controlFlow.js +49 -25
- package/output/core/classes/parser/scripting/deferred.d.ts +1 -1
- package/output/core/classes/parser/scripting/deferred.js +1 -1
- package/output/core/classes/parser/scripting/scope.js +38 -19
- package/output/core/classes/parser/types.d.ts +0 -5
- package/output/core/classes/parser/wrappers/IndexedReference.d.ts +4 -3
- package/output/core/classes/parser/wrappers/IndexedReference.js +8 -0
- package/output/core/classes/parser/wrappers/KeyValuePair.d.ts +2 -2
- package/output/core/classes/polynomial/Polynomial.js +1 -1
- package/output/core/classes/polynomial/SparsePolynomial.d.ts +11 -11
- package/output/core/classes/polynomial/SparsePolynomial.js +65 -65
- package/output/core/classes/vector/Vector.d.ts +2 -3
- package/output/core/classes/vector/Vector.js +6 -14
- package/output/core/common/classes/StructuredEntity.d.ts +0 -17
- package/output/core/common/classes/StructuredEntity.js +3 -64
- package/output/core/converters/BaseConverter.js +2 -1
- package/output/core/fullFunctions.js +14 -14
- package/output/core/functions/bigint/bigint.d.ts +1 -1
- package/output/core/functions/numeric.d.ts +1 -1
- package/output/core/parserFunctions.js +10 -10
- package/output/index.d.ts +29 -29
- package/output/index.js +124 -20
- package/output/math/dispatch.js +1 -1
- package/output/math/math.js +21 -21
- package/output/math/trig.js +4 -4
- package/output/solve/solve.js +1 -1
- package/package.json +34 -15
- package/dist/parser.js +0 -2
- package/dist/parser.js.LICENSE.txt +0 -7
- package/docs-data/parser-functions.json +0 -2248
- package/output/core/classes/parser/operations/comma.d.ts +0 -7
- package/output/core/classes/parser/operations/comma.js +0 -11
|
@@ -19,10 +19,10 @@ const Rational_1 = require("../rational/Rational");
|
|
|
19
19
|
const ValuesSet_1 = require("../valuesSet/ValuesSet");
|
|
20
20
|
const Vector_1 = require("../vector/Vector");
|
|
21
21
|
const constants_1 = require("./constants");
|
|
22
|
+
const controlFlowSignals_1 = require("./controlFlowSignals");
|
|
22
23
|
const functions_2 = require("./operations/functions");
|
|
23
24
|
const preprocess_1 = require("./preprocess");
|
|
24
25
|
const Token_1 = require("./Token");
|
|
25
|
-
const controlFlowSignals_1 = require("./controlFlowSignals");
|
|
26
26
|
const IndexedReference_1 = require("./wrappers/IndexedReference");
|
|
27
27
|
const KeyValuePair_1 = require("./wrappers/KeyValuePair");
|
|
28
28
|
function shouldPopOperator(stackOperator, incomingOperator) {
|
|
@@ -92,6 +92,47 @@ class ExpressionParser {
|
|
|
92
92
|
* result, so ordinary substitution does not hand out the stored object itself.
|
|
93
93
|
*/
|
|
94
94
|
KNOWN_VALUES = {};
|
|
95
|
+
/**
|
|
96
|
+
* Resolves a Dictionary index through the active parser scope.
|
|
97
|
+
*
|
|
98
|
+
* A plain variable index is resolved directly instead of reparsing its square
|
|
99
|
+
* scope. This matters for deferred scripting bodies, where LET installs the
|
|
100
|
+
* current binding in KNOWN_VALUES while excluding that name from inherited
|
|
101
|
+
* call-scoped substitutions.
|
|
102
|
+
*
|
|
103
|
+
* An unresolved symbolic index remains its own textual key, so d[x] still
|
|
104
|
+
* addresses the literal key "x". Computed indices continue through the normal
|
|
105
|
+
* parser path.
|
|
106
|
+
*/
|
|
107
|
+
extractDictionaryKey(scope, values, assertive) {
|
|
108
|
+
if (scope.length === 1 &&
|
|
109
|
+
Token_1.Token.isToken(scope[0]) &&
|
|
110
|
+
scope[0].type === Token_1.Token.VARIABLE) {
|
|
111
|
+
const token = scope[0];
|
|
112
|
+
const scopedValue = values?.[token.value];
|
|
113
|
+
if (scopedValue !== undefined) {
|
|
114
|
+
if (Expression_1.Expression.isExpression(scopedValue) ||
|
|
115
|
+
Equation_1.Equation.isEquation(scopedValue) ||
|
|
116
|
+
(0, structuredEntityUtils_1.isEnumerable)(scopedValue)) {
|
|
117
|
+
return scopedValue.text();
|
|
118
|
+
}
|
|
119
|
+
return Expression_1.Expression.create(scopedValue, undefined, true).text();
|
|
120
|
+
}
|
|
121
|
+
if (Settings_1.Settings.SUBSTITUTE && token.value in this.KNOWN_VALUES) {
|
|
122
|
+
return this.KNOWN_VALUES[token.value].text();
|
|
123
|
+
}
|
|
124
|
+
return token.value;
|
|
125
|
+
}
|
|
126
|
+
const parsed = this.parseRPN(scope, values, assertive);
|
|
127
|
+
let key = parsed;
|
|
128
|
+
if (Vector_1.Vector.isVector(parsed) && parsed.elements.length === 1) {
|
|
129
|
+
key = parsed.elements[0];
|
|
130
|
+
}
|
|
131
|
+
else if (Collection_1.Collection.isCollection(parsed) && parsed.getElements().length === 1) {
|
|
132
|
+
key = parsed.getElements()[0];
|
|
133
|
+
}
|
|
134
|
+
return key.text();
|
|
135
|
+
}
|
|
95
136
|
/**
|
|
96
137
|
* Converts an index scope to the zero-based indices used internally.
|
|
97
138
|
*
|
|
@@ -156,26 +197,38 @@ class ExpressionParser {
|
|
|
156
197
|
return retval;
|
|
157
198
|
}
|
|
158
199
|
/**
|
|
159
|
-
*
|
|
160
|
-
*
|
|
161
|
-
*
|
|
200
|
+
* Resolves or preserves symbolic bracket access after the target and indices have
|
|
201
|
+
* been parsed. Vector and Matrix arity is checked here so direct bracket parsing
|
|
202
|
+
* and reevaluation of a preserved accessor follow the same rules.
|
|
162
203
|
*/
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
204
|
+
resolveSymbolicAccess(symbolicTarget, resolvedTarget, indices) {
|
|
205
|
+
if (indices.length > 2) {
|
|
206
|
+
throw new errors_1.ParserError((0, errors_1.message)('symbolicAccessMaxIndices'));
|
|
207
|
+
}
|
|
208
|
+
if (Vector_1.Vector.isVector(resolvedTarget) && indices.length !== 1) {
|
|
209
|
+
throw new errors_1.ParserError((0, errors_1.message)('symbolicVectorIndexCount'));
|
|
210
|
+
}
|
|
211
|
+
if (Matrix_1.Matrix.isMatrix(resolvedTarget) && indices.length !== 2) {
|
|
212
|
+
if (indices.length === 1) {
|
|
213
|
+
throw new errors_1.ParserError((0, errors_1.message)('symbolicMatrixRowNonScalar'));
|
|
170
214
|
}
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
215
|
+
throw new errors_1.ParserError((0, errors_1.message)('symbolicMatrixCellIndexCount'));
|
|
216
|
+
}
|
|
217
|
+
if (Vector_1.Vector.isVector(resolvedTarget) || Matrix_1.Matrix.isMatrix(resolvedTarget)) {
|
|
218
|
+
const numericIndices = [];
|
|
219
|
+
for (const index of indices) {
|
|
220
|
+
const numericIndex = Number(index.text());
|
|
221
|
+
if (!Number.isFinite(numericIndex)) {
|
|
222
|
+
return Expression_1.Expression.toAccessor(symbolicTarget, indices);
|
|
223
|
+
}
|
|
224
|
+
numericIndices.push(numericIndex - Settings_1.Settings.INDEX_BASE);
|
|
174
225
|
}
|
|
175
|
-
|
|
176
|
-
keys.push(item.value);
|
|
226
|
+
return resolvedTarget.__get__(numericIndices);
|
|
177
227
|
}
|
|
178
|
-
|
|
228
|
+
if (Expression_1.Expression.isExpression(resolvedTarget) && resolvedTarget.isPlainVariable()) {
|
|
229
|
+
return Expression_1.Expression.toAccessor(symbolicTarget, indices);
|
|
230
|
+
}
|
|
231
|
+
throw new errors_1.ParserError((0, errors_1.message)('symbolicAccessTargetType'));
|
|
179
232
|
}
|
|
180
233
|
/** Creates another spelling for an existing operator without changing its action. */
|
|
181
234
|
aliasOperator(symbol, alias) {
|
|
@@ -385,8 +438,9 @@ class ExpressionParser {
|
|
|
385
438
|
retval = this.parseRPN(rpn, values);
|
|
386
439
|
}
|
|
387
440
|
catch (error) {
|
|
388
|
-
if (controlFlowSignals_1.NullSignal.isNullSignal(error))
|
|
441
|
+
if (controlFlowSignals_1.NullSignal.isNullSignal(error)) {
|
|
389
442
|
throw new errors_1.NullError((0, errors_1.message)('nullValue'));
|
|
443
|
+
}
|
|
390
444
|
throw error;
|
|
391
445
|
}
|
|
392
446
|
return retval;
|
|
@@ -419,15 +473,10 @@ class ExpressionParser {
|
|
|
419
473
|
// The output stack
|
|
420
474
|
const output = [];
|
|
421
475
|
const operators = this.operators;
|
|
422
|
-
// TODO: this needs to be applied at the operation level. It's somewhat clunky to apply this here.
|
|
423
|
-
// const precision = this.getPrecision();
|
|
424
476
|
function addToOutput(expression) {
|
|
425
477
|
if (expression === undefined) {
|
|
426
478
|
throw new errors_1.ParserError((0, errors_1.message)('malformedExpression'));
|
|
427
479
|
}
|
|
428
|
-
// Keep track of the precision used to make this calculation
|
|
429
|
-
// TODO: this needs to be applied at the operation level. It's somewhat clunky to apply this here.
|
|
430
|
-
// expression.precision = expression.precision || precision;
|
|
431
480
|
output.push(expression);
|
|
432
481
|
}
|
|
433
482
|
function resolveStackValue(value) {
|
|
@@ -446,6 +495,16 @@ class ExpressionParser {
|
|
|
446
495
|
}
|
|
447
496
|
return resolved;
|
|
448
497
|
}
|
|
498
|
+
const parseScope = (scope, scopeValues, scopeAssertive, substitute) => {
|
|
499
|
+
const parse = () => this.parseRPN(scope, scopeValues, scopeAssertive);
|
|
500
|
+
return typeof substitute === 'boolean'
|
|
501
|
+
? (0, Settings_1.scopedBlock)('SUBSTITUTE', substitute, parse)
|
|
502
|
+
: parse();
|
|
503
|
+
};
|
|
504
|
+
const parseArguments = (scope, argumentValues, functionAssertive, substitute) => {
|
|
505
|
+
const parsed = parseScope(scope, argumentValues, functionAssertive, substitute);
|
|
506
|
+
return Collection_1.Collection.isCollection(parsed) ? parsed.getElements() : [parsed];
|
|
507
|
+
};
|
|
449
508
|
const createDeferredArgument = (getArgumentRPN, inheritedValues, functionAssertive) => {
|
|
450
509
|
let argumentRPN;
|
|
451
510
|
return (options) => {
|
|
@@ -458,468 +517,271 @@ class ExpressionParser {
|
|
|
458
517
|
delete argumentValues[name];
|
|
459
518
|
}
|
|
460
519
|
}
|
|
461
|
-
|
|
462
|
-
if (typeof options?.substitute === 'boolean') {
|
|
463
|
-
retval = (0, Settings_1.scopedBlock)('SUBSTITUTE', options.substitute, () => {
|
|
464
|
-
return this.parseRPN(rpn, argumentValues, functionAssertive);
|
|
465
|
-
});
|
|
466
|
-
}
|
|
467
|
-
else {
|
|
468
|
-
retval = this.parseRPN(rpn, argumentValues, functionAssertive);
|
|
469
|
-
}
|
|
470
|
-
return retval;
|
|
520
|
+
return parseScope(rpn, argumentValues, functionAssertive, options?.substitute);
|
|
471
521
|
};
|
|
472
522
|
};
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
else if (token.deferLHSResolution) {
|
|
483
|
-
// Left-hand targets are parsed without substitution so assignment can update a
|
|
484
|
-
// variable that already has a known value.
|
|
485
|
-
const parsed = (0, Settings_1.scopedBlock)('SUBSTITUTE', false, () => {
|
|
486
|
-
return this.parseRPN(token, undefined, assertive);
|
|
487
|
-
});
|
|
488
|
-
addToOutput(parsed);
|
|
523
|
+
const handleFunction = (token, argsScope) => {
|
|
524
|
+
if (token.value === constants_1.SYMBOLIC_ACCESSOR) {
|
|
525
|
+
const preservedArgs = parseArguments(argsScope, undefined, assertive, false);
|
|
526
|
+
const resolvedArgs = parseArguments(argsScope, values, assertive);
|
|
527
|
+
if (preservedArgs.length < 2 ||
|
|
528
|
+
preservedArgs.length !== resolvedArgs.length ||
|
|
529
|
+
!Expression_1.Expression.isExpression(preservedArgs[0]) ||
|
|
530
|
+
!preservedArgs[0].isPlainVariable()) {
|
|
531
|
+
throw new errors_1.ParserError((0, errors_1.message)('parserMalformedSymbolicAccessor'));
|
|
489
532
|
}
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
if ((0, structuredEntityUtils_1.isEnumerable)(lastOutput) ||
|
|
497
|
-
IndexedReference_1.IndexedReference.isIndexedReference(lastOutput)) {
|
|
498
|
-
// Indexing: target[indices]
|
|
499
|
-
const resolvedTarget = IndexedReference_1.IndexedReference.isIndexedReference(lastOutput)
|
|
500
|
-
? lastOutput.resolve()
|
|
501
|
-
: lastOutput;
|
|
502
|
-
const previousRPN = rpn[i - 1];
|
|
503
|
-
let targetName;
|
|
504
|
-
if (Token_1.Token.isToken(previousRPN) &&
|
|
505
|
-
previousRPN.type === Token_1.Token.VARIABLE &&
|
|
506
|
-
!(values && previousRPN.value in values) &&
|
|
507
|
-
previousRPN.value in this.KNOWN_VALUES) {
|
|
508
|
-
targetName = previousRPN.value;
|
|
509
|
-
}
|
|
510
|
-
let indices;
|
|
511
|
-
if (Dictionary_1.Dictionary.isDictionary(resolvedTarget)) {
|
|
512
|
-
// Dictionary indexing: extract string keys from the index scope.
|
|
513
|
-
// d[x] → key "x"
|
|
514
|
-
const keys = this.extractStringKeys(token);
|
|
515
|
-
indices = keys[0];
|
|
516
|
-
}
|
|
517
|
-
else {
|
|
518
|
-
// Numeric indexing for Vector, Matrix, etc.
|
|
519
|
-
indices = this.extractIndices(token, values, assertive);
|
|
520
|
-
}
|
|
521
|
-
output.pop();
|
|
522
|
-
if (Array.isArray(indices) &&
|
|
523
|
-
indices.length > 0 &&
|
|
524
|
-
Expression_1.Expression.isExpression(indices[0])) {
|
|
525
|
-
const symbolicIndices = indices;
|
|
526
|
-
let symbolicTarget;
|
|
527
|
-
if ((Vector_1.Vector.isVector(resolvedTarget) || Matrix_1.Matrix.isMatrix(resolvedTarget)) &&
|
|
528
|
-
resolvedTarget.symbolicTarget) {
|
|
529
|
-
symbolicTarget = resolvedTarget.symbolicTarget;
|
|
530
|
-
}
|
|
531
|
-
else if (Token_1.Token.isToken(previousRPN) &&
|
|
532
|
-
previousRPN.type === Token_1.Token.VARIABLE) {
|
|
533
|
-
symbolicTarget = Expression_1.Expression.Variable(previousRPN.value);
|
|
534
|
-
}
|
|
535
|
-
if (!symbolicTarget ||
|
|
536
|
-
!(Vector_1.Vector.isVector(resolvedTarget) || Matrix_1.Matrix.isMatrix(resolvedTarget))) {
|
|
537
|
-
throw new errors_1.ParserError((0, errors_1.message)('symbolicAccessNamedTargetRequired'));
|
|
538
|
-
}
|
|
539
|
-
if (Vector_1.Vector.isVector(resolvedTarget) && symbolicIndices.length !== 1) {
|
|
540
|
-
throw new errors_1.ParserError((0, errors_1.message)('symbolicVectorIndexCount'));
|
|
541
|
-
}
|
|
542
|
-
if (Matrix_1.Matrix.isMatrix(resolvedTarget) && symbolicIndices.length !== 2) {
|
|
543
|
-
if (symbolicIndices.length === 1) {
|
|
544
|
-
throw new errors_1.ParserError((0, errors_1.message)('symbolicMatrixRowNonScalar'));
|
|
545
|
-
}
|
|
546
|
-
throw new errors_1.ParserError((0, errors_1.message)('symbolicMatrixCellIndexCount'));
|
|
547
|
-
}
|
|
548
|
-
addToOutput(resolvedTarget.withSymbolicAccessor(symbolicTarget, symbolicIndices));
|
|
549
|
-
}
|
|
550
|
-
else {
|
|
551
|
-
addToOutput(new IndexedReference_1.IndexedReference(resolvedTarget, indices, targetName));
|
|
552
|
-
}
|
|
533
|
+
const symbolicTarget = preservedArgs[0];
|
|
534
|
+
const resolvedTarget = resolvedArgs[0];
|
|
535
|
+
const symbolicIndices = [];
|
|
536
|
+
for (let j = 1; j < preservedArgs.length; j++) {
|
|
537
|
+
if (!Expression_1.Expression.isExpression(preservedArgs[j])) {
|
|
538
|
+
throw new errors_1.ParserError((0, errors_1.message)('parserMalformedSymbolicAccessorIndex'));
|
|
553
539
|
}
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
// structured carrier; concrete bracket adjacency keeps its legacy
|
|
558
|
-
// implicit-multiplication behavior.
|
|
559
|
-
const indices = this.extractIndices(token, values, assertive);
|
|
560
|
-
if (indices.length > 0 &&
|
|
561
|
-
Expression_1.Expression.isExpression(indices[0])) {
|
|
562
|
-
const symbolicIndices = indices;
|
|
563
|
-
if (symbolicIndices.length > 2) {
|
|
564
|
-
throw new errors_1.ParserError((0, errors_1.message)('symbolicAccessMaxIndices'));
|
|
565
|
-
}
|
|
566
|
-
const carrier = symbolicIndices.length === 2 ? new Matrix_1.Matrix([]) : new Vector_1.Vector();
|
|
567
|
-
output.pop();
|
|
568
|
-
addToOutput(carrier.withSymbolicAccessor(lastOutput, symbolicIndices));
|
|
569
|
-
}
|
|
570
|
-
else if (Settings_1.Settings.ALLOW_IMPLICIT_MULTIPLICATION) {
|
|
571
|
-
const indexExpr = this.parseRPN(token, values, assertive);
|
|
572
|
-
const mulFn = functions_2._['multiply'];
|
|
573
|
-
const a = resolveStackValue(output.pop());
|
|
574
|
-
addToOutput(mulFn(a, indexExpr));
|
|
575
|
-
}
|
|
576
|
-
else {
|
|
577
|
-
const parsed = this.parseRPN(token, values, assertive);
|
|
578
|
-
addToOutput(parsed);
|
|
579
|
-
}
|
|
580
|
-
}
|
|
581
|
-
else if (token.implicitMultiply && Settings_1.Settings.ALLOW_IMPLICIT_MULTIPLICATION) {
|
|
582
|
-
// Implicit multiplication: x[1,2] where x is not a structured entity.
|
|
583
|
-
const indexExpr = this.parseRPN(token, values, assertive);
|
|
584
|
-
const mulFn = functions_2._['multiply'];
|
|
585
|
-
const a = resolveStackValue(output.pop());
|
|
586
|
-
addToOutput(mulFn(a, indexExpr));
|
|
587
|
-
}
|
|
588
|
-
else {
|
|
589
|
-
const parsed = this.parseRPN(token, values, assertive);
|
|
590
|
-
addToOutput(parsed);
|
|
540
|
+
const resolvedIndex = resolvedArgs[j];
|
|
541
|
+
if (!Expression_1.Expression.isExpression(resolvedIndex)) {
|
|
542
|
+
throw new errors_1.ParserError((0, errors_1.message)('symbolicAccessIndexScalar'));
|
|
591
543
|
}
|
|
544
|
+
symbolicIndices.push(resolvedIndex);
|
|
592
545
|
}
|
|
593
|
-
|
|
594
|
-
// Non-square scope or inside parentheses or nothing on output — parse normally
|
|
595
|
-
const parsed = this.parseRPN(token, values, assertive);
|
|
596
|
-
addToOutput(parsed);
|
|
597
|
-
}
|
|
546
|
+
return this.resolveSymbolicAccess(symbolicTarget, resolvedTarget, symbolicIndices);
|
|
598
547
|
}
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
if (operator.action === 'comma') {
|
|
610
|
-
const a = output.pop();
|
|
611
|
-
const fn = functions_2._[operator.action];
|
|
612
|
-
result = fn(a, b);
|
|
613
|
-
}
|
|
614
|
-
// If it's a postfix operator then the operation occurs only on the previous element
|
|
615
|
-
else if (operator.isPostfix) {
|
|
616
|
-
b = resolveStackValue(b);
|
|
617
|
-
b = Expression_1.Expression.fromSymbolicAccess(b) ?? b;
|
|
618
|
-
const fn = functions_2._[operator.action];
|
|
619
|
-
result = fn(b);
|
|
620
|
-
}
|
|
621
|
-
else {
|
|
622
|
-
let a = output.pop();
|
|
623
|
-
const previousRPN = rpn[i - 1];
|
|
624
|
-
const possibleFunction = rpn[i - 2];
|
|
625
|
-
if (token.position === -1 &&
|
|
626
|
-
operator.action === 'times' &&
|
|
627
|
-
Scope_1.Scope.isScope(previousRPN) &&
|
|
628
|
-
Collection_1.Collection.isCollection(b) &&
|
|
629
|
-
Token_1.Token.isToken(possibleFunction) &&
|
|
630
|
-
possibleFunction.type === Token_1.Token.VARIABLE &&
|
|
631
|
-
Expression_1.Expression.isExpression(a) &&
|
|
632
|
-
a.isPlainVariable()) {
|
|
633
|
-
throw new errors_1.ParserError((0, errors_1.message)('unsupportedFunction', { function: possibleFunction.value }));
|
|
634
|
-
}
|
|
635
|
-
// Handle indexed assignment before ordinary left-hand resolution so the
|
|
636
|
-
// reference itself remains available to the setter.
|
|
637
|
-
if (operator.action === 'assign' &&
|
|
638
|
-
IndexedReference_1.IndexedReference.isIndexedReference(a)) {
|
|
639
|
-
let assignValue = true;
|
|
640
|
-
try {
|
|
641
|
-
b = typeof b === 'function' ? b() : resolveStackValue(b);
|
|
642
|
-
}
|
|
643
|
-
catch (error) {
|
|
644
|
-
if (controlFlowSignals_1.NullSignal.isNullSignal(error)) {
|
|
645
|
-
assignValue = false;
|
|
646
|
-
}
|
|
647
|
-
else {
|
|
648
|
-
throw error;
|
|
649
|
-
}
|
|
650
|
-
}
|
|
651
|
-
if (assignValue) {
|
|
652
|
-
if (typeof a.indices === 'string') {
|
|
653
|
-
a.target.__set__(a.indices, b);
|
|
654
|
-
}
|
|
655
|
-
else {
|
|
656
|
-
a.target.__set__(a.indices, b);
|
|
657
|
-
}
|
|
658
|
-
if (a.targetName) {
|
|
659
|
-
this.KNOWN_VALUES[a.targetName] = a.target;
|
|
660
|
-
}
|
|
661
|
-
}
|
|
662
|
-
result = a.target;
|
|
663
|
-
}
|
|
664
|
-
else if (operator.deferRHSResolution) {
|
|
665
|
-
a = resolveStackValue(a);
|
|
666
|
-
if (typeof b !== 'function') {
|
|
667
|
-
throw new errors_1.ParserError((0, errors_1.message)('malformedExpression'));
|
|
668
|
-
}
|
|
669
|
-
const fn = functions_2._[operator.action];
|
|
670
|
-
result = fn(a, b);
|
|
671
|
-
}
|
|
672
|
-
else if (operator.deferLHSResolution) {
|
|
673
|
-
a = resolveStackValue(a);
|
|
674
|
-
b = resolveStackValue(b);
|
|
675
|
-
const fn = functions_2._[operator.action];
|
|
676
|
-
result = fn(a, b);
|
|
677
|
-
}
|
|
678
|
-
else if (operator.action === 'mapTo') {
|
|
679
|
-
// '=>' operator: create a key-value pair for Dictionary construction
|
|
680
|
-
// 'a' is the key (should be a variable name), 'b' is the value
|
|
681
|
-
a = resolveStackValue(a);
|
|
682
|
-
b = resolveStackValue(b);
|
|
683
|
-
const key = Expression_1.Expression.isExpression(a) ? a.text() : String(a.text());
|
|
684
|
-
result = new KeyValuePair_1.KeyValuePair(key, b);
|
|
548
|
+
if (dispatch_1.mathFunctionRegistry[token.value]?.deferArguments) {
|
|
549
|
+
const argumentScopes = [];
|
|
550
|
+
if (argsScope.length > 0) {
|
|
551
|
+
let argumentScope = new Scope_1.Scope(argsScope.type, argsScope.column);
|
|
552
|
+
for (const argumentToken of argsScope) {
|
|
553
|
+
if (Token_1.Token.isToken(argumentToken) &&
|
|
554
|
+
argumentToken.type === Token_1.Token.OPERATOR &&
|
|
555
|
+
argumentToken.value === constants_1.COMMA) {
|
|
556
|
+
argumentScopes.push(argumentScope);
|
|
557
|
+
argumentScope = new Scope_1.Scope(argsScope.type, argsScope.column);
|
|
685
558
|
}
|
|
686
559
|
else {
|
|
687
|
-
|
|
688
|
-
// access before ordinary scalar/aggregate operator routing.
|
|
689
|
-
a = resolveStackValue(a);
|
|
690
|
-
b = resolveStackValue(b);
|
|
691
|
-
a = Expression_1.Expression.fromSymbolicAccess(a) ?? a;
|
|
692
|
-
b = Expression_1.Expression.fromSymbolicAccess(b) ?? b;
|
|
693
|
-
const action = assertive && operator.assertiveAction
|
|
694
|
-
? operator.assertiveAction
|
|
695
|
-
: operator.action;
|
|
696
|
-
const fn = functions_2._[action];
|
|
697
|
-
if (a.isEnumerable ||
|
|
698
|
-
b.isEnumerable ||
|
|
699
|
-
Equation_1.Equation.isEquation(a) ||
|
|
700
|
-
Equation_1.Equation.isEquation(b)) {
|
|
701
|
-
// Delegate this to the router who can handle more
|
|
702
|
-
result = (0, functions_2.route)(a, b, operator.action);
|
|
703
|
-
}
|
|
704
|
-
else {
|
|
705
|
-
result = fn(a, b);
|
|
706
|
-
}
|
|
560
|
+
argumentScope.push(argumentToken);
|
|
707
561
|
}
|
|
708
562
|
}
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
563
|
+
argumentScopes.push(argumentScope);
|
|
564
|
+
}
|
|
565
|
+
const normalizeArguments = dispatch_1.mathFunctionRegistry[token.value].normalizeDeferredArguments;
|
|
566
|
+
const normalizedScopes = normalizeArguments
|
|
567
|
+
? normalizeArguments(argumentScopes)
|
|
568
|
+
: argumentScopes;
|
|
569
|
+
const functionAssertive = common_1.ASSERTIVE_FUNCTIONS.includes(token.value);
|
|
570
|
+
const args = normalizedScopes.map(argumentScope => createDeferredArgument(() => this.toRPN(argumentScope), values, functionAssertive));
|
|
571
|
+
return (0, functions_2.callFunction)(token.value, args);
|
|
572
|
+
}
|
|
573
|
+
if (argsScope.deferLHSResolution) {
|
|
574
|
+
const args = argsScope.length > 0
|
|
575
|
+
? [...parseArguments(argsScope, undefined, assertive, false)]
|
|
576
|
+
: [];
|
|
577
|
+
args.push(Expression_1.Expression.Variable(token.value));
|
|
578
|
+
return new Collection_1.Collection(args);
|
|
579
|
+
}
|
|
580
|
+
return (0, functions_2.callFunction)(token.value, parseArguments(argsScope, values, common_1.ASSERTIVE_FUNCTIONS.includes(token.value)));
|
|
581
|
+
};
|
|
582
|
+
const handleOperator = (token, index) => {
|
|
583
|
+
const operator = token.resolvedOperator ?? this.operators[token.value];
|
|
584
|
+
let b = output.pop();
|
|
585
|
+
if (operator.action === 'comma') {
|
|
586
|
+
addToOutput(b);
|
|
587
|
+
return undefined;
|
|
588
|
+
}
|
|
589
|
+
if (operator.isPostfix) {
|
|
590
|
+
b = resolveStackValue(b);
|
|
591
|
+
const fn = functions_2._[operator.action];
|
|
592
|
+
return fn(b);
|
|
593
|
+
}
|
|
594
|
+
let a = output.pop();
|
|
595
|
+
const previousRPN = rpn[index - 1];
|
|
596
|
+
const possibleFunction = rpn[index - 2];
|
|
597
|
+
if (token.position === -1 &&
|
|
598
|
+
operator.action === 'times' &&
|
|
599
|
+
Scope_1.Scope.isScope(previousRPN) &&
|
|
600
|
+
Collection_1.Collection.isCollection(b) &&
|
|
601
|
+
Token_1.Token.isToken(possibleFunction) &&
|
|
602
|
+
possibleFunction.type === Token_1.Token.VARIABLE &&
|
|
603
|
+
Expression_1.Expression.isExpression(a) &&
|
|
604
|
+
a.isPlainVariable()) {
|
|
605
|
+
throw new errors_1.ParserError((0, errors_1.message)('unsupportedFunction', { function: possibleFunction.value }));
|
|
606
|
+
}
|
|
607
|
+
if (operator.action === 'assign' && IndexedReference_1.IndexedReference.isIndexedReference(a)) {
|
|
608
|
+
let assignValue = true;
|
|
609
|
+
try {
|
|
610
|
+
b = typeof b === 'function' ? b() : resolveStackValue(b);
|
|
611
|
+
}
|
|
612
|
+
catch (error) {
|
|
613
|
+
if (controlFlowSignals_1.NullSignal.isNullSignal(error)) {
|
|
614
|
+
assignValue = false;
|
|
712
615
|
}
|
|
713
616
|
else {
|
|
714
|
-
|
|
617
|
+
throw error;
|
|
715
618
|
}
|
|
716
619
|
}
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
// Preserve the original target and index expressions while resolving the
|
|
722
|
-
// same RPN scope under the active values. This avoids serializing either
|
|
723
|
-
// side back through tokenize/toRPN just to apply substitutions.
|
|
724
|
-
const preserved = (0, Settings_1.scopedBlock)('SUBSTITUTE', false, () => {
|
|
725
|
-
return this.parseRPN(argsScope, undefined, assertive);
|
|
726
|
-
});
|
|
727
|
-
const preservedArgs = Collection_1.Collection.isCollection(preserved)
|
|
728
|
-
? preserved.getElements()
|
|
729
|
-
: [preserved];
|
|
730
|
-
const resolved = this.parseRPN(argsScope, values, assertive);
|
|
731
|
-
const resolvedArgs = Collection_1.Collection.isCollection(resolved)
|
|
732
|
-
? resolved.getElements()
|
|
733
|
-
: [resolved];
|
|
734
|
-
if (preservedArgs.length < 2 ||
|
|
735
|
-
preservedArgs.length !== resolvedArgs.length ||
|
|
736
|
-
!Expression_1.Expression.isExpression(preservedArgs[0]) ||
|
|
737
|
-
!preservedArgs[0].isPlainVariable()) {
|
|
738
|
-
throw new errors_1.ParserError((0, errors_1.message)('parserMalformedSymbolicAccessor'));
|
|
739
|
-
}
|
|
740
|
-
const symbolicTarget = preservedArgs[0];
|
|
741
|
-
const resolvedTarget = resolvedArgs[0];
|
|
742
|
-
const symbolicIndices = [];
|
|
743
|
-
const numericIndices = [];
|
|
744
|
-
let allResolved = true;
|
|
745
|
-
for (let j = 1; j < preservedArgs.length; j++) {
|
|
746
|
-
const preservedIndex = preservedArgs[j];
|
|
747
|
-
const resolvedIndex = resolvedArgs[j];
|
|
748
|
-
if (!Expression_1.Expression.isExpression(preservedIndex)) {
|
|
749
|
-
throw new errors_1.ParserError((0, errors_1.message)('parserMalformedSymbolicAccessorIndex'));
|
|
750
|
-
}
|
|
751
|
-
if (!Expression_1.Expression.isExpression(resolvedIndex)) {
|
|
752
|
-
throw new errors_1.ParserError((0, errors_1.message)('symbolicAccessIndexScalar'));
|
|
753
|
-
}
|
|
754
|
-
symbolicIndices.push(resolvedIndex);
|
|
755
|
-
const numericIndex = Number(resolvedIndex.text());
|
|
756
|
-
if (Number.isFinite(numericIndex)) {
|
|
757
|
-
numericIndices.push(numericIndex - Settings_1.Settings.INDEX_BASE);
|
|
758
|
-
}
|
|
759
|
-
else {
|
|
760
|
-
allResolved = false;
|
|
761
|
-
}
|
|
762
|
-
}
|
|
763
|
-
if (symbolicIndices.length > 2) {
|
|
764
|
-
throw new errors_1.ParserError((0, errors_1.message)('symbolicAccessMaxIndices'));
|
|
765
|
-
}
|
|
766
|
-
if (Vector_1.Vector.isVector(resolvedTarget) && symbolicIndices.length !== 1) {
|
|
767
|
-
throw new errors_1.ParserError((0, errors_1.message)('symbolicVectorIndexCount'));
|
|
768
|
-
}
|
|
769
|
-
if (Matrix_1.Matrix.isMatrix(resolvedTarget) && symbolicIndices.length !== 2) {
|
|
770
|
-
if (symbolicIndices.length === 1) {
|
|
771
|
-
throw new errors_1.ParserError((0, errors_1.message)('symbolicMatrixRowNonScalar'));
|
|
772
|
-
}
|
|
773
|
-
throw new errors_1.ParserError((0, errors_1.message)('symbolicMatrixCellIndexCount'));
|
|
774
|
-
}
|
|
775
|
-
let result;
|
|
776
|
-
if ((Vector_1.Vector.isVector(resolvedTarget) || Matrix_1.Matrix.isMatrix(resolvedTarget)) && allResolved) {
|
|
777
|
-
result = resolvedTarget.__get__(numericIndices);
|
|
778
|
-
}
|
|
779
|
-
else {
|
|
780
|
-
let carrier;
|
|
781
|
-
if (Vector_1.Vector.isVector(resolvedTarget) || Matrix_1.Matrix.isMatrix(resolvedTarget)) {
|
|
782
|
-
carrier = resolvedTarget;
|
|
783
|
-
}
|
|
784
|
-
else if (Expression_1.Expression.isExpression(resolvedTarget) &&
|
|
785
|
-
resolvedTarget.isPlainVariable()) {
|
|
786
|
-
carrier = symbolicIndices.length === 2 ? new Matrix_1.Matrix([]) : new Vector_1.Vector();
|
|
787
|
-
}
|
|
788
|
-
else {
|
|
789
|
-
throw new errors_1.ParserError((0, errors_1.message)('symbolicAccessTargetType'));
|
|
790
|
-
}
|
|
791
|
-
result = carrier.withSymbolicAccessor(symbolicTarget, symbolicIndices);
|
|
792
|
-
}
|
|
793
|
-
addToOutput(result);
|
|
620
|
+
if (assignValue) {
|
|
621
|
+
a.set(b);
|
|
622
|
+
if (a.targetName) {
|
|
623
|
+
this.KNOWN_VALUES[a.targetName] = a.target;
|
|
794
624
|
}
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
625
|
+
}
|
|
626
|
+
return a.target;
|
|
627
|
+
}
|
|
628
|
+
if (operator.deferRHSResolution) {
|
|
629
|
+
a = resolveStackValue(a);
|
|
630
|
+
if (typeof b !== 'function') {
|
|
631
|
+
throw new errors_1.ParserError((0, errors_1.message)('malformedExpression'));
|
|
632
|
+
}
|
|
633
|
+
const fn = functions_2._[operator.action];
|
|
634
|
+
return fn(a, b);
|
|
635
|
+
}
|
|
636
|
+
a = resolveStackValue(a);
|
|
637
|
+
b = resolveStackValue(b);
|
|
638
|
+
if (operator.action === 'mapTo') {
|
|
639
|
+
return new KeyValuePair_1.KeyValuePair(a.text(), b);
|
|
640
|
+
}
|
|
641
|
+
const action = assertive && operator.assertiveAction
|
|
642
|
+
? operator.assertiveAction
|
|
643
|
+
: operator.action;
|
|
644
|
+
const fn = functions_2._[action];
|
|
645
|
+
if (a.isEnumerable ||
|
|
646
|
+
b.isEnumerable ||
|
|
647
|
+
Equation_1.Equation.isEquation(a) ||
|
|
648
|
+
Equation_1.Equation.isEquation(b)) {
|
|
649
|
+
return (0, functions_2.route)(a, b, operator.action);
|
|
650
|
+
}
|
|
651
|
+
return fn(a, b);
|
|
652
|
+
};
|
|
653
|
+
const handleScope = (token, index) => {
|
|
654
|
+
const lastOutput = output[output.length - 1];
|
|
655
|
+
if (token.deferRHSResolution) {
|
|
656
|
+
addToOutput(createDeferredArgument(() => token, values, assertive));
|
|
657
|
+
return;
|
|
658
|
+
}
|
|
659
|
+
if (token.type === 'square' && token.implicitMultiply && lastOutput) {
|
|
660
|
+
if ((0, structuredEntityUtils_1.isEnumerable)(lastOutput) ||
|
|
661
|
+
IndexedReference_1.IndexedReference.isIndexedReference(lastOutput)) {
|
|
662
|
+
const resolvedTarget = IndexedReference_1.IndexedReference.isIndexedReference(lastOutput)
|
|
663
|
+
? lastOutput.resolve()
|
|
664
|
+
: lastOutput;
|
|
665
|
+
const previousRPN = rpn[index - 1];
|
|
666
|
+
let targetName;
|
|
667
|
+
if (Token_1.Token.isToken(previousRPN) &&
|
|
668
|
+
previousRPN.type === Token_1.Token.VARIABLE &&
|
|
669
|
+
!(values && previousRPN.value in values) &&
|
|
670
|
+
previousRPN.value in this.KNOWN_VALUES) {
|
|
671
|
+
targetName = previousRPN.value;
|
|
824
672
|
}
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
673
|
+
const indices = Dictionary_1.Dictionary.isDictionary(resolvedTarget)
|
|
674
|
+
? this.extractDictionaryKey(token, values, assertive)
|
|
675
|
+
: this.extractIndices(token, values, assertive);
|
|
676
|
+
output.pop();
|
|
677
|
+
if (Array.isArray(indices) &&
|
|
678
|
+
indices.length > 0 &&
|
|
679
|
+
Expression_1.Expression.isExpression(indices[0])) {
|
|
680
|
+
const symbolicIndices = indices;
|
|
681
|
+
if (!Token_1.Token.isToken(previousRPN) ||
|
|
682
|
+
previousRPN.type !== Token_1.Token.VARIABLE ||
|
|
683
|
+
!(Vector_1.Vector.isVector(resolvedTarget) || Matrix_1.Matrix.isMatrix(resolvedTarget))) {
|
|
684
|
+
throw new errors_1.ParserError((0, errors_1.message)('symbolicAccessNamedTargetRequired'));
|
|
832
685
|
}
|
|
833
|
-
|
|
834
|
-
// action is responsible for interpreting that structure.
|
|
835
|
-
args.push(Expression_1.Expression.Variable(token.value));
|
|
836
|
-
addToOutput(new Collection_1.Collection(args));
|
|
686
|
+
addToOutput(this.resolveSymbolicAccess(Expression_1.Expression.Variable(previousRPN.value), resolvedTarget, symbolicIndices));
|
|
837
687
|
}
|
|
838
688
|
else {
|
|
839
|
-
|
|
840
|
-
// know so it can modify it's behavior accordingly. This would be in the case of functions like assume where
|
|
841
|
-
// the operators assert a value rather than compare it.
|
|
842
|
-
const parsed = this.parseRPN(argsScope, values, common_1.ASSERTIVE_FUNCTIONS.includes(token.value));
|
|
843
|
-
const args = Collection_1.Collection.isCollection(parsed) ? parsed.getElements() : [parsed];
|
|
844
|
-
const result = (0, functions_2.callFunction)(token.value, args);
|
|
845
|
-
addToOutput(result);
|
|
689
|
+
addToOutput(new IndexedReference_1.IndexedReference(resolvedTarget, indices, targetName));
|
|
846
690
|
}
|
|
691
|
+
return;
|
|
847
692
|
}
|
|
848
|
-
|
|
849
|
-
const
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
693
|
+
if (Expression_1.Expression.isExpression(lastOutput) && lastOutput.isPlainVariable()) {
|
|
694
|
+
const indices = this.extractIndices(token, values, assertive);
|
|
695
|
+
if (indices.length > 0 &&
|
|
696
|
+
Expression_1.Expression.isExpression(indices[0])) {
|
|
697
|
+
output.pop();
|
|
698
|
+
addToOutput(this.resolveSymbolicAccess(lastOutput, lastOutput, indices));
|
|
699
|
+
return;
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
const parsed = parseScope(token, values, assertive);
|
|
703
|
+
if (Settings_1.Settings.ALLOW_IMPLICIT_MULTIPLICATION) {
|
|
704
|
+
const mulFn = functions_2._['multiply'];
|
|
705
|
+
addToOutput(mulFn(resolveStackValue(output.pop()), parsed));
|
|
855
706
|
}
|
|
856
707
|
else {
|
|
857
|
-
|
|
858
|
-
const constant = this.CONSTANTS[token.value];
|
|
859
|
-
// User-defined constants are stored as strings and substitute during ordinary parsing.
|
|
860
|
-
// They take precedence over scoped values, matching the public setConstant method.
|
|
861
|
-
if (typeof constant === 'string') {
|
|
862
|
-
expression = this.parse(constant);
|
|
863
|
-
}
|
|
864
|
-
// Substitute values from the values object. A number is not considered a proper LH value.
|
|
865
|
-
else if (values && token.value in values && !token.is(Token_1.Token.NUMBER)) {
|
|
866
|
-
// expression = this.parse(String(values[token.value]), values);
|
|
867
|
-
const scopedValue = values[token.value];
|
|
868
|
-
if (Expression_1.Expression.isExpression(scopedValue) ||
|
|
869
|
-
Equation_1.Equation.isEquation(scopedValue) ||
|
|
870
|
-
(0, structuredEntityUtils_1.isEnumerable)(scopedValue)) {
|
|
871
|
-
expression = scopedValue.copy();
|
|
872
|
-
}
|
|
873
|
-
else {
|
|
874
|
-
expression = Expression_1.Expression.create(scopedValue, undefined, true);
|
|
875
|
-
}
|
|
876
|
-
}
|
|
877
|
-
else if (token.value in this.KNOWN_VALUES && Settings_1.Settings.SUBSTITUTE) {
|
|
878
|
-
expression = this.KNOWN_VALUES[token.value].copy();
|
|
879
|
-
}
|
|
880
|
-
// Built-in constants are factories so they evaluate at the active precision.
|
|
881
|
-
else if (Settings_1.Settings.EVALUATE && typeof constant === 'function') {
|
|
882
|
-
expression = this.parse(constant(), values);
|
|
883
|
-
}
|
|
884
|
-
else {
|
|
885
|
-
// At this point the expression type is variable or a number
|
|
886
|
-
switch (token.type) {
|
|
887
|
-
case Token_1.Token.FUNCTION:
|
|
888
|
-
expression = Expression_1.Expression.Function(token.value);
|
|
889
|
-
break;
|
|
890
|
-
case Token_1.Token.VARIABLE:
|
|
891
|
-
if (constants_1.INFINITY.includes(token.value)) {
|
|
892
|
-
expression = Expression_1.Expression.Inf();
|
|
893
|
-
}
|
|
894
|
-
else {
|
|
895
|
-
expression = Expression_1.Expression.Variable(token.value);
|
|
896
|
-
}
|
|
897
|
-
break;
|
|
898
|
-
default:
|
|
899
|
-
expression = Expression_1.Expression.Number(token.value);
|
|
900
|
-
break;
|
|
901
|
-
}
|
|
902
|
-
}
|
|
903
|
-
// Add it to output
|
|
904
|
-
addToOutput(expression);
|
|
708
|
+
addToOutput(parsed);
|
|
905
709
|
}
|
|
710
|
+
return;
|
|
711
|
+
}
|
|
712
|
+
addToOutput(token.deferLHSResolution
|
|
713
|
+
? parseScope(token, undefined, assertive, false)
|
|
714
|
+
: parseScope(token, values, assertive));
|
|
715
|
+
};
|
|
716
|
+
const resolveToken = (token) => {
|
|
717
|
+
const constant = this.CONSTANTS[token.value];
|
|
718
|
+
// User-defined constants take precedence over scoped values.
|
|
719
|
+
if (typeof constant === 'string') {
|
|
720
|
+
return this.parse(constant);
|
|
721
|
+
}
|
|
722
|
+
if (values && token.value in values && !token.is(Token_1.Token.NUMBER)) {
|
|
723
|
+
const scopedValue = values[token.value];
|
|
724
|
+
if (Expression_1.Expression.isExpression(scopedValue) ||
|
|
725
|
+
Equation_1.Equation.isEquation(scopedValue) ||
|
|
726
|
+
(0, structuredEntityUtils_1.isEnumerable)(scopedValue)) {
|
|
727
|
+
return scopedValue.copy();
|
|
728
|
+
}
|
|
729
|
+
return Expression_1.Expression.create(scopedValue, undefined, true);
|
|
730
|
+
}
|
|
731
|
+
if (token.value in this.KNOWN_VALUES && Settings_1.Settings.SUBSTITUTE) {
|
|
732
|
+
return this.KNOWN_VALUES[token.value].copy();
|
|
733
|
+
}
|
|
734
|
+
// Built-in constants are factories so they evaluate at the active precision.
|
|
735
|
+
if (Settings_1.Settings.EVALUATE && typeof constant === 'function') {
|
|
736
|
+
return this.parse(constant(), values);
|
|
737
|
+
}
|
|
738
|
+
if (token.type === Token_1.Token.FUNCTION) {
|
|
739
|
+
return Expression_1.Expression.Function(token.value);
|
|
740
|
+
}
|
|
741
|
+
if (token.type === Token_1.Token.VARIABLE) {
|
|
742
|
+
return constants_1.INFINITY.includes(token.value)
|
|
743
|
+
? Expression_1.Expression.Inf()
|
|
744
|
+
: Expression_1.Expression.Variable(token.value);
|
|
745
|
+
}
|
|
746
|
+
return Expression_1.Expression.Number(token.value);
|
|
747
|
+
};
|
|
748
|
+
const handlePrefix = (token) => {
|
|
749
|
+
const value = resolveStackValue(output.pop());
|
|
750
|
+
const prefixAction = `${operators[token.value].action}Prefix`;
|
|
751
|
+
const fn = functions_2._[prefixAction];
|
|
752
|
+
return fn(value);
|
|
753
|
+
};
|
|
754
|
+
for (let i = 0; i < rpn.length; i++) {
|
|
755
|
+
const token = rpn[i];
|
|
756
|
+
if (Scope_1.Scope.isScope(token)) {
|
|
757
|
+
handleScope(token, i);
|
|
758
|
+
continue;
|
|
759
|
+
}
|
|
760
|
+
if (token.type === Token_1.Token.OPERATOR) {
|
|
761
|
+
const result = handleOperator(token, i);
|
|
762
|
+
if (result !== undefined) {
|
|
763
|
+
addToOutput(result);
|
|
764
|
+
}
|
|
765
|
+
}
|
|
766
|
+
else if (token.type === Token_1.Token.FUNCTION) {
|
|
767
|
+
addToOutput(handleFunction(token, rpn[++i]));
|
|
768
|
+
}
|
|
769
|
+
else if (token.type === Token_1.Token.PREFIX) {
|
|
770
|
+
addToOutput(handlePrefix(token));
|
|
771
|
+
}
|
|
772
|
+
else {
|
|
773
|
+
addToOutput(resolveToken(token));
|
|
906
774
|
}
|
|
907
775
|
}
|
|
908
776
|
let retval;
|
|
909
|
-
// Since as function args can have multiple arguments in the output
|
|
910
|
-
// the entire array gets returned. We do the same with
|
|
911
777
|
if (rpn.type === 'square') {
|
|
912
778
|
retval = new Vector_1.Vector(resolveStackValues(output));
|
|
913
779
|
}
|
|
914
780
|
else if (rpn.type === 'curly') {
|
|
915
|
-
// If the output contains KeyValuePairs (from '=>' operators), build a Dictionary.
|
|
916
|
-
// Otherwise build a ValuesSet as before.
|
|
917
781
|
if (output.length > 0 && KeyValuePair_1.KeyValuePair.isKeyValuePair(output[0])) {
|
|
918
782
|
const dict = new Dictionary_1.Dictionary();
|
|
919
783
|
for (const item of output) {
|
|
920
|
-
|
|
921
|
-
dict.set(item.key, item.value);
|
|
922
|
-
}
|
|
784
|
+
dict.set(item.key, item.value);
|
|
923
785
|
}
|
|
924
786
|
retval = dict;
|
|
925
787
|
}
|