MCPcopy Create free account
hub / github.com/cortex-js/compute-engine / parseDSLGroup

Function parseDSLGroup

src/compute-engine/numerics/unit-data.ts:534–598  ·  view source on GitHub ↗

* Parse a DSL group, which may contain parenthesized sub-expressions. * Handles `(m*s^2)` by stripping outer parens and recursing. * * A single pass finds both the first top-level `/` and all top-level `*` * split points. `/` binds more loosely than `*`, so if a slash is found * the string is

(s: string)

Source from the content-addressed store, hash-verified

532 * Flatten a compound unit expression into a map from unit symbol to its
533 * summed exponent.
534 *
535 * - `string` → add `exp` to the symbol's running total.
536 * - `["Multiply", ...]` → recurse each child with the same exponent.
537 * - `["Divide", a, b]` → recurse `a` with `+exp`, `b` with `−exp`.
538 * - `["Power", base, n]` (n a number) → recurse `base` with `exp·n`.
539 *
540 * Returns `null` on any other shape (the caller then leaves the unit
541 * untouched). Because same-symbol exponents are summed, `in¹·in⁻¹` cancels
542 * exactly, with no floating-point scale involved.
543 */
544export function flattenUnitFactors(
545 expr: UnitExpression
546): Map<string, number> | null {
547 const factors = new Map<string, number>();
548
549 function walk(e: UnitExpression, exp: number): boolean {
550 if (typeof e === 'string') {
551 factors.set(e, (factors.get(e) ?? 0) + exp);
552 return true;
553 }
554 if (!Array.isArray(e) || e.length < 2) return false;
555 const op = e[0];
556 if (op === 'Multiply') {
557 for (let i = 1; i < e.length; i++) if (!walk(e[i], exp)) return false;
558 return true;
559 }
560 if (op === 'Divide') {
561 if (e.length !== 3) return false;
562 return walk(e[1], exp) && walk(e[2], -exp);
563 }
564 if (op === 'Power') {
565 if (e.length !== 3) return false;
566 const n = e[2];
567 if (typeof n !== 'number') return false;
568 return walk(e[1], exp * n);
569 }
570 return false;
571 }
572
573 if (!walk(expr, 1)) return null;
574 return factors;
575}
576
577/**
578 * Cancel repeated unit factors that share a physical dimension.
579 *
580 * Zero-exponent entries are dropped. The remaining symbols are grouped by
581 * their dimension vector. For each group with MIXED-SIGN exponents (genuine
582 * cancellation potential, e.g. `m` and `in` with `+1`/`−1`), the member with
583 * the largest scale is chosen as the representative (same convention as
584 * `quantityAdd`); every other member `s` with exponent `e` folds into the
585 * representative (`magnitudeScale *= (scale_s / scale_rep) ** e`, and `e` is
586 * added to the representative's exponent). The representative itself is
587 * dropped if its summed exponent reaches 0. Groups whose exponents are all
588 * the same sign are left untouched (so `in·ft` area survives as written).
589 *
590 * Offsets (degC/degF) are intentionally ignored, consistent with
591 * `getExpressionScale`/`convertCompoundUnit` in compound contexts.

Callers 1

parseUnitDSLFunction · 0.85

Calls 3

parseUnitTokenFunction · 0.85
sliceMethod · 0.65
mapMethod · 0.65

Tested by

no test coverage detected