Portable exact numeric text conversion
Date: 2026-07-19
Area: engine
The floating-point text routines exposed by GocciaScript's supported Pascal compilers do not provide one portable ECMAScript contract. FPC's Str is not correctly rounded at every precision, Delphi's decimal rendering differs across targets, and TryStrToFloat does not reliably give the same binary64 result at all rounding boundaries. Locale-neutral format settings solve only the decimal-separator problem; they do not establish ECMA-262 rounding or shortest-representation semantics. The engine nevertheless needs one result for source numeric literals, StringToNumber, Number.parseFloat, JSON and other structured-data parsers, property-key coercion, and JSON serialization.
Decision: NumericText owns the compiler-independent conversion between exact decimal text and binary64. Decimal parsing constructs the exact rational value with TBigInteger and rounds once to IEEE 754 binary64 using round-to-nearest, ties-to-even, including signed zero, subnormal/normal boundaries, and overflow. Number formatting uses a direct Pascal port of Ulf Adams' Ryū binary64 shortest-conversion core, pinned to upstream commit 4c0618b0e44f7ef027ebae05d2cc7812048f7c8f and retained under the Boost Software License 1.0 in the source. NumericText applies the fixed-versus-scientific layout required by ES2026 §6.1.6.1.20 Number::toString; callers with narrower syntactic grammars continue to validate those grammars before delegating the exact decimal value conversion. ECMA-402 Intl formatting and human-facing presentation formats remain separate concerns and may use their own locale-aware or explicitly invariant formatting paths.
ECMAScript semantic paths do not use Str, Val, FloatToStr, StrToFloat, FormatFloat, or TryStrToFloat for decimal/binary64 conversion. This decision supersedes ADR 0080's first-hit Str/Val precision scan as the implementation of FormatDouble; ADR 0080 remains the record of why probe-skipping the former FPC implementation was invalid. The normative reference is ECMA-262 ES2026 snapshot 0248456c758431e4bb8e5d26333ff1865123c9cd: §6.1.6.1.20 requires the shortest round-tripping decimal for radix 10, and §§7.1.4.1.1–7.1.4.1.2 require StringToNumber and RoundMVResult. Validation covers bit-level boundary vectors, interpreter and bytecode behavior, supported compiler targets, and differential corpora against Node/V8 for both formatting and parsing.