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:
agra
2026-06-12 09:31:53 +03:00
parent 515ecebea7
commit d8076b9333
1054 changed files with 6836 additions and 6839 deletions

View File

@@ -56,15 +56,15 @@ test "ProgramIndex declaration maps round-trip (A1.1b)" {
try std.testing.expect(idx.fn_ast_map.get("main").? == &fd);
// type_alias_map: alias name → target TypeId.
try idx.type_alias_map.put("ShaderHandle", .s64);
try std.testing.expectEqual(@as(?types.TypeId, .s64), idx.type_alias_map.get("ShaderHandle"));
try idx.type_alias_map.put("ShaderHandle", .i64);
try std.testing.expectEqual(@as(?types.TypeId, .i64), idx.type_alias_map.get("ShaderHandle"));
// global_names: #run global name → GlobalInfo.
try idx.global_names.put("g", .{ .id = inst.GlobalId.fromIndex(0), .ty = .s64 });
try idx.global_names.put("g", .{ .id = inst.GlobalId.fromIndex(0), .ty = .i64 });
try std.testing.expect(idx.global_names.get("g").?.id == inst.GlobalId.fromIndex(0));
// module_const_map: const name → ModuleConstInfo.
try idx.module_const_map.put("AF_INET", .{ .value = &blk, .ty = .s32 });
try idx.module_const_map.put("AF_INET", .{ .value = &blk, .ty = .i32 });
try std.testing.expect(idx.module_const_map.get("AF_INET").?.value == &blk);
// foreign_class_map: sx alias → ForeignClassDecl.
@@ -110,22 +110,22 @@ test "ProgramIndex source-keyed caches partition same-name authors by source" {
var blk_b = ast.Node{ .span = .{ .start = 1, .end = 1 }, .data = .{ .block = .{ .stmts = &.{} } } };
// SAME alias name `Foo` authored in two modules → two distinct TypeIds.
idx.putTypeAliasBySource("a.sx", "Foo", .s64);
idx.putTypeAliasBySource("a.sx", "Foo", .i64);
idx.putTypeAliasBySource("b.sx", "Foo", .f64);
try std.testing.expectEqual(@as(?types.TypeId, .s64), idx.type_aliases_by_source.get("a.sx").?.get("Foo"));
try std.testing.expectEqual(@as(?types.TypeId, .i64), idx.type_aliases_by_source.get("a.sx").?.get("Foo"));
try std.testing.expectEqual(@as(?types.TypeId, .f64), idx.type_aliases_by_source.get("b.sx").?.get("Foo"));
try std.testing.expectEqual(@as(u32, 2), idx.type_aliases_by_source.count());
// SAME const name `K` authored in two modules → two distinct ModuleConstInfos.
idx.putModuleConstBySource("a.sx", "K", .{ .value = &blk_a, .ty = .s32 });
idx.putModuleConstBySource("a.sx", "K", .{ .value = &blk_a, .ty = .i32 });
idx.putModuleConstBySource("b.sx", "K", .{ .value = &blk_b, .ty = .f32 });
try std.testing.expect(idx.module_consts_by_source.get("a.sx").?.get("K").?.value == &blk_a);
try std.testing.expect(idx.module_consts_by_source.get("b.sx").?.get("K").?.value == &blk_b);
try std.testing.expectEqual(@as(?types.TypeId, .s32), idx.module_consts_by_source.get("a.sx").?.get("K").?.ty);
try std.testing.expectEqual(@as(?types.TypeId, .i32), idx.module_consts_by_source.get("a.sx").?.get("K").?.ty);
try std.testing.expectEqual(@as(?types.TypeId, .f32), idx.module_consts_by_source.get("b.sx").?.get("K").?.ty);
// SAME global name `g` authored in two modules → two distinct GlobalInfos.
idx.putGlobalBySource("a.sx", "g", .{ .id = inst.GlobalId.fromIndex(0), .ty = .s64 });
idx.putGlobalBySource("a.sx", "g", .{ .id = inst.GlobalId.fromIndex(0), .ty = .i64 });
idx.putGlobalBySource("b.sx", "g", .{ .id = inst.GlobalId.fromIndex(1), .ty = .f64 });
try std.testing.expect(idx.globals_by_source.get("a.sx").?.get("g").?.id == inst.GlobalId.fromIndex(0));
try std.testing.expect(idx.globals_by_source.get("b.sx").?.get("g").?.id == inst.GlobalId.fromIndex(1));
@@ -133,10 +133,10 @@ test "ProgramIndex source-keyed caches partition same-name authors by source" {
// Compat readers: the legacy global maps stay keyed by NAME alone, so a
// same-name author is last-wins there — exactly ONE entry for `Foo` / `K`,
// unchanged by the source-keyed writes above.
idx.type_alias_map.put("Foo", .s64) catch unreachable;
idx.type_alias_map.put("Foo", .i64) catch unreachable;
idx.type_alias_map.put("Foo", .f64) catch unreachable;
try std.testing.expectEqual(@as(u32, 1), idx.type_alias_map.count());
idx.module_const_map.put("K", .{ .value = &blk_a, .ty = .s32 }) catch unreachable;
idx.module_const_map.put("K", .{ .value = &blk_a, .ty = .i32 }) catch unreachable;
idx.module_const_map.put("K", .{ .value = &blk_b, .ty = .f32 }) catch unreachable;
try std.testing.expectEqual(@as(u32, 1), idx.module_const_map.count());
@@ -315,9 +315,9 @@ test "moduleConstInt folds expression-RHS consts and rejects cycles" {
var f_val = nFloat(4.0);
var g_val = nFloat(4.5);
try map.put("M", .{ .value = &m_val, .ty = .s64 });
try map.put("N", .{ .value = &n_val, .ty = .s64 });
try map.put("P", .{ .value = &p_val, .ty = .s64 });
try map.put("M", .{ .value = &m_val, .ty = .i64 });
try map.put("N", .{ .value = &n_val, .ty = .i64 });
try map.put("P", .{ .value = &p_val, .ty = .i64 });
try map.put("F", .{ .value = &f_val, .ty = .f64 });
try map.put("G", .{ .value = &g_val, .ty = .f64 });
@@ -338,9 +338,9 @@ test "moduleConstInt folds expression-RHS consts and rejects cycles" {
var a_val = nBin(.add, &b_id, &zero);
var b_val = nBin(.add, &a_id, &zero);
var c_val = nBin(.add, &c_id, &zero);
try map.put("A", .{ .value = &a_val, .ty = .s64 });
try map.put("B", .{ .value = &b_val, .ty = .s64 });
try map.put("C", .{ .value = &c_val, .ty = .s64 });
try map.put("A", .{ .value = &a_val, .ty = .i64 });
try map.put("B", .{ .value = &b_val, .ty = .i64 });
try map.put("C", .{ .value = &c_val, .ty = .i64 });
try std.testing.expect(pi.moduleConstInt(&map, &table, "A") == null);
try std.testing.expect(pi.moduleConstInt(&map, &table, "B") == null);
try std.testing.expect(pi.moduleConstInt(&map, &table, "C") == null);
@@ -354,7 +354,7 @@ test "moduleConstIsFloatTyped judges a const by VALUE, catching untyped float-EX
// KT : f64 : 4.0 (typed float), MI :: 2 (untyped int), ML :: 5.0 (untyped
// float literal → f64), ME :: 4.0 + 1.0 (untyped float EXPRESSION, placeholder
// type s64 yet float-valued), IE :: 1 + 2 (untyped int expression).
// type i64 yet float-valued), IE :: 1 + 2 (untyped int expression).
var kt_val = nFloat(4.0);
var mi_val = nLit(2);
var ml_val = nFloat(5.0);
@@ -365,13 +365,13 @@ test "moduleConstIsFloatTyped judges a const by VALUE, catching untyped float-EX
var l2 = nLit(2);
var ie_val = nBin(.add, &l1, &l2);
try map.put("KT", .{ .value = &kt_val, .ty = .f64 });
try map.put("MI", .{ .value = &mi_val, .ty = .s64 });
try map.put("MI", .{ .value = &mi_val, .ty = .i64 });
try map.put("ML", .{ .value = &ml_val, .ty = .f64 }); // pass-0 stores a float literal as f64
try map.put("ME", .{ .value = &me_val, .ty = .s64 }); // pass-0 placeholder for a binary_op
try map.put("IE", .{ .value = &ie_val, .ty = .s64 });
try map.put("ME", .{ .value = &me_val, .ty = .i64 }); // pass-0 placeholder for a binary_op
try map.put("IE", .{ .value = &ie_val, .ty = .i64 });
// Float-valued: a typed float const, an untyped float literal, AND an untyped
// float EXPRESSION whose declared type is the s64 placeholder (judged by value).
// float EXPRESSION whose declared type is the i64 placeholder (judged by value).
try std.testing.expect(pi.moduleConstIsFloatTyped(&map, &table, "KT"));
try std.testing.expect(pi.moduleConstIsFloatTyped(&map, &table, "ML"));
try std.testing.expect(pi.moduleConstIsFloatTyped(&map, &table, "ME"));
@@ -386,8 +386,8 @@ test "moduleConstIsFloatTyped judges a const by VALUE, catching untyped float-EX
var az = nFloat(0.0);
var a_val = nBin(.add, &b_id, &az);
var b_val = nBin(.add, &a_id, &az);
try map.put("A", .{ .value = &a_val, .ty = .s64 });
try map.put("B", .{ .value = &b_val, .ty = .s64 });
try map.put("A", .{ .value = &a_val, .ty = .i64 });
try map.put("B", .{ .value = &b_val, .ty = .i64 });
// The `+ 0.0` literal still makes them float-valued (a finite, non-cyclic leaf
// is reached before the cycle); the point is it TERMINATES.
try std.testing.expect(pi.moduleConstIsFloatTyped(&map, &table, "A"));
@@ -404,7 +404,7 @@ test "moduleConstInt gates the fold on the declared type, not the initializer no
// initializer must never be folded into a count: the count path
// consults `ModuleConstInfo.ty`, not just the node shape.
var int_val = nLit(4);
try map.put("OK", .{ .value = &int_val, .ty = .s64 });
try map.put("OK", .{ .value = &int_val, .ty = .i64 });
try map.put("STR", .{ .value = &int_val, .ty = .string });
try map.put("BOOLEAN", .{ .value = &int_val, .ty = .bool });
@@ -415,12 +415,12 @@ test "moduleConstInt gates the fold on the declared type, not the initializer no
// The same gate holds for a const-EXPRESSION value node (`M + 2`), not just
// a bare literal: a `string`-typed const whose initializer is a foldable
// integer expression must still never fold as a count (the
// const-expression leak). `KEXPR : s64 : M + 2` (numeric type) folds; the
// const-expression leak). `KEXPR : i64 : M + 2` (numeric type) folds; the
// same expression declared `string` does not.
var m_lit = nLit(2);
var add2 = nLit(2);
var expr_val = nBin(.add, &m_lit, &add2);
try map.put("KEXPR", .{ .value = &expr_val, .ty = .s64 });
try map.put("KEXPR", .{ .value = &expr_val, .ty = .i64 });
try map.put("STREXPR", .{ .value = &expr_val, .ty = .string });
try std.testing.expectEqual(@as(?i64, 4), pi.moduleConstInt(&map, &table, "KEXPR"));
try std.testing.expect(pi.moduleConstInt(&map, &table, "STREXPR") == null);
@@ -539,21 +539,21 @@ test "a backtick raw-shadow receiver is a field read, not a numeric-limit fold (
const ctx = DimCtx{};
// BARE type receiver (`is_raw = false`) → the numeric-limit accessor folds:
// `f64.epsilon` is the builtin eps, `s8.max` is 127.
// `f64.epsilon` is the builtin eps, `i8.max` is 127.
var f64ty = nIdent("f64");
var s8ty = nIdent("s8");
var s8ty = nIdent("i8");
var bare_feps = nField(&f64ty, "epsilon");
var bare_smax = nField(&s8ty, "max");
try std.testing.expectEqual(@as(?f64, @as(f64, std.math.floatEps(f64))), evalf(&bare_feps, ctx));
try std.testing.expectEqual(@as(?i64, std.math.maxInt(i8)), evali(&bare_smax, ctx));
// RAW receiver (`` `f64 ``/`` `s8 ``) shadows the builtin with a VALUE — the
// RAW receiver (`` `f64 ``/`` `i8 ``) shadows the builtin with a VALUE — the
// field access is an ordinary runtime field READ, so it is NOT a compile-time
// leaf in either evaluator (→ null), exactly as the sibling `isFloatValuedExpr`
// already treats it. The whole point: a value-shadow can never be misread as
// the builtin limit.
var f64raw = nIdentRaw("f64");
var s8raw = nIdentRaw("s8");
var s8raw = nIdentRaw("i8");
var raw_feps = nField(&f64raw, "epsilon");
var raw_smax = nField(&s8raw, "max");
try std.testing.expect(evalf(&raw_feps, ctx) == null);