const { assert } = import("test"); // MVS P1: parser-only support for parameter mode keywords. // // These tests verify that the parser accepts the three parameter modes // (default = let, mut, move) and that programs using them compile and // run identically to the same programs without the mode annotations. // Semantic enforcement (init analysis, exclusivity, scope-escape, drop // synthesis) lands in P2 and beyond. See docs/MVS.md. // Default mode (no keyword): read-only borrow fn readDefault(x: u32) u32 { return x; } // mut: exclusive read-write borrow fn modifyMut(x: mut u32) u32 { x = x + 1; return x; } // move: consume ownership fn moveValue(buf: move u32) u32 { return buf; } // All three modes mixed in one signature fn mixedModes(a: u32, b: mut u32, c: move u32) u32 { b = b + 1; return a + b + c; } // Mode applied to a pointer-typed parameter // `mut *mut u32` reads as: mut-mode borrow of a pointer-to-mut-u32. // The mode keyword sits after `:`; the pointer's own `mut` qualifier // stays inside the type. No ambiguity (pointer types start with `*`). fn modifyMutPtr(p: mut *mut u32) u32 { return p.*; } // Parameter named `out` is allowed: `out` is not a reserved word fn paramNamedOut(out: u32) u32 { return out; } // Local helper for the test path fn fillThenReadHelper() u8 { var arr: [4]u8 = [1, 2, 3, 4]; return arr[2]; } // Tests tfn readDefaultParses() { assert(readDefault(7), 7); } tfn modifyMutParses() { var n: u32 = 10; assert(modifyMut(n), 11); } tfn moveValueParses() { var v: u32 = 99; assert(moveValue(v), 99); } tfn mixedModesParses() { var b: u32 = 2; var c: u32 = 3; assert(mixedModes(1, b, c), 7); } tfn modifyMutPtrParses() { var x: u32 = 33; var p: *mut u32 = &x; assert(modifyMutPtr(&p), 33); } tfn paramNamedOutParses() { assert(paramNamedOut(123), 123); } tfn arrayLiteralReads() { assert(fillThenReadHelper(), 3); }