✓
Passing This code compiles and runs correctly.
Code
// TEST: Comptime events can return modified Program
//
// A [comptime] event that declares `program: *const Program` in its OUTPUT
// should have that Program used as the new AST going forward.
//
// This enables holistic AST transformations without needing [transform].
// Transforms are for surgical replacement of specific invocations.
// Comptime + Program return is for cross-cutting AST modifications.
const std = @import("std");
const ast = @import("ast");
const ast_functional = @import("ast_functional");
// Comptime event that RETURNS a modified Program
~[comptime] tor augment-program {
program: *const ast.Program,
allocator: std.mem.Allocator
} -> *const ast.Program
~[comptime] proc augment-program|zig {
// Use ast_functional to add a new item to the program
// For now, just return the program unchanged
std.debug.print("augment_program: received {} items\n", .{program.items.len});
// TODO: Actually modify the program using ast_functional
// const new_program = ast_functional.addItem(allocator, program, new_item);
// return new_program;
return program;
}
// Invoke the augmentation — no continuations needed
~augment-program()
// A simple runtime event to verify compilation works
~tor hello {}
~proc hello|zig {
std.debug.print("Hello from augmented program!\n", .{});
}
~hello()
Supporting Files
# TODO: Comptime Program Return
## Feature Description
Allow `[comptime]` events to return a modified `Program` that becomes the new AST.
Currently:
- `[comptime]` events can RECEIVE `program: *const Program` (injection works)
- `[comptime|transform]` events can modify AST by replacing invocations
Missing:
- `[comptime]` events returning `program: *const Program` in their output branch
## Use Case: Route Collector
```koru
~[comptime] event collect_routes { program: *const Program, allocator: Allocator }
| done { program: *const Program }
~[comptime] proc collect_routes {
// 1. Walk AST, find all [norun] route declarations
// 2. Generate routing table as new AST item
// 3. Return program with routing table added
const routing_table = generateRoutingTable(program, allocator);
const new_program = ast_functional.addItem(allocator, program, routing_table);
return .{ .done = .{ .program = new_program } };
}
```
## Conceptual Difference
| Annotation | Purpose | Scope |
|------------|---------|-------|
| `[comptime\|transform]` | Replace specific invocations | Surgical - one invocation at a time |
| `[comptime]` + Program return | Modify entire AST | Holistic - cross-cutting changes |
## Implementation Notes
1. In `compiler.kz` (evaluate_comptime pass):
- Check if comptime event's done branch has a `program` field
- If so, use the returned Program as `ctx.ast` going forward
2. In generated code:
- The `comptime_flowN()` function needs to return the Program
- `comptime_main()` needs to chain Programs through multiple flows
3. Use `ast_functional.zig` for safe, immutable transformations
## Status
- [x] Detect Program in comptime event output
- [x] Thread returned Program through comptime_main
- [x] Update ctx.ast with returned Program
- [ ] Test with actual AST modification
Actual
Hello from augmented program!
Flows
flow ~augment-program click a branch to expand · @labels scroll to their anchor
augment-program
flow ~hello click a branch to expand · @labels scroll to their anchor
hello
Test Configuration
MUST_RUN