diff options
Diffstat (limited to 'src/value.zig')
| -rw-r--r-- | src/value.zig | 837 |
1 files changed, 57 insertions, 780 deletions
diff --git a/src/value.zig b/src/value.zig index 4170b005bf..66a23692c1 100644 --- a/src/value.zig +++ b/src/value.zig @@ -103,6 +103,8 @@ pub const Value = extern union { float_64, float_128, enum_literal, + /// A specific enum tag, indicated by the field index (declaration order). + enum_field_index, @"error", error_union, /// This is a special value that tracks a set of types that have been stored @@ -186,6 +188,8 @@ pub const Value = extern union { .enum_literal, => Payload.Bytes, + .enum_field_index => Payload.U32, + .ty => Payload.Ty, .int_type => Payload.IntType, .int_u64 => Payload.U64, @@ -394,6 +398,7 @@ pub const Value = extern union { }; return Value{ .ptr_otherwise = &new_payload.base }; }, + .enum_field_index => return self.copyPayloadShallow(allocator, Payload.U32), .@"error" => return self.copyPayloadShallow(allocator, Payload.Error), .error_union => { const payload = self.castTag(.error_union).?; @@ -416,6 +421,8 @@ pub const Value = extern union { return Value{ .ptr_otherwise = &new_payload.base }; } + /// TODO this should become a debug dump() function. In order to print values in a meaningful way + /// we also need access to the type. pub fn format( self: Value, comptime fmt: []const u8, @@ -506,6 +513,7 @@ pub const Value = extern union { }, .empty_array => return out_stream.writeAll(".{}"), .enum_literal => return out_stream.print(".{}", .{std.zig.fmtId(self.castTag(.enum_literal).?.data)}), + .enum_field_index => return out_stream.print("(enum field {d})", .{self.castTag(.enum_field_index).?.data}), .bytes => return out_stream.print("\"{}\"", .{std.zig.fmtEscapes(self.castTag(.bytes).?.data)}), .repeated => { try out_stream.writeAll("(repeated) "); @@ -626,6 +634,7 @@ pub const Value = extern union { .float_64, .float_128, .enum_literal, + .enum_field_index, .@"error", .error_union, .empty_struct_value, @@ -638,76 +647,6 @@ pub const Value = extern union { /// Asserts the value is an integer. pub fn toBigInt(self: Value, space: *BigIntSpace) BigIntConst { switch (self.tag()) { - .ty, - .int_type, - .u8_type, - .i8_type, - .u16_type, - .i16_type, - .u32_type, - .i32_type, - .u64_type, - .i64_type, - .u128_type, - .i128_type, - .usize_type, - .isize_type, - .c_short_type, - .c_ushort_type, - .c_int_type, - .c_uint_type, - .c_long_type, - .c_ulong_type, - .c_longlong_type, - .c_ulonglong_type, - .c_longdouble_type, - .f16_type, - .f32_type, - .f64_type, - .f128_type, - .c_void_type, - .bool_type, - .void_type, - .type_type, - .anyerror_type, - .comptime_int_type, - .comptime_float_type, - .noreturn_type, - .null_type, - .undefined_type, - .fn_noreturn_no_args_type, - .fn_void_no_args_type, - .fn_naked_noreturn_no_args_type, - .fn_ccc_void_no_args_type, - .single_const_pointer_to_comptime_int_type, - .const_slice_u8_type, - .enum_literal_type, - .null_value, - .function, - .extern_fn, - .variable, - .ref_val, - .decl_ref, - .elem_ptr, - .bytes, - .repeated, - .float_16, - .float_32, - .float_64, - .float_128, - .void_value, - .unreachable_value, - .empty_array, - .enum_literal, - .error_union, - .@"error", - .empty_struct_value, - .inferred_alloc, - .abi_align_default, - => unreachable, - - .undef => unreachable, - .zero, .bool_false, => return BigIntMutable.init(&space.limbs, 0).toConst(), @@ -720,82 +659,15 @@ pub const Value = extern union { .int_i64 => return BigIntMutable.init(&space.limbs, self.castTag(.int_i64).?.data).toConst(), .int_big_positive => return self.castTag(.int_big_positive).?.asBigInt(), .int_big_negative => return self.castTag(.int_big_negative).?.asBigInt(), + + .undef => unreachable, + else => unreachable, } } /// Asserts the value is an integer and it fits in a u64 pub fn toUnsignedInt(self: Value) u64 { switch (self.tag()) { - .ty, - .int_type, - .u8_type, - .i8_type, - .u16_type, - .i16_type, - .u32_type, - .i32_type, - .u64_type, - .i64_type, - .u128_type, - .i128_type, - .usize_type, - .isize_type, - .c_short_type, - .c_ushort_type, - .c_int_type, - .c_uint_type, - .c_long_type, - .c_ulong_type, - .c_longlong_type, - .c_ulonglong_type, - .c_longdouble_type, - .f16_type, - .f32_type, - .f64_type, - .f128_type, - .c_void_type, - .bool_type, - .void_type, - .type_type, - .anyerror_type, - .comptime_int_type, - .comptime_float_type, - .noreturn_type, - .null_type, - .undefined_type, - .fn_noreturn_no_args_type, - .fn_void_no_args_type, - .fn_naked_noreturn_no_args_type, - .fn_ccc_void_no_args_type, - .single_const_pointer_to_comptime_int_type, - .const_slice_u8_type, - .enum_literal_type, - .null_value, - .function, - .extern_fn, - .variable, - .ref_val, - .decl_ref, - .elem_ptr, - .bytes, - .repeated, - .float_16, - .float_32, - .float_64, - .float_128, - .void_value, - .unreachable_value, - .empty_array, - .enum_literal, - .@"error", - .error_union, - .empty_struct_value, - .inferred_alloc, - .abi_align_default, - => unreachable, - - .undef => unreachable, - .zero, .bool_false, => return 0, @@ -808,82 +680,15 @@ pub const Value = extern union { .int_i64 => return @intCast(u64, self.castTag(.int_i64).?.data), .int_big_positive => return self.castTag(.int_big_positive).?.asBigInt().to(u64) catch unreachable, .int_big_negative => return self.castTag(.int_big_negative).?.asBigInt().to(u64) catch unreachable, + + .undef => unreachable, + else => unreachable, } } /// Asserts the value is an integer and it fits in a i64 pub fn toSignedInt(self: Value) i64 { switch (self.tag()) { - .ty, - .int_type, - .u8_type, - .i8_type, - .u16_type, - .i16_type, - .u32_type, - .i32_type, - .u64_type, - .i64_type, - .u128_type, - .i128_type, - .usize_type, - .isize_type, - .c_short_type, - .c_ushort_type, - .c_int_type, - .c_uint_type, - .c_long_type, - .c_ulong_type, - .c_longlong_type, - .c_ulonglong_type, - .c_longdouble_type, - .f16_type, - .f32_type, - .f64_type, - .f128_type, - .c_void_type, - .bool_type, - .void_type, - .type_type, - .anyerror_type, - .comptime_int_type, - .comptime_float_type, - .noreturn_type, - .null_type, - .undefined_type, - .fn_noreturn_no_args_type, - .fn_void_no_args_type, - .fn_naked_noreturn_no_args_type, - .fn_ccc_void_no_args_type, - .single_const_pointer_to_comptime_int_type, - .const_slice_u8_type, - .enum_literal_type, - .null_value, - .function, - .extern_fn, - .variable, - .ref_val, - .decl_ref, - .elem_ptr, - .bytes, - .repeated, - .float_16, - .float_32, - .float_64, - .float_128, - .void_value, - .unreachable_value, - .empty_array, - .enum_literal, - .@"error", - .error_union, - .empty_struct_value, - .inferred_alloc, - .abi_align_default, - => unreachable, - - .undef => unreachable, - .zero, .bool_false, => return 0, @@ -896,6 +701,9 @@ pub const Value = extern union { .int_i64 => return self.castTag(.int_i64).?.data, .int_big_positive => return self.castTag(.int_big_positive).?.asBigInt().to(i64) catch unreachable, .int_big_negative => return self.castTag(.int_big_negative).?.asBigInt().to(i64) catch unreachable, + + .undef => unreachable, + else => unreachable, } } @@ -929,75 +737,6 @@ pub const Value = extern union { /// Returns the number of bits the value requires to represent stored in twos complement form. pub fn intBitCountTwosComp(self: Value) usize { switch (self.tag()) { - .ty, - .int_type, - .u8_type, - .i8_type, - .u16_type, - .i16_type, - .u32_type, - .i32_type, - .u64_type, - .i64_type, - .u128_type, - .i128_type, - .usize_type, - .isize_type, - .c_short_type, - .c_ushort_type, - .c_int_type, - .c_uint_type, - .c_long_type, - .c_ulong_type, - .c_longlong_type, - .c_ulonglong_type, - .c_longdouble_type, - .f16_type, - .f32_type, - .f64_type, - .f128_type, - .c_void_type, - .bool_type, - .void_type, - .type_type, - .anyerror_type, - .comptime_int_type, - .comptime_float_type, - .noreturn_type, - .null_type, - .undefined_type, - .fn_noreturn_no_args_type, - .fn_void_no_args_type, - .fn_naked_noreturn_no_args_type, - .fn_ccc_void_no_args_type, - .single_const_pointer_to_comptime_int_type, - .const_slice_u8_type, - .enum_literal_type, - .null_value, - .function, - .extern_fn, - .variable, - .ref_val, - .decl_ref, - .elem_ptr, - .bytes, - .undef, - .repeated, - .float_16, - .float_32, - .float_64, - .float_128, - .void_value, - .unreachable_value, - .empty_array, - .enum_literal, - .@"error", - .error_union, - .empty_struct_value, - .inferred_alloc, - .abi_align_default, - => unreachable, - .zero, .bool_false, => return 0, @@ -1016,80 +755,14 @@ pub const Value = extern union { }, .int_big_positive => return self.castTag(.int_big_positive).?.asBigInt().bitCountTwosComp(), .int_big_negative => return self.castTag(.int_big_negative).?.asBigInt().bitCountTwosComp(), + + else => unreachable, } } /// Asserts the value is an integer, and the destination type is ComptimeInt or Int. pub fn intFitsInType(self: Value, ty: Type, target: Target) bool { switch (self.tag()) { - .ty, - .int_type, - .u8_type, - .i8_type, - .u16_type, - .i16_type, - .u32_type, - .i32_type, - .u64_type, - .i64_type, - .u128_type, - .i128_type, - .usize_type, - .isize_type, - .c_short_type, - .c_ushort_type, - .c_int_type, - .c_uint_type, - .c_long_type, - .c_ulong_type, - .c_longlong_type, - .c_ulonglong_type, - .c_longdouble_type, - .f16_type, - .f32_type, - .f64_type, - .f128_type, - .c_void_type, - .bool_type, - .void_type, - .type_type, - .anyerror_type, - .comptime_int_type, - .comptime_float_type, - .noreturn_type, - .null_type, - .undefined_type, - .fn_noreturn_no_args_type, - .fn_void_no_args_type, - .fn_naked_noreturn_no_args_type, - .fn_ccc_void_no_args_type, - .single_const_pointer_to_comptime_int_type, - .const_slice_u8_type, - .enum_literal_type, - .null_value, - .function, - .extern_fn, - .variable, - .ref_val, - .decl_ref, - .elem_ptr, - .bytes, - .repeated, - .float_16, - .float_32, - .float_64, - .float_128, - .void_value, - .unreachable_value, - .empty_array, - .enum_literal, - .@"error", - .error_union, - .empty_struct_value, - .inferred_alloc, - .abi_align_default, - => unreachable, - .zero, .undef, .bool_false, @@ -1144,6 +817,8 @@ pub const Value = extern union { .ComptimeInt => return true, else => unreachable, }, + + else => unreachable, } } @@ -1180,77 +855,6 @@ pub const Value = extern union { /// Asserts the value is a float pub fn floatHasFraction(self: Value) bool { return switch (self.tag()) { - .ty, - .int_type, - .u8_type, - .i8_type, - .u16_type, - .i16_type, - .u32_type, - .i32_type, - .u64_type, - .i64_type, - .u128_type, - .i128_type, - .usize_type, - .isize_type, - .c_short_type, - .c_ushort_type, - .c_int_type, - .c_uint_type, - .c_long_type, - .c_ulong_type, - .c_longlong_type, - .c_ulonglong_type, - .c_longdouble_type, - .f16_type, - .f32_type, - .f64_type, - .f128_type, - .c_void_type, - .bool_type, - .void_type, - .type_type, - .anyerror_type, - .comptime_int_type, - .comptime_float_type, - .noreturn_type, - .null_type, - .undefined_type, - .fn_noreturn_no_args_type, - .fn_void_no_args_type, - .fn_naked_noreturn_no_args_type, - .fn_ccc_void_no_args_type, - .single_const_pointer_to_comptime_int_type, - .const_slice_u8_type, - .enum_literal_type, - .bool_true, - .bool_false, - .null_value, - .function, - .extern_fn, - .variable, - .ref_val, - .decl_ref, - .elem_ptr, - .bytes, - .repeated, - .undef, - .int_u64, - .int_i64, - .int_big_positive, - .int_big_negative, - .empty_array, - .void_value, - .unreachable_value, - .enum_literal, - .@"error", - .error_union, - .empty_struct_value, - .inferred_alloc, - .abi_align_default, - => unreachable, - .zero, .one, => false, @@ -1260,76 +864,13 @@ pub const Value = extern union { .float_64 => @rem(self.castTag(.float_64).?.data, 1) != 0, // .float_128 => @rem(self.castTag(.float_128).?.data, 1) != 0, .float_128 => @panic("TODO lld: error: undefined symbol: fmodl"), + + else => unreachable, }; } pub fn orderAgainstZero(lhs: Value) std.math.Order { return switch (lhs.tag()) { - .ty, - .int_type, - .u8_type, - .i8_type, - .u16_type, - .i16_type, - .u32_type, - .i32_type, - .u64_type, - .i64_type, - .u128_type, - .i128_type, - .usize_type, - .isize_type, - .c_short_type, - .c_ushort_type, - .c_int_type, - .c_uint_type, - .c_long_type, - .c_ulong_type, - .c_longlong_type, - .c_ulonglong_type, - .c_longdouble_type, - .f16_type, - .f32_type, - .f64_type, - .f128_type, - .c_void_type, - .bool_type, - .void_type, - .type_type, - .anyerror_type, - .comptime_int_type, - .comptime_float_type, - .noreturn_type, - .null_type, - .undefined_type, - .fn_noreturn_no_args_type, - .fn_void_no_args_type, - .fn_naked_noreturn_no_args_type, - .fn_ccc_void_no_args_type, - .single_const_pointer_to_comptime_int_type, - .const_slice_u8_type, - .enum_literal_type, - .null_value, - .function, - .extern_fn, - .variable, - .ref_val, - .decl_ref, - .elem_ptr, - .bytes, - .repeated, - .undef, - .void_value, - .unreachable_value, - .empty_array, - .enum_literal, - .@"error", - .error_union, - .empty_struct_value, - .inferred_alloc, - .abi_align_default, - => unreachable, - .zero, .bool_false, => .eq, @@ -1347,6 +888,8 @@ pub const Value = extern union { .float_32 => std.math.order(lhs.castTag(.float_32).?.data, 0), .float_64 => std.math.order(lhs.castTag(.float_64).?.data, 0), .float_128 => std.math.order(lhs.castTag(.float_128).?.data, 0), + + else => unreachable, }; } @@ -1396,10 +939,12 @@ pub const Value = extern union { } pub fn eql(a: Value, b: Value) bool { - if (a.tag() == b.tag()) { - if (a.tag() == .void_value or a.tag() == .null_value) { + const a_tag = a.tag(); + const b_tag = b.tag(); + if (a_tag == b_tag) { + if (a_tag == .void_value or a_tag == .null_value) { return true; - } else if (a.tag() == .enum_literal) { + } else if (a_tag == .enum_literal) { const a_name = a.castTag(.enum_literal).?.data; const b_name = b.castTag(.enum_literal).?.data; return std.mem.eql(u8, a_name, b_name); @@ -1416,6 +961,10 @@ pub const Value = extern union { return compare(a, .eq, b); } + pub fn hash_u32(self: Value) u32 { + return @truncate(u32, self.hash()); + } + pub fn hash(self: Value) u64 { var hasher = std.hash.Wyhash.init(0); @@ -1493,11 +1042,18 @@ pub const Value = extern union { .zero, .bool_false => std.hash.autoHash(&hasher, @as(u64, 0)), .one, .bool_true => std.hash.autoHash(&hasher, @as(u64, 1)), - .float_16, .float_32, .float_64, .float_128 => {}, + .float_16, .float_32, .float_64, .float_128 => { + @panic("TODO implement Value.hash for floats"); + }, + .enum_literal => { const payload = self.castTag(.enum_literal).?; hasher.update(payload.data); }, + .enum_field_index => { + const payload = self.castTag(.enum_field_index).?; + std.hash.autoHash(&hasher, payload.data); + }, .bytes => { const payload = self.castTag(.bytes).?; hasher.update(payload.data); @@ -1573,80 +1129,6 @@ pub const Value = extern union { /// Returns error.AnalysisFail if the pointer points to a Decl that failed semantic analysis. pub fn pointerDeref(self: Value, allocator: *Allocator) error{ AnalysisFail, OutOfMemory }!Value { return switch (self.tag()) { - .ty, - .int_type, - .u8_type, - .i8_type, - .u16_type, - .i16_type, - .u32_type, - .i32_type, - .u64_type, - .i64_type, - .u128_type, - .i128_type, - .usize_type, - .isize_type, - .c_short_type, - .c_ushort_type, - .c_int_type, - .c_uint_type, - .c_long_type, - .c_ulong_type, - .c_longlong_type, - .c_ulonglong_type, - .c_longdouble_type, - .f16_type, - .f32_type, - .f64_type, - .f128_type, - .c_void_type, - .bool_type, - .void_type, - .type_type, - .anyerror_type, - .comptime_int_type, - .comptime_float_type, - .noreturn_type, - .null_type, - .undefined_type, - .fn_noreturn_no_args_type, - .fn_void_no_args_type, - .fn_naked_noreturn_no_args_type, - .fn_ccc_void_no_args_type, - .single_const_pointer_to_comptime_int_type, - .const_slice_u8_type, - .enum_literal_type, - .zero, - .one, - .bool_true, - .bool_false, - .null_value, - .function, - .extern_fn, - .variable, - .int_u64, - .int_i64, - .int_big_positive, - .int_big_negative, - .bytes, - .undef, - .repeated, - .float_16, - .float_32, - .float_64, - .float_128, - .void_value, - .unreachable_value, - .empty_array, - .enum_literal, - .@"error", - .error_union, - .empty_struct_value, - .inferred_alloc, - .abi_align_default, - => unreachable, - .ref_val => self.castTag(.ref_val).?.data, .decl_ref => self.castTag(.decl_ref).?.data.value(), .elem_ptr => { @@ -1654,6 +1136,8 @@ pub const Value = extern union { const array_val = try elem_ptr.array_ptr.pointerDeref(allocator); return array_val.elemValue(allocator, elem_ptr.index); }, + + else => unreachable, }; } @@ -1661,86 +1145,14 @@ pub const Value = extern union { /// or an unknown-length pointer, and returns the element value at the index. pub fn elemValue(self: Value, allocator: *Allocator, index: usize) error{OutOfMemory}!Value { switch (self.tag()) { - .ty, - .int_type, - .u8_type, - .i8_type, - .u16_type, - .i16_type, - .u32_type, - .i32_type, - .u64_type, - .i64_type, - .u128_type, - .i128_type, - .usize_type, - .isize_type, - .c_short_type, - .c_ushort_type, - .c_int_type, - .c_uint_type, - .c_long_type, - .c_ulong_type, - .c_longlong_type, - .c_ulonglong_type, - .c_longdouble_type, - .f16_type, - .f32_type, - .f64_type, - .f128_type, - .c_void_type, - .bool_type, - .void_type, - .type_type, - .anyerror_type, - .comptime_int_type, - .comptime_float_type, - .noreturn_type, - .null_type, - .undefined_type, - .fn_noreturn_no_args_type, - .fn_void_no_args_type, - .fn_naked_noreturn_no_args_type, - .fn_ccc_void_no_args_type, - .single_const_pointer_to_comptime_int_type, - .const_slice_u8_type, - .enum_literal_type, - .zero, - .one, - .bool_true, - .bool_false, - .null_value, - .function, - .extern_fn, - .variable, - .int_u64, - .int_i64, - .int_big_positive, - .int_big_negative, - .undef, - .elem_ptr, - .ref_val, - .decl_ref, - .float_16, - .float_32, - .float_64, - .float_128, - .void_value, - .unreachable_value, - .enum_literal, - .@"error", - .error_union, - .empty_struct_value, - .inferred_alloc, - .abi_align_default, - => unreachable, - .empty_array => unreachable, // out of bounds array index .bytes => return Tag.int_u64.create(allocator, self.castTag(.bytes).?.data[index]), // No matter the index; all the elements are the same! .repeated => return self.castTag(.repeated).?.data, + + else => unreachable, } } @@ -1766,161 +1178,18 @@ pub const Value = extern union { /// Valid for all types. Asserts the value is not undefined and not unreachable. pub fn isNull(self: Value) bool { return switch (self.tag()) { - .ty, - .int_type, - .u8_type, - .i8_type, - .u16_type, - .i16_type, - .u32_type, - .i32_type, - .u64_type, - .i64_type, - .u128_type, - .i128_type, - .usize_type, - .isize_type, - .c_short_type, - .c_ushort_type, - .c_int_type, - .c_uint_type, - .c_long_type, - .c_ulong_type, - .c_longlong_type, - .c_ulonglong_type, - .c_longdouble_type, - .f16_type, - .f32_type, - .f64_type, - .f128_type, - .c_void_type, - .bool_type, - .void_type, - .type_type, - .anyerror_type, - .comptime_int_type, - .comptime_float_type, - .noreturn_type, - .null_type, - .undefined_type, - .fn_noreturn_no_args_type, - .fn_void_no_args_type, - .fn_naked_noreturn_no_args_type, - .fn_ccc_void_no_args_type, - .single_const_pointer_to_comptime_int_type, - .const_slice_u8_type, - .enum_literal_type, - .zero, - .one, - .empty_array, - .bool_true, - .bool_false, - .function, - .extern_fn, - .variable, - .int_u64, - .int_i64, - .int_big_positive, - .int_big_negative, - .ref_val, - .decl_ref, - .elem_ptr, - .bytes, - .repeated, - .float_16, - .float_32, - .float_64, - .float_128, - .void_value, - .enum_literal, - .@"error", - .error_union, - .empty_struct_value, - .abi_align_default, - => false, - .undef => unreachable, .unreachable_value => unreachable, .inferred_alloc => unreachable, .null_value => true, + + else => false, }; } /// Valid for all types. Asserts the value is not undefined and not unreachable. pub fn getError(self: Value) ?[]const u8 { return switch (self.tag()) { - .ty, - .int_type, - .u8_type, - .i8_type, - .u16_type, - .i16_type, - .u32_type, - .i32_type, - .u64_type, - .i64_type, - .u128_type, - .i128_type, - .usize_type, - .isize_type, - .c_short_type, - .c_ushort_type, - .c_int_type, - .c_uint_type, - .c_long_type, - .c_ulong_type, - .c_longlong_type, - .c_ulonglong_type, - .c_longdouble_type, - .f16_type, - .f32_type, - .f64_type, - .f128_type, - .c_void_type, - .bool_type, - .void_type, - .type_type, - .anyerror_type, - .comptime_int_type, - .comptime_float_type, - .noreturn_type, - .null_type, - .undefined_type, - .fn_noreturn_no_args_type, - .fn_void_no_args_type, - .fn_naked_noreturn_no_args_type, - .fn_ccc_void_no_args_type, - .single_const_pointer_to_comptime_int_type, - .const_slice_u8_type, - .enum_literal_type, - .zero, - .one, - .null_value, - .empty_array, - .bool_true, - .bool_false, - .function, - .extern_fn, - .variable, - .int_u64, - .int_i64, - .int_big_positive, - .int_big_negative, - .ref_val, - .decl_ref, - .elem_ptr, - .bytes, - .repeated, - .float_16, - .float_32, - .float_64, - .float_128, - .void_value, - .enum_literal, - .empty_struct_value, - .abi_align_default, - => null, - .error_union => { const data = self.castTag(.error_union).?.data; return if (data.tag() == .@"error") @@ -1932,6 +1201,8 @@ pub const Value = extern union { .undef => unreachable, .unreachable_value => unreachable, .inferred_alloc => unreachable, + + else => null, }; } /// Valid for all types. Asserts the value is not undefined. @@ -2021,6 +1292,7 @@ pub const Value = extern union { .float_128, .void_value, .enum_literal, + .enum_field_index, .@"error", .error_union, .empty_struct_value, @@ -2038,6 +1310,11 @@ pub const Value = extern union { pub const Payload = struct { tag: Tag, + pub const U32 = struct { + base: Payload, + data: u32, + }; + pub const U64 = struct { base: Payload, data: u64, |
