import "std/mem.zc" // ** Globals ** let DROP_COUNT = 0; // ** Structs & Helpers ** // trait Drop defined in std/mem.zc struct Resource { id: int; } impl Drop for Resource { fn drop(self) { println "Dropping Resource {self.id}"; DROP_COUNT = DROP_COUNT + 1; } } fn create_resource(id: int) { let r = Resource{id: id}; println "Created Resource {r.id}"; } struct Point { x: int; y: int; } fn distance(p1: Point, p2: Point) -> int { let dx = p2.x - p1.x; let dy = p2.y - p1.y; return dx * dx + dy * dy; } fn accumulate(start: int, count: int) -> int { let sum = start; let i = 0; while (i < count) { sum += i; i++; } return sum; } fn process_point(p: Point) -> Point { let result = Point { x: p.x * 2, y: p.y * 2 }; return result; } fn counter_immut() { let count = 0; { let inner = 10; inner = inner + 5; count = count + inner; } } struct Permissions { mask: U8; } impl Permissions { fn new(m: U8) -> Permissions { return Permissions { mask: m }; } fn bitor(self, other: Permissions) -> Permissions { return Permissions { mask: self.mask | other.mask }; } fn has(self, flag: U8) -> U8 { return (self.mask & flag) == flag; } } fn get_resource() -> int { println "resource opened"; return 42; } fn release_resource(id: int) { if (id == 42) println "resource 42 released"; else println "resource released (unknown)"; } fn test_defer_logic() { println "start test"; let x = get_resource() defer release_resource(it); println "using resource {x}"; } test "test_alloc" { "Testing alloc..."; let p = alloc(); *p = 42; f" alloc(): {*p}"; assert(*p == 42, "alloc failed"); free(p); let arr = alloc_n(5); for let i = 0; i < 5; i++ { arr[i] = i * 10; } f" alloc_n(5): [{arr[0]}, {arr[1]}, {arr[2]}, {arr[3]}, {arr[4]}]"; free(arr); " ✓ alloc works!"; } test "test_box" { "Testing Box..."; let b = Box::new(); *b.get() = 100; let val = *b.get(); f" Box value: {val}"; assert(val == 100, "Box failed"); b.free(); " ✓ Box works!"; } test "test_slice" { "Testing Slice..."; let data: int[5] = [1, 2, 3, 4, 5]; let s = Slice::new(&data[0], 5); f" Slice len: {(int)s.len}"; let v2 = s.get(2); f" Slice[2]: {v2}"; assert(v2 == 3, "Slice get failed"); s.set(0, 99); let v0 = s.get(0); f" After set: Slice[0] = {v0}"; assert(v0 == 99, "Slice set failed"); " ✓ Slice works!"; } test "test_swap" { "Testing swap..."; let a = 10; let b = 20; f" Before: a={a}, b={b}"; swap(&a, &b); f" After: a={a}, b={b}"; assert(a == 20 && b == 10, "swap failed"); " ✓ swap works!"; } test "test_autofree" { println "Testing autofree..."; { autofree let p = malloc(1024); if (p == NULL) { eprintln "Malloc failed!"; } strcpy(p, "Auto-freed string"); print f"Allocated: {p}"; println ""; } println "Exited block successfully (hopefully freed)"; { autofree let p1 = malloc(10); autofree let p2 = malloc(20); } } test "test_raii_drop" { DROP_COUNT = 0; "Entering scope..."; create_resource(1); "Exited scope."; assert(DROP_COUNT == 1, "Expected Drop to be called once"); { let r2 = Resource{id: 2}; let r3 = Resource{id: 3}; } assert(DROP_COUNT == 3, "Expected 3 total drops"); } test "test_immutable" { let p1 = Point { x: 0, y: 0 }; let p2 = Point { x: 3, y: 4 }; let dist = distance(p1, p2); "Distance: {dist}"; let sum = accumulate(10, 5); "Accumulate: {sum}"; let p3 = process_point(Point { x: 0, y: 0 }); "Processed: ({p3.x}, {p3.y})"; counter_immut(); } test "test_permissions" { def READ : U8 = 0b100; def WRITE : U8 = 0b010; def EXEC : U8 = 0b001; let p1 = Permissions::new(READ); "Start: {p1.mask} (Read)"; let p2 = Permissions::new(WRITE); let p_rw = p1 | p2; "Combined: {p_rw.mask} (Read + Write)"; if (p_rw.has(EXEC)) { " > Has Execute access"; } else { " > No Execute access"; } if (p_rw.has(READ)) { " > Has Read access"; } let p_all = p_rw | Permissions::new(EXEC); "Final: {p_all.mask} (All)"; } test "test_value_defer" { test_defer_logic(); println "end test"; }