comptime VM: Phase 3 — type_kind + type_field_value readers (read side complete)
The last two read-only readers the metatype's type_info(T) needs, each backed by
a TypeTable query both the legacy handler and the VM call (no drift):
type_kind(t: TypeId) -> i64 (kindCode; stable discriminant, total — never bails)
type_field_value(t: TypeId, idx) -> i64 (memberValue; enum explicit value or ordinal)
kindCode codes (compiler-owned, stable): 0 other / 1 struct / 2 enum /
3 tagged_union / 4 tuple / 5 union / 6 array / 7 vector / 8 error_set.
With these, the READ side is complete: find_type + type_kind + type_field_count +
type_field_{name,type} + type_nominal_name + type_field_value cover everything
reflectTypeInfo reads — a comptime sx fn can fully reflect a struct/enum/tuple
into data with no #builtin.
Example 0630 reflects Color / WindowFlags(flags) / Point. VM unit test added.
Revised forward direction: the write side will be ONE register_type(info) fn that
branches on the kind in the compiler (subsuming define's per-kind dispatch), not a
per-kind register_struct.
Parity 691/691 (gate OFF and -Dcomptime-flat).
This commit is contained in:
@@ -554,6 +554,46 @@ pub const TypeTable = struct {
|
||||
};
|
||||
}
|
||||
|
||||
/// Stable kind discriminant of a type, for comptime reflection branching.
|
||||
/// TOTAL (never fails): an unnamed / non-aggregate type or an out-of-range id
|
||||
/// is `other` (0). Codes are compiler-owned and stable — NOT tied to any sx
|
||||
/// enum's declaration order; the sx side maps them. Backs the `type_kind`
|
||||
/// reader. (A `tagged_union` is a payload-carrying enum; the sx metatype folds
|
||||
/// codes 2 and 3 onto its single `.enum` TypeInfo variant.)
|
||||
/// 0 other · 1 struct · 2 enum · 3 tagged_union · 4 tuple
|
||||
/// 5 union · 6 array · 7 vector · 8 error_set
|
||||
pub fn kindCode(self: *const TypeTable, id: TypeId) i64 {
|
||||
if (id.index() >= self.infos.items.len) return 0;
|
||||
return switch (self.get(id)) {
|
||||
.@"struct" => 1,
|
||||
.@"enum" => 2,
|
||||
.tagged_union => 3,
|
||||
.tuple => 4,
|
||||
.@"union" => 5,
|
||||
.array => 6,
|
||||
.vector => 7,
|
||||
.error_set => 8,
|
||||
else => 0,
|
||||
};
|
||||
}
|
||||
|
||||
/// Integer value of enum variant `idx`: its explicit value when the enum
|
||||
/// declares one (custom values or flags), else its ordinal. Null for a
|
||||
/// non-enum type, a negative / out-of-range `idx`, or an out-of-range id.
|
||||
/// Backs the `type_field_value` reader (mirrors the `field_value_int` builtin).
|
||||
pub fn memberValue(self: *const TypeTable, id: TypeId, idx: i64) ?i64 {
|
||||
if (idx < 0 or id.index() >= self.infos.items.len) return null;
|
||||
const i: usize = @intCast(idx);
|
||||
return switch (self.get(id)) {
|
||||
.@"enum" => |e| blk: {
|
||||
if (i >= e.variants.len) break :blk null;
|
||||
if (e.explicit_values) |vals| if (i < vals.len) break :blk vals[i];
|
||||
break :blk @intCast(i); // ordinal default
|
||||
},
|
||||
else => null,
|
||||
};
|
||||
}
|
||||
|
||||
/// Source-sensitive variant of `findByName`: asserts at most one named type
|
||||
/// matches, then returns it (or null). Quarantines the global first-match
|
||||
/// scan — new resolver code that must not silently pick a first-of-many
|
||||
|
||||
Reference in New Issue
Block a user