ReviewOS

zig-utils/zig-js

Intl.NumberFormat: generate locale range interval and compact-collapse patterns

#570
Closed chris opened this 9 days ago ·
9 days ago

Parent: #475 Follow-up to: #568

Problem

Intl.NumberFormat.prototype.formatRange() and formatRangeToParts() still use engine-wide separator and suffix-sharing heuristics. Locale interval syntax and compact-affix collapse are data-driven behaviors: JavaScriptCore uses 1.2M – 2.3M for English short compact, 1235万 ~ 2346万 for Japanese, 1235万 - 2346万 for Simplified Chinese, and 1235만 ~ 2346만 for Korean. The current engine can instead share an equal compact suffix and emit a generic en dash.

This is independent of the compact magnitude/plural patterns generated by #568. It affects both rendered text and the source attribution of formatRangeToParts().

Requirements

  • Generate the supported locales range separator/interval data from the repository-pinned CLDR revision.
  • Implement locale- and pattern-sensitive compact affix collapse/repetition for equal and unequal plural forms.
  • Keep text and parts on one structural path, preserving exact BigInt inputs, numbering-system digits, approximation behavior, and startRange/endRange/shared sources.
  • Store the generated tables as immutable engine data shared safely by realms and threads.
  • Cover short and long compact notation across English, German, French, Hindi, Japanese, Chinese, Korean, Russian, Arabic, and Hebrew.

Acceptance

  • Differential controls match JavaScriptCore for range text, part types/values, and sources across the supported locale matrix.
  • Focused normal, OOM, moving-GC, no-GIL, and TSan tests pass.
  • Relevant Intl402 range corpora and the full unit suite have no regressions.

Non-goals

  • No hand-written locale switch.
  • No system ICU/runtime locale dependency.
  • No copied expected-output fixture used as implementation data.
9 days ago

#569 now generates locale currency names and CLDR plural-range categories in b82dfbfb. That removed currency-name and range-plural confounders from the interval controls.

On the current main, the 4-job currency-name checksums exactly match JavaScriptCore for text (1,732,688), parts (1,653,952), and range text (1,733,504). Range parts remain 3,904,992 versus 4,298,272. Direct differential output now differs only in locale interval separators/source values: Spanish/Italian/Chinese -, Japanese ~, Korean ~, Romanian -, plus the compact-collapse cases already listed here.

This narrows #570 to generated interval syntax and affix-collapse/source attribution; currency plural selection is complete and should not be reimplemented in this issue.

9 days ago

42cb6a23 completed the numbering-system side of range formatting from #571. The dedicated range checksum moved from 673664 to 803968 against JSC 804096; text, parts, and resolved-state controls now match exactly. The remaining 128-point delta is therefore isolated to this issue's locale interval/collapse patterns.

9 days ago

Implemented and verified in cb3e8182 (fix(intl): generate NumberFormat range patterns (#570)).

The pinned generator now emits 910 immutable locale/system interval rows with raw/padded separators and exact approximation signs. formatRange() and formatRangeToParts() share one structural path for compact collapse/repetition and start/end/shared attribution.

Verification:

  • 24-case JSC oracle: exact text, part values/types, and sources
  • focused Intl.NumberFormat: 13/13 normally and under TSan
  • OOM, moving nursery, and no-GIL shared-formatter coverage: pass
  • NumberFormat: 249/249
  • Intl402: 3341/3341
  • full sharded units: 1652 pass, 1 skip, 0 fail, 0 leak
  • generator: byte-for-byte deterministic

At 4 jobs / 5 stable samples, compact range (1777984), compact range parts (4469520), currency-name range parts (4298272), and numbering-system range (804096) now match JSC exactly. No test262 regressions (0 flips).

Sign in to comment on this issue.