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

@@ -93,12 +93,12 @@ DOCK_ANIM_DURATION :f32: 0.19; // 190ms
DockInteraction :: struct {
// Drag state
dragging_child: s64; // -1 = none
dragging_child: i64; // -1 = none
drag_start_pos: Point;
drag_offset: Point;
click_fraction_x: f32;
click_fraction_y: f32;
hovered_zone: s64; // -1 = none, else DockZone ordinal
hovered_zone: i64; // -1 = none, else DockZone ordinal
// Per-child state
natural_sizes: List(Size);
@@ -111,7 +111,7 @@ DockInteraction :: struct {
anim_sizes: List(Animated(Size));
header_pressed: List(bool);
child_count: s64;
child_count: i64;
parent_allocator: Allocator; // GPA — used for persistent list growth
init :: (self: *DockInteraction) {
@@ -135,7 +135,7 @@ DockInteraction :: struct {
self.header_pressed = List(bool).{};
}
ensure_capacity :: (self: *DockInteraction, count: s64) {
ensure_capacity :: (self: *DockInteraction, count: i64) {
if self.child_count >= count { return; }
while self.child_count < count {
self.natural_sizes.append(Size.zero(), self.parent_allocator);
@@ -151,7 +151,7 @@ DockInteraction :: struct {
}
}
set_target_size :: (self: *DockInteraction, index: s64, target: Size) {
set_target_size :: (self: *DockInteraction, index: i64, target: Size) {
if index >= self.child_count { return; }
anim := @self.anim_sizes.items[index];
cur := anim.to;
@@ -168,7 +168,7 @@ DockInteraction :: struct {
}
}
get_animated_size :: (self: *DockInteraction, index: s64) -> Size {
get_animated_size :: (self: *DockInteraction, index: i64) -> Size {
if index >= self.child_count { return Size.zero(); }
(@self.anim_sizes.items[index]).current
}
@@ -197,7 +197,7 @@ DockInteraction :: struct {
}
}
start_dragging :: (interaction: *DockInteraction, child_index: s64, pos: Point, panel_frame: Frame) {
start_dragging :: (interaction: *DockInteraction, child_index: i64, pos: Point, panel_frame: Frame) {
interaction.dragging_child = child_index;
interaction.drag_start_pos = pos;
interaction.drag_offset = Point.zero();
@@ -218,7 +218,7 @@ start_dragging :: (interaction: *DockInteraction, child_index: s64, pos: Point,
// Helper functions
// =============================================================================
zone_by_index :: (i: s64) -> DockZone {
zone_by_index :: (i: i64) -> DockZone {
if i == {
case 0: .fill;
case 1: .center;
@@ -234,8 +234,8 @@ zone_by_index :: (i: s64) -> DockZone {
}
find_hovered_zone :: (bounds: Frame, pos: Point, hint_size: f32, enable_corners: bool) -> ?DockZone {
count : s64 = if enable_corners then 10 else 6;
i : s64 = 0;
count : i64 = if enable_corners then 10 else 6;
i : i64 = 0;
while i < count {
zone := zone_by_index(i);
hint := dock_zone_get_hint_frame(zone, bounds, hint_size);
@@ -365,7 +365,7 @@ DockPanel :: struct {
corner_radius: f32;
header_height: f32;
dock_interaction: *DockInteraction;
panel_index: s64;
panel_index: i64;
DEFAULT_BG :Color: Color.rgba(26, 26, 31, 242);
DEFAULT_HEADER_BG :Color: Color.rgba(38, 38, 46, 255);
@@ -469,7 +469,7 @@ Dock :: struct {
hint_active_color: Color;
preview_color: Color;
enable_corners: bool;
on_dock: ?Closure(s64, DockZone);
on_dock: ?Closure(i64, DockZone);
make :: (interaction: *DockInteraction, delta_time: *f32) -> Dock {
d : Dock = ---;
@@ -519,7 +519,7 @@ impl View for Dock {
dt : f32 = self.delta_time.*;
interaction.tick_animations(dt);
i : s64 = 0;
i : i64 = 0;
while i < self.children.len {
child := @self.children.items[i];
@@ -603,7 +603,7 @@ impl View for Dock {
}
// Draw children
i : s64 = 0;
i : i64 = 0;
while i < self.children.len {
child := @self.children.items[i];
child.view.render(ctx, child.computed_frame);
@@ -619,8 +619,8 @@ impl View for Dock {
}
// Zone hint indicators
count : s64 = if self.enable_corners then 10 else 6;
j : s64 = 0;
count : i64 = if self.enable_corners then 10 else 6;
j : i64 = 0;
while j < count {
zone := zone_by_index(j);
hint_frame := dock_zone_get_hint_frame(zone, frame, self.hint_size);

View File

@@ -16,14 +16,14 @@ GesturePhase :: enum {
TapValue :: struct {
location: Point;
count: s32;
count: i32;
}
TapGesture :: struct {
count: s32;
count: i32;
on_tap: ?Closure();
phase: GesturePhase;
tap_count: s32;
tap_count: i32;
start_position: Point;
TAP_THRESHOLD :f32: 10.0;

View File

@@ -50,7 +50,7 @@ ShapedGlyph :: struct {
}
is_ascii :: (text: string) -> bool {
i : s64 = 0;
i : i64 = 0;
while i < text.len {
if text[i] >= 128 { return false; }
i += 1;
@@ -69,9 +69,9 @@ KBTS_USER_ID_GENERATION_MODE_CODEPOINT_INDEX :u32: 0;
KbtsGlyphIterator :: struct {
glyph_storage: *void;
current_glyph: *void;
last_advance_x: s32;
x: s32;
y: s32;
last_advance_x: i32;
x: i32;
y: i32;
}
KbtsRun :: struct {
@@ -89,15 +89,15 @@ KbtsGlyph :: struct {
codepoint: u32;
id: u16;
uid: u16;
user_id_or_codepoint_index: s32;
offset_x: s32;
offset_y: s32;
advance_x: s32;
advance_y: s32;
user_id_or_codepoint_index: i32;
offset_x: i32;
offset_y: i32;
advance_x: i32;
advance_y: i32;
}
// kbts_font_info2 base (simplified — we only need the Size field for dispatch)
KBTS_FONT_INFO_STRING_ID_COUNT :s32: 7;
KBTS_FONT_INFO_STRING_ID_COUNT :i32: 7;
KbtsFontInfo2 :: struct {
size: u32;
@@ -111,21 +111,21 @@ KbtsFontInfo2 :: struct {
KbtsFontInfo2_1 :: struct {
base: KbtsFontInfo2;
units_per_em: u16;
x_min: s16;
y_min: s16;
x_max: s16;
y_max: s16;
ascent: s16;
descent: s16;
line_gap: s16;
x_min: i16;
y_min: i16;
x_max: i16;
y_max: i16;
ascent: i16;
descent: i16;
line_gap: i16;
}
GLYPH_ATLAS_W :s32: 1024;
GLYPH_ATLAS_H :s32: 1024;
FONTINFO_SIZE :s64: 256;
GLYPH_ATLAS_W :i32: 1024;
GLYPH_ATLAS_H :i32: 1024;
FONTINFO_SIZE :i64: 256;
PackResult :: struct {
x, y: s32;
x, y: i32;
}
// Dynamic glyph cache with on-demand rasterization and texture atlas packing.
@@ -136,25 +136,25 @@ GlyphCache :: struct {
// Atlas texture (GPU)
texture_id: u32;
atlas_width: s32;
atlas_height: s32;
atlas_width: i32;
atlas_height: i32;
// Atlas bitmap (CPU-side for updates)
bitmap: [*]u8;
// Shelf packer state
shelf_y: s32;
shelf_height: s32;
cursor_x: s32;
padding: s32;
shelf_y: i32;
shelf_height: i32;
cursor_x: i32;
padding: i32;
// Glyph lookup cache
entries: List(GlyphEntry);
// Hash table for O(1) glyph lookup (open addressing, linear probing)
hash_keys: [*]u32; // key per slot (0 = empty sentinel)
hash_vals: [*]s32; // index into entries list
hash_cap: s64; // table capacity (power of 2)
hash_vals: [*]i32; // index into entries list
hash_cap: i64; // table capacity (power of 2)
// Dirty tracking for texture upload
dirty: bool;
@@ -172,12 +172,12 @@ GlyphCache :: struct {
shape_ctx: *void;
shape_font: *void;
units_per_em: u16;
font_data_size: s32;
font_data_size: i32;
shaped_buf: List(ShapedGlyph);
// Shape cache: skip reshaping if same text + size as last call
last_shape_ptr: [*]u8;
last_shape_len: s64;
last_shape_len: i64;
last_shape_size_q: u16;
// Allocator that owns every dynamically-grown buffer on this cache —
@@ -199,7 +199,7 @@ GlyphCache :: struct {
self.parent_allocator = context.allocator;
// Load font file
file_size : s32 = 0;
file_size : i32 = 0;
font_data := read_file_bytes(path, @file_size);
if font_data == null {
out("Failed to load font: ");
@@ -216,9 +216,9 @@ GlyphCache :: struct {
stbtt_InitFont(self.font_info, font_data, 0);
// Get font vertical metrics (in unscaled font units)
ascent_i : s32 = 0;
descent_i : s32 = 0;
linegap_i : s32 = 0;
ascent_i : i32 = 0;
descent_i : i32 = 0;
linegap_i : i32 = 0;
stbtt_GetFontVMetrics(self.font_info, @ascent_i, @descent_i, @linegap_i);
// Store unscaled metrics — we'll scale per font_size in measure_text
@@ -241,7 +241,7 @@ GlyphCache :: struct {
// Allocate atlas bitmap
self.atlas_width = GLYPH_ATLAS_W;
self.atlas_height = GLYPH_ATLAS_H;
bitmap_size : s64 = xx self.atlas_width * xx self.atlas_height;
bitmap_size : i64 = xx self.atlas_width * xx self.atlas_height;
self.bitmap = xx self.parent_allocator.alloc_bytes(bitmap_size);
memset(self.bitmap, 0, bitmap_size);
@@ -257,10 +257,10 @@ GlyphCache :: struct {
// Init hash table (256 slots)
self.hash_cap = 256;
hash_bytes : s64 = self.hash_cap * 4; // u32 per slot
hash_bytes : i64 = self.hash_cap * 4; // u32 per slot
self.hash_keys = xx self.parent_allocator.alloc_bytes(hash_bytes);
memset(self.hash_keys, 0, hash_bytes);
val_bytes : s64 = self.hash_cap * 8; // s64 per slot (s32 would suffice but alignment)
val_bytes : i64 = self.hash_cap * 8; // i64 per slot (i32 would suffice but alignment)
self.hash_vals = xx self.parent_allocator.alloc_bytes(val_bytes);
// Create the atlas texture. In GPU-protocol mode we create empty and
@@ -296,7 +296,7 @@ GlyphCache :: struct {
// Hash table lookup (open addressing, linear probing)
mask := self.hash_cap - 1;
slot : s64 = xx ((key * 2654435761) >> 24) & xx mask;
slot : i64 = xx ((key * 2654435761) >> 24) & xx mask;
while self.hash_keys[slot] != 0 {
if self.hash_keys[slot] == key {
return @self.entries.items[self.hash_vals[slot]].glyph;
@@ -309,18 +309,18 @@ GlyphCache :: struct {
scale := stbtt_ScaleForPixelHeight(self.font_info, actual_size);
// Get glyph bounding box
x0 : s32 = 0;
y0 : s32 = 0;
x1 : s32 = 0;
y1 : s32 = 0;
x0 : i32 = 0;
y0 : i32 = 0;
x1 : i32 = 0;
y1 : i32 = 0;
stbtt_GetGlyphBitmapBox(self.font_info, xx glyph_index, scale, scale, @x0, @y0, @x1, @y1);
glyph_w := if x1 > x0 then x1 - x0 else 0;
glyph_h := if y1 > y0 then y1 - y0 else 0;
// Get horizontal metrics
advance_i : s32 = 0;
lsb_i : s32 = 0;
advance_i : i32 = 0;
lsb_i : i32 = 0;
stbtt_GetGlyphHMetrics(self.font_info, xx glyph_index, @advance_i, @lsb_i);
advance : f32 = xx advance_i * scale;
@@ -349,7 +349,7 @@ GlyphCache :: struct {
}
// Rasterize directly into atlas bitmap
dest_offset : s64 = xx pack.y * xx self.atlas_width + xx pack.x;
dest_offset : i64 = xx pack.y * xx self.atlas_width + xx pack.x;
stbtt_MakeGlyphBitmap(
self.font_info,
@self.bitmap[dest_offset],
@@ -384,13 +384,13 @@ GlyphCache :: struct {
}
// Insert a key→index mapping into the hash table, growing if needed
hash_insert :: (self: *GlyphCache, key: u32, index: s64) {
hash_insert :: (self: *GlyphCache, key: u32, index: i64) {
// Grow if load factor > 70%
if self.entries.len * 10 > self.hash_cap * 7 {
self.hash_grow();
}
mask := self.hash_cap - 1;
slot : s64 = xx ((key * 2654435761) >> 24) & xx mask;
slot : i64 = xx ((key * 2654435761) >> 24) & xx mask;
while self.hash_keys[slot] != 0 {
slot = (slot + 1) & mask;
}
@@ -405,19 +405,19 @@ GlyphCache :: struct {
old_vals := self.hash_vals;
self.hash_cap = old_cap * 2;
hash_bytes : s64 = self.hash_cap * 4;
hash_bytes : i64 = self.hash_cap * 4;
self.hash_keys = xx self.parent_allocator.alloc_bytes(hash_bytes);
memset(self.hash_keys, 0, hash_bytes);
val_bytes : s64 = self.hash_cap * 8;
val_bytes : i64 = self.hash_cap * 8;
self.hash_vals = xx self.parent_allocator.alloc_bytes(val_bytes);
// Rehash
mask := self.hash_cap - 1;
i : s64 = 0;
i : i64 = 0;
while i < old_cap {
k := old_keys[i];
if k != 0 {
slot : s64 = xx ((k * 2654435761) >> 24) & xx mask;
slot : i64 = xx ((k * 2654435761) >> 24) & xx mask;
while self.hash_keys[slot] != 0 {
slot = (slot + 1) & mask;
}
@@ -456,7 +456,7 @@ GlyphCache :: struct {
// Shelf-based rectangle packer.
// Returns PackResult with x >= 0 on success, x = -1 if no space.
try_pack :: (self: *GlyphCache, w: s32, h: s32) -> PackResult {
try_pack :: (self: *GlyphCache, w: i32, h: i32) -> PackResult {
padded_w := w + self.padding;
padded_h := h + self.padding;
@@ -488,15 +488,15 @@ GlyphCache :: struct {
grow :: (self: *GlyphCache) {
new_w := self.atlas_width * 2;
new_h := self.atlas_height * 2;
new_size : s64 = xx new_w * xx new_h;
new_size : i64 = xx new_w * xx new_h;
new_bitmap : [*]u8 = xx self.parent_allocator.alloc_bytes(new_size);
memset(new_bitmap, 0, new_size);
// Copy old rows into new bitmap
y : s32 = 0;
y : i32 = 0;
while y < self.atlas_height {
old_off : s64 = xx y * xx self.atlas_width;
new_off : s64 = xx y * xx new_w;
old_off : i64 = xx y * xx self.atlas_width;
new_off : i64 = xx y * xx new_w;
memcpy(@new_bitmap[new_off], @self.bitmap[old_off], xx self.atlas_width);
y += 1;
}
@@ -525,7 +525,7 @@ GlyphCache :: struct {
// Recompute UV coordinates for all cached glyphs
atlas_wf : f32 = xx new_w;
atlas_hf : f32 = xx new_h;
i : s64 = 0;
i : i64 = 0;
while i < self.entries.len {
g := @self.entries.items[i].glyph;
if g.width > 0.0 {
@@ -591,13 +591,13 @@ GlyphCache :: struct {
shape_ascii :: (self: *GlyphCache, text: string, font_size: f32) {
scale := stbtt_ScaleForPixelHeight(self.font_info, font_size);
total : f32 = 0.0;
i : s64 = 0;
i : i64 = 0;
while i < text.len {
ch : s32 = xx text[i];
ch : i32 = xx text[i];
glyph_index : u16 = xx stbtt_FindGlyphIndex(self.font_info, ch);
advance_i : s32 = 0;
lsb_i : s32 = 0;
advance_i : i32 = 0;
lsb_i : i32 = 0;
stbtt_GetGlyphHMetrics(self.font_info, xx glyph_index, @advance_i, @lsb_i);
adv : f32 = xx advance_i * scale;
@@ -650,7 +650,7 @@ GlyphCache :: struct {
measure_text :: (self: *GlyphCache, text: string, font_size: f32) -> Size {
self.shape_text(text, font_size);
width : f32 = 0.0;
i : s64 = 0;
i : i64 = 0;
while i < self.shaped_buf.len {
width += self.shaped_buf.items[i].advance;
i += 1;

View File

@@ -27,7 +27,7 @@ UIPipeline :: struct {
// `push Context` site.
arena_a: Arena;
arena_b: Arena;
frame_index: s64;
frame_index: i64;
body: Closure() -> View;
has_body: bool;
parent_allocator: Allocator;

View File

@@ -35,12 +35,12 @@ RenderNode :: struct {
// Opacity
opacity: f32;
depth: s64;
depth: i64;
}
RenderTree :: struct {
nodes: List(RenderNode);
generation: s64;
generation: i64;
init :: () -> RenderTree {
RenderTree.{ generation = 0 }
@@ -51,7 +51,7 @@ RenderTree :: struct {
self.generation += 1;
}
add :: (self: *RenderTree, node: RenderNode) -> s64 {
add :: (self: *RenderTree, node: RenderNode) -> i64 {
idx := self.nodes.len;
self.nodes.append(node);
idx
@@ -62,9 +62,9 @@ RenderTree :: struct {
RenderContext :: struct {
tree: *RenderTree;
clip_depth: s64;
clip_depth: i64;
opacity: f32;
depth: s64;
depth: i64;
init :: (tree: *RenderTree) -> RenderContext {
RenderContext.{

View File

@@ -10,27 +10,27 @@
#import "modules/ui/font.sx";
// Vertex: pos(2) + uv(2) + color(4) + params(4) = 12 floats
UI_VERTEX_FLOATS :s64: 12;
UI_VERTEX_BYTES :s64: 48;
MAX_UI_VERTICES :s64: 16384;
UI_VERTEX_FLOATS :i64: 12;
UI_VERTEX_BYTES :i64: 48;
MAX_UI_VERTICES :i64: 16384;
UIRenderer :: struct {
// GL-side handles. Used when `gpu == null` (every non-iOS target today).
vao: u32;
vbo: u32;
shader: u32;
proj_loc: s32;
tex_loc: s32;
proj_loc: i32;
tex_loc: i32;
// CPU-side vertex scratch buffer — same for both backends.
vertices: [*]f32;
vertex_count: s64;
vertex_count: i64;
screen_width: f32;
screen_height: f32;
dpi_scale: f32;
white_texture: u32; // GL name OR TextureHandle (both are u32-shaped)
current_texture: u32;
draw_calls: s64;
draw_calls: i64;
// GPU protocol backend. When set, the renderer routes shader / buffer /
// texture / draw calls through `gpu` instead of raw GL. The chess game
@@ -44,8 +44,8 @@ UIRenderer :: struct {
// time, not at draw-call submission, so re-using offset 0 across flushes
// would let the last writer win and earlier batches would render as
// whatever was uploaded last. Reset to 0 in `begin()`.
mtl_buf_offset: s64 = 0;
mtl_buf_capacity: s64 = 0;
mtl_buf_offset: i64 = 0;
mtl_buf_capacity: i64 = 0;
init :: (self: *UIRenderer) {
// Allocate vertex scratch (CPU side) — same for both backends.
@@ -295,7 +295,7 @@ UIRenderer :: struct {
flush :: (self: *UIRenderer) {
if self.vertex_count == 0 { return; }
upload_size : s64 = self.vertex_count * UI_VERTEX_BYTES;
upload_size : i64 = self.vertex_count * UI_VERTEX_BYTES;
if self.gpu != null {
// Mirror the GL path: bind current texture before drawing.
@@ -315,7 +315,7 @@ UIRenderer :: struct {
}
byte_off := self.mtl_buf_offset;
self.gpu.update_buffer_at(self.mtl_vbuf, xx self.vertices, upload_size, byte_off);
vertex_off : s32 = xx (byte_off / UI_VERTEX_BYTES);
vertex_off : i32 = xx (byte_off / UI_VERTEX_BYTES);
self.gpu.draw_triangles(vertex_off, xx self.vertex_count);
// Each batch starts on a vertex boundary so `vertex_off =
// byte_off / UI_VERTEX_BYTES` lands on a whole vertex (otherwise
@@ -364,7 +364,7 @@ UIRenderer :: struct {
raster_size := node.font_size * font.dpi_scale;
inv_dpi := font.inv_dpi;
i : s64 = 0;
i : i64 = 0;
while i < font.shaped_buf.len {
shaped := font.shaped_buf.items[i];
cached := font.get_or_rasterize(shaped.glyph_index, raster_size);

View File

@@ -14,17 +14,17 @@ State :: struct ($T: Type) {
// --- StateEntry — type-erased storage ---
StateEntry :: struct {
id: s64;
id: i64;
data: [*]u8;
size: s64;
generation: s64;
size: i64;
generation: i64;
}
// --- StateStore — manages persistent state ---
StateStore :: struct {
entries: List(StateEntry);
current_generation: s64;
current_generation: i64;
parent_allocator: Allocator;
init :: (self: *StateStore) {
@@ -33,9 +33,9 @@ StateStore :: struct {
self.parent_allocator = context.allocator;
}
get_or_create :: (self: *StateStore, id: s64, $T: Type, default: T) -> State(T) {
get_or_create :: (self: *StateStore, id: i64, $T: Type, default: T) -> State(T) {
// Search for existing entry
i : s64 = 0;
i : i64 = 0;
while i < self.entries.len {
if self.entries.items[i].id == id {
self.entries.items[i].generation = self.current_generation;

View File

@@ -45,7 +45,7 @@ impl View for StatsPanel {
// FPS value
dt := self.delta_time.*;
fps : s64 = if dt > 0.0 then xx (1.0 / dt) else 0;
fps : i64 = if dt > 0.0 then xx (1.0 / dt) else 0;
fps_text := format("FPS: {}", fps);
fps_size := measure_text(fps_text, StatsPanel.VALUE_SIZE);
fps_frame := Frame.make(