21-tuples.ha (4998B)
1 use rt::{compile, exited, EXIT_SUCCESS}; 2 3 def CONST: (int, str) = (15, "foo"); 4 5 fn storage() void = { 6 let x: (int, size) = (42, 1337); 7 assert(size((int, size)) == size(size) * 2); 8 assert(size((int, (u8, size))) == size(size) * 3); 9 assert(align((int, size)) == align(size)); 10 assert(align((int, (u8, size))) == align(size)); 11 let ptr = &x: *struct { i: int, z: size }; 12 assert(ptr.i == 42 && ptr.z == 1337); 13 }; 14 15 fn indexing() void = { 16 let x: ((int, uint), size) = ((42, 69), 1337); 17 assert(x.0.0 == 42); 18 assert(x.0.1 == 69); 19 assert(x.1 == 1337); 20 assert(x.1z == 1337); 21 assert(x.0x1 == 1337); 22 assert(x.1e+0 == 1337); 23 }; 24 25 fn func(in: (int, size)) (int, size) = (in.0 + 1, in.1 + 1); 26 fn eval_expr_access() void = { 27 static assert((42, 0).0 == 42 && (42, 0).1 == 0); 28 static assert(CONST.0 == 15 && CONST.1 == "foo"); 29 }; 30 31 fn eval_expr_tuple() void = { 32 static let t = (42, 8); 33 }; 34 35 fn funcs() void = { 36 let x = func((41, 1336)); 37 assert(x.0 == 42 && x.1 == 1337); 38 }; 39 40 fn unpacking_static() int = { 41 static let (a, b) = (0, 0); 42 a += 1; 43 b += 1; 44 return a; 45 }; 46 47 fn unpacking_demo() (int, int) = { 48 return (10, 20); 49 }; 50 51 fn unpacking_eval() (int, int) = { 52 static let i = 0; 53 const res = (10 + i, 20 + i); 54 i += 1; 55 return res; 56 }; 57 58 let unpacking_global: int = 0i; 59 60 fn unpacking_addone() int = { 61 unpacking_global += 1; 62 return unpacking_global; 63 }; 64 65 type tuple_alias = (int, int); 66 fn unpacking() void = { 67 const (a, b, c) = (42, 8, 12); 68 assert(a == 42); 69 assert(b == 8); 70 assert(c == 12); 71 72 const (a, b): (i64, u64) = (2i, 4z); 73 assert(a == 2i64); 74 assert(b == 4u64); 75 76 const (a, b, c): (i64, str, f64) = (2i, "hello", 1.0); 77 assert(a == 2i64); 78 assert(b == "hello"); 79 assert(c == 1.0f64); 80 81 let (a, b): (i64, u64) = (1i, 3z); 82 a += 1; 83 b += 1; 84 assert(a == 2i64); 85 assert(b == 4u64); 86 87 const (_, b, c) = (1, 2, 3); 88 assert(b == 2); 89 assert(c == 3); 90 91 const (a, _, c) = (1, 2, 3); 92 assert(a == 1); 93 assert(c == 3); 94 95 const (a, b, _) = (1, 2, 3); 96 assert(a == 1); 97 assert(b == 2); 98 99 const t: tuple_alias = (1, 2); 100 const (a, b) = t; 101 assert(a == 1); 102 assert(b == 2); 103 104 unpacking_static(); 105 unpacking_static(); 106 const a = unpacking_static(); 107 assert(a == 3); 108 109 const (a, b) = unpacking_demo(); 110 assert(a == 10); 111 assert(b == 20); 112 113 const (a, b) = unpacking_eval(); 114 assert(a == 10); 115 assert(b == 20); 116 117 let (a, b, _, d) = (unpacking_addone(), unpacking_addone(), 118 unpacking_addone(), unpacking_addone()); 119 assert(a == 1 && b == 2 && d == 4); 120 }; 121 122 // Regression tests for miscellaneous compiler bugs 123 fn regression() void = { 124 let a: (((int | void), int) | void) = (void, 0); 125 126 let x = (1, 0); 127 x = (2, x.0); 128 assert(x.0 == 2 && x.1 == 1); 129 }; 130 131 fn reject() void = { 132 let tests = [ 133 // no name in unpack 134 "fn t() void = { let (_, _) = (1, 2); };", 135 // unpack of non-tuple type 136 "fn t() void = { let (x, y) = 5; };", 137 "fn t() void = { let (a, b): int = (2, 3); };", 138 // static unpack 139 "fn getval() int = 5; fn t() void = { static let (a, b) = (2, getval()); };", 140 "fn getval() int = 5; fn t() void = { static let (a, _) = (2, getval()); };", 141 142 // member count mismatch 143 "fn t() void = { let a: (u8, u8, u8) = (2, 3); };", 144 "fn t() void = { let a: (u8, u8) = (2, 3); let b: (u8, u8, u8) = a; };", 145 "fn t() void = { let a: (u8, u8) = (2, 3, 4); };", 146 "fn t() void = { let a: (u8, u8, u8) = (2, 3, 4); let b: (u8, u8) = a; };", 147 "fn t() void = { let (x, y) = (1, 2, 3); };", 148 "fn t() void = { let (x, y, z) = (1, 2); };", 149 "fn t() void = { let (x, y, _) = (1, 2); };", 150 "fn t() void = { let (x, _, _) = (1, 2); };", 151 // empty tuple 152 "fn t() void = { let a: (() | void) = void; };", 153 "fn t() void = { let a = () };", 154 "fn t() void = { let () = () };", 155 // one member 156 "fn t() void = { let a: ((int) | void) = void; };", 157 "fn t() void = { let a = (4u); a.0; };", 158 "fn t() void = { let (a) = (4u); a.0; };", 159 "fn t() void = { let (a) = 4u; a.0; };", 160 // zero-sized member 161 "fn t() void = { let a: ((void, int) | void) = void; };", 162 "fn t() void = { let a = (void, 2); };", 163 "fn t() void = { let (a, b) = (void, 2); };", 164 "fn t() void = { let (_, b) = (void, 2); };", 165 // member of undefined size 166 "fn t() void = { let a: (([*]int, int) | void) = void; };", 167 "fn t() void = { let a = (t, 2); };", 168 "fn t() void = { let (a, b) = (t, 2); };", 169 "fn t() void = { let (_, b) = (t, 2); };", 170 // null type member 171 "fn t() void = { let a: ((null, int) | void) = void; };", 172 "fn t() void = { let a = (null, 2); };", 173 "fn t() void = { let (a, b) = (null, 2); };", 174 "fn t() void = { let (_, b) = (null, 2); };", 175 // invalid field access 176 "fn t() void = { let a = (0, 1, 2); a.3; };", 177 "fn t() void = { let a = (0, 1, 2); a.-1; };", 178 "fn t() void = { let a = (0, 1, 2).3; };", 179 "fn t() void = { let a = (0, 1, 2).-1; };", 180 ]; 181 182 for (let i = 0z; i < len(tests); i += 1) { 183 assert(compile(tests[i]) as exited != EXIT_SUCCESS); 184 }; 185 }; 186 187 export fn main() void = { 188 storage(); 189 indexing(); 190 funcs(); 191 eval_expr_tuple(); 192 eval_expr_access(); 193 unpacking(); 194 regression(); 195 reject(); 196 };