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).
This commit is contained in:
@@ -24,6 +24,14 @@ 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;
|
||||
|
||||
Reference in New Issue
Block a user