hare

[hare] The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

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 };