08-slices.ha (4690B)
1 use rt::{compile, exited, EXIT_SUCCESS}; 2 3 fn from_array() void = { 4 let src = [1, 2, 3]; 5 let x: []int = src; 6 let xptr = &x: *struct { 7 data: nullable *[*]int, 8 length: size, 9 capacity: size, 10 }; 11 assert(xptr.data == &src); 12 13 let y: []int = []; 14 let yptr = &y: *struct { 15 data: nullable *[*]int, 16 length: size, 17 capacity: size, 18 }; 19 assert(yptr.data == null); 20 }; 21 22 fn storage() void = { 23 let x: []int = [1, 2, 3, 4, 5]; 24 const expected = [1, 2, 3, 4, 5]; 25 26 let ptr = &x: *struct { 27 data: *[*]int, 28 length: size, 29 capacity: size, 30 }; 31 32 assert(len(x) == 5); 33 assert(ptr.length == 5 && ptr.capacity == 5); 34 35 for (let i = 0z; i < len(expected); i += 1) { 36 assert(x[i] == expected[i]); 37 }; 38 39 let x: *[1]u8 = alloc([0...]); 40 free(x); 41 }; 42 43 fn casting() void = { 44 let x: []int = [1, 2, 3, 4, 5]; 45 let y = x: *[5]int; 46 for (let i = 0z; i < len(x); i += 1) { 47 assert(x[i] == y[i]); 48 }; 49 }; 50 51 fn measurements() void = { 52 let x: []int = [1, 2, 3, 4, 5]; 53 assert(size([]int) == size(*[*]int) + size(size) * 2); 54 assert(align([]int) == (if (align(*[*]int) > align(size)) align(*[*]int) 55 else align(size))); 56 assert(len(x) == 5); 57 assert(&x[0]: uintptr: size % size(int) == 0); 58 }; 59 60 fn indexing() void = { 61 let x = [1, 3, 3, 7]; 62 assert(x[0] == 1 && x[1] == 3 && x[2] == 3 && x[3] == 7); 63 assert(compile( 64 "fn test() void = { let x: []int = [1, 2, 3]; x[\"hello\"]; };" 65 ) as exited != EXIT_SUCCESS); 66 assert(compile( 67 "fn test() void = { let x = 10; x[10]; };" 68 ) as exited != EXIT_SUCCESS); 69 assert(compile( 70 "fn test() void = { let s: []u8 = []; let ss = s: []void; ss[0] = ss[1]; };" 71 ) as exited != EXIT_SUCCESS); 72 }; 73 74 fn zero3(s: []int) void = { 75 s[..] = [0, 0, 0]; 76 }; 77 78 fn assignment() void = { 79 let source = [1, 2, 3]; 80 let x: []int = source; 81 x[0] = 4; 82 x[1] = 5; 83 x[2] = 6; 84 assert(x[0] == 4 && x[1] == 5 && x[2] == 6); 85 assert(source[0] == 4 && source[1] == 5 && source[2] == 6); 86 let y: []int = [4, 5, 6]; 87 x = y; 88 x[0] = 7; 89 x[1] = 8; 90 x[2] = 9; 91 assert(x[0] == 7 && x[1] == 8 && x[2] == 9); 92 assert(source[0] == 4 && source[1] == 5 && source[2] == 6); 93 94 zero3(y); 95 assert(y[0] == 0 && y[1] == 0 && y[2] == 0); 96 let z: []int = [1, 2, 3, 4, 5]; 97 z[1..4] = [42, 69, 1337]; 98 assert(z[0] == 1 && z[1] == 42 && z[2] == 69 && z[3] == 1337 && z[4] == 5); 99 z[2..5] = y; 100 assert(z[0] == 1 && z[1] == 42 && z[2] == 0 && z[3] == 0 && z[4] == 0); 101 assert(compile( 102 "export fn main() void = { let a: []int = [1]; a[..] += a; };" 103 ) as exited != EXIT_SUCCESS); 104 }; 105 106 fn assert_slice_eq(actual: []int, expected: []int) void = { 107 assert(len(expected) == len(actual)); 108 for (let i = 0z; i < len(expected); i += 1) { 109 assert(expected[i] == actual[i]); 110 }; 111 }; 112 113 fn slicing() void = { 114 let a = [1, 2, 3, 4, 5]; 115 assert_slice_eq(a[..], [1, 2, 3, 4, 5]); 116 assert_slice_eq(a[..3], [1, 2, 3]); 117 assert_slice_eq(a[1..3], [2, 3]); 118 assert_slice_eq(a[1..], [2, 3, 4, 5]); 119 assert_slice_eq(a[5..], []); 120 121 let b: []int = [1, 2, 3, 4, 5]; 122 assert_slice_eq(b[..], [1, 2, 3, 4, 5]); 123 assert_slice_eq(b[..3], [1, 2, 3]); 124 assert_slice_eq(b[1..3], [2, 3]); 125 assert_slice_eq(b[1..], [2, 3, 4, 5]); 126 assert_slice_eq(b[5..], []); 127 128 let p = &a; 129 assert_slice_eq(p[..], [1, 2, 3, 4, 5]); 130 assert_slice_eq(p[..3], [1, 2, 3]); 131 assert_slice_eq(p[1..3], [2, 3]); 132 assert_slice_eq(p[1..], [2, 3, 4, 5]); 133 assert_slice_eq(p[5..], []); 134 135 assert(compile( 136 "fn test() void = { let x = \"test\"; x[1..3]; };" 137 ) as exited != EXIT_SUCCESS); 138 assert(compile( 139 "fn test() void = { let x = [1, 2, 3]; x[\"hi\"..]; };" 140 ) as exited != EXIT_SUCCESS); 141 assert(compile( 142 "fn test() void = { let x = [1, 2, 3]; x[2..1]; };" 143 ) as exited != EXIT_SUCCESS); 144 assert(compile( 145 "fn test() void = { let x = [1, 2, 3]; x[..4]; };" 146 ) as exited != EXIT_SUCCESS); 147 }; 148 149 type tree = struct { 150 value: u64, 151 children: []tree, 152 }; 153 154 fn sum_tree(t: tree) u64 = { 155 let sum = t.value; 156 for (let i = 0z; i < len(t.children); i += 1) { 157 sum += sum_tree(t.children[i]); 158 }; 159 return sum; 160 }; 161 162 fn recursive_structure() void = { 163 const t = tree { 164 value = 15, 165 children = [tree { 166 value = 23, 167 children = [tree { 168 value = 62, 169 children = [], 170 }, tree { 171 value = 34, 172 children = [], 173 }], 174 }], 175 }; 176 assert(sum_tree(t) == 134, "recursive structure using slices"); 177 }; 178 179 fn expandable() void = { 180 let s: [6]u64 = [0...]; 181 182 s[2..2] = [1...]; 183 assert(s[2] == 0); 184 185 s[1..3] = [1...]; 186 assert(s[0] == 0); 187 assert(s[1] == 1); 188 assert(s[2] == 1); 189 assert(s[3] == 0); 190 191 s[2..] = [123...]; 192 assert(s[1] == 1); 193 assert(s[2] == 123); 194 assert(s[3] == 123); 195 assert(s[4] == 123); 196 assert(s[5] == 123); 197 }; 198 199 export fn main() void = { 200 from_array(); 201 storage(); 202 measurements(); 203 indexing(); 204 assignment(); 205 slicing(); 206 recursive_structure(); 207 expandable(); 208 };