harec

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

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