feat(types): Huge + Angle + Percent polish numeric types (#55)
All checks were successful
bootstrap / cfree-fixpoint (push) Successful in 19s
ci / build-and-test (push) Successful in 1m30s
commit-lint / conventional-commits (push) Successful in 6s
docs / build-and-deploy (push) Successful in 23s

Types phase 5 (polish). A splice-on-demand numeric runtime
(runtime/native/numeric.ludic, built on the inline Math.* trig) behind three
namespaces:

- Huge.* — idle big numbers (normalized mantissa x 10^exponent): from/add/
  sub/mul/neg/cmp/sign/mantissa/exp/str (scientific 1.23e45). Display-scale,
  not lockstep-exact (BigInt/Decimal for exactness).
- Angle.* — auto-wrapping radians: from_degrees/to_degrees/wrap/sin/cos/add/
  diff (shortest signed rotation)/lerp (shortest arc).
- Percent.* — clamped [0,1]: clamp/of/lerp/apply.

Remaining phase-5 items are already covered (duration=Duration.*,
rune=Unicode.*, i64=long) or need a type-checking pass (handle, typed name,
other sized ints) — tracked for later.

Wired: parser splice trigger (g_uses_numeric), emit_call dispatch, reseeded
seed, a self-asserting example (examples/library/numeric.ludic + feat_case),
per-symbol docs + inventory. All suites green incl. golden renders byte-
identical and the bootstrap fixpoint.

NOTE: fixed `const`s lower to raw-int-typed values (emit_call N_CONST), which
breaks fixed comparisons — the runtime uses inline fixed literals instead.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Orkun ÇAKILKAYA 2026-08-31 19:04:37 +03:00
parent 539f258d92
commit 5dc8394f22
33 changed files with 23162 additions and 21092 deletions

View file

@ -0,0 +1,7 @@
---
id: huge
title: Huge
order: 14
---
Idle/incremental big numbers — magnitudes far past what a 32- or 64-bit integer can hold, for prestige currencies and exponential growth. A <code>Huge</code> is a normalized mantissa (a Q16.16 <code>fixed</code> in [1, 10)) times <code>10^exponent</code>, so it can represent 10^100 or 10^1000 while staying one small value. It is a <strong>display-scale</strong> number (about four significant digits), <em>not</em> a lockstep-exact one — keep it out of the deterministic simulation and reach for <code>BigInt</code> / <code>Decimal</code> when exactness matters. Build one with <code>Huge.from</code>, combine with <code>add</code> / <code>sub</code> / <code>mul</code> / <code>neg</code>, compare with <code>cmp</code> / <code>sign</code>, read <code>mantissa</code> / <code>exp</code>, and render as <code>1.23e45</code> with <code>str</code>. Arguments are positional. Spliced in only when a program mentions <code>Huge.*</code>.

View file

@ -0,0 +1,22 @@
---
id: huge-add
name: Huge.add
category: huge
kind: namespace-method
tokens: Huge.add
sig: Huge.add(a, b) -> Huge
tip: Sum of two big numbers.
order: 1
ns: Huge
member: add
---
Adds two big numbers, aligning their exponents; a term too small to matter at display precision is dropped.
```ludic
program Demo {
handler Step phase Update {
gold = Huge.add(gold, income)
}
}
```

View file

@ -0,0 +1,22 @@
---
id: huge-cmp
name: Huge.cmp
category: huge
kind: namespace-method
tokens: Huge.cmp
sig: Huge.cmp(a, b) -> int
tip: Compare two big numbers: -1, 0, or 1.
order: 5
ns: Huge
member: cmp
---
Compares two big numbers, returning <code>-1</code>, <code>0</code>, or <code>1</code> as <code>a</code> is less than, equal to, or greater than <code>b</code>.
```ludic
program Demo {
handler Step phase Update {
if Huge.cmp(gold, price) >= 0 { buy() }
}
}
```

View file

@ -0,0 +1,22 @@
---
id: huge-exp
name: Huge.exp
category: huge
kind: namespace-method
tokens: Huge.exp
sig: Huge.exp(a) -> int
tip: The base-10 exponent.
order: 8
ns: Huge
member: exp
---
Returns the base-10 exponent — how many orders of magnitude the value spans.
```ludic
program Demo {
handler Step phase Update {
let order = Huge.exp(gold)
}
}
```

View file

@ -0,0 +1,22 @@
---
id: huge-from
name: Huge.from
category: huge
kind: namespace-method
tokens: Huge.from
sig: Huge.from(value) -> Huge
tip: Turn an int into a Huge.
order: 0
ns: Huge
member: from
---
Lifts a plain <code>int</code> into a <code>Huge</code>, the starting point for idle-game magnitudes that grow past the integer range.
```ludic
program Demo {
handler Step phase Update {
var gold = Huge.from(1000)
}
}
```

View file

@ -0,0 +1,22 @@
---
id: huge-mantissa
name: Huge.mantissa
category: huge
kind: namespace-method
tokens: Huge.mantissa
sig: Huge.mantissa(a) -> fixed
tip: The mantissa in [1, 10).
order: 7
ns: Huge
member: mantissa
---
Returns the normalized mantissa, a <code>fixed</code> in [1, 10) (or 0). Pair it with <code>Huge.exp</code> to format a value your own way.
```ludic
program Demo {
handler Step phase Update {
let m = Huge.mantissa(gold)
}
}
```

View file

@ -0,0 +1,22 @@
---
id: huge-mul
name: Huge.mul
category: huge
kind: namespace-method
tokens: Huge.mul
sig: Huge.mul(a, b) -> Huge
tip: Product of two big numbers.
order: 3
ns: Huge
member: mul
---
Multiplies two big numbers (mantissas multiply, exponents add) — the exponential growth step at the heart of an idle game.
```ludic
program Demo {
handler Step phase Update {
gold = Huge.mul(gold, multiplier)
}
}
```

View file

@ -0,0 +1,22 @@
---
id: huge-neg
name: Huge.neg
category: huge
kind: namespace-method
tokens: Huge.neg
sig: Huge.neg(a) -> Huge
tip: Negate a big number.
order: 4
ns: Huge
member: neg
---
Returns <code>-a</code>, the same magnitude with the opposite sign.
```ludic
program Demo {
handler Step phase Update {
let owed = Huge.neg(balance)
}
}
```

View file

@ -0,0 +1,22 @@
---
id: huge-sign
name: Huge.sign
category: huge
kind: namespace-method
tokens: Huge.sign
sig: Huge.sign(a) -> int
tip: The sign: -1, 0, or 1.
order: 6
ns: Huge
member: sign
---
Returns the sign of the value: <code>-1</code>, <code>0</code>, or <code>1</code>.
```ludic
program Demo {
handler Step phase Update {
if Huge.sign(balance) < 0 { warn() }
}
}
```

View file

@ -0,0 +1,22 @@
---
id: huge-str
name: Huge.str
category: huge
kind: namespace-method
tokens: Huge.str
sig: Huge.str(a) -> string
tip: Render as scientific text like 1.23e45.
order: 9
ns: Huge
member: str
---
Renders the value in scientific form, like <code>1.23e45</code> (a two-decimal mantissa). This is how you show an idle magnitude on the HUD.
```ludic
program Demo {
handler Step phase Update {
Screen.draw_text(8, 8, Huge.str(gold), Color.White, 1)
}
}
```

View file

@ -0,0 +1,22 @@
---
id: huge-sub
name: Huge.sub
category: huge
kind: namespace-method
tokens: Huge.sub
sig: Huge.sub(a, b) -> Huge
tip: Difference of two big numbers.
order: 2
ns: Huge
member: sub
---
Subtracts <code>b</code> from <code>a</code>.
```ludic
program Demo {
handler Step phase Update {
gold = Huge.sub(gold, cost)
}
}
```