IR: start a new passing self hosted test suite
parent
09c34352f8
commit
6b2d06710c
|
@ -2286,9 +2286,11 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
|
|||
case IrInstructionIdEnumTag:
|
||||
return ir_render_enum_tag(g, executable, (IrInstructionEnumTag *)instruction);
|
||||
case IrInstructionIdSwitchVar:
|
||||
zig_panic("TODO render switch var instruction to LLVM");
|
||||
case IrInstructionIdContainerInitList:
|
||||
zig_panic("TODO render container init list instruction to LLVM");
|
||||
case IrInstructionIdStructInit:
|
||||
zig_panic("TODO render more IR instructions to LLVM");
|
||||
zig_panic("TODO render struct init to LLVM");
|
||||
}
|
||||
zig_unreachable();
|
||||
}
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
pub fn foo() -> %i32 {
|
||||
const x = %return bar();
|
||||
return x + 1
|
||||
}
|
||||
|
||||
pub fn bar() -> %i32 {
|
||||
return 13;
|
||||
}
|
||||
|
||||
pub fn baz() -> %i32 {
|
||||
const y = foo() %% 1234;
|
||||
return y + 1;
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
fn cmpxchg() {
|
||||
@setFnTest(this);
|
||||
|
||||
var x: i32 = 1234;
|
||||
while (!@cmpxchg(&x, 1234, 5678, AtomicOrder.SeqCst, AtomicOrder.SeqCst)) {}
|
||||
assert(x == 5678);
|
||||
}
|
||||
|
||||
fn fence() {
|
||||
@setFnTest(this);
|
||||
|
||||
var x: i32 = 1234;
|
||||
@fence(AtomicOrder.SeqCst);
|
||||
x = 5678;
|
||||
}
|
||||
|
||||
// TODO const assert = @import("std").debug.assert;
|
||||
fn assert(ok: bool) {
|
||||
if (!ok)
|
||||
@unreachable();
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
export fn disabledExternFn() {
|
||||
@setFnVisible(this, false);
|
||||
}
|
||||
|
||||
fn callDisabledExternFn() {
|
||||
@setFnTest(this);
|
||||
disabledExternFn();
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
// normal comment
|
||||
/// this is a documentation comment
|
||||
/// doc comment line 2
|
||||
fn emptyFunctionWithComments() {
|
||||
@setFnTest(this);
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
pub fn foo() -> %i32 {
|
||||
const x = %return bar();
|
||||
return x + 1
|
||||
}
|
||||
|
||||
pub fn bar() -> %i32 {
|
||||
return 13;
|
||||
}
|
||||
|
||||
pub fn baz() -> %i32 {
|
||||
const y = foo() %% 1234;
|
||||
return y + 1;
|
||||
}
|
||||
|
||||
fn errorWrapping() {
|
||||
@setFnTest(this);
|
||||
|
||||
assert(%%baz() == 15);
|
||||
}
|
||||
|
||||
// TODO const assert = @import("std").debug.assert;
|
||||
fn assert(ok: bool) {
|
||||
if (!ok)
|
||||
@unreachable();
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
fn continueInForLoop() {
|
||||
@setFnTest(this);
|
||||
|
||||
const array = []i32 {1, 2, 3, 4, 5};
|
||||
var sum : i32 = 0;
|
||||
for (array) |x| {
|
||||
sum += x;
|
||||
if (x < 3) {
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (sum != 6) @unreachable()
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
fn simpleGenericFn() {
|
||||
@setFnTest(this);
|
||||
|
||||
assert(max(i32, 3, -1) == 3);
|
||||
assert(max(f32, 0.123, 0.456) == 0.456);
|
||||
assert(add(2, 3) == 5);
|
||||
}
|
||||
|
||||
fn max(inline T: type, a: T, b: T) -> T {
|
||||
return if (a > b) a else b;
|
||||
}
|
||||
|
||||
fn add(inline a: i32, b: i32) -> i32 {
|
||||
return @staticEval(a) + b;
|
||||
}
|
||||
|
||||
const the_max = max(u32, 1234, 5678);
|
||||
fn compileTimeGenericEval() {
|
||||
@setFnTest(this);
|
||||
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 fnWithInlineArgs() {
|
||||
@setFnTest(this);
|
||||
|
||||
assert(gimmeTheBigOne(1234, 5678) == 5678);
|
||||
assert(shouldCallSameInstance(34, 12) == 34);
|
||||
assert(sameButWithFloats(0.43, 0.49) == 0.49);
|
||||
}
|
||||
|
||||
|
||||
// TODO const assert = @import("std").debug.assert;
|
||||
fn assert(ok: bool) {
|
||||
if (!ok)
|
||||
@unreachable();
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
fn gotoAndLabels() {
|
||||
@setFnTest(this);
|
||||
|
||||
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;
|
||||
|
||||
|
||||
|
||||
fn gotoLeaveDeferScope() {
|
||||
@setFnTest(this);
|
||||
|
||||
testGotoLeaveDeferScope(true);
|
||||
}
|
||||
fn testGotoLeaveDeferScope(b: bool) {
|
||||
var it_worked = false;
|
||||
|
||||
goto entry;
|
||||
exit:
|
||||
if (it_worked) {
|
||||
return;
|
||||
}
|
||||
@unreachable();
|
||||
entry:
|
||||
defer it_worked = true;
|
||||
if (b) goto exit;
|
||||
}
|
||||
|
||||
// TODO const assert = @import("std").debug.assert;
|
||||
fn assert(ok: bool) {
|
||||
if (!ok)
|
||||
@unreachable();
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
|
||||
fn inlinedLoop() {
|
||||
@setFnTest(this);
|
||||
|
||||
inline var i = 0;
|
||||
inline var sum = 0;
|
||||
inline while (i <= 5; i += 1)
|
||||
sum += i;
|
||||
assert(sum == 15);
|
||||
}
|
||||
|
||||
// TODO const assert = @import("std").debug.assert;
|
||||
fn assert(ok: bool) {
|
||||
if (!ok)
|
||||
@unreachable();
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
fn exactDivision() {
|
||||
@setFnTest(this);
|
||||
|
||||
assert(divExact(55, 11) == 5);
|
||||
}
|
||||
fn divExact(a: u32, b: u32) -> u32 {
|
||||
@divExact(a, b)
|
||||
}
|
||||
|
||||
fn floatDivision() {
|
||||
@setFnTest(this);
|
||||
|
||||
assert(fdiv32(12.0, 3.0) == 4.0);
|
||||
}
|
||||
fn fdiv32(a: f32, b: f32) -> f32 {
|
||||
a / b
|
||||
}
|
||||
|
||||
fn overflowIntrinsics() {
|
||||
@setFnTest(this);
|
||||
|
||||
var result: u8 = undefined;
|
||||
assert(@addWithOverflow(u8, 250, 100, &result));
|
||||
assert(!@addWithOverflow(u8, 100, 150, &result));
|
||||
assert(result == 250);
|
||||
}
|
||||
|
||||
fn shlWithOverflow() {
|
||||
@setFnTest(this);
|
||||
|
||||
var result: u16 = undefined;
|
||||
assert(@shlWithOverflow(u16, 0b0010111111111111, 3, &result));
|
||||
assert(!@shlWithOverflow(u16, 0b0010111111111111, 2, &result));
|
||||
assert(result == 0b1011111111111100);
|
||||
}
|
||||
|
||||
fn countLeadingZeroes() {
|
||||
@setFnTest(this);
|
||||
|
||||
assert(@clz(u8(0b00001010)) == 4);
|
||||
assert(@clz(u8(0b10001010)) == 0);
|
||||
assert(@clz(u8(0b00000000)) == 8);
|
||||
}
|
||||
|
||||
fn countTrailingZeroes() {
|
||||
@setFnTest(this);
|
||||
|
||||
assert(@ctz(u8(0b10100000)) == 5);
|
||||
assert(@ctz(u8(0b10001010)) == 1);
|
||||
assert(@ctz(u8(0b00000000)) == 8);
|
||||
}
|
||||
|
||||
// TODO const assert = @import("std").debug.assert;
|
||||
fn assert(ok: bool) {
|
||||
if (!ok)
|
||||
@unreachable();
|
||||
}
|
||||
|
|
@ -0,0 +1,111 @@
|
|||
fn intTypeBuiltin() {
|
||||
@setFnTest(this);
|
||||
|
||||
assert(@intType(true, 8) == i8);
|
||||
assert(@intType(true, 16) == i16);
|
||||
assert(@intType(true, 32) == i32);
|
||||
assert(@intType(true, 64) == i64);
|
||||
|
||||
assert(@intType(false, 8) == u8);
|
||||
assert(@intType(false, 16) == u16);
|
||||
assert(@intType(false, 32) == u32);
|
||||
assert(@intType(false, 64) == u64);
|
||||
|
||||
assert(i8.bit_count == 8);
|
||||
assert(i16.bit_count == 16);
|
||||
assert(i32.bit_count == 32);
|
||||
assert(i64.bit_count == 64);
|
||||
|
||||
assert(i8.is_signed);
|
||||
assert(i16.is_signed);
|
||||
assert(i32.is_signed);
|
||||
assert(i64.is_signed);
|
||||
assert(isize.is_signed);
|
||||
|
||||
assert(!u8.is_signed);
|
||||
assert(!u16.is_signed);
|
||||
assert(!u32.is_signed);
|
||||
assert(!u64.is_signed);
|
||||
assert(!usize.is_signed);
|
||||
}
|
||||
|
||||
fn minValueAndMaxValue() {
|
||||
@setFnTest(this);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
fn shortCircuit() {
|
||||
@setFnTest(this);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
fn truncate() {
|
||||
@setFnTest(this);
|
||||
|
||||
assert(testTruncate(0x10fd) == 0xfd);
|
||||
}
|
||||
fn testTruncate(x: u32) -> u8 {
|
||||
@truncate(u8, x)
|
||||
}
|
||||
|
||||
fn assignToIfVarPtr() {
|
||||
@setFnTest(this);
|
||||
|
||||
var maybe_bool: ?bool = true;
|
||||
|
||||
if (const *b ?= maybe_bool) {
|
||||
*b = false;
|
||||
}
|
||||
|
||||
assert(??maybe_bool == false);
|
||||
}
|
||||
|
||||
|
||||
// TODO const assert = @import("std").debug.assert;
|
||||
fn assert(ok: bool) {
|
||||
if (!ok)
|
||||
@unreachable();
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
fn switchWithNumbers() {
|
||||
@setFnTest(this);
|
||||
|
||||
testSwitchWithNumbers(13);
|
||||
}
|
||||
|
||||
fn testSwitchWithNumbers(x: u32) {
|
||||
const result = switch (x) {
|
||||
1, 2, 3, 4 ... 8 => false,
|
||||
13 => true,
|
||||
else => false,
|
||||
};
|
||||
assert(result);
|
||||
}
|
||||
|
||||
fn switchWithAllRanges() {
|
||||
@setFnTest(this);
|
||||
|
||||
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,
|
||||
}
|
||||
}
|
||||
|
||||
fn inlineSwitch() {
|
||||
@setFnTest(this);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
// TODO const assert = @import("std").debug.assert;
|
||||
fn assert(ok: bool) {
|
||||
if (!ok)
|
||||
@unreachable();
|
||||
}
|
|
@ -2,7 +2,6 @@ const std = @import("std");
|
|||
const assert = std.debug.assert;
|
||||
const str = std.str;
|
||||
const cstr = std.cstr;
|
||||
// TODO '_' identifier for unused variable bindings
|
||||
const test_return_type_type = @import("cases/return_type_type.zig");
|
||||
const test_zeroes = @import("cases/zeroes.zig");
|
||||
const test_sizeof_and_typeof = @import("cases/sizeof_and_typeof.zig");
|
||||
|
@ -16,12 +15,6 @@ const test_enum_with_members = @import("cases/enum_with_members.zig");
|
|||
const test_struct_contains_slice_of_itself = @import("cases/struct_contains_slice_of_itself.zig");
|
||||
const test_this = @import("cases/this.zig");
|
||||
|
||||
// normal comment
|
||||
/// this is a documentation comment
|
||||
/// doc comment line 2
|
||||
fn emptyFunctionWithComments() {
|
||||
@setFnTest(this, true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -129,41 +122,6 @@ fn getArrayLen(a: []u32) -> usize {
|
|||
a.len
|
||||
}
|
||||
|
||||
fn shortCircuit() {
|
||||
@setFnTest(this, true);
|
||||
|
||||
var hit_1 = false;
|
||||
var hit_2 = false;
|
||||
var hit_3 = false;
|
||||
var hit_4 = false;
|
||||
|
||||
if (true || {assertRuntime(false); false}) {
|
||||
hit_1 = true;
|
||||
}
|
||||
if (false || { hit_2 = true; false }) {
|
||||
assertRuntime(false);
|
||||
}
|
||||
|
||||
if (true && { hit_3 = true; false }) {
|
||||
assertRuntime(false);
|
||||
}
|
||||
if (false && {assertRuntime(false); false}) {
|
||||
assertRuntime(false);
|
||||
} else {
|
||||
hit_4 = true;
|
||||
}
|
||||
assert(hit_1);
|
||||
assert(hit_2);
|
||||
assert(hit_3);
|
||||
assert(hit_4);
|
||||
}
|
||||
|
||||
fn assertRuntime(b: bool) {
|
||||
@setFnStaticEval(this, false);
|
||||
|
||||
if (!b) @unreachable()
|
||||
}
|
||||
|
||||
fn modifyOperators() {
|
||||
@setFnTest(this, true);
|
||||
|
||||
|
@ -505,22 +463,6 @@ enum AnEnumWithPayload {
|
|||
}
|
||||
|
||||
|
||||
fn continueInForLoop() {
|
||||
@setFnTest(this, true);
|
||||
|
||||
const array = []i32 {1, 2, 3, 4, 5};
|
||||
var sum : i32 = 0;
|
||||
for (array) |x| {
|
||||
sum += x;
|
||||
if (x < 3) {
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (sum != 6) @unreachable()
|
||||
}
|
||||
|
||||
|
||||
fn castBoolToInt() {
|
||||
@setFnTest(this, true);
|
||||
|
||||
|
@ -727,23 +669,6 @@ struct ArrayDotLenConstExpr {
|
|||
const some_array = []u8 {0, 1, 2, 3};
|
||||
|
||||
|
||||
fn countLeadingZeroes() {
|
||||
@setFnTest(this, true);
|
||||
|
||||
assert(@clz(u8, 0b00001010) == 4);
|
||||
assert(@clz(u8, 0b10001010) == 0);
|
||||
assert(@clz(u8, 0b00000000) == 8);
|
||||
}
|
||||
|
||||
fn countTrailingZeroes() {
|
||||
@setFnTest(this, true);
|
||||
|
||||
assert(@ctz(u8, 0b10100000) == 5);
|
||||
assert(@ctz(u8, 0b10001010) == 1);
|
||||
assert(@ctz(u8, 0b00000000) == 8);
|
||||
}
|
||||
|
||||
|
||||
fn multilineString() {
|
||||
@setFnTest(this, true);
|
||||
|
||||
|
@ -770,23 +695,6 @@ fn multilineCString() {
|
|||
|
||||
|
||||
|
||||
fn simpleGenericFn() {
|
||||
@setFnTest(this, true);
|
||||
|
||||
assert(max(i32, 3, -1) == 3);
|
||||
assert(max(f32, 0.123, 0.456) == 0.456);
|
||||
assert(add(2, 3) == 5);
|
||||
}
|
||||
|
||||
fn max(inline T: type, a: T, b: T) -> T {
|
||||
return if (a > b) a else b;
|
||||
}
|
||||
|
||||
fn add(inline a: i32, b: i32) -> i32 {
|
||||
return @constEval(a) + b;
|
||||
}
|
||||
|
||||
|
||||
fn constantEqualFunctionPointers() {
|
||||
@setFnTest(this, true);
|
||||
|
||||
|
@ -838,49 +746,6 @@ fn errorNameString() {
|
|||
}
|
||||
|
||||
|
||||
fn gotoAndLabels() {
|
||||
@setFnTest(this, true);
|
||||
|
||||
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;
|
||||
|
||||
|
||||
|
||||
fn gotoLeaveDeferScope() {
|
||||
@setFnTest(this, true);
|
||||
|
||||
testGotoLeaveDeferScope(true);
|
||||
}
|
||||
fn testGotoLeaveDeferScope(b: bool) {
|
||||
@setFnStaticEval(this, false);
|
||||
|
||||
var it_worked = false;
|
||||
|
||||
goto entry;
|
||||
exit:
|
||||
if (it_worked) {
|
||||
return;
|
||||
}
|
||||
@unreachable();
|
||||
entry:
|
||||
defer it_worked = true;
|
||||
if (b) goto exit;
|
||||
}
|
||||
|
||||
|
||||
fn castUndefined() {
|
||||
@setFnTest(this, true);
|
||||
|
||||
|
@ -1112,40 +977,6 @@ fn constantExpressions() {
|
|||
const array_size : u8 = 20;
|
||||
|
||||
|
||||
fn minValueAndMaxValue() {
|
||||
@setFnTest(this, true);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
fn overflowIntrinsics() {
|
||||
@setFnTest(this, true);
|
||||
|
||||
var result: u8 = undefined;
|
||||
assert(@addWithOverflow(u8, 250, 100, &result));
|
||||
assert(!@addWithOverflow(u8, 100, 150, &result));
|
||||
assert(result == 250);
|
||||
}
|
||||
|
||||
|
||||
fn nestedArrays() {
|
||||
@setFnTest(this, true);
|
||||
|
||||
|
@ -1554,22 +1385,6 @@ fn assignToIfVarPtr() {
|
|||
assert(??maybe_bool == false);
|
||||
}
|
||||
|
||||
fn cmpxchg() {
|
||||
@setFnTest(this, true);
|
||||
|
||||
var x: i32 = 1234;
|
||||
while (!@cmpxchg(&x, 1234, 5678, AtomicOrder.SeqCst, AtomicOrder.SeqCst)) {}
|
||||
assert(x == 5678);
|
||||
}
|
||||
|
||||
fn fence() {
|
||||
@setFnTest(this, true);
|
||||
|
||||
var x: i32 = 1234;
|
||||
@fence(AtomicOrder.SeqCst);
|
||||
x = 5678;
|
||||
}
|
||||
|
||||
fn unsignedWrapping() {
|
||||
@setFnTest(this, true);
|
||||
|
||||
|
@ -1648,15 +1463,6 @@ fn testShlWrappingNoeval(x: u16) {
|
|||
assert(shifted == 65534);
|
||||
}
|
||||
|
||||
fn shlWithOverflow() {
|
||||
@setFnTest(this, true);
|
||||
|
||||
var result: u16 = undefined;
|
||||
assert(@shlWithOverflow(u16, 0b0010111111111111, 3, &result));
|
||||
assert(!@shlWithOverflow(u16, 0b0010111111111111, 2, &result));
|
||||
assert(result == 0b1011111111111100);
|
||||
}
|
||||
|
||||
fn cStringConcatenation() {
|
||||
@setFnTest(this, true);
|
||||
|
||||
|
@ -1709,28 +1515,6 @@ fn castSliceToU8Slice() {
|
|||
assert(bytes[11] == @maxValue(u8));
|
||||
}
|
||||
|
||||
fn floatDivision() {
|
||||
@setFnTest(this, true);
|
||||
|
||||
assert(fdiv32(12.0, 3.0) == 4.0);
|
||||
}
|
||||
fn fdiv32(a: f32, b: f32) -> f32 {
|
||||
@setFnStaticEval(this, false);
|
||||
|
||||
a / b
|
||||
}
|
||||
|
||||
fn exactDivision() {
|
||||
@setFnTest(this, true);
|
||||
|
||||
assert(divExact(55, 11) == 5);
|
||||
}
|
||||
fn divExact(a: u32, b: u32) -> u32 {
|
||||
@setFnStaticEval(this, false);
|
||||
|
||||
@divExact(a, b)
|
||||
}
|
||||
|
||||
fn nullLiteralOutsideFunction() {
|
||||
@setFnTest(this, true);
|
||||
|
||||
|
@ -1744,17 +1528,6 @@ const here_is_a_null_literal = SillyStruct {
|
|||
.context = null,
|
||||
};
|
||||
|
||||
fn truncate() {
|
||||
@setFnTest(this, true);
|
||||
|
||||
assert(testTruncate(0x10fd) == 0xfd);
|
||||
}
|
||||
fn testTruncate(x: u32) -> u8 {
|
||||
@setFnStaticEval(this, false);
|
||||
|
||||
@truncate(u8, x)
|
||||
}
|
||||
|
||||
fn constDeclsInStruct() {
|
||||
@setFnTest(this, true);
|
||||
|
||||
|
@ -1794,38 +1567,6 @@ struct DivResult {
|
|||
remainder: u64,
|
||||
}
|
||||
|
||||
fn intTypeBuiltin() {
|
||||
@setFnTest(this, true);
|
||||
|
||||
assert(@intType(true, 8) == i8);
|
||||
assert(@intType(true, 16) == i16);
|
||||
assert(@intType(true, 32) == i32);
|
||||
assert(@intType(true, 64) == i64);
|
||||
|
||||
assert(@intType(false, 8) == u8);
|
||||
assert(@intType(false, 16) == u16);
|
||||
assert(@intType(false, 32) == u32);
|
||||
assert(@intType(false, 64) == u64);
|
||||
|
||||
assert(i8.bit_count == 8);
|
||||
assert(i16.bit_count == 16);
|
||||
assert(i32.bit_count == 32);
|
||||
assert(i64.bit_count == 64);
|
||||
|
||||
assert(i8.is_signed);
|
||||
assert(i16.is_signed);
|
||||
assert(i32.is_signed);
|
||||
assert(i64.is_signed);
|
||||
assert(isize.is_signed);
|
||||
|
||||
assert(!u8.is_signed);
|
||||
assert(!u16.is_signed);
|
||||
assert(!u32.is_signed);
|
||||
assert(!u64.is_signed);
|
||||
assert(!usize.is_signed);
|
||||
|
||||
}
|
||||
|
||||
fn intToEnum() {
|
||||
@setFnTest(this, true);
|
||||
|
||||
|
|
|
@ -1,91 +1,10 @@
|
|||
const case_namespace_fn_call = @import("cases/namespace_fn_call.zig");
|
||||
const case_err_wrapping = @import("cases/err_wrapping.zig");
|
||||
|
||||
pub const SYS_write = 1;
|
||||
pub const SYS_exit = 60;
|
||||
pub const stdout_fileno = 1;
|
||||
|
||||
// normal comment
|
||||
/// this is a documentation comment
|
||||
/// doc comment line 2
|
||||
fn emptyFunctionWithComments() {
|
||||
}
|
||||
|
||||
export fn disabledExternFn() {
|
||||
@setFnVisible(this, false);
|
||||
}
|
||||
|
||||
fn inlinedLoop() {
|
||||
inline var i = 0;
|
||||
inline var sum = 0;
|
||||
inline while (i <= 5; i += 1)
|
||||
sum += i;
|
||||
assert(sum == 15);
|
||||
}
|
||||
|
||||
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,
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
fn testNamespaceFnCall() {
|
||||
assert(case_namespace_fn_call.foo() == 1234);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
|
||||
|
||||
const FooA = struct {
|
||||
fn add(a: i32, b: i32) -> i32 { a + b }
|
||||
|
@ -112,89 +31,6 @@ fn testCompileTimeFib() {
|
|||
assert(fib_7 == 13);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -217,28 +53,6 @@ fn testInlineVarsAgain() {
|
|||
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);
|
||||
}
|
||||
|
||||
fn first4KeysOfHomeRow() -> []const u8 {
|
||||
"aoeu"
|
||||
}
|
||||
|
@ -268,111 +82,8 @@ fn testErrorName() {
|
|||
assert(memeql(@errorName(error.ItBroke), "ItBroke"));
|
||||
}
|
||||
|
||||
//error One;
|
||||
//fn getAnErrorValue (b: bool) -> %i32 {
|
||||
// const result = if (b) error.One else i32(1234);
|
||||
// return result;
|
||||
//}
|
||||
|
||||
fn cmpxchg() {
|
||||
var x: i32 = 1234;
|
||||
while (!@cmpxchg(&x, 1234, 5678, AtomicOrder.SeqCst, AtomicOrder.SeqCst)) {}
|
||||
assert(x == 5678);
|
||||
}
|
||||
|
||||
fn fence() {
|
||||
var x: i32 = 1234;
|
||||
@fence(AtomicOrder.SeqCst);
|
||||
x = 5678;
|
||||
}
|
||||
|
||||
fn exactDivision() {
|
||||
assert(divExact(55, 11) == 5);
|
||||
}
|
||||
fn divExact(a: u32, b: u32) -> u32 {
|
||||
@divExact(a, b)
|
||||
}
|
||||
|
||||
fn truncate() {
|
||||
assert(testTruncate(0x10fd) == 0xfd);
|
||||
}
|
||||
fn testTruncate(x: u32) -> u8 {
|
||||
@truncate(u8, x)
|
||||
}
|
||||
|
||||
fn intTypeBuiltin() {
|
||||
assert(@intType(true, 8) == i8);
|
||||
assert(@intType(true, 16) == i16);
|
||||
assert(@intType(true, 32) == i32);
|
||||
assert(@intType(true, 64) == i64);
|
||||
|
||||
assert(@intType(false, 8) == u8);
|
||||
assert(@intType(false, 16) == u16);
|
||||
assert(@intType(false, 32) == u32);
|
||||
assert(@intType(false, 64) == u64);
|
||||
|
||||
assert(i8.bit_count == 8);
|
||||
assert(i16.bit_count == 16);
|
||||
assert(i32.bit_count == 32);
|
||||
assert(i64.bit_count == 64);
|
||||
|
||||
assert(i8.is_signed);
|
||||
assert(i16.is_signed);
|
||||
assert(i32.is_signed);
|
||||
assert(i64.is_signed);
|
||||
assert(isize.is_signed);
|
||||
|
||||
assert(!u8.is_signed);
|
||||
assert(!u16.is_signed);
|
||||
assert(!u32.is_signed);
|
||||
assert(!u64.is_signed);
|
||||
assert(!usize.is_signed);
|
||||
|
||||
}
|
||||
|
||||
fn overflowIntrinsics() {
|
||||
var result: u8 = undefined;
|
||||
assert(@addWithOverflow(u8, 250, 100, &result));
|
||||
assert(!@addWithOverflow(u8, 100, 150, &result));
|
||||
assert(result == 250);
|
||||
}
|
||||
|
||||
fn shlWithOverflow() {
|
||||
var result: u16 = undefined;
|
||||
assert(@shlWithOverflow(u16, 0b0010111111111111, 3, &result));
|
||||
assert(!@shlWithOverflow(u16, 0b0010111111111111, 2, &result));
|
||||
assert(result == 0b1011111111111100);
|
||||
}
|
||||
|
||||
fn assignToIfVarPtr() {
|
||||
|
||||
var maybe_bool: ?bool = true;
|
||||
|
||||
if (const *b ?= maybe_bool) {
|
||||
*b = false;
|
||||
}
|
||||
|
||||
assert(??maybe_bool == false);
|
||||
}
|
||||
|
||||
fn errorWrapping() {
|
||||
assert(%%case_err_wrapping.baz() == 15);
|
||||
}
|
||||
|
||||
fn assert(ok: bool) {
|
||||
if (!ok)
|
||||
@unreachable();
|
||||
}
|
||||
|
||||
fn runAllTests() {
|
||||
emptyFunctionWithComments();
|
||||
disabledExternFn();
|
||||
inlinedLoop();
|
||||
switchWithNumbers();
|
||||
switchWithAllRanges();
|
||||
testInlineSwitch();
|
||||
testNamespaceFnCall();
|
||||
gotoAndLabels();
|
||||
testStructStatic();
|
||||
testStaticFnEval();
|
||||
testCompileTimeFib();
|
||||
|
@ -380,58 +91,9 @@ fn runAllTests() {
|
|||
testFnWithInlineArgs();
|
||||
testContinueInForLoop();
|
||||
shortCircuit();
|
||||
testGotoLeaveDeferScope(true);
|
||||
testStaticAddOne();
|
||||
testInlineVarsAgain();
|
||||
testMinValueAndMaxValue();
|
||||
testReturnStringFromFunction();
|
||||
testErrorName();
|
||||
cmpxchg();
|
||||
fence();
|
||||
exactDivision();
|
||||
truncate();
|
||||
intTypeBuiltin();
|
||||
overflowIntrinsics();
|
||||
shlWithOverflow();
|
||||
assignToIfVarPtr();
|
||||
errorWrapping();
|
||||
}
|
||||
|
||||
export nakedcc fn _start() -> unreachable {
|
||||
myMain();
|
||||
}
|
||||
|
||||
fn myMain() -> unreachable {
|
||||
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()
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
// TODO '_' identifier for unused variable bindings
|
||||
const test_empty_fn_with_comments = @import("cases3/empty_fn_with_comments.zig");
|
||||
const test_disabled_export = @import("cases3/disabled_export.zig");
|
||||
const test_inlined_loop = @import("cases3/inlined_loop.zig");
|
||||
const test_misc = @import("cases3/misc.zig");
|
||||
const test_switch = @import("cases3/switch.zig");
|
||||
const test_error = @import("cases3/error.zig");
|
||||
const test_goto = @import("cases3/goto.zig");
|
||||
const test_atomics = @import("cases3/atomics.zig");
|
||||
const test_for = @import("cases3/for.zig");
|
||||
const test_math = @import("cases3/math.zig");
|
||||
const test_generics = @import("cases3/generics.zig");
|
Loading…
Reference in New Issue