pimath 0.0.66 → 0.0.67
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/.eslintrc.js +23 -23
- package/dist/pi.js +178 -44
- package/dist/pi.js.map +1 -1
- package/dist/pi.min.js +1 -1
- package/dist/pi.min.js.map +1 -1
- package/docs/assets/highlight.css +78 -78
- package/docs/assets/main.js +52 -52
- package/docs/assets/style.css +1413 -1413
- package/docs/classes/Logicalset.Logicalset-1.html +4 -4
- package/docs/classes/Polynom.Rational.html +3 -3
- package/docs/classes/algebra_equation.Equation.html +25 -25
- package/docs/classes/algebra_monom.Monom.html +113 -113
- package/docs/classes/algebra_polynom.Polynom.html +29 -29
- package/docs/classes/coefficients_fraction.Fraction.html +18 -18
- package/docs/classes/coefficients_nthroot.NthRoot.html +2 -2
- package/docs/classes/geometry_circle.Circle.html +2 -2
- package/docs/classes/geometry_line.Line.html +2 -2
- package/docs/classes/geometry_triangle.Triangle.html +16 -16
- package/docs/classes/numeric.Numeric.html +13 -13
- package/docs/classes/shutingyard.Shutingyard.html +17 -17
- package/docs/index.html +10 -10
- package/docs/interfaces/algebra_equation.ISolution.html +2 -2
- package/docs/modules/Logicalset.html +2 -2
- package/docs/modules/Polynom.html +2 -2
- package/docs/modules/Vector.html +2 -2
- package/esm/maths/algebra/equation.js +2 -2
- package/esm/maths/algebra/equation.js.map +1 -1
- package/esm/maths/algebra/polynom.d.ts +4 -5
- package/esm/maths/algebra/polynom.js +2 -2
- package/esm/maths/algebra/polynom.js.map +1 -1
- package/esm/maths/algebra/rational.d.ts +8 -10
- package/esm/maths/algebra/rational.js +11 -6
- package/esm/maths/algebra/study/rationalStudy.d.ts +1 -2
- package/esm/maths/algebra/study/rationalStudy.js +14 -14
- package/esm/maths/algebra/study/rationalStudy.js.map +1 -1
- package/esm/maths/algebra/study.d.ts +9 -22
- package/esm/maths/algebra/study.js +33 -23
- package/esm/maths/algebra/study.js.map +1 -1
- package/esm/maths/coefficients/fraction.d.ts +8 -6
- package/esm/maths/coefficients/fraction.js +34 -17
- package/esm/maths/coefficients/fraction.js.map +1 -1
- package/esm/maths/expressions/expression.d.ts +21 -0
- package/esm/maths/expressions/expression.js +161 -0
- package/esm/maths/expressions/expression.js.map +1 -0
- package/esm/maths/expressions/expressionFactor.d.ts +29 -0
- package/esm/maths/expressions/expressionFactor.js +109 -0
- package/esm/maths/expressions/expressionFactor.js.map +1 -0
- package/esm/maths/expressions/expressionMember.d.ts +16 -0
- package/esm/maths/expressions/expressionMember.js +90 -0
- package/esm/maths/expressions/expressionMember.js.map +1 -0
- package/esm/maths/expressions/expressionOperators.d.ts +8 -0
- package/esm/maths/expressions/expressionOperators.js +42 -0
- package/esm/maths/expressions/expressionOperators.js.map +1 -0
- package/esm/maths/expressions/expressionParser.d.ts +12 -0
- package/esm/maths/expressions/expressionParser.js +219 -0
- package/esm/maths/expressions/expressionParser.js.map +1 -0
- package/esm/maths/expressions/factors/ExpFactor.d.ts +7 -0
- package/esm/maths/expressions/factors/ExpFactor.js +22 -0
- package/esm/maths/expressions/factors/ExpFactor.js.map +1 -0
- package/esm/maths/expressions/factors/ExpFactorConstant.d.ts +13 -0
- package/esm/maths/expressions/factors/ExpFactorConstant.js +49 -0
- package/esm/maths/expressions/factors/ExpFactorConstant.js.map +1 -0
- package/esm/maths/expressions/factors/ExpFactorExponential.d.ts +7 -0
- package/esm/maths/expressions/factors/ExpFactorExponential.js +18 -0
- package/esm/maths/expressions/factors/ExpFactorExponential.js.map +1 -0
- package/esm/maths/expressions/factors/ExpFactorNumber.d.ts +13 -0
- package/esm/maths/expressions/factors/ExpFactorNumber.js +36 -0
- package/esm/maths/expressions/factors/ExpFactorNumber.js.map +1 -0
- package/esm/maths/expressions/factors/ExpFactorPower.d.ts +9 -0
- package/esm/maths/expressions/factors/ExpFactorPower.js +22 -0
- package/esm/maths/expressions/factors/ExpFactorPower.js.map +1 -0
- package/esm/maths/expressions/factors/ExpFactorSin.d.ts +7 -0
- package/esm/maths/expressions/factors/ExpFactorSin.js +22 -0
- package/esm/maths/expressions/factors/ExpFactorSin.js.map +1 -0
- package/esm/maths/expressions/factors/ExpFactorTrigo.d.ts +19 -0
- package/esm/maths/expressions/factors/ExpFactorTrigo.js +40 -0
- package/esm/maths/expressions/factors/ExpFactorTrigo.js.map +1 -0
- package/esm/maths/expressions/factors/ExpFactorVariable.d.ts +12 -0
- package/esm/maths/expressions/factors/ExpFactorVariable.js +33 -0
- package/esm/maths/expressions/factors/ExpFactorVariable.js.map +1 -0
- package/esm/maths/expressions/internals.d.ts +12 -0
- package/esm/maths/expressions/internals.js +29 -0
- package/esm/maths/expressions/internals.js.map +1 -0
- package/esm/maths/shutingyard.d.ts +4 -1
- package/esm/maths/shutingyard.js +137 -21
- package/esm/maths/shutingyard.js.map +1 -1
- package/graph.svg +1033 -0
- package/package.json +1 -1
- package/src/maths/algebra/equation.ts +2 -2
- package/src/maths/algebra/polynom.ts +1 -0
- package/src/maths/algebra/study.ts +4 -4
- package/src/maths/coefficients/fraction.ts +111 -86
- package/src/maths/expressions/expression.ts +191 -0
- package/src/maths/expressions/expressionFactor.ts +138 -0
- package/src/maths/expressions/expressionMember.ts +114 -0
- package/src/maths/expressions/expressionOperators.ts +49 -0
- package/src/maths/expressions/expressionParser.ts +249 -0
- package/src/maths/expressions/factors/ExpFactor.ts +26 -0
- package/src/maths/expressions/factors/ExpFactorConstant.ts +56 -0
- package/src/maths/expressions/factors/ExpFactorExponential.ts +19 -0
- package/src/maths/expressions/factors/ExpFactorNumber.ts +44 -0
- package/src/maths/expressions/factors/ExpFactorPower.ts +24 -0
- package/src/maths/expressions/factors/ExpFactorTrigo.ts +44 -0
- package/src/maths/expressions/factors/ExpFactorVariable.ts +40 -0
- package/src/maths/expressions/internals.ts +14 -0
- package/src/maths/shutingyard.ts +156 -26
- package/tests/coefficients/fraction.test.ts +17 -0
- package/tests/expressions/expressions.test.ts +124 -0
- package/tests/shutingyard.test.ts +22 -0
- package/.idea/shelf/Uncommitted_changes_before_Update_at_17_04_2022_12_40_[Changes]/shelved.patch +0 -21
- package/.idea/shelf/Uncommitted_changes_before_Update_at_17_04_2022_12_40__Changes_.xml +0 -4
package/.eslintrc.js
CHANGED
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
module.exports = {
|
|
2
|
-
"env": {
|
|
3
|
-
"browser": true,
|
|
4
|
-
"es6": true
|
|
5
|
-
},
|
|
6
|
-
"extends": [
|
|
7
|
-
"eslint:recommended",
|
|
8
|
-
"plugin:@typescript-eslint/eslint-recommended"
|
|
9
|
-
],
|
|
10
|
-
"globals": {
|
|
11
|
-
"Atomics": "readonly",
|
|
12
|
-
"SharedArrayBuffer": "readonly"
|
|
13
|
-
},
|
|
14
|
-
"parser": "@typescript-eslint/parser",
|
|
15
|
-
"parserOptions": {
|
|
16
|
-
"ecmaVersion": 2018,
|
|
17
|
-
"sourceType": "module"
|
|
18
|
-
},
|
|
19
|
-
"plugins": [
|
|
20
|
-
"@typescript-eslint"
|
|
21
|
-
],
|
|
22
|
-
"rules": {
|
|
23
|
-
}
|
|
1
|
+
module.exports = {
|
|
2
|
+
"env": {
|
|
3
|
+
"browser": true,
|
|
4
|
+
"es6": true
|
|
5
|
+
},
|
|
6
|
+
"extends": [
|
|
7
|
+
"eslint:recommended",
|
|
8
|
+
"plugin:@typescript-eslint/eslint-recommended"
|
|
9
|
+
],
|
|
10
|
+
"globals": {
|
|
11
|
+
"Atomics": "readonly",
|
|
12
|
+
"SharedArrayBuffer": "readonly"
|
|
13
|
+
},
|
|
14
|
+
"parser": "@typescript-eslint/parser",
|
|
15
|
+
"parserOptions": {
|
|
16
|
+
"ecmaVersion": 2018,
|
|
17
|
+
"sourceType": "module"
|
|
18
|
+
},
|
|
19
|
+
"plugins": [
|
|
20
|
+
"@typescript-eslint"
|
|
21
|
+
],
|
|
22
|
+
"rules": {
|
|
23
|
+
}
|
|
24
24
|
};
|
package/dist/pi.js
CHANGED
|
@@ -434,10 +434,10 @@ class Equation {
|
|
|
434
434
|
else {
|
|
435
435
|
// Must handle the case if the m1 monom is negative.
|
|
436
436
|
if ((this.isGreater() && m1.sign() === 1) || (!this.isGreater() && m1.sign() === -1)) {
|
|
437
|
-
s = `\\left${this.isAlsoEqual() ? '\\[' : '\\]'}${v};+\\infty\\right\\[`;
|
|
437
|
+
s = `\\left${this.isAlsoEqual() ? '\\[' : '\\]'}${v.tex};+\\infty\\right\\[`;
|
|
438
438
|
}
|
|
439
439
|
else {
|
|
440
|
-
s = `\\left\\]-\\infty;${v} \\right\\${this.isAlsoEqual() ? '\\]' : '\\['}`;
|
|
440
|
+
s = `\\left\\]-\\infty;${v.tex} \\right\\${this.isAlsoEqual() ? '\\]' : '\\['}`;
|
|
441
441
|
}
|
|
442
442
|
}
|
|
443
443
|
this._solutions = [{
|
|
@@ -2245,6 +2245,7 @@ class Polynom {
|
|
|
2245
2245
|
this._monoms = [];
|
|
2246
2246
|
this._factors = [];
|
|
2247
2247
|
this.mark_as_dirty();
|
|
2248
|
+
// TODO: allow to enter a liste of Fraction (a, b, c, ...) to make a polynom ax^n + bx^(n-1) + cx^(n-2) + ...
|
|
2248
2249
|
if (typeof inputStr === 'string') {
|
|
2249
2250
|
return this._parseString(inputStr, ...values);
|
|
2250
2251
|
}
|
|
@@ -3467,9 +3468,9 @@ var FUNCTION_EXTREMA;
|
|
|
3467
3468
|
})(FUNCTION_EXTREMA = exports.FUNCTION_EXTREMA || (exports.FUNCTION_EXTREMA = {}));
|
|
3468
3469
|
var TABLE_OF_SIGNS;
|
|
3469
3470
|
(function (TABLE_OF_SIGNS) {
|
|
3470
|
-
TABLE_OF_SIGNS[
|
|
3471
|
-
TABLE_OF_SIGNS[
|
|
3472
|
-
TABLE_OF_SIGNS[
|
|
3471
|
+
TABLE_OF_SIGNS["SIGNS"] = "signs";
|
|
3472
|
+
TABLE_OF_SIGNS["GROWS"] = "grows";
|
|
3473
|
+
TABLE_OF_SIGNS["VARIATIONS"] = "variatins";
|
|
3473
3474
|
})(TABLE_OF_SIGNS = exports.TABLE_OF_SIGNS || (exports.TABLE_OF_SIGNS = {}));
|
|
3474
3475
|
/**
|
|
3475
3476
|
* The study class is a "function study" class that will get:
|
|
@@ -3723,7 +3724,7 @@ class Study {
|
|
|
3723
3724
|
;
|
|
3724
3725
|
makeSigns() {
|
|
3725
3726
|
return {
|
|
3726
|
-
type: TABLE_OF_SIGNS.
|
|
3727
|
+
type: TABLE_OF_SIGNS.SIGNS,
|
|
3727
3728
|
fx: null,
|
|
3728
3729
|
factors: [],
|
|
3729
3730
|
zeroes: [],
|
|
@@ -3970,8 +3971,12 @@ const numeric_1 = __webpack_require__(956);
|
|
|
3970
3971
|
*/
|
|
3971
3972
|
class Fraction {
|
|
3972
3973
|
constructor(value, denominatorOrPeriodic) {
|
|
3973
|
-
|
|
3974
|
-
|
|
3974
|
+
this.isApproximative = () => {
|
|
3975
|
+
return this._numerator.toString().length >= 15 && this._denominator.toString().length >= 15;
|
|
3976
|
+
};
|
|
3977
|
+
this.isExact = () => {
|
|
3978
|
+
return !this.isApproximative();
|
|
3979
|
+
};
|
|
3975
3980
|
// ------------------------------------------
|
|
3976
3981
|
/**
|
|
3977
3982
|
* Parse the value to get the numerator and denominator
|
|
@@ -3988,15 +3993,15 @@ class Fraction {
|
|
|
3988
3993
|
}
|
|
3989
3994
|
switch (typeof value) {
|
|
3990
3995
|
case "string":
|
|
3991
|
-
// Split the
|
|
3996
|
+
// Split the string value in two parts: Numerator/Denominator
|
|
3992
3997
|
S = value.split('/');
|
|
3993
3998
|
// Security checks
|
|
3994
3999
|
if (S.length > 2)
|
|
3995
|
-
throw "
|
|
4000
|
+
throw value + " has too many divide signs";
|
|
3996
4001
|
if (S.map(x => x === '' || isNaN(Number(x))).includes(true))
|
|
3997
|
-
throw "
|
|
4002
|
+
throw value + " is not a valid number";
|
|
3998
4003
|
if (S.length === 1) {
|
|
3999
|
-
// No divide sign
|
|
4004
|
+
// No divide sign - it's a number
|
|
4000
4005
|
return this.parse(+S[0]);
|
|
4001
4006
|
}
|
|
4002
4007
|
else if (S.length === 2) {
|
|
@@ -4013,6 +4018,7 @@ class Fraction {
|
|
|
4013
4018
|
}
|
|
4014
4019
|
else {
|
|
4015
4020
|
// More than one divide sign ?
|
|
4021
|
+
// This is impossible
|
|
4016
4022
|
this._numerator = NaN;
|
|
4017
4023
|
this._denominator = 1;
|
|
4018
4024
|
}
|
|
@@ -4053,6 +4059,8 @@ class Fraction {
|
|
|
4053
4059
|
}
|
|
4054
4060
|
return this;
|
|
4055
4061
|
};
|
|
4062
|
+
// ------------------------------------------
|
|
4063
|
+
// Mathematical operations
|
|
4056
4064
|
this.clone = () => {
|
|
4057
4065
|
let F = new Fraction();
|
|
4058
4066
|
F.numerator = +this._numerator;
|
|
@@ -4080,8 +4088,6 @@ class Fraction {
|
|
|
4080
4088
|
return this;
|
|
4081
4089
|
};
|
|
4082
4090
|
// ------------------------------------------
|
|
4083
|
-
// Mathematical operations
|
|
4084
|
-
// ------------------------------------------
|
|
4085
4091
|
this.opposed = () => {
|
|
4086
4092
|
this._numerator = -this._numerator;
|
|
4087
4093
|
return this;
|
|
@@ -4360,22 +4366,32 @@ class Fraction {
|
|
|
4360
4366
|
if (this.isInfinity()) {
|
|
4361
4367
|
return `${this.sign() === 1 ? '+' : '-'}\\infty`;
|
|
4362
4368
|
}
|
|
4363
|
-
if (this.
|
|
4364
|
-
|
|
4365
|
-
|
|
4366
|
-
|
|
4367
|
-
|
|
4369
|
+
if (this.isExact()) {
|
|
4370
|
+
if (this._denominator === 1) {
|
|
4371
|
+
return `${this._numerator}`;
|
|
4372
|
+
}
|
|
4373
|
+
else if (this._numerator < 0) {
|
|
4374
|
+
return `-\\frac{ ${-this._numerator} }{ ${this._denominator} }`;
|
|
4375
|
+
}
|
|
4376
|
+
else {
|
|
4377
|
+
return `\\frac{ ${this._numerator} }{ ${this._denominator} }`;
|
|
4378
|
+
}
|
|
4368
4379
|
}
|
|
4369
4380
|
else {
|
|
4370
|
-
return
|
|
4381
|
+
return this.value.toFixed(3);
|
|
4371
4382
|
}
|
|
4372
4383
|
}
|
|
4373
4384
|
get display() {
|
|
4374
|
-
if (this.
|
|
4375
|
-
|
|
4385
|
+
if (this.isExact()) {
|
|
4386
|
+
if (this._denominator === 1) {
|
|
4387
|
+
return `${this._numerator}`;
|
|
4388
|
+
}
|
|
4389
|
+
else {
|
|
4390
|
+
return `${this._numerator}/${this._denominator}`;
|
|
4391
|
+
}
|
|
4376
4392
|
}
|
|
4377
4393
|
else {
|
|
4378
|
-
return
|
|
4394
|
+
return this.value.toFixed(3);
|
|
4379
4395
|
}
|
|
4380
4396
|
}
|
|
4381
4397
|
// Helper function to display fractions
|
|
@@ -4410,6 +4426,8 @@ Fraction.min = (...fractions) => {
|
|
|
4410
4426
|
}
|
|
4411
4427
|
return M;
|
|
4412
4428
|
};
|
|
4429
|
+
// ------------------------------------------
|
|
4430
|
+
// Creation / parsing functions
|
|
4413
4431
|
Fraction.average = (...fractions) => {
|
|
4414
4432
|
let M = new Fraction().zero();
|
|
4415
4433
|
for (let f of fractions) {
|
|
@@ -6831,6 +6849,7 @@ var ShutingyardType;
|
|
|
6831
6849
|
})(ShutingyardType = exports.ShutingyardType || (exports.ShutingyardType = {}));
|
|
6832
6850
|
var ShutingyardMode;
|
|
6833
6851
|
(function (ShutingyardMode) {
|
|
6852
|
+
ShutingyardMode["EXPRESSION"] = "expression";
|
|
6834
6853
|
ShutingyardMode["POLYNOM"] = "polynom";
|
|
6835
6854
|
ShutingyardMode["SET"] = "set";
|
|
6836
6855
|
ShutingyardMode["NUMERIC"] = "numeric";
|
|
@@ -6846,6 +6865,9 @@ class Shutingyard {
|
|
|
6846
6865
|
// console.log(this._rpn)
|
|
6847
6866
|
return this._rpn;
|
|
6848
6867
|
}
|
|
6868
|
+
get rpnToken() {
|
|
6869
|
+
return this._rpn.map(x => x.token);
|
|
6870
|
+
}
|
|
6849
6871
|
/**
|
|
6850
6872
|
* Determin if the token is a defined operation
|
|
6851
6873
|
* Defined operations: + - * / ^ sin cos tan
|
|
@@ -6887,6 +6909,22 @@ class Shutingyard {
|
|
|
6887
6909
|
};
|
|
6888
6910
|
this._uniformize = false;
|
|
6889
6911
|
}
|
|
6912
|
+
else if (this._mode === ShutingyardMode.EXPRESSION) {
|
|
6913
|
+
this._tokenConfig = {
|
|
6914
|
+
'^': { precedence: 4, associative: 'right', type: ShutingyardType.OPERATION },
|
|
6915
|
+
'*': { precedence: 3, associative: 'left', type: ShutingyardType.OPERATION },
|
|
6916
|
+
'/': { precedence: 3, associative: 'left', type: ShutingyardType.OPERATION },
|
|
6917
|
+
'+': { precedence: 2, associative: 'left', type: ShutingyardType.OPERATION },
|
|
6918
|
+
'-': { precedence: 2, associative: 'left', type: ShutingyardType.OPERATION },
|
|
6919
|
+
'%': { precedence: 3, associative: 'right', type: ShutingyardType.OPERATION },
|
|
6920
|
+
'sin': { precedence: 4, associative: 'right', type: ShutingyardType.FUNCTION },
|
|
6921
|
+
'cos': { precedence: 4, associative: 'right', type: ShutingyardType.FUNCTION },
|
|
6922
|
+
'tan': { precedence: 4, associative: 'right', type: ShutingyardType.FUNCTION },
|
|
6923
|
+
'sqrt': { precedence: 4, associative: 'right', type: ShutingyardType.FUNCTION },
|
|
6924
|
+
'nthrt': { precedence: 4, associative: 'right', type: ShutingyardType.FUNCTION },
|
|
6925
|
+
};
|
|
6926
|
+
this._uniformize = true;
|
|
6927
|
+
}
|
|
6890
6928
|
else {
|
|
6891
6929
|
this._tokenConfig = {
|
|
6892
6930
|
'^': { precedence: 4, associative: 'right', type: ShutingyardType.OPERATION },
|
|
@@ -6894,10 +6932,6 @@ class Shutingyard {
|
|
|
6894
6932
|
'/': { precedence: 3, associative: 'left', type: ShutingyardType.OPERATION },
|
|
6895
6933
|
'+': { precedence: 2, associative: 'left', type: ShutingyardType.OPERATION },
|
|
6896
6934
|
'-': { precedence: 2, associative: 'left', type: ShutingyardType.OPERATION },
|
|
6897
|
-
// '%': {precedence: 3, associative: 'right', type: ShutingyardType.OPERATION},
|
|
6898
|
-
// 'sin': {precedence: 4, associative: 'right', type: ShutingyardType.FUNCTION},
|
|
6899
|
-
// 'cos': {precedence: 4, associative: 'right', type: ShutingyardType.FUNCTION},
|
|
6900
|
-
// 'tan': {precedence: 4, associative: 'right', type: ShutingyardType.FUNCTION},
|
|
6901
6935
|
};
|
|
6902
6936
|
this._uniformize = true;
|
|
6903
6937
|
}
|
|
@@ -6929,9 +6963,6 @@ class Shutingyard {
|
|
|
6929
6963
|
tokenType = 'function-argument';
|
|
6930
6964
|
}
|
|
6931
6965
|
else {
|
|
6932
|
-
// Order token keys by token characters length (descending)
|
|
6933
|
-
// TODO: this is done each time ! SHould be done once !
|
|
6934
|
-
// const keys = Object.keys(this._tokenConfig).sort((a,b)=>b.length-a.length)
|
|
6935
6966
|
// Extract operation and function tokens
|
|
6936
6967
|
for (let key of this._tokenKeys) {
|
|
6937
6968
|
if (expr.substring(start, start + key.length) === key) {
|
|
@@ -6953,7 +6984,7 @@ class Shutingyard {
|
|
|
6953
6984
|
if (expr[start].match(/[0-9]/)) {
|
|
6954
6985
|
if (this._mode === ShutingyardMode.POLYNOM && false) {}
|
|
6955
6986
|
else {
|
|
6956
|
-
token = expr.substring(start).match(/^([0-9
|
|
6987
|
+
token = expr.substring(start).match(/^([0-9.]+)/)[0];
|
|
6957
6988
|
}
|
|
6958
6989
|
tokenType = ShutingyardType.COEFFICIENT;
|
|
6959
6990
|
}
|
|
@@ -6970,19 +7001,114 @@ class Shutingyard {
|
|
|
6970
7001
|
}
|
|
6971
7002
|
return [token, start + token.length, tokenType];
|
|
6972
7003
|
}
|
|
7004
|
+
normalize(expr) {
|
|
7005
|
+
// Get the list of function token.
|
|
7006
|
+
let fnToken = [], kToken = [];
|
|
7007
|
+
for (let token in this._tokenConfig) {
|
|
7008
|
+
if (this._tokenConfig[token].type === ShutingyardType.FUNCTION) {
|
|
7009
|
+
fnToken.push(token);
|
|
7010
|
+
}
|
|
7011
|
+
}
|
|
7012
|
+
// sort if from the lengthy to the smallest function
|
|
7013
|
+
fnToken.sort((a, b) => b.length - a.length);
|
|
7014
|
+
for (let token in exports.tokenConstant) {
|
|
7015
|
+
kToken.push(token);
|
|
7016
|
+
}
|
|
7017
|
+
// sort if from the lengthy to the smallest function
|
|
7018
|
+
kToken.sort((a, b) => b.length - a.length);
|
|
7019
|
+
let normalizedExpr = "", i = 0, crtToken, nextToken;
|
|
7020
|
+
while (i < expr.length - 1) {
|
|
7021
|
+
// Check if we have a function token.
|
|
7022
|
+
// The function MUST have an open parentheses
|
|
7023
|
+
let tokenIdx = 0;
|
|
7024
|
+
while (tokenIdx < fnToken.length) {
|
|
7025
|
+
let token = fnToken[tokenIdx];
|
|
7026
|
+
if (expr.slice(i, i + token.length + 1) === token + '(') {
|
|
7027
|
+
normalizedExpr += token + '(';
|
|
7028
|
+
i += token.length + 1;
|
|
7029
|
+
// Restart the scan for the function token
|
|
7030
|
+
tokenIdx = 0;
|
|
7031
|
+
}
|
|
7032
|
+
else {
|
|
7033
|
+
// scan for a next function token
|
|
7034
|
+
tokenIdx++;
|
|
7035
|
+
}
|
|
7036
|
+
}
|
|
7037
|
+
// Check for a constant
|
|
7038
|
+
tokenIdx = 0;
|
|
7039
|
+
while (tokenIdx < kToken.length) {
|
|
7040
|
+
let token = kToken[tokenIdx];
|
|
7041
|
+
if (expr.slice(i, i + token.length) === token) {
|
|
7042
|
+
// We have found a constant.
|
|
7043
|
+
// add it, but with remove the last letter
|
|
7044
|
+
normalizedExpr += token.slice(0, -1);
|
|
7045
|
+
i += token.length - 1;
|
|
7046
|
+
// Exit the loop
|
|
7047
|
+
break;
|
|
7048
|
+
}
|
|
7049
|
+
tokenIdx++;
|
|
7050
|
+
}
|
|
7051
|
+
// The function token are solved.
|
|
7052
|
+
crtToken = expr[i];
|
|
7053
|
+
nextToken = expr[i + 1];
|
|
7054
|
+
normalizedExpr += crtToken;
|
|
7055
|
+
if (crtToken.match(/[a-zA-Z]/g)) {
|
|
7056
|
+
// Current element is a letter.
|
|
7057
|
+
// if the next element is a letter, a number or an opening parentheses, add the multiplication sign.
|
|
7058
|
+
if (nextToken.match(/[a-zA-Z\d(]/)) {
|
|
7059
|
+
normalizedExpr += '*';
|
|
7060
|
+
}
|
|
7061
|
+
}
|
|
7062
|
+
else if (crtToken.match(/\d/)) {
|
|
7063
|
+
// Current element is a number.
|
|
7064
|
+
// if the next element is a letter or a parentheses, add the multiplication sign.
|
|
7065
|
+
if (nextToken.match(/[a-zA-Z(]/)) {
|
|
7066
|
+
normalizedExpr += '*';
|
|
7067
|
+
}
|
|
7068
|
+
}
|
|
7069
|
+
else if (crtToken === ')') {
|
|
7070
|
+
// Current element is a closing parentheses.
|
|
7071
|
+
// if the next element is a letter, a number or an opening parentheses, add the multiplication sign
|
|
7072
|
+
if (nextToken.match(/[a-zA-Z\d(]/)) {
|
|
7073
|
+
normalizedExpr += '*';
|
|
7074
|
+
}
|
|
7075
|
+
}
|
|
7076
|
+
// Go to next token
|
|
7077
|
+
i++;
|
|
7078
|
+
}
|
|
7079
|
+
// add the last token
|
|
7080
|
+
return normalizedExpr + nextToken;
|
|
7081
|
+
}
|
|
6973
7082
|
/**
|
|
6974
7083
|
* Sanitize an expression by adding missing common operation (multiplication between parentheseses)
|
|
6975
7084
|
* @param expr
|
|
6976
7085
|
* @constructor
|
|
6977
7086
|
*/
|
|
6978
7087
|
Uniformizer(expr) {
|
|
7088
|
+
// TODO: Delete this old version
|
|
7089
|
+
// Prefere "normalize", much more robust !
|
|
6979
7090
|
// Determiner if need to be uniformized
|
|
6980
7091
|
if (!this._uniformize) {
|
|
6981
7092
|
return expr;
|
|
6982
7093
|
}
|
|
7094
|
+
// Generate the list of function token.
|
|
7095
|
+
let fnToken = [];
|
|
7096
|
+
for (let token in this._tokenConfig) {
|
|
7097
|
+
if (this._tokenConfig[token].type === ShutingyardType.FUNCTION) {
|
|
7098
|
+
fnToken.push(token);
|
|
7099
|
+
}
|
|
7100
|
+
}
|
|
7101
|
+
// sort if from the lengthy to the smallest function
|
|
7102
|
+
fnToken.sort((a, b) => b.length - a.length);
|
|
7103
|
+
let tokenRegExp = new RegExp(`(${fnToken.join('|')})`, 'g');
|
|
7104
|
+
let functionTokenOrder = Array.from(expr.matchAll(tokenRegExp));
|
|
6983
7105
|
let expr2;
|
|
7106
|
+
// Replace all function by @
|
|
7107
|
+
expr2 = expr.replace(tokenRegExp, '@');
|
|
7108
|
+
// Add * before @ (functionn)
|
|
7109
|
+
expr2 = expr2.replace(/([\da-zA-Z])(@)/g, "$1*$2");
|
|
6984
7110
|
// Replace missing multiplication between two parenthese
|
|
6985
|
-
expr2 =
|
|
7111
|
+
expr2 = expr2.replace(/\)\(/g, ')*(');
|
|
6986
7112
|
// Replace missing multiplication between number or setLetter and parenthese.
|
|
6987
7113
|
// 3x(x-4) => 3x*(x-4)
|
|
6988
7114
|
expr2 = expr2.replace(/([\da-zA-Z])(\()/g, "$1*$2");
|
|
@@ -6992,14 +7118,24 @@ class Shutingyard {
|
|
|
6992
7118
|
// 3x => 3*x
|
|
6993
7119
|
expr2 = expr2.replace(/([0-9])([a-zA-Z])/g, "$1*$2");
|
|
6994
7120
|
expr2 = expr2.replace(/([a-zA-Z])([0-9])/g, "$1*$2");
|
|
7121
|
+
// Remove letter between function token and it's parenthese.
|
|
7122
|
+
// for (let token of fnToken) {
|
|
7123
|
+
// // Remove
|
|
7124
|
+
// expr2 = expr2.replace(new RegExp(token + '\\*', 'g'), token);
|
|
7125
|
+
// }
|
|
6995
7126
|
// Add multiplication between letters ?
|
|
6996
|
-
|
|
6997
|
-
expr2 = expr2.replace(/([
|
|
6998
|
-
// Restore operation auto
|
|
6999
|
-
|
|
7000
|
-
|
|
7001
|
-
|
|
7002
|
-
|
|
7127
|
+
expr2 = expr2.replace(/([a-zA-Z])([a-zA-Z])/g, "$1*$2");
|
|
7128
|
+
expr2 = expr2.replace(/([a-zA-Z])([a-zA-Z])/g, "$1*$2");
|
|
7129
|
+
// Restore operation auto formatting (prevent adding the multiplication star)
|
|
7130
|
+
let exprAsArray = expr2.split('@');
|
|
7131
|
+
if (exprAsArray.length > 0) {
|
|
7132
|
+
expr2 = "";
|
|
7133
|
+
for (let idx in exprAsArray) {
|
|
7134
|
+
}
|
|
7135
|
+
for (let token of fnToken) {
|
|
7136
|
+
// Remove
|
|
7137
|
+
// expr2 = expr2.replace(new RegExp(token + '\\*', 'g'), token);
|
|
7138
|
+
}
|
|
7003
7139
|
}
|
|
7004
7140
|
return expr2;
|
|
7005
7141
|
}
|
|
@@ -7013,7 +7149,9 @@ class Shutingyard {
|
|
|
7013
7149
|
let outQueue = [], // Output queue
|
|
7014
7150
|
opStack = [], // Operation queue
|
|
7015
7151
|
token = '', tokenPos = 0, tokenType = '', previousOpStatckLength = 0;
|
|
7016
|
-
|
|
7152
|
+
// Normalize the input if required.
|
|
7153
|
+
if (this._uniformize)
|
|
7154
|
+
expr = this.normalize(expr);
|
|
7017
7155
|
let securityLoopLvl1 = 50, securityLoopLvl2_default = 50, securityLoopLvl2;
|
|
7018
7156
|
while (tokenPos < expr.length) {
|
|
7019
7157
|
securityLoopLvl1--;
|
|
@@ -7032,10 +7170,6 @@ class Shutingyard {
|
|
|
7032
7170
|
token,
|
|
7033
7171
|
tokenType
|
|
7034
7172
|
});
|
|
7035
|
-
// if(previousOpStatckLength == opStack.length && outQueue.length>=2){
|
|
7036
|
-
// console.log('opStatckLength', outQueue, opStack.length)
|
|
7037
|
-
// outQueue.push('*')
|
|
7038
|
-
// }
|
|
7039
7173
|
break;
|
|
7040
7174
|
case 'operation':
|
|
7041
7175
|
previousOpStatckLength = opStack.length;
|