harec

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

12-loops.ha (2448B)


      1 use rt::{compile, exited, EXIT_SUCCESS};
      2 
      3 fn scope() void = {
      4 	let x = 0;
      5 	for (let i = 1; i == 1; i += 1) {
      6 		for (true) {
      7 			assert(x == 0);
      8 			assert(i == 1);
      9 			break;
     10 		};
     11 	};
     12 	assert(compile("fn test() void = { for (true) { let x = 10; }; x; };") as exited != EXIT_SUCCESS);
     13 	// To make sure that the afterthought is part of the loop's scope
     14 	for (let i = 0; true; (if (true) { break; })) true;
     15 };
     16 
     17 fn conditional() void = {
     18 	let i = 1;
     19 	for (i < 10) {
     20 		i *= 2;
     21 	};
     22 	assert(i == 16);
     23 };
     24 
     25 fn afterthought() void = {
     26 	let i = 1;
     27 	for (i < 5; i += 1) {
     28 		i *= 2;
     29 	};
     30 	assert(i == 7);
     31 };
     32 
     33 fn binding() void = {
     34 	let x = 0;
     35 	for (let i = 0; i < 10; i += 1) {
     36 		i *= 2;
     37 		x += 1;
     38 	};
     39 	assert(x == 4);
     40 };
     41 
     42 fn _break() void = {
     43 	let x = 0;
     44 	for (let i = 0; i < 1; i += 1) {
     45 		let j = 0;
     46 		for (j < 10) {
     47 			j += 1;
     48 			if (j == 5) {
     49 				break;
     50 			};
     51 		};
     52 		assert(j == 5);
     53 		x += 1;
     54 	};
     55 	assert(x == 1);
     56 };
     57 
     58 fn _continue() void = {
     59 	let done = false;
     60 	let x = 0;
     61 	for (!done) {
     62 		for (let i = 0; i < 10; i += 1) {
     63 			if (i == 5) {
     64 				continue;
     65 			};
     66 			assert(i != 5);
     67 		};
     68 		done = true;
     69 		x += 1;
     70 	};
     71 	assert(x == 1);
     72 };
     73 
     74 fn label() void = {
     75 	let i = 0;
     76 	for (i < 10) :outer {
     77 		for (let j = 0; j < 7; j += 1) :inner {
     78 			i += 1;
     79 			if (j == 6) {
     80 				for (let k = 0; k < 5; k += 1) {
     81 					if (k == 2) {
     82 						continue :inner;
     83 					};
     84 					assert(k < 2);
     85 				};
     86 			};
     87 			assert(j != 6);
     88 			if (i > 7) {
     89 				break :outer;
     90 			};
     91 		};
     92 	};
     93 	assert(i == 8);
     94 	assert(compile("fn test() void = { :foo for (true) { break :bar; }; };") as exited != EXIT_SUCCESS);
     95 	assert(compile("fn test() void = { for (true) { break :bar; }; };") as exited != EXIT_SUCCESS);
     96 	assert(compile("fn test() void = { break :bar; };") as exited != EXIT_SUCCESS);
     97 	assert(compile("fn test() void = { :foo for (true) { :foo for (true) void; } ; };") as exited != EXIT_SUCCESS);
     98 	assert(compile("fn test() void = :foo { break :foo; };") as exited != EXIT_SUCCESS);
     99 	assert(compile("fn test() void = { for (true) { { break; }; void; }; };") as exited != EXIT_SUCCESS);
    100 };
    101 
    102 type abool = bool;
    103 
    104 fn alias() void = {
    105 	for (true: abool) {
    106 		return;
    107 	};
    108 	abort("unreachable");
    109 };
    110 
    111 fn _static() void = {
    112 	let count = 0z;
    113 	for (let i = 0z; i < 2; i += 1) {
    114 		for (static let j = 0z; j < 5; j += 1) {
    115 			count += 1;
    116 		};
    117 	};
    118 	assert(count == 5);
    119 };
    120 
    121 export fn main() void = {
    122 	scope();
    123 	conditional();
    124 	afterthought();
    125 	binding();
    126 	_break();
    127 	_continue();
    128 	label();
    129 	alias();
    130 	_static();
    131 };