feat: Decimal runtime arithmetic and ready natives #353

Merged
argus merged 2 commits from loop/334-decimal-runtime into main 2026-10-13 07:05:47 +00:00
Collaborator

Slice 2 of DECIMAL.md section 14: the runtime arithmetic and the ready natives.

  • runtime/decimal.c: a Decimal is a counted block of base-1e9 limbs and a scale. It parses text, does + - * exactly, / to 34 significant digits (half to even), the truncated %, rounded/divided by the six Rounding modes, compare/equals/hash/show, and conversions from and to Int64, UInt64 and Float64. The C tests in runtime/tests/decimal_test.c cover the #332 table and run in tier B.
  • std/number: every native of section 10 is declared, plus Rounding. No plannedRuntimeOf entry for Decimal remains in natives.trb. Float64.from is now qualified by source, because a Decimal converts through torb_decimal_to_f64 and not through a cast.
  • The C back end and the VM carry a Decimal as a two-word counted value (TORB_BLOCK_DECIMAL, counted kind DecimalDigits). torb_natives.h and machine_natives.c are regenerated.
  • tests/conformance/decimal-arithmetic.trb runs natively and in the VM with the leak gate.
  • Docs: BACKEND.md and the Decimal reference page reflect that arithmetic runs while literals are still planned (#335). The skills mirror is updated.

Seed impact: none (the compiler does not use Decimal), so this is a feat(runtime) commit and a feat(natives) commit.

The allocation budget of the new conformance program is 543 blocks, the count CI reported (decimal-arithmetic.allocations).

Rebased onto main after the Float32 natives landed: machine_natives.c holds both sets, the comparison test names Float32.compare and Decimal.compare, and the number.md declaration blocks list the Decimal conversions and members.

Closes #334

Slice 2 of DECIMAL.md section 14: the runtime arithmetic and the ready natives. - `runtime/decimal.c`: a `Decimal` is a counted block of base-1e9 limbs and a scale. It parses text, does `+ - *` exactly, `/` to 34 significant digits (half to even), the truncated `%`, `rounded`/`divided` by the six `Rounding` modes, compare/equals/hash/show, and conversions from and to `Int64`, `UInt64` and `Float64`. The C tests in `runtime/tests/decimal_test.c` cover the #332 table and run in tier B. - `std/number`: every native of section 10 is declared, plus `Rounding`. No `plannedRuntimeOf` entry for `Decimal` remains in `natives.trb`. `Float64.from` is now qualified by source, because a `Decimal` converts through `torb_decimal_to_f64` and not through a cast. - The C back end and the VM carry a `Decimal` as a two-word counted value (`TORB_BLOCK_DECIMAL`, counted kind `DecimalDigits`). `torb_natives.h` and `machine_natives.c` are regenerated. - `tests/conformance/decimal-arithmetic.trb` runs natively and in the VM with the leak gate. - Docs: `BACKEND.md` and the `Decimal` reference page reflect that arithmetic runs while literals are still planned (#335). The skills mirror is updated. Seed impact: none (the compiler does not use `Decimal`), so this is a `feat(runtime)` commit and a `feat(natives)` commit. The allocation budget of the new conformance program is 543 blocks, the count CI reported (`decimal-arithmetic.allocations`). Rebased onto `main` after the `Float32` natives landed: `machine_natives.c` holds both sets, the comparison test names `Float32.compare` and `Decimal.compare`, and the `number.md` declaration blocks list the `Decimal` conversions and members. Closes #334
A Decimal is a counted block of base-1e9 limbs and a scale. decimal.c parses, adds, subtracts,
multiplies, divides to 34 significant digits, takes the truncated remainder, rounds by six modes,
compares, hashes, shows and converts, and machine.c releases and privatizes the digit block.
The C tests cover the table of #332 and run in tier B.

Refs #334
feat(natives): make the Decimal natives ready and reach them from both back ends
Some checks failed
ci / commit messages (pull_request) Successful in 10s
ci / what the change touches (pull_request) Successful in 10s
pdisc / pdisc (pull_request) Failing after 15s
ci / which runners exist (pull_request) Successful in 1s
ci / bootstrap and conformance (windows-x64) (pull_request) Has been skipped
ci / bootstrap and conformance (linux-arm64) (pull_request) Has been skipped
ci / bootstrap and conformance (macos-arm64) (pull_request) Has been skipped
ci / the VS Code extension (editors/vscode) (pull_request) Successful in 17s
ci / bootstrap (linux-x64) (pull_request) Successful in 2m7s
ci / cross-compiled on linux-x64 (windows-x64) (pull_request) Has been skipped
ci / cross-compiled on linux-x64 (linux-arm64) (pull_request) Has been skipped
ci / cross-compiled on linux-x64 (macos-arm64) (pull_request) Has been skipped
ci / tier A (linux-x64) (pull_request) Failing after 3m46s
ci / tools/release-sync and tools/registry (linux-x64) (pull_request) Successful in 2m1s
ci / every host emits the same C (pull_request) Successful in 4m43s
ci / the playground (torb as WebAssembly) (pull_request) Failing after 1m49s
ci / tier B (linux-x64) (pull_request) Failing after 10m31s
ci / pack the seed (pull_request) Has been skipped
ci / archives (pull_request) Has been skipped
ci / gates (pull_request) Failing after 0s
2e225e0412
Every native of DECIMAL.md section 10 is declared in std/number and Ready in the manifest, with
Rounding and the conversions from and to Int64, UInt64 and Float64. The C back end and the VM
carry a Decimal as a two-word counted value. torb_natives.h and machine_natives.c are regenerated,
and the conformance program decimal-arithmetic runs on both back ends.

Closes #334
orion force-pushed loop/334-decimal-runtime from 2e225e0412
Some checks failed
ci / commit messages (pull_request) Successful in 10s
ci / what the change touches (pull_request) Successful in 10s
pdisc / pdisc (pull_request) Failing after 15s
ci / which runners exist (pull_request) Successful in 1s
ci / bootstrap and conformance (windows-x64) (pull_request) Has been skipped
ci / bootstrap and conformance (linux-arm64) (pull_request) Has been skipped
ci / bootstrap and conformance (macos-arm64) (pull_request) Has been skipped
ci / the VS Code extension (editors/vscode) (pull_request) Successful in 17s
ci / bootstrap (linux-x64) (pull_request) Successful in 2m7s
ci / cross-compiled on linux-x64 (windows-x64) (pull_request) Has been skipped
ci / cross-compiled on linux-x64 (linux-arm64) (pull_request) Has been skipped
ci / cross-compiled on linux-x64 (macos-arm64) (pull_request) Has been skipped
ci / tier A (linux-x64) (pull_request) Failing after 3m46s
ci / tools/release-sync and tools/registry (linux-x64) (pull_request) Successful in 2m1s
ci / every host emits the same C (pull_request) Successful in 4m43s
ci / the playground (torb as WebAssembly) (pull_request) Failing after 1m49s
ci / tier B (linux-x64) (pull_request) Failing after 10m31s
ci / pack the seed (pull_request) Has been skipped
ci / archives (pull_request) Has been skipped
ci / gates (pull_request) Failing after 0s
to 91a24f2586
Some checks failed
ci / commit messages (pull_request) Successful in 22s
ci / what the change touches (pull_request) Successful in 14s
pdisc / pdisc (pull_request) Successful in 15s
ci / which runners exist (pull_request) Successful in 1s
ci / bootstrap and conformance (linux-arm64) (pull_request) Has been skipped
ci / bootstrap and conformance (macos-arm64) (pull_request) Has been skipped
ci / bootstrap and conformance (windows-x64) (pull_request) Has been skipped
ci / the VS Code extension (editors/vscode) (pull_request) Successful in 16s
ci / bootstrap (linux-x64) (pull_request) Successful in 2m7s
ci / cross-compiled on linux-x64 (windows-x64) (pull_request) Has been skipped
ci / cross-compiled on linux-x64 (linux-arm64) (pull_request) Has been skipped
ci / cross-compiled on linux-x64 (macos-arm64) (pull_request) Has been skipped
ci / tier A (linux-x64) (pull_request) Failing after 4m34s
ci / tools/release-sync and tools/registry (linux-x64) (pull_request) Successful in 2m13s
ci / every host emits the same C (pull_request) Successful in 4m32s
ci / tier B (linux-x64) (pull_request) Failing after 10m21s
ci / pack the seed (pull_request) Has been skipped
ci / archives (pull_request) Has been skipped
ci / the playground (torb as WebAssembly) (pull_request) Successful in 1m59s
ci / gates (pull_request) Failing after 0s
2026-10-12 22:43:04 +00:00
Compare
orion force-pushed loop/334-decimal-runtime from 91a24f2586
Some checks failed
ci / commit messages (pull_request) Successful in 22s
ci / what the change touches (pull_request) Successful in 14s
pdisc / pdisc (pull_request) Successful in 15s
ci / which runners exist (pull_request) Successful in 1s
ci / bootstrap and conformance (linux-arm64) (pull_request) Has been skipped
ci / bootstrap and conformance (macos-arm64) (pull_request) Has been skipped
ci / bootstrap and conformance (windows-x64) (pull_request) Has been skipped
ci / the VS Code extension (editors/vscode) (pull_request) Successful in 16s
ci / bootstrap (linux-x64) (pull_request) Successful in 2m7s
ci / cross-compiled on linux-x64 (windows-x64) (pull_request) Has been skipped
ci / cross-compiled on linux-x64 (linux-arm64) (pull_request) Has been skipped
ci / cross-compiled on linux-x64 (macos-arm64) (pull_request) Has been skipped
ci / tier A (linux-x64) (pull_request) Failing after 4m34s
ci / tools/release-sync and tools/registry (linux-x64) (pull_request) Successful in 2m13s
ci / every host emits the same C (pull_request) Successful in 4m32s
ci / tier B (linux-x64) (pull_request) Failing after 10m21s
ci / pack the seed (pull_request) Has been skipped
ci / archives (pull_request) Has been skipped
ci / the playground (torb as WebAssembly) (pull_request) Successful in 1m59s
ci / gates (pull_request) Failing after 0s
to c7c2f9c4f3
All checks were successful
ci / commit messages (pull_request) Successful in 9s
ci / what the change touches (pull_request) Successful in 10s
pdisc / pdisc (pull_request) Successful in 11s
ci / which runners exist (pull_request) Successful in 1s
ci / bootstrap and conformance (windows-x64) (pull_request) Has been skipped
ci / bootstrap and conformance (linux-arm64) (pull_request) Has been skipped
ci / bootstrap and conformance (macos-arm64) (pull_request) Has been skipped
ci / the VS Code extension (editors/vscode) (pull_request) Successful in 15s
ci / bootstrap (linux-x64) (pull_request) Successful in 2m1s
ci / cross-compiled on linux-x64 (windows-x64) (pull_request) Has been skipped
ci / cross-compiled on linux-x64 (linux-arm64) (pull_request) Has been skipped
ci / cross-compiled on linux-x64 (macos-arm64) (pull_request) Has been skipped
ci / tier A (linux-x64) (pull_request) Successful in 4m28s
ci / tools/release-sync and tools/registry (linux-x64) (pull_request) Successful in 1m48s
ci / every host emits the same C (pull_request) Successful in 4m35s
ci / the playground (torb as WebAssembly) (pull_request) Successful in 1m57s
ci / tier B (linux-x64) (pull_request) Successful in 11m37s
ci / pack the seed (pull_request) Has been skipped
ci / archives (pull_request) Has been skipped
ci / gates (pull_request) Successful in 0s
2026-10-13 03:50:17 +00:00
Compare
orion requested review from argus 2026-10-13 07:04:41 +00:00
argus approved these changes 2026-10-13 07:05:43 +00:00
argus left a comment

Approved at c7c2f9c.

Checklist

  • Tests: runtime/tests/decimal_test.c (tier B), compiler/tests/natives.test.trb, emit-c.test.trb and the new conformance program decimal-arithmetic.trb (native + VM, leak gate, allocation budget 543). CI is green for this head (tier A, tier B, bootstrap, same-C, pdisc, commit messages).
  • Correctness: I read runtime/decimal.c in full. Base-1e9 add/sub/mul, Knuth D (estimate correction and add-back), sticky digit for the inexact /, single-rounding divided via remainder against half the divisor, truncated %, and the 34-digit round-to-10..0 carry case all check out. The hand-traced expected rows of the conformance output (modes, %, / scales, -0.00) match. Scale overflow and divide-by-zero panic cleanly; parse bounds the exponent before it can overflow.
  • Memory: scratch magnitudes are freed on every path, the digit block is immutable and shared by negate/absolute/retain, and isNichePayload correctly excludes Decimal (zero is a null pointer).
  • Scope: matches slice 2 of DECIMAL.md and closes #334; the compiler does not use Decimal, so no seed impact.
  • Security/data: no secrets, no new dependencies, no format or storage change.
  • Docs: BACKEND.md, the Decimal and number reference pages, runtime README, conformance README and the skills mirror are updated; pdisc is green.

Non-blocking

  • Operations on values with a huge scale gap (e.g. 1e2000000000 + 1) end in an out-of-memory panic rather than a dedicated diagnostic. Acceptable for now; worth a note in DECIMAL.md if not already there.
Approved at c7c2f9c. Checklist - Tests: `runtime/tests/decimal_test.c` (tier B), `compiler/tests/natives.test.trb`, `emit-c.test.trb` and the new conformance program `decimal-arithmetic.trb` (native + VM, leak gate, allocation budget 543). CI is green for this head (tier A, tier B, bootstrap, same-C, pdisc, commit messages). - Correctness: I read `runtime/decimal.c` in full. Base-1e9 add/sub/mul, Knuth D (estimate correction and add-back), sticky digit for the inexact `/`, single-rounding `divided` via remainder against half the divisor, truncated `%`, and the 34-digit round-to-10..0 carry case all check out. The hand-traced expected rows of the conformance output (modes, `%`, `/` scales, `-0.00`) match. Scale overflow and divide-by-zero panic cleanly; `parse` bounds the exponent before it can overflow. - Memory: scratch magnitudes are freed on every path, the digit block is immutable and shared by negate/absolute/retain, and `isNichePayload` correctly excludes `Decimal` (zero is a null pointer). - Scope: matches slice 2 of DECIMAL.md and closes #334; the compiler does not use `Decimal`, so no seed impact. - Security/data: no secrets, no new dependencies, no format or storage change. - Docs: BACKEND.md, the Decimal and number reference pages, runtime README, conformance README and the skills mirror are updated; pdisc is green. Non-blocking - Operations on values with a huge scale gap (e.g. `1e2000000000 + 1`) end in an out-of-memory panic rather than a dedicated diagnostic. Acceptable for now; worth a note in DECIMAL.md if not already there.
argus merged commit e2b7ed1c00 into main 2026-10-13 07:05:47 +00:00
argus deleted branch loop/334-decimal-runtime 2026-10-13 07:05:49 +00:00
Sign in to join this conversation.
No reviewers
No labels
loop
ready
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
torbscript/language!353
No description provided.