Files
ww/lib/types/types.ww
Hojun-Cho d9cfb91cb9 types: add INT/UINT limit constants, derived from size(int) (#114)
ww's int/uint are machine words (8B on amd64, type.c:58), not the 4B
Hare gives them on amd64 (arch+x86_64.ha maps INT_MAX->I32_MAX). So the
limits can't alias a per-arch literal; they DERIVE from size(int) the
Go way (cf math.MaxInt), staying correct on any word width:

  INT_MAX:  int  = (1 << (size(int)*8 - 1)) - 1
  INT_MIN:  int  = -1 << (size(int)*8 - 1)
  UINT_MIN: uint = 0
  UINT_MAX: uint = ~(0: uint)

All four const-fold in def-init; on amd64 they evaluate to I64_MAX,
I64_MIN, 0, U64_MAX. UINT_MAX uses the all-ones complement to dodge the
1<<64 overflow. Per the user ruling (2026-05-26): derived, not literal.

Probe 959_types_intlim_run asserts each value vs both the literal and
the i64/u64 limit const, plus wrap-through-i32 arithmetic usability.
combined.ww regenerated for all 5 selfhost tools + smoke (all embed
lib/types).
2026-05-26 08:31:41 +09:00

44 lines
1.3 KiB
Plaintext

// types — integer limits. Mirrors Hare's types::limits (I8_MAX, …)
// platform-fixed for amd64. Numeric helpers live in lib/math, matching
// Hare's split between types::limits and math::.
package types;
def I8_MAX: i8 = 127;
def I16_MAX: i16 = 32767;
def I32_MAX: i32 = 2147483647;
def I64_MAX: i64 = 9223372036854775807;
def I8_MIN: i8 = -128;
def I16_MIN: i16 = -32768;
def I32_MIN: i32 = -2147483648;
def I64_MIN: i64 = -9223372036854775808;
def U8_MAX: u8 = 255;
def U16_MAX: u16 = 65535;
def U32_MAX: u32 = 4294967295;
def U64_MAX: u64 = 18446744073709551615;
def U8_MIN: u8 = 0;
def U16_MIN: u16 = 0;
def U32_MIN: u32 = 0;
def U64_MIN: u64 = 0;
// int/uint are machine-word (Go-style, type.c:58); limits derived from
// size(int) per #114 + user ruling; cf Go math.MaxInt; diverges from
// Hare's per-arch literal (arch+x86_64.ha) because ww's int is 64-bit.
def INT_MAX: int = (1 << (size(int)*8 - 1)) - 1;
def INT_MIN: int = -1 << (size(int)*8 - 1);
def UINT_MIN: uint = 0;
def UINT_MAX: uint = ~(0: uint);
// size is 8B on amd64; no cast needed (size ∈ unsigned class per #113).
def SIZE_MIN: size = U64_MIN;
def SIZE_MAX: size = U64_MAX;
// uintptr not in the unsigned class, so the cast is required (Hare's form).
def UINTPTR_MIN: uintptr = U64_MIN: uintptr;
def UINTPTR_MAX: uintptr = U64_MAX: uintptr;
def RUNE_MIN: rune = '\0';