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:
@@ -82,7 +82,7 @@ pub fn lowerStructLiteral(self: *Lowering, sl: *const ast.StructLiteral, span: a
|
||||
// `.ambiguous`/`.not_visible` surface their loud diagnostic + poison.
|
||||
self.resolveNominalLeaf(name, false, span)
|
||||
else if (sl.type_expr) |te|
|
||||
// Generic struct literal: Pair(s32).{ ... } — resolve type from type_expr
|
||||
// Generic struct literal: Pair(i32).{ ... } — resolve type from type_expr
|
||||
self.resolveTypeWithBindings(te)
|
||||
else self.target_type orelse .unresolved;
|
||||
|
||||
@@ -315,7 +315,7 @@ pub fn fixupMethodReceiver(self: *Lowering, method_args: *std.ArrayList(Ref), fu
|
||||
/// Get the name of a struct type (dereferencing pointers). Returns null for non-struct types.
|
||||
pub fn getStructTypeName(self: *Lowering, ty: TypeId) ?[]const u8 {
|
||||
if (ty.isBuiltin()) {
|
||||
// Map builtin types to their names for method resolution (e.g., s64.eq)
|
||||
// Map builtin types to their names for method resolution (e.g., i64.eq)
|
||||
return builtinTypeName(ty);
|
||||
}
|
||||
var resolved = ty;
|
||||
@@ -333,10 +333,10 @@ pub fn getStructTypeName(self: *Lowering, ty: TypeId) ?[]const u8 {
|
||||
|
||||
pub fn builtinTypeName(ty: TypeId) ?[]const u8 {
|
||||
return switch (ty) {
|
||||
.s8 => "s8",
|
||||
.s16 => "s16",
|
||||
.s32 => "s32",
|
||||
.s64 => "s64",
|
||||
.i8 => "i8",
|
||||
.i16 => "i16",
|
||||
.i32 => "i32",
|
||||
.i64 => "i64",
|
||||
.u8 => "u8",
|
||||
.u16 => "u16",
|
||||
.u32 => "u32",
|
||||
@@ -351,7 +351,7 @@ pub fn builtinTypeName(ty: TypeId) ?[]const u8 {
|
||||
|
||||
/// Resolve the type of a named field on a given type.
|
||||
pub fn resolveFieldType(self: *Lowering, ty: TypeId, field: []const u8) TypeId {
|
||||
if (std.mem.eql(u8, field, "len")) return .s64;
|
||||
if (std.mem.eql(u8, field, "len")) return .i64;
|
||||
if (std.mem.eql(u8, field, "ptr")) {
|
||||
const elem_ty = self.getElementType(ty);
|
||||
return self.module.types.manyPtrTo(elem_ty);
|
||||
@@ -497,7 +497,7 @@ pub fn lowerFieldAccess(self: *Lowering, fa: *const ast.FieldAccess, span: ast.S
|
||||
if (self.pack_param_count) |ppc| {
|
||||
if (fa.object.data == .identifier and std.mem.eql(u8, fa.field, "len")) {
|
||||
if (ppc.get(fa.object.data.identifier.name)) |n| {
|
||||
return self.builder.constInt(@as(i64, @intCast(n)), .s64);
|
||||
return self.builder.constInt(@as(i64, @intCast(n)), .i64);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -606,7 +606,7 @@ pub fn lowerFieldAccess(self: *Lowering, fa: *const ast.FieldAccess, span: ast.S
|
||||
|
||||
if (is_special) {
|
||||
if (std.mem.eql(u8, fa.field, "len")) {
|
||||
return self.builder.emit(.{ .length = .{ .operand = obj } }, .s64);
|
||||
return self.builder.emit(.{ .length = .{ .operand = obj } }, .i64);
|
||||
}
|
||||
{
|
||||
const elem_ty = self.getElementType(obj_ty);
|
||||
@@ -658,7 +658,7 @@ pub fn identifierBindsValue(self: *Lowering, name: []const u8) bool {
|
||||
/// a builtin type (a user struct → ordinary field lowering reports
|
||||
/// field-not-found). Two clean diagnostics (then a placeholder, so lowering
|
||||
/// finishes and `hasErrors()` aborts the build):
|
||||
/// - a FLOAT-only accessor on an integer type (`s32.epsilon`, `u8.inf`);
|
||||
/// - a FLOAT-only accessor on an integer type (`i32.epsilon`, `u8.inf`);
|
||||
/// - any accessor on a builtin NON-numeric receiver
|
||||
/// (`bool`/`string`/`void`/`Any`/`noreturn`).
|
||||
pub fn lowerNumericLimit(self: *Lowering, fa: *const ast.FieldAccess, span: ast.Span) ?Ref {
|
||||
@@ -704,7 +704,7 @@ pub fn lowerStructConstant(self: *Lowering, info: StructConstInfo) Ref {
|
||||
return switch (val_node.data) {
|
||||
.int_literal => |lit| blk: {
|
||||
if (info.ty) |t| self.checkIntLiteralFits(lit.value, t, val_node.span);
|
||||
break :blk self.builder.constInt(lit.value, info.ty orelse .s64);
|
||||
break :blk self.builder.constInt(lit.value, info.ty orelse .i64);
|
||||
},
|
||||
.float_literal => |lit| self.builder.constFloat(lit.value, info.ty orelse .f64),
|
||||
.bool_literal => |lit| self.builder.constBool(lit.value),
|
||||
@@ -1199,9 +1199,9 @@ pub fn resolveArrayLiteralType(self: *Lowering, te: *const Node) TypeId {
|
||||
return self.module.types.vectorOf(elem, length);
|
||||
}
|
||||
}
|
||||
// Generic-struct typed-literal head (`Box(s64).[...]`): route
|
||||
// Generic-struct typed-literal head (`Box(i64).[...]`): route
|
||||
// through the single layout choke-point (CP-1). A qualified head
|
||||
// `a.Box(s64).[...]` selects a's OWN template via the namespace edge
|
||||
// `a.Box(i64).[...]` selects a's OWN template via the namespace edge
|
||||
// (Counter-1: was the global last-wins map); a bare head selects the
|
||||
// single bare-VISIBLE author.
|
||||
if (headNameOfCallee(cl.callee)) |hn| {
|
||||
@@ -1258,7 +1258,7 @@ pub fn lowerIndexExpr(self: *Lowering, ie: *const ast.IndexExpr) Ref {
|
||||
// bounds" instead of the generic "unresolved 'args'" that the
|
||||
// fall-through scope-lookup would produce.
|
||||
if (self.diagPackIndexOOB(ie)) {
|
||||
return self.builder.constInt(0, .s64);
|
||||
return self.builder.constInt(0, .i64);
|
||||
}
|
||||
// Runtime index into a comptime-only pack (Decision 1): a pack has no
|
||||
// runtime representation, so the index must be a compile-time constant.
|
||||
@@ -1271,7 +1271,7 @@ pub fn lowerIndexExpr(self: *Lowering, ie: *const ast.IndexExpr) Ref {
|
||||
if (self.diagnostics) |diags| {
|
||||
diags.addFmt(.err, ie.index.span, "pack '{s}' must be indexed by a compile-time constant — a pack is comptime-only and has no runtime value", .{pname});
|
||||
}
|
||||
return self.builder.constInt(0, .s64);
|
||||
return self.builder.constInt(0, .i64);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1306,10 +1306,10 @@ pub fn lowerIndexExpr(self: *Lowering, ie: *const ast.IndexExpr) Ref {
|
||||
|
||||
pub fn lowerSliceExpr(self: *Lowering, se: *const ast.SliceExpr) Ref {
|
||||
const obj = self.lowerExpr(se.object);
|
||||
var lo = if (se.start) |s| self.lowerExpr(s) else self.builder.constInt(0, .s64);
|
||||
if (se.start_exclusive) lo = self.builder.add(lo, self.builder.constInt(1, .s64), .s64);
|
||||
var hi = if (se.end) |e| self.lowerExpr(e) else self.builder.emit(.{ .length = .{ .operand = obj } }, .s64);
|
||||
if (se.end_inclusive) hi = self.builder.add(hi, self.builder.constInt(1, .s64), .s64);
|
||||
var lo = if (se.start) |s| self.lowerExpr(s) else self.builder.constInt(0, .i64);
|
||||
if (se.start_exclusive) lo = self.builder.add(lo, self.builder.constInt(1, .i64), .i64);
|
||||
var hi = if (se.end) |e| self.lowerExpr(e) else self.builder.emit(.{ .length = .{ .operand = obj } }, .i64);
|
||||
if (se.end_inclusive) hi = self.builder.add(hi, self.builder.constInt(1, .i64), .i64);
|
||||
// Infer result slice type from the object
|
||||
const obj_ty = self.inferExprType(se.object);
|
||||
// Subslice of string stays string (same {ptr, i64} layout, correct type category)
|
||||
@@ -1598,8 +1598,8 @@ pub fn lowerExpr(self: *Lowering, node: *const Node) Ref {
|
||||
}
|
||||
}
|
||||
const ty = if (self.target_type) |tt| blk: {
|
||||
break :blk if (self.isIntEx(tt)) tt else .s64;
|
||||
} else .s64;
|
||||
break :blk if (self.isIntEx(tt)) tt else .i64;
|
||||
} else .i64;
|
||||
self.checkIntLiteralFits(lit.value, ty, node.span);
|
||||
return self.builder.constInt(lit.value, ty);
|
||||
},
|
||||
@@ -1645,7 +1645,7 @@ pub fn lowerExpr(self: *Lowering, node: *const Node) Ref {
|
||||
// Check compile-time constants (OS, ARCH, POINTER_SIZE) before globals
|
||||
if (self.comptime_constants.get(id.name)) |cv| {
|
||||
switch (cv) {
|
||||
.int_val => |iv| break :blk self.builder.constInt(iv, .s64),
|
||||
.int_val => |iv| break :blk self.builder.constInt(iv, .i64),
|
||||
.enum_tag => |et| break :blk self.builder.constInt(@intCast(et.tag), et.ty),
|
||||
}
|
||||
}
|
||||
@@ -1683,7 +1683,7 @@ pub fn lowerExpr(self: *Lowering, node: *const Node) Ref {
|
||||
.untracked => break :blk self.builder.emit(.{ .global_get = gi.id }, gi.ty),
|
||||
}
|
||||
}
|
||||
// Check module-level value constants (e.g. AF_INET :s32: 2)
|
||||
// Check module-level value constants (e.g. AF_INET :i32: 2)
|
||||
if (self.program_index.module_const_map.get(id.name)) |ci_global| {
|
||||
if (!self.isNameVisible(id.name)) {
|
||||
if (self.diagnostics) |d|
|
||||
@@ -1820,7 +1820,7 @@ pub fn lowerExpr(self: *Lowering, node: *const Node) Ref {
|
||||
// examples/50-smoke.sx has both shapes.
|
||||
}
|
||||
}
|
||||
break :blk self.builder.emit(.{ .func_ref = fid }, .s64);
|
||||
break :blk self.builder.emit(.{ .func_ref = fid }, .i64);
|
||||
}
|
||||
}
|
||||
// Type-as-value: a name that resolves to a TypeId
|
||||
@@ -1927,7 +1927,7 @@ pub fn lowerExpr(self: *Lowering, node: *const Node) Ref {
|
||||
break :blk self.builder.constFloat(@floatFromInt(v), tt);
|
||||
}
|
||||
}
|
||||
const nty = if (self.target_type) |tt| (if (self.isIntEx(tt)) tt else TypeId.s64) else TypeId.s64;
|
||||
const nty = if (self.target_type) |tt| (if (self.isIntEx(tt)) tt else TypeId.i64) else TypeId.i64;
|
||||
self.checkIntLiteralFits(v, nty, node.span);
|
||||
break :blk self.builder.constInt(v, nty);
|
||||
}
|
||||
@@ -2031,7 +2031,7 @@ pub fn lowerExpr(self: *Lowering, node: *const Node) Ref {
|
||||
},
|
||||
|
||||
// type_expr can appear as a variable reference when the name collides
|
||||
// with a builtin type name (e.g. s2, u8). Check scope first.
|
||||
// with a builtin type name (e.g. i2, u8). Check scope first.
|
||||
.type_expr => |te| blk: {
|
||||
if (self.scope) |scope| {
|
||||
if (scope.lookup(te.name)) |binding| {
|
||||
@@ -2057,8 +2057,8 @@ pub fn lowerExpr(self: *Lowering, node: *const Node) Ref {
|
||||
|
||||
// Compound type literals (`*T`, `[]T`, `[*]T`, `?T`, `[N]T`, fn types)
|
||||
// in expression position are first-class `Type` values, exactly like
|
||||
// the named form above (`t : Type = *s64;` ↔ `t : Type = f64;`). Also
|
||||
// the path a static `cast(*s64) v` type argument takes — call args are
|
||||
// the named form above (`t : Type = *i64;` ↔ `t : Type = f64;`). Also
|
||||
// the path a static `cast(*i64) v` type argument takes — call args are
|
||||
// lowered before the cast handler inspects the AST (issue 0118).
|
||||
.pointer_type_expr,
|
||||
.many_pointer_type_expr,
|
||||
@@ -2128,7 +2128,7 @@ pub fn lowerBinaryOp(self: *Lowering, bop: *const ast.BinaryOp) Ref {
|
||||
}
|
||||
|
||||
// Type-literal comparison fold: when both sides are type-shaped
|
||||
// AST nodes (`s64`, `*u8`, `?T`, `[3]f64`, etc.) OR resolve to
|
||||
// AST nodes (`i64`, `*u8`, `?T`, `[3]f64`, etc.) OR resolve to
|
||||
// a static TypeId at lower time (`type_of(x)` for any
|
||||
// statically-typed `x`), resolve each and emit a `const_bool`.
|
||||
// Same semantic as `type_eq(A, B)` but using the standard `==`
|
||||
@@ -2144,11 +2144,11 @@ pub fn lowerBinaryOp(self: *Lowering, bop: *const ast.BinaryOp) Ref {
|
||||
}
|
||||
}
|
||||
|
||||
// Any-shaped `==` (e.g. `t == s64` where `t: Type`): both
|
||||
// Any-shaped `==` (e.g. `t == i64` where `t: Type`): both
|
||||
// operands are 16-byte `{tag, value}` aggregates. LLVM
|
||||
// doesn't accept `icmp` on aggregates directly. Decompose
|
||||
// via `unbox_any` (which extracts the value field at
|
||||
// `.s64`) and compare the i64s. Tag fields are stable
|
||||
// `.i64`) and compare the i64s. Tag fields are stable
|
||||
// across compilations of the same source so value-only
|
||||
// identity is enough.
|
||||
if (bop.op == .eq or bop.op == .neq) {
|
||||
@@ -2157,8 +2157,8 @@ pub fn lowerBinaryOp(self: *Lowering, bop: *const ast.BinaryOp) Ref {
|
||||
if (lhs_ty == .any and rhs_ty == .any) {
|
||||
const lhs = self.lowerExpr(bop.lhs);
|
||||
const rhs = self.lowerExpr(bop.rhs);
|
||||
const lhs_val = self.builder.emit(.{ .unbox_any = .{ .operand = lhs } }, .s64);
|
||||
const rhs_val = self.builder.emit(.{ .unbox_any = .{ .operand = rhs } }, .s64);
|
||||
const lhs_val = self.builder.emit(.{ .unbox_any = .{ .operand = lhs } }, .i64);
|
||||
const rhs_val = self.builder.emit(.{ .unbox_any = .{ .operand = rhs } }, .i64);
|
||||
if (bop.op == .eq) {
|
||||
return self.builder.emit(.{ .cmp_eq = .{ .lhs = lhs_val, .rhs = rhs_val } }, .bool);
|
||||
} else {
|
||||
@@ -2249,7 +2249,7 @@ pub fn lowerBinaryOp(self: *Lowering, bop: *const ast.BinaryOp) Ref {
|
||||
if (rhs_ref_pointee) |p| rhs = self.builder.load(rhs, p);
|
||||
self.target_type = saved_tt;
|
||||
// Result type follows the shared promotion rule: an int LHS with a
|
||||
// float RHS promotes to the float (`s64 * f32` → `f32`); vectors /
|
||||
// float RHS promotes to the float (`i64 * f32` → `f32`); vectors /
|
||||
// structs keep the LHS type. `inferExprType` reuses the same helper
|
||||
// so static typing agrees with the value produced here.
|
||||
const rhs_inferred = rhs_ref_pointee orelse self.inferExprType(bop.rhs);
|
||||
@@ -2298,7 +2298,7 @@ pub fn lowerBinaryOp(self: *Lowering, bop: *const ast.BinaryOp) Ref {
|
||||
}
|
||||
|
||||
// Reject scalar ops on incompatible operand types (e.g.
|
||||
// `s64 + string`, `s64 < string`, `s64 & string`). The result type
|
||||
// `i64 + string`, `i64 < string`, `i64 & string`). The result type
|
||||
// `ty` is derived from the LHS, so without this the op lowers as
|
||||
// `<op> : <lhs>` and either reinterprets the RHS bytes (arithmetic
|
||||
// / bitwise → garbage) or feeds mismatched LLVM types to `icmp`
|
||||
@@ -2448,7 +2448,7 @@ pub fn lowerTupleOp(self: *Lowering, bop: *const ast.BinaryOp, lhs: Ref, rhs: Re
|
||||
// Lexicographic comparison
|
||||
return self.lowerTupleLexCompare(bop.op, lhs, rhs, lhs_fields);
|
||||
},
|
||||
else => return self.builder.constInt(0, .s64),
|
||||
else => return self.builder.constInt(0, .i64),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user