feat(calc): evaluate mixed unit expressions - #6
Merged
Conversation
Users type light math into quantity fields and models emit expressions
they cannot reliably compute. @pascal-app/lingo/calc is a closed
calculator over already-parsed values — no variables, functions, or
dimensional algebra — so 7m*2 is 14 million, 9min x 4 is 36 min, and
half of 56kg+1700g is 28.85 kg.
lingo() stays range-first: 5-10 kg is still a range, 2 ft + 3 in is
still a compound. 2+3 kg was a silent CJK-adjacent-range false
positive and now fails with TRAILING_INPUT; calc('2+3 kg') is 5 kg.
Completions and quantityField inject calc with trigger '=' so mixed
fields do not steal dashes.
Glued m at an operator boundary is million unless kind is length or
duration (SCALE_ASSUMED); spaced 7 m is meters; 1m80 stays 1.80 m.
Results format as words, grouped, scientific, or compact. expression
is two-way infix; latex is display-only. Additive affine compounds
warn AFFINE_DELTA_ASSUMED and still delta-convert.
Budgets recalibrated in D73: the calculator is ~4 kB marginal / ~35 kB
standalone. Full and core grow because the CJK gate, affine warning,
and calc-scale matching must run inside parseQty before unit matching.
Co-authored-by: Aymeric Rabot <Aymericr@users.noreply.github.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
|
React Doctor found no new issues. 🎉 Reviewed by React Doctor for commit |
1700 g was typeset as 1.7 × 10^3 because latex reused the compact scientific threshold meant for million-scale numbers. Docs import for the Calculations snippet and regenerated schema artifacts (five new issue codes) land in the same change so check stays green. Co-authored-by: Aymeric Rabot <Aymericr@users.noreply.github.com>
Adversarial pass: quantityField missed division, compact/latex dropped tight symbols, snapshot restore turned 1e999 into NO_VALUE, and SCALAR_EXPECTED claimed 10 / 2 kg was two quantities. Co-authored-by: Aymeric Rabot <Aymericr@users.noreply.github.com>
Keep unit/latex and operator-slash behavior; drop the extra gzip that tipped ./calc, ./ai, and quantityField-only over their D73 lines. Co-authored-by: Aymeric Rabot <Aymericr@users.noreply.github.com>
Reuse the number parser's issue instead of emitting a second copy. Co-authored-by: Aymeric Rabot <Aymericr@users.noreply.github.com>
…nless Cross-currency +/−/÷ reported RATE_REQUIRED instead of adding factors of 1 or relabeling the conversion throw as NONFINITE. Same-kind q/q stays a number even when kind/unit are implied, and quantityField does not stuff that ratio into the field unit. Co-authored-by: Aymeric Rabot <Aymericr@users.noreply.github.com>
Inline the cross-currency guard and drop the implied-unit ratio skip that tipped ./calc over 4.1 kB. Park the canceled q/q re-unit holdover in the backlog. Co-authored-by: Aymeric Rabot <Aymericr@users.noreply.github.com>
p.reg.kind() takes Kind, not Kind | null; require left.kind so the cross-currency guard typechecks. Co-authored-by: Aymeric Rabot <Aymericr@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Plan 032 go, recorded as D73.
@pascal-app/lingo/calcevaluates closed arithmetic over quantities and numbers — inspired by mathjs expression trees, without scopes, functions, or dimensional algebra.calc('7m*2')→ 14 million (SCALE_ASSUMED); format as"14 million"/"14,000,000"/"14e6"/"14m"calc('9min x 4')→ 36 min, or 0.6 hcalc('half of 56kg+1700g')→ 28.85 kglingo()stays range-first.5-10 kgis still a range.2+3 kgwas a silent CJK-adjacent-range false positive and now fails withTRAILING_INPUT;calc('2+3 kg')is 5 kg.Completions still require a leading
=so mixed fields do not steal dashes.quantityField({ calc })useslooksLikeCalc(never-; glued5/10 kgstays a fraction) and then evaluates, so12 * 0.75 kgand10 kg / 2work unprefixed.Always-ship parser fixes: CJK adjacent-range gated on
adjacentRange; additive affine compounds warnAFFINE_DELTA_ASSUMEDand still delta-convert.Quality pass after adversarial review:
25°C,10%,$5) instead of dropping them.calc('1e999')reports a singleNONFINITEinstead of masking it asNO_VALUE.SCALAR_EXPECTEDcopy is honest forn / q, not onlyq * q.RATE_REQUIRED(same guard as ranges), not$15at full confidence or a maskedNONFINITE. The evaltry/catchthat relabeled conversion throws is gone../calcmarginal 4.10 / 4.1).bun run check: 1068 passed, 1 skipped.Holdover (parked in
plans/backlog.md):calc('10 L / 2 L', { kind: 'mass', unit: 'kg' })still re-attaches the implied unit. Aratioflag to skip that busts the 4.1 kB budget.Checklist
Gates
bun run checkgreen (typecheck, tests, build, size budgets, corpus gate, zero-deps gate)bun run lintgreen (Biome via Ultracite; rule mismatches go in biome.jsonc with a reason, never inline)2+3 kgis not an English corpus row; D73 records the interpretation changeAPI surface (public exports touched)
./calcentry (additive).2+3 kgpreviously returned a range at full confidence (bug fix / interpretation change, not in corpus). Affine warning is additive. Next 0.x release can take this as a minor with a Changed note.wiki/api-design.mdchecklist run@exampleon every new public symbolKnowledge layer
RATE_REQUIREDfor rate-based mixed units[Unreleased]wiki/inspiration.md(shipped as./calc)