math-expression-compiler 4.4.0 → 4.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js ADDED
@@ -0,0 +1,1886 @@
1
+ import { exhaustiveGuard } from "@esposter/shared";
2
+ import { err, ok } from "neverthrow";
3
+ // src/models/compiler/MathExpressionBitwiseAbsorption.ts
4
+ let MathExpressionBitwiseAbsorption = /* @__PURE__ */ function(MathExpressionBitwiseAbsorption) {
5
+ MathExpressionBitwiseAbsorption["BitAnd"] = "bitAnd";
6
+ MathExpressionBitwiseAbsorption["BitOr"] = "bitOr";
7
+ return MathExpressionBitwiseAbsorption;
8
+ }({});
9
+ // src/models/function/MathExpressionFunctionName.ts
10
+ let MathExpressionFunctionName = /* @__PURE__ */ function(MathExpressionFunctionName) {
11
+ MathExpressionFunctionName["CTranspose"] = "ctranspose";
12
+ MathExpressionFunctionName["Factorial"] = "factorial";
13
+ MathExpressionFunctionName["UnaryMinus"] = "unaryMinus";
14
+ MathExpressionFunctionName["UnaryPlus"] = "unaryPlus";
15
+ return MathExpressionFunctionName;
16
+ }({});
17
+ // src/models/function/MathExpressionParameterType.ts
18
+ let MathExpressionParameterType = /* @__PURE__ */ function(MathExpressionParameterType) {
19
+ MathExpressionParameterType["Any"] = "any";
20
+ MathExpressionParameterType["List"] = "list";
21
+ MathExpressionParameterType["Number"] = "number";
22
+ return MathExpressionParameterType;
23
+ }({});
24
+ // src/models/parser/MathExpressionBinaryOperatorSymbol.ts
25
+ let MathExpressionBinaryOperatorSymbol = /* @__PURE__ */ function(MathExpressionBinaryOperatorSymbol) {
26
+ MathExpressionBinaryOperatorSymbol["Add"] = "+";
27
+ MathExpressionBinaryOperatorSymbol["And"] = "and";
28
+ MathExpressionBinaryOperatorSymbol["BitwiseAnd"] = "&";
29
+ MathExpressionBinaryOperatorSymbol["BitwiseOr"] = "|";
30
+ MathExpressionBinaryOperatorSymbol["BitwiseXor"] = "^|";
31
+ MathExpressionBinaryOperatorSymbol["Divide"] = "/";
32
+ MathExpressionBinaryOperatorSymbol["ElementwiseDivide"] = "./";
33
+ MathExpressionBinaryOperatorSymbol["ElementwiseMultiply"] = ".*";
34
+ MathExpressionBinaryOperatorSymbol["Equal"] = "==";
35
+ MathExpressionBinaryOperatorSymbol["GreaterThan"] = ">";
36
+ MathExpressionBinaryOperatorSymbol["GreaterThanOrEqual"] = ">=";
37
+ MathExpressionBinaryOperatorSymbol["LessThan"] = "<";
38
+ MathExpressionBinaryOperatorSymbol["LessThanOrEqual"] = "<=";
39
+ MathExpressionBinaryOperatorSymbol["Multiply"] = "*";
40
+ MathExpressionBinaryOperatorSymbol["NotEqual"] = "!=";
41
+ MathExpressionBinaryOperatorSymbol["Or"] = "or";
42
+ MathExpressionBinaryOperatorSymbol["ShiftLeft"] = "<<";
43
+ MathExpressionBinaryOperatorSymbol["ShiftRight"] = ">>";
44
+ MathExpressionBinaryOperatorSymbol["Subtract"] = "-";
45
+ MathExpressionBinaryOperatorSymbol["UnsignedShiftRight"] = ">>>";
46
+ MathExpressionBinaryOperatorSymbol["Xor"] = "xor";
47
+ return MathExpressionBinaryOperatorSymbol;
48
+ }({});
49
+ // src/models/parser/MathExpressionGrammarRule.ts
50
+ let MathExpressionGrammarRule = /* @__PURE__ */ function(MathExpressionGrammarRule) {
51
+ MathExpressionGrammarRule["Assignment"] = "Assignment";
52
+ MathExpressionGrammarRule["Binary"] = "Binary";
53
+ MathExpressionGrammarRule["Conditional"] = "Conditional";
54
+ MathExpressionGrammarRule["LeftHand"] = "LeftHand";
55
+ MathExpressionGrammarRule["Nullish"] = "Nullish";
56
+ MathExpressionGrammarRule["Percentage"] = "Percentage";
57
+ MathExpressionGrammarRule["Power"] = "Power";
58
+ MathExpressionGrammarRule["Symbol"] = "Symbol";
59
+ MathExpressionGrammarRule["Unary"] = "Unary";
60
+ return MathExpressionGrammarRule;
61
+ }({});
62
+ // src/models/parser/MathExpressionTokenType.ts
63
+ let MathExpressionTokenType = /* @__PURE__ */ function(MathExpressionTokenType) {
64
+ MathExpressionTokenType["Delimiter"] = "delimiter";
65
+ MathExpressionTokenType["Null"] = "null";
66
+ MathExpressionTokenType["Number"] = "number";
67
+ MathExpressionTokenType["Symbol"] = "symbol";
68
+ MathExpressionTokenType["Unknown"] = "unknown";
69
+ return MathExpressionTokenType;
70
+ }({});
71
+ // src/models/parser/token/MathExpressionRadix.ts
72
+ let MathExpressionRadix = /* @__PURE__ */ function(MathExpressionRadix) {
73
+ MathExpressionRadix["Binary"] = "b";
74
+ MathExpressionRadix["Hexadecimal"] = "x";
75
+ MathExpressionRadix["Octal"] = "o";
76
+ return MathExpressionRadix;
77
+ }({});
78
+ // src/models/shared/MathExpressionError.ts
79
+ var MathExpressionError = class extends Error {
80
+ constructor(message) {
81
+ super(message);
82
+ this.name = "MathExpressionError";
83
+ }
84
+ };
85
+ // src/models/shared/MathExpressionLogicalOperator.ts
86
+ let MathExpressionLogicalOperator = /* @__PURE__ */ function(MathExpressionLogicalOperator) {
87
+ MathExpressionLogicalOperator["And"] = "and";
88
+ MathExpressionLogicalOperator["Nullish"] = "nullish";
89
+ MathExpressionLogicalOperator["Or"] = "or";
90
+ return MathExpressionLogicalOperator;
91
+ }({});
92
+ // src/models/shared/MathExpressionNodeType.ts
93
+ let MathExpressionNodeType = /* @__PURE__ */ function(MathExpressionNodeType) {
94
+ MathExpressionNodeType["Assignment"] = "assignment";
95
+ MathExpressionNodeType["Binary"] = "binary";
96
+ MathExpressionNodeType["Call"] = "call";
97
+ MathExpressionNodeType["Comparison"] = "comparison";
98
+ MathExpressionNodeType["Conditional"] = "conditional";
99
+ MathExpressionNodeType["Group"] = "group";
100
+ MathExpressionNodeType["List"] = "list";
101
+ MathExpressionNodeType["Logical"] = "logical";
102
+ MathExpressionNodeType["Name"] = "name";
103
+ MathExpressionNodeType["Number"] = "number";
104
+ MathExpressionNodeType["Percentage"] = "percentage";
105
+ MathExpressionNodeType["Unary"] = "unary";
106
+ return MathExpressionNodeType;
107
+ }({});
108
+ // src/services/compiler/constants.ts
109
+ const NO_VALUES = [];
110
+ const NO_LOCALS = [];
111
+ const ADDITIVE_NAMES = ["add", "subtract"];
112
+ // src/services/compiler/checkIsPercentageExpression.ts
113
+ const checkIsPercentageExpression = (node) => {
114
+ if (node.type === "percentage") return true;
115
+ if (node.type !== "binary") return false;
116
+ if (!ADDITIVE_NAMES.includes(node.name)) return false;
117
+ return checkIsPercentageExpression(node.left) && checkIsPercentageExpression(node.right);
118
+ };
119
+ // src/services/shared/getMathExpressionChildren.ts
120
+ const getMathExpressionChildren = (node) => {
121
+ switch (node.type) {
122
+ case "assignment": return [node.value];
123
+ case "binary":
124
+ case "logical": return [node.left, node.right];
125
+ case "call": return node.arguments;
126
+ case "comparison": return node.operands;
127
+ case "conditional": return [
128
+ node.condition,
129
+ node.whenTrue,
130
+ node.whenFalse
131
+ ];
132
+ case "group":
133
+ case "percentage":
134
+ case "unary": return [node.operand];
135
+ case "list": return node.elements;
136
+ case "name":
137
+ case "number": return [];
138
+ default: return exhaustiveGuard(node);
139
+ }
140
+ };
141
+ // src/services/compiler/collectMathExpressionAssignedNames.ts
142
+ const collectMathExpressionAssignedNames = (node, names) => {
143
+ if (node.type === "assignment") names.add(node.name);
144
+ for (const child of getMathExpressionChildren(node)) collectMathExpressionAssignedNames(child, names);
145
+ };
146
+ // src/services/compiler/compileList.ts
147
+ const compileList = (elements, context) => {
148
+ const compiledElements = elements.map((element) => context.compile(element));
149
+ return {
150
+ evaluate: (values, locals) => {
151
+ const numbers = [];
152
+ for (const element of compiledElements) {
153
+ const elementValue = element.evaluate(values, locals);
154
+ if (elementValue === null) return null;
155
+ numbers.push(elementValue);
156
+ }
157
+ return numbers;
158
+ },
159
+ isConstant: compiledElements.every((element) => element.isConstant)
160
+ };
161
+ };
162
+ // src/services/compiler/compileArgument.ts
163
+ const compileArgument = (node, context) => {
164
+ if (node.type === "list") return compileList(node.elements, context);
165
+ return context.compile(node);
166
+ };
167
+ // src/services/compiler/node/compileAssignment.ts
168
+ const compileAssignment = (node, context) => {
169
+ const slot = context.assignedSlots.get(node.name) ?? 0;
170
+ const compiledValue = context.compile(node.value);
171
+ return {
172
+ evaluate: (values, locals) => {
173
+ const value = compiledValue.evaluate(values, locals);
174
+ locals[slot] = value;
175
+ return value;
176
+ },
177
+ isConstant: false
178
+ };
179
+ };
180
+ // src/services/function/constants.ts
181
+ const MATH_EXPRESSION_RELATIVE_TOLERANCE = 1e-12;
182
+ const MATH_EXPRESSION_ABSOLUTE_TOLERANCE = 1e-15;
183
+ const SQRT_PI = Math.sqrt(Math.PI);
184
+ const MAXIMUM_DIGITS = 15;
185
+ const MILLER_RABIN_BASES = [
186
+ 2n,
187
+ 3n,
188
+ 5n,
189
+ 7n,
190
+ 11n,
191
+ 13n,
192
+ 17n,
193
+ 19n,
194
+ 23n,
195
+ 29n,
196
+ 31n,
197
+ 37n
198
+ ];
199
+ const OVERFLOW_ARGUMENT = 171.35;
200
+ const LAST_FACTORIAL_ARGUMENT = 171;
201
+ const STIRLING_THRESHOLD = 15;
202
+ const STIRLING_TERMS = [
203
+ 1 / 12,
204
+ -1 / 360,
205
+ 1 / 1260,
206
+ -1 / 1680,
207
+ 1 / 1188,
208
+ -691 / 360360,
209
+ 1 / 156
210
+ ];
211
+ // src/services/function/checkIsNearlyEqual.ts
212
+ const checkIsNearlyEqual = (left, right) => {
213
+ if (Number.isNaN(left) || Number.isNaN(right)) return false;
214
+ if (!Number.isFinite(left) || !Number.isFinite(right)) return left === right;
215
+ if (left === right) return true;
216
+ const tolerance = Math.max(MATH_EXPRESSION_RELATIVE_TOLERANCE * Math.max(Math.abs(left), Math.abs(right)), MATH_EXPRESSION_ABSOLUTE_TOLERANCE);
217
+ return Math.abs(left - right) <= tolerance;
218
+ };
219
+ // src/services/function/checkIsLarger.ts
220
+ const checkIsLarger = (left, right) => left > right && !checkIsNearlyEqual(left, right);
221
+ // src/services/function/computeModularPower.ts
222
+ const computeModularPower = (base, exponent, modulus) => {
223
+ let result = 1n;
224
+ let square = base % modulus;
225
+ let remaining = exponent;
226
+ while (remaining > 0n) {
227
+ if (remaining % 2n === 1n) result = result * square % modulus;
228
+ square = square * square % modulus;
229
+ remaining /= 2n;
230
+ }
231
+ return result;
232
+ };
233
+ // src/services/function/checkIsMillerRabinPassing.ts
234
+ const checkIsMillerRabinPassing = (candidate, base, oddPart, twos) => {
235
+ const minusOne = candidate - 1n;
236
+ let power = computeModularPower(base, oddPart, candidate);
237
+ if (power === 1n || power === minusOne) return true;
238
+ for (let round = 1; round < twos; round++) {
239
+ power = power * power % candidate;
240
+ if (power === minusOne) return true;
241
+ }
242
+ return false;
243
+ };
244
+ // src/services/function/checkIsPrime.ts
245
+ const checkIsPrime = (value) => {
246
+ if (!Number.isInteger(value) || value < 2 || value > Number.MAX_SAFE_INTEGER) return false;
247
+ const candidate = BigInt(value);
248
+ for (const base of MILLER_RABIN_BASES) {
249
+ if (candidate === base) return true;
250
+ if (candidate % base === 0n) return false;
251
+ }
252
+ let oddPart = candidate - 1n;
253
+ let twos = 0;
254
+ while (oddPart % 2n === 0n) {
255
+ oddPart /= 2n;
256
+ twos++;
257
+ }
258
+ return MILLER_RABIN_BASES.every((base) => checkIsMillerRabinPassing(candidate, base, oddPart, twos));
259
+ };
260
+ // src/services/function/checkIsSmaller.ts
261
+ const checkIsSmaller = (left, right) => left < right && !checkIsNearlyEqual(left, right);
262
+ // src/services/function/computeBitwiseAnd.ts
263
+ const computeBitwiseAnd = (left, right) => left & right;
264
+ // src/services/function/computeBitwiseOr.ts
265
+ const computeBitwiseOr = (left, right) => left | right;
266
+ // src/services/function/computeCombinations.ts
267
+ const computeCombinations = (available, chosen) => {
268
+ const smaller = Math.min(chosen, available - chosen);
269
+ let result = 1;
270
+ for (let step = 1; step <= smaller; step++) {
271
+ result = result * (available - smaller + step) / step;
272
+ if (result > Number.MAX_VALUE) return Number.POSITIVE_INFINITY;
273
+ }
274
+ return Math.round(result);
275
+ };
276
+ // src/services/function/computeComparison.ts
277
+ const computeComparison = (left, right) => {
278
+ if (checkIsNearlyEqual(left, right)) return 0;
279
+ return left > right ? 1 : -1;
280
+ };
281
+ // src/services/function/computeCompositions.ts
282
+ const computeCompositions = (total, parts) => {
283
+ if (!Number.isInteger(total) || !Number.isInteger(parts) || parts < 1 || parts > total) return null;
284
+ return computeCombinations(total - 1, parts - 1);
285
+ };
286
+ // src/services/function/computeDotProduct.ts
287
+ const computeDotProduct = (left, right) => {
288
+ if (left.length !== right.length) return null;
289
+ return left.reduce((total, value, index) => total + value * (right[index] ?? NaN), 0);
290
+ };
291
+ // src/services/function/computeSum.ts
292
+ const computeSum = (values) => values.length === 0 ? 0 : values.reduce((total, value) => total + value);
293
+ // src/services/function/computeCorrelation.ts
294
+ const computeCorrelation = (left, right) => {
295
+ if (left.length !== right.length) return null;
296
+ const count = left.length;
297
+ const sumLeft = computeSum(left);
298
+ const sumRight = computeSum(right);
299
+ const sumProducts = computeDotProduct(left, right) ?? NaN;
300
+ const sumLeftSquares = computeSum(left.map((value) => value ** 2));
301
+ const sumRightSquares = computeSum(right.map((value) => value ** 2));
302
+ return (count * sumProducts - sumLeft * sumRight) / Math.sqrt((count * sumLeftSquares - sumLeft ** 2) * (count * sumRightSquares - sumRight ** 2));
303
+ };
304
+ // src/services/function/computeDeterminant.ts
305
+ const computeDeterminant = (values) => {
306
+ if (values.length === 0) return 1;
307
+ return values.length === 1 ? values[0] ?? null : null;
308
+ };
309
+ // src/services/function/computePointToLine2D.ts
310
+ const computePointToLine2D = (point, line) => {
311
+ const [x = NaN, y = NaN] = point;
312
+ const [a = NaN, b = NaN, c = NaN] = line;
313
+ return Math.abs(a * x + b * y + c) / Math.hypot(a, b);
314
+ };
315
+ // src/services/function/computePointToLine3D.ts
316
+ const computePointToLine3D = (point, line) => {
317
+ const [x = NaN, y = NaN, z = NaN] = point;
318
+ const [x0 = NaN, y0 = NaN, z0 = NaN, a = NaN, b = NaN, c = NaN] = line;
319
+ const first = (y0 - y) * c - (z0 - z) * b;
320
+ const second = (z0 - z) * a - (x0 - x) * c;
321
+ const third = (x0 - x) * b - (y0 - y) * a;
322
+ return Math.hypot(first, second, third) / Math.hypot(a, b, c);
323
+ };
324
+ // src/services/function/computeDistance.ts
325
+ const computeDistance = (point, other) => {
326
+ if (point.length === 2 && other.length === 3) return computePointToLine2D(point, other);
327
+ if (point.length === 3 && other.length === 6) return computePointToLine3D(point, other);
328
+ if (point.length !== other.length || point.length === 0) return null;
329
+ let total = 0;
330
+ for (const [index, value] of point.entries()) {
331
+ const difference = value - (other[index] ?? NaN);
332
+ total = difference * difference + total;
333
+ }
334
+ return Math.sqrt(total);
335
+ };
336
+ // src/services/function/computeErf.ts
337
+ const SERIES_LIMIT = 3;
338
+ const CONTINUED_FRACTION_DEPTH = 80;
339
+ const computeErf = (value) => {
340
+ if (Number.isNaN(value)) return NaN;
341
+ const magnitude = Math.abs(value);
342
+ const sign = value < 0 ? -1 : 1;
343
+ if (magnitude < SERIES_LIMIT) {
344
+ const squared = magnitude * magnitude;
345
+ let term = magnitude;
346
+ let total = magnitude;
347
+ for (let index = 1; index < 200; index++) {
348
+ term *= 2 * squared / (2 * index + 1);
349
+ total += term;
350
+ if (term < total * 1e-17) break;
351
+ }
352
+ return sign * 2 * Math.exp(-squared) * total / SQRT_PI;
353
+ }
354
+ let fraction = magnitude;
355
+ for (let index = CONTINUED_FRACTION_DEPTH; index >= 1; index--) fraction = magnitude + index / 2 / fraction;
356
+ return sign * (1 - Math.exp(-magnitude * magnitude) / SQRT_PI / fraction);
357
+ };
358
+ // src/services/function/computeStirlingLogGamma.ts
359
+ const computeStirlingLogGamma = (value) => {
360
+ const inverse = 1 / value;
361
+ const squared = inverse * inverse;
362
+ let power = inverse;
363
+ let series = 0;
364
+ for (const term of STIRLING_TERMS) {
365
+ series += term * power;
366
+ power *= squared;
367
+ }
368
+ return (value - .5) * Math.log(value) - value + .5 * Math.log(2 * Math.PI) + series;
369
+ };
370
+ // src/services/function/computeLogGammaOfPositive.ts
371
+ const computeLogGammaOfPositive = (value) => {
372
+ let shifted = value;
373
+ let product = 1;
374
+ while (shifted < 15) {
375
+ product *= shifted;
376
+ shifted += 1;
377
+ }
378
+ return {
379
+ logGamma: computeStirlingLogGamma(shifted),
380
+ product
381
+ };
382
+ };
383
+ // src/services/function/computeProductOfRange.ts
384
+ const computeProductOfRange = (first, last) => {
385
+ if (last < first) return 1;
386
+ if (last === first) return last;
387
+ const middle = Math.floor((first + last) / 2);
388
+ return computeProductOfRange(first, middle) * computeProductOfRange(middle + 1, last);
389
+ };
390
+ // src/services/function/computeGamma.ts
391
+ const computeGamma = (value) => {
392
+ if (Number.isNaN(value)) return NaN;
393
+ if (Number.isInteger(value)) {
394
+ if (value <= 0 || value > 171) return Number.POSITIVE_INFINITY;
395
+ return computeProductOfRange(1, value - 1);
396
+ }
397
+ if (value < .5) return Math.PI / (Math.sin(Math.PI * value) * computeGamma(1 - value));
398
+ if (value >= 171.35) return Number.POSITIVE_INFINITY;
399
+ const { logGamma, product } = computeLogGammaOfPositive(value);
400
+ return Math.exp(logGamma) / product;
401
+ };
402
+ // src/services/function/computeFactorial.ts
403
+ const computeFactorial = (value) => {
404
+ if (value < 0) return null;
405
+ return computeGamma(value + 1);
406
+ };
407
+ // src/services/function/computeHypotenuse.ts
408
+ const computeHypotenuse = (values) => {
409
+ let largest = 0;
410
+ let total = 0;
411
+ for (const value of values) {
412
+ const magnitude = Math.abs(value);
413
+ if (largest < magnitude) {
414
+ const ratio = largest / magnitude;
415
+ total = total * (ratio * ratio) + 1;
416
+ largest = magnitude;
417
+ } else if (magnitude > 0) {
418
+ const ratio = magnitude === largest ? 1 : magnitude / largest;
419
+ total += ratio * ratio;
420
+ } else total += magnitude;
421
+ }
422
+ return largest * Math.sqrt(total);
423
+ };
424
+ // src/services/function/computeGreatestCommonDivisor.ts
425
+ const computeGreatestCommonDivisor = (left, right) => right === 0 ? Math.abs(left) : computeGreatestCommonDivisor(right, left % right);
426
+ // src/services/function/computeIntegerGreatestCommonDivisor.ts
427
+ const computeIntegerGreatestCommonDivisor = (values) => {
428
+ if (!values.every((value) => Number.isInteger(value))) return null;
429
+ return values.reduce((total, value) => computeGreatestCommonDivisor(total, value), 0);
430
+ };
431
+ // src/services/function/computeInverseCoth.ts
432
+ const computeInverseCoth = (value) => {
433
+ const magnitude = Math.abs(value);
434
+ if (magnitude < 1) return NaN;
435
+ if (magnitude === 1) return value * Number.POSITIVE_INFINITY;
436
+ return Math.sign(value) * .5 * Math.log1p(2 / (magnitude - 1));
437
+ };
438
+ // src/services/function/computeKullbackLeibler.ts
439
+ const computeKullbackLeibler = (distribution, reference) => {
440
+ if (distribution.length !== reference.length) return null;
441
+ const distributionSum = computeSum(distribution);
442
+ const referenceSum = computeSum(reference);
443
+ if (distributionSum === 0 || referenceSum === 0) return null;
444
+ const normalizedDistribution = distribution.map((value) => value / distributionSum);
445
+ const normalizedReference = reference.map((value) => value / referenceSum);
446
+ return computeSum(normalizedDistribution.map((value, index) => value * Math.log(value / (normalizedReference[index] ?? NaN))));
447
+ };
448
+ // src/services/function/computeLeastCommonMultiple.ts
449
+ const computeLeastCommonMultiple = (left, right) => {
450
+ if (!Number.isInteger(left) || !Number.isInteger(right)) return null;
451
+ const divisor = computeGreatestCommonDivisor(left, right);
452
+ return divisor === 0 ? 0 : Math.abs(left * right / divisor);
453
+ };
454
+ // src/services/function/computeListComparison.ts
455
+ const computeListComparison = (left, right) => {
456
+ for (const [index, value] of left.entries()) {
457
+ const other = right[index];
458
+ if (other === void 0) return 1;
459
+ const comparison = computeComparison(value, other);
460
+ if (comparison !== 0) return comparison;
461
+ }
462
+ return left.length < right.length ? -1 : 0;
463
+ };
464
+ // src/services/function/computeLogarithm.ts
465
+ const computeLogarithm = (value, base) => base === void 0 ? Math.log(value) : Math.log(value) / Math.log(base);
466
+ // src/services/function/computeMean.ts
467
+ const computeMean = (values) => computeSum(values) / values.length;
468
+ // src/services/function/compareNumbers.ts
469
+ const compareNumbers = (left, right) => left - right;
470
+ // src/services/function/computeMedian.ts
471
+ const computeMedian = (values) => {
472
+ const sorted = values.toSorted(compareNumbers);
473
+ const middle = Math.floor(sorted.length / 2);
474
+ if (sorted.length % 2 === 1) return sorted[middle] ?? NaN;
475
+ return ((sorted[middle - 1] ?? NaN) + (sorted[middle] ?? NaN)) / 2;
476
+ };
477
+ // src/services/function/computeMedianAbsoluteDeviation.ts
478
+ const computeMedianAbsoluteDeviation = (values) => {
479
+ const center = computeMedian(values);
480
+ return computeMedian(values.map((value) => Math.abs(value - center)));
481
+ };
482
+ // src/services/function/computeModulo.ts
483
+ const computeModulo = (dividend, divisor) => {
484
+ if (divisor === 0) return dividend;
485
+ if (!Number.isFinite(dividend) || !Number.isFinite(divisor)) return NaN;
486
+ if (Number.isInteger(dividend) && Number.isInteger(divisor)) {
487
+ const remainder = dividend % divisor;
488
+ if (remainder === 0) return 0;
489
+ return Math.sign(remainder) === Math.sign(divisor) ? remainder : remainder + divisor;
490
+ }
491
+ const quotient = dividend / divisor;
492
+ if (checkIsNearlyEqual(quotient, Math.round(quotient))) return 0;
493
+ return dividend - divisor * Math.floor(quotient);
494
+ };
495
+ // src/services/function/computeModularInverse.ts
496
+ const computeModularInverse = (value, modulus) => {
497
+ if (!Number.isInteger(value) || !Number.isInteger(modulus) || modulus === 0) return null;
498
+ let remainder = value;
499
+ let nextRemainder = modulus;
500
+ let coefficient = 0;
501
+ let previousCoefficient = 1;
502
+ while (nextRemainder !== 0) {
503
+ const quotient = Math.floor(remainder / nextRemainder);
504
+ [coefficient, previousCoefficient] = [previousCoefficient - quotient * coefficient, coefficient];
505
+ [remainder, nextRemainder] = [nextRemainder, remainder - quotient * nextRemainder];
506
+ }
507
+ if ((remainder < 0 ? -remainder : remainder) !== 1) return NaN;
508
+ const inverse = computeModulo(remainder < 0 ? -previousCoefficient : previousCoefficient, modulus);
509
+ return inverse < 0 ? inverse + modulus : inverse;
510
+ };
511
+ // src/services/function/computeMultinomial.ts
512
+ const computeMultinomial = (parts) => {
513
+ if (!parts.every((part) => Number.isInteger(part) && part > 0)) return null;
514
+ let result = 1;
515
+ let running = 0;
516
+ for (const part of parts) {
517
+ running += part;
518
+ result *= computeCombinations(running, part);
519
+ }
520
+ return result;
521
+ };
522
+ // src/services/function/computeNorm.ts
523
+ const computeNorm = (values) => {
524
+ if (values.length === 0) return 0;
525
+ if (values.length === 1) return Math.abs(values[0] ?? NaN);
526
+ return Math.sqrt(computeSum(values.map((value) => value * value)));
527
+ };
528
+ // src/services/function/computeNthRoot.ts
529
+ const computeNthRoot = (value, root) => {
530
+ const isInverse = root < 0;
531
+ const degree = Math.abs(root);
532
+ if (degree === 0) return null;
533
+ if (value < 0 && degree % 2 !== 1) return null;
534
+ if (value === 0) return isInverse ? Number.POSITIVE_INFINITY : 0;
535
+ if (!Number.isFinite(value)) return isInverse ? 0 : value;
536
+ let result = Math.abs(value) ** (1 / degree);
537
+ const rounded = Math.round(result);
538
+ if (Number.isInteger(degree) && rounded ** degree === Math.abs(value)) result = rounded;
539
+ if (value < 0) result = -result;
540
+ return isInverse ? 1 / result : result;
541
+ };
542
+ // src/services/function/computePartitionSelect.ts
543
+ const computePartitionSelect = (values, index) => {
544
+ if (!Number.isInteger(index) || index < 0 || index >= values.length) return null;
545
+ return values.toSorted(compareNumbers)[index] ?? null;
546
+ };
547
+ // src/services/function/computePermutations.ts
548
+ const computePermutations = (available, chosen) => {
549
+ if (!Number.isInteger(available) || !Number.isInteger(chosen) || chosen < 0 || chosen > available) return null;
550
+ let result = 1;
551
+ for (let factor = available - chosen + 1; factor <= available; factor++) {
552
+ result *= factor;
553
+ if (result > Number.MAX_VALUE) return Number.POSITIVE_INFINITY;
554
+ }
555
+ return result;
556
+ };
557
+ // src/services/function/scaleList.ts
558
+ const scaleList = (list, scalar) => list.map((element) => element * scalar);
559
+ // src/services/function/multiplyPair.ts
560
+ const multiplyPair = (left, right) => {
561
+ if (typeof left === "number" && typeof right === "number") return left * right;
562
+ if (typeof left === "number" && Array.isArray(right)) return scaleList(right, left);
563
+ if (Array.isArray(left) && typeof right === "number") return scaleList(left, right);
564
+ if (Array.isArray(left) && Array.isArray(right)) return computeDotProduct(left, right);
565
+ return null;
566
+ };
567
+ // src/services/function/computeProduct.ts
568
+ const computeProduct = (values) => {
569
+ let total = 1;
570
+ for (const value of values) {
571
+ if (total === null) return null;
572
+ total = multiplyPair(total, value);
573
+ }
574
+ return typeof total === "number" ? total : null;
575
+ };
576
+ // src/services/function/computeQuantile.ts
577
+ const computeQuantile = (values, probability, isSorted) => {
578
+ if (values.length === 0 || probability < 0 || probability > 1) return null;
579
+ const ordered = isSorted ? values : values.toSorted(compareNumbers);
580
+ const index = probability * (ordered.length - 1);
581
+ const integerPart = Math.floor(index);
582
+ if (Number.isInteger(index)) return ordered[integerPart] ?? NaN;
583
+ const fraction = index % 1;
584
+ return (ordered[integerPart] ?? NaN) * (1 - fraction) + (ordered[integerPart + 1] ?? NaN) * fraction;
585
+ };
586
+ // src/services/shared/checkIsTruthy.ts
587
+ const checkIsTruthy = (value) => value !== 0 && !Number.isNaN(value);
588
+ // src/services/function/computeTruthyCount.ts
589
+ const computeTruthyCount = (values) => values.filter((value) => checkIsTruthy(value)).length;
590
+ // src/services/function/computeVariance.ts
591
+ const computeVariance = (values) => {
592
+ if (values.length === 1) return Number.isFinite(values[0] ?? NaN) ? 0 : NaN;
593
+ const average = computeMean(values);
594
+ return computeSum(values.map((value) => (value - average) ** 2)) / (values.length - 1);
595
+ };
596
+ // src/services/function/computeExtreme.ts
597
+ const computeExtreme = (values, initial, checkIsPreferred) => {
598
+ let extreme = initial;
599
+ for (const value of values) {
600
+ if (Number.isNaN(value)) return NaN;
601
+ if (checkIsPreferred(value, extreme)) extreme = value;
602
+ }
603
+ return extreme;
604
+ };
605
+ // src/services/function/computeVectorNorm.ts
606
+ const computeVectorNorm = (values, power) => {
607
+ if (Number.isNaN(power)) return null;
608
+ const magnitudes = values.map((value) => Math.abs(value));
609
+ if (Math.abs(power) === Number.POSITIVE_INFINITY) {
610
+ const [first] = magnitudes;
611
+ if (first === void 0) return 0;
612
+ return computeExtreme(magnitudes, first, power > 0 ? checkIsLarger : checkIsSmaller);
613
+ }
614
+ if (checkIsNearlyEqual(power, 0)) return Number.POSITIVE_INFINITY;
615
+ return computeSum(magnitudes.map((magnitude) => magnitude ** power)) ** (1 / power);
616
+ };
617
+ // src/services/function/signature/createNumericCompute.ts
618
+ const createNumericCompute = (compute) => (values) => compute(values.flat());
619
+ // src/services/function/signature/createSignature.ts
620
+ const createSignature = (parameters, minArity, maxArity, compute, scalarCompute = {}) => ({
621
+ compute,
622
+ maxArity,
623
+ minArity,
624
+ parameters,
625
+ ...scalarCompute
626
+ });
627
+ // src/services/function/signature/createNumberSignature.ts
628
+ const createNumberSignature = (minArity, maxArity, compute, scalarCompute) => createSignature(["number"], minArity, maxArity, createNumericCompute(compute), scalarCompute);
629
+ // src/services/function/signature/createRangedSignatures.ts
630
+ const createRangedSignatures = (minArity, maxArity, compute, scalarCompute) => [createNumberSignature(minArity, maxArity, compute, scalarCompute)];
631
+ // src/services/function/signature/createBinarySignatures.ts
632
+ const createBinarySignatures = (compute) => createRangedSignatures(2, 2, (values) => compute(values[0] ?? NaN, values[1] ?? NaN), { computeBinary: compute });
633
+ // src/services/function/signature/createBitwisePair.ts
634
+ const createBitwisePair = (absorbing, compute) => (left, right) => {
635
+ if (left === absorbing) return absorbing;
636
+ if (!Number.isInteger(left) || !Number.isInteger(right)) return null;
637
+ return compute(left, right);
638
+ };
639
+ // src/services/function/signature/createBitwiseFold.ts
640
+ const createBitwiseFold = (absorbing, compute) => {
641
+ const computePair = createBitwisePair(absorbing, compute);
642
+ return (values) => values.slice(1).reduce((result, value) => result === null ? null : computePair(result, value), values[0] ?? NaN);
643
+ };
644
+ // src/services/function/shiftDecimalPlaces.ts
645
+ const shiftDecimalPlaces = (value, places) => {
646
+ if (!Number.isFinite(value)) return value;
647
+ const [mantissa = "", exponent = "0"] = value.toExponential().split("e");
648
+ return Number(`${mantissa}e${Number(exponent) + places}`);
649
+ };
650
+ // src/services/function/roundToDigits.ts
651
+ const roundToDigits = (rounder, value, digits) => {
652
+ if (!Number.isInteger(digits) || digits < 0 || digits > 15) return null;
653
+ if (!Number.isFinite(value)) return value;
654
+ if (Number.isInteger(value)) return value + 0;
655
+ if (digits === 0) return rounder(value) + 0;
656
+ return shiftDecimalPlaces(rounder(shiftDecimalPlaces(value, digits)), -digits);
657
+ };
658
+ // src/services/function/signature/createDigitSignatures.ts
659
+ const createDigitSignatures = (rounder) => createRangedSignatures(1, 2, (values) => {
660
+ const [value = NaN, digits = 0] = values;
661
+ return roundToDigits(rounder, value, digits);
662
+ }, {
663
+ computeBinary: (value, digits) => roundToDigits(rounder, value, digits),
664
+ computeUnary: (value) => roundToDigits(rounder, value, 0)
665
+ });
666
+ // src/services/function/signature/createNonEmptyCompute.ts
667
+ const createNonEmptyCompute = (compute) => (values) => values.length === 0 ? null : compute(values);
668
+ // src/services/function/signature/createListSignature.ts
669
+ const createListSignature = (compute) => createSignature(["list"], 1, 1, createNumericCompute(compute));
670
+ // src/services/function/signature/createVariadicSignatures.ts
671
+ const createVariadicSignatures = (minArity, compute, computeBinary) => [createNumberSignature(minArity, Number.POSITIVE_INFINITY, compute, { computeBinary })];
672
+ // src/services/function/signature/createSpreadSignatures.ts
673
+ const createSpreadSignatures = (minArity, compute) => [...createVariadicSignatures(minArity, compute), createListSignature(compute)];
674
+ // src/services/function/signature/createExtremeSignatures.ts
675
+ const createExtremeSignatures = (checkIsPreferred) => createSpreadSignatures(1, createNonEmptyCompute((values) => computeExtreme(values, values[0] ?? NaN, checkIsPreferred)));
676
+ // src/services/function/signature/createSingletonListSignature.ts
677
+ const createSingletonListSignature = (compute) => createListSignature((values) => values.length === 1 ? compute(values[0] ?? NaN) : null);
678
+ // src/services/function/signature/createUnarySignatures.ts
679
+ const createUnarySignatures = (compute) => createRangedSignatures(1, 1, (values) => compute(values[0] ?? NaN), { computeUnary: compute });
680
+ // src/services/function/signature/createIdentitySignatures.ts
681
+ const createIdentitySignatures = () => [...createUnarySignatures((value) => value), createSingletonListSignature((value) => value)];
682
+ // src/services/function/signature/createIntegerBinarySignatures.ts
683
+ const createIntegerBinarySignatures = (compute) => createBinarySignatures((left, right) => Number.isInteger(left) && Number.isInteger(right) ? compute(left, right) : null);
684
+ // src/services/function/signature/createIntegerUnarySignatures.ts
685
+ const createIntegerUnarySignatures = (compute) => createUnarySignatures((value) => Number.isInteger(value) ? compute(value) : null);
686
+ // src/services/function/signature/createListFirstCompute.ts
687
+ const createListFirstCompute = (compute) => (values) => compute(values.slice(0, 1).flat(), values.slice(1).flat());
688
+ // src/services/function/signature/createListPairCompute.ts
689
+ const createListPairCompute = (compute) => (values) => compute(values.slice(0, 1).flat(), values.slice(1, 2).flat());
690
+ // src/services/function/signature/createListPairSignature.ts
691
+ const createListPairSignature = (compute) => createSignature(["list", "list"], 2, 2, createListPairCompute(compute));
692
+ // src/services/function/signature/createOrderedListSignatures.ts
693
+ const createOrderedListSignatures = (compute) => {
694
+ const computePair = createListPairCompute(compute);
695
+ return [
696
+ ["number", "list"],
697
+ ["list", "number"],
698
+ ["list", "list"]
699
+ ].map((parameters) => createSignature(parameters, 2, 2, computePair));
700
+ };
701
+ // src/services/shared/toNumber.ts
702
+ const toNumber = (flag) => flag ? 1 : 0;
703
+ // src/services/function/MathExpressionFunctionMap.ts
704
+ const MathExpressionFunctionMap = {
705
+ abs: createUnarySignatures(Math.abs),
706
+ acos: createUnarySignatures(Math.acos),
707
+ acosh: createUnarySignatures(Math.acosh),
708
+ acot: createUnarySignatures((value) => Math.atan(1 / value)),
709
+ acoth: createUnarySignatures(computeInverseCoth),
710
+ acsc: createUnarySignatures((value) => Math.asin(1 / value)),
711
+ acsch: createUnarySignatures((value) => Math.asinh(1 / value)),
712
+ add: createVariadicSignatures(2, computeSum, (left, right) => left + right),
713
+ addScalar: createBinarySignatures((left, right) => left + right),
714
+ and: createVariadicSignatures(1, (values) => toNumber(values.every((value) => checkIsTruthy(value)))),
715
+ arg: createUnarySignatures((value) => Number.isNaN(value) ? NaN : value < 0 ? Math.PI : 0),
716
+ asec: createUnarySignatures((value) => Math.acos(1 / value)),
717
+ asech: createUnarySignatures((value) => Math.acosh(1 / value)),
718
+ asin: createUnarySignatures(Math.asin),
719
+ asinh: createUnarySignatures(Math.asinh),
720
+ atan: createUnarySignatures(Math.atan),
721
+ atan2: createBinarySignatures((left, right) => Math.atan2(left, right)),
722
+ atanh: createUnarySignatures(Math.atanh),
723
+ bitAnd: createVariadicSignatures(2, createBitwiseFold(0, computeBitwiseAnd), createBitwisePair(0, computeBitwiseAnd)),
724
+ bitNot: createIntegerUnarySignatures((value) => ~value),
725
+ bitOr: createVariadicSignatures(2, createBitwiseFold(-1, computeBitwiseOr), createBitwisePair(-1, computeBitwiseOr)),
726
+ bitXor: createIntegerBinarySignatures((left, right) => left ^ right),
727
+ boolean: createRangedSignatures(0, 1, (values) => values.length === 0 ? 0 : toNumber(checkIsTruthy(values[0] ?? 0))),
728
+ cbrt: createUnarySignatures(Math.cbrt),
729
+ ceil: createDigitSignatures(Math.ceil),
730
+ clone: createUnarySignatures((value) => value),
731
+ combinations: createBinarySignatures((available, chosen) => Number.isInteger(available) && Number.isInteger(chosen) && chosen >= 0 && chosen <= available ? computeCombinations(available, chosen) : null),
732
+ combinationsWithRep: createBinarySignatures((available, chosen) => Number.isInteger(available) && Number.isInteger(chosen) && available >= 1 && chosen >= 0 ? computeCombinations(available + chosen - 1, chosen) : null),
733
+ compare: createBinarySignatures(computeComparison),
734
+ compareNatural: [...createBinarySignatures(computeComparison), ...createOrderedListSignatures(computeListComparison)],
735
+ composition: createBinarySignatures(computeCompositions),
736
+ conj: createUnarySignatures((value) => value),
737
+ corr: [createListPairSignature(computeCorrelation)],
738
+ cos: createUnarySignatures(Math.cos),
739
+ cosh: createUnarySignatures(Math.cosh),
740
+ cot: createUnarySignatures((value) => 1 / Math.tan(value)),
741
+ coth: createUnarySignatures((value) => 1 / Math.tanh(value)),
742
+ count: [createListSignature((values) => values.length)],
743
+ csc: createUnarySignatures((value) => 1 / Math.sin(value)),
744
+ csch: createUnarySignatures((value) => 1 / Math.sinh(value)),
745
+ cube: createUnarySignatures((value) => value * value * value),
746
+ deepEqual: [
747
+ ...createBinarySignatures((left, right) => toNumber(checkIsNearlyEqual(left, right))),
748
+ createListPairSignature((left, right) => toNumber(left.length === right.length && left.every((value, index) => checkIsNearlyEqual(value, right[index] ?? NaN)))),
749
+ createSignature(["number", "list"], 2, 2, () => toNumber(false)),
750
+ createSignature(["list", "number"], 2, 2, () => toNumber(false))
751
+ ],
752
+ det: [...createUnarySignatures((value) => value), createListSignature(computeDeterminant)],
753
+ distance: [createListPairSignature(computeDistance)],
754
+ divide: createBinarySignatures((left, right) => left / right),
755
+ divideScalar: createBinarySignatures((left, right) => left / right),
756
+ dot: [createListPairSignature(computeDotProduct)],
757
+ dotDivide: createBinarySignatures((left, right) => left / right),
758
+ dotMultiply: createBinarySignatures((left, right) => left * right),
759
+ dotPow: createBinarySignatures((left, right) => left ** right),
760
+ equal: createBinarySignatures((left, right) => toNumber(checkIsNearlyEqual(left, right))),
761
+ equalScalar: createBinarySignatures((left, right) => toNumber(checkIsNearlyEqual(left, right))),
762
+ erf: createUnarySignatures(computeErf),
763
+ exp: createUnarySignatures(Math.exp),
764
+ expm1: createUnarySignatures(Math.expm1),
765
+ fix: createDigitSignatures(Math.trunc),
766
+ floor: createDigitSignatures(Math.floor),
767
+ gamma: createUnarySignatures(computeGamma),
768
+ gcd: createSpreadSignatures(2, (values) => values.length < 2 ? null : computeIntegerGreatestCommonDivisor(values)),
769
+ hypot: createSpreadSignatures(1, computeHypotenuse),
770
+ im: createUnarySignatures(() => 0),
771
+ inv: createUnarySignatures((value) => 1 / value),
772
+ invmod: createBinarySignatures(computeModularInverse),
773
+ isBounded: [...createUnarySignatures((value) => toNumber(Number.isFinite(value))), createListSignature((values) => toNumber(values.every((value) => Number.isFinite(value))))],
774
+ isFinite: createUnarySignatures((value) => toNumber(Number.isFinite(value))),
775
+ isInteger: createUnarySignatures((value) => toNumber(Number.isInteger(value))),
776
+ isNaN: createUnarySignatures((value) => toNumber(Number.isNaN(value))),
777
+ isNegative: createUnarySignatures((value) => toNumber(value < 0)),
778
+ isPositive: createUnarySignatures((value) => toNumber(value > 0)),
779
+ isPrime: createUnarySignatures((value) => toNumber(checkIsPrime(value))),
780
+ isZero: createUnarySignatures((value) => toNumber(value === 0)),
781
+ kldivergence: [createListPairSignature(computeKullbackLeibler)],
782
+ larger: createBinarySignatures((left, right) => toNumber(checkIsLarger(left, right))),
783
+ largerEq: createBinarySignatures((left, right) => toNumber(left >= right || checkIsNearlyEqual(left, right))),
784
+ lcm: createVariadicSignatures(2, (values) => {
785
+ const [first = NaN, ...rest] = values;
786
+ return rest.reduce((total, value) => total === null ? null : computeLeastCommonMultiple(total, value), first);
787
+ }),
788
+ leftShift: createIntegerBinarySignatures((left, right) => left << right),
789
+ log: createRangedSignatures(1, 2, (values) => computeLogarithm(values[0] ?? NaN, values[1])),
790
+ log1p: createRangedSignatures(1, 2, (values) => {
791
+ const [value = NaN, base] = values;
792
+ return base === void 0 ? Math.log1p(value) : Math.log1p(value) / Math.log(base);
793
+ }),
794
+ log2: createUnarySignatures(Math.log2),
795
+ log10: createUnarySignatures(Math.log10),
796
+ mad: createSpreadSignatures(1, createNonEmptyCompute(computeMedianAbsoluteDeviation)),
797
+ ["ctranspose"]: createUnarySignatures((value) => value),
798
+ ["factorial"]: createUnarySignatures(computeFactorial),
799
+ ["unaryMinus"]: createUnarySignatures((value) => -value),
800
+ ["unaryPlus"]: createUnarySignatures((value) => value),
801
+ max: createExtremeSignatures(checkIsLarger),
802
+ mean: createSpreadSignatures(1, createNonEmptyCompute(computeMean)),
803
+ median: createSpreadSignatures(1, createNonEmptyCompute(computeMedian)),
804
+ min: createExtremeSignatures(checkIsSmaller),
805
+ mod: createBinarySignatures(computeModulo),
806
+ multinomial: [createListSignature(computeMultinomial)],
807
+ multiply: [
808
+ ...createVariadicSignatures(2, (values) => values.reduce((total, value) => total * value, 1), (left, right) => left * right),
809
+ createListPairSignature(computeDotProduct),
810
+ createSignature(["any"], 2, Number.POSITIVE_INFINITY, computeProduct)
811
+ ],
812
+ multiplyScalar: createBinarySignatures((left, right) => left * right),
813
+ norm: [
814
+ ...createRangedSignatures(1, 1, computeNorm),
815
+ createListSignature(computeNorm),
816
+ createSignature(["list", "number"], 2, 2, createListFirstCompute((list, [power = NaN]) => computeVectorNorm(list, power)))
817
+ ],
818
+ not: createUnarySignatures((value) => toNumber(!checkIsTruthy(value))),
819
+ nthRoot: createRangedSignatures(1, 2, (values) => computeNthRoot(values[0] ?? NaN, values[1] ?? 2)),
820
+ nullish: createVariadicSignatures(1, (values) => values[0] ?? NaN),
821
+ number: createRangedSignatures(0, 1, (values) => values.length === 0 ? 0 : values[0] ?? NaN),
822
+ numeric: createUnarySignatures((value) => value),
823
+ or: createVariadicSignatures(1, (values) => toNumber(computeTruthyCount(values) > 0)),
824
+ partitionSelect: [createSignature(["list", "number"], 2, 2, createListFirstCompute((list, [index = NaN]) => computePartitionSelect(list, index)))],
825
+ permutations: createRangedSignatures(1, 2, (values) => {
826
+ const [available = NaN, chosen = available] = values;
827
+ return computePermutations(available, chosen);
828
+ }),
829
+ pinv: createUnarySignatures((value) => value === 0 ? 0 : 1 / value),
830
+ pow: createBinarySignatures((left, right) => left ** right),
831
+ prod: createSpreadSignatures(1, createNonEmptyCompute((values) => values.reduce((total, value) => total * value, 1))),
832
+ quantileSeq: [createSignature(["list", "number"], 2, 3, createListFirstCompute((list, [probability = NaN, sorted = 0]) => computeQuantile(list, probability, checkIsTruthy(sorted))))],
833
+ re: createUnarySignatures((value) => value),
834
+ rightArithShift: createIntegerBinarySignatures((left, right) => left >> right),
835
+ rightLogShift: createIntegerBinarySignatures((left, right) => left >>> right),
836
+ round: createDigitSignatures((value) => Math.sign(value) * Math.round(Math.abs(value))),
837
+ sec: createUnarySignatures((value) => 1 / Math.cos(value)),
838
+ sech: createUnarySignatures((value) => 1 / Math.cosh(value)),
839
+ setIsSubset: [createListPairSignature((left, right) => toNumber(left.every((value) => right.includes(value))))],
840
+ setMultiplicity: [createSignature(["number", "list"], 2, 2, createListFirstCompute(([value = NaN], list) => list.filter((element) => element === value).length))],
841
+ setSize: [createListSignature((values) => values.length)],
842
+ sign: createUnarySignatures(Math.sign),
843
+ sin: createUnarySignatures(Math.sin),
844
+ sinh: createUnarySignatures(Math.sinh),
845
+ smaller: createBinarySignatures((left, right) => toNumber(checkIsSmaller(left, right))),
846
+ smallerEq: createBinarySignatures((left, right) => toNumber(left <= right || checkIsNearlyEqual(left, right))),
847
+ sqrt: createUnarySignatures(Math.sqrt),
848
+ square: createUnarySignatures((value) => value * value),
849
+ squeeze: createIdentitySignatures(),
850
+ std: createSpreadSignatures(1, createNonEmptyCompute((values) => Math.sqrt(computeVariance(values)))),
851
+ subtract: createBinarySignatures((left, right) => left - right),
852
+ subtractScalar: createBinarySignatures((left, right) => left - right),
853
+ sum: createSpreadSignatures(1, computeSum),
854
+ tan: createUnarySignatures(Math.tan),
855
+ tanh: createUnarySignatures(Math.tanh),
856
+ trace: createIdentitySignatures(),
857
+ transpose: createIdentitySignatures(),
858
+ unequal: createBinarySignatures((left, right) => toNumber(!checkIsNearlyEqual(left, right))),
859
+ variance: createSpreadSignatures(1, createNonEmptyCompute(computeVariance)),
860
+ xor: createVariadicSignatures(1, (values) => toNumber(computeTruthyCount(values) % 2 === 1), (left, right) => toNumber(checkIsTruthy(left) !== checkIsTruthy(right)))
861
+ };
862
+ // src/services/shared/getOwnValue.ts
863
+ const getOwnValue = (record, key) => Object.hasOwn(record, key) ? record[key] : void 0;
864
+ // src/services/shared/getMathExpressionSignatures.ts
865
+ const getMathExpressionSignatures = (name) => getOwnValue(MathExpressionFunctionMap, name);
866
+ // src/services/compiler/getMathExpressionScalarCompute.ts
867
+ const getMathExpressionScalarCompute = (name, key) => {
868
+ const signature = getMathExpressionSignatures(name)?.[0];
869
+ if (signature === void 0) return () => null;
870
+ const scalarCompute = signature[key];
871
+ if (scalarCompute !== void 0) return scalarCompute;
872
+ return (...values) => signature.compute(values);
873
+ };
874
+ // src/services/compiler/MathExpressionBitwiseAbsorptionMap.ts
875
+ const MathExpressionBitwiseAbsorptionMap = {
876
+ ["bitAnd"]: {
877
+ absorbs: 0,
878
+ result: 0
879
+ },
880
+ ["bitOr"]: {
881
+ absorbs: -1,
882
+ result: -1
883
+ }
884
+ };
885
+ // src/services/compiler/node/compileBinary.ts
886
+ const compileBinary = (node, context) => {
887
+ const { left, name, right } = node;
888
+ const compiledLeft = context.compile(left);
889
+ if (ADDITIVE_NAMES.includes(name) && right.type === "percentage" && !checkIsPercentageExpression(left)) {
890
+ const compiledPercent = context.compile(right.operand);
891
+ const sign = name === "add" ? 1 : -1;
892
+ const evaluate = (values, locals) => {
893
+ const base = compiledLeft.evaluate(values, locals);
894
+ const percent = compiledPercent.evaluate(values, locals);
895
+ if (base === null || percent === null) return null;
896
+ return base + sign * base * (percent / 100);
897
+ };
898
+ return {
899
+ evaluate,
900
+ isConstant: compiledLeft.isConstant && compiledPercent.isConstant
901
+ };
902
+ }
903
+ const compiledRight = context.compile(right);
904
+ const compute = getMathExpressionScalarCompute(name, "computeBinary");
905
+ const absorption = MathExpressionBitwiseAbsorptionMap[name];
906
+ const evaluate = (values, locals) => {
907
+ const leftValue = compiledLeft.evaluate(values, locals);
908
+ if (leftValue === null) return null;
909
+ if (absorption?.absorbs === leftValue) return absorption.result;
910
+ const rightValue = compiledRight.evaluate(values, locals);
911
+ if (rightValue === null) return null;
912
+ return compute(leftValue, rightValue);
913
+ };
914
+ return {
915
+ evaluate,
916
+ isConstant: compiledLeft.isConstant && compiledRight.isConstant
917
+ };
918
+ };
919
+ // src/services/shared/getMathExpressionParameterType.ts
920
+ const getMathExpressionParameterType = (node) => node.type === "list" ? "list" : "number";
921
+ // src/services/shared/checkIsMatchingKind.ts
922
+ const checkIsMatchingKind = (parameterType, argumentType) => parameterType === "any" || parameterType === argumentType;
923
+ // src/services/shared/getParameterType.ts
924
+ const getParameterType = (signature, index) => signature.parameters[Math.min(index, signature.parameters.length - 1)];
925
+ // src/services/shared/checkIsMatching.ts
926
+ const checkIsMatching = (signature, parameterTypes) => parameterTypes.length >= signature.minArity && parameterTypes.length <= signature.maxArity && parameterTypes.every((parameterType, index) => checkIsMatchingKind(getParameterType(signature, index), parameterType));
927
+ // src/services/shared/matchMathExpressionSignature.ts
928
+ const matchMathExpressionSignature = (signatures, parameterTypes) => signatures.find((signature) => checkIsMatching(signature, parameterTypes));
929
+ // src/services/compiler/node/compileCall.ts
930
+ const compileCall = (node, context) => {
931
+ const signatures = getMathExpressionSignatures(node.name);
932
+ const parameterTypes = node.arguments.map((argument) => getMathExpressionParameterType(argument));
933
+ const signature = matchMathExpressionSignature(signatures ?? [], parameterTypes);
934
+ const compute = signature?.compute ?? (() => null);
935
+ const computeUnary = signature?.computeUnary;
936
+ const computeBinary = signature?.computeBinary;
937
+ const compiledArguments = node.arguments.map((argument) => compileArgument(argument, context));
938
+ const isConstant = compiledArguments.every((argument) => argument.isConstant);
939
+ const [first, second] = compiledArguments;
940
+ if (compiledArguments.length === 1 && first !== void 0) return {
941
+ evaluate: (values, locals) => {
942
+ const firstValue = first.evaluate(values, locals);
943
+ if (firstValue === null) return null;
944
+ if (computeUnary !== void 0 && typeof firstValue === "number") return computeUnary(firstValue);
945
+ return compute([firstValue]);
946
+ },
947
+ isConstant
948
+ };
949
+ if (compiledArguments.length === 2 && first !== void 0 && second !== void 0) return {
950
+ evaluate: (values, locals) => {
951
+ const firstValue = first.evaluate(values, locals);
952
+ if (firstValue === null) return null;
953
+ const secondValue = second.evaluate(values, locals);
954
+ if (secondValue === null) return null;
955
+ if (computeBinary !== void 0 && typeof firstValue === "number" && typeof secondValue === "number") return computeBinary(firstValue, secondValue);
956
+ return compute([firstValue, secondValue]);
957
+ },
958
+ isConstant
959
+ };
960
+ return {
961
+ evaluate: (values, locals) => {
962
+ const argumentValues = [];
963
+ for (const argument of compiledArguments) {
964
+ const argumentValue = argument.evaluate(values, locals);
965
+ if (argumentValue === null) return null;
966
+ argumentValues.push(argumentValue);
967
+ }
968
+ return compute(argumentValues);
969
+ },
970
+ isConstant
971
+ };
972
+ };
973
+ // src/services/compiler/node/compileComparison.ts
974
+ const compileComparison = (node, context) => {
975
+ const compiledOperands = node.operands.map((operand) => context.compile(operand));
976
+ const computes = node.names.map((name) => getMathExpressionScalarCompute(name, "computeBinary"));
977
+ const evaluate = (values, locals) => {
978
+ let left = compiledOperands[0]?.evaluate(values, locals) ?? null;
979
+ let result = 1;
980
+ for (const [index, compute] of computes.entries()) {
981
+ const right = compiledOperands[index + 1]?.evaluate(values, locals) ?? null;
982
+ if (left === null || right === null) return null;
983
+ result = compute(left, right);
984
+ if (result !== 1) return result;
985
+ left = right;
986
+ }
987
+ return result;
988
+ };
989
+ return {
990
+ evaluate,
991
+ isConstant: compiledOperands.every((operand) => operand.isConstant)
992
+ };
993
+ };
994
+ // src/services/compiler/node/compileConditional.ts
995
+ const compileConditional = (node, context) => {
996
+ const compiledCondition = context.compile(node.condition);
997
+ const compiledWhenTrue = context.compile(node.whenTrue);
998
+ const compiledWhenFalse = context.compile(node.whenFalse);
999
+ const evaluate = (values, locals) => {
1000
+ const test = compiledCondition.evaluate(values, locals);
1001
+ if (test === null) return null;
1002
+ return checkIsTruthy(test) ? compiledWhenTrue.evaluate(values, locals) : compiledWhenFalse.evaluate(values, locals);
1003
+ };
1004
+ return {
1005
+ evaluate,
1006
+ isConstant: compiledCondition.isConstant && compiledWhenTrue.isConstant && compiledWhenFalse.isConstant
1007
+ };
1008
+ };
1009
+ // src/services/compiler/node/compileGroup.ts
1010
+ const compileGroup = (node, context) => context.compile(node.operand);
1011
+ // src/services/compiler/node/compileListNode.ts
1012
+ const compileListNode = () => ({
1013
+ evaluate: () => null,
1014
+ isConstant: false
1015
+ });
1016
+ // src/services/compiler/node/compileLogical.ts
1017
+ const compileLogical = (node, context) => {
1018
+ const compiledLeft = context.compile(node.left);
1019
+ if (node.operator === "nullish") return compiledLeft;
1020
+ const compiledRight = context.compile(node.right);
1021
+ const isConstant = compiledLeft.isConstant && compiledRight.isConstant;
1022
+ switch (node.operator) {
1023
+ case "and": return {
1024
+ evaluate: (values, locals) => {
1025
+ const leftValue = compiledLeft.evaluate(values, locals);
1026
+ if (leftValue === null) return null;
1027
+ if (!checkIsTruthy(leftValue)) return 0;
1028
+ const rightValue = compiledRight.evaluate(values, locals);
1029
+ return rightValue === null ? null : toNumber(checkIsTruthy(rightValue));
1030
+ },
1031
+ isConstant
1032
+ };
1033
+ case "or": return {
1034
+ evaluate: (values, locals) => {
1035
+ const leftValue = compiledLeft.evaluate(values, locals);
1036
+ if (leftValue === null) return null;
1037
+ if (checkIsTruthy(leftValue)) return 1;
1038
+ const rightValue = compiledRight.evaluate(values, locals);
1039
+ return rightValue === null ? null : toNumber(checkIsTruthy(rightValue));
1040
+ },
1041
+ isConstant
1042
+ };
1043
+ default: return exhaustiveGuard(node.operator);
1044
+ }
1045
+ };
1046
+ // src/services/shared/MathExpressionConstantMap.ts
1047
+ const MathExpressionConstantMap = {
1048
+ E: Math.E,
1049
+ e: Math.E,
1050
+ false: 0,
1051
+ Infinity: Number.POSITIVE_INFINITY,
1052
+ LN2: Math.LN2,
1053
+ LN10: Math.LN10,
1054
+ LOG2E: Math.LOG2E,
1055
+ LOG10E: Math.LOG10E,
1056
+ NaN: NaN,
1057
+ phi: (1 + Math.sqrt(5)) / 2,
1058
+ PI: Math.PI,
1059
+ pi: Math.PI,
1060
+ SQRT1_2: Math.SQRT1_2,
1061
+ SQRT2: Math.SQRT2,
1062
+ tau: 2 * Math.PI,
1063
+ true: 1
1064
+ };
1065
+ // src/services/compiler/getMathExpressionConstant.ts
1066
+ const getMathExpressionConstant = (name) => getOwnValue(MathExpressionConstantMap, name);
1067
+ // src/services/compiler/node/compileName.ts
1068
+ const compileName = (node, context) => {
1069
+ const slot = context.assignedSlots.get(node.name);
1070
+ if (slot !== void 0) return {
1071
+ evaluate: (_values, locals) => locals[slot] ?? null,
1072
+ isConstant: false
1073
+ };
1074
+ const index = context.variableIndices.get(node.name);
1075
+ if (index !== void 0) return {
1076
+ evaluate: (values) => values[index] ?? NaN,
1077
+ isConstant: false
1078
+ };
1079
+ const constant = getMathExpressionConstant(node.name);
1080
+ return {
1081
+ evaluate: () => constant ?? null,
1082
+ isConstant: true
1083
+ };
1084
+ };
1085
+ // src/services/compiler/node/compileNumber.ts
1086
+ const compileNumber = (node) => {
1087
+ const { value } = node;
1088
+ return {
1089
+ evaluate: () => value,
1090
+ isConstant: true
1091
+ };
1092
+ };
1093
+ // src/services/compiler/node/compilePercentage.ts
1094
+ const compilePercentage = (node, context) => {
1095
+ const compiledOperand = context.compile(node.operand);
1096
+ return {
1097
+ evaluate: (values, locals) => {
1098
+ const operandValue = compiledOperand.evaluate(values, locals);
1099
+ return operandValue === null ? null : operandValue / 100;
1100
+ },
1101
+ isConstant: compiledOperand.isConstant
1102
+ };
1103
+ };
1104
+ // src/services/compiler/node/compileUnary.ts
1105
+ const compileUnary = (node, context) => {
1106
+ const compute = getMathExpressionScalarCompute(node.name, "computeUnary");
1107
+ const compiledOperand = context.compile(node.operand);
1108
+ return {
1109
+ evaluate: (values, locals) => {
1110
+ const operandValue = compiledOperand.evaluate(values, locals);
1111
+ return operandValue === null ? null : compute(operandValue);
1112
+ },
1113
+ isConstant: compiledOperand.isConstant
1114
+ };
1115
+ };
1116
+ // src/services/compiler/MathExpressionNodeCompileMap.ts
1117
+ const MathExpressionNodeCompileMap = {
1118
+ ["assignment"]: compileAssignment,
1119
+ ["binary"]: compileBinary,
1120
+ ["call"]: compileCall,
1121
+ ["comparison"]: compileComparison,
1122
+ ["conditional"]: compileConditional,
1123
+ ["group"]: compileGroup,
1124
+ ["list"]: compileListNode,
1125
+ ["logical"]: compileLogical,
1126
+ ["name"]: compileName,
1127
+ ["number"]: compileNumber,
1128
+ ["percentage"]: compilePercentage,
1129
+ ["unary"]: compileUnary
1130
+ };
1131
+ // src/services/compiler/compileMathExpressionNode.ts
1132
+ const compileMathExpressionNode = (node, context) => {
1133
+ const compileOfType = MathExpressionNodeCompileMap[node.type];
1134
+ const compiled = compileOfType(node, context);
1135
+ if (!compiled.isConstant) return compiled;
1136
+ const value = compiled.evaluate(NO_VALUES, NO_LOCALS);
1137
+ return {
1138
+ evaluate: () => value,
1139
+ isConstant: true
1140
+ };
1141
+ };
1142
+ // src/services/compiler/getMathExpressionOuterValue.ts
1143
+ const getMathExpressionOuterValue = (outer, values) => {
1144
+ if (outer.variableIndex !== void 0) return values[outer.variableIndex] ?? NaN;
1145
+ return outer.constant ?? null;
1146
+ };
1147
+ // src/services/compiler/compileMathExpression.ts
1148
+ const compileMathExpression = (node, variableNames) => {
1149
+ const assignedNames = /* @__PURE__ */ new Set();
1150
+ collectMathExpressionAssignedNames(node, assignedNames);
1151
+ const assignedSlots = new Map(Array.from(assignedNames, (name, slot) => [name, slot]));
1152
+ const variableIndices = new Map(variableNames.map((name, index) => [name, index]));
1153
+ const context = {
1154
+ assignedSlots,
1155
+ compile: (child) => compileMathExpressionNode(child, context),
1156
+ variableIndices
1157
+ };
1158
+ const compiled = context.compile(node);
1159
+ const outerBindings = Array.from(assignedNames, (name) => ({
1160
+ constant: getMathExpressionConstant(name),
1161
+ variableIndex: variableIndices.get(name)
1162
+ }));
1163
+ return (values) => {
1164
+ const locals = outerBindings.length === 0 ? NO_LOCALS : outerBindings.map((outer) => getMathExpressionOuterValue(outer, values));
1165
+ return compiled.evaluate(values, locals) ?? NaN;
1166
+ };
1167
+ };
1168
+ // src/services/names/walkNode.ts
1169
+ const walkNode = (node, bound, free) => {
1170
+ switch (node.type) {
1171
+ case "assignment":
1172
+ walkNode(node.value, bound, free);
1173
+ bound.add(node.name);
1174
+ return;
1175
+ case "binary": {
1176
+ walkNode(node.left, bound, free);
1177
+ const rightBound = Object.hasOwn(MathExpressionBitwiseAbsorptionMap, node.name) ? new Set(bound) : bound;
1178
+ walkNode(node.right, rightBound, free);
1179
+ return;
1180
+ }
1181
+ case "call":
1182
+ case "group":
1183
+ case "list":
1184
+ case "number":
1185
+ case "percentage":
1186
+ case "unary":
1187
+ for (const child of getMathExpressionChildren(node)) walkNode(child, bound, free);
1188
+ return;
1189
+ case "comparison": {
1190
+ let chainBound = bound;
1191
+ for (const [index, operand] of node.operands.entries()) {
1192
+ if (index === 2) chainBound = new Set(bound);
1193
+ walkNode(operand, chainBound, free);
1194
+ }
1195
+ return;
1196
+ }
1197
+ case "conditional": {
1198
+ walkNode(node.condition, bound, free);
1199
+ const whenTrueBound = new Set(bound);
1200
+ const whenFalseBound = new Set(bound);
1201
+ walkNode(node.whenTrue, whenTrueBound, free);
1202
+ walkNode(node.whenFalse, whenFalseBound, free);
1203
+ for (const name of whenTrueBound) if (whenFalseBound.has(name)) bound.add(name);
1204
+ return;
1205
+ }
1206
+ case "logical":
1207
+ walkNode(node.left, bound, free);
1208
+ if (node.operator !== "nullish") walkNode(node.right, new Set(bound), free);
1209
+ return;
1210
+ case "name":
1211
+ if (!bound.has(node.name)) free.add(node.name);
1212
+ return;
1213
+ default: return exhaustiveGuard(node);
1214
+ }
1215
+ };
1216
+ // src/services/names/getMathExpressionNames.ts
1217
+ const getMathExpressionNames = (node) => {
1218
+ const bound = /* @__PURE__ */ new Set();
1219
+ const free = /* @__PURE__ */ new Set();
1220
+ walkNode(node, bound, free);
1221
+ return [...free].filter((name) => getMathExpressionConstant(name) === void 0);
1222
+ };
1223
+ // src/services/parser/constants.ts
1224
+ const MAX_MATH_EXPRESSION_DEPTH = 64;
1225
+ const PLACEHOLDER = {
1226
+ type: "number",
1227
+ value: NaN
1228
+ };
1229
+ // src/services/parser/failMathExpressionAt.ts
1230
+ const failMathExpressionAt = (state, message, column) => {
1231
+ if (state.error !== null) return;
1232
+ state.error = new MathExpressionError(`${message} (char ${column})`);
1233
+ };
1234
+ // src/services/parser/getMathExpressionColumn.ts
1235
+ const getMathExpressionColumn = (state) => state.index - state.token.length + 1;
1236
+ // src/services/parser/failMathExpression.ts
1237
+ const failMathExpression = (state, message) => {
1238
+ failMathExpressionAt(state, message, getMathExpressionColumn(state));
1239
+ };
1240
+ // src/services/parser/checkCanMathExpressionNest.ts
1241
+ const checkCanMathExpressionNest = (state) => {
1242
+ if (state.depth < 64) return true;
1243
+ failMathExpression(state, `Formula nests deeper than 64 levels`);
1244
+ return false;
1245
+ };
1246
+ // src/services/parser/checkIsOperatorOperand.ts
1247
+ const checkIsOperatorOperand = (node) => {
1248
+ if (node.type === "unary") return node.name !== "factorial";
1249
+ return node.type === "binary" || node.type === "comparison" || node.type === "logical";
1250
+ };
1251
+ // src/services/parser/checkIsToken.ts
1252
+ const checkIsToken = (state, token) => state.token === token;
1253
+ // src/services/parser/checkIsFactorStart.ts
1254
+ const checkIsFactorStart = (state, last) => {
1255
+ if (last.type === "percentage") return false;
1256
+ if (state.tokenType === "symbol" || checkIsToken(state, "(")) return true;
1257
+ return state.tokenType === "number" && last.type !== "number" && !checkIsOperatorOperand(last);
1258
+ };
1259
+ // src/services/parser/checkIsNameToken.ts
1260
+ const checkIsNameToken = (state) => state.tokenType === "symbol" || state.tokenType === "delimiter" && getMathExpressionSignatures(state.token) !== void 0;
1261
+ // src/services/parser/token/MathExpressionRadixMap.ts
1262
+ const MathExpressionRadixMap = {
1263
+ ["b"]: {
1264
+ digit: /^[01]$/u,
1265
+ radix: 2
1266
+ },
1267
+ ["x"]: {
1268
+ digit: /^[0-9a-fA-F]$/u,
1269
+ radix: 16
1270
+ },
1271
+ ["o"]: {
1272
+ digit: /^[0-7]$/u,
1273
+ radix: 8
1274
+ }
1275
+ };
1276
+ // src/services/parser/computeNumberLiteral.ts
1277
+ const computeNumberLiteral = (token) => {
1278
+ const radixEntry = MathExpressionRadixMap[token.charAt(1)];
1279
+ if (!token.startsWith("0") || radixEntry === void 0) return Number(token);
1280
+ const { radix } = radixEntry;
1281
+ const [digits = "", wordSize] = token.slice(2).split("i");
1282
+ const [integerDigits = "", fractionDigits = ""] = digits.split(".");
1283
+ let value = 0;
1284
+ for (const digit of integerDigits) value = value * radix + Number.parseInt(digit, radix);
1285
+ let scale = 1 / radix;
1286
+ for (const digit of fractionDigits) {
1287
+ value += Number.parseInt(digit, radix) * scale;
1288
+ scale /= radix;
1289
+ }
1290
+ if (wordSize === void 0) return value;
1291
+ const bits = Number(wordSize);
1292
+ if (value > 2 ** bits - 1) return null;
1293
+ return value >= 2 ** (bits - 1) ? value - 2 ** bits : value;
1294
+ };
1295
+ // src/services/parser/createBinaryNode.ts
1296
+ const createBinaryNode = (left, name, right) => ({
1297
+ left,
1298
+ name,
1299
+ right,
1300
+ type: "binary"
1301
+ });
1302
+ // src/services/parser/createLogicalNode.ts
1303
+ const createLogicalNode = (left, operator, right) => ({
1304
+ left,
1305
+ operator,
1306
+ right,
1307
+ type: "logical"
1308
+ });
1309
+ // src/services/parser/createBinaryOperation.ts
1310
+ const createBinaryOperation = (left, operator, right) => {
1311
+ if (operator.type === "logical") return createLogicalNode(left, operator.operator, right);
1312
+ if (operator.type === "binary") return createBinaryNode(left, operator.name, right);
1313
+ if (left.type === "comparison") {
1314
+ left.names.push(operator.name);
1315
+ left.operands.push(right);
1316
+ return left;
1317
+ }
1318
+ return {
1319
+ names: [operator.name],
1320
+ operands: [left, right],
1321
+ type: "comparison"
1322
+ };
1323
+ };
1324
+ // src/services/parser/getArgumentCountText.ts
1325
+ const getArgumentCountText = (count) => `${count} ${count === 1 ? "argument" : "arguments"}`;
1326
+ // src/services/parser/getMathExpressionArityMessage.ts
1327
+ const getMathExpressionArityMessage = (name, minArity, maxArity) => {
1328
+ if (maxArity === Number.POSITIVE_INFINITY) return `"${name}" takes at least ${getArgumentCountText(minArity)}`;
1329
+ if (minArity === maxArity) return `"${name}" takes ${getArgumentCountText(minArity)}`;
1330
+ return `"${name}" takes ${minArity} or ${maxArity} arguments`;
1331
+ };
1332
+ // src/services/parser/getMathExpressionSignatureError.ts
1333
+ const getMathExpressionSignatureError = (name, signatures, parameterTypes) => {
1334
+ const count = parameterTypes.length;
1335
+ if (signatures.filter((signature) => count >= signature.minArity && count <= signature.maxArity).length === 0) return getMathExpressionArityMessage(name, Math.min(...signatures.map((signature) => signature.minArity)), Math.max(...signatures.map((signature) => signature.maxArity)));
1336
+ if (parameterTypes.includes("list")) return `"${name}" does not take a list argument`;
1337
+ return `"${name}" takes a list argument`;
1338
+ };
1339
+ // src/services/parser/token/checkIsDigitCharacter.ts
1340
+ const checkIsDigitCharacter = (character) => character >= "0" && character <= "9";
1341
+ // src/services/parser/token/constants.ts
1342
+ const SYMBOLIC_BINARY_SYMBOLS = Object.values(MathExpressionBinaryOperatorSymbol).filter((symbol) => !/\p{L}/u.test(symbol));
1343
+ const SYMBOLIC_BINARY_SYMBOLS_OF_THREE = SYMBOLIC_BINARY_SYMBOLS.filter((symbol) => symbol.length === 3);
1344
+ const SYMBOLIC_BINARY_SYMBOLS_OF_TWO = SYMBOLIC_BINARY_SYMBOLS.filter((symbol) => symbol.length === 2);
1345
+ const SYMBOLIC_BINARY_SYMBOLS_OF_ONE = SYMBOLIC_BINARY_SYMBOLS.filter((symbol) => symbol.length === 1);
1346
+ const DELIMITERS_OF_THREE = new Set(SYMBOLIC_BINARY_SYMBOLS_OF_THREE);
1347
+ const DELIMITERS_OF_TWO = /* @__PURE__ */ new Set([
1348
+ ...SYMBOLIC_BINARY_SYMBOLS_OF_TWO,
1349
+ ".^",
1350
+ "??"
1351
+ ]);
1352
+ const DELIMITERS_OF_ONE = /* @__PURE__ */ new Set([
1353
+ ...SYMBOLIC_BINARY_SYMBOLS_OF_ONE,
1354
+ "!",
1355
+ "%",
1356
+ "'",
1357
+ "(",
1358
+ ")",
1359
+ ",",
1360
+ ":",
1361
+ "=",
1362
+ "?",
1363
+ "[",
1364
+ "]",
1365
+ "^",
1366
+ "~"
1367
+ ]);
1368
+ const FIRST_CHARACTERS_OF_THREE = new Set(Array.from(DELIMITERS_OF_THREE, (delimiter) => delimiter.charAt(0)));
1369
+ const FIRST_CHARACTERS_OF_TWO = new Set(Array.from(DELIMITERS_OF_TWO, (delimiter) => delimiter.charAt(0)));
1370
+ const NAMED_DELIMITERS = /* @__PURE__ */ new Set([
1371
+ "in",
1372
+ "and",
1373
+ "or",
1374
+ "xor",
1375
+ "mod",
1376
+ "not",
1377
+ "to"
1378
+ ]);
1379
+ const DECIMAL_MARK_OPERATOR_FOLLOWERS = /* @__PURE__ */ new Set([
1380
+ "^",
1381
+ "/",
1382
+ "*"
1383
+ ]);
1384
+ const WORD_START_REGEX = /^[\p{L}_$]$/u;
1385
+ const WORD_CHARACTER_REGEX = /^[\p{L}\p{Nd}_$]$/u;
1386
+ // src/services/parser/token/checkIsWordStartCharacter.ts
1387
+ const checkIsWordStartCharacter = (character) => {
1388
+ if (character >= "€") return WORD_START_REGEX.test(character);
1389
+ return character >= "a" && character <= "z" || character >= "A" && character <= "Z" || character === "_" || character === "$";
1390
+ };
1391
+ // src/services/parser/token/getMathExpressionCharacter.ts
1392
+ const getMathExpressionCharacter = (state, offset) => state.source.charAt(state.index + offset);
1393
+ // src/services/parser/token/readMathExpressionDelimiter.ts
1394
+ const readMathExpressionDelimiter = (state) => {
1395
+ const character = getMathExpressionCharacter(state, 0);
1396
+ let length = 0;
1397
+ if (FIRST_CHARACTERS_OF_THREE.has(character) && DELIMITERS_OF_THREE.has(state.source.slice(state.index, state.index + 3))) length = 3;
1398
+ else if (FIRST_CHARACTERS_OF_TWO.has(character) && DELIMITERS_OF_TWO.has(state.source.slice(state.index, state.index + 2))) length = 2;
1399
+ else if (DELIMITERS_OF_ONE.has(character)) length = 1;
1400
+ if (length === 0) return 0;
1401
+ state.token = state.source.slice(state.index, state.index + length);
1402
+ state.index += length;
1403
+ state.tokenType = "delimiter";
1404
+ if (["(", "["].includes(state.token)) state.nestingLevel++;
1405
+ if ([")", "]"].includes(state.token)) state.nestingLevel--;
1406
+ return length;
1407
+ };
1408
+ // src/services/parser/token/takeMathExpressionMatching.ts
1409
+ const takeMathExpressionMatching = (state, checkCharacter) => {
1410
+ const start = state.index;
1411
+ while (checkCharacter(getMathExpressionCharacter(state, 0))) state.index++;
1412
+ return state.source.slice(start, state.index);
1413
+ };
1414
+ // src/services/parser/token/readRadixNumber.ts
1415
+ const readRadixNumber = (state, prefix, baseDigits) => {
1416
+ const checkBaseDigit = (character) => baseDigits.test(character);
1417
+ state.index += 2;
1418
+ let digits = takeMathExpressionMatching(state, checkBaseDigit);
1419
+ if (digits === "") {
1420
+ state.index--;
1421
+ state.token = "0";
1422
+ state.tokenType = "number";
1423
+ return;
1424
+ }
1425
+ if (getMathExpressionCharacter(state, 0) === ".") {
1426
+ state.index++;
1427
+ digits += `.${takeMathExpressionMatching(state, checkBaseDigit)}`;
1428
+ }
1429
+ let wordSize = "";
1430
+ if (getMathExpressionCharacter(state, 0) === "i" && checkIsDigitCharacter(getMathExpressionCharacter(state, 1))) {
1431
+ state.index++;
1432
+ wordSize = `i${takeMathExpressionMatching(state, checkIsDigitCharacter)}`;
1433
+ }
1434
+ state.token = `0${prefix}${digits}${wordSize}`;
1435
+ state.tokenType = "number";
1436
+ };
1437
+ // src/services/parser/token/checkIsDecimalMark.ts
1438
+ const checkIsDecimalMark = (character, nextCharacter) => character === "." && !DECIMAL_MARK_OPERATOR_FOLLOWERS.has(nextCharacter);
1439
+ // src/services/parser/token/failExponent.ts
1440
+ const failExponent = (state, text) => {
1441
+ state.token = text;
1442
+ failMathExpression(state, `Digit expected, got "${getMathExpressionCharacter(state, 0)}"`);
1443
+ };
1444
+ // src/services/parser/token/takeExponent.ts
1445
+ const takeExponent = (state, text) => {
1446
+ const exponentMarker = getMathExpressionCharacter(state, 0);
1447
+ if (!["e", "E"].includes(exponentMarker)) return text;
1448
+ const afterMarker = getMathExpressionCharacter(state, 1);
1449
+ if (checkIsDecimalMark(afterMarker, getMathExpressionCharacter(state, 2))) {
1450
+ state.index++;
1451
+ failExponent(state, text);
1452
+ return text;
1453
+ }
1454
+ if (!checkIsDigitCharacter(afterMarker) && !["+", "-"].includes(afterMarker)) return text;
1455
+ state.index++;
1456
+ let exponent = "e";
1457
+ if (["+", "-"].includes(afterMarker)) {
1458
+ exponent += afterMarker;
1459
+ state.index++;
1460
+ }
1461
+ if (!checkIsDigitCharacter(getMathExpressionCharacter(state, 0))) {
1462
+ const partial = text + exponent;
1463
+ failExponent(state, partial);
1464
+ return partial;
1465
+ }
1466
+ const taken = text + exponent + takeMathExpressionMatching(state, checkIsDigitCharacter);
1467
+ if (checkIsDecimalMark(getMathExpressionCharacter(state, 0), getMathExpressionCharacter(state, 1))) failExponent(state, taken);
1468
+ return taken;
1469
+ };
1470
+ // src/services/parser/token/readMathExpressionNumber.ts
1471
+ const readMathExpressionNumber = (state) => {
1472
+ const prefix = getMathExpressionCharacter(state, 1);
1473
+ const radixEntry = MathExpressionRadixMap[prefix];
1474
+ if (getMathExpressionCharacter(state, 0) === "0" && radixEntry !== void 0) {
1475
+ readRadixNumber(state, prefix, radixEntry.digit);
1476
+ return;
1477
+ }
1478
+ const start = state.index;
1479
+ takeMathExpressionMatching(state, checkIsDigitCharacter);
1480
+ if (getMathExpressionCharacter(state, 0) === ".") {
1481
+ state.index++;
1482
+ takeMathExpressionMatching(state, checkIsDigitCharacter);
1483
+ }
1484
+ state.token = takeExponent(state, state.source.slice(start, state.index));
1485
+ state.tokenType = "number";
1486
+ };
1487
+ // src/services/parser/token/checkIsWordCharacter.ts
1488
+ const checkIsWordCharacter = (character) => {
1489
+ if (character >= "€") return WORD_CHARACTER_REGEX.test(character);
1490
+ return checkIsWordStartCharacter(character) || checkIsDigitCharacter(character);
1491
+ };
1492
+ // src/services/parser/token/readMathExpressionWord.ts
1493
+ const readMathExpressionWord = (state) => {
1494
+ state.token = takeMathExpressionMatching(state, checkIsWordCharacter);
1495
+ state.tokenType = NAMED_DELIMITERS.has(state.token) ? "delimiter" : "symbol";
1496
+ };
1497
+ // src/services/parser/token/skipMathExpressionSpaces.ts
1498
+ const skipMathExpressionSpaces = (state) => {
1499
+ while (state.index < state.source.length) {
1500
+ const character = getMathExpressionCharacter(state, 0);
1501
+ if ([
1502
+ " ",
1503
+ " ",
1504
+ "\xA0"
1505
+ ].includes(character) || character === "\n" && state.nestingLevel > 0) state.index++;
1506
+ else if (character === "#") while (state.index < state.source.length && getMathExpressionCharacter(state, 0) !== "\n") state.index++;
1507
+ else break;
1508
+ }
1509
+ };
1510
+ // src/services/parser/getMathExpressionToken.ts
1511
+ const getMathExpressionToken = (state) => {
1512
+ state.token = "";
1513
+ state.tokenType = "null";
1514
+ skipMathExpressionSpaces(state);
1515
+ if (state.index >= state.source.length || state.error !== null) return;
1516
+ const character = getMathExpressionCharacter(state, 0);
1517
+ const next = getMathExpressionCharacter(state, 1);
1518
+ if (checkIsDigitCharacter(character) || character === "." && checkIsDigitCharacter(next)) readMathExpressionNumber(state);
1519
+ else if (checkIsWordStartCharacter(character)) readMathExpressionWord(state);
1520
+ else if (readMathExpressionDelimiter(state) === 0) {
1521
+ state.token = character;
1522
+ state.index++;
1523
+ state.tokenType = "unknown";
1524
+ }
1525
+ };
1526
+ // src/services/parser/MathExpressionBinaryOperatorMap.ts
1527
+ const MathExpressionBinaryOperatorMap = {
1528
+ ["+"]: {
1529
+ name: "add",
1530
+ power: 9,
1531
+ type: "binary"
1532
+ },
1533
+ ["and"]: {
1534
+ operator: "and",
1535
+ power: 3,
1536
+ type: "logical"
1537
+ },
1538
+ ["&"]: {
1539
+ name: "bitAnd",
1540
+ power: 6,
1541
+ type: "binary"
1542
+ },
1543
+ ["|"]: {
1544
+ name: "bitOr",
1545
+ power: 4,
1546
+ type: "binary"
1547
+ },
1548
+ ["^|"]: {
1549
+ name: "bitXor",
1550
+ power: 5,
1551
+ type: "binary"
1552
+ },
1553
+ ["/"]: {
1554
+ name: "divide",
1555
+ power: 10,
1556
+ type: "binary"
1557
+ },
1558
+ ["./"]: {
1559
+ name: "dotDivide",
1560
+ power: 10,
1561
+ type: "binary"
1562
+ },
1563
+ [".*"]: {
1564
+ name: "dotMultiply",
1565
+ power: 10,
1566
+ type: "binary"
1567
+ },
1568
+ ["=="]: {
1569
+ name: "equal",
1570
+ power: 7,
1571
+ type: "comparison"
1572
+ },
1573
+ [">"]: {
1574
+ name: "larger",
1575
+ power: 7,
1576
+ type: "comparison"
1577
+ },
1578
+ [">="]: {
1579
+ name: "largerEq",
1580
+ power: 7,
1581
+ type: "comparison"
1582
+ },
1583
+ ["<"]: {
1584
+ name: "smaller",
1585
+ power: 7,
1586
+ type: "comparison"
1587
+ },
1588
+ ["<="]: {
1589
+ name: "smallerEq",
1590
+ power: 7,
1591
+ type: "comparison"
1592
+ },
1593
+ ["*"]: {
1594
+ name: "multiply",
1595
+ power: 10,
1596
+ type: "binary"
1597
+ },
1598
+ ["!="]: {
1599
+ name: "unequal",
1600
+ power: 7,
1601
+ type: "comparison"
1602
+ },
1603
+ ["or"]: {
1604
+ operator: "or",
1605
+ power: 1,
1606
+ type: "logical"
1607
+ },
1608
+ ["<<"]: {
1609
+ name: "leftShift",
1610
+ power: 8,
1611
+ type: "binary"
1612
+ },
1613
+ [">>"]: {
1614
+ name: "rightArithShift",
1615
+ power: 8,
1616
+ type: "binary"
1617
+ },
1618
+ ["-"]: {
1619
+ name: "subtract",
1620
+ power: 9,
1621
+ type: "binary"
1622
+ },
1623
+ [">>>"]: {
1624
+ name: "rightLogShift",
1625
+ power: 8,
1626
+ type: "binary"
1627
+ },
1628
+ ["xor"]: {
1629
+ name: "xor",
1630
+ power: 2,
1631
+ type: "binary"
1632
+ }
1633
+ };
1634
+ // src/services/parser/MathExpressionOperatorMap.ts
1635
+ const MathExpressionOperatorMap = {
1636
+ ["Nullish"]: { "??": "nullish" },
1637
+ ["Power"]: {
1638
+ ".^": "dotPow",
1639
+ "^": "pow"
1640
+ },
1641
+ ["Unary"]: {
1642
+ "+": "unaryPlus",
1643
+ "-": "unaryMinus",
1644
+ not: "not",
1645
+ "~": "bitNot"
1646
+ }
1647
+ };
1648
+ // src/services/parser/rule/parseAssignment.ts
1649
+ const parseAssignment = (state, parse) => {
1650
+ if (!checkCanMathExpressionNest(state)) return PLACEHOLDER;
1651
+ state.depth++;
1652
+ const left = parse(state, "Conditional");
1653
+ let node = left;
1654
+ if (state.error === null && checkIsToken(state, "=")) if (left.type === "name") {
1655
+ getMathExpressionToken(state);
1656
+ const value = parse(state, "Assignment");
1657
+ node = {
1658
+ name: left.name,
1659
+ type: "assignment",
1660
+ value
1661
+ };
1662
+ } else failMathExpression(state, "Invalid left hand side of assignment operator =");
1663
+ state.depth--;
1664
+ return node;
1665
+ };
1666
+ // src/services/parser/parseBinaryOperators.ts
1667
+ const parseBinaryOperators = (state, parse, minimumPower) => {
1668
+ let node = parse(state, "Percentage");
1669
+ let last = node;
1670
+ while (state.error === null) {
1671
+ const isImplicit = checkIsFactorStart(state, last);
1672
+ const operator = isImplicit ? MathExpressionBinaryOperatorMap["*"] : getOwnValue(MathExpressionBinaryOperatorMap, state.token);
1673
+ if (operator === void 0 || operator.power < minimumPower) break;
1674
+ if (!isImplicit) getMathExpressionToken(state);
1675
+ last = parseBinaryOperators(state, parse, operator.power + 1);
1676
+ node = createBinaryOperation(node, operator, last);
1677
+ }
1678
+ return node;
1679
+ };
1680
+ // src/services/parser/rule/parseBinary.ts
1681
+ const parseBinary = (state, parse) => parseBinaryOperators(state, parse, 0);
1682
+ // src/services/parser/rule/parseConditional.ts
1683
+ const parseConditional = (state, parse) => {
1684
+ const condition = parse(state, "Binary");
1685
+ if (state.error !== null || !checkIsToken(state, "?")) return condition;
1686
+ getMathExpressionToken(state);
1687
+ if (checkIsToken(state, ":")) {
1688
+ failMathExpression(state, "The true-expression of a conditional operator may not be empty");
1689
+ return PLACEHOLDER;
1690
+ }
1691
+ const whenTrue = parse(state, "Assignment");
1692
+ if (state.error === null && !checkIsToken(state, ":")) failMathExpression(state, "False part of conditional expression expected");
1693
+ if (state.error !== null) return PLACEHOLDER;
1694
+ getMathExpressionToken(state);
1695
+ state.depth++;
1696
+ const whenFalse = parse(state, "Conditional");
1697
+ state.depth--;
1698
+ return {
1699
+ condition,
1700
+ type: "conditional",
1701
+ whenFalse,
1702
+ whenTrue
1703
+ };
1704
+ };
1705
+ // src/services/parser/rule/parseLeftHand.ts
1706
+ const parseLeftHand = (state, parse) => {
1707
+ let node = parse(state, "Symbol");
1708
+ while (state.error === null && (checkIsToken(state, "!") || checkIsToken(state, "'"))) {
1709
+ const name = checkIsToken(state, "!") ? "factorial" : "ctranspose";
1710
+ getMathExpressionToken(state);
1711
+ node = {
1712
+ name,
1713
+ operand: node,
1714
+ type: "unary"
1715
+ };
1716
+ }
1717
+ return node;
1718
+ };
1719
+ // src/services/parser/rule/parseNullish.ts
1720
+ const parseNullish = (state, parse) => {
1721
+ const operators = MathExpressionOperatorMap["Nullish"];
1722
+ let node = parse(state, "LeftHand");
1723
+ let operator = getOwnValue(operators, state.token);
1724
+ while (state.error === null && operator !== void 0) {
1725
+ getMathExpressionToken(state);
1726
+ const right = parse(state, "LeftHand");
1727
+ node = createLogicalNode(node, operator, right);
1728
+ operator = getOwnValue(operators, state.token);
1729
+ }
1730
+ return node;
1731
+ };
1732
+ // src/services/parser/rule/parsePercentage.ts
1733
+ const parsePercentage = (state, parse) => {
1734
+ const node = parse(state, "Unary");
1735
+ if (state.error !== null || !checkIsToken(state, "%")) return node;
1736
+ getMathExpressionToken(state);
1737
+ return {
1738
+ operand: node,
1739
+ type: "percentage"
1740
+ };
1741
+ };
1742
+ // src/services/parser/rule/parsePower.ts
1743
+ const parsePower = (state, parse) => {
1744
+ const base = parse(state, "Nullish");
1745
+ const name = getOwnValue(MathExpressionOperatorMap["Power"], state.token);
1746
+ if (state.error !== null || name === void 0) return base;
1747
+ if (!checkCanMathExpressionNest(state)) return PLACEHOLDER;
1748
+ getMathExpressionToken(state);
1749
+ state.depth++;
1750
+ const exponent = parse(state, "Unary");
1751
+ state.depth--;
1752
+ return createBinaryNode(base, name, exponent);
1753
+ };
1754
+ // src/services/parser/parseSequence.ts
1755
+ const parseSequence = (state, closing, parseItem) => {
1756
+ const nodes = [];
1757
+ if (checkIsToken(state, closing)) return nodes;
1758
+ while (state.error === null) {
1759
+ nodes.push(parseItem(state));
1760
+ if (!checkIsToken(state, ",")) break;
1761
+ getMathExpressionToken(state);
1762
+ }
1763
+ if (state.error === null && !checkIsToken(state, closing)) failMathExpression(state, closing === ")" ? "Parenthesis ) expected" : "Parenthesis ] expected");
1764
+ return nodes;
1765
+ };
1766
+ // src/services/parser/parseList.ts
1767
+ const parseList = (state, parse) => {
1768
+ getMathExpressionToken(state);
1769
+ const elements = parseSequence(state, "]", (item) => parse(item, "Assignment"));
1770
+ if (state.error !== null) return PLACEHOLDER;
1771
+ getMathExpressionToken(state);
1772
+ return {
1773
+ elements,
1774
+ type: "list"
1775
+ };
1776
+ };
1777
+ // src/services/parser/parseArgument.ts
1778
+ const parseArgument = (state, parse) => checkIsToken(state, "[") ? parseList(state, parse) : parse(state, "Assignment");
1779
+ // src/services/parser/parseCall.ts
1780
+ const parseCall = (state, name, column, parse) => {
1781
+ const signatures = getMathExpressionSignatures(name);
1782
+ if (signatures === void 0) {
1783
+ failMathExpressionAt(state, `Unknown function "${name}"`, column);
1784
+ return PLACEHOLDER;
1785
+ }
1786
+ getMathExpressionToken(state);
1787
+ const argumentNodes = parseSequence(state, ")", (argument) => parseArgument(argument, parse));
1788
+ if (state.error !== null) return PLACEHOLDER;
1789
+ getMathExpressionToken(state);
1790
+ const parameterTypes = argumentNodes.map((argument) => getMathExpressionParameterType(argument));
1791
+ if (matchMathExpressionSignature(signatures, parameterTypes) === void 0) {
1792
+ failMathExpressionAt(state, getMathExpressionSignatureError(name, signatures, parameterTypes), column);
1793
+ return PLACEHOLDER;
1794
+ }
1795
+ return {
1796
+ arguments: argumentNodes,
1797
+ name,
1798
+ type: "call"
1799
+ };
1800
+ };
1801
+ // src/services/parser/rule/parseSymbol.ts
1802
+ const parseSymbol = (state, parse) => {
1803
+ if (state.tokenType === "number") {
1804
+ const value = computeNumberLiteral(state.token);
1805
+ if (value === null) {
1806
+ failMathExpression(state, `String "${state.token.split("i")[0]}" is out of range`);
1807
+ getMathExpressionToken(state);
1808
+ return PLACEHOLDER;
1809
+ }
1810
+ getMathExpressionToken(state);
1811
+ return {
1812
+ type: "number",
1813
+ value
1814
+ };
1815
+ }
1816
+ if (checkIsNameToken(state)) {
1817
+ const name = state.token;
1818
+ const column = getMathExpressionColumn(state);
1819
+ const isSymbol = state.tokenType === "symbol";
1820
+ getMathExpressionToken(state);
1821
+ if (checkIsToken(state, "(")) return parseCall(state, name, column, parse);
1822
+ if (isSymbol) return {
1823
+ name,
1824
+ type: "name"
1825
+ };
1826
+ }
1827
+ if (checkIsToken(state, "(")) {
1828
+ getMathExpressionToken(state);
1829
+ const operand = parse(state, "Assignment");
1830
+ if (state.error === null && !checkIsToken(state, ")")) failMathExpression(state, "Parenthesis ) expected");
1831
+ if (state.error !== null) return PLACEHOLDER;
1832
+ getMathExpressionToken(state);
1833
+ return {
1834
+ operand,
1835
+ type: "group"
1836
+ };
1837
+ }
1838
+ failMathExpression(state, checkIsToken(state, "") ? "Unexpected end of expression" : "Value expected");
1839
+ return PLACEHOLDER;
1840
+ };
1841
+ // src/services/parser/rule/parseUnary.ts
1842
+ const parseUnary = (state, parse) => {
1843
+ const name = getOwnValue(MathExpressionOperatorMap["Unary"], state.token);
1844
+ if (name === void 0) return parse(state, "Power");
1845
+ if (!checkCanMathExpressionNest(state)) return PLACEHOLDER;
1846
+ getMathExpressionToken(state);
1847
+ state.depth++;
1848
+ const operand = parse(state, "Unary");
1849
+ state.depth--;
1850
+ return {
1851
+ name,
1852
+ operand,
1853
+ type: "unary"
1854
+ };
1855
+ };
1856
+ // src/services/parser/MathExpressionRuleParserMap.ts
1857
+ const MathExpressionRuleParserMap = {
1858
+ ["Assignment"]: parseAssignment,
1859
+ ["Binary"]: parseBinary,
1860
+ ["Conditional"]: parseConditional,
1861
+ ["LeftHand"]: parseLeftHand,
1862
+ ["Nullish"]: parseNullish,
1863
+ ["Percentage"]: parsePercentage,
1864
+ ["Power"]: parsePower,
1865
+ ["Symbol"]: parseSymbol,
1866
+ ["Unary"]: parseUnary
1867
+ };
1868
+ // src/services/parser/parseMathExpressionRule.ts
1869
+ const parseMathExpressionRule = (state, rule) => MathExpressionRuleParserMap[rule](state, parseMathExpressionRule);
1870
+ // src/services/parser/parseMathExpression.ts
1871
+ const parseMathExpression = (formula) => {
1872
+ const state = {
1873
+ depth: 0,
1874
+ error: null,
1875
+ index: 0,
1876
+ nestingLevel: 0,
1877
+ source: formula,
1878
+ token: "",
1879
+ tokenType: "null"
1880
+ };
1881
+ getMathExpressionToken(state);
1882
+ const node = parseMathExpressionRule(state, "Assignment");
1883
+ if (state.error === null && !checkIsToken(state, "")) failMathExpression(state, state.tokenType === "delimiter" ? `Unexpected operator ${state.token}` : `Unexpected part "${state.token}"`);
1884
+ return state.error === null ? ok(node) : err(state.error);
1885
+ };
1886
+ export { ADDITIVE_NAMES, DECIMAL_MARK_OPERATOR_FOLLOWERS, DELIMITERS_OF_ONE, DELIMITERS_OF_THREE, DELIMITERS_OF_TWO, FIRST_CHARACTERS_OF_THREE, FIRST_CHARACTERS_OF_TWO, LAST_FACTORIAL_ARGUMENT, MATH_EXPRESSION_ABSOLUTE_TOLERANCE, MATH_EXPRESSION_RELATIVE_TOLERANCE, MAXIMUM_DIGITS, MAX_MATH_EXPRESSION_DEPTH, MILLER_RABIN_BASES, MathExpressionBinaryOperatorMap, MathExpressionBinaryOperatorSymbol, MathExpressionBitwiseAbsorption, MathExpressionBitwiseAbsorptionMap, MathExpressionConstantMap, MathExpressionError, MathExpressionFunctionMap, MathExpressionFunctionName, MathExpressionGrammarRule, MathExpressionLogicalOperator, MathExpressionNodeCompileMap, MathExpressionNodeType, MathExpressionOperatorMap, MathExpressionParameterType, MathExpressionRadix, MathExpressionRadixMap, MathExpressionRuleParserMap, MathExpressionTokenType, NAMED_DELIMITERS, NO_LOCALS, NO_VALUES, OVERFLOW_ARGUMENT, PLACEHOLDER, SQRT_PI, STIRLING_TERMS, STIRLING_THRESHOLD, WORD_CHARACTER_REGEX, WORD_START_REGEX, checkCanMathExpressionNest, checkIsDecimalMark, checkIsDigitCharacter, checkIsFactorStart, checkIsLarger, checkIsMatching, checkIsMatchingKind, checkIsMillerRabinPassing, checkIsNameToken, checkIsNearlyEqual, checkIsOperatorOperand, checkIsPercentageExpression, checkIsPrime, checkIsSmaller, checkIsToken, checkIsTruthy, checkIsWordCharacter, checkIsWordStartCharacter, collectMathExpressionAssignedNames, compareNumbers, compileArgument, compileAssignment, compileBinary, compileCall, compileComparison, compileConditional, compileGroup, compileList, compileListNode, compileLogical, compileMathExpression, compileMathExpressionNode, compileName, compileNumber, compilePercentage, compileUnary, computeBitwiseAnd, computeBitwiseOr, computeCombinations, computeComparison, computeCompositions, computeCorrelation, computeDeterminant, computeDistance, computeDotProduct, computeErf, computeExtreme, computeFactorial, computeGamma, computeGreatestCommonDivisor, computeHypotenuse, computeIntegerGreatestCommonDivisor, computeInverseCoth, computeKullbackLeibler, computeLeastCommonMultiple, computeListComparison, computeLogGammaOfPositive, computeLogarithm, computeMean, computeMedian, computeMedianAbsoluteDeviation, computeModularInverse, computeModularPower, computeModulo, computeMultinomial, computeNorm, computeNthRoot, computeNumberLiteral, computePartitionSelect, computePermutations, computePointToLine2D, computePointToLine3D, computeProduct, computeProductOfRange, computeQuantile, computeStirlingLogGamma, computeSum, computeTruthyCount, computeVariance, computeVectorNorm, createBinaryNode, createBinaryOperation, createBinarySignatures, createBitwiseFold, createBitwisePair, createDigitSignatures, createExtremeSignatures, createIdentitySignatures, createIntegerBinarySignatures, createIntegerUnarySignatures, createListFirstCompute, createListPairCompute, createListPairSignature, createListSignature, createLogicalNode, createNonEmptyCompute, createNumberSignature, createNumericCompute, createOrderedListSignatures, createRangedSignatures, createSignature, createSingletonListSignature, createSpreadSignatures, createUnarySignatures, createVariadicSignatures, failExponent, failMathExpression, failMathExpressionAt, getArgumentCountText, getMathExpressionArityMessage, getMathExpressionCharacter, getMathExpressionChildren, getMathExpressionColumn, getMathExpressionConstant, getMathExpressionNames, getMathExpressionOuterValue, getMathExpressionParameterType, getMathExpressionScalarCompute, getMathExpressionSignatureError, getMathExpressionSignatures, getMathExpressionToken, getOwnValue, getParameterType, matchMathExpressionSignature, multiplyPair, parseArgument, parseAssignment, parseBinary, parseBinaryOperators, parseCall, parseConditional, parseLeftHand, parseList, parseMathExpression, parseMathExpressionRule, parseNullish, parsePercentage, parsePower, parseSequence, parseSymbol, parseUnary, readMathExpressionDelimiter, readMathExpressionNumber, readMathExpressionWord, readRadixNumber, roundToDigits, scaleList, shiftDecimalPlaces, skipMathExpressionSpaces, takeExponent, takeMathExpressionMatching, toNumber, walkNode };