✓
Passing This code compiles and runs correctly.
Code
// TEST: Optional Expression parameter (?Expression)
//
// Verifies that a comptime transform can declare an optional expression field.
// When called with (value), expr is the value string.
// When called without (), expr is null.
~import std/io
const std = @import("std");
~[comptime|transform]pub event labeled {
expr: ?Expression,
invocation: *const Invocation,
item: *const Item,
program: *const Program,
allocator: std.mem.Allocator
}
| transformed SiteResult
~proc labeled|zig {
const ast = @import("ast");
// expr is ?[]const u8 — null when called without (), non-null otherwise
const text: []const u8 = if (expr != null) "yes" else "no";
const code = std.fmt.allocPrint(allocator,
\\_ = @import("std").posix.write(1, "{s}\n") catch {{}};
, .{text}) catch unreachable;
_ = invocation;
// Position-agnostic write-back: the handler always sees its invocation as
// a flow's own invocation (the runner lifts nested sites), so the
// replacement is the uniform flow-shaped one — never a nested-node search.
const flow = &item.flow;
const new_item = ast.Item{ .inline_code = ast.InlineCode{
.code = code,
.location = flow.location,
.module = allocator.dupe(u8, flow.module) catch unreachable,
} };
return .{ .transformed = .{ .replacement = new_item } };
}
// The invocations sit nested under a noop chain on purpose: they exercise the
// lift/graft path — the transform above must work identically at any depth.
~event noop {}
~proc noop|zig {}
~noop() |> labeled("hello")
~noop() |> labeled()
Actual
yes
no
Expected output
yes
no
Test Configuration
MUST_RUN