Skip to content

ir: one decimal-literal grammar for BigVal, bound comparison and YAML integers #786

Closed

Description

@OmarAlJarrah

Problem

The grammar of a decimal numeric literal is scanned in three places, and the comments in two of them say they have drifted before.

  • ir/bigval.go: isDecimalLiteral, scanMantissa, scanExponent and canonicalDecimal validate and canonicalize for NewBigVal.
  • compilers/openapi/internal/annotation/decimal.go: parseDecimalBound splits sign, digits and exponent a second time for BigValEqual. Its doc says "the two grammars live in different packages and have already moved apart once", and TestBigValGrammarStaysWithinTheDecimalReading exists to hold them together.
  • compilers/openapi/internal/value/value.go: isPlainDecimal decides which !!int spellings are already base 10.

ir/irverify/bigval.go re-checks through NewBigVal, so it is not a fourth copy.

A grammar with one definition and derived predicates cannot disagree with itself; a grammar scanned three times needs a test that it still agrees.

Constraints

  • ir imports the standard library only, so the shared piece lives in ir and is stdlib-only. That also rules out a decimal library for the grammar itself.
  • Comparison must stay total for exponents math/big will not build: 1e1000001 is legal in a spec, and openapi/merge: equal bounds past big.Rat's range are reported as a conflict #287 was a conflict reported for equal bounds past big.Rat's range. The comparison reads sign, digits and exponent; it never materializes 10^exp.
  • NewBigVal keeps preserving every significant digit and the exponent's text; only JSON-invalid affixes are normalized.

Proposed direction

ir exposes one parse of a validated literal into its sign, significant digits and decimal exponent. NewBigVal's canonical form, an ordering (Cmp or equivalent) and the equality BigValEqual needs all derive from it. annotation/decimal.go keeps no scanner. isPlainDecimal either uses the same parse or states why a YAML base prefix makes it a different question.

Acceptance

  • One scanner remains in the repository; grep -rn 'scanMantissa\|parseDecimalBound' --include='*.go' . finds one definition.
  • A fuzz test compares the ordering against big.Rat over inputs whose exponents big.Rat can build, and against sign/exponent reasoning beyond them.
  • 1e1000001, 10e1000000, -0.0, 5e1 and 50 keep their current equalities.
  • Exported ir additions are additive; no existing signature changes.

Metadata

Metadata

Assignees

No one assigned

    Labels

    priority:P4Refactors, tests, CI, hostile-input hardening, cosmetic diagnostics, other formatstype:choreRefactor or cleanup, no behavior change

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions