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).
19 lines
748 B
Plaintext
19 lines
748 B
Plaintext
// Numeric-limit accessors apply only to numeric types. `.min`/`.max` on a
|
|
// NON-numeric receiver is a clean compile error (never a silent value, never
|
|
// the `.unresolved` sentinel reaching codegen):
|
|
// - a builtin non-numeric type (`bool`, `void`, `string`) → a dedicated
|
|
// "type 'X' has no '.min'/'.max'" diagnostic from the accessor intercept;
|
|
// - a user struct (`MyStruct`) → the type name is not a builtin, so the
|
|
// intercept stays out and the existing field-not-found path reports it.
|
|
// Each case is accurate and located at the access; the program exits non-zero.
|
|
#import "modules/std.sx";
|
|
|
|
MyStruct :: struct { a: s64; }
|
|
|
|
main :: () -> s32 {
|
|
b := bool.max;
|
|
s := MyStruct.min;
|
|
v := void.max;
|
|
return 0;
|
|
}
|