diff --git a/test/cases/max_value_type.zig b/test/cases/max_value_type.zig deleted file mode 100644 index e93ce5eb84..0000000000 --- a/test/cases/max_value_type.zig +++ /dev/null @@ -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); -} diff --git a/test/cases/zeroes.zig b/test/cases/zeroes.zig deleted file mode 100644 index c30b01d4af..0000000000 --- a/test/cases/zeroes.zig +++ /dev/null @@ -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); -} - diff --git a/test/cases3/array.zig b/test/cases3/array.zig index 94f453c100..3ae53c7734 100644 --- a/test/cases3/array.zig +++ b/test/cases3/array.zig @@ -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) diff --git a/test/cases3/bool.zig b/test/cases3/bool.zig new file mode 100644 index 0000000000..7ca892d8ea --- /dev/null +++ b/test/cases3/bool.zig @@ -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(); +} diff --git a/test/cases3/enum.zig b/test/cases3/enum.zig index 9c89414958..5d204e8538 100644 --- a/test/cases3/enum.zig +++ b/test/cases3/enum.zig @@ -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(); diff --git a/test/cases3/error.zig b/test/cases3/error.zig index 310a3457f6..4e6e72689c 100644 --- a/test/cases3/error.zig +++ b/test/cases3/error.zig @@ -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) diff --git a/test/cases3/generics.zig b/test/cases3/generics.zig index 6bccc11245..79ead86184 100644 --- a/test/cases3/generics.zig +++ b/test/cases3/generics.zig @@ -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) diff --git a/test/cases3/math.zig b/test/cases3/math.zig index 8eda479c89..41c0d52fc4 100644 --- a/test/cases3/math.zig +++ b/test/cases3/math.zig @@ -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) { diff --git a/test/cases3/misc.zig b/test/cases3/misc.zig index d17cfb647a..73ddad19d6 100644 --- a/test/cases3/misc.zig +++ b/test/cases3/misc.zig @@ -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) diff --git a/test/cases3/null.zig b/test/cases3/null.zig new file mode 100644 index 0000000000..059fb743f7 --- /dev/null +++ b/test/cases3/null.zig @@ -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(); +} + diff --git a/test/cases3/struct.zig b/test/cases3/struct.zig index 45328a554f..996b0598ea 100644 --- a/test/cases3/struct.zig +++ b/test/cases3/struct.zig @@ -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) { diff --git a/test/cases3/switch.zig b/test/cases3/switch.zig index 84f8521600..c32a478b2e 100644 --- a/test/cases3/switch.zig +++ b/test/cases3/switch.zig @@ -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) diff --git a/test/cases/this.zig b/test/cases3/this.zig similarity index 57% rename from test/cases/this.zig rename to test/cases3/this.zig index f7197290f2..48ad31c93f 100644 --- a/test/cases/this.zig +++ b/test/cases3/this.zig @@ -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(); +} diff --git a/test/cases3/while.zig b/test/cases3/while.zig new file mode 100644 index 0000000000..b9b444f708 --- /dev/null +++ b/test/cases3/while.zig @@ -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(); +} diff --git a/test/self_hosted.zig b/test/self_hosted.zig index f67a3c81d5..9435f6023a 100644 --- a/test/self_hosted.zig +++ b/test/self_hosted.zig @@ -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); diff --git a/test/self_hosted3.zig b/test/self_hosted3.zig index c32926a5a0..2c75a42c60 100644 --- a/test/self_hosted3.zig +++ b/test/self_hosted3.zig @@ -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");