✓
Passing This code compiles and runs correctly.
Code
// Test: Interpreter Conditionals (ASPIRATIONAL)
// Runtime evaluation of ~if conditionals
//
// THE GOAL: Parse and execute conditional flows at runtime
//
// ~validate(data: input)
// | valid v |> ~if(v.score > 50)
// | true |> approved { data: v.value }
// | false |> rejected { reason: "score too low" }
// | invalid e |> error { message: e.reason }
~import "$std/runtime"
const std = @import("std");
// ============================================================================
// Events for testing
// ============================================================================
~pub event check { value: []const u8 }
| high { score: []const u8 }
| low { score: []const u8 }
~proc check {
// Parse value as number, return high if > 50
const num = std.fmt.parseInt(i32, value, 10) catch 0;
if (num > 50) {
return .{ .high = .{ .score = value } };
}
return .{ .low = .{ .score = value } };
}
// Register events
~std.runtime:register(scope: "test") {
check
}
// ============================================================================
// 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 CONDITIONALS TEST (ASPIRATIONAL) ║\n", .{});
std.debug.print("╚══════════════════════════════════════════════════════════════╝\n\n", .{});
const dispatcher_fn = dispatch_test;
// ========================================================================
// Test 1: See what ~if parses to
// ========================================================================
std.debug.print("Test 1: Parse ~if and inspect AST\n", .{});
{
// Simple conditional flow
const test_source =
\\~if(true)
\\| true |> yes {}
\\| false |> no {}
;
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});
if (parser.reporter.hasErrors()) {
for (parser.reporter.errors.items) |parse_err| {
std.debug.print(" {s} at {}:{}\n", .{parse_err.message, parse_err.location.line, parse_err.location.column});
}
}
std.debug.print(" (This is expected if ~if needs special handling)\n\n", .{});
return;
};
std.debug.print(" Parsed {d} items!\n", .{parse_result.source_file.items.len});
for (parse_result.source_file.items) |item| {
std.debug.print(" Item type: {s}\n", .{@tagName(item)});
if (item == .flow) {
const flow = &item.flow;
const inv = &flow.invocation;
std.debug.print(" Flow invocation: ", .{});
if (inv.path.module_qualifier) |mq| {
std.debug.print("{s}:", .{mq});
}
for (inv.path.segments, 0..) |seg, i| {
if (i > 0) std.debug.print(".", .{});
std.debug.print("{s}", .{seg});
}
std.debug.print("\n", .{});
std.debug.print(" Args: {d}\n", .{inv.args.len});
for (inv.args) |arg| {
std.debug.print(" {s} = {s}\n", .{arg.name, arg.value});
}
std.debug.print(" Continuations: {d}\n", .{flow.continuations.len});
for (flow.continuations) |cont| {
std.debug.print(" | {s}", .{cont.branch});
if (cont.binding) |b| std.debug.print(" {s}", .{b});
std.debug.print(" |>\n", .{});
if (cont.node) |node| {
std.debug.print(" node: {s}\n", .{@tagName(node)});
}
}
}
}
std.debug.print(" ✓ TEST 1 COMPLETE\n\n", .{});
}
// ========================================================================
// Test 2: Chain with conditional (ASPIRATIONAL)
// ========================================================================
std.debug.print("Test 2: Dataflow with conditional branching\n", .{});
{
// What we WANT to support:
// ~check(value: "75")
// | high h |> approved { score: h.score }
// | low l |> rejected { score: l.score }
const test_source =
\\~check(value: "75")
\\| high h |> approved { score: "high" }
\\| low l |> rejected { score: "low" }
;
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(" ERROR: Parse failed: {}\n", .{err});
return;
};
std.debug.print(" Parsed successfully!\n", .{});
for (parse_result.source_file.items) |item| {
if (item == .flow) {
const flow = &item.flow;
// Dispatch
const ast_inv = &flow.invocation;
const inv: *const Invocation = @ptrCast(ast_inv);
var dispatch_result: DispatchResult = undefined;
dispatcher_fn(inv, &dispatch_result) catch |err| {
std.debug.print(" ERROR: Dispatch failed: {}\n", .{err});
return;
};
std.debug.print(" Dispatched: branch={s}\n", .{dispatch_result.branch});
// Find matching continuation
for (flow.continuations) |cont| {
if (std.mem.eql(u8, cont.branch, dispatch_result.branch)) {
std.debug.print(" Matched: | {s} |>\n", .{cont.branch});
if (cont.node) |node| {
if (node == .branch_constructor) {
const bc = node.branch_constructor;
std.debug.print(" RESULT:\n", .{});
std.debug.print(" branch: {s}\n", .{bc.branch_name});
for (bc.fields) |field| {
var value = field.expression_str orelse "";
if (value.len >= 2 and value[0] == '"' and value[value.len-1] == '"') {
value = value[1..value.len-1];
}
std.debug.print(" {s}: {s}\n", .{field.name, value});
}
}
}
break;
}
}
std.debug.print(" ✓ TEST 2 PASSED\n\n", .{});
break;
}
}
}
// ========================================================================
// Test 3: Now with low value
// ========================================================================
std.debug.print("Test 3: Same flow, different input (low path)\n", .{});
{
const test_source =
\\~check(value: "25")
\\| high h |> approved { score: "high" }
\\| low l |> rejected { score: "low" }
;
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 return;
for (parse_result.source_file.items) |item| {
if (item == .flow) {
const flow = &item.flow;
const ast_inv = &flow.invocation;
const inv: *const Invocation = @ptrCast(ast_inv);
var dispatch_result: DispatchResult = undefined;
dispatcher_fn(inv, &dispatch_result) catch return;
std.debug.print(" Dispatched: branch={s}\n", .{dispatch_result.branch});
for (flow.continuations) |cont| {
if (std.mem.eql(u8, cont.branch, dispatch_result.branch)) {
std.debug.print(" Matched: | {s} |>\n", .{cont.branch});
if (cont.node) |node| {
if (node == .branch_constructor) {
const bc = node.branch_constructor;
std.debug.print(" RESULT:\n", .{});
std.debug.print(" branch: {s}\n", .{bc.branch_name});
for (bc.fields) |field| {
var value = field.expression_str orelse "";
if (value.len >= 2 and value[0] == '"' and value[value.len-1] == '"') {
value = value[1..value.len-1];
}
std.debug.print(" {s}: {s}\n", .{field.name, value});
}
}
}
break;
}
}
std.debug.print(" ✓ TEST 3 PASSED\n\n", .{});
break;
}
}
}
std.debug.print("╔══════════════════════════════════════════════════════════════╗\n", .{});
std.debug.print("║ CONDITIONAL TESTS COMPLETE ║\n", .{});
std.debug.print("╚══════════════════════════════════════════════════════════════╝\n", .{});
}