lang: rename signed integer types sN -> iN
Surface rename of the signed integer family: s1..s64 become i1..i64
(u1..u64, usize, isize unchanged). 'string' keeps the s-prefix arm in
name classification; width parsing moves to the i-prefix arm next to
isize.
Internal TypeId tags follow the surface (.s8/.s16/.s32/.s64 ->
.i8/.i16/.i32/.i64), as do mono-key mangle fragments (ptr_i64,
tu_i64_bool) and all display/diagnostic formatting (i{d}).
Migrated in the same sweep: stdlib + examples + issue repros + FFI C
companions (shared symbol names like ffi_id_i64), expected
stdout/stderr/ir snapshots, specs.md, readme.md, CLAUDE.md/AGENTS.md,
implementation_plan.md, docs/, issue writeups. Vendored stb_image and
historical flow state left untouched.
zig build test: 426/426; examples suite: 595/595.
This commit is contained in:
@@ -150,7 +150,7 @@ pub fn isFloatConstType(ty: TypeId) bool {
|
||||
/// True iff `name` is a FLOAT-valued module const — judged by the const's VALUE,
|
||||
/// not only its DECLARED type, so it catches both a typed float const
|
||||
/// (`K : f64 : 4.0`, `F : f64 : 2.5`) AND an UNTYPED float-EXPRESSION const
|
||||
/// (`ME :: 4.0 + 1.0`), whose pass-0 placeholder type is `s64` even though its
|
||||
/// (`ME :: 4.0 + 1.0`), whose pass-0 placeholder type is `i64` even though its
|
||||
/// value is float. The int folder's division arm consults this to tell a FLOAT
|
||||
/// division apart from an integer one even when both operands fold to integers
|
||||
/// (`K / 3`, `ME / 3`). `frame` cycle-guards a const whose value references
|
||||
@@ -170,11 +170,11 @@ fn moduleConstFloatValuedFramed(consts: *const std.StringHashMap(ModuleConstInfo
|
||||
/// is gated on `ModuleConstInfo.ty`, not just the shape of the initializer node:
|
||||
/// a `string`/`bool`/pointer/struct-typed const can never be folded into a count
|
||||
/// off an integer-looking initializer (the second symptom, where
|
||||
/// `N : string : 4` folded `[N]s64` to 4 by reading the `int_literal` node and
|
||||
/// `N : string : 4` folded `[N]i64` to 4 by reading the `int_literal` node and
|
||||
/// ignoring the `string` annotation).
|
||||
pub fn isCountableConstType(table: *const types.TypeTable, ty: TypeId) bool {
|
||||
return switch (ty) {
|
||||
.s8, .s16, .s32, .s64, .u8, .u16, .u32, .u64, .usize, .isize, .f32, .f64 => true,
|
||||
.i8, .i16, .i32, .i64, .u8, .u16, .u32, .u64, .usize, .isize, .f32, .f64 => true,
|
||||
else => if (ty.isBuiltin()) false else switch (table.get(ty)) {
|
||||
.signed, .unsigned => true,
|
||||
else => false,
|
||||
@@ -198,7 +198,7 @@ fn moduleConstIntFramed(consts: *const std.StringHashMap(ModuleConstInfo), table
|
||||
/// laid out via a type alias (`Arr :: [N]T`, stateless) gets a different length
|
||||
/// than the direct form (`a : [N]T`, stateful) — that miscompile class.
|
||||
/// Every const's RHS is folded through the shared `evalConstIntExpr`, so an
|
||||
/// untyped (`N :: 16`) / typed (`N : s64 : 16`) literal, an integral float
|
||||
/// untyped (`N :: 16`) / typed (`N : i64 : 16`) literal, an integral float
|
||||
/// (`N : f64 : 4.0` → 4, via `floatToIntExact`; `4.5` → null), AND an expression
|
||||
/// RHS over other consts (`M :: 2; N :: M + 1` → 3) all resolve identically and
|
||||
/// everywhere a count is accepted. Cyclic consts fold to null (see
|
||||
@@ -212,8 +212,8 @@ pub fn moduleConstInt(consts: *const std.StringHashMap(ModuleConstInfo), table:
|
||||
/// `moduleConstIntFramed` exactly — same `isCountableConstType` gate, same cyclic-
|
||||
/// definition frame — but recovers the value through `evalConstFloatExpr`, so the
|
||||
/// unified float→int narrowing rule resolves a NON-INTEGRAL float-const leaf
|
||||
/// (`y : s64 = F + 0.25`) the same way the int folder resolves an int-const leaf
|
||||
/// (`M :: 2; y : s64 = M + 0.5`). An integral float / integer const folds through
|
||||
/// (`y : i64 = F + 0.25`) the same way the int folder resolves an int-const leaf
|
||||
/// (`M :: 2; y : i64 = M + 0.5`). An integral float / integer const folds through
|
||||
/// the int path inside `evalConstFloatExpr` and never reaches the leaf arm that
|
||||
/// calls this; this surfaces the genuinely non-integral float so `floatToIntExact`
|
||||
/// can reject it.
|
||||
@@ -231,7 +231,7 @@ pub fn moduleConstFloat(consts: *const std.StringHashMap(ModuleConstInfo), table
|
||||
|
||||
/// True iff `name` is a FLOAT-valued module const — judged by VALUE, so it covers
|
||||
/// a typed float const (`K : f64 : 4.0`), an untyped float-EXPRESSION const
|
||||
/// (`ME :: 4.0 + 1.0`, whose placeholder type is `s64`), and a non-integral float
|
||||
/// (`ME :: 4.0 + 1.0`, whose placeholder type is `i64`), and a non-integral float
|
||||
/// const (`F : f64 : 2.5`). SINGLE source for the stateful (`Lowering`) and
|
||||
/// stateless (`type_bridge`) division-arm float checks, so they agree on which
|
||||
/// const-leaf divisions are float.
|
||||
@@ -255,7 +255,7 @@ pub fn moduleConstIsFloatTyped(consts: *const std.StringHashMap(ModuleConstInfo)
|
||||
/// Also the precise "is this a compile-time float-valued initializer" test the
|
||||
/// typed-binding narrowing path (`Lowering.foldComptimeFloatInit`) uses alongside
|
||||
/// `inferExprType`, so an untyped float-EXPRESSION const (`ME :: 4.0 + 1.0`,
|
||||
/// placeholder type `s64`) flowing into an integer binding (`x : s64 = ME / 2`)
|
||||
/// placeholder type `i64`) flowing into an integer binding (`x : i64 = ME / 2`)
|
||||
/// is judged float-valued even though `inferExprType` reads its placeholder type.
|
||||
pub fn isFloatValuedExpr(node: *const Node, ctx: anytype) bool {
|
||||
return switch (node.data) {
|
||||
@@ -323,7 +323,7 @@ pub fn evalConstIntExpr(node: *const Node, ctx: anytype) ?i64 {
|
||||
.identifier => |id| ctx.lookupDimName(id.name),
|
||||
.type_expr => |te| ctx.lookupDimName(te.name),
|
||||
.field_access => |fa| blk: {
|
||||
// A backtick RAW receiver (`` `s64.max ``, `` `f64.epsilon ``) is an
|
||||
// A backtick RAW receiver (`` `i64.max ``, `` `f64.epsilon ``) is an
|
||||
// ordinary field READ on a value whose spelling shadows a builtin
|
||||
// type name, NOT a numeric-limit / pack-arity accessor — so it is
|
||||
// never a compile-time leaf here; its field is a runtime value
|
||||
@@ -596,10 +596,10 @@ pub fn intTypeRange(name: []const u8) ?IntRange {
|
||||
if (eql(u8, name, "u16")) return .{ .min = 0, .max = std.math.maxInt(u16) };
|
||||
if (eql(u8, name, "u32")) return .{ .min = 0, .max = std.math.maxInt(u32) };
|
||||
if (eql(u8, name, "u64") or eql(u8, name, "usize")) return .{ .min = 0, .max = std.math.maxInt(i64) };
|
||||
if (eql(u8, name, "s8")) return .{ .min = std.math.minInt(i8), .max = std.math.maxInt(i8) };
|
||||
if (eql(u8, name, "s16")) return .{ .min = std.math.minInt(i16), .max = std.math.maxInt(i16) };
|
||||
if (eql(u8, name, "s32")) return .{ .min = std.math.minInt(i32), .max = std.math.maxInt(i32) };
|
||||
if (eql(u8, name, "s64") or eql(u8, name, "isize") or eql(u8, name, "int"))
|
||||
if (eql(u8, name, "i8")) return .{ .min = std.math.minInt(i8), .max = std.math.maxInt(i8) };
|
||||
if (eql(u8, name, "i16")) return .{ .min = std.math.minInt(i16), .max = std.math.maxInt(i16) };
|
||||
if (eql(u8, name, "i32")) return .{ .min = std.math.minInt(i32), .max = std.math.maxInt(i32) };
|
||||
if (eql(u8, name, "i64") or eql(u8, name, "isize") or eql(u8, name, "int"))
|
||||
return .{ .min = std.math.minInt(i64), .max = std.math.maxInt(i64) };
|
||||
return null;
|
||||
}
|
||||
@@ -682,7 +682,7 @@ pub const ProgramIndex = struct {
|
||||
protocol_decl_map: std.StringHashMap(ProtocolDeclInfo),
|
||||
/// Protocol name → AST node.
|
||||
protocol_ast_map: std.StringHashMap(*const ast.ProtocolDecl),
|
||||
/// Module-level value constants (e.g. AF_INET :s32: 2).
|
||||
/// Module-level value constants (e.g. AF_INET :i32: 2).
|
||||
module_const_map: std.StringHashMap(ModuleConstInfo),
|
||||
/// UFCS alias name → target function name.
|
||||
ufcs_alias_map: std.StringHashMap([]const u8),
|
||||
|
||||
Reference in New Issue
Block a user