✓
Passing This code compiles and runs correctly.
Code
// Test: Interpreter Runtime ~if
// Tests the interpreter executing flows with ~if conditionals
~import "$std/runtime"
~import "$std/interpreter"
const std = @import("std");
// ============================================================================
// Test event that returns a score
// ============================================================================
~pub event get_score { value: []const u8 }
| score { amount: i32 }
~proc get_score {
const num = std.fmt.parseInt(i32, value, 10) catch 0;
return .{ .score = .{ .amount = num } };
}
// Register events for dispatch
~std.runtime:register(scope: "test") {
get_score
}
// ============================================================================
// Entry point
// ============================================================================
pub fn main() void {
const koru_parser = @import("koru_parser");
const koru_errors = @import("koru_errors");
std.debug.print("\n", .{});
std.debug.print("╔══════════════════════════════════════════════════════════════╗\n", .{});
std.debug.print("║ INTERPRETER RUNTIME ~if TEST ║\n", .{});
std.debug.print("╚══════════════════════════════════════════════════════════════╝\n\n", .{});
const dispatcher_fn = dispatch_test;
// ========================================================================
// Test 1: ~if(true) should take | then |> branch
// ========================================================================
std.debug.print("Test 1: ~if(true) - then branch\n", .{});
{
const test_source =
\\~if(true)
\\| then |> yes { answer: "correct" }
\\| else |> no { answer: "wrong" }
;
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
defer arena.deinit();
const allocator = arena.allocator();
var reporter = koru_errors.ErrorReporter.init(allocator, "test", test_source) catch return;
defer reporter.deinit();
var parser = koru_parser.Parser.init(allocator, test_source, "test", &[_][]const u8{}, null) catch return;
defer parser.deinit();
const parse_result = parser.parse() catch |err| {
std.debug.print(" Parse error: {}\n", .{err});
return;
};
std.debug.print(" Parsed {d} items\n", .{parse_result.source_file.items.len});
for (parse_result.source_file.items) |item| {
if (item == .flow) {
const flow = &item.flow;
std.debug.print(" Flow: path={s}\n", .{flow.invocation.path.segments[0]});
std.debug.print(" Continuations: {d}\n", .{flow.continuations.len});
for (flow.continuations) |cont| {
std.debug.print(" | {s} |>\n", .{cont.branch});
}
// Dispatch (will use special if handling)
const ast_inv = &flow.invocation;
const inv: *const Invocation = @ptrCast(ast_inv);
var dispatch_result: DispatchResult = undefined;
dispatcher_fn(inv, &dispatch_result) catch |err| {
// Expected - if is not in our registered scope
// The interpreter handles it specially
std.debug.print(" Dispatch result: {s} (handled specially)\n", .{@errorName(err)});
};
std.debug.print(" ✓ TEST 1 PARSED SUCCESSFULLY\n\n", .{});
break;
}
}
}
// ========================================================================
// Test 2: ~if(false) should take | else |> branch
// ========================================================================
std.debug.print("Test 2: ~if(false) - else branch\n", .{});
{
const test_source =
\\~if(false)
\\| then |> yes { answer: "wrong" }
\\| else |> no { answer: "correct" }
;
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
defer arena.deinit();
const allocator = arena.allocator();
var reporter = koru_errors.ErrorReporter.init(allocator, "test", test_source) catch return;
defer reporter.deinit();
var parser = koru_parser.Parser.init(allocator, test_source, "test", &[_][]const u8{}, null) catch return;
defer parser.deinit();
const parse_result = parser.parse() catch |err| {
std.debug.print(" Parse error: {}\n", .{err});
return;
};
std.debug.print(" Parsed successfully\n", .{});
for (parse_result.source_file.items) |item| {
if (item == .flow) {
const flow = &item.flow;
std.debug.print(" Flow: path={s}\n", .{flow.invocation.path.segments[0]});
std.debug.print(" Args: {d}\n", .{flow.invocation.args.len});
if (flow.invocation.args.len > 0) {
std.debug.print(" arg[0].value = {s}\n", .{flow.invocation.args[0].value});
}
std.debug.print(" ✓ TEST 2 PARSED SUCCESSFULLY\n\n", .{});
break;
}
}
}
std.debug.print("╔══════════════════════════════════════════════════════════════╗\n", .{});
std.debug.print("║ INTERPRETER ~if TESTS COMPLETE ║\n", .{});
std.debug.print("╚══════════════════════════════════════════════════════════════╝\n", .{});
}
Expected Output
╔══════════════════════════════════════════════════════════════╗
║ INTERPRETER RUNTIME ~if TEST ║
╚══════════════════════════════════════════════════════════════╝
Test 1: ~if(true) - then branch
Parsed 1 items
Flow: path=if
Continuations: 2
| then |>
| else |>
Dispatch result: EventDenied (handled specially)
✓ TEST 1 PARSED SUCCESSFULLY
Test 2: ~if(false) - else branch
Parsed successfully
Flow: path=if
Args: 1
arg[0].value = false
✓ TEST 2 PARSED SUCCESSFULLY
╔══════════════════════════════════════════════════════════════╗
║ INTERPRETER ~if TESTS COMPLETE ║
╚══════════════════════════════════════════════════════════════╝
Test Configuration
MUST_RUN