math-exercises 2.0.18 → 2.0.20
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/lib/exercises/calculLitteral/equation/firstDegreeEquation.js +1 -1
- package/lib/exercises/percent/applyPercent.js +1 -1
- package/lib/exercises/trigonometry/remarkableValues.js +1 -1
- package/lib/server.js +10 -12
- package/lib/tree/nodes/functions/oppositeNode.d.ts +1 -1
- package/lib/tree/nodes/functions/oppositeNode.js +2 -1
- package/lib/tree/nodes/operators/powerNode.d.ts.map +1 -1
- package/lib/tree/nodes/operators/powerNode.js +6 -3
- package/lib/tree/nodes/operators/substractNode.js +1 -1
- package/lib/tree/parsers/latexParser.d.ts +4 -0
- package/lib/tree/parsers/latexParser.d.ts.map +1 -0
- package/lib/tree/parsers/latexParser.js +287 -0
- package/package.json +1 -1
|
@@ -48,7 +48,7 @@ exports.firstDegreeEquation = {
|
|
|
48
48
|
connector: "=",
|
|
49
49
|
label: "Résoudre une équation du premier degré du type $\\frac{a}{x} = b$",
|
|
50
50
|
levels: ["2nde", "1reESM", "1reSpé"],
|
|
51
|
-
sections: ["Équations"],
|
|
51
|
+
sections: ["Équations", "Fonction inverse", "Fonctions de référence"],
|
|
52
52
|
isSingleStep: false,
|
|
53
53
|
generator: (nb) => (0, getDistinctQuestions_1.getDistinctQuestions)(getFirstDegreeEquation, nb),
|
|
54
54
|
getPropositions,
|
|
@@ -56,7 +56,7 @@ const isAnswerValid = (ans, { answer }) => {
|
|
|
56
56
|
exports.applyPercent = {
|
|
57
57
|
id: "applyPercent",
|
|
58
58
|
connector: "=",
|
|
59
|
-
label: "Appliquer un pourcentage d'augmentation ou de diminution
|
|
59
|
+
label: "Appliquer un pourcentage d'augmentation ou de diminution",
|
|
60
60
|
levels: [
|
|
61
61
|
"4ème",
|
|
62
62
|
"3ème",
|
|
@@ -52,7 +52,7 @@ const getPropositions = (n, { answer }) => {
|
|
|
52
52
|
return (0, shuffle_1.shuffle)(propositions);
|
|
53
53
|
};
|
|
54
54
|
const isAnswerValid = (ans, { mainValue, isCos }) => {
|
|
55
|
-
const remarkableValue = remarkableValues_1.remarkableTrigoValues.find((point) => point.angle.evaluate({})
|
|
55
|
+
const remarkableValue = remarkableValues_1.remarkableTrigoValues.find((point) => Math.abs(point.angle.evaluate({}) - mainValue) < 0.0001);
|
|
56
56
|
const answer = isCos ? remarkableValue.cos : remarkableValue.sin;
|
|
57
57
|
const texs = answer.toAllValidTexs({
|
|
58
58
|
allowFractionToDecimal: true,
|
package/lib/server.js
CHANGED
|
@@ -35,24 +35,22 @@ const express_1 = __importDefault(require("express"));
|
|
|
35
35
|
const body_parser_1 = __importDefault(require("body-parser"));
|
|
36
36
|
const dotenv_1 = __importDefault(require("dotenv"));
|
|
37
37
|
const cors_1 = __importDefault(require("cors"));
|
|
38
|
-
const addNode_1 = require("./tree/nodes/operators/addNode");
|
|
39
|
-
const numberNode_1 = require("./tree/nodes/numbers/numberNode");
|
|
40
|
-
const powerNode_1 = require("./tree/nodes/operators/powerNode");
|
|
41
|
-
const sqrtNode_1 = require("./tree/nodes/functions/sqrtNode");
|
|
42
|
-
const multiplyNode_1 = require("./tree/nodes/operators/multiplyNode");
|
|
43
38
|
const jsonParser = body_parser_1.default.json();
|
|
44
39
|
const allExercises = [...exercises];
|
|
45
40
|
const runServer = () => {
|
|
46
41
|
dotenv_1.default.config();
|
|
47
42
|
const app = (0, express_1.default)();
|
|
48
43
|
app.use((0, cors_1.default)());
|
|
49
|
-
|
|
50
|
-
const
|
|
51
|
-
const
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
console.log(
|
|
44
|
+
// const string = "\\frac{9}{12}";
|
|
45
|
+
// const a = string.match(/^[0-9]+,?[0-9]*/);
|
|
46
|
+
// const before = Date.now();
|
|
47
|
+
// const parsed = parseLatex(string);
|
|
48
|
+
// console.log("res", parsed);
|
|
49
|
+
// console.log(parsed?.toTex());
|
|
50
|
+
// console.log(parsed?.simplify().toTex());
|
|
51
|
+
// console.log(parsed?.evaluate({ x: 1 }));
|
|
52
|
+
// console.log("time", Date.now() - before);
|
|
53
|
+
// tokenize(string);
|
|
56
54
|
app.get("/", (req, res) => {
|
|
57
55
|
res.json(allExercises);
|
|
58
56
|
});
|
|
@@ -19,7 +19,7 @@ export declare class OppositeNode implements FunctionNode {
|
|
|
19
19
|
*/
|
|
20
20
|
toAllValidTexs(opts?: NodeOptions): string[];
|
|
21
21
|
evaluate(vars: Record<string, number>): number;
|
|
22
|
-
simplify(opts?: SimplifyOptions):
|
|
22
|
+
simplify(opts?: SimplifyOptions): AlgebraicNode;
|
|
23
23
|
equals(node: AlgebraicNode): boolean;
|
|
24
24
|
}
|
|
25
25
|
//# sourceMappingURL=oppositeNode.d.ts.map
|
|
@@ -6,6 +6,7 @@ const node_1 = require("../node");
|
|
|
6
6
|
const operatorNode_1 = require("../operators/operatorNode");
|
|
7
7
|
const functionNode_1 = require("./functionNode");
|
|
8
8
|
const numberNode_1 = require("../numbers/numberNode");
|
|
9
|
+
const multiplyNode_1 = require("../operators/multiplyNode");
|
|
9
10
|
const fractionNode_1 = require("../operators/fractionNode");
|
|
10
11
|
function isOppositeNode(a) {
|
|
11
12
|
return (0, functionNode_1.isFunctionNode)(a) && a.id === functionNode_1.FunctionsIds.opposite;
|
|
@@ -70,7 +71,7 @@ class OppositeNode {
|
|
|
70
71
|
return -this.child.evaluate(vars);
|
|
71
72
|
}
|
|
72
73
|
simplify(opts) {
|
|
73
|
-
return new
|
|
74
|
+
return new multiplyNode_1.MultiplyNode(new numberNode_1.NumberNode(-1), this.child).simplify(opts);
|
|
74
75
|
}
|
|
75
76
|
equals(node) {
|
|
76
77
|
return isOppositeNode(node) && node.child.equals(this.child);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"powerNode.d.ts","sourceRoot":"","sources":["../../../../src/tree/nodes/operators/powerNode.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,YAAY,EAAkB,MAAM,gBAAgB,CAAC;AAG3E,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAOlE,wBAAgB,WAAW,CAAC,CAAC,EAAE,IAAI,GAAG,CAAC,IAAI,SAAS,CAEnD;AAED,qBAAa,SAAU,YAAW,YAAY;IAC5C,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,EAAE,EAAE,WAAW,CAAC;IAChB,SAAS,EAAE,aAAa,CAAC;IACzB,UAAU,EAAE,aAAa,CAAC;IAC1B,IAAI,EAAE,QAAQ,CAAC;IACf,SAAS,EAAE,OAAO,CAAC;gBAEjB,SAAS,EAAE,aAAa,EACxB,UAAU,EAAE,aAAa,EACzB,IAAI,CAAC,EAAE,WAAW;IAUpB,YAAY,IAAI,MAAM;IAItB,iBAAiB;IAqBjB,cAAc,IAAI,MAAM,EAAE;IAI1B,KAAK,IAAI,MAAM;IAuBf,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IA+FrC,QAAQ,CAAC,IAAI,CAAC,EAAE,eAAe,GAAG,aAAa;
|
|
1
|
+
{"version":3,"file":"powerNode.d.ts","sourceRoot":"","sources":["../../../../src/tree/nodes/operators/powerNode.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,YAAY,EAAkB,MAAM,gBAAgB,CAAC;AAG3E,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAOlE,wBAAgB,WAAW,CAAC,CAAC,EAAE,IAAI,GAAG,CAAC,IAAI,SAAS,CAEnD;AAED,qBAAa,SAAU,YAAW,YAAY;IAC5C,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,EAAE,EAAE,WAAW,CAAC;IAChB,SAAS,EAAE,aAAa,CAAC;IACzB,UAAU,EAAE,aAAa,CAAC;IAC1B,IAAI,EAAE,QAAQ,CAAC;IACf,SAAS,EAAE,OAAO,CAAC;gBAEjB,SAAS,EAAE,aAAa,EACxB,UAAU,EAAE,aAAa,EACzB,IAAI,CAAC,EAAE,WAAW;IAUpB,YAAY,IAAI,MAAM;IAItB,iBAAiB;IAqBjB,cAAc,IAAI,MAAM,EAAE;IAI1B,KAAK,IAAI,MAAM;IAuBf,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IA+FrC,QAAQ,CAAC,IAAI,CAAC,EAAE,eAAe,GAAG,aAAa;IAY/C,MAAM,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO;CAOrC;AAED,qBAAa,UAAW,SAAQ,SAAS;gBAC3B,KAAK,EAAE,aAAa,EAAE,IAAI,CAAC,EAAE,WAAW;CAGrD"}
|
|
@@ -157,11 +157,14 @@ class PowerNode {
|
|
|
157
157
|
// // puissances négatives ?
|
|
158
158
|
// }
|
|
159
159
|
simplify(opts) {
|
|
160
|
+
const leftSimplified = this.leftChild.simplify(opts);
|
|
161
|
+
const rightSimplified = this.rightChild.simplify(opts);
|
|
162
|
+
const copy = new PowerNode(leftSimplified, rightSimplified, this.opts);
|
|
160
163
|
//! temporaire
|
|
161
|
-
if ((0, numberNode_1.isNumberNode)(
|
|
162
|
-
return new multiplyNode_1.MultiplyNode(
|
|
164
|
+
if ((0, numberNode_1.isNumberNode)(copy.rightChild) && copy.rightChild.value === 2) {
|
|
165
|
+
return new multiplyNode_1.MultiplyNode(copy.leftChild, copy.leftChild).simplify(opts);
|
|
163
166
|
}
|
|
164
|
-
return
|
|
167
|
+
return copy;
|
|
165
168
|
}
|
|
166
169
|
equals(node) {
|
|
167
170
|
return (isPowerNode(node) &&
|
|
@@ -43,7 +43,7 @@ class SubstractNode {
|
|
|
43
43
|
[operatorNode_1.OperatorIds.add, operatorNode_1.OperatorIds.substract].includes(this.rightChild.id)) ||
|
|
44
44
|
rightTex[0] === "-";
|
|
45
45
|
if (needBrackets)
|
|
46
|
-
rightTex =
|
|
46
|
+
rightTex = `\\left(${rightTex}\\right)`;
|
|
47
47
|
return `${leftTex}-${rightTex}`;
|
|
48
48
|
}
|
|
49
49
|
evaluate(vars) {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"latexParser.d.ts","sourceRoot":"","sources":["../../../src/tree/parsers/latexParser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AA0CvD,eAAO,MAAM,QAAQ,UAAW,MAAM,aA4BrC,CAAC;AAEF,eAAO,MAAM,UAAU,UAAW,MAAM,kBAavC,CAAC"}
|
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseLatex = exports.tokenize = void 0;
|
|
4
|
+
const oppositeNode_1 = require("../nodes/functions/oppositeNode");
|
|
5
|
+
const sqrtNode_1 = require("../nodes/functions/sqrtNode");
|
|
6
|
+
const numberNode_1 = require("../nodes/numbers/numberNode");
|
|
7
|
+
const addNode_1 = require("../nodes/operators/addNode");
|
|
8
|
+
const fractionNode_1 = require("../nodes/operators/fractionNode");
|
|
9
|
+
const multiplyNode_1 = require("../nodes/operators/multiplyNode");
|
|
10
|
+
const powerNode_1 = require("../nodes/operators/powerNode");
|
|
11
|
+
const substractNode_1 = require("../nodes/operators/substractNode");
|
|
12
|
+
const variableNode_1 = require("../nodes/variables/variableNode");
|
|
13
|
+
//cmd that needs a child, like \exp{3}
|
|
14
|
+
const functions = [
|
|
15
|
+
"\\exp",
|
|
16
|
+
"\\sqrt",
|
|
17
|
+
"\\log",
|
|
18
|
+
"\\ln",
|
|
19
|
+
"\\cos",
|
|
20
|
+
"\\sin",
|
|
21
|
+
"\\frac",
|
|
22
|
+
];
|
|
23
|
+
const operators = ["+", "-", "\\div", "\\times", "^"];
|
|
24
|
+
const isDyck = (tokens) => {
|
|
25
|
+
const brackets = tokens.filter((el) => el === "(" || el === ")");
|
|
26
|
+
while (brackets.length) {
|
|
27
|
+
const rightIndex = brackets.findIndex((el) => el == ")");
|
|
28
|
+
if (rightIndex === -1 || rightIndex === 0)
|
|
29
|
+
return false;
|
|
30
|
+
let leftIndex = -1;
|
|
31
|
+
for (let i = rightIndex - 1; i > -1; i--) {
|
|
32
|
+
if (brackets[i] === "(") {
|
|
33
|
+
leftIndex = i;
|
|
34
|
+
}
|
|
35
|
+
break;
|
|
36
|
+
}
|
|
37
|
+
if (leftIndex === -1)
|
|
38
|
+
return false;
|
|
39
|
+
brackets.splice(rightIndex, 1);
|
|
40
|
+
brackets.splice(leftIndex, 1);
|
|
41
|
+
}
|
|
42
|
+
return true;
|
|
43
|
+
};
|
|
44
|
+
const tokenize = (latex) => {
|
|
45
|
+
const tokens = [];
|
|
46
|
+
for (let i = 0; i < latex.length; i++) {
|
|
47
|
+
const char = latex[i];
|
|
48
|
+
if (char === " ")
|
|
49
|
+
continue;
|
|
50
|
+
const match = char.match(/[\+\-\(\)\^a-zA-Z_=\{\}]/);
|
|
51
|
+
if (match) {
|
|
52
|
+
tokens.push(char);
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
const substring = latex.substring(i);
|
|
56
|
+
const nbMatch = substring.match(/^[0-9]+,?[0-9]*/); //x nombres éventuellement séparés par une virgule
|
|
57
|
+
if (nbMatch) {
|
|
58
|
+
tokens.push(nbMatch[0].replace(",", "."));
|
|
59
|
+
i += nbMatch[0].length - 1;
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
const cmdMatch = substring.match(/^\\[a-z]+/i);
|
|
63
|
+
if (cmdMatch) {
|
|
64
|
+
tokens.push(cmdMatch[0]);
|
|
65
|
+
i += cmdMatch[0].length - 1;
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return tokens;
|
|
70
|
+
};
|
|
71
|
+
exports.tokenize = tokenize;
|
|
72
|
+
const parseLatex = (latex) => {
|
|
73
|
+
const formattedLatex = latex
|
|
74
|
+
.replaceAll("\\left", "")
|
|
75
|
+
.replaceAll("\\right", "");
|
|
76
|
+
const tokens = (0, exports.tokenize)(formattedLatex);
|
|
77
|
+
if (!isDyck(tokens))
|
|
78
|
+
throw Error("Problème de parenthèses.");
|
|
79
|
+
try {
|
|
80
|
+
const parsed = buildTree(tokens);
|
|
81
|
+
return parsed;
|
|
82
|
+
}
|
|
83
|
+
catch (err) {
|
|
84
|
+
throw err;
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
exports.parseLatex = parseLatex;
|
|
88
|
+
const buildTree = (tokens) => {
|
|
89
|
+
let currentDepth = 0;
|
|
90
|
+
let maxDepth = 0;
|
|
91
|
+
const depthedTokens = [];
|
|
92
|
+
for (const token of tokens) {
|
|
93
|
+
if (token === "(" || token === "{")
|
|
94
|
+
currentDepth++;
|
|
95
|
+
depthedTokens.push({
|
|
96
|
+
token,
|
|
97
|
+
depth: currentDepth,
|
|
98
|
+
});
|
|
99
|
+
if (currentDepth > maxDepth)
|
|
100
|
+
maxDepth = currentDepth;
|
|
101
|
+
if (token === ")" || token === "}")
|
|
102
|
+
currentDepth--;
|
|
103
|
+
}
|
|
104
|
+
console.log("depthed: ", depthedTokens);
|
|
105
|
+
while (true) {
|
|
106
|
+
if (maxDepth === 0) {
|
|
107
|
+
const tree = buildTreeForSameDepthTokens(depthedTokens.map((el) => el.token));
|
|
108
|
+
return tree;
|
|
109
|
+
}
|
|
110
|
+
for (let i = 0; i < depthedTokens.length; i++) {
|
|
111
|
+
const token = depthedTokens[i];
|
|
112
|
+
if (token.depth < maxDepth)
|
|
113
|
+
continue;
|
|
114
|
+
//le token est forcément ici ( ou {
|
|
115
|
+
//et on est sur qu'il n'y a aucun autre nestage à l'intérieur
|
|
116
|
+
const endIndex = depthedTokens.findIndex((el, index) => index > i && (el.token === ")" || el.token === "}"));
|
|
117
|
+
const tree = buildTreeForSameDepthTokens(depthedTokens.slice(i + 1, endIndex).map((el) => el.token));
|
|
118
|
+
depthedTokens.splice(i, endIndex - i + 1, {
|
|
119
|
+
token: tree,
|
|
120
|
+
depth: token.depth - 1,
|
|
121
|
+
});
|
|
122
|
+
console.log(`depthed after iter ${i}`, depthedTokens);
|
|
123
|
+
}
|
|
124
|
+
maxDepth--;
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
const buildTreeForSameDepthTokens = (tokens) => {
|
|
128
|
+
console.log("start: ", tokens);
|
|
129
|
+
let tempTokens = [];
|
|
130
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
131
|
+
const token = tokens[i];
|
|
132
|
+
if (typeof token !== "string") {
|
|
133
|
+
tempTokens[i] = token;
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
if (token[0].match(/[0-9]/)) {
|
|
137
|
+
tempTokens[i] = new numberNode_1.NumberNode(Number(token));
|
|
138
|
+
}
|
|
139
|
+
else if (token[0].match(/[a-z]/i))
|
|
140
|
+
tempTokens[i] = new variableNode_1.VariableNode(token);
|
|
141
|
+
//! les fonctions qui attendent un child ne sont pas encore parsées
|
|
142
|
+
else if (functions.includes(token)) {
|
|
143
|
+
tempTokens[i] = token;
|
|
144
|
+
}
|
|
145
|
+
//!idem pour les opérators
|
|
146
|
+
else if (operators.includes(token))
|
|
147
|
+
tempTokens[i] = token;
|
|
148
|
+
else
|
|
149
|
+
throw Error(`token not implemented: ${token}`);
|
|
150
|
+
}
|
|
151
|
+
console.log("after parses : ", tempTokens);
|
|
152
|
+
//1 build les fct
|
|
153
|
+
for (let i = 0; i < tempTokens.length; i++) {
|
|
154
|
+
if (typeof tempTokens[i] !== "string")
|
|
155
|
+
continue;
|
|
156
|
+
const token = tempTokens[i];
|
|
157
|
+
if (functions.includes(token)) {
|
|
158
|
+
if (typeof tempTokens[i + 1] === "string")
|
|
159
|
+
throw Error(`Function child has not been parsed at index ${i}`);
|
|
160
|
+
switch (token) {
|
|
161
|
+
case "\\sqrt":
|
|
162
|
+
tempTokens[i] = new sqrtNode_1.SqrtNode(tempTokens[i + 1]);
|
|
163
|
+
tempTokens.splice(i + 1, 1);
|
|
164
|
+
break;
|
|
165
|
+
case "\\frac":
|
|
166
|
+
tempTokens[i] = new fractionNode_1.FractionNode(tempTokens[i + 1], tempTokens[i + 2]);
|
|
167
|
+
tempTokens.splice(i + 1, 2);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
if (token === "^") {
|
|
171
|
+
if (!tempTokens[i - 1] ||
|
|
172
|
+
typeof tempTokens[i - 1] === "string" ||
|
|
173
|
+
!tempTokens[i + 1] ||
|
|
174
|
+
typeof tempTokens[i + 1] === "string")
|
|
175
|
+
throw Error("Error parsing power node");
|
|
176
|
+
else {
|
|
177
|
+
tempTokens[i - 1] = new powerNode_1.PowerNode(tempTokens[i - 1], tempTokens[i + 1]);
|
|
178
|
+
tempTokens.splice(i, 2);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
//2 build les opposites
|
|
183
|
+
for (let i = 0; i < tempTokens.length; i++) {
|
|
184
|
+
const token = tempTokens[i];
|
|
185
|
+
if (token === "-") {
|
|
186
|
+
if (i === 0 ||
|
|
187
|
+
tempTokens[i - 1] === "\\times" ||
|
|
188
|
+
tempTokens[i - 1] === "+" ||
|
|
189
|
+
tempTokens[i - 1] === "-") {
|
|
190
|
+
//faire la liste des - conéscutifs
|
|
191
|
+
let j = i + 1;
|
|
192
|
+
while (tempTokens[j] === "-" && j < tempTokens.length) {
|
|
193
|
+
j++;
|
|
194
|
+
}
|
|
195
|
+
if (j === tempTokens.length)
|
|
196
|
+
throw Error("Nothing after minus");
|
|
197
|
+
const nextToken = tempTokens[j];
|
|
198
|
+
//! à ce stade, le nextToken est soit un node, soit : + ou \\times
|
|
199
|
+
//!on fait ici le choix d'interdire -+x
|
|
200
|
+
if (typeof nextToken === "string") {
|
|
201
|
+
throw Error("Opposé pas clair");
|
|
202
|
+
}
|
|
203
|
+
const oppositeCount = j - i;
|
|
204
|
+
let node = nextToken;
|
|
205
|
+
for (let k = 0; k < oppositeCount; k++) {
|
|
206
|
+
node = new oppositeNode_1.OppositeNode(node);
|
|
207
|
+
}
|
|
208
|
+
tempTokens[i] = node;
|
|
209
|
+
tempTokens.splice(i + 1, oppositeCount);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
console.log("after fcts: ", tempTokens);
|
|
214
|
+
//3 build les *
|
|
215
|
+
let currentProduct;
|
|
216
|
+
let currentProductStartIndex;
|
|
217
|
+
for (let i = 0; i < tempTokens.length; i++) {
|
|
218
|
+
const token = tempTokens[i];
|
|
219
|
+
if (token === "\\times")
|
|
220
|
+
continue;
|
|
221
|
+
//la seule chose qui arrete un produit est + ou -
|
|
222
|
+
//y a t il d'autres cas ?
|
|
223
|
+
//? rappel ici on est sur une expression de niveau uniforme (sans parentheses ni childs)
|
|
224
|
+
if (token === "+" || token === "-") {
|
|
225
|
+
if (currentProduct &&
|
|
226
|
+
(0, multiplyNode_1.isMultiplyNode)(currentProduct) &&
|
|
227
|
+
currentProductStartIndex !== undefined) {
|
|
228
|
+
tempTokens[currentProductStartIndex] = currentProduct;
|
|
229
|
+
tempTokens.splice(currentProductStartIndex + 1, i - currentProductStartIndex - 1);
|
|
230
|
+
i = currentProductStartIndex + 1;
|
|
231
|
+
}
|
|
232
|
+
currentProduct = undefined;
|
|
233
|
+
currentProductStartIndex = undefined;
|
|
234
|
+
continue;
|
|
235
|
+
}
|
|
236
|
+
else {
|
|
237
|
+
if (currentProduct) {
|
|
238
|
+
currentProduct = new multiplyNode_1.MultiplyNode(currentProduct, token);
|
|
239
|
+
}
|
|
240
|
+
else {
|
|
241
|
+
currentProduct = token;
|
|
242
|
+
currentProductStartIndex = i;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
if (currentProduct &&
|
|
247
|
+
(0, multiplyNode_1.isMultiplyNode)(currentProduct) &&
|
|
248
|
+
currentProductStartIndex !== undefined) {
|
|
249
|
+
tempTokens[currentProductStartIndex] = currentProduct;
|
|
250
|
+
tempTokens.splice(currentProductStartIndex + 1, tempTokens.length - 1 - currentProductStartIndex);
|
|
251
|
+
}
|
|
252
|
+
//4 build les +
|
|
253
|
+
let currentAdd;
|
|
254
|
+
console.log("beforeAdd", tempTokens);
|
|
255
|
+
for (let i = 0; i < tempTokens.length; i++) {
|
|
256
|
+
const token = tempTokens[i];
|
|
257
|
+
if (!currentAdd) {
|
|
258
|
+
if (typeof token === "string") {
|
|
259
|
+
if (token === "+" || token === "-") {
|
|
260
|
+
throw Error("Addition with no first term");
|
|
261
|
+
}
|
|
262
|
+
else
|
|
263
|
+
throw Error(`unexpected non parsed token ${token}`);
|
|
264
|
+
}
|
|
265
|
+
else {
|
|
266
|
+
currentAdd = token;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
else {
|
|
270
|
+
if (typeof token !== "string" || (token !== "+" && token !== "-")) {
|
|
271
|
+
throw Error(`unexpected consecutive nodes without addition : ${token}`);
|
|
272
|
+
}
|
|
273
|
+
const next = tempTokens[i + 1];
|
|
274
|
+
if (typeof next === "string") {
|
|
275
|
+
throw Error(`unexpected non parsed token ${next}`);
|
|
276
|
+
}
|
|
277
|
+
else {
|
|
278
|
+
if (token === "+")
|
|
279
|
+
currentAdd = new addNode_1.AddNode(currentAdd, next);
|
|
280
|
+
else
|
|
281
|
+
currentAdd = new substractNode_1.SubstractNode(currentAdd, next);
|
|
282
|
+
i++;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
return currentAdd;
|
|
287
|
+
};
|