harec

[hare] Hare compiler, written in C11 for POSIX OSs
Log | Files | Refs | README | LICENSE

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