expr_test.ha (7422B)
1 // SPDX-License-Identifier: MPL-2.0 2 // (c) Hare authors <https://harelang.org> 3 4 @test fn assignment() void = { 5 roundtrip("export fn main() void = { 6 x = y; 7 *x = *y + 10; 8 *x = *foo(); 9 *y() = bar(); 10 x[y] = z; 11 x[y][z] = foo(); 12 x.y = z; 13 x.y.z = foo(); 14 x[y].z = foo(); 15 x.y[z] = foo(); 16 x += 10; 17 x -= 10; 18 x *= 10; 19 x /= 10; 20 x %= 10; 21 x &= 10; 22 x |= 10; 23 x ^= 10; 24 x >>= 10; 25 x <<= 10; 26 x &&= true; 27 x ||= true; 28 x ^^= true; 29 }; 30 "); 31 }; 32 33 @test fn binarithm() void = { 34 roundtrip("export fn main() void = *void + void * void / void;\n"); 35 }; 36 37 @test fn binding() void = { 38 roundtrip("export fn main() void = { 39 let x: int = 1337, y = 7331; 40 const z: int = 42, q: int = 24; 41 const (foo, bar): (int, bool) = (42, true); 42 const (foo, _, bar): (int, uint, bool) = (42, 12u, true); 43 def X: int = 1337, y = 7331; 44 static let p: int = 62893, o = 39826; 45 static const w: int = 62893, t = 39826; 46 }; 47 "); 48 }; 49 50 @test fn builtin() void = { 51 roundtrip(`export fn main() void = { 52 align(u32); 53 alloc(1234); 54 alloc(1234...); 55 alloc(4321, 1234); 56 append(x, 10); 57 append(x, [10]...); 58 append(x, [10...], 20); 59 static append(x, 10); 60 abort(); 61 abort("surprize"); 62 static abort(); 63 static abort("surprize"); 64 assert(x == 12); 65 assert(x == 12, "number mismatch"); 66 static assert(x == 12); 67 static assert(x == 12, "number mismatch"); 68 delete(x[10]); 69 delete(x[10..20]); 70 delete(x[..]); 71 delete(x.y.z[..]); 72 static delete(x[10]); 73 free(x); 74 insert(x[0], foo); 75 insert(x[0], foo...); 76 insert(x[0], foo, bar); 77 static insert(x[0], foo); 78 len([1, 2, 3, 4]); 79 offset(foo.bar); 80 size(u32); 81 vastart(); 82 vaarg(va); 83 vaend(va); 84 }; 85 `); 86 }; 87 88 @test fn call() void = { 89 roundtrip("export fn main() void = test();\n\n" 90 "export fn main() void = test(void, void, void);\n\n" 91 "export fn main() void = test(void, void, void...);\n\n" 92 "export fn main() void = test()()(void);\n"); 93 roundtrip_reparse("export fn main() void = test(void,);\n"); 94 }; 95 96 @test fn cast() void = { 97 roundtrip("export fn main() void = void: int;\n\n" 98 "export fn main() void = void as int;\n\n" 99 "export fn main() void = void is int;\n\n" 100 "export fn main() void = void as null;\n\n" 101 "export fn main() void = void is null;\n\n" 102 "export fn main() void = void: int: uint: u16: u8;\n\n" 103 "export fn main() void = void: int as uint: u16 is u8;\n\n" 104 "export fn main() void = void: int as null: u16 is null;\n\n" 105 "export fn main() void = {\n\tyield void;\n}: int;\n"); 106 }; 107 108 @test fn compound() void = { 109 roundtrip("export fn main() void = :label {\n" 110 "\tvoid;\n" 111 "};\n"); 112 }; 113 114 @test fn constant() void = { 115 roundtrip(`export fn main() void = { 116 2 + (-4 + void) * true / ("hello" << '?'); 117 [1, 2, 3, 4]; 118 [1, 2, 3, 4...]; 119 (1, 2, 3); 120 struct { 121 x: int = 10, 122 y: int = 20, 123 }; 124 coords { 125 x: int = 10, 126 y: int = 20, 127 ... 128 }; 129 coords { 130 x = 10, 131 y = 20, 132 }; 133 struct { 134 x: int = 10, 135 struct { 136 y: int = 20, 137 }, 138 }; 139 struct { 140 x: int = 10, 141 coords { 142 y: int = 20, 143 }, 144 }; 145 struct { 146 x: int = 10, 147 namespace::coords { 148 y: int = 20, 149 }, 150 }; 151 coords { 152 ... 153 }; 154 13.37; 155 13.37f32; 156 13.37f64; 157 6.022e23; 158 1.616255e-35; 159 1337z; 160 1337u; 161 1337i8; 162 1337u8; 163 1337i16; 164 1337u16; 165 1337i32; 166 1337u32; 167 1337i64; 168 1337u64; 169 "backslashes\\and \"double quotes\""; 170 '\''; 171 '\\'; 172 }; 173 `); 174 roundtrip_reparse(`export fn main() void = { 175 struct { x: int = 10, y: int = 20 }; 176 coords { x: int = 10, y: int = 20 }; 177 "string " "concatenation"; 178 }; 179 `); 180 }; 181 182 @test fn control() void = { 183 roundtrip("export fn main() void = { 184 break; 185 break :foo; 186 continue; 187 continue :foo; 188 return; 189 return 2 + 2; 190 }; 191 "); 192 }; 193 194 @test fn defer_expr() void = { 195 roundtrip("export fn main() void = { 196 defer foo(); 197 }; 198 "); 199 }; 200 201 @test fn for_expr() void = { 202 roundtrip("fn next() (int | done) = 4; 203 204 export fn main() void = { 205 for (true) { 206 x; 207 }; 208 for :label (true) { 209 x; 210 }; 211 for (let x = 0; x < 10) { 212 x; 213 }; 214 for (x < 10; x) { 215 x; 216 }; 217 for (let x = 10; x < 10; x) { 218 x; 219 }; 220 for (let x => next()) { 221 x; 222 }; 223 for (let x .. [1, 2, 3]) { 224 x; 225 }; 226 for (let x &.. [1, 2, 3]) { 227 x; 228 }; 229 }; 230 "); 231 }; 232 233 @test fn if_expr() void = { 234 roundtrip("export fn main() void = { 235 if (x == y) { 236 z; 237 }; 238 if (y == x) z; 239 if (z == q) r else p; 240 if (a == b) c else if (d == e) f else g; 241 }; 242 "); 243 }; 244 245 @test fn list() void = { 246 roundtrip("export fn main() void = { 247 2 + 2; 248 call(); 249 }; 250 "); 251 }; 252 253 @test fn postfix() void = { 254 roundtrip("export fn main() void = x.y;\n\n" 255 "export fn main() void = x.y.z.q;\n\n" 256 "export fn main() void = x().y;\n\n" 257 "export fn main() void = x.42;\n\n" 258 "export fn main() void = x().y.0.q;\n\n" 259 "export fn main() void = x?;\n\n" 260 "export fn main() void = x!;\n\n" 261 "export fn main() void = x()?.y;\n\n" 262 "export fn main() void = x[10];\n\n" 263 "export fn main() void = x[10 + 10][20];\n"); 264 }; 265 266 @test fn slice() void = { 267 roundtrip("export fn main() void = x[..];\n\n" 268 "export fn main() void = x[123..];\n\n" 269 "export fn main() void = x[123..321];\n\n" 270 "export fn main() void = x[..321];\n"); 271 }; 272 273 @test fn switch_expr() void = { 274 roundtrip("export fn main() void = { 275 switch (x) { 276 case 1234, 4321 => 277 return y; 278 case 1337 => 279 let x = 0; 280 case => void; 281 case => abort(); 282 case => 283 defer x; 284 }; 285 switch :label (x) { 286 case => void; 287 }; 288 }; 289 "); 290 }; 291 292 @test fn match_expr() void = { 293 roundtrip("export fn main() void = { 294 match (x) { 295 case let i: size => 296 return y; 297 case foo => 298 return bar; 299 case *int => 300 return bar; 301 case foo::bar => 302 return baz; 303 case null => void; 304 case => abort(); 305 }; 306 match :label (x) { 307 case let s: matchdata => 308 return y; 309 case str => 310 let x = 0; 311 case => 312 defer x; 313 }; 314 }; 315 "); 316 }; 317 318 @test fn unarithm() void = { 319 roundtrip("export fn main() void = -void;\n\n" 320 "export fn main() void = *void;\n\n" 321 "export fn main() void = ~void;\n\n" 322 "export fn main() void = !void;\n\n" 323 "export fn main() void = &void;\n\n" 324 "export fn main() void = &switch (0) {\n" 325 "case => void;\n" 326 "};\n\n" 327 "export fn main() void = &match (0) {\n" 328 "case => void;\n" 329 "};\n"); 330 }; 331 332 @test fn yield_expr() void = { 333 roundtrip("export fn main() void = yield;\n\n" 334 "export fn main() void = yield void;\n\n" 335 "export fn main() void = yield :foo;\n\n" 336 "export fn main() void = yield :foo, void;\n"); 337 }; 338 339 @test fn parenthesis() void = { 340 roundtrip( 341 "export fn main() void = -((2 + 2) * 2);\n\n" 342 "export fn main() void = &(1: uint);\n\n" 343 "export fn main() void = **x;\n\n" 344 "export fn main() void = *alloc(2);\n\n" 345 "export fn main() void = &(&x);\n\n" 346 "export fn main() void = &*&*&x;\n\n" 347 "export fn main() void = x: int: uint: u8;\n\n" 348 "export fn main() void = &array[idx];\n\n" 349 "export fn main() void = &array[idx..];\n\n" 350 "export fn main() void = (array: *[*]u8)[idx];\n\n" 351 "export fn main() void = (s: *object).field;\n\n" 352 "export fn main() void = (s: *object).0;\n\n" 353 "export fn main() void = &offset(header.x);\n\n" 354 "export fn main() void = *((a + b): uintptr);\n\n" 355 "export fn main() void = *value();\n\n" 356 "export fn main() void = (ptr: function)();\n\n" 357 "export fn main() void = func()?.field;\n\n" 358 "export fn main() void = (x: thing)?;\n\n" 359 "export fn main() void = (x: thing)!;\n\n" 360 "export fn main() void = (hey: *[*]u8)[1..2];\n\n" 361 "export fn main() void = (hey: *[*]u8)[0];\n\n" 362 "export fn main() void = &{\n" 363 "\t" "yield 12;\n" 364 "};\n\n" 365 "export fn main() void = ({\n" 366 "\t" "yield err;\n" 367 "})!;\n\n" 368 "export fn main() void = &(if (true) 1 else 2);\n\n" 369 "export fn main() void = (a + b): uintptr: size;\n"); 370 };