2017-01-05 00:57:48 -08:00
|
|
|
const assert = @import("std").debug.assert;
|
|
|
|
|
2017-05-04 07:18:01 -07:00
|
|
|
test "while loop" {
|
2016-12-21 22:20:08 -08:00
|
|
|
var i : i32 = 0;
|
|
|
|
while (i < 4) {
|
|
|
|
i += 1;
|
|
|
|
}
|
|
|
|
assert(i == 4);
|
|
|
|
assert(whileLoop1() == 1);
|
|
|
|
}
|
2018-01-25 01:10:11 -08:00
|
|
|
fn whileLoop1() i32 {
|
2016-12-21 22:20:08 -08:00
|
|
|
return whileLoop2();
|
|
|
|
}
|
2018-01-25 01:10:11 -08:00
|
|
|
fn whileLoop2() i32 {
|
2016-12-21 22:20:08 -08:00
|
|
|
while (true) {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
2017-05-04 07:18:01 -07:00
|
|
|
test "static eval while" {
|
2016-12-21 22:20:08 -08:00
|
|
|
assert(static_eval_while_number == 1);
|
|
|
|
}
|
|
|
|
const static_eval_while_number = staticWhileLoop1();
|
2018-01-25 01:10:11 -08:00
|
|
|
fn staticWhileLoop1() i32 {
|
2016-12-21 22:20:08 -08:00
|
|
|
return whileLoop2();
|
|
|
|
}
|
2018-01-25 01:10:11 -08:00
|
|
|
fn staticWhileLoop2() i32 {
|
2016-12-21 22:20:08 -08:00
|
|
|
while (true) {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-04 07:18:01 -07:00
|
|
|
test "continue and break" {
|
2016-12-21 22:42:30 -08:00
|
|
|
runContinueAndBreakTest();
|
|
|
|
assert(continue_and_break_counter == 8);
|
|
|
|
}
|
|
|
|
var continue_and_break_counter: i32 = 0;
|
2018-01-25 01:10:11 -08:00
|
|
|
fn runContinueAndBreakTest() void {
|
2016-12-21 22:42:30 -08:00
|
|
|
var i : i32 = 0;
|
|
|
|
while (true) {
|
|
|
|
continue_and_break_counter += 2;
|
|
|
|
i += 1;
|
|
|
|
if (i < 4) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
assert(i == 4);
|
|
|
|
}
|
|
|
|
|
2017-05-04 07:18:01 -07:00
|
|
|
test "return with implicit cast from while loop" {
|
2018-01-08 21:07:01 -08:00
|
|
|
returnWithImplicitCastFromWhileLoopTest() catch unreachable;
|
2016-12-21 22:42:30 -08:00
|
|
|
}
|
2018-02-02 11:26:14 -08:00
|
|
|
fn returnWithImplicitCastFromWhileLoopTest() error!void {
|
2016-12-21 22:42:30 -08:00
|
|
|
while (true) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-04 07:18:01 -07:00
|
|
|
test "while with continue expression" {
|
2016-12-21 22:42:30 -08:00
|
|
|
var sum: i32 = 0;
|
2017-05-03 15:12:07 -07:00
|
|
|
{var i: i32 = 0; while (i < 10) : (i += 1) {
|
2016-12-21 22:42:30 -08:00
|
|
|
if (i == 5) continue;
|
|
|
|
sum += i;
|
|
|
|
}}
|
|
|
|
assert(sum == 40);
|
|
|
|
}
|
2017-05-04 07:18:01 -07:00
|
|
|
|
|
|
|
test "while with else" {
|
|
|
|
var sum: i32 = 0;
|
|
|
|
var i: i32 = 0;
|
|
|
|
var got_else: i32 = 0;
|
|
|
|
while (i < 10) : (i += 1) {
|
|
|
|
sum += 1;
|
|
|
|
} else {
|
|
|
|
got_else += 1;
|
|
|
|
}
|
|
|
|
assert(sum == 10);
|
|
|
|
assert(got_else == 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
test "while with nullable as condition" {
|
|
|
|
numbers_left = 10;
|
|
|
|
var sum: i32 = 0;
|
|
|
|
while (getNumberOrNull()) |value| {
|
|
|
|
sum += value;
|
|
|
|
}
|
|
|
|
assert(sum == 45);
|
|
|
|
}
|
|
|
|
|
|
|
|
test "while with nullable as condition with else" {
|
|
|
|
numbers_left = 10;
|
|
|
|
var sum: i32 = 0;
|
|
|
|
var got_else: i32 = 0;
|
|
|
|
while (getNumberOrNull()) |value| {
|
|
|
|
sum += value;
|
|
|
|
assert(got_else == 0);
|
|
|
|
} else {
|
|
|
|
got_else += 1;
|
|
|
|
}
|
|
|
|
assert(sum == 45);
|
|
|
|
assert(got_else == 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
test "while with error union condition" {
|
|
|
|
numbers_left = 10;
|
|
|
|
var sum: i32 = 0;
|
|
|
|
var got_else: i32 = 0;
|
|
|
|
while (getNumberOrErr()) |value| {
|
|
|
|
sum += value;
|
|
|
|
} else |err| {
|
|
|
|
assert(err == error.OutOfNumbers);
|
|
|
|
got_else += 1;
|
|
|
|
}
|
|
|
|
assert(sum == 45);
|
|
|
|
assert(got_else == 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
var numbers_left: i32 = undefined;
|
2018-02-02 11:26:14 -08:00
|
|
|
fn getNumberOrErr() error!i32 {
|
2017-12-21 21:50:30 -08:00
|
|
|
return if (numbers_left == 0)
|
2017-05-04 07:18:01 -07:00
|
|
|
error.OutOfNumbers
|
2017-12-21 21:50:30 -08:00
|
|
|
else x: {
|
2017-05-04 07:18:01 -07:00
|
|
|
numbers_left -= 1;
|
2017-12-21 21:50:30 -08:00
|
|
|
break :x numbers_left;
|
2017-05-04 07:18:01 -07:00
|
|
|
};
|
|
|
|
}
|
2018-01-25 01:10:11 -08:00
|
|
|
fn getNumberOrNull() ?i32 {
|
2017-12-21 21:50:30 -08:00
|
|
|
return if (numbers_left == 0)
|
2017-05-04 07:18:01 -07:00
|
|
|
null
|
2017-12-21 21:50:30 -08:00
|
|
|
else x: {
|
2017-05-04 07:18:01 -07:00
|
|
|
numbers_left -= 1;
|
2017-12-21 21:50:30 -08:00
|
|
|
break :x numbers_left;
|
2017-05-04 07:18:01 -07:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2017-05-04 09:43:11 -07:00
|
|
|
test "while on nullable with else result follow else prong" {
|
|
|
|
const result = while (returnNull()) |value| {
|
|
|
|
break value;
|
2017-12-21 21:50:30 -08:00
|
|
|
} else i32(2);
|
2017-05-04 09:43:11 -07:00
|
|
|
assert(result == 2);
|
|
|
|
}
|
|
|
|
|
|
|
|
test "while on nullable with else result follow break prong" {
|
|
|
|
const result = while (returnMaybe(10)) |value| {
|
|
|
|
break value;
|
2017-12-21 21:50:30 -08:00
|
|
|
} else i32(2);
|
2017-05-04 09:43:11 -07:00
|
|
|
assert(result == 10);
|
|
|
|
}
|
|
|
|
|
|
|
|
test "while on error union with else result follow else prong" {
|
|
|
|
const result = while (returnError()) |value| {
|
|
|
|
break value;
|
2017-12-21 21:50:30 -08:00
|
|
|
} else |err| i32(2);
|
2017-05-04 09:43:11 -07:00
|
|
|
assert(result == 2);
|
|
|
|
}
|
|
|
|
|
|
|
|
test "while on error union with else result follow break prong" {
|
|
|
|
const result = while (returnSuccess(10)) |value| {
|
|
|
|
break value;
|
2017-12-21 21:50:30 -08:00
|
|
|
} else |err| i32(2);
|
2017-05-04 09:43:11 -07:00
|
|
|
assert(result == 10);
|
|
|
|
}
|
|
|
|
|
|
|
|
test "while on bool with else result follow else prong" {
|
|
|
|
const result = while (returnFalse()) {
|
|
|
|
break i32(10);
|
2017-12-21 21:50:30 -08:00
|
|
|
} else i32(2);
|
2017-05-04 09:43:11 -07:00
|
|
|
assert(result == 2);
|
|
|
|
}
|
|
|
|
|
|
|
|
test "while on bool with else result follow break prong" {
|
|
|
|
const result = while (returnTrue()) {
|
|
|
|
break i32(10);
|
2017-12-21 21:50:30 -08:00
|
|
|
} else i32(2);
|
2017-05-04 09:43:11 -07:00
|
|
|
assert(result == 10);
|
|
|
|
}
|
|
|
|
|
2017-12-20 19:55:24 -08:00
|
|
|
test "break from outer while loop" {
|
|
|
|
testBreakOuter();
|
|
|
|
comptime testBreakOuter();
|
|
|
|
}
|
|
|
|
|
2018-01-25 01:10:11 -08:00
|
|
|
fn testBreakOuter() void {
|
2017-12-20 19:55:24 -08:00
|
|
|
outer: while (true) {
|
|
|
|
while (true) {
|
|
|
|
break :outer;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
test "continue outer while loop" {
|
|
|
|
testContinueOuter();
|
|
|
|
comptime testContinueOuter();
|
|
|
|
}
|
|
|
|
|
2018-01-25 01:10:11 -08:00
|
|
|
fn testContinueOuter() void {
|
2017-12-20 19:55:24 -08:00
|
|
|
var i: usize = 0;
|
|
|
|
outer: while (i < 10) : (i += 1) {
|
|
|
|
while (true) {
|
|
|
|
continue :outer;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-01-25 01:10:11 -08:00
|
|
|
fn returnNull() ?i32 { return null; }
|
|
|
|
fn returnMaybe(x: i32) ?i32 { return x; }
|
2018-02-02 11:26:14 -08:00
|
|
|
fn returnError() error!i32 { return error.YouWantedAnError; }
|
|
|
|
fn returnSuccess(x: i32) error!i32 { return x; }
|
2018-01-25 01:10:11 -08:00
|
|
|
fn returnFalse() bool { return false; }
|
|
|
|
fn returnTrue() bool { return true; }
|