implement union values
This commit is contained in:
parent
30f919d854
commit
985cfb6d06
@ -75,7 +75,7 @@ pub const Enum = struct {
|
|||||||
|
|
||||||
pub const Field = struct {
|
pub const Field = struct {
|
||||||
name: []const u8,
|
name: []const u8,
|
||||||
ty: Index,
|
val: Index,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -126,7 +126,7 @@ pub const Bytes = []const u8;
|
|||||||
pub const Aggregate = []const Index;
|
pub const Aggregate = []const Index;
|
||||||
|
|
||||||
pub const UnionValue = packed struct {
|
pub const UnionValue = packed struct {
|
||||||
tag: Index,
|
field_index: u32,
|
||||||
val: Index,
|
val: Index,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -651,7 +651,6 @@ pub const Key = union(enum) {
|
|||||||
options: std.fmt.FormatOptions,
|
options: std.fmt.FormatOptions,
|
||||||
writer: anytype,
|
writer: anytype,
|
||||||
) @TypeOf(writer).Error!void {
|
) @TypeOf(writer).Error!void {
|
||||||
comptime assert(fmt.len == 0);
|
|
||||||
_ = options;
|
_ = options;
|
||||||
if (fmt.len != 0) std.fmt.invalidFmtError(fmt, Key);
|
if (fmt.len != 0) std.fmt.invalidFmtError(fmt, Key);
|
||||||
return printValue(ctx.value, ctx.ty, ctx.ip, writer);
|
return printValue(ctx.value, ctx.ty, ctx.ip, writer);
|
||||||
@ -747,11 +746,11 @@ pub const Key = union(enum) {
|
|||||||
.union_value => |union_value| {
|
.union_value => |union_value| {
|
||||||
const union_info = ip.indexToKey(ty).union_type;
|
const union_info = ip.indexToKey(ty).union_type;
|
||||||
|
|
||||||
try writer.writeAll(".{ ");
|
try writer.print(".{{ .{} = {} }}", .{
|
||||||
try printValue(ip.indexToKey(union_info.tag_type), union_value.tag, ip, writer);
|
std.zig.fmtId(union_info.fields[union_value.field_index].name),
|
||||||
try writer.writeAll(" = ");
|
// union_value.tag.fmtValue(union_info.tag_type, ip),
|
||||||
try printValue(union_value.val, @panic("TODO"), ip, writer);
|
union_value.val.fmtValue(union_info.fields[union_value.field_index].ty, ip),
|
||||||
try writer.writeAll(" }");
|
});
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2703,28 +2702,64 @@ test "struct type" {
|
|||||||
const field2 = Struct.Field{ .name = "bar", .ty = i32_type };
|
const field2 = Struct.Field{ .name = "bar", .ty = i32_type };
|
||||||
const field3 = Struct.Field{ .name = "baz", .ty = bool_type };
|
const field3 = Struct.Field{ .name = "baz", .ty = bool_type };
|
||||||
|
|
||||||
const struct_type_0 = try ip.get(gpa, Key{
|
const struct_type_0 = try ip.get(gpa, .{ .struct_type = .{
|
||||||
.struct_type = Struct{
|
.fields = &.{ field1, field2, field3 },
|
||||||
.fields = &.{ field1, field2, field3 },
|
.namespace = .none,
|
||||||
.namespace = .none,
|
.layout = .Auto,
|
||||||
.layout = .Auto,
|
.backing_int_ty = .none,
|
||||||
.backing_int_ty = .none,
|
} });
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
_ = try ip.get(gpa, .{ .simple = .unreachable_value });
|
const struct_type_1 = try ip.get(gpa, .{ .struct_type = .{
|
||||||
|
.fields = &.{ field1, field2, field3 },
|
||||||
|
.namespace = .none,
|
||||||
|
.layout = .Auto,
|
||||||
|
.backing_int_ty = .none,
|
||||||
|
} });
|
||||||
|
|
||||||
const struct_type_1 = try ip.get(gpa, Key{
|
|
||||||
.struct_type = Struct{
|
|
||||||
.fields = &.{ field1, field2, field3 },
|
|
||||||
.namespace = .none,
|
|
||||||
.layout = .Auto,
|
|
||||||
.backing_int_ty = .none,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
try std.testing.expect(struct_type_0 == struct_type_1);
|
try std.testing.expect(struct_type_0 == struct_type_1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "enum type" {
|
||||||
|
const gpa = std.testing.allocator;
|
||||||
|
|
||||||
|
var ip: InternPool = .{};
|
||||||
|
defer ip.deinit(gpa);
|
||||||
|
|
||||||
|
const empty_enum1 = try ip.get(gpa, .{ .enum_type = .{
|
||||||
|
.tag_type = .none,
|
||||||
|
.fields = &.{},
|
||||||
|
.namespace = .none,
|
||||||
|
.tag_type_infered = true,
|
||||||
|
} });
|
||||||
|
|
||||||
|
const empty_enum2 = try ip.get(gpa, .{ .enum_type = .{
|
||||||
|
.tag_type = .none,
|
||||||
|
.fields = &.{},
|
||||||
|
.namespace = .none,
|
||||||
|
.tag_type_infered = true,
|
||||||
|
} });
|
||||||
|
|
||||||
|
const field1 = Enum.Field{ .name = "zig", .val = .none };
|
||||||
|
const field2 = Enum.Field{ .name = "cpp", .val = .none };
|
||||||
|
|
||||||
|
const enum1 = try ip.get(gpa, .{ .enum_type = .{
|
||||||
|
.tag_type = .none,
|
||||||
|
.fields = &.{ field1, field2 },
|
||||||
|
.namespace = .none,
|
||||||
|
.tag_type_infered = true,
|
||||||
|
} });
|
||||||
|
const enum2 = try ip.get(gpa, .{ .enum_type = .{
|
||||||
|
.tag_type = .none,
|
||||||
|
.fields = &.{ field2, field1 },
|
||||||
|
.namespace = .none,
|
||||||
|
.tag_type_infered = true,
|
||||||
|
} });
|
||||||
|
|
||||||
|
try std.testing.expect(empty_enum1 == empty_enum2);
|
||||||
|
try std.testing.expect(empty_enum2 != enum1);
|
||||||
|
try std.testing.expect(enum1 != enum2);
|
||||||
|
}
|
||||||
|
|
||||||
test "function type" {
|
test "function type" {
|
||||||
const gpa = std.testing.allocator;
|
const gpa = std.testing.allocator;
|
||||||
|
|
||||||
@ -2771,6 +2806,73 @@ test "function type" {
|
|||||||
try testExpectFmtType(ip, @"fn() align(4) callconv(.C) type", "fn() align(4) callconv(.C) type");
|
try testExpectFmtType(ip, @"fn() align(4) callconv(.C) type", "fn() align(4) callconv(.C) type");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "union type" {
|
||||||
|
const gpa = std.testing.allocator;
|
||||||
|
|
||||||
|
var ip: InternPool = .{};
|
||||||
|
defer ip.deinit(gpa);
|
||||||
|
|
||||||
|
const u32_type = try ip.get(gpa, .{ .int_type = .{ .signedness = .unsigned, .bits = 32 } });
|
||||||
|
const void_type = try ip.get(gpa, .{ .simple = .void });
|
||||||
|
|
||||||
|
var field1 = Union.Field{ .name = "Ok", .ty = u32_type, .alignment = 0 };
|
||||||
|
var field2 = Union.Field{ .name = "Err", .ty = void_type, .alignment = 0 };
|
||||||
|
|
||||||
|
const union_type1 = try ip.get(gpa, .{
|
||||||
|
.union_type = .{
|
||||||
|
.tag_type = .none,
|
||||||
|
.fields = &.{ field1, field2 },
|
||||||
|
.namespace = .none,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const union_type2 = try ip.get(gpa, .{
|
||||||
|
.union_type = .{
|
||||||
|
.tag_type = .none,
|
||||||
|
.fields = &.{ field2, field1 },
|
||||||
|
.namespace = .none,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
try std.testing.expect(union_type1 != union_type2);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "union value" {
|
||||||
|
const gpa = std.testing.allocator;
|
||||||
|
|
||||||
|
var ip: InternPool = .{};
|
||||||
|
defer ip.deinit(gpa);
|
||||||
|
|
||||||
|
const u32_type = try ip.get(gpa, .{ .int_type = .{ .signedness = .unsigned, .bits = 32 } });
|
||||||
|
const f16_type = try ip.get(gpa, .{ .simple = .f16 });
|
||||||
|
|
||||||
|
const int_value = try ip.get(gpa, .{ .int_u64_value = 1 });
|
||||||
|
const f16_value = try ip.get(gpa, .{ .float_16_value = 0.25 });
|
||||||
|
|
||||||
|
var field1 = Union.Field{ .name = "int", .ty = u32_type, .alignment = 0 };
|
||||||
|
var field2 = Union.Field{ .name = "float", .ty = f16_type, .alignment = 0 };
|
||||||
|
|
||||||
|
const union_type = try ip.get(gpa, .{
|
||||||
|
.union_type = .{
|
||||||
|
.tag_type = .none,
|
||||||
|
.fields = &.{ field1, field2 },
|
||||||
|
.namespace = .none,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const union_value1 = try ip.get(gpa, .{ .union_value = .{
|
||||||
|
.field_index = 0,
|
||||||
|
.val = int_value,
|
||||||
|
} });
|
||||||
|
const union_value2 = try ip.get(gpa, .{ .union_value = .{
|
||||||
|
.field_index = 1,
|
||||||
|
.val = f16_value,
|
||||||
|
} });
|
||||||
|
|
||||||
|
try testExpectFmtValue(ip, union_value1, union_type, ".{ .int = 1 }");
|
||||||
|
try testExpectFmtValue(ip, union_value2, union_type, ".{ .float = 0.25 }");
|
||||||
|
}
|
||||||
|
|
||||||
test "anyframe type" {
|
test "anyframe type" {
|
||||||
const gpa = std.testing.allocator;
|
const gpa = std.testing.allocator;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user