comptime VM: Phase 3 — field-level reflection readers
Three more read-only compiler-API readers on the TypeId-handle shape, each backed
by a new TypeTable query that both the legacy handler and the VM call (no drift):
type_nominal_name(t: TypeId) -> StringId (nominalName; loud-bail for unnamed types)
type_field_name(t: TypeId, idx: i64) -> StringId (memberName)
type_field_type(t: TypeId, idx: i64) -> TypeId (memberType)
All loud-bail on out-of-range idx / no-member — no silent default. First multi-arg
compiler fns (callCompilerFn now reads arg 1 = idx); added Vm.argHandle/argTypeId
range-checked arg readers and moved find_type/type_field_count onto them. Names use
the type_* family to avoid colliding with the std metatype builtins (field_name /
type_name in core.sx); the new TypeTable.nominalName is distinct from the existing
typeName(id) display-string renderer.
Example 0629 reflects Pair { lo: Point; hi: Point } — each field name + the nominal
name of a field's type, #run-folded, VM-HANDLED natively. VM unit test added.
Parity 690/690 (gate OFF and -Dcomptime-flat).
This commit is contained in:
@@ -500,6 +500,60 @@ pub const TypeTable = struct {
|
||||
};
|
||||
}
|
||||
|
||||
/// Nominal name of a named type (struct / union / tagged-union / enum /
|
||||
/// error-set / protocol), or null for an unnamed type (scalar, pointer,
|
||||
/// slice, …) or an out-of-range id. Backs the `type_nominal_name` comptime
|
||||
/// compiler-API reader (legacy handler + VM both call it — no drift).
|
||||
/// (Distinct from `typeName` below, which renders a display string for any
|
||||
/// type; this returns the interned nominal-name handle for NAMED types only.)
|
||||
pub fn nominalName(self: *const TypeTable, id: TypeId) ?StringId {
|
||||
if (id.index() >= self.infos.items.len) return null;
|
||||
return switch (self.get(id)) {
|
||||
.@"struct" => |s| s.name,
|
||||
.@"union" => |u| u.name,
|
||||
.tagged_union => |u| u.name,
|
||||
.@"enum" => |e| e.name,
|
||||
.error_set => |e| e.name,
|
||||
.protocol => |p| p.name,
|
||||
else => null,
|
||||
};
|
||||
}
|
||||
|
||||
/// Name of member `idx` of an aggregate: a struct/union/tagged-union field
|
||||
/// name, an enum variant name, or a named-tuple element name. Null for a
|
||||
/// negative / out-of-range `idx`, an unnamed tuple element, or a type with no
|
||||
/// named members. Backs the `type_field_name` reader.
|
||||
pub fn memberName(self: *const TypeTable, id: TypeId, idx: i64) ?StringId {
|
||||
if (idx < 0 or id.index() >= self.infos.items.len) return null;
|
||||
const i: usize = @intCast(idx);
|
||||
return switch (self.get(id)) {
|
||||
.@"struct" => |s| if (i < s.fields.len) s.fields[i].name else null,
|
||||
.@"union" => |u| if (i < u.fields.len) u.fields[i].name else null,
|
||||
.tagged_union => |u| if (i < u.fields.len) u.fields[i].name else null,
|
||||
.@"enum" => |e| if (i < e.variants.len) e.variants[i] else null,
|
||||
.tuple => |t| if (t.names) |ns| (if (i < ns.len) ns[i] else null) else null,
|
||||
else => null,
|
||||
};
|
||||
}
|
||||
|
||||
/// Type of member `idx` of an aggregate: a struct/union/tagged-union field
|
||||
/// type, a tuple element type, or an array/vector element type. Null for a
|
||||
/// negative / out-of-range `idx` or a type with no member types (e.g. a
|
||||
/// payloadless enum). Backs the `type_field_type` reader.
|
||||
pub fn memberType(self: *const TypeTable, id: TypeId, idx: i64) ?TypeId {
|
||||
if (idx < 0 or id.index() >= self.infos.items.len) return null;
|
||||
const i: usize = @intCast(idx);
|
||||
return switch (self.get(id)) {
|
||||
.@"struct" => |s| if (i < s.fields.len) s.fields[i].ty else null,
|
||||
.@"union" => |u| if (i < u.fields.len) u.fields[i].ty else null,
|
||||
.tagged_union => |u| if (i < u.fields.len) u.fields[i].ty else null,
|
||||
.tuple => |t| if (i < t.fields.len) t.fields[i] else null,
|
||||
.array => |a| if (i < a.length) a.element else null,
|
||||
.vector => |v| if (i < v.length) v.element else null,
|
||||
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