binding scopes

✓ Passing This code compiles and runs correctly.

Code

// Test 202: Binding scopes and persistence
// Tests the scoping rules from SPEC.md:
// - Bindings persist through ALL nested continuations
// - Parent bindings remain accessible at any depth
// - Duplicate binding names are forbidden (enforced by parser)

const std = @import("std");

// Events for testing scoping
~event outer { x: i32 }
| result i32

~proc outer {
    // x is accessible here directly
    return .{ .result = x };
}

~event middle { y: i32 }
| data i32

~proc middle {
    return .{ .data = y * 2 };
}

~event inner { z: i32 }
| final i32

~proc inner {
    return .{ .final = z * 3 };
}

// Event with nested structure for field access testing
~event nested_data { info: UserInfo }
| processed i32

// Define the struct type inline
const UserInfo = struct {
    profile: struct {
        name: []const u8,
        age: i32,
    },
};

~proc nested_data {
    // Access nested field
    const len: i32 = @intCast(info.profile.name.len);
    return .{ .processed = len };
}

// Event to demonstrate access to outer scope bindings
~event show_values { a: i32, b: i32, c: i32 }
| done

~proc show_values {
    // Should print values showing the scope chain worked
    std.debug.print("Values from scope chain: {} {} {}\n", .{a, b, c});
    return .{ .done = .{} };
}

// Top-level flow to test scoping rules
// Test 1: Bindings persist through nested continuations
// r should be 10, d should be 20, f should be 60
~outer(x: 10)
| result r |> middle(y: r)
    | data d |> inner(z: d)
        | final f |> show_values(a: r, b: d, c: f)
            | done |> _

// The binding 'r' from outer should be accessible in all nested continuations
// The binding 'd' from middle should be accessible in inner's continuation
// Each binding creates a new scope that persists through its continuations
input.kz

Expected

Values from scope chain: 10 20 60

Actual

Values from scope chain: 10 20 60

Test Configuration

MUST_RUN