Skip to content

feat(data/json): float support in number parsing#355

Merged
octalide merged 2 commits into
devfrom
feat/349
Jul 3, 2026
Merged

feat(data/json): float support in number parsing#355
octalide merged 2 commits into
devfrom
feat/349

Conversation

@octalide

@octalide octalide commented Jul 3, 2026

Copy link
Copy Markdown
Collaborator

Closes #349.

Problem

std.data.json parsed integer numbers only. Downstream mach-gltf needs full
JSON numeric support (node transforms, accessor bounds, keyframes, material
factors are all floats), so the loader cannot progress past structural parsing
until floats land here.

Change

  • Number parsing now accepts the full RFC 8259 grammar (int frac? exp?). A
    number carrying a fraction or exponent becomes a float; an integer-looking
    number keeps yielding an i64, byte-for-byte the same path and error messages
    as before.
  • Float values are parsed with correct rounding by reusing
    std.text.parse's bignum decimal→f64 machinery over the zero-copy source
    span
    — no allocation, no copy.
  • Value gains is_float + float_val. New accessors:
    • value_is_float(v) bool — whether the number was parsed as a float.
    • value_float(v) f64 — the float value, or an integer widened to f64, so it
      is defined for any NUMBER.
    • value_number(v) i64 unchanged; documented as the integer-number accessor.
  • emit writes floats in shortest round-trippable form (fmt.write_f64).

Enabling change (std.text.parse)

parse_f64 derives its length via str_len, assuming null termination — unsafe
on a span embedded in a larger buffer, which is exactly the zero-copy JSON case.
Factored the body into parse_f64_len(s, len) (bounded by an explicit length);
parse_f64 now delegates. No behaviour change for existing callers.

Tests

json (+14): float with fraction / exponent / signed & uppercase exponent /
negative, integer-stays-integer, mixed int+float array, float in object,
malformed rejection (1., 1e, 1.5e), emit exact bytes, built-float emit,
and parse→emit→parse round-trip. parse (+2): parse_f64_len bounded span (does
not read past len) and zero length. Full suite: 620 passed / 0 failed
(std.data.json 52→66). riscv64 cross smoke test green.

octalide added 2 commits July 3, 2026 01:36
parse_f64 assumes a null terminator (it derives length via str_len), which is
unsafe on a byte span embedded in a larger buffer -- the exact case a zero-copy
parser faces. Factor the body into parse_f64_len(s, len), bounded by an explicit
length, and have parse_f64 delegate with str_len(s). No behaviour change for
existing callers.
Extend number parsing to the full RFC 8259 grammar (fraction + exponent). A
number with a fraction or exponent yields a float value, parsed with correct
rounding via parse_f64_len over the zero-copy source span; integer-looking
numbers keep yielding an i64 exactly as before. Value gains is_float/float_val,
with value_is_float and value_float accessors (value_float widens integers so it
is defined for any NUMBER); emit writes floats in shortest round-trippable form.

Closes #349.
@octalide octalide marked this pull request as ready for review July 3, 2026 05:37
@octalide octalide merged commit a85fabc into dev Jul 3, 2026
3 checks passed
@octalide octalide deleted the feat/349 branch July 3, 2026 05:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(data): float support in std.data.json number parsing

1 participant