@embed & Static Data

@embed

Read a file at compile time into a compile-time string:

tape
@tape {
    var shader = @embed("shaders/blur.glsl");
    @println("shader length: {shader.len}");
}

@embed is a comptime intrinsic — it runs only inside @tape {} blocks. The file path is relative to the working directory. Maximum file size: 16 MB.

The result is a []const u8 stored in rodata. It can be:

  • Used as runtime data (shaders, fonts, icons baked into the binary)
  • Printed with @print / @println at compile time
  • Compared or manipulated in comptime logic
  • Used as input to other comptime operations

Deduplication

Multiple @embed calls with the same file path — even across different modules — produce references to a single rodata entry. The file is read once and stored once in the binary.

tape
// module_a.tape
@tape const ICON = @embed("assets/logo.png");

// module_b.tape
@tape const LOGO = @embed("assets/logo.png");

// Same rodata entry — binary contains one copy

Deduplication is by canonical file path, not by content. Two different files with identical bytes get separate rodata entries (content comparison adds complexity for negligible gain).

@tape const (expression form)

Declare a constant with a compile-time evaluated expression:

tape
@tape const SIZE: i64 = 16 * 16;
@tape const MASK: i64 = 0xFF;
@tape const MAX_ITEMS: i64 = 1024;

The init expression is available to both comptime (@tape blocks can reference the constant) and runtime code (the expression is lowered normally).

@tape const (block form)

Compute a constant value with arbitrary comptime logic:

tape
@tape const TABLE: i64 = {
    var sum: i64 = 0;
    var i: i64 = 0;
    while (i < 10) {
        sum = sum + i;
        i = i + 1;
    }
    return sum;
};

The block runs at compile time. The returned value becomes a compile-time constant, accessible in both comptime scope and runtime code.

@emit const

To generate runtime constants from comptime evaluation, use @emit const inside a @tape {} block:

tape
@tape fn sizes(T: type) {
    @emit const SIZE_${T} = @sizeof(T);
    @emit const ALIGN_${T} = @alignof(T);
}

@tape { sizes(Point); }
// generates: const SIZE_Point = 24; const ALIGN_Point = 8;

@emit const evaluates the initializer at comptime and replaces it with a literal (integer or bool). The resulting constant is usable at runtime.

Static assertions

Verify invariants at compile time:

tape
@tape { @assert(@sizeof(Packet) == 64); }
@tape { @assert(@sizeof(u64) == 8); }

Use cases

PatternHow
Compile-time computed sizes@emit const SIZE_X = @sizeof(T);
Static assertions@tape { @assert(...); }
Conditional code generationcomptime if / comptime match with @emit
Compile-time string processing@embed + @println for build-time diagnostics
Computed lookup tables@tape const TABLE: [256]u32 = { ... };
Embedded assets@tape const SHADER = @embed("blur.glsl");

Last modified: