nerdamer 1.1.13 → 2.0.0-rc.1
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/LICENSE.md +184 -0
- package/README.md +293 -312
- package/dist/bundle.js +2 -0
- package/dist/bundle.js.LICENSE.txt +7 -0
- package/dist/parser.js +2 -0
- package/dist/parser.js.LICENSE.txt +7 -0
- package/docs-data/parser-functions.json +1960 -0
- package/index.d.ts +10 -426
- package/output/algebra/adapters.d.ts +33 -0
- package/output/algebra/adapters.js +109 -0
- package/output/algebra/algorithms/arith.d.ts +84 -0
- package/output/algebra/algorithms/arith.js +323 -0
- package/output/algebra/algorithms/factor.d.ts +3 -0
- package/output/algebra/algorithms/factor.js +5 -0
- package/output/algebra/algorithms/factorMultivariate.d.ts +23 -0
- package/output/algebra/algorithms/factorMultivariate.js +2393 -0
- package/output/algebra/algorithms/factorUnivariate.d.ts +72 -0
- package/output/algebra/algorithms/factorUnivariate.js +1072 -0
- package/output/algebra/algorithms/gcd.d.ts +22 -0
- package/output/algebra/algorithms/gcd.js +690 -0
- package/output/algebra/algorithms/groebnerBase.d.ts +157 -0
- package/output/algebra/algorithms/groebnerBase.js +1166 -0
- package/output/algebra/algorithms/multiPoly/MultiPoly.d.ts +137 -0
- package/output/algebra/algorithms/multiPoly/MultiPoly.js +346 -0
- package/output/algebra/algorithms/poly.d.ts +228 -0
- package/output/algebra/algorithms/poly.js +1299 -0
- package/output/algebra/algorithms/rational.d.ts +17 -0
- package/output/algebra/algorithms/rational.js +115 -0
- package/output/algebra/factor/factor.d.ts +62 -0
- package/output/algebra/factor/factor.js +158 -0
- package/output/algebra/gcd/gcd.d.ts +29 -0
- package/output/algebra/gcd/gcd.js +141 -0
- package/output/algebra/groebner.d.ts +21 -0
- package/output/algebra/groebner.js +42 -0
- package/output/algebra/partfrac.d.ts +19 -0
- package/output/algebra/partfrac.js +398 -0
- package/output/algebra/polynomialize.d.ts +20 -0
- package/output/algebra/polynomialize.js +24 -0
- package/output/algebra/simplify/complexsimp.d.ts +7 -0
- package/output/algebra/simplify/complexsimp.js +24 -0
- package/output/algebra/simplify/factorCommon.d.ts +13 -0
- package/output/algebra/simplify/factorCommon.js +136 -0
- package/output/algebra/simplify/funcsimp.d.ts +26 -0
- package/output/algebra/simplify/funcsimp.js +633 -0
- package/output/algebra/simplify/invtrigrewrite.d.ts +10 -0
- package/output/algebra/simplify/invtrigrewrite.js +96 -0
- package/output/algebra/simplify/ratsimp.d.ts +21 -0
- package/output/algebra/simplify/ratsimp.js +140 -0
- package/output/algebra/simplify/simplify.d.ts +25 -0
- package/output/algebra/simplify/simplify.js +228 -0
- package/output/algebra/simplify/trigreduce.d.ts +38 -0
- package/output/algebra/simplify/trigreduce.js +424 -0
- package/output/algebra/simplify/trigrewrite.d.ts +17 -0
- package/output/algebra/simplify/trigrewrite.js +156 -0
- package/output/algebra/simplify/trigsimp.d.ts +11 -0
- package/output/algebra/simplify/trigsimp.js +369 -0
- package/output/algebra/simplify/utils.d.ts +32 -0
- package/output/algebra/simplify/utils.js +56 -0
- package/output/algebra/utils.d.ts +32 -0
- package/output/algebra/utils.js +48 -0
- package/output/api/advanced.d.ts +7 -0
- package/output/api/advanced.js +18 -0
- package/output/api/algebra.d.ts +17 -0
- package/output/api/algebra.js +32 -0
- package/output/api/assumptions.d.ts +4 -0
- package/output/api/assumptions.js +11 -0
- package/output/api/calculus.d.ts +9 -0
- package/output/api/calculus.js +21 -0
- package/output/api/core.d.ts +17 -0
- package/output/api/core.js +41 -0
- package/output/api/debug.d.ts +16 -0
- package/output/api/debug.js +23 -0
- package/output/api/parser.d.ts +85 -0
- package/output/api/parser.js +16 -0
- package/output/api/solve.d.ts +10 -0
- package/output/api/solve.js +16 -0
- package/output/api/structures.d.ts +10 -0
- package/output/api/structures.js +22 -0
- package/output/calculus/derivative/diff.d.ts +30 -0
- package/output/calculus/derivative/diff.js +238 -0
- package/output/calculus/fresnel.d.ts +16 -0
- package/output/calculus/fresnel.js +39 -0
- package/output/calculus/integrate/byParts.d.ts +18 -0
- package/output/calculus/integrate/byParts.js +339 -0
- package/output/calculus/integrate/bySubstitution.d.ts +135 -0
- package/output/calculus/integrate/bySubstitution.js +411 -0
- package/output/calculus/integrate/integrate.d.ts +38 -0
- package/output/calculus/integrate/integrate.js +652 -0
- package/output/calculus/integrate/integrationTable.d.ts +2 -0
- package/output/calculus/integrate/integrationTable.js +914 -0
- package/output/calculus/integrate/utils.d.ts +28 -0
- package/output/calculus/integrate/utils.js +96 -0
- package/output/calculus/laplace/ilaplace.d.ts +31 -0
- package/output/calculus/laplace/ilaplace.js +192 -0
- package/output/calculus/laplace/ilaplaceTable.d.ts +2 -0
- package/output/calculus/laplace/ilaplaceTable.js +200 -0
- package/output/calculus/laplace/laplace.d.ts +22 -0
- package/output/calculus/laplace/laplace.js +109 -0
- package/output/calculus/laplace/laplaceTable.d.ts +2 -0
- package/output/calculus/laplace/laplaceTable.js +187 -0
- package/output/calculus/limit/limit.d.ts +35 -0
- package/output/calculus/limit/limit.js +1183 -0
- package/output/calculus/limit/limitsTable.d.ts +2 -0
- package/output/calculus/limit/limitsTable.js +7 -0
- package/output/core/Settings.d.ts +32 -0
- package/output/core/Settings.js +68 -0
- package/output/core/adapters.d.ts +18 -0
- package/output/core/adapters.js +40 -0
- package/output/core/classes/assumption/Assumption.d.ts +218 -0
- package/output/core/classes/assumption/Assumption.js +605 -0
- package/output/core/classes/assumption/assertiveFunctions.d.ts +6 -0
- package/output/core/classes/assumption/assertiveFunctions.js +64 -0
- package/output/core/classes/assumption/assume.d.ts +90 -0
- package/output/core/classes/assumption/assume.js +145 -0
- package/output/core/classes/collection/Collection.d.ts +107 -0
- package/output/core/classes/collection/Collection.js +231 -0
- package/output/core/classes/complex/Complex.d.ts +99 -0
- package/output/core/classes/complex/Complex.js +135 -0
- package/output/core/classes/decimalSet/DecimalSet.d.ts +226 -0
- package/output/core/classes/decimalSet/DecimalSet.js +453 -0
- package/output/core/classes/dictionary/Dictionary.d.ts +102 -0
- package/output/core/classes/dictionary/Dictionary.js +213 -0
- package/output/core/classes/equation/Equation.d.ts +256 -0
- package/output/core/classes/equation/Equation.js +350 -0
- package/output/core/classes/expression/CoeffObject.d.ts +100 -0
- package/output/core/classes/expression/CoeffObject.js +198 -0
- package/output/core/classes/expression/Expression.d.ts +1674 -0
- package/output/core/classes/expression/Expression.js +2332 -0
- package/output/core/classes/expression/analysis.d.ts +25 -0
- package/output/core/classes/expression/analysis.js +218 -0
- package/output/core/classes/expression/collect.d.ts +9 -0
- package/output/core/classes/expression/collect.js +49 -0
- package/output/core/classes/expression/format.d.ts +45 -0
- package/output/core/classes/expression/format.js +217 -0
- package/output/core/classes/expression/products.d.ts +23 -0
- package/output/core/classes/expression/products.js +115 -0
- package/output/core/classes/expression/shortcuts.d.ts +35 -0
- package/output/core/classes/expression/shortcuts.js +129 -0
- package/output/core/classes/expression/traversal.d.ts +31 -0
- package/output/core/classes/expression/traversal.js +216 -0
- package/output/core/classes/expression/trig.d.ts +25 -0
- package/output/core/classes/expression/trig.js +40 -0
- package/output/core/classes/expression/utils.d.ts +52 -0
- package/output/core/classes/expression/utils.js +189 -0
- package/output/core/classes/lookupTable/LookupTable.d.ts +12 -0
- package/output/core/classes/lookupTable/LookupTable.js +55 -0
- package/output/core/classes/matrix/Matrix.d.ts +227 -0
- package/output/core/classes/matrix/Matrix.js +889 -0
- package/output/core/classes/matrix/Sylvester.d.ts +11 -0
- package/output/core/classes/matrix/Sylvester.js +54 -0
- package/output/core/classes/matrix/functions.d.ts +26 -0
- package/output/core/classes/matrix/functions.js +52 -0
- package/output/core/classes/matrix/utils.d.ts +9 -0
- package/output/core/classes/matrix/utils.js +22 -0
- package/output/core/classes/parser/Parser.d.ts +480 -0
- package/output/core/classes/parser/Parser.js +1812 -0
- package/output/core/classes/parser/Token.d.ts +58 -0
- package/output/core/classes/parser/Token.js +137 -0
- package/output/core/classes/parser/constants.d.ts +160 -0
- package/output/core/classes/parser/constants.js +227 -0
- package/output/core/classes/parser/helpers.d.ts +21 -0
- package/output/core/classes/parser/helpers.js +42 -0
- package/output/core/classes/parser/operations/add.d.ts +15 -0
- package/output/core/classes/parser/operations/add.js +238 -0
- package/output/core/classes/parser/operations/comma.d.ts +7 -0
- package/output/core/classes/parser/operations/comma.js +11 -0
- package/output/core/classes/parser/operations/compare.d.ts +21 -0
- package/output/core/classes/parser/operations/compare.js +461 -0
- package/output/core/classes/parser/operations/divide.d.ts +2 -0
- package/output/core/classes/parser/operations/divide.js +72 -0
- package/output/core/classes/parser/operations/functions.d.ts +46 -0
- package/output/core/classes/parser/operations/functions.js +430 -0
- package/output/core/classes/parser/operations/multiply.d.ts +11 -0
- package/output/core/classes/parser/operations/multiply.js +321 -0
- package/output/core/classes/parser/operations/power.d.ts +48 -0
- package/output/core/classes/parser/operations/power.js +673 -0
- package/output/core/classes/parser/operations/subtract.d.ts +3 -0
- package/output/core/classes/parser/operations/subtract.js +35 -0
- package/output/core/classes/parser/preprocess.d.ts +14 -0
- package/output/core/classes/parser/preprocess.js +259 -0
- package/output/core/classes/parser/scripting/controlFlow.d.ts +121 -0
- package/output/core/classes/parser/scripting/controlFlow.js +355 -0
- package/output/core/classes/parser/scripting/evaluate.d.ts +10 -0
- package/output/core/classes/parser/scripting/evaluate.js +112 -0
- package/output/core/classes/parser/scripting/functions.d.ts +14 -0
- package/output/core/classes/parser/scripting/functions.js +59 -0
- package/output/core/classes/parser/scripting/scope.d.ts +35 -0
- package/output/core/classes/parser/scripting/scope.js +155 -0
- package/output/core/classes/parser/types.d.ts +125 -0
- package/output/core/classes/parser/types.js +2 -0
- package/output/core/classes/parser/wrappers/IndexedReference.d.ts +31 -0
- package/output/core/classes/parser/wrappers/IndexedReference.js +68 -0
- package/output/core/classes/parser/wrappers/KeyValuePair.d.ts +24 -0
- package/output/core/classes/parser/wrappers/KeyValuePair.js +51 -0
- package/output/core/classes/polynomial/Polynomial.d.ts +500 -0
- package/output/core/classes/polynomial/Polynomial.js +1149 -0
- package/output/core/classes/polynomial/Term.d.ts +222 -0
- package/output/core/classes/polynomial/Term.js +430 -0
- package/output/core/classes/polynomial/functions.d.ts +69 -0
- package/output/core/classes/polynomial/functions.js +126 -0
- package/output/core/classes/polynomial/utils.d.ts +62 -0
- package/output/core/classes/polynomial/utils.js +206 -0
- package/output/core/classes/rational/Rational.d.ts +504 -0
- package/output/core/classes/rational/Rational.js +779 -0
- package/output/core/classes/seq/SEQ.d.ts +13 -0
- package/output/core/classes/seq/SEQ.js +137 -0
- package/output/core/classes/valuesSet/ValuesSet.d.ts +179 -0
- package/output/core/classes/valuesSet/ValuesSet.js +381 -0
- package/output/core/classes/vector/Vector.d.ts +222 -0
- package/output/core/classes/vector/Vector.js +497 -0
- package/output/core/classes/vector/functions.d.ts +28 -0
- package/output/core/classes/vector/functions.js +47 -0
- package/output/core/common/classes/MathematicalAggregate.d.ts +53 -0
- package/output/core/common/classes/MathematicalAggregate.js +140 -0
- package/output/core/common/classes/Scope.d.ts +62 -0
- package/output/core/common/classes/Scope.js +122 -0
- package/output/core/common/classes/StructuredEntity.d.ts +55 -0
- package/output/core/common/classes/StructuredEntity.js +151 -0
- package/output/core/common/common.d.ts +63 -0
- package/output/core/common/common.js +279 -0
- package/output/core/common/functions/functions.d.ts +14 -0
- package/output/core/common/functions/functions.js +33 -0
- package/output/core/common/functions/structuredEntityUtils.d.ts +27 -0
- package/output/core/common/functions/structuredEntityUtils.js +40 -0
- package/output/core/converters/BaseConverter.d.ts +97 -0
- package/output/core/converters/BaseConverter.js +405 -0
- package/output/core/converters/Converter.d.ts +111 -0
- package/output/core/converters/Converter.js +802 -0
- package/output/core/converters/Pattern.d.ts +71 -0
- package/output/core/converters/Pattern.js +302 -0
- package/output/core/dispatch.d.ts +34 -0
- package/output/core/dispatch.js +304 -0
- package/output/core/errors.d.ts +531 -0
- package/output/core/errors.js +621 -0
- package/output/core/functions/bigint/bigint.d.ts +121 -0
- package/output/core/functions/bigint/bigint.js +392 -0
- package/output/core/functions/bigint/primeFactor.d.ts +49 -0
- package/output/core/functions/bigint/primeFactor.js +267 -0
- package/output/core/functions/bigint/primes.d.ts +1 -0
- package/output/core/functions/bigint/primes.js +11 -0
- package/output/core/functions/build/definitions.d.ts +12 -0
- package/output/core/functions/build/definitions.js +133 -0
- package/output/core/functions/build/index.d.ts +32 -0
- package/output/core/functions/build/index.js +136 -0
- package/output/core/functions/complex.d.ts +90 -0
- package/output/core/functions/complex.js +482 -0
- package/output/core/functions/decimal.d.ts +24 -0
- package/output/core/functions/decimal.js +664 -0
- package/output/core/functions/expand/expand.d.ts +42 -0
- package/output/core/functions/expand/expand.js +376 -0
- package/output/core/functions/fresnelNumeric.d.ts +12 -0
- package/output/core/functions/fresnelNumeric.js +123 -0
- package/output/core/functions/numeric.d.ts +140 -0
- package/output/core/functions/numeric.js +790 -0
- package/output/core/functions/rationalNormalization.d.ts +11 -0
- package/output/core/functions/rationalNormalization.js +117 -0
- package/output/core/functions/setFunction.d.ts +19 -0
- package/output/core/functions/setFunction.js +75 -0
- package/output/core/functions/string.d.ts +26 -0
- package/output/core/functions/string.js +101 -0
- package/output/core/functions/subst.d.ts +90 -0
- package/output/core/functions/subst.js +498 -0
- package/output/core/functions/utils.d.ts +24 -0
- package/output/core/functions/utils.js +51 -0
- package/output/core/types.d.ts +48 -0
- package/output/core/types.js +2 -0
- package/output/index.d.ts +339 -0
- package/output/index.js +715 -0
- package/output/math/defint/defintDecimal.d.ts +37 -0
- package/output/math/defint/defintDecimal.js +320 -0
- package/output/math/defint/defintNative.d.ts +57 -0
- package/output/math/defint/defintNative.js +292 -0
- package/output/math/geometry.d.ts +8 -0
- package/output/math/geometry.js +32 -0
- package/output/math/math.d.ts +655 -0
- package/output/math/math.js +1811 -0
- package/output/math/trig.d.ts +518 -0
- package/output/math/trig.js +1444 -0
- package/output/math/trunc.d.ts +19 -0
- package/output/math/trunc.js +36 -0
- package/output/math/utils.d.ts +60 -0
- package/output/math/utils.js +180 -0
- package/output/solve/classes/DecimalMatrix.d.ts +17 -0
- package/output/solve/classes/DecimalMatrix.js +86 -0
- package/output/solve/classes/FunctionSolver.d.ts +135 -0
- package/output/solve/classes/FunctionSolver.js +433 -0
- package/output/solve/classes/MultivariateSolver.d.ts +84 -0
- package/output/solve/classes/MultivariateSolver.js +240 -0
- package/output/solve/classes/PolynomialSolver.d.ts +85 -0
- package/output/solve/classes/PolynomialSolver.js +292 -0
- package/output/solve/classes/SolutionSet.d.ts +153 -0
- package/output/solve/classes/SolutionSet.js +357 -0
- package/output/solve/classes/Solver.d.ts +17 -0
- package/output/solve/classes/Solver.js +132 -0
- package/output/solve/classes/SymbolicSolver.d.ts +74 -0
- package/output/solve/classes/SymbolicSolver.js +601 -0
- package/output/solve/linsolve.d.ts +51 -0
- package/output/solve/linsolve.js +225 -0
- package/output/solve/solve.d.ts +34 -0
- package/output/solve/solve.js +260 -0
- package/output/solve/solveSystem.d.ts +31 -0
- package/output/solve/solveSystem.js +290 -0
- package/output/solve/utils.d.ts +9 -0
- package/output/solve/utils.js +62 -0
- package/output/utils/array.d.ts +42 -0
- package/output/utils/array.js +98 -0
- package/output/utils/debug.d.ts +131 -0
- package/output/utils/debug.js +295 -0
- package/output/utils/decimal.d.ts +3 -0
- package/output/utils/decimal.js +16 -0
- package/output/utils/numeric.d.ts +14 -0
- package/output/utils/numeric.js +51 -0
- package/output/utils/object.d.ts +26 -0
- package/output/utils/object.js +56 -0
- package/package.json +213 -57
- package/.travis.yml +0 -3
- package/Algebra.js +0 -4568
- package/BREAKING_CHANGES.md +0 -5
- package/CODE_OF_CONDUCT.md +0 -46
- package/CONTRIBUTING.md +0 -14
- package/Calculus.js +0 -2675
- package/Extra.js +0 -622
- package/Solve.js +0 -1783
- package/all.js +0 -16
- package/all.min.js +0 -1
- package/gulpfile.js +0 -16
- package/index.html +0 -158
- package/license.txt +0 -19
- package/nerdamer.core.js +0 -12510
- package/spec/LaTeX.spec.js +0 -302
- package/spec/TeXConvert.spec.js +0 -8
- package/spec/algebra.spec.js +0 -287
- package/spec/basic_parser.spec.js +0 -134
- package/spec/build.spec.js +0 -131
- package/spec/calculus.spec.js +0 -183
- package/spec/core.spec.js +0 -2970
- package/spec/extra.spec.js +0 -54
- package/spec/solve.spec.js +0 -126
- package/spec/support/jasmine.json +0 -11
- package/spec/support/utils.js +0 -42
- package/spec/text.spec.js +0 -132
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.subtract = subtract;
|
|
4
|
+
exports.subtractPrefix = subtractPrefix;
|
|
5
|
+
const Settings_1 = require("../../../Settings");
|
|
6
|
+
const Expression_1 = require("../../expression/Expression");
|
|
7
|
+
const add_1 = require("./add");
|
|
8
|
+
function subtract(a, b) {
|
|
9
|
+
let retval;
|
|
10
|
+
if (Settings_1.Settings.DEFER_SIMPLIFICATION) {
|
|
11
|
+
retval = (0, add_1.add)(a, b.neg());
|
|
12
|
+
retval.deferred = true;
|
|
13
|
+
}
|
|
14
|
+
else {
|
|
15
|
+
if (a.isNUM() && b.isNUM()) {
|
|
16
|
+
retval = Expression_1.Expression.fromRational(a.getMultiplier().minus(b.getMultiplier()));
|
|
17
|
+
}
|
|
18
|
+
// Any value minus inf is -inf
|
|
19
|
+
else if (!a.isInf() && b.isInf()) {
|
|
20
|
+
retval = Expression_1.Expression.Inf().neg();
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
retval = (0, add_1.add)(a, b.neg());
|
|
24
|
+
}
|
|
25
|
+
if (!retval) {
|
|
26
|
+
throw new Error(`Subtraction not defined for ${a.type}-${b.type} | ${a}-${b}`);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return retval;
|
|
30
|
+
}
|
|
31
|
+
function subtractPrefix(a) {
|
|
32
|
+
// Just negates the multiplier
|
|
33
|
+
const x = a.neg();
|
|
34
|
+
return x;
|
|
35
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
type FunctionMetadata = {
|
|
2
|
+
bracketlessStatement?: boolean;
|
|
3
|
+
maxArgs: number;
|
|
4
|
+
};
|
|
5
|
+
type FunctionRegistry = Record<string, FunctionMetadata>;
|
|
6
|
+
/**
|
|
7
|
+
* Converts accepted parser shorthand to the ordinary notation consumed by the tokenizer.
|
|
8
|
+
* Paired-hash comments are removed before root-level semicolon sequences are mapped to the
|
|
9
|
+
* existing block construct and legacy bracketless function calls are normalized. Existing
|
|
10
|
+
* parenthesized calls are untouched; only a registered function followed by whitespace is
|
|
11
|
+
* considered a bracketless call.
|
|
12
|
+
*/
|
|
13
|
+
export declare function preprocess(input: string, functions: FunctionRegistry): string;
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.preprocess = preprocess;
|
|
4
|
+
const errors_1 = require("../../errors");
|
|
5
|
+
const BLOCK_FUNCTION = 'block';
|
|
6
|
+
const COMMENT_DELIMITER = '##';
|
|
7
|
+
function isIdentifierStart(character) {
|
|
8
|
+
return /[a-z_]/i.test(character);
|
|
9
|
+
}
|
|
10
|
+
function isIdentifierPart(character) {
|
|
11
|
+
return /[a-z0-9_]/i.test(character);
|
|
12
|
+
}
|
|
13
|
+
function getPreviousIdentifier(input, at) {
|
|
14
|
+
let end = at;
|
|
15
|
+
while (end > 0 && /\s/.test(input[end - 1])) {
|
|
16
|
+
end--;
|
|
17
|
+
}
|
|
18
|
+
let start = end;
|
|
19
|
+
while (start > 0 && isIdentifierPart(input[start - 1])) {
|
|
20
|
+
start--;
|
|
21
|
+
}
|
|
22
|
+
const identifier = input.slice(start, end);
|
|
23
|
+
return identifier && isIdentifierStart(identifier[0]) ? identifier : undefined;
|
|
24
|
+
}
|
|
25
|
+
function getNextSignificantCharacter(input, at) {
|
|
26
|
+
let index = at;
|
|
27
|
+
while (index < input.length && /\s/.test(input[index])) {
|
|
28
|
+
index++;
|
|
29
|
+
}
|
|
30
|
+
return input[index];
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Removes paired-hash comments before any other parser-input normalization occurs.
|
|
34
|
+
*
|
|
35
|
+
* A comment begins at `##` and ends at the next `##`. Comment contents are replaced
|
|
36
|
+
* with whitespace so adjacent tokens do not accidentally merge. A lone `#` is left
|
|
37
|
+
* untouched and retains its ordinary parser meaning.
|
|
38
|
+
*/
|
|
39
|
+
function normalizeComments(input) {
|
|
40
|
+
let retval = '';
|
|
41
|
+
let index = 0;
|
|
42
|
+
while (index < input.length) {
|
|
43
|
+
const opening = input.indexOf(COMMENT_DELIMITER, index);
|
|
44
|
+
if (opening === -1) {
|
|
45
|
+
retval += input.slice(index);
|
|
46
|
+
break;
|
|
47
|
+
}
|
|
48
|
+
retval += input.slice(index, opening);
|
|
49
|
+
const closing = input.indexOf(COMMENT_DELIMITER, opening + COMMENT_DELIMITER.length);
|
|
50
|
+
if (closing === -1) {
|
|
51
|
+
throw new errors_1.ParserError(`Missing closing comment delimiter "${COMMENT_DELIMITER}".`);
|
|
52
|
+
}
|
|
53
|
+
retval += ' ';
|
|
54
|
+
index = closing + COMMENT_DELIMITER.length;
|
|
55
|
+
}
|
|
56
|
+
return retval;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Normalizes semicolon statement syntax onto the parser's existing block sequencing.
|
|
60
|
+
*
|
|
61
|
+
* Root-level statement sequences become an implicit block. Inside an explicit block,
|
|
62
|
+
* semicolons separate block arguments just like the commas that already drive BLOCK's
|
|
63
|
+
* deferred evaluation. A trailing semicolon before a closing bracket or comma is simply
|
|
64
|
+
* discarded. Semicolons in other nested expression contexts are left untouched so the
|
|
65
|
+
* ordinary parser can reject syntax whose sequencing semantics have not been defined.
|
|
66
|
+
*/
|
|
67
|
+
function normalizeStatementSeparators(input) {
|
|
68
|
+
const scopes = [];
|
|
69
|
+
let retval = '';
|
|
70
|
+
let hasRootSequence = false;
|
|
71
|
+
for (let index = 0; index < input.length; index++) {
|
|
72
|
+
const character = input[index];
|
|
73
|
+
if (character === '(' || character === '[' || character === '{') {
|
|
74
|
+
const closingBracket = character === '(' ? ')' : character === '[' ? ']' : '}';
|
|
75
|
+
scopes.push({
|
|
76
|
+
closingBracket,
|
|
77
|
+
functionName: character === '(' ? getPreviousIdentifier(input, index) : undefined,
|
|
78
|
+
});
|
|
79
|
+
retval += character;
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
if (character === ')' || character === ']' || character === '}') {
|
|
83
|
+
const currentScope = scopes[scopes.length - 1];
|
|
84
|
+
if (currentScope?.closingBracket === character) {
|
|
85
|
+
scopes.pop();
|
|
86
|
+
}
|
|
87
|
+
retval += character;
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
if (character === ';') {
|
|
91
|
+
const nextCharacter = getNextSignificantCharacter(input, index + 1);
|
|
92
|
+
const currentScope = scopes[scopes.length - 1];
|
|
93
|
+
const isTrailingTerminator = nextCharacter === undefined ||
|
|
94
|
+
nextCharacter === ',' ||
|
|
95
|
+
nextCharacter === currentScope?.closingBracket;
|
|
96
|
+
if (scopes.length === 0) {
|
|
97
|
+
if (!isTrailingTerminator) {
|
|
98
|
+
retval += ',';
|
|
99
|
+
hasRootSequence = true;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
else if (isTrailingTerminator) {
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
else if (currentScope?.functionName === BLOCK_FUNCTION) {
|
|
106
|
+
retval += ',';
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
retval += character;
|
|
110
|
+
}
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
retval += character;
|
|
114
|
+
}
|
|
115
|
+
if (hasRootSequence) {
|
|
116
|
+
retval = `${BLOCK_FUNCTION}(${retval})`;
|
|
117
|
+
}
|
|
118
|
+
return retval;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Finds the right-most registered function that is separated from its argument by whitespace.
|
|
122
|
+
* Processing from the inside out lets nested input such as `sin sin x` normalize without
|
|
123
|
+
* introducing a separate parser mode.
|
|
124
|
+
*/
|
|
125
|
+
function findBracketlessFunction(input, functions) {
|
|
126
|
+
let retval;
|
|
127
|
+
let index = 0;
|
|
128
|
+
while (index < input.length) {
|
|
129
|
+
if (!isIdentifierStart(input[index])) {
|
|
130
|
+
index++;
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
const nameStart = index;
|
|
134
|
+
index++;
|
|
135
|
+
while (index < input.length && isIdentifierPart(input[index])) {
|
|
136
|
+
index++;
|
|
137
|
+
}
|
|
138
|
+
const nameEnd = index;
|
|
139
|
+
const name = input.slice(nameStart, nameEnd);
|
|
140
|
+
if (!(name in functions) || !/\s/.test(input[index] ?? '')) {
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
while (index < input.length && /\s/.test(input[index])) {
|
|
144
|
+
index++;
|
|
145
|
+
}
|
|
146
|
+
if (index < input.length) {
|
|
147
|
+
const firstArgumentCharacter = input[index];
|
|
148
|
+
const nextCharacter = input[index + 1] ?? '';
|
|
149
|
+
// Whitespace around an ordinary binary operator must not turn a registered
|
|
150
|
+
// function name used as a variable into a bracketless call. A sign glued to
|
|
151
|
+
// its operand remains valid prefix syntax, as in `sin -x`.
|
|
152
|
+
const startsWithOperatorBoundary = /[*/=<>:&|]/.test(firstArgumentCharacter) ||
|
|
153
|
+
((firstArgumentCharacter === '+' || firstArgumentCharacter === '-') &&
|
|
154
|
+
/\s/.test(nextCharacter));
|
|
155
|
+
if (!startsWithOperatorBoundary) {
|
|
156
|
+
retval = {
|
|
157
|
+
argumentStart: index,
|
|
158
|
+
consumeStatement: functions[name].bracketlessStatement === true,
|
|
159
|
+
maxArgs: functions[name].maxArgs,
|
|
160
|
+
nameEnd,
|
|
161
|
+
nameStart,
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
return retval;
|
|
167
|
+
}
|
|
168
|
+
function isOpeningBracket(character) {
|
|
169
|
+
return character === '(' || character === '[' || character === '{';
|
|
170
|
+
}
|
|
171
|
+
function isClosingBracket(character) {
|
|
172
|
+
return character === ')' || character === ']' || character === '}';
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Finds the end of one bracketless function application. Function application binds more
|
|
176
|
+
* tightly than ordinary binary arithmetic but less tightly than powers and postfix operators.
|
|
177
|
+
* Multi-argument functions keep comma-separated arguments in the same application.
|
|
178
|
+
*/
|
|
179
|
+
function findArgumentEnd(input, start, maxArgs, consumeStatement = false) {
|
|
180
|
+
let depth = 0;
|
|
181
|
+
let index = start;
|
|
182
|
+
let previousSignificant = '';
|
|
183
|
+
const multipleArguments = maxArgs !== 1;
|
|
184
|
+
for (; index < input.length; index++) {
|
|
185
|
+
const character = input[index];
|
|
186
|
+
if (isOpeningBracket(character)) {
|
|
187
|
+
depth++;
|
|
188
|
+
previousSignificant = character;
|
|
189
|
+
continue;
|
|
190
|
+
}
|
|
191
|
+
if (isClosingBracket(character)) {
|
|
192
|
+
if (depth === 0) {
|
|
193
|
+
break;
|
|
194
|
+
}
|
|
195
|
+
depth--;
|
|
196
|
+
previousSignificant = character;
|
|
197
|
+
continue;
|
|
198
|
+
}
|
|
199
|
+
if (depth > 0) {
|
|
200
|
+
if (!/\s/.test(character)) {
|
|
201
|
+
previousSignificant = character;
|
|
202
|
+
}
|
|
203
|
+
continue;
|
|
204
|
+
}
|
|
205
|
+
if (consumeStatement) {
|
|
206
|
+
if (character === ',') {
|
|
207
|
+
break;
|
|
208
|
+
}
|
|
209
|
+
if (!/\s/.test(character)) {
|
|
210
|
+
previousSignificant = character;
|
|
211
|
+
}
|
|
212
|
+
continue;
|
|
213
|
+
}
|
|
214
|
+
if (/\s/.test(character)) {
|
|
215
|
+
if (multipleArguments && previousSignificant === ',') {
|
|
216
|
+
continue;
|
|
217
|
+
}
|
|
218
|
+
break;
|
|
219
|
+
}
|
|
220
|
+
if (character === ',') {
|
|
221
|
+
if (!multipleArguments) {
|
|
222
|
+
break;
|
|
223
|
+
}
|
|
224
|
+
previousSignificant = character;
|
|
225
|
+
continue;
|
|
226
|
+
}
|
|
227
|
+
const isPrefixSign = (character === '+' || character === '-') &&
|
|
228
|
+
(index === start || previousSignificant === ',' || previousSignificant === '^');
|
|
229
|
+
const isBinaryBoundary = /[+\-*/=<>:&|]/.test(character) && !isPrefixSign;
|
|
230
|
+
if (isBinaryBoundary) {
|
|
231
|
+
break;
|
|
232
|
+
}
|
|
233
|
+
previousSignificant = character;
|
|
234
|
+
}
|
|
235
|
+
return index;
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Converts accepted parser shorthand to the ordinary notation consumed by the tokenizer.
|
|
239
|
+
* Paired-hash comments are removed before root-level semicolon sequences are mapped to the
|
|
240
|
+
* existing block construct and legacy bracketless function calls are normalized. Existing
|
|
241
|
+
* parenthesized calls are untouched; only a registered function followed by whitespace is
|
|
242
|
+
* considered a bracketless call.
|
|
243
|
+
*/
|
|
244
|
+
function preprocess(input, functions) {
|
|
245
|
+
let retval = normalizeComments(input);
|
|
246
|
+
retval = normalizeStatementSeparators(retval);
|
|
247
|
+
let bracketless = findBracketlessFunction(retval, functions);
|
|
248
|
+
while (bracketless) {
|
|
249
|
+
const argumentEnd = findArgumentEnd(retval, bracketless.argumentStart, bracketless.maxArgs, bracketless.consumeStatement);
|
|
250
|
+
const name = retval.slice(bracketless.nameStart, bracketless.nameEnd);
|
|
251
|
+
const argument = retval.slice(bracketless.argumentStart, argumentEnd);
|
|
252
|
+
retval =
|
|
253
|
+
retval.slice(0, bracketless.nameStart) +
|
|
254
|
+
`${name}(${argument})` +
|
|
255
|
+
retval.slice(argumentEnd);
|
|
256
|
+
bracketless = findBracketlessFunction(retval, functions);
|
|
257
|
+
}
|
|
258
|
+
return retval;
|
|
259
|
+
}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { Expression } from '../../expression/Expression';
|
|
2
|
+
import type { ParserEntity } from '../../../types';
|
|
3
|
+
import type { DeferredFunctionArgument } from '../types';
|
|
4
|
+
export declare const RETURN_SIGNAL = "RETURN_SIGNAL";
|
|
5
|
+
export declare const BREAK_SIGNAL = "BREAK_SIGNAL";
|
|
6
|
+
export declare const CONTINUE_SIGNAL = "CONTINUE_SIGNAL";
|
|
7
|
+
/** Base class for internal parser control transfers. These signals are not parser errors. */
|
|
8
|
+
export declare abstract class ControlFlowSignal extends Error {
|
|
9
|
+
constructor();
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Internal control-flow signal used to carry a symbolic function's return value to its
|
|
13
|
+
* function boundary. It is not a mathematical parser result.
|
|
14
|
+
*/
|
|
15
|
+
export declare class ReturnSignal extends ControlFlowSignal {
|
|
16
|
+
readonly value: ParserEntity;
|
|
17
|
+
readonly dataType: typeof RETURN_SIGNAL;
|
|
18
|
+
constructor(value: ParserEntity);
|
|
19
|
+
static isReturnSignal(obj: unknown): obj is ReturnSignal;
|
|
20
|
+
}
|
|
21
|
+
/** Internal control-flow signal consumed by the nearest parser loop. */
|
|
22
|
+
export declare class BreakSignal extends ControlFlowSignal {
|
|
23
|
+
readonly dataType: typeof BREAK_SIGNAL;
|
|
24
|
+
static isBreakSignal(obj: unknown): obj is BreakSignal;
|
|
25
|
+
}
|
|
26
|
+
/** Internal control-flow signal consumed by the nearest parser loop. */
|
|
27
|
+
export declare class ContinueSignal extends ControlFlowSignal {
|
|
28
|
+
readonly dataType: typeof CONTINUE_SIGNAL;
|
|
29
|
+
static isContinueSignal(obj: unknown): obj is ContinueSignal;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Evaluates one symbolic-function body and consumes control flow at the function boundary.
|
|
33
|
+
* RETURN becomes the function result, while BREAK and CONTINUE cannot escape a function call.
|
|
34
|
+
*/
|
|
35
|
+
export declare function functionBoundary(evaluate: () => ParserEntity): ParserEntity;
|
|
36
|
+
/**
|
|
37
|
+
* Returns a value from the current symbolic function.
|
|
38
|
+
* @param x
|
|
39
|
+
* @returns
|
|
40
|
+
*/
|
|
41
|
+
export declare function RETURN(x: ParserEntity): never;
|
|
42
|
+
/** Exits the nearest parser control-flow loop. */
|
|
43
|
+
export declare function BREAK(): never;
|
|
44
|
+
/** Skips to the next iteration of the nearest parser control-flow loop. */
|
|
45
|
+
export declare function CONTINUE(): never;
|
|
46
|
+
/**
|
|
47
|
+
* Returns 1 when every deferred argument is nonzero, otherwise 0.
|
|
48
|
+
* Evaluation stops as soon as a false argument is found.
|
|
49
|
+
*/
|
|
50
|
+
export declare function AND(...args: DeferredFunctionArgument[]): Expression;
|
|
51
|
+
/**
|
|
52
|
+
* Returns 1 when at least one deferred argument is nonzero, otherwise 0.
|
|
53
|
+
* Evaluation stops as soon as a true argument is found.
|
|
54
|
+
*/
|
|
55
|
+
export declare function OR(...args: DeferredFunctionArgument[]): Expression;
|
|
56
|
+
/** Returns 1 when the argument is zero and 0 otherwise. */
|
|
57
|
+
export declare function NOT(value: ParserEntity): Expression;
|
|
58
|
+
/** Returns 1 when an odd number of arguments are nonzero, otherwise 0. */
|
|
59
|
+
export declare function XOR(...args: ParserEntity[]): Expression;
|
|
60
|
+
/**
|
|
61
|
+
* Evaluates an expression and returns its result unless evaluation throws an ordinary error.
|
|
62
|
+
* The fallback is evaluated only after an error. Internal parser control-flow signals continue
|
|
63
|
+
* unwinding to their enclosing function or loop boundary.
|
|
64
|
+
*/
|
|
65
|
+
export declare function IFERROR(expression: DeferredFunctionArgument, fallback: DeferredFunctionArgument): ParserEntity;
|
|
66
|
+
/**
|
|
67
|
+
* Returns 1 when deferred evaluation throws an ordinary error and 0 otherwise.
|
|
68
|
+
* Internal parser control-flow signals are not errors and continue unwinding normally.
|
|
69
|
+
*/
|
|
70
|
+
export declare function ISERROR(expression: DeferredFunctionArgument): Expression;
|
|
71
|
+
/**
|
|
72
|
+
* A branching function. Its arguments are deferred so only the selected branch is evaluated.
|
|
73
|
+
* When the false branch is omitted, a false condition produces the parser's empty result.
|
|
74
|
+
* @param condition
|
|
75
|
+
* @param branch1
|
|
76
|
+
* @param branch2
|
|
77
|
+
* @returns
|
|
78
|
+
*/
|
|
79
|
+
export declare function IF(condition: DeferredFunctionArgument, branch1: DeferredFunctionArgument, branch2?: DeferredFunctionArgument): ParserEntity;
|
|
80
|
+
/**
|
|
81
|
+
* Repeatedly evaluates a deferred body while a deferred condition is nonzero.
|
|
82
|
+
* The condition is reevaluated before every iteration. BREAK and CONTINUE are consumed here so
|
|
83
|
+
* they apply only to the nearest loop; other control-flow signals continue to unwind outward.
|
|
84
|
+
* The final completed body result is returned; if the body never completes, an empty Vector is
|
|
85
|
+
* returned.
|
|
86
|
+
* @param condition
|
|
87
|
+
* @param body
|
|
88
|
+
* @returns
|
|
89
|
+
*/
|
|
90
|
+
export declare function WHILE(condition: DeferredFunctionArgument, body: DeferredFunctionArgument): ParserEntity;
|
|
91
|
+
/**
|
|
92
|
+
* Evaluates a deferred initializer once, then delegates repeated condition and body evaluation
|
|
93
|
+
* to WHILE. The update runs after each completed body evaluation and also before a CONTINUE
|
|
94
|
+
* advances to the next condition check. BREAK and RETURN skip the pending update. The final
|
|
95
|
+
* completed body result is returned; if the body never completes, WHILE's empty-Vector result
|
|
96
|
+
* is preserved.
|
|
97
|
+
* @param initializer
|
|
98
|
+
* @param condition
|
|
99
|
+
* @param update
|
|
100
|
+
* @param body
|
|
101
|
+
* @returns
|
|
102
|
+
*/
|
|
103
|
+
export declare function FOR(initializer: DeferredFunctionArgument, condition: DeferredFunctionArgument, update: DeferredFunctionArgument, body: DeferredFunctionArgument): ParserEntity;
|
|
104
|
+
/**
|
|
105
|
+
* Evaluates a sequence of deferred parser commands in order.
|
|
106
|
+
* The final command's result is returned. Control-flow signals are not consumed here, allowing
|
|
107
|
+
* RETURN, BREAK, and CONTINUE to unwind to their enclosing function or loop boundary. An empty
|
|
108
|
+
* block retains the historical empty-vector result.
|
|
109
|
+
* @param args
|
|
110
|
+
* @returns
|
|
111
|
+
*/
|
|
112
|
+
export declare function BLOCK(...args: DeferredFunctionArgument[]): ParserEntity;
|
|
113
|
+
/**
|
|
114
|
+
* Evaluates one parser-dispatched function through the outer return boundary.
|
|
115
|
+
*
|
|
116
|
+
* Nested parser calls keep propagating RETURN. The outermost parser call consumes it when
|
|
117
|
+
* execution is not already inside a symbolic function.
|
|
118
|
+
*/
|
|
119
|
+
export declare function parserReturnBoundary(evaluate: () => ParserEntity): ParserEntity;
|
|
120
|
+
/** Evaluates BLOCK through the parser return boundary. */
|
|
121
|
+
export declare function parserBlock(...args: DeferredFunctionArgument[]): ParserEntity;
|