math-exercises 2.0.19 → 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.
@@ -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({}) === mainValue);
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
@@ -41,13 +41,16 @@ const runServer = () => {
41
41
  dotenv_1.default.config();
42
42
  const app = (0, express_1.default)();
43
43
  app.use((0, cors_1.default)());
44
- // const latex = "\\sqrt{3,230982}";
45
- // try {
46
- // const res = parseLatex(latex);
47
- // console.log(res.toTex());
48
- // } catch (err) {
49
- // throw err;
50
- // }
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);
51
54
  app.get("/", (req, res) => {
52
55
  res.json(allExercises);
53
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): OppositeNode;
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 OppositeNode(this.child.simplify(opts));
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;IAO/C,MAAM,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO;CAOrC;AAED,qBAAa,UAAW,SAAQ,SAAS;gBAC3B,KAAK,EAAE,aAAa,EAAE,IAAI,CAAC,EAAE,WAAW;CAGrD"}
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)(this.rightChild) && this.rightChild.value === 2) {
162
- return new multiplyNode_1.MultiplyNode(this.leftChild, this.leftChild).simplify(opts);
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 this;
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 = `(${rightTex})`;
46
+ rightTex = `\\left(${rightTex}\\right)`;
47
47
  return `${leftTex}-${rightTex}`;
48
48
  }
49
49
  evaluate(vars) {
@@ -1,3 +1,4 @@
1
1
  import { AlgebraicNode } from "../nodes/algebraicNode";
2
+ export declare const tokenize: (latex: string) => string[];
2
3
  export declare const parseLatex: (latex: string) => AlgebraicNode;
3
4
  //# sourceMappingURL=latexParser.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"latexParser.d.ts","sourceRoot":"","sources":["../../../src/tree/parsers/latexParser.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AA2BvD,eAAO,MAAM,UAAU,UAAW,MAAM,kBAgBvC,CAAC"}
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"}
@@ -1,11 +1,28 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.parseLatex = void 0;
4
- const isLetter_1 = require("../../utils/isLetter");
3
+ exports.parseLatex = exports.tokenize = void 0;
4
+ const oppositeNode_1 = require("../nodes/functions/oppositeNode");
5
5
  const sqrtNode_1 = require("../nodes/functions/sqrtNode");
6
6
  const numberNode_1 = require("../nodes/numbers/numberNode");
7
- const isDyck = (latex) => {
8
- const brackets = latex.split("").filter((el) => el === "(" || el === ")");
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 === ")");
9
26
  while (brackets.length) {
10
27
  const rightIndex = brackets.findIndex((el) => el == ")");
11
28
  if (rightIndex === -1 || rightIndex === 0)
@@ -24,157 +41,247 @@ const isDyck = (latex) => {
24
41
  }
25
42
  return true;
26
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;
27
72
  const parseLatex = (latex) => {
28
73
  const formattedLatex = latex
29
74
  .replaceAll("\\left", "")
30
75
  .replaceAll("\\right", "");
31
- const isWellBracketed = isDyck(latex);
32
- if (!isWellBracketed)
76
+ const tokens = (0, exports.tokenize)(formattedLatex);
77
+ if (!isDyck(tokens))
33
78
  throw Error("Problème de parenthèses.");
34
- let currentTree;
35
- let currentItem;
36
- const length = formattedLatex.length;
37
79
  try {
38
- const parsed = parseString(latex);
39
- return parsed.node;
80
+ const parsed = buildTree(tokens);
81
+ return parsed;
40
82
  }
41
83
  catch (err) {
42
84
  throw err;
43
85
  }
44
86
  };
45
87
  exports.parseLatex = parseLatex;
46
- const parseString = (latex) => {
47
- let currentTree;
48
- let currentItem;
49
- let currentAddCandidate;
50
- const length = latex.length;
51
- let jump = 0;
52
- try {
53
- for (let i = 0; i < length; i++) {
54
- const char = latex[i];
55
- const parsed = parseItem(latex);
56
- currentItem = parsed.node;
57
- currentTree = parsed.node;
58
- jump = parsed.jump;
59
- i += parsed.jump;
60
- }
61
- return {
62
- node: currentTree,
63
- jump,
64
- };
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--;
65
103
  }
66
- catch (err) {
67
- throw err;
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--;
68
125
  }
69
126
  };
70
- const parseItem = (latex) => {
71
- const length = latex.length;
72
- const char = latex[0];
73
- if (charIsNumber(char)) {
74
- return parseNumber(latex);
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}`);
75
150
  }
76
- else if (char === "\\") {
77
- const cmdData = parseCommand(latex);
78
- switch (cmdData.cmd) {
79
- case "sqrt":
80
- const childLatex = getChildLatex(latex.substring(cmdData.jump));
81
- const parsedChild = parseString(childLatex);
82
- return {
83
- node: new sqrtNode_1.SqrtNode(parsedChild.node),
84
- jump: parsedChild.jump,
85
- };
86
- default:
87
- throw Error(`Commande ${cmdData.cmd} non gérée`);
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
+ }
88
180
  }
89
181
  }
90
- else if (char === "+") {
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
+ }
91
212
  }
92
- throw Error(`Symbole ${char} non géré`);
93
- };
94
- /**
95
- *
96
- * @param latex latex[0] must be {
97
- *
98
- *
99
- * cette fonction extrait le latex d'un child,
100
- * par ex elle renverra "x" dans \\sqrt{x}
101
- */
102
- const getChildLatex = (latex) => {
103
- const childStartIndex = 1;
104
- let leftBracesCount = 0;
105
- let childEndIndex = -1;
106
- for (let i = childStartIndex; i < latex.length; i++) {
107
- if (latex[i] === "{")
108
- leftBracesCount++;
109
- if (latex[i] === "}") {
110
- if (leftBracesCount === 0) {
111
- return latex.substring(1, i);
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;
112
243
  }
113
- else
114
- leftBracesCount--;
115
244
  }
116
245
  }
117
- throw Error(`Erreur en récupérant un child dans ${latex}`);
118
- };
119
- /**
120
- *
121
- * @param latex latex[0] must be \
122
- */
123
- const parseCommand = (latex) => {
124
- let nextChar = latex[1];
125
- const length = latex.length;
126
- if (!nextChar)
127
- throw Error("Antislash mais pas de nom de commande");
128
- let j = 1;
129
- let cmd = "";
130
- while (j < length && (0, isLetter_1.isLetter)(nextChar)) {
131
- cmd += nextChar;
132
- j++;
133
- nextChar = latex[j];
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);
134
251
  }
135
- return {
136
- cmd,
137
- jump: 1 + cmd.length,
138
- };
139
- };
140
- /**
141
- *
142
- * @param latex latex[0] must be a number
143
- * @returns
144
- */
145
- const parseNumber = (latex) => {
146
- const char = latex[0];
147
- const length = latex.length;
148
- let numberString = char;
149
- let j = 1;
150
- let nextChar = latex[j];
151
- while (j < length && (charIsNumber(nextChar) || nextChar === ",")) {
152
- numberString += nextChar;
153
- j++;
154
- nextChar = latex[j];
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
+ }
155
285
  }
156
- if (numberString[numberString.length - 1] === ",")
157
- throw Error(`Nombre ${numberString} avec virgule mais sans partie décimale`);
158
- if (numberString.split(",").length > 2)
159
- throw Error(`Trop de virgules dans le nombre ${numberString}`);
160
- const number = Number(numberString.replace(",", "."));
161
- return {
162
- node: new numberNode_1.NumberNode(number),
163
- jump: numberString.length,
164
- };
165
- };
166
- /***
167
- * Nombres
168
- * Constantes
169
- * Opérations :
170
- * - +
171
- * - -
172
- * - *
173
- * - /
174
- * Fonctions :
175
- * - exp
176
- * - ln
177
- */
178
- const charIsNumber = (s) => {
179
- return ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"].includes(s);
286
+ return currentAdd;
180
287
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "math-exercises",
3
- "version": "2.0.19",
3
+ "version": "2.0.20",
4
4
  "description": "Math exercises generator for middle school and high school",
5
5
  "main": "lib/index.js",
6
6
  "files": [