zig/test/self_hosted2.zig

306 lines
6.1 KiB
Zig
Raw Normal View History

2016-11-26 17:52:22 -08:00
const case_namespace_fn_call = @import("cases/namespace_fn_call.zig");
pub const SYS_write = 1;
pub const SYS_exit = 60;
pub const stdout_fileno = 1;
2016-11-21 12:36:25 -08:00
// normal comment
/// this is a documentation comment
/// doc comment line 2
fn emptyFunctionWithComments() {
}
export fn disabledExternFn() {
@setFnVisible(this, false);
}
2016-11-23 23:44:03 -08:00
fn inlinedLoop() {
inline var i = 0;
inline var sum = 0;
inline while (i <= 5; i += 1)
sum += i;
assert(sum == 15);
}
2016-11-26 01:03:39 -08:00
fn switchWithNumbers() {
testSwitchWithNumbers(13);
}
fn testSwitchWithNumbers(x: u32) {
const result = switch (x) {
1, 2, 3, 4 ... 8 => false,
13 => true,
else => false,
};
assert(result);
}
fn switchWithAllRanges() {
assert(testSwitchWithAllRanges(50, 3) == 1);
assert(testSwitchWithAllRanges(101, 0) == 2);
assert(testSwitchWithAllRanges(300, 5) == 3);
assert(testSwitchWithAllRanges(301, 6) == 6);
}
fn testSwitchWithAllRanges(x: u32, y: u32) -> u32 {
switch (x) {
0 ... 100 => 1,
101 ... 200 => 2,
201 ... 300 => 3,
else => y,
}
}
2016-11-26 12:38:07 -08:00
fn testInlineSwitch() {
const x = 3 + 4;
const result = inline switch (x) {
3 => 10,
4 => 11,
5, 6 => 12,
7, 8 => 13,
else => 14,
};
assert(result + 1 == 14);
}
2016-11-26 17:52:22 -08:00
fn testNamespaceFnCall() {
assert(case_namespace_fn_call.foo() == 1234);
}
2016-11-26 20:16:38 -08:00
fn gotoAndLabels() {
gotoLoop();
assert(goto_counter == 10);
}
fn gotoLoop() {
var i: i32 = 0;
goto cond;
loop:
i += 1;
cond:
if (!(i < 10)) goto end;
goto_counter += 1;
goto loop;
end:
}
var goto_counter: i32 = 0;
struct FooA {
fn add(a: i32, b: i32) -> i32 { a + b }
}
const foo_a = FooA {};
fn testStructStatic() {
const result = FooA.add(3, 4);
assert(result == 7);
}
2016-12-04 20:52:43 -08:00
const should_be_11 = FooA.add(5, 6);
fn testStaticFnEval() {
assert(should_be_11 == 11);
}
fn fib(x: i32) -> i32 {
if (x < 2) x else fib(x - 1) + fib(x - 2)
}
const fib_7 = fib(7);
fn testCompileTimeFib() {
assert(fib_7 == 13);
}
2016-12-05 02:12:05 -08:00
fn max(inline T: type, a: T, b: T) -> T {
if (a > b) a else b
}
const the_max = max(u32, 1234, 5678);
fn testCompileTimeGenericEval() {
assert(the_max == 5678);
}
fn gimmeTheBigOne(a: u32, b: u32) -> u32 {
max(u32, a, b)
}
fn shouldCallSameInstance(a: u32, b: u32) -> u32 {
max(u32, a, b)
}
fn sameButWithFloats(a: f64, b: f64) -> f64 {
max(f64, a, b)
}
fn testFnWithInlineArgs() {
assert(gimmeTheBigOne(1234, 5678) == 5678);
assert(shouldCallSameInstance(34, 12) == 34);
assert(sameButWithFloats(0.43, 0.49) == 0.49);
}
2016-12-04 20:52:43 -08:00
2016-12-05 15:43:16 -08:00
fn testContinueInForLoop() {
const array = []i32 {1, 2, 3, 4, 5};
var sum : i32 = 0;
for (array) |x| {
sum += x;
if (x < 3) {
continue;
}
break;
}
assert(sum == 6);
}
fn shortCircuit() {
var hit_1 = false;
var hit_2 = false;
var hit_3 = false;
var hit_4 = false;
if (true || {assert(false); false}) {
hit_1 = true;
}
if (false || { hit_2 = true; false }) {
assert(false);
}
if (true && { hit_3 = true; false }) {
assert(false);
}
if (false && {assert(false); false}) {
assert(false);
} else {
hit_4 = true;
}
assert(hit_1);
assert(hit_2);
assert(hit_3);
assert(hit_4);
}
2016-12-06 18:26:17 -08:00
fn testGotoLeaveDeferScope(b: bool) {
var it_worked = false;
goto entry;
exit:
if (it_worked) {
return;
}
@unreachable();
entry:
defer it_worked = true;
if (it_worked) @unreachable();
if (b) goto exit;
}
fn unwrapAndAddOne(blah: ?i32) -> i32 {
return ??blah + 1;
}
const should_be_1235 = unwrapAndAddOne(1234);
fn testStaticAddOne() {
assert(should_be_1235 == 1235);
}
2016-12-06 18:26:17 -08:00
fn gimme1or2(inline a: bool) -> i32 {
const x: i32 = 1;
const y: i32 = 2;
inline var z: i32 = inline if (a) x else y;
return z;
}
fn testInlineVarsAgain() {
assert(gimme1or2(true) == 1);
assert(gimme1or2(false) == 2);
}
fn testMinValueAndMaxValue() {
assert(@maxValue(u8) == 255);
assert(@maxValue(u16) == 65535);
assert(@maxValue(u32) == 4294967295);
assert(@maxValue(u64) == 18446744073709551615);
assert(@maxValue(i8) == 127);
assert(@maxValue(i16) == 32767);
assert(@maxValue(i32) == 2147483647);
assert(@maxValue(i64) == 9223372036854775807);
assert(@minValue(u8) == 0);
assert(@minValue(u16) == 0);
assert(@minValue(u32) == 0);
assert(@minValue(u64) == 0);
assert(@minValue(i8) == -128);
assert(@minValue(i16) == -32768);
assert(@minValue(i32) == -2147483648);
assert(@minValue(i64) == -9223372036854775808);
}
2016-12-05 15:43:16 -08:00
2016-11-23 23:44:03 -08:00
fn assert(ok: bool) {
if (!ok)
@unreachable();
}
2016-11-21 12:36:25 -08:00
fn runAllTests() {
emptyFunctionWithComments();
disabledExternFn();
2016-11-23 23:44:03 -08:00
inlinedLoop();
2016-11-26 01:03:39 -08:00
switchWithNumbers();
switchWithAllRanges();
2016-11-26 12:38:07 -08:00
testInlineSwitch();
2016-11-26 17:52:22 -08:00
testNamespaceFnCall();
2016-11-26 20:16:38 -08:00
gotoAndLabels();
testStructStatic();
2016-12-04 20:52:43 -08:00
testStaticFnEval();
testCompileTimeFib();
2016-12-05 02:12:05 -08:00
testCompileTimeGenericEval();
testFnWithInlineArgs();
2016-12-05 15:43:16 -08:00
testContinueInForLoop();
shortCircuit();
2016-12-06 18:26:17 -08:00
testGotoLeaveDeferScope(true);
testStaticAddOne();
testInlineVarsAgain();
testMinValueAndMaxValue();
2016-11-21 12:36:25 -08:00
}
export nakedcc fn _start() -> unreachable {
myMain();
}
fn myMain() -> unreachable {
2016-11-21 12:36:25 -08:00
runAllTests();
const text = "OK\n";
write(stdout_fileno, &text[0], text.len);
exit(0);
}
pub inline fn syscall1(number: usize, arg1: usize) -> usize {
asm volatile ("syscall"
: [ret] "={rax}" (-> usize)
: [number] "{rax}" (number),
[arg1] "{rdi}" (arg1)
: "rcx", "r11")
}
pub inline fn syscall3(number: usize, arg1: usize, arg2: usize, arg3: usize) -> usize {
asm volatile ("syscall"
: [ret] "={rax}" (-> usize)
: [number] "{rax}" (number),
[arg1] "{rdi}" (arg1),
[arg2] "{rsi}" (arg2),
[arg3] "{rdx}" (arg3)
: "rcx", "r11")
}
pub fn write(fd: i32, buf: &const u8, count: usize) -> usize {
syscall3(SYS_write, usize(fd), usize(buf), count)
}
pub fn exit(status: i32) -> unreachable {
syscall1(SYS_exit, usize(status));
@unreachable()
}