Compile-Time Reflection
@typeof(T)
Returns a TypeInfo compound value at compile time:
@tape fn inspect(T: type) {
var info = @typeof(T);
@println("type: {info.name}, size: {info.size}, align: {info.align}");
}TypeInfo fields:
| Field | Type | Description |
|---|---|---|
name | string | Type name |
kind | int | Type kind (struct, primitive, etc.) |
size | int | Size in bytes |
align | int | Alignment requirement |
fields | array | Array of field descriptors |
Field descriptors
Each element in info.fields is a compound with:
| Field | Type | Description |
|---|---|---|
name | string | Field name |
type | type | Field type (as type value) |
offset | int | Byte offset in struct |
size | int | Field size in bytes |
__attrs | array | Attributes applied to this field |
@tape fn print_fields(T: type) {
var info = @typeof(T);
@println("struct {info.name} (size={info.size}, align={info.align}):");
for (field in info.fields) {
@println(" {field.name} : offset={field.offset}, size={field.size}");
}
}@sizeof(T)
Returns the size in bytes of a type:
@tape { @assert(@sizeof(u64) == 8); }
@tape { @assert(@sizeof(i32) == 4); }@alignof(T)
Returns the alignment requirement of a type:
@tape { @assert(@alignof(f64) == 8); }
@tape { @assert(@alignof(u8) == 1); }@has_field(T, name)
Returns true if the struct type has a field with the given name:
@tape fn maybe_print_name(T: type) {
comptime if (@has_field(T, "name")) {
@emit fn print_name(obj: *${T}) {
io.println(obj.name);
}
}
}@has_method(T, name)
Returns true if a method with the given name exists on the type (checks receiver functions in the current module):
@tape fn gen_print(T: type) {
comptime if (@has_method(T, "to_string")) {
@emit fn print_val(v: *${T}) { io.println(v.to_string()); }
} else {
@emit fn print_val(v: *${T}) { io.println("<opaque>"); }
}
}@field_type(T, name)
Returns the type of a named field as a type value:
@tape fn check_field(T: type) {
var ft = @field_type(T, "id");
comptime match(ft) {
i64 => { @println("id is i64"); }
_ => { @println("id is something else"); }
}
}@field_type returns a comptime type value. It cannot be used directly in type position (e.g., as a return type annotation). Use $ splicing to insert type names into emitted declarations.
@inner_type(T)
@inner_type is parsed but currently always produces an error. It is intended to extract the inner type from pointers, slices, and optionals.@assert
Static assertion — produces a compile error if the condition is false:
@tape { @assert(@sizeof(Header) == 64); }
@tape { @assert(@alignof(Vec4) == 16); }Takes a single boolean expression.
@assert(cond, "message")) is not yet implemented.@compile_error
Abort compilation with a diagnostic message:
@tape fn require_field(T: type, name: string) {
comptime if (!@has_field(T, name)) {
@compile_error("type is missing required field");
}
}@embed(path)
Read a file at compile time into a string value:
@tape {
var shader_src = @embed("shaders/vertex.glsl");
@emit const VERTEX_SHADER = shader_src;
}Path is relative to the source file. Maximum file size: 16 MB.
@print / @println
Compile-time output (prints during compilation, not at runtime):
@tape {
@print("compiling...");
@println("struct size = {info.size}");
}Supports string interpolation with {expr} inside the message. Values of type int, string, bool, and type are printed. Type values print their name.
Attribute reflection
Field descriptors carry their __attrs array, accessible via .has_attr() and .attr():
attr serializable;
attr max_length(n: i64);
@tape fn gen_validate(T: type) {
var info = @typeof(T);
comptime for (field in info.fields) {
comptime if (field.has_attr(serializable)) {
@println(" {field.name} is serializable");
}
}
}| Method | Returns | Description |
|---|---|---|
field.has_attr(attr) | bool | Whether the field has this attribute |
field.attr(attr) | compound | The attribute value (with .value for arguments) |
Array operations in comptime
Comptime arrays (like info.fields) support:
.len— element countarr[i]— index accessfor (elem in arr)— iterationfor (elem, i in arr)— iteration with index
Last modified: