sdl phase 2

This commit is contained in:
agra
2026-02-12 21:37:25 +02:00
parent dab162bfe4
commit 4ff828fd1a
5 changed files with 281 additions and 132 deletions

View File

@@ -56,6 +56,38 @@ pub const Type = union(enum) {
name: []const u8,
};
/// Content-based equality: compares string fields by content, not pointer identity.
pub fn eql(self: Type, other: Type) bool {
const Tag = std.meta.Tag(Type);
const self_tag: Tag = self;
const other_tag: Tag = other;
if (self_tag != other_tag) return false;
return switch (self) {
.signed => |w| w == other.signed,
.unsigned => |w| w == other.unsigned,
.f32, .f64, .void_type, .boolean, .string_type, .any_type => true,
.enum_type => |n| std.mem.eql(u8, n, other.enum_type),
.struct_type => |n| std.mem.eql(u8, n, other.struct_type),
.union_type => |n| std.mem.eql(u8, n, other.union_type),
.array_type => |info| info.length == other.array_type.length and
std.mem.eql(u8, info.element_name, other.array_type.element_name),
.slice_type => |info| std.mem.eql(u8, info.element_name, other.slice_type.element_name),
.pointer_type => |info| std.mem.eql(u8, info.pointee_name, other.pointer_type.pointee_name),
.many_pointer_type => |info| std.mem.eql(u8, info.element_name, other.many_pointer_type.element_name),
.vector_type => |info| info.length == other.vector_type.length and
std.mem.eql(u8, info.element_name, other.vector_type.element_name),
.function_type => |info| {
const o = other.function_type;
if (info.param_types.len != o.param_types.len) return false;
for (info.param_types, o.param_types) |a, b| {
if (!a.eql(b)) return false;
}
return info.return_type.eql(o.return_type.*);
},
.meta_type => |info| std.mem.eql(u8, info.name, other.meta_type.name),
};
}
// Convenience constructors
pub fn s(width: u8) Type {
return .{ .signed = width };
@@ -91,6 +123,17 @@ pub const Type = union(enum) {
if (name.len >= 2 and name[0] == '*') {
return .{ .pointer_type = .{ .pointee_name = name[1..] } };
}
// Vector: Vector(N,T)
if (name.len >= 10 and std.mem.startsWith(u8, name, "Vector(") and name[name.len - 1] == ')') {
const inner = name[7 .. name.len - 1]; // contents between ( and )
if (std.mem.indexOfScalar(u8, inner, ',')) |comma| {
const length = std.fmt.parseInt(u32, inner[0..comma], 10) catch return null;
const elem_name = inner[comma + 1 ..];
if (elem_name.len > 0) {
return .{ .vector_type = .{ .element_name = elem_name, .length = length } };
}
}
}
// Variable-width integers: s1..s64, u1..u64
if (name.len >= 2 and (name[0] == 's' or name[0] == 'u')) {
const width = std.fmt.parseInt(u8, name[1..], 10) catch return null;
@@ -263,29 +306,16 @@ pub const Type = union(enum) {
/// - Float to wider float (f32 → f64)
/// Everything else requires `xx`.
pub fn isImplicitlyConvertibleTo(self: Type, target: Type) bool {
if (std.meta.eql(self, target)) return true;
// Struct types: compare names by content (not pointer identity)
if (self.isStruct() and target.isStruct()) {
return std.mem.eql(u8, self.struct_type, target.struct_type);
}
// Slice types: compare element names by content (not pointer)
if (self.isSlice() and target.isSlice()) {
return std.mem.eql(u8, self.slice_type.element_name, target.slice_type.element_name);
}
if (self.eql(target)) return true;
// string <-> []u8: same layout, bidirectional implicit conversion
if (self == .string_type and target.isSlice() and
std.mem.eql(u8, target.slice_type.element_name, "u8")) return true;
if (self.isSlice() and std.mem.eql(u8, self.slice_type.element_name, "u8") and
target == .string_type) return true;
// Pointer types: compare pointee names by content, *void is universal (both directions)
// *void is universal pointer (both directions)
if (self.isPointer() and target.isPointer()) {
if (std.mem.eql(u8, self.pointer_type.pointee_name, "void")) return true;
if (std.mem.eql(u8, target.pointer_type.pointee_name, "void")) return true;
return std.mem.eql(u8, self.pointer_type.pointee_name, target.pointer_type.pointee_name);
}
// Many-pointer types: compare element names by content
if (self.isManyPointer() and target.isManyPointer()) {
return std.mem.eql(u8, self.many_pointer_type.element_name, target.many_pointer_type.element_name);
}
// *T → [*]T: pointer to element is implicitly convertible to many-pointer
// null (*void) → [*]T is also allowed
@@ -418,7 +448,7 @@ pub const Type = union(enum) {
/// Used for arithmetic type promotion (e.g., s16 + s32 → s32, int + float → float).
pub fn widen(a: Type, b: Type) Type {
// Same type → return it
if (std.meta.eql(a, b)) return a;
if (a.eql(b)) return a;
// Vector + vector of same dimensions → return a
if (a.isVector() and b.isVector()) return a;