feat(lang): integer numeric-limit accessors (s64.max, u8.min, s3.max) [NL.1]

A field-like access on a builtin INTEGER type name folds to a compile-time
constant of the queried type, driven by (width, signedness) arithmetic:
  sN: min=-(2^(N-1)), max=2^(N-1)-1;  uN: min=0, max=2^N-1
for every width s1..s64 / u1..u64 (not just power-of-two), plus usize/isize.

- type_resolver.zig: extract the single width parser (parseWidthInt) reused by
  resolveNamed AND the new accessors (no second parser — issue-0083 class);
  add resolveBuiltinName / integerWidthSign / integerLimitBits / integerLimitFor.
- lower.zig: lowerNumericLimit intercept beside the error.X / Struct.CONST /
  pack-arity identifier-receiver intercepts; folds ints via constInt, emits a
  clean diagnostic for a non-numeric receiver (bool/string/void/Any/noreturn),
  falls through for floats (NL.2).
- expr_typer.zig: mirror the result type so inferExprType reports the queried type.
- program_index.zig: recognize the accessors in the comptime-int / array-dim path
  so [u8.max]T (255) / [s16.max]T (32767) work; [u64.max]T is rejected oversized.
- u64.max / usize.max stored as the all-ones bit pattern with TYPE u64 (i64 -1),
  asserted via union { u: u64; s: s64 } reinterpret.

Docs: specs.md numeric-limits subsection (formulas + result-type + u64 note);
readme.md language overview. Examples 0148 (positive) / 0149 (negative-receiver).
Unit tests for the value computation in type_resolver.test.zig.

Gate: zig build, zig build test (359/359), tests/run_examples.sh (416 ok, 0 failed).
This commit is contained in:
agra
2026-06-04 16:14:06 +03:00
parent bc9777d81f
commit 04f46ef384
15 changed files with 384 additions and 14 deletions

View File

@@ -117,6 +117,43 @@ GLSL;
- `Any` — type-erased value, represented as `{ i64, i64 }` (type tag + payload). Used for variadic arguments and runtime type dispatch.
- `Type` — compile-time type value. At runtime, represented as an `i64` type tag (same tag space as `Any`).
### Numeric Limits
A field-like access on a builtin **integer** type name folds, at compile time, to
that type's smallest/largest representable value:
```sx
maxS64 := s64.max; // 9223372036854775807
minS32 := s32.min; // -2147483648
maxU8 := u8.max; // 255
minU8 := u8.min; // 0
m3 := s3.max; // 3 (arbitrary width)
n := u64.max; // 18446744073709551615 (all-ones)
```
- **Receiver.** Any builtin integer type: every signed width `s1`..`s64`, every
unsigned width `u1`..`u64` (arbitrary 164 bit widths, not only the
power-of-two ones), plus `usize`/`isize` (target-width — `u64`/`s64` on a
64-bit host).
- **Value.** Pure `(width, signedness)` arithmetic — never a per-name table:
- `sN`: `min = -(2^(N-1))`, `max = 2^(N-1) - 1`
- `uN`: `min = 0`, `max = 2^N - 1`
- **Result type.** The constant has the **queried** type: `s3.max` is an `s3`,
`u64.max` is a `u64`. So it is usable anywhere a constant of that type is
legal — initializers, `::` / `:=` bindings, and larger expressions — and in
array-dimension / count position via the compile-time integer path
(`[u8.max]T` is a 255-element array; `[s16.max]T` a 32767-element one). A
count that does not fit (`[u64.max]T`) is rejected as an oversized dimension.
- **Representation note.** `u64.max` / `usize.max` is the all-ones 64-bit value
(`18446744073709551615`), which exceeds the signed `i64` range used for
integer constants; it is stored as that exact bit pattern carrying the `u64`
type (it reinterprets to `-1` as an `s64`). It cannot be written as a decimal
literal, and the default integer formatter (which is `s64`-based) prints it as
`-1`; assert it exactly through a bit reinterpret (`union { u: u64; s: s64 }`).
- **Non-numeric receivers.** `.min` / `.max` on a non-numeric type (`bool`,
`string`, a pointer, a `struct`, `void`, an `enum`) is a compile error, never
a silent value.
### Enum Types
User-defined sum types with named variants. Variants may optionally carry typed data (tagged unions). Internally, payload-less enums are represented as `i64` (variant index). Enums with payloads are represented as `{ i64, [max_payload_size x i8] }` (tag + data).