IR: port more tests

This commit is contained in:
Andrew Kelley 2016-12-22 01:20:08 -05:00
parent 5fc95c2a53
commit 5a71718757
16 changed files with 386 additions and 362 deletions

View File

@ -1,11 +0,0 @@
const assert = @import("std").debug.assert;
fn maxValueType() {
@setFnTest(this, true);
// If the type of @maxValue(i32) was i32 then this implicit cast to
// u32 would not work. But since the value is a number literal,
// it works fine.
const x: u32 = @maxValue(i32);
assert(x == 2147483647);
}

View File

@ -1,19 +0,0 @@
const assert = @import("std").debug.assert;
struct Foo {
a: f32,
b: i32,
c: bool,
d: ?i32,
}
fn initializing_a_struct_with_zeroes() {
@setFnTest(this, true);
const foo: Foo = zeroes;
assert(foo.a == 0.0);
assert(foo.b == 0);
assert(foo.c == false);
assert(if (const x ?= foo.d) false else true);
}

View File

@ -24,6 +24,27 @@ fn getArrayLen(a: []u32) -> usize {
a.len
}
fn voidArrays() {
@setFnTest(this);
var array: [4]void = undefined;
array[0] = void{};
array[1] = array[2];
assert(@sizeOf(@typeOf(array)) == 0);
assert(array.len == 4);
}
fn arrayLiteral() {
@setFnTest(this);
const hex_mult = []u16{4096, 256, 16, 1};
assert(hex_mult.len == 4);
assert(hex_mult[1] == 256);
}
// TODO const assert = @import("std").debug.assert;
fn assert(ok: bool) {
if (!ok)

27
test/cases3/bool.zig Normal file
View File

@ -0,0 +1,27 @@
fn boolLiterals() {
@setFnTest(this);
assert(true);
assert(!false);
}
fn castBoolToInt() {
@setFnTest(this);
const t = true;
const f = false;
assert(i32(t) == i32(1));
assert(i32(f) == i32(0));
nonConstCastBoolToInt(t, f);
}
fn nonConstCastBoolToInt(t: bool, f: bool) {
assert(i32(t) == i32(1));
assert(i32(f) == i32(0));
}
// TODO const assert = @import("std").debug.assert;
fn assert(ok: bool) {
if (!ok)
@unreachable();
}

View File

@ -43,6 +43,36 @@ fn returnAnInt(x: i32) -> Foo {
}
fn constantEnumWithPayload() {
@setFnTest(this);
var empty = AnEnumWithPayload.Empty;
var full = AnEnumWithPayload.Full {13};
shouldBeEmpty(empty);
shouldBeNotEmpty(full);
}
fn shouldBeEmpty(x: AnEnumWithPayload) {
switch (x) {
AnEnumWithPayload.Empty => {},
else => @unreachable(),
}
}
fn shouldBeNotEmpty(x: AnEnumWithPayload) {
switch (x) {
AnEnumWithPayload.Empty => @unreachable(),
else => {},
}
}
const AnEnumWithPayload = enum {
Empty,
Full: i32,
};
fn assert(ok: bool) {
if (!ok)
@unreachable();

View File

@ -29,6 +29,34 @@ fn errorName() {
}
fn errorValues() {
@setFnTest(this);
const a = i32(error.err1);
const b = i32(error.err2);
assert(a != b);
}
error err1;
error err2;
fn redefinitionOfErrorValuesAllowed() {
@setFnTest(this);
shouldBeNotEqual(error.AnError, error.SecondError);
}
error AnError;
error AnError;
error SecondError;
fn shouldBeNotEqual(a: error, b: error) {
if (a == b) @unreachable()
}
// TODO const assert = @import("std").debug.assert;
fn assert(ok: bool) {
if (!ok)

View File

@ -40,6 +40,30 @@ fn fnWithInlineArgs() {
assert(sameButWithFloats(0.43, 0.49) == 0.49);
}
fn varParams() {
@setFnTest(this);
assert(max_i32(12, 34) == 34);
assert(max_f64(1.2, 3.4) == 3.4);
}
// TODO `_`
const _1 = assert(max_i32(12, 34) == 34);
const _2 = assert(max_f64(1.2, 3.4) == 3.4);
fn max_var(a: var, b: var) -> @typeOf(a + b) {
if (a > b) a else b
}
fn max_i32(a: i32, b: i32) -> i32 {
max_var(a, b)
}
fn max_f64(a: f64, b: f64) -> f64 {
max_var(a, b)
}
// TODO const assert = @import("std").debug.assert;
fn assert(ok: bool) {
if (!ok)

View File

@ -68,6 +68,38 @@ fn modifyOperators() {
i |= 3; assert(i == 7);
}
fn threeExprInARow() {
@setFnTest(this);
assertFalse(false || false || false);
assertFalse(true && true && false);
assertFalse(1 | 2 | 4 != 7);
assertFalse(3 ^ 6 ^ 8 != 13);
assertFalse(7 & 14 & 28 != 4);
assertFalse(9 << 1 << 2 != 9 << 3);
assertFalse(90 >> 1 >> 2 != 90 >> 3);
assertFalse(100 - 1 + 1000 != 1099);
assertFalse(5 * 4 / 2 % 3 != 1);
assertFalse(i32(i32(5)) != 5);
assertFalse(!!false);
assertFalse(i32(7) != --(i32(7)));
}
fn assertFalse(b: bool) {
assert(!b);
}
fn constNumberLiteral() {
@setFnTest(this);
const one = 1;
const eleven = ten + one;
assert(eleven == 11);
}
const ten = 10;
// TODO const assert = @import("std").debug.assert;
fn assert(ok: bool) {

View File

@ -70,6 +70,16 @@ fn minValueAndMaxValue() {
assert(@minValue(i64) == -9223372036854775808);
}
fn maxValueType() {
@setFnTest(this);
// If the type of @maxValue(i32) was i32 then this implicit cast to
// u32 would not work. But since the value is a number literal,
// it works fine.
const x: u32 = @maxValue(i32);
assert(x == 2147483647);
}
fn shortCircuit() {
@setFnTest(this);
@ -130,14 +140,20 @@ fn ReturnStringFromFunction() {
assert(memeql(first4KeysOfHomeRow(), "aoeu"));
}
fn boolLiterals() {
const g1 : i32 = 1233 + 1;
var g2 : i32 = 0;
fn globalVariables() {
@setFnTest(this);
assert(true);
assert(!false);
assert(g2 == 0);
g2 = g1;
assert(g2 == 1234);
}
// TODO import from std.str
pub fn memeql(a: []const u8, b: []const u8) -> bool {
sliceEql(u8, a, b)

34
test/cases3/null.zig Normal file
View File

@ -0,0 +1,34 @@
fn nullableType() {
@setFnTest(this);
const x : ?bool = true;
if (const y ?= x) {
if (y) {
// OK
} else {
@unreachable();
}
} else {
@unreachable();
}
const next_x : ?i32 = null;
const z = next_x ?? 1234;
assert(z == 1234);
const final_x : ?i32 = 13;
const num = final_x ?? @unreachable();
assert(num == 13);
}
// TODO const assert = @import("std").debug.assert;
fn assert(ok: bool) {
if (!ok)
@unreachable();
}

View File

@ -63,6 +63,67 @@ fn testMutation(foo : &StructFoo) {
}
const Node = struct {
val: Val,
next: &Node,
};
const Val = struct {
x: i32,
};
fn structPointToSelf() {
@setFnTest(this);
var root : Node = undefined;
root.val.x = 1;
var node : Node = undefined;
node.next = &root;
node.val.x = 2;
root.next = &node;
assert(node.next.next.next.val.x == 1);
}
fn structByvalAssign() {
@setFnTest(this);
var foo1 : StructFoo = undefined;
var foo2 : StructFoo = undefined;
foo1.a = 1234;
foo2.a = 0;
assert(foo2.a == 0);
foo2 = foo1;
assert(foo2.a == 1234);
}
fn structInitializer() {
const val = Val { .x = 42 };
assert(val.x == 42);
}
fn fnCallOfStructField() {
@setFnTest(this);
assert(callStructField(Foo {.ptr = aFunc,}) == 13);
}
const Foo = struct {
ptr: fn() -> i32,
};
fn aFunc() -> i32 { 13 }
fn callStructField(foo: Foo) -> i32 {
return foo.ptr();
}
// TODO const assert = @import("std").debug.assert;
fn assert(ok: bool) {

View File

@ -45,6 +45,50 @@ fn inlineSwitch() {
assert(result + 1 == 14);
}
fn switchOnEnum() {
@setFnTest(this);
const fruit = Fruit.Orange;
nonConstSwitchOnEnum(fruit);
}
const Fruit = enum {
Apple,
Orange,
Banana,
};
fn nonConstSwitchOnEnum(fruit: Fruit) {
switch (fruit) {
Fruit.Apple => @unreachable(),
Fruit.Orange => {},
Fruit.Banana => @unreachable(),
}
}
fn switchStatement() {
@setFnTest(this);
nonConstSwitch(SwitchStatmentFoo.C);
}
fn nonConstSwitch(foo: SwitchStatmentFoo) {
const val = switch (foo) {
SwitchStatmentFoo.A => i32(1),
SwitchStatmentFoo.B => 2,
SwitchStatmentFoo.C => 3,
SwitchStatmentFoo.D => 4,
};
if (val != 3) @unreachable();
}
const SwitchStatmentFoo = enum {
A,
B,
C,
D,
};
// TODO const assert = @import("std").debug.assert;
fn assert(ok: bool) {
if (!ok)

View File

@ -1,14 +1,15 @@
const assert = @import("std").debug.assert;
const module = this;
struct Point(inline T: type) {
const Self = this;
x: T,
y: T,
fn Point(inline T: type) -> type {
struct {
const Self = this;
x: T,
y: T,
fn addOne(self: &Self) {
self.x += 1;
self.y += 1;
fn addOne(self: &Self) {
self.x += 1;
self.y += 1;
}
}
}
@ -26,13 +27,13 @@ fn factorial(x: i32) -> i32 {
}
fn thisReferToModuleCallPrivateFn() {
@setFnTest(this, true);
@setFnTest(this);
assert(module.add(1, 2) == 3);
}
fn thisReferToContainer() {
@setFnTest(this, true);
@setFnTest(this);
var pt = Point(i32) {
.x = 12,
@ -44,7 +45,13 @@ fn thisReferToContainer() {
}
fn thisReferToFn() {
@setFnTest(this, true);
@setFnTest(this);
assert(factorial(5) == 120);
}
// TODO const assert = @import("std").debug.assert;
fn assert(ok: bool) {
if (!ok)
@unreachable();
}

38
test/cases3/while.zig Normal file
View File

@ -0,0 +1,38 @@
fn whileLoop() {
@setFnTest(this);
var i : i32 = 0;
while (i < 4) {
i += 1;
}
assert(i == 4);
assert(whileLoop1() == 1);
}
fn whileLoop1() -> i32 {
return whileLoop2();
}
fn whileLoop2() -> i32 {
while (true) {
return 1;
}
}
fn staticEvalWhile() {
@setFnTest(this);
assert(static_eval_while_number == 1);
}
const static_eval_while_number = staticWhileLoop1();
fn staticWhileLoop1() -> i32 {
return whileLoop2();
}
fn staticWhileLoop2() -> i32 {
while (true) {
return 1;
}
}
// TODO const assert = @import("std").debug.assert;
fn assert(ok: bool) {
if (!ok)
@unreachable();
}

View File

@ -3,334 +3,37 @@ const assert = std.debug.assert;
const str = std.str;
const cstr = std.cstr;
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");
const test_maybe_return = @import("cases/maybe_return.zig");
const test_max_value_type = @import("cases/max_value_type.zig");
const test_var_params = @import("cases/var_params.zig");
const test_const_slice_child = @import("cases/const_slice_child.zig");
const test_switch_prong_implicit_cast = @import("cases/switch_prong_implicit_cast.zig");
const test_switch_prong_err_enum = @import("cases/switch_prong_err_enum.zig");
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");
struct Node {
val: Val,
next: &Node,
}
struct Val {
x: i32,
}
fn structPointToSelf() {
@setFnTest(this, true);
var root : Node = undefined;
root.val.x = 1;
var node : Node = undefined;
node.next = &root;
node.val.x = 2;
root.next = &node;
assert(node.next.next.next.val.x == 1);
}
fn structByvalAssign() {
@setFnTest(this, true);
var foo1 : StructFoo = undefined;
var foo2 : StructFoo = undefined;
foo1.a = 1234;
foo2.a = 0;
assert(foo2.a == 0);
foo2 = foo1;
assert(foo2.a == 1234);
}
fn structInitializer() {
const val = Val { .x = 42 };
assert(val.x == 42);
}
const g1 : i32 = 1233 + 1;
var g2 : i32 = 0;
fn globalVariables() {
@setFnTest(this, true);
assert(g2 == 0);
g2 = g1;
assert(g2 == 1234);
}
fn whileLoop() {
@setFnTest(this, true);
var i : i32 = 0;
while (i < 4) {
i += 1;
}
assert(i == 4);
assert(whileLoop1() == 1);
}
fn whileLoop1() -> i32 {
return whileLoop2();
}
fn whileLoop2() -> i32 {
while (true) {
return 1;
}
}
fn voidArrays() {
@setFnTest(this, true);
var array: [4]void = undefined;
array[0] = void{};
array[1] = array[2];
assert(@sizeOf(@typeOf(array)) == 0);
assert(array.len == 4);
}
fn threeExprInARow() {
@setFnTest(this, true);
assertFalse(false || false || false);
assertFalse(true && true && false);
assertFalse(1 | 2 | 4 != 7);
assertFalse(3 ^ 6 ^ 8 != 13);
assertFalse(7 & 14 & 28 != 4);
assertFalse(9 << 1 << 2 != 9 << 3);
assertFalse(90 >> 1 >> 2 != 90 >> 3);
assertFalse(100 - 1 + 1000 != 1099);
assertFalse(5 * 4 / 2 % 3 != 1);
assertFalse(i32(i32(5)) != 5);
assertFalse(!!false);
assertFalse(i32(7) != --(i32(7)));
}
fn assertFalse(b: bool) {
assert(!b);
}
fn maybeType() {
@setFnTest(this, true);
const x : ?bool = true;
if (const y ?= x) {
if (y) {
// OK
} else {
@unreachable();
}
} else {
@unreachable();
}
const next_x : ?i32 = null;
const z = next_x ?? 1234;
assert(z == 1234);
const final_x : ?i32 = 13;
const num = final_x ?? @unreachable();
assert(num == 13);
}
fn arrayLiteral() {
@setFnTest(this, true);
const hex_mult = []u16{4096, 256, 16, 1};
assert(hex_mult.len == 4);
assert(hex_mult[1] == 256);
}
fn constNumberLiteral() {
@setFnTest(this, true);
const one = 1;
const eleven = ten + one;
assert(eleven == 11);
}
const ten = 10;
fn errorValues() {
@setFnTest(this, true);
const a = i32(error.err1);
const b = i32(error.err2);
assert(a != b);
}
error err1;
error err2;
fn fnCallOfStructField() {
@setFnTest(this, true);
assert(callStructField(Foo {.ptr = aFunc,}) == 13);
}
struct Foo {
ptr: fn() -> i32,
}
fn aFunc() -> i32 { 13 }
fn callStructField(foo: Foo) -> i32 {
return foo.ptr();
}
fn redefinitionOfErrorValuesAllowed() {
@setFnTest(this, true);
shouldBeNotEqual(error.AnError, error.SecondError);
}
error AnError;
error AnError;
error SecondError;
fn shouldBeNotEqual(a: error, b: error) {
if (a == b) @unreachable()
}
fn constantEnumWithPayload() {
@setFnTest(this, true);
var empty = AnEnumWithPayload.Empty;
var full = AnEnumWithPayload.Full {13};
shouldBeEmpty(empty);
shouldBeNotEmpty(full);
}
fn shouldBeEmpty(x: AnEnumWithPayload) {
switch (x) {
Empty => {},
else => @unreachable(),
}
}
fn shouldBeNotEmpty(x: AnEnumWithPayload) {
switch (x) {
Empty => @unreachable(),
else => {},
}
}
enum AnEnumWithPayload {
Empty,
Full: i32,
}
fn castBoolToInt() {
@setFnTest(this, true);
const t = true;
const f = false;
assert(i32(t) == i32(1));
assert(i32(f) == i32(0));
nonConstCastBoolToInt(t, f);
}
fn nonConstCastBoolToInt(t: bool, f: bool) {
assert(i32(t) == i32(1));
assert(i32(f) == i32(0));
}
fn switchOnEnum() {
@setFnTest(this, true);
const fruit = Fruit.Orange;
nonConstSwitchOnEnum(fruit);
}
enum Fruit {
Apple,
Orange,
Banana,
}
fn nonConstSwitchOnEnum(fruit: Fruit) {
@setFnStaticEval(this, false);
switch (fruit) {
Apple => @unreachable(),
Orange => {},
Banana => @unreachable(),
}
}
fn switchStatement() {
@setFnTest(this, true);
nonConstSwitch(SwitchStatmentFoo.C);
}
fn nonConstSwitch(foo: SwitchStatmentFoo) {
@setFnStaticEval(this, false);
const val: i32 = switch (foo) {
A => 1,
B => 2,
C => 3,
D => 4,
};
if (val != 3) @unreachable();
}
enum SwitchStatmentFoo {
A,
B,
C,
D,
}
fn switchProngWithVar() {
@setFnTest(this, true);
@setFnTest(this);
switchProngWithVarFn(SwitchProngWithVarEnum.One {13});
switchProngWithVarFn(SwitchProngWithVarEnum.Two {13.0});
switchProngWithVarFn(SwitchProngWithVarEnum.Meh);
}
enum SwitchProngWithVarEnum {
const SwitchProngWithVarEnum = enum {
One: i32,
Two: f32,
Meh,
}
};
fn switchProngWithVarFn(a: SwitchProngWithVarEnum) {
@setFnStaticEval(this, false);
switch(a) {
One => |x| {
SwitchProngWithVarEnum.One => |x| {
if (x != 13) @unreachable();
},
Two => |x| {
SwitchProngWithVarEnum.Two => |x| {
if (x != 13.0) @unreachable();
},
Meh => |x| {
SwitchProngWithVarEnum.Meh => |x| {
const v: void = x;
},
}
@ -677,21 +380,6 @@ fn fibbonaci(x: i32) -> i32 {
return fibbonaci(x - 1) + fibbonaci(x - 2);
}
fn staticEvalWhile() {
@setFnTest(this, true);
assert(static_eval_while_number == 1);
}
const static_eval_while_number = staticWhileLoop1();
fn staticWhileLoop1() -> i32 {
return whileLoop2();
}
fn staticWhileLoop2() -> i32 {
while (true) {
return 1;
}
}
fn staticEvalListInit() {
@setFnTest(this, true);

View File

@ -1,6 +1,7 @@
// TODO '_' identifier for unused variable bindings
const test_array = @import("cases3/array.zig");
const test_atomics = @import("cases3/atomics.zig");
const test_bool = @import("cases3/bool.zig");
const test_defer = @import("cases3/defer.zig");
const test_enum = @import("cases3/enum.zig");
const test_error = @import("cases3/error.zig");
@ -13,5 +14,8 @@ const test_if = @import("cases3/if.zig");
const test_import = @import("cases3/import.zig");
const test_math = @import("cases3/math.zig");
const test_misc = @import("cases3/misc.zig");
const test_null = @import("cases3/null.zig");
const test_struct = @import("cases3/struct.zig");
const test_switch = @import("cases3/switch.zig");
const test_this = @import("cases3/this.zig");
const test_while = @import("cases3/while.zig");