| author | |
| committer | |
| log | 6c9ec3688eead05f1c41e0444a17e1d2bdb7a21e |
| tree | fd8a9ca5e291fec0fce4ac17f77d018df4298c64 |
| parent | 66777ccd7d3744670fe58d451f982f29d65612ac |
67 files changed, 2056 insertions(+), 2056 deletions(-)
test/cases/array.zig created+64| ... | ... | @@ -0,0 +1,64 @@ |
| 1 | fn arrays() { | |
| 2 | @setFnTest(this); | |
| 3 | ||
| 4 | var array : [5]u32 = undefined; | |
| 5 | ||
| 6 | var i : u32 = 0; | |
| 7 | while (i < 5) { | |
| 8 | array[i] = i + 1; | |
| 9 | i = array[i]; | |
| 10 | } | |
| 11 | ||
| 12 | i = 0; | |
| 13 | var accumulator = u32(0); | |
| 14 | while (i < 5) { | |
| 15 | accumulator += array[i]; | |
| 16 | ||
| 17 | i += 1; | |
| 18 | } | |
| 19 | ||
| 20 | assert(accumulator == 15); | |
| 21 | assert(getArrayLen(array) == 5); | |
| 22 | } | |
| 23 | fn getArrayLen(a: []u32) -> usize { | |
| 24 | a.len | |
| 25 | } | |
| 26 | ||
| 27 | fn voidArrays() { | |
| 28 | @setFnTest(this); | |
| 29 | ||
| 30 | var array: [4]void = undefined; | |
| 31 | array[0] = void{}; | |
| 32 | array[1] = array[2]; | |
| 33 | assert(@sizeOf(@typeOf(array)) == 0); | |
| 34 | assert(array.len == 4); | |
| 35 | } | |
| 36 | ||
| 37 | fn arrayLiteral() { | |
| 38 | @setFnTest(this); | |
| 39 | ||
| 40 | const hex_mult = []u16{4096, 256, 16, 1}; | |
| 41 | ||
| 42 | assert(hex_mult.len == 4); | |
| 43 | assert(hex_mult[1] == 256); | |
| 44 | } | |
| 45 | ||
| 46 | fn arrayDotLenConstExpr() { | |
| 47 | @setFnTest(this); | |
| 48 | ||
| 49 | assert(@staticEval(some_array.len) == 4); | |
| 50 | } | |
| 51 | ||
| 52 | const ArrayDotLenConstExpr = struct { | |
| 53 | y: [some_array.len]u8, | |
| 54 | }; | |
| 55 | const some_array = []u8 {0, 1, 2, 3}; | |
| 56 | ||
| 57 | ||
| 58 | ||
| 59 | ||
| 60 | // TODO const assert = @import("std").debug.assert; | |
| 61 | fn assert(ok: bool) { | |
| 62 | if (!ok) | |
| 63 | @unreachable(); | |
| 64 | } |
test/cases/atomics.zig created+21| ... | ... | @@ -0,0 +1,21 @@ |
| 1 | fn cmpxchg() { | |
| 2 | @setFnTest(this); | |
| 3 | ||
| 4 | var x: i32 = 1234; | |
| 5 | while (!@cmpxchg(&x, 1234, 5678, AtomicOrder.SeqCst, AtomicOrder.SeqCst)) {} | |
| 6 | assert(x == 5678); | |
| 7 | } | |
| 8 | ||
| 9 | fn fence() { | |
| 10 | @setFnTest(this); | |
| 11 | ||
| 12 | var x: i32 = 1234; | |
| 13 | @fence(AtomicOrder.SeqCst); | |
| 14 | x = 5678; | |
| 15 | } | |
| 16 | ||
| 17 | // TODO const assert = @import("std").debug.assert; | |
| 18 | fn assert(ok: bool) { | |
| 19 | if (!ok) | |
| 20 | @unreachable(); | |
| 21 | } |
test/cases/bool.zig created+36| ... | ... | @@ -0,0 +1,36 @@ |
| 1 | fn boolLiterals() { | |
| 2 | @setFnTest(this); | |
| 3 | ||
| 4 | assert(true); | |
| 5 | assert(!false); | |
| 6 | } | |
| 7 | ||
| 8 | fn castBoolToInt() { | |
| 9 | @setFnTest(this); | |
| 10 | ||
| 11 | const t = true; | |
| 12 | const f = false; | |
| 13 | assert(i32(t) == i32(1)); | |
| 14 | assert(i32(f) == i32(0)); | |
| 15 | nonConstCastBoolToInt(t, f); | |
| 16 | } | |
| 17 | ||
| 18 | fn nonConstCastBoolToInt(t: bool, f: bool) { | |
| 19 | assert(i32(t) == i32(1)); | |
| 20 | assert(i32(f) == i32(0)); | |
| 21 | } | |
| 22 | ||
| 23 | fn boolCmp() { | |
| 24 | @setFnTest(this); | |
| 25 | ||
| 26 | assert(testBoolCmp(true, false) == false); | |
| 27 | } | |
| 28 | fn testBoolCmp(a: bool, b: bool) -> bool { | |
| 29 | a == b | |
| 30 | } | |
| 31 | ||
| 32 | // TODO const assert = @import("std").debug.assert; | |
| 33 | fn assert(ok: bool) { | |
| 34 | if (!ok) | |
| 35 | @unreachable(); | |
| 36 | } |
test/cases/cast.zig created+14| ... | ... | @@ -0,0 +1,14 @@ |
| 1 | //fn intToPtrCast() { | |
| 2 | // @setFnTest(this); | |
| 3 | // | |
| 4 | // const x = isize(13); | |
| 5 | // const y = (&u8)(x); | |
| 6 | // const z = usize(y); | |
| 7 | // assert(z == 13); | |
| 8 | //} | |
| 9 | ||
| 10 | // TODO const assert = @import("std").debug.assert; | |
| 11 | fn assert(ok: bool) { | |
| 12 | if (!ok) | |
| 13 | @unreachable(); | |
| 14 | } |
test/cases/const_slice_child.zig created+49| ... | ... | @@ -0,0 +1,49 @@ |
| 1 | var argv: &&const u8 = undefined; | |
| 2 | ||
| 3 | fn constSliceChild() { | |
| 4 | @setFnTest(this); | |
| 5 | ||
| 6 | const strs = ([]&const u8) { | |
| 7 | c"one", | |
| 8 | c"two", | |
| 9 | c"three", | |
| 10 | }; | |
| 11 | argv = &strs[0]; | |
| 12 | bar(strs.len); | |
| 13 | } | |
| 14 | ||
| 15 | fn foo(args: [][]const u8) { | |
| 16 | assert(args.len == 3); | |
| 17 | assert(streql(args[0], "one")); | |
| 18 | assert(streql(args[1], "two")); | |
| 19 | assert(streql(args[2], "three")); | |
| 20 | } | |
| 21 | ||
| 22 | fn bar(argc: usize) { | |
| 23 | const args = @alloca([]u8, argc); | |
| 24 | for (args) |_, i| { | |
| 25 | const ptr = argv[i]; | |
| 26 | args[i] = ptr[0...strlen(ptr)]; | |
| 27 | } | |
| 28 | foo(args); | |
| 29 | } | |
| 30 | ||
| 31 | fn strlen(ptr: &const u8) -> usize { | |
| 32 | var count: usize = 0; | |
| 33 | while (ptr[count] != 0; count += 1) {} | |
| 34 | return count; | |
| 35 | } | |
| 36 | ||
| 37 | fn streql(a: []const u8, b: []const u8) -> bool { | |
| 38 | if (a.len != b.len) return false; | |
| 39 | for (a) |item, index| { | |
| 40 | if (b[index] != item) return false; | |
| 41 | } | |
| 42 | return true; | |
| 43 | } | |
| 44 | ||
| 45 | // TODO const assert = @import("std").debug.assert; | |
| 46 | fn assert(ok: bool) { | |
| 47 | if (!ok) | |
| 48 | @unreachable(); | |
| 49 | } |
test/cases/defer.zig created+57| ... | ... | @@ -0,0 +1,57 @@ |
| 1 | var result: [3]u8 = undefined; | |
| 2 | var index: usize = undefined; | |
| 3 | ||
| 4 | error FalseNotAllowed; | |
| 5 | ||
| 6 | fn runSomeErrorDefers(x: bool) -> %bool { | |
| 7 | index = 0; | |
| 8 | defer {result[index] = 'a'; index += 1;}; | |
| 9 | %defer {result[index] = 'b'; index += 1;}; | |
| 10 | defer {result[index] = 'c'; index += 1;}; | |
| 11 | return if (x) x else error.FalseNotAllowed; | |
| 12 | } | |
| 13 | ||
| 14 | fn runSomeMaybeDefers(x: bool) -> ?bool { | |
| 15 | index = 0; | |
| 16 | defer {result[index] = 'a'; index += 1;}; | |
| 17 | ?defer {result[index] = 'b'; index += 1;}; | |
| 18 | defer {result[index] = 'c'; index += 1;}; | |
| 19 | return if (x) x else null; | |
| 20 | } | |
| 21 | ||
| 22 | fn mixingNormalAndErrorDefers() { | |
| 23 | @setFnTest(this); | |
| 24 | ||
| 25 | assert(%%runSomeErrorDefers(true)); | |
| 26 | assert(result[0] == 'c'); | |
| 27 | assert(result[1] == 'a'); | |
| 28 | ||
| 29 | const ok = runSomeErrorDefers(false) %% |err| { | |
| 30 | assert(err == error.FalseNotAllowed); | |
| 31 | true | |
| 32 | }; | |
| 33 | assert(ok); | |
| 34 | assert(result[0] == 'c'); | |
| 35 | assert(result[1] == 'b'); | |
| 36 | assert(result[2] == 'a'); | |
| 37 | } | |
| 38 | ||
| 39 | fn mixingNormalAndMaybeDefers() { | |
| 40 | @setFnTest(this); | |
| 41 | ||
| 42 | assert(??runSomeMaybeDefers(true)); | |
| 43 | assert(result[0] == 'c'); | |
| 44 | assert(result[1] == 'a'); | |
| 45 | ||
| 46 | const ok = runSomeMaybeDefers(false) ?? true; | |
| 47 | assert(ok); | |
| 48 | assert(result[0] == 'c'); | |
| 49 | assert(result[1] == 'b'); | |
| 50 | assert(result[2] == 'a'); | |
| 51 | } | |
| 52 | ||
| 53 | // TODO const assert = @import("std").debug.assert; | |
| 54 | fn assert(ok: bool) { | |
| 55 | if (!ok) | |
| 56 | @unreachable(); | |
| 57 | } |
test/cases/enum.zig created+105| ... | ... | @@ -0,0 +1,105 @@ |
| 1 | fn enumType() { | |
| 2 | @setFnTest(this); | |
| 3 | ||
| 4 | const foo1 = Foo.One {13}; | |
| 5 | const foo2 = Foo.Two { Point { .x = 1234, .y = 5678, }}; | |
| 6 | const bar = Bar.B; | |
| 7 | ||
| 8 | assert(bar == Bar.B); | |
| 9 | assert(@memberCount(Foo) == 3); | |
| 10 | assert(@memberCount(Bar) == 4); | |
| 11 | const expected_foo_size = 16 + @sizeOf(usize); | |
| 12 | assert(@sizeOf(Foo) == expected_foo_size); | |
| 13 | assert(@sizeOf(Bar) == 1); | |
| 14 | } | |
| 15 | ||
| 16 | fn enumAsReturnValue () { | |
| 17 | @setFnTest(this); | |
| 18 | ||
| 19 | switch (returnAnInt(13)) { | |
| 20 | Foo.One => |value| assert(value == 13), | |
| 21 | else => @unreachable(), | |
| 22 | } | |
| 23 | } | |
| 24 | ||
| 25 | const Point = struct { | |
| 26 | x: u64, | |
| 27 | y: u64, | |
| 28 | }; | |
| 29 | const Foo = enum { | |
| 30 | One: i32, | |
| 31 | Two: Point, | |
| 32 | Three: void, | |
| 33 | }; | |
| 34 | const Bar = enum { | |
| 35 | A, | |
| 36 | B, | |
| 37 | C, | |
| 38 | D, | |
| 39 | }; | |
| 40 | ||
| 41 | fn returnAnInt(x: i32) -> Foo { | |
| 42 | Foo.One { x } | |
| 43 | } | |
| 44 | ||
| 45 | ||
| 46 | fn constantEnumWithPayload() { | |
| 47 | @setFnTest(this); | |
| 48 | ||
| 49 | var empty = AnEnumWithPayload.Empty; | |
| 50 | var full = AnEnumWithPayload.Full {13}; | |
| 51 | shouldBeEmpty(empty); | |
| 52 | shouldBeNotEmpty(full); | |
| 53 | } | |
| 54 | ||
| 55 | fn shouldBeEmpty(x: AnEnumWithPayload) { | |
| 56 | switch (x) { | |
| 57 | AnEnumWithPayload.Empty => {}, | |
| 58 | else => @unreachable(), | |
| 59 | } | |
| 60 | } | |
| 61 | ||
| 62 | fn shouldBeNotEmpty(x: AnEnumWithPayload) { | |
| 63 | switch (x) { | |
| 64 | AnEnumWithPayload.Empty => @unreachable(), | |
| 65 | else => {}, | |
| 66 | } | |
| 67 | } | |
| 68 | ||
| 69 | const AnEnumWithPayload = enum { | |
| 70 | Empty, | |
| 71 | Full: i32, | |
| 72 | }; | |
| 73 | ||
| 74 | ||
| 75 | ||
| 76 | const Number = enum { | |
| 77 | Zero, | |
| 78 | One, | |
| 79 | Two, | |
| 80 | Three, | |
| 81 | Four, | |
| 82 | }; | |
| 83 | ||
| 84 | fn enumToInt() { | |
| 85 | @setFnTest(this); | |
| 86 | ||
| 87 | shouldEqual(Number.Zero, 0); | |
| 88 | shouldEqual(Number.One, 1); | |
| 89 | shouldEqual(Number.Two, 2); | |
| 90 | shouldEqual(Number.Three, 3); | |
| 91 | shouldEqual(Number.Four, 4); | |
| 92 | } | |
| 93 | ||
| 94 | fn shouldEqual(n: Number, expected: usize) { | |
| 95 | assert(usize(n) == expected); | |
| 96 | } | |
| 97 | ||
| 98 | // TODO import from std | |
| 99 | fn assert(ok: bool) { | |
| 100 | if (!ok) | |
| 101 | @unreachable(); | |
| 102 | } | |
| 103 | ||
| 104 | ||
| 105 |
test/cases/enum_with_members.zig created+83| ... | ... | @@ -0,0 +1,83 @@ |
| 1 | const ET = enum { | |
| 2 | SINT: i32, | |
| 3 | UINT: u32, | |
| 4 | ||
| 5 | pub fn print(a: &ET, buf: []u8) -> %usize { | |
| 6 | return switch (*a) { | |
| 7 | ET.SINT => |x| { bufPrintInt(i32, buf, x) }, | |
| 8 | ET.UINT => |x| { bufPrintInt(u32, buf, x) }, | |
| 9 | } | |
| 10 | } | |
| 11 | }; | |
| 12 | ||
| 13 | fn enumWithMembers() { | |
| 14 | @setFnTest(this); | |
| 15 | ||
| 16 | const a = ET.SINT { -42 }; | |
| 17 | const b = ET.UINT { 42 }; | |
| 18 | var buf: [20]u8 = undefined; | |
| 19 | ||
| 20 | assert(%%a.print(buf) == 3); | |
| 21 | assert(memeql(buf[0...3], "-42")); | |
| 22 | ||
| 23 | assert(%%b.print(buf) == 2); | |
| 24 | assert(memeql(buf[0...2], "42")); | |
| 25 | } | |
| 26 | ||
| 27 | // TODO all the below should be imported from std | |
| 28 | ||
| 29 | const max_u64_base10_digits = 20; | |
| 30 | pub fn bufPrintInt(inline T: type, out_buf: []u8, x: T) -> usize { | |
| 31 | if (T.is_signed) bufPrintSigned(T, out_buf, x) else bufPrintUnsigned(T, out_buf, x) | |
| 32 | } | |
| 33 | ||
| 34 | fn bufPrintSigned(inline T: type, out_buf: []u8, x: T) -> usize { | |
| 35 | const uint = @intType(false, T.bit_count); | |
| 36 | if (x < 0) { | |
| 37 | out_buf[0] = '-'; | |
| 38 | return 1 + bufPrintUnsigned(uint, out_buf[1...], uint(-(x + 1)) + 1); | |
| 39 | } else { | |
| 40 | return bufPrintUnsigned(uint, out_buf, uint(x)); | |
| 41 | } | |
| 42 | } | |
| 43 | ||
| 44 | fn bufPrintUnsigned(inline T: type, out_buf: []u8, x: T) -> usize { | |
| 45 | var buf: [max_u64_base10_digits]u8 = undefined; | |
| 46 | var a = x; | |
| 47 | var index: usize = buf.len; | |
| 48 | ||
| 49 | while (true) { | |
| 50 | const digit = a % 10; | |
| 51 | index -= 1; | |
| 52 | buf[index] = '0' + u8(digit); | |
| 53 | a /= 10; | |
| 54 | if (a == 0) | |
| 55 | break; | |
| 56 | } | |
| 57 | ||
| 58 | const len = buf.len - index; | |
| 59 | ||
| 60 | @memcpy(&out_buf[0], &buf[index], len); | |
| 61 | ||
| 62 | return len; | |
| 63 | } | |
| 64 | ||
| 65 | // TODO const assert = @import("std").debug.assert; | |
| 66 | fn assert(ok: bool) { | |
| 67 | if (!ok) | |
| 68 | @unreachable(); | |
| 69 | } | |
| 70 | ||
| 71 | // TODO import from std.str | |
| 72 | pub fn memeql(a: []const u8, b: []const u8) -> bool { | |
| 73 | sliceEql(u8, a, b) | |
| 74 | } | |
| 75 | ||
| 76 | // TODO import from std.str | |
| 77 | pub fn sliceEql(inline T: type, a: []const T, b: []const T) -> bool { | |
| 78 | if (a.len != b.len) return false; | |
| 79 | for (a) |item, index| { | |
| 80 | if (b[index] != item) return false; | |
| 81 | } | |
| 82 | return true; | |
| 83 | } |
test/cases/error.zig created+122| ... | ... | @@ -0,0 +1,122 @@ |
| 1 | pub fn foo() -> %i32 { | |
| 2 | const x = %return bar(); | |
| 3 | return x + 1 | |
| 4 | } | |
| 5 | ||
| 6 | pub fn bar() -> %i32 { | |
| 7 | return 13; | |
| 8 | } | |
| 9 | ||
| 10 | pub fn baz() -> %i32 { | |
| 11 | const y = foo() %% 1234; | |
| 12 | return y + 1; | |
| 13 | } | |
| 14 | ||
| 15 | fn errorWrapping() { | |
| 16 | @setFnTest(this); | |
| 17 | ||
| 18 | assert(%%baz() == 15); | |
| 19 | } | |
| 20 | ||
| 21 | error ItBroke; | |
| 22 | fn gimmeItBroke() -> []const u8 { | |
| 23 | @errorName(error.ItBroke) | |
| 24 | } | |
| 25 | ||
| 26 | fn errorName() { | |
| 27 | @setFnTest(this); | |
| 28 | assert(memeql(@errorName(error.AnError), "AnError")); | |
| 29 | assert(memeql(@errorName(error.ALongerErrorName), "ALongerErrorName")); | |
| 30 | } | |
| 31 | error AnError; | |
| 32 | error ALongerErrorName; | |
| 33 | ||
| 34 | ||
| 35 | fn errorValues() { | |
| 36 | @setFnTest(this); | |
| 37 | ||
| 38 | const a = i32(error.err1); | |
| 39 | const b = i32(error.err2); | |
| 40 | assert(a != b); | |
| 41 | } | |
| 42 | error err1; | |
| 43 | error err2; | |
| 44 | ||
| 45 | ||
| 46 | fn redefinitionOfErrorValuesAllowed() { | |
| 47 | @setFnTest(this); | |
| 48 | ||
| 49 | shouldBeNotEqual(error.AnError, error.SecondError); | |
| 50 | } | |
| 51 | error AnError; | |
| 52 | error AnError; | |
| 53 | error SecondError; | |
| 54 | fn shouldBeNotEqual(a: error, b: error) { | |
| 55 | if (a == b) @unreachable() | |
| 56 | } | |
| 57 | ||
| 58 | ||
| 59 | fn errBinaryOperator() { | |
| 60 | @setFnTest(this); | |
| 61 | ||
| 62 | const a = errBinaryOperatorG(true) %% 3; | |
| 63 | const b = errBinaryOperatorG(false) %% 3; | |
| 64 | assert(a == 3); | |
| 65 | assert(b == 10); | |
| 66 | } | |
| 67 | error ItBroke; | |
| 68 | fn errBinaryOperatorG(x: bool) -> %isize { | |
| 69 | if (x) { | |
| 70 | error.ItBroke | |
| 71 | } else { | |
| 72 | isize(10) | |
| 73 | } | |
| 74 | } | |
| 75 | ||
| 76 | ||
| 77 | fn unwrapSimpleValueFromError() { | |
| 78 | @setFnTest(this); | |
| 79 | ||
| 80 | const i = %%unwrapSimpleValueFromErrorDo(); | |
| 81 | assert(i == 13); | |
| 82 | } | |
| 83 | fn unwrapSimpleValueFromErrorDo() -> %isize { 13 } | |
| 84 | ||
| 85 | ||
| 86 | fn errReturnInAssignment() { | |
| 87 | @setFnTest(this); | |
| 88 | ||
| 89 | %%doErrReturnInAssignment(); | |
| 90 | } | |
| 91 | ||
| 92 | fn doErrReturnInAssignment() -> %void { | |
| 93 | var x : i32 = undefined; | |
| 94 | x = %return makeANonErr(); | |
| 95 | } | |
| 96 | ||
| 97 | fn makeANonErr() -> %i32 { | |
| 98 | return 1; | |
| 99 | } | |
| 100 | ||
| 101 | ||
| 102 | ||
| 103 | // TODO const assert = @import("std").debug.assert; | |
| 104 | fn assert(ok: bool) { | |
| 105 | if (!ok) | |
| 106 | @unreachable(); | |
| 107 | } | |
| 108 | ||
| 109 | // TODO import from std.str | |
| 110 | pub fn memeql(a: []const u8, b: []const u8) -> bool { | |
| 111 | sliceEql(u8, a, b) | |
| 112 | } | |
| 113 | ||
| 114 | // TODO import from std.str | |
| 115 | pub fn sliceEql(inline T: type, a: []const T, b: []const T) -> bool { | |
| 116 | if (a.len != b.len) return false; | |
| 117 | for (a) |item, index| { | |
| 118 | if (b[index] != item) return false; | |
| 119 | } | |
| 120 | return true; | |
| 121 | } | |
| 122 |
test/cases/eval.zig created+82| ... | ... | @@ -0,0 +1,82 @@ |
| 1 | fn compileTimeRecursion() { | |
| 2 | @setFnTest(this); | |
| 3 | ||
| 4 | assert(some_data.len == 21); | |
| 5 | } | |
| 6 | var some_data: [usize(fibbonaci(7))]u8 = undefined; | |
| 7 | fn fibbonaci(x: i32) -> i32 { | |
| 8 | if (x <= 1) return 1; | |
| 9 | return fibbonaci(x - 1) + fibbonaci(x - 2); | |
| 10 | } | |
| 11 | ||
| 12 | ||
| 13 | ||
| 14 | fn unwrapAndAddOne(blah: ?i32) -> i32 { | |
| 15 | return ??blah + 1; | |
| 16 | } | |
| 17 | const should_be_1235 = unwrapAndAddOne(1234); | |
| 18 | fn testStaticAddOne() { | |
| 19 | @setFnTest(this); | |
| 20 | assert(should_be_1235 == 1235); | |
| 21 | } | |
| 22 | ||
| 23 | fn inlinedLoop() { | |
| 24 | @setFnTest(this); | |
| 25 | ||
| 26 | inline var i = 0; | |
| 27 | inline var sum = 0; | |
| 28 | inline while (i <= 5; i += 1) | |
| 29 | sum += i; | |
| 30 | assert(sum == 15); | |
| 31 | } | |
| 32 | ||
| 33 | fn gimme1or2(inline a: bool) -> i32 { | |
| 34 | const x: i32 = 1; | |
| 35 | const y: i32 = 2; | |
| 36 | inline var z: i32 = if (a) x else y; | |
| 37 | return z; | |
| 38 | } | |
| 39 | fn inlineVariableGetsResultOfConstIf() { | |
| 40 | @setFnTest(this); | |
| 41 | assert(gimme1or2(true) == 1); | |
| 42 | assert(gimme1or2(false) == 2); | |
| 43 | } | |
| 44 | ||
| 45 | ||
| 46 | fn staticFunctionEvaluation() { | |
| 47 | @setFnTest(this); | |
| 48 | ||
| 49 | assert(statically_added_number == 3); | |
| 50 | } | |
| 51 | const statically_added_number = staticAdd(1, 2); | |
| 52 | fn staticAdd(a: i32, b: i32) -> i32 { a + b } | |
| 53 | ||
| 54 | ||
| 55 | fn constExprEvalOnSingleExprBlocks() { | |
| 56 | @setFnTest(this); | |
| 57 | ||
| 58 | assert(constExprEvalOnSingleExprBlocksFn(1, true) == 3); | |
| 59 | } | |
| 60 | ||
| 61 | fn constExprEvalOnSingleExprBlocksFn(x: i32, b: bool) -> i32 { | |
| 62 | const literal = 3; | |
| 63 | ||
| 64 | const result = if (b) { | |
| 65 | literal | |
| 66 | } else { | |
| 67 | x | |
| 68 | }; | |
| 69 | ||
| 70 | return result; | |
| 71 | } | |
| 72 | ||
| 73 | ||
| 74 | ||
| 75 | ||
| 76 | ||
| 77 | // TODO const assert = @import("std").debug.assert; | |
| 78 | fn assert(ok: bool) { | |
| 79 | if (!ok) | |
| 80 | @unreachable(); | |
| 81 | } | |
| 82 |
test/cases/fn.zig created+94| ... | ... | @@ -0,0 +1,94 @@ |
| 1 | fn params() { | |
| 2 | @setFnTest(this); | |
| 3 | ||
| 4 | assert(testParamsAdd(22, 11) == 33); | |
| 5 | } | |
| 6 | fn testParamsAdd(a: i32, b: i32) -> i32 { | |
| 7 | a + b | |
| 8 | } | |
| 9 | ||
| 10 | ||
| 11 | fn localVariables() { | |
| 12 | @setFnTest(this); | |
| 13 | ||
| 14 | testLocVars(2); | |
| 15 | } | |
| 16 | fn testLocVars(b: i32) { | |
| 17 | const a: i32 = 1; | |
| 18 | if (a + b != 3) @unreachable(); | |
| 19 | } | |
| 20 | ||
| 21 | ||
| 22 | fn voidParameters() { | |
| 23 | @setFnTest(this); | |
| 24 | ||
| 25 | voidFun(1, void{}, 2, {}); | |
| 26 | } | |
| 27 | fn voidFun(a: i32, b: void, c: i32, d: void) { | |
| 28 | const v = b; | |
| 29 | const vv: void = if (a == 1) {v} else {}; | |
| 30 | assert(a + c == 3); | |
| 31 | return vv; | |
| 32 | } | |
| 33 | ||
| 34 | ||
| 35 | fn mutableLocalVariables() { | |
| 36 | @setFnTest(this); | |
| 37 | ||
| 38 | var zero : i32 = 0; | |
| 39 | assert(zero == 0); | |
| 40 | ||
| 41 | var i = i32(0); | |
| 42 | while (i != 3) { | |
| 43 | i += 1; | |
| 44 | } | |
| 45 | assert(i == 3); | |
| 46 | } | |
| 47 | ||
| 48 | fn separateBlockScopes() { | |
| 49 | @setFnTest(this); | |
| 50 | ||
| 51 | { | |
| 52 | const no_conflict : i32 = 5; | |
| 53 | assert(no_conflict == 5); | |
| 54 | } | |
| 55 | ||
| 56 | const c = { | |
| 57 | const no_conflict = i32(10); | |
| 58 | no_conflict | |
| 59 | }; | |
| 60 | assert(c == 10); | |
| 61 | } | |
| 62 | ||
| 63 | fn callFnWithEmptyString() { | |
| 64 | @setFnTest(this); | |
| 65 | ||
| 66 | acceptsString(""); | |
| 67 | } | |
| 68 | ||
| 69 | fn acceptsString(foo: []u8) { } | |
| 70 | ||
| 71 | ||
| 72 | fn @"weird function name"() { | |
| 73 | @setFnTest(this); | |
| 74 | } | |
| 75 | ||
| 76 | fn implicitCastFnUnreachableReturn() { | |
| 77 | @setFnTest(this); | |
| 78 | ||
| 79 | wantsFnWithVoid(fnWithUnreachable); | |
| 80 | } | |
| 81 | ||
| 82 | fn wantsFnWithVoid(f: fn()) { } | |
| 83 | ||
| 84 | fn fnWithUnreachable() -> unreachable { | |
| 85 | @unreachable() | |
| 86 | } | |
| 87 | ||
| 88 | ||
| 89 | ||
| 90 | // TODO const assert = @import("std").debug.assert; | |
| 91 | fn assert(ok: bool) { | |
| 92 | if (!ok) | |
| 93 | @unreachable(); | |
| 94 | } |
test/cases/for.zig created+14| ... | ... | @@ -0,0 +1,14 @@ |
| 1 | fn continueInForLoop() { | |
| 2 | @setFnTest(this); | |
| 3 | ||
| 4 | const array = []i32 {1, 2, 3, 4, 5}; | |
| 5 | var sum : i32 = 0; | |
| 6 | for (array) |x| { | |
| 7 | sum += x; | |
| 8 | if (x < 3) { | |
| 9 | continue; | |
| 10 | } | |
| 11 | break; | |
| 12 | } | |
| 13 | if (sum != 6) @unreachable() | |
| 14 | } |
test/cases/generics.zig created+96| ... | ... | @@ -0,0 +1,96 @@ |
| 1 | fn simpleGenericFn() { | |
| 2 | @setFnTest(this); | |
| 3 | ||
| 4 | assert(max(i32, 3, -1) == 3); | |
| 5 | assert(max(f32, 0.123, 0.456) == 0.456); | |
| 6 | assert(add(2, 3) == 5); | |
| 7 | } | |
| 8 | ||
| 9 | fn max(inline T: type, a: T, b: T) -> T { | |
| 10 | return if (a > b) a else b; | |
| 11 | } | |
| 12 | ||
| 13 | fn add(inline a: i32, b: i32) -> i32 { | |
| 14 | return @staticEval(a) + b; | |
| 15 | } | |
| 16 | ||
| 17 | const the_max = max(u32, 1234, 5678); | |
| 18 | fn compileTimeGenericEval() { | |
| 19 | @setFnTest(this); | |
| 20 | assert(the_max == 5678); | |
| 21 | } | |
| 22 | ||
| 23 | fn gimmeTheBigOne(a: u32, b: u32) -> u32 { | |
| 24 | max(u32, a, b) | |
| 25 | } | |
| 26 | ||
| 27 | fn shouldCallSameInstance(a: u32, b: u32) -> u32 { | |
| 28 | max(u32, a, b) | |
| 29 | } | |
| 30 | ||
| 31 | fn sameButWithFloats(a: f64, b: f64) -> f64 { | |
| 32 | max(f64, a, b) | |
| 33 | } | |
| 34 | ||
| 35 | fn fnWithInlineArgs() { | |
| 36 | @setFnTest(this); | |
| 37 | ||
| 38 | assert(gimmeTheBigOne(1234, 5678) == 5678); | |
| 39 | assert(shouldCallSameInstance(34, 12) == 34); | |
| 40 | assert(sameButWithFloats(0.43, 0.49) == 0.49); | |
| 41 | } | |
| 42 | ||
| 43 | ||
| 44 | fn varParams() { | |
| 45 | @setFnTest(this); | |
| 46 | ||
| 47 | assert(max_i32(12, 34) == 34); | |
| 48 | assert(max_f64(1.2, 3.4) == 3.4); | |
| 49 | } | |
| 50 | ||
| 51 | // TODO `_` | |
| 52 | const _1 = assert(max_i32(12, 34) == 34); | |
| 53 | const _2 = assert(max_f64(1.2, 3.4) == 3.4); | |
| 54 | ||
| 55 | fn max_var(a: var, b: var) -> @typeOf(a + b) { | |
| 56 | if (a > b) a else b | |
| 57 | } | |
| 58 | ||
| 59 | fn max_i32(a: i32, b: i32) -> i32 { | |
| 60 | max_var(a, b) | |
| 61 | } | |
| 62 | ||
| 63 | fn max_f64(a: f64, b: f64) -> f64 { | |
| 64 | max_var(a, b) | |
| 65 | } | |
| 66 | ||
| 67 | ||
| 68 | pub fn List(inline T: type) -> type { | |
| 69 | SmallList(T, 8) | |
| 70 | } | |
| 71 | ||
| 72 | pub fn SmallList(inline T: type, inline STATIC_SIZE: usize) -> type { | |
| 73 | struct { | |
| 74 | items: []T, | |
| 75 | length: usize, | |
| 76 | prealloc_items: [STATIC_SIZE]T, | |
| 77 | } | |
| 78 | } | |
| 79 | ||
| 80 | fn functionWithReturnTypeType() { | |
| 81 | @setFnTest(this); | |
| 82 | ||
| 83 | var list: List(i32) = undefined; | |
| 84 | var list2: List(i32) = undefined; | |
| 85 | list.length = 10; | |
| 86 | list2.length = 10; | |
| 87 | assert(list.prealloc_items.len == 8); | |
| 88 | assert(list2.prealloc_items.len == 8); | |
| 89 | } | |
| 90 | ||
| 91 | // TODO const assert = @import("std").debug.assert; | |
| 92 | fn assert(ok: bool) { | |
| 93 | if (!ok) | |
| 94 | @unreachable(); | |
| 95 | } | |
| 96 |
test/cases/goto.zig created+45| ... | ... | @@ -0,0 +1,45 @@ |
| 1 | fn gotoAndLabels() { | |
| 2 | @setFnTest(this); | |
| 3 | ||
| 4 | gotoLoop(); | |
| 5 | assert(goto_counter == 10); | |
| 6 | } | |
| 7 | fn gotoLoop() { | |
| 8 | var i: i32 = 0; | |
| 9 | goto cond; | |
| 10 | loop: | |
| 11 | i += 1; | |
| 12 | cond: | |
| 13 | if (!(i < 10)) goto end; | |
| 14 | goto_counter += 1; | |
| 15 | goto loop; | |
| 16 | end: | |
| 17 | } | |
| 18 | var goto_counter: i32 = 0; | |
| 19 | ||
| 20 | ||
| 21 | ||
| 22 | fn gotoLeaveDeferScope() { | |
| 23 | @setFnTest(this); | |
| 24 | ||
| 25 | testGotoLeaveDeferScope(true); | |
| 26 | } | |
| 27 | fn testGotoLeaveDeferScope(b: bool) { | |
| 28 | var it_worked = false; | |
| 29 | ||
| 30 | goto entry; | |
| 31 | exit: | |
| 32 | if (it_worked) { | |
| 33 | return; | |
| 34 | } | |
| 35 | @unreachable(); | |
| 36 | entry: | |
| 37 | defer it_worked = true; | |
| 38 | if (b) goto exit; | |
| 39 | } | |
| 40 | ||
| 41 | // TODO const assert = @import("std").debug.assert; | |
| 42 | fn assert(ok: bool) { | |
| 43 | if (!ok) | |
| 44 | @unreachable(); | |
| 45 | } |
test/cases/if.zig created+46| ... | ... | @@ -0,0 +1,46 @@ |
| 1 | fn ifStatements() { | |
| 2 | @setFnTest(this); | |
| 3 | ||
| 4 | shouldBeEqual(1, 1); | |
| 5 | firstEqlThird(2, 1, 2); | |
| 6 | } | |
| 7 | fn shouldBeEqual(a: i32, b: i32) { | |
| 8 | if (a != b) { | |
| 9 | @unreachable(); | |
| 10 | } else { | |
| 11 | return; | |
| 12 | } | |
| 13 | } | |
| 14 | fn firstEqlThird(a: i32, b: i32, c: i32) { | |
| 15 | if (a == b) { | |
| 16 | @unreachable(); | |
| 17 | } else if (b == c) { | |
| 18 | @unreachable(); | |
| 19 | } else if (a == c) { | |
| 20 | return; | |
| 21 | } else { | |
| 22 | @unreachable(); | |
| 23 | } | |
| 24 | } | |
| 25 | ||
| 26 | ||
| 27 | fn elseIfExpression() { | |
| 28 | @setFnTest(this); | |
| 29 | ||
| 30 | assert(elseIfExpressionF(1) == 1); | |
| 31 | } | |
| 32 | fn elseIfExpressionF(c: u8) -> u8 { | |
| 33 | if (c == 0) { | |
| 34 | 0 | |
| 35 | } else if (c == 1) { | |
| 36 | 1 | |
| 37 | } else { | |
| 38 | u8(2) | |
| 39 | } | |
| 40 | } | |
| 41 | ||
| 42 | // TODO const assert = @import("std").debug.assert; | |
| 43 | fn assert(ok: bool) { | |
| 44 | if (!ok) | |
| 45 | @unreachable(); | |
| 46 | } |
test/cases/import.zig created+13| ... | ... | @@ -0,0 +1,13 @@ |
| 1 | const a_namespace = @import("cases/import/a_namespace.zig"); | |
| 2 | ||
| 3 | fn callFnViaNamespaceLookup() { | |
| 4 | @setFnTest(this); | |
| 5 | ||
| 6 | assert(a_namespace.foo() == 1234); | |
| 7 | } | |
| 8 | ||
| 9 | // TODO const assert = @import("std").debug.assert; | |
| 10 | fn assert(ok: bool) { | |
| 11 | if (!ok) | |
| 12 | @unreachable(); | |
| 13 | } |
test/cases/import/a_namespace.zig created+1| ... | ... | @@ -0,0 +1 @@ |
| 1 | pub fn foo() -> i32 { 1234 } |
test/cases/math.zig created+109| ... | ... | @@ -0,0 +1,109 @@ |
| 1 | fn exactDivision() { | |
| 2 | @setFnTest(this); | |
| 3 | ||
| 4 | assert(divExact(55, 11) == 5); | |
| 5 | } | |
| 6 | fn divExact(a: u32, b: u32) -> u32 { | |
| 7 | @divExact(a, b) | |
| 8 | } | |
| 9 | ||
| 10 | fn floatDivision() { | |
| 11 | @setFnTest(this); | |
| 12 | ||
| 13 | assert(fdiv32(12.0, 3.0) == 4.0); | |
| 14 | } | |
| 15 | fn fdiv32(a: f32, b: f32) -> f32 { | |
| 16 | a / b | |
| 17 | } | |
| 18 | ||
| 19 | fn overflowIntrinsics() { | |
| 20 | @setFnTest(this); | |
| 21 | ||
| 22 | var result: u8 = undefined; | |
| 23 | assert(@addWithOverflow(u8, 250, 100, &result)); | |
| 24 | assert(!@addWithOverflow(u8, 100, 150, &result)); | |
| 25 | assert(result == 250); | |
| 26 | } | |
| 27 | ||
| 28 | fn shlWithOverflow() { | |
| 29 | @setFnTest(this); | |
| 30 | ||
| 31 | var result: u16 = undefined; | |
| 32 | assert(@shlWithOverflow(u16, 0b0010111111111111, 3, &result)); | |
| 33 | assert(!@shlWithOverflow(u16, 0b0010111111111111, 2, &result)); | |
| 34 | assert(result == 0b1011111111111100); | |
| 35 | } | |
| 36 | ||
| 37 | fn countLeadingZeroes() { | |
| 38 | @setFnTest(this); | |
| 39 | ||
| 40 | assert(@clz(u8(0b00001010)) == 4); | |
| 41 | assert(@clz(u8(0b10001010)) == 0); | |
| 42 | assert(@clz(u8(0b00000000)) == 8); | |
| 43 | } | |
| 44 | ||
| 45 | fn countTrailingZeroes() { | |
| 46 | @setFnTest(this); | |
| 47 | ||
| 48 | assert(@ctz(u8(0b10100000)) == 5); | |
| 49 | assert(@ctz(u8(0b10001010)) == 1); | |
| 50 | assert(@ctz(u8(0b00000000)) == 8); | |
| 51 | } | |
| 52 | ||
| 53 | fn modifyOperators() { | |
| 54 | @setFnTest(this); | |
| 55 | ||
| 56 | var i : i32 = 0; | |
| 57 | i += 5; assert(i == 5); | |
| 58 | i -= 2; assert(i == 3); | |
| 59 | i *= 20; assert(i == 60); | |
| 60 | i /= 3; assert(i == 20); | |
| 61 | i %= 11; assert(i == 9); | |
| 62 | i <<= 1; assert(i == 18); | |
| 63 | i >>= 2; assert(i == 4); | |
| 64 | i = 6; | |
| 65 | i &= 5; assert(i == 4); | |
| 66 | i ^= 6; assert(i == 2); | |
| 67 | i = 6; | |
| 68 | i |= 3; assert(i == 7); | |
| 69 | } | |
| 70 | ||
| 71 | fn threeExprInARow() { | |
| 72 | @setFnTest(this); | |
| 73 | ||
| 74 | assertFalse(false || false || false); | |
| 75 | assertFalse(true && true && false); | |
| 76 | assertFalse(1 | 2 | 4 != 7); | |
| 77 | assertFalse(3 ^ 6 ^ 8 != 13); | |
| 78 | assertFalse(7 & 14 & 28 != 4); | |
| 79 | assertFalse(9 << 1 << 2 != 9 << 3); | |
| 80 | assertFalse(90 >> 1 >> 2 != 90 >> 3); | |
| 81 | assertFalse(100 - 1 + 1000 != 1099); | |
| 82 | assertFalse(5 * 4 / 2 % 3 != 1); | |
| 83 | assertFalse(i32(i32(5)) != 5); | |
| 84 | assertFalse(!!false); | |
| 85 | assertFalse(i32(7) != --(i32(7))); | |
| 86 | } | |
| 87 | fn assertFalse(b: bool) { | |
| 88 | assert(!b); | |
| 89 | } | |
| 90 | ||
| 91 | ||
| 92 | fn constNumberLiteral() { | |
| 93 | @setFnTest(this); | |
| 94 | ||
| 95 | const one = 1; | |
| 96 | const eleven = ten + one; | |
| 97 | ||
| 98 | assert(eleven == 11); | |
| 99 | } | |
| 100 | const ten = 10; | |
| 101 | ||
| 102 | ||
| 103 | ||
| 104 | // TODO const assert = @import("std").debug.assert; | |
| 105 | fn assert(ok: bool) { | |
| 106 | if (!ok) | |
| 107 | @unreachable(); | |
| 108 | } | |
| 109 |
test/cases/misc.zig created+305| ... | ... | @@ -0,0 +1,305 @@ |
| 1 | // normal comment | |
| 2 | /// this is a documentation comment | |
| 3 | /// doc comment line 2 | |
| 4 | fn emptyFunctionWithComments() { | |
| 5 | @setFnTest(this); | |
| 6 | } | |
| 7 | ||
| 8 | export fn disabledExternFn() { | |
| 9 | @setFnVisible(this, false); | |
| 10 | } | |
| 11 | ||
| 12 | fn callDisabledExternFn() { | |
| 13 | @setFnTest(this); | |
| 14 | ||
| 15 | disabledExternFn(); | |
| 16 | } | |
| 17 | ||
| 18 | fn intTypeBuiltin() { | |
| 19 | @setFnTest(this); | |
| 20 | ||
| 21 | assert(@intType(true, 8) == i8); | |
| 22 | assert(@intType(true, 16) == i16); | |
| 23 | assert(@intType(true, 32) == i32); | |
| 24 | assert(@intType(true, 64) == i64); | |
| 25 | ||
| 26 | assert(@intType(false, 8) == u8); | |
| 27 | assert(@intType(false, 16) == u16); | |
| 28 | assert(@intType(false, 32) == u32); | |
| 29 | assert(@intType(false, 64) == u64); | |
| 30 | ||
| 31 | assert(i8.bit_count == 8); | |
| 32 | assert(i16.bit_count == 16); | |
| 33 | assert(i32.bit_count == 32); | |
| 34 | assert(i64.bit_count == 64); | |
| 35 | ||
| 36 | assert(i8.is_signed); | |
| 37 | assert(i16.is_signed); | |
| 38 | assert(i32.is_signed); | |
| 39 | assert(i64.is_signed); | |
| 40 | assert(isize.is_signed); | |
| 41 | ||
| 42 | assert(!u8.is_signed); | |
| 43 | assert(!u16.is_signed); | |
| 44 | assert(!u32.is_signed); | |
| 45 | assert(!u64.is_signed); | |
| 46 | assert(!usize.is_signed); | |
| 47 | } | |
| 48 | ||
| 49 | fn minValueAndMaxValue() { | |
| 50 | @setFnTest(this); | |
| 51 | ||
| 52 | assert(@maxValue(u8) == 255); | |
| 53 | assert(@maxValue(u16) == 65535); | |
| 54 | assert(@maxValue(u32) == 4294967295); | |
| 55 | assert(@maxValue(u64) == 18446744073709551615); | |
| 56 | ||
| 57 | assert(@maxValue(i8) == 127); | |
| 58 | assert(@maxValue(i16) == 32767); | |
| 59 | assert(@maxValue(i32) == 2147483647); | |
| 60 | assert(@maxValue(i64) == 9223372036854775807); | |
| 61 | ||
| 62 | assert(@minValue(u8) == 0); | |
| 63 | assert(@minValue(u16) == 0); | |
| 64 | assert(@minValue(u32) == 0); | |
| 65 | assert(@minValue(u64) == 0); | |
| 66 | ||
| 67 | assert(@minValue(i8) == -128); | |
| 68 | assert(@minValue(i16) == -32768); | |
| 69 | assert(@minValue(i32) == -2147483648); | |
| 70 | assert(@minValue(i64) == -9223372036854775808); | |
| 71 | } | |
| 72 | ||
| 73 | fn maxValueType() { | |
| 74 | @setFnTest(this); | |
| 75 | ||
| 76 | // If the type of @maxValue(i32) was i32 then this implicit cast to | |
| 77 | // u32 would not work. But since the value is a number literal, | |
| 78 | // it works fine. | |
| 79 | const x: u32 = @maxValue(i32); | |
| 80 | assert(x == 2147483647); | |
| 81 | } | |
| 82 | ||
| 83 | fn shortCircuit() { | |
| 84 | @setFnTest(this); | |
| 85 | ||
| 86 | var hit_1 = false; | |
| 87 | var hit_2 = false; | |
| 88 | var hit_3 = false; | |
| 89 | var hit_4 = false; | |
| 90 | ||
| 91 | if (true || {assert(false); false}) { | |
| 92 | hit_1 = true; | |
| 93 | } | |
| 94 | if (false || { hit_2 = true; false }) { | |
| 95 | assert(false); | |
| 96 | } | |
| 97 | ||
| 98 | if (true && { hit_3 = true; false }) { | |
| 99 | assert(false); | |
| 100 | } | |
| 101 | if (false && {assert(false); false}) { | |
| 102 | assert(false); | |
| 103 | } else { | |
| 104 | hit_4 = true; | |
| 105 | } | |
| 106 | assert(hit_1); | |
| 107 | assert(hit_2); | |
| 108 | assert(hit_3); | |
| 109 | assert(hit_4); | |
| 110 | } | |
| 111 | ||
| 112 | fn truncate() { | |
| 113 | @setFnTest(this); | |
| 114 | ||
| 115 | assert(testTruncate(0x10fd) == 0xfd); | |
| 116 | } | |
| 117 | fn testTruncate(x: u32) -> u8 { | |
| 118 | @truncate(u8, x) | |
| 119 | } | |
| 120 | ||
| 121 | fn assignToIfVarPtr() { | |
| 122 | @setFnTest(this); | |
| 123 | ||
| 124 | var maybe_bool: ?bool = true; | |
| 125 | ||
| 126 | if (const *b ?= maybe_bool) { | |
| 127 | *b = false; | |
| 128 | } | |
| 129 | ||
| 130 | assert(??maybe_bool == false); | |
| 131 | } | |
| 132 | ||
| 133 | fn first4KeysOfHomeRow() -> []const u8 { | |
| 134 | "aoeu" | |
| 135 | } | |
| 136 | ||
| 137 | fn ReturnStringFromFunction() { | |
| 138 | @setFnTest(this); | |
| 139 | ||
| 140 | assert(memeql(first4KeysOfHomeRow(), "aoeu")); | |
| 141 | } | |
| 142 | ||
| 143 | const g1 : i32 = 1233 + 1; | |
| 144 | var g2 : i32 = 0; | |
| 145 | ||
| 146 | fn globalVariables() { | |
| 147 | @setFnTest(this); | |
| 148 | ||
| 149 | assert(g2 == 0); | |
| 150 | g2 = g1; | |
| 151 | assert(g2 == 1234); | |
| 152 | } | |
| 153 | ||
| 154 | ||
| 155 | fn memcpyAndMemsetIntrinsics() { | |
| 156 | @setFnTest(this); | |
| 157 | ||
| 158 | var foo : [20]u8 = undefined; | |
| 159 | var bar : [20]u8 = undefined; | |
| 160 | ||
| 161 | @memset(&foo[0], 'A', foo.len); | |
| 162 | @memcpy(&bar[0], &foo[0], bar.len); | |
| 163 | ||
| 164 | if (bar[11] != 'A') @unreachable(); | |
| 165 | } | |
| 166 | ||
| 167 | fn builtinStaticEval() { | |
| 168 | @setFnTest(this); | |
| 169 | ||
| 170 | const x : i32 = @staticEval(1 + 2 + 3); | |
| 171 | assert(x == @staticEval(6)); | |
| 172 | } | |
| 173 | ||
| 174 | fn slicing() { | |
| 175 | @setFnTest(this); | |
| 176 | ||
| 177 | var array : [20]i32 = undefined; | |
| 178 | ||
| 179 | array[5] = 1234; | |
| 180 | ||
| 181 | var slice = array[5...10]; | |
| 182 | ||
| 183 | if (slice.len != 5) @unreachable(); | |
| 184 | ||
| 185 | const ptr = &slice[0]; | |
| 186 | if (ptr[0] != 1234) @unreachable(); | |
| 187 | ||
| 188 | var slice_rest = array[10...]; | |
| 189 | if (slice_rest.len != 10) @unreachable(); | |
| 190 | } | |
| 191 | ||
| 192 | ||
| 193 | fn constantEqualFunctionPointers() { | |
| 194 | @setFnTest(this); | |
| 195 | ||
| 196 | const alias = emptyFn; | |
| 197 | assert(@staticEval(emptyFn == alias)); | |
| 198 | } | |
| 199 | ||
| 200 | fn emptyFn() {} | |
| 201 | ||
| 202 | ||
| 203 | fn hexEscape() { | |
| 204 | @setFnTest(this); | |
| 205 | ||
| 206 | assert(memeql("\x68\x65\x6c\x6c\x6f", "hello")); | |
| 207 | } | |
| 208 | ||
| 209 | fn stringConcatenation() { | |
| 210 | @setFnTest(this); | |
| 211 | ||
| 212 | assert(memeql("OK" ++ " IT " ++ "WORKED", "OK IT WORKED")); | |
| 213 | } | |
| 214 | ||
| 215 | fn arrayMultOperator() { | |
| 216 | @setFnTest(this); | |
| 217 | ||
| 218 | assert(memeql("ab" ** 5, "ababababab")); | |
| 219 | } | |
| 220 | ||
| 221 | fn stringEscapes() { | |
| 222 | @setFnTest(this); | |
| 223 | ||
| 224 | assert(memeql("\"", "\x22")); | |
| 225 | assert(memeql("\'", "\x27")); | |
| 226 | assert(memeql("\n", "\x0a")); | |
| 227 | assert(memeql("\r", "\x0d")); | |
| 228 | assert(memeql("\t", "\x09")); | |
| 229 | assert(memeql("\\", "\x5c")); | |
| 230 | assert(memeql("\u1234\u0069", "\xe1\x88\xb4\x69")); | |
| 231 | } | |
| 232 | ||
| 233 | fn multilineString() { | |
| 234 | @setFnTest(this); | |
| 235 | ||
| 236 | const s1 = | |
| 237 | \\one | |
| 238 | \\two) | |
| 239 | \\three | |
| 240 | ; | |
| 241 | const s2 = "one\ntwo)\nthree"; | |
| 242 | assert(memeql(s1, s2)); | |
| 243 | } | |
| 244 | ||
| 245 | fn multilineCString() { | |
| 246 | @setFnTest(this); | |
| 247 | ||
| 248 | const s1 = | |
| 249 | c\\one | |
| 250 | c\\two) | |
| 251 | c\\three | |
| 252 | ; | |
| 253 | const s2 = c"one\ntwo)\nthree"; | |
| 254 | assert(cstrcmp(s1, s2) == 0); | |
| 255 | } | |
| 256 | ||
| 257 | ||
| 258 | fn typeEquality() { | |
| 259 | @setFnTest(this); | |
| 260 | ||
| 261 | assert(&const u8 != &u8); | |
| 262 | } | |
| 263 | ||
| 264 | ||
| 265 | const global_a: i32 = 1234; | |
| 266 | const global_b: &const i32 = &global_a; | |
| 267 | const global_c: &const f32 = (&const f32)(global_b); | |
| 268 | fn compileTimeGlobalReinterpret() { | |
| 269 | @setFnTest(this); | |
| 270 | const d = (&const i32)(global_c); | |
| 271 | assert(*d == 1234); | |
| 272 | } | |
| 273 | ||
| 274 | // TODO import from std.str | |
| 275 | pub fn memeql(a: []const u8, b: []const u8) -> bool { | |
| 276 | sliceEql(u8, a, b) | |
| 277 | } | |
| 278 | ||
| 279 | // TODO import from std.str | |
| 280 | pub fn sliceEql(inline T: type, a: []const T, b: []const T) -> bool { | |
| 281 | if (a.len != b.len) return false; | |
| 282 | for (a) |item, index| { | |
| 283 | if (b[index] != item) return false; | |
| 284 | } | |
| 285 | return true; | |
| 286 | } | |
| 287 | ||
| 288 | // TODO import from std.cstr | |
| 289 | pub fn cstrcmp(a: &const u8, b: &const u8) -> i8 { | |
| 290 | var index: usize = 0; | |
| 291 | while (a[index] == b[index] && a[index] != 0; index += 1) {} | |
| 292 | return if (a[index] > b[index]) { | |
| 293 | 1 | |
| 294 | } else if (a[index] < b[index]) { | |
| 295 | -1 | |
| 296 | } else { | |
| 297 | i8(0) | |
| 298 | }; | |
| 299 | } | |
| 300 | ||
| 301 | // TODO const assert = @import("std").debug.assert; | |
| 302 | fn assert(ok: bool) { | |
| 303 | if (!ok) | |
| 304 | @unreachable(); | |
| 305 | } |
test/cases/namespace_depends_on_compile_var/a.zig created+1| ... | ... | @@ -0,0 +1 @@ |
| 1 | pub const a_bool = true; |
test/cases/namespace_depends_on_compile_var/b.zig created+1| ... | ... | @@ -0,0 +1 @@ |
| 1 | pub const a_bool = false; |
test/cases/namespace_depends_on_compile_var/index.zig created+19| ... | ... | @@ -0,0 +1,19 @@ |
| 1 | fn namespaceDependsOnCompileVar() { | |
| 2 | @setFnTest(this); | |
| 3 | ||
| 4 | if (some_namespace.a_bool) { | |
| 5 | assert(some_namespace.a_bool); | |
| 6 | } else { | |
| 7 | assert(!some_namespace.a_bool); | |
| 8 | } | |
| 9 | } | |
| 10 | const some_namespace = switch(@compileVar("os")) { | |
| 11 | Os.linux => @import("cases/namespace_depends_on_compile_var/a.zig"), | |
| 12 | else => @import("cases/namespace_depends_on_compile_var/b.zig"), | |
| 13 | }; | |
| 14 | ||
| 15 | // TODO const assert = @import("std").debug.assert; | |
| 16 | fn assert(ok: bool) { | |
| 17 | if (!ok) | |
| 18 | @unreachable(); | |
| 19 | } |
test/cases/null.zig created+68| ... | ... | @@ -0,0 +1,68 @@ |
| 1 | fn nullableType() { | |
| 2 | @setFnTest(this); | |
| 3 | ||
| 4 | const x : ?bool = true; | |
| 5 | ||
| 6 | if (const y ?= x) { | |
| 7 | if (y) { | |
| 8 | // OK | |
| 9 | } else { | |
| 10 | @unreachable(); | |
| 11 | } | |
| 12 | } else { | |
| 13 | @unreachable(); | |
| 14 | } | |
| 15 | ||
| 16 | const next_x : ?i32 = null; | |
| 17 | ||
| 18 | const z = next_x ?? 1234; | |
| 19 | ||
| 20 | assert(z == 1234); | |
| 21 | ||
| 22 | const final_x : ?i32 = 13; | |
| 23 | ||
| 24 | const num = final_x ?? @unreachable(); | |
| 25 | ||
| 26 | assert(num == 13); | |
| 27 | } | |
| 28 | ||
| 29 | fn assignToIfVarPtr() { | |
| 30 | @setFnTest(this); | |
| 31 | ||
| 32 | var maybe_bool: ?bool = true; | |
| 33 | ||
| 34 | if (const *b ?= maybe_bool) { | |
| 35 | *b = false; | |
| 36 | } | |
| 37 | ||
| 38 | assert(??maybe_bool == false); | |
| 39 | } | |
| 40 | ||
| 41 | fn rhsMaybeUnwrapReturn() { | |
| 42 | @setFnTest(this); | |
| 43 | ||
| 44 | const x: ?bool = true; | |
| 45 | const y = x ?? return; | |
| 46 | } | |
| 47 | ||
| 48 | ||
| 49 | fn maybeReturn() { | |
| 50 | @setFnTest(this); | |
| 51 | ||
| 52 | assert(??foo(1235)); | |
| 53 | assert(if (const _ ?= foo(null)) false else true); | |
| 54 | assert(!??foo(1234)); | |
| 55 | } | |
| 56 | ||
| 57 | // TODO test static eval maybe return | |
| 58 | fn foo(x: ?i32) -> ?bool { | |
| 59 | const value = ?return x; | |
| 60 | return value > 1234; | |
| 61 | } | |
| 62 | ||
| 63 | // TODO const assert = @import("std").debug.assert; | |
| 64 | fn assert(ok: bool) { | |
| 65 | if (!ok) | |
| 66 | @unreachable(); | |
| 67 | } | |
| 68 |
test/cases/pub_enum/index.zig created+23| ... | ... | @@ -0,0 +1,23 @@ |
| 1 | const other = @import("cases/pub_enum/other.zig"); | |
| 2 | ||
| 3 | fn pubEnum() { | |
| 4 | @setFnTest(this); | |
| 5 | ||
| 6 | pubEnumTest(other.APubEnum.Two); | |
| 7 | } | |
| 8 | fn pubEnumTest(foo: other.APubEnum) { | |
| 9 | assert(foo == other.APubEnum.Two); | |
| 10 | } | |
| 11 | ||
| 12 | fn castWithImportedSymbol() { | |
| 13 | @setFnTest(this); | |
| 14 | ||
| 15 | assert(other.size_t(42) == 42); | |
| 16 | } | |
| 17 | ||
| 18 | ||
| 19 | // TODO const assert = @import("std").debug.assert; | |
| 20 | fn assert(ok: bool) { | |
| 21 | if (!ok) | |
| 22 | @unreachable(); | |
| 23 | } |
test/cases/pub_enum/other.zig created+6| ... | ... | @@ -0,0 +1,6 @@ |
| 1 | pub const APubEnum = enum { | |
| 2 | One, | |
| 3 | Two, | |
| 4 | Three, | |
| 5 | }; | |
| 6 | pub const size_t = u64; |
test/cases/sizeof_and_typeof.zig created+14| ... | ... | @@ -0,0 +1,14 @@ |
| 1 | fn sizeofAndTypeOf() { | |
| 2 | @setFnTest(this); | |
| 3 | ||
| 4 | const y: @typeOf(x) = 120; | |
| 5 | assert(@sizeOf(@typeOf(y)) == 2); | |
| 6 | } | |
| 7 | const x: u16 = 13; | |
| 8 | const z: @typeOf(x) = 19; | |
| 9 | ||
| 10 | // TODO const assert = @import("std").debug.assert; | |
| 11 | fn assert(ok: bool) { | |
| 12 | if (!ok) | |
| 13 | @unreachable(); | |
| 14 | } |
test/cases/struct.zig created+166| ... | ... | @@ -0,0 +1,166 @@ |
| 1 | const StructWithNoFields = struct { | |
| 2 | fn add(a: i32, b: i32) -> i32 { a + b } | |
| 3 | }; | |
| 4 | const empty_global_instance = StructWithNoFields {}; | |
| 5 | ||
| 6 | fn callStructStaticMethod() { | |
| 7 | @setFnTest(this); | |
| 8 | const result = StructWithNoFields.add(3, 4); | |
| 9 | assert(result == 7); | |
| 10 | } | |
| 11 | ||
| 12 | fn returnEmptyStructInstance() -> StructWithNoFields { | |
| 13 | @setFnTest(this); | |
| 14 | return empty_global_instance; | |
| 15 | } | |
| 16 | ||
| 17 | const should_be_11 = StructWithNoFields.add(5, 6); | |
| 18 | ||
| 19 | fn invokeStaticMethodInGlobalScope() { | |
| 20 | @setFnTest(this); | |
| 21 | assert(should_be_11 == 11); | |
| 22 | } | |
| 23 | ||
| 24 | fn voidStructFields() { | |
| 25 | @setFnTest(this); | |
| 26 | ||
| 27 | const foo = VoidStructFieldsFoo { | |
| 28 | .a = void{}, | |
| 29 | .b = 1, | |
| 30 | .c = void{}, | |
| 31 | }; | |
| 32 | assert(foo.b == 1); | |
| 33 | assert(@sizeOf(VoidStructFieldsFoo) == 4); | |
| 34 | } | |
| 35 | const VoidStructFieldsFoo = struct { | |
| 36 | a : void, | |
| 37 | b : i32, | |
| 38 | c : void, | |
| 39 | }; | |
| 40 | ||
| 41 | ||
| 42 | pub fn structs() { | |
| 43 | @setFnTest(this); | |
| 44 | ||
| 45 | var foo: StructFoo = undefined; | |
| 46 | @memset((&u8)(&foo), 0, @sizeOf(StructFoo)); | |
| 47 | foo.a += 1; | |
| 48 | foo.b = foo.a == 1; | |
| 49 | testFoo(foo); | |
| 50 | testMutation(&foo); | |
| 51 | assert(foo.c == 100); | |
| 52 | } | |
| 53 | const StructFoo = struct { | |
| 54 | a : i32, | |
| 55 | b : bool, | |
| 56 | c : f32, | |
| 57 | }; | |
| 58 | fn testFoo(foo : StructFoo) { | |
| 59 | assert(foo.b); | |
| 60 | } | |
| 61 | fn testMutation(foo : &StructFoo) { | |
| 62 | foo.c = 100; | |
| 63 | } | |
| 64 | ||
| 65 | ||
| 66 | const Node = struct { | |
| 67 | val: Val, | |
| 68 | next: &Node, | |
| 69 | }; | |
| 70 | ||
| 71 | const Val = struct { | |
| 72 | x: i32, | |
| 73 | }; | |
| 74 | ||
| 75 | fn structPointToSelf() { | |
| 76 | @setFnTest(this); | |
| 77 | ||
| 78 | var root : Node = undefined; | |
| 79 | root.val.x = 1; | |
| 80 | ||
| 81 | var node : Node = undefined; | |
| 82 | node.next = &root; | |
| 83 | node.val.x = 2; | |
| 84 | ||
| 85 | root.next = &node; | |
| 86 | ||
| 87 | assert(node.next.next.next.val.x == 1); | |
| 88 | } | |
| 89 | ||
| 90 | fn structByvalAssign() { | |
| 91 | @setFnTest(this); | |
| 92 | ||
| 93 | var foo1 : StructFoo = undefined; | |
| 94 | var foo2 : StructFoo = undefined; | |
| 95 | ||
| 96 | foo1.a = 1234; | |
| 97 | foo2.a = 0; | |
| 98 | assert(foo2.a == 0); | |
| 99 | foo2 = foo1; | |
| 100 | assert(foo2.a == 1234); | |
| 101 | } | |
| 102 | ||
| 103 | fn structInitializer() { | |
| 104 | const val = Val { .x = 42 }; | |
| 105 | assert(val.x == 42); | |
| 106 | } | |
| 107 | ||
| 108 | ||
| 109 | fn fnCallOfStructField() { | |
| 110 | @setFnTest(this); | |
| 111 | ||
| 112 | assert(callStructField(Foo {.ptr = aFunc,}) == 13); | |
| 113 | } | |
| 114 | ||
| 115 | const Foo = struct { | |
| 116 | ptr: fn() -> i32, | |
| 117 | }; | |
| 118 | ||
| 119 | fn aFunc() -> i32 { 13 } | |
| 120 | ||
| 121 | fn callStructField(foo: Foo) -> i32 { | |
| 122 | return foo.ptr(); | |
| 123 | } | |
| 124 | ||
| 125 | ||
| 126 | fn storeMemberFunctionInVariable() { | |
| 127 | @setFnTest(this); | |
| 128 | ||
| 129 | const instance = MemberFnTestFoo { .x = 1234, }; | |
| 130 | const memberFn = MemberFnTestFoo.member; | |
| 131 | const result = memberFn(instance); | |
| 132 | assert(result == 1234); | |
| 133 | } | |
| 134 | const MemberFnTestFoo = struct { | |
| 135 | x: i32, | |
| 136 | fn member(foo: MemberFnTestFoo) -> i32 { foo.x } | |
| 137 | }; | |
| 138 | ||
| 139 | ||
| 140 | fn callMemberFunctionDirectly() { | |
| 141 | @setFnTest(this); | |
| 142 | ||
| 143 | const instance = MemberFnTestFoo { .x = 1234, }; | |
| 144 | const result = MemberFnTestFoo.member(instance); | |
| 145 | assert(result == 1234); | |
| 146 | } | |
| 147 | ||
| 148 | fn memberFunctions() { | |
| 149 | @setFnTest(this); | |
| 150 | ||
| 151 | const r = MemberFnRand {.seed = 1234}; | |
| 152 | assert(r.getSeed() == 1234); | |
| 153 | } | |
| 154 | const MemberFnRand = struct { | |
| 155 | seed: u32, | |
| 156 | pub fn getSeed(r: MemberFnRand) -> u32 { | |
| 157 | r.seed | |
| 158 | } | |
| 159 | }; | |
| 160 | ||
| 161 | ||
| 162 | // TODO const assert = @import("std").debug.assert; | |
| 163 | fn assert(ok: bool) { | |
| 164 | if (!ok) | |
| 165 | @unreachable(); | |
| 166 | } |
test/cases/struct_contains_slice_of_itself.zig created+48| ... | ... | @@ -0,0 +1,48 @@ |
| 1 | const Node = struct { | |
| 2 | payload: i32, | |
| 3 | children: []Node, | |
| 4 | }; | |
| 5 | ||
| 6 | fn structContainsSliceOfItself() { | |
| 7 | @setFnTest(this); | |
| 8 | ||
| 9 | var nodes = []Node { | |
| 10 | Node { | |
| 11 | .payload = 1, | |
| 12 | .children = []Node{}, | |
| 13 | }, | |
| 14 | Node { | |
| 15 | .payload = 2, | |
| 16 | .children = []Node{}, | |
| 17 | }, | |
| 18 | Node { | |
| 19 | .payload = 3, | |
| 20 | .children = []Node{ | |
| 21 | Node { | |
| 22 | .payload = 31, | |
| 23 | .children = []Node{}, | |
| 24 | }, | |
| 25 | Node { | |
| 26 | .payload = 32, | |
| 27 | .children = []Node{}, | |
| 28 | }, | |
| 29 | }, | |
| 30 | }, | |
| 31 | }; | |
| 32 | const root = Node { | |
| 33 | .payload = 1234, | |
| 34 | .children = nodes[0...], | |
| 35 | }; | |
| 36 | assert(root.payload == 1234); | |
| 37 | assert(root.children[0].payload == 1); | |
| 38 | assert(root.children[1].payload == 2); | |
| 39 | assert(root.children[2].payload == 3); | |
| 40 | assert(root.children[2].children[0].payload == 31); | |
| 41 | assert(root.children[2].children[1].payload == 32); | |
| 42 | } | |
| 43 | ||
| 44 | // TODO const assert = @import("std").debug.assert; | |
| 45 | fn assert(ok: bool) { | |
| 46 | if (!ok) | |
| 47 | @unreachable(); | |
| 48 | } |
test/cases/switch.zig created+123| ... | ... | @@ -0,0 +1,123 @@ |
| 1 | fn switchWithNumbers() { | |
| 2 | @setFnTest(this); | |
| 3 | ||
| 4 | testSwitchWithNumbers(13); | |
| 5 | } | |
| 6 | ||
| 7 | fn testSwitchWithNumbers(x: u32) { | |
| 8 | const result = switch (x) { | |
| 9 | 1, 2, 3, 4 ... 8 => false, | |
| 10 | 13 => true, | |
| 11 | else => false, | |
| 12 | }; | |
| 13 | assert(result); | |
| 14 | } | |
| 15 | ||
| 16 | fn switchWithAllRanges() { | |
| 17 | @setFnTest(this); | |
| 18 | ||
| 19 | assert(testSwitchWithAllRanges(50, 3) == 1); | |
| 20 | assert(testSwitchWithAllRanges(101, 0) == 2); | |
| 21 | assert(testSwitchWithAllRanges(300, 5) == 3); | |
| 22 | assert(testSwitchWithAllRanges(301, 6) == 6); | |
| 23 | } | |
| 24 | ||
| 25 | fn testSwitchWithAllRanges(x: u32, y: u32) -> u32 { | |
| 26 | switch (x) { | |
| 27 | 0 ... 100 => 1, | |
| 28 | 101 ... 200 => 2, | |
| 29 | 201 ... 300 => 3, | |
| 30 | else => y, | |
| 31 | } | |
| 32 | } | |
| 33 | ||
| 34 | fn inlineSwitch() { | |
| 35 | @setFnTest(this); | |
| 36 | ||
| 37 | const x = 3 + 4; | |
| 38 | const result = inline switch (x) { | |
| 39 | 3 => 10, | |
| 40 | 4 => 11, | |
| 41 | 5, 6 => 12, | |
| 42 | 7, 8 => 13, | |
| 43 | else => 14, | |
| 44 | }; | |
| 45 | assert(result + 1 == 14); | |
| 46 | } | |
| 47 | ||
| 48 | fn switchOnEnum() { | |
| 49 | @setFnTest(this); | |
| 50 | ||
| 51 | const fruit = Fruit.Orange; | |
| 52 | nonConstSwitchOnEnum(fruit); | |
| 53 | } | |
| 54 | const Fruit = enum { | |
| 55 | Apple, | |
| 56 | Orange, | |
| 57 | Banana, | |
| 58 | }; | |
| 59 | fn nonConstSwitchOnEnum(fruit: Fruit) { | |
| 60 | switch (fruit) { | |
| 61 | Fruit.Apple => @unreachable(), | |
| 62 | Fruit.Orange => {}, | |
| 63 | Fruit.Banana => @unreachable(), | |
| 64 | } | |
| 65 | } | |
| 66 | ||
| 67 | ||
| 68 | fn switchStatement() { | |
| 69 | @setFnTest(this); | |
| 70 | ||
| 71 | nonConstSwitch(SwitchStatmentFoo.C); | |
| 72 | } | |
| 73 | fn nonConstSwitch(foo: SwitchStatmentFoo) { | |
| 74 | const val = switch (foo) { | |
| 75 | SwitchStatmentFoo.A => i32(1), | |
| 76 | SwitchStatmentFoo.B => 2, | |
| 77 | SwitchStatmentFoo.C => 3, | |
| 78 | SwitchStatmentFoo.D => 4, | |
| 79 | }; | |
| 80 | if (val != 3) @unreachable(); | |
| 81 | } | |
| 82 | const SwitchStatmentFoo = enum { | |
| 83 | A, | |
| 84 | B, | |
| 85 | C, | |
| 86 | D, | |
| 87 | }; | |
| 88 | ||
| 89 | ||
| 90 | fn switchProngWithVar() { | |
| 91 | @setFnTest(this); | |
| 92 | ||
| 93 | switchProngWithVarFn(SwitchProngWithVarEnum.One {13}); | |
| 94 | switchProngWithVarFn(SwitchProngWithVarEnum.Two {13.0}); | |
| 95 | switchProngWithVarFn(SwitchProngWithVarEnum.Meh); | |
| 96 | } | |
| 97 | const SwitchProngWithVarEnum = enum { | |
| 98 | One: i32, | |
| 99 | Two: f32, | |
| 100 | Meh, | |
| 101 | }; | |
| 102 | fn switchProngWithVarFn(a: SwitchProngWithVarEnum) { | |
| 103 | switch(a) { | |
| 104 | SwitchProngWithVarEnum.One => |x| { | |
| 105 | if (x != 13) @unreachable(); | |
| 106 | }, | |
| 107 | SwitchProngWithVarEnum.Two => |x| { | |
| 108 | if (x != 13.0) @unreachable(); | |
| 109 | }, | |
| 110 | SwitchProngWithVarEnum.Meh => |x| { | |
| 111 | const v: void = x; | |
| 112 | }, | |
| 113 | } | |
| 114 | } | |
| 115 | ||
| 116 | ||
| 117 | ||
| 118 | ||
| 119 | // TODO const assert = @import("std").debug.assert; | |
| 120 | fn assert(ok: bool) { | |
| 121 | if (!ok) | |
| 122 | @unreachable(); | |
| 123 | } |
test/cases/switch_prong_err_enum.zig created+33| ... | ... | @@ -0,0 +1,33 @@ |
| 1 | var read_count: u64 = 0; | |
| 2 | ||
| 3 | fn readOnce() -> %u64 { | |
| 4 | read_count += 1; | |
| 5 | return read_count; | |
| 6 | } | |
| 7 | ||
| 8 | error InvalidDebugInfo; | |
| 9 | ||
| 10 | const FormValue = enum { | |
| 11 | Address: u64, | |
| 12 | Other: bool, | |
| 13 | }; | |
| 14 | ||
| 15 | fn doThing(form_id: u64) -> %FormValue { | |
| 16 | return switch (form_id) { | |
| 17 | 17 => FormValue.Address { %return readOnce() }, | |
| 18 | else => error.InvalidDebugInfo, | |
| 19 | } | |
| 20 | } | |
| 21 | ||
| 22 | fn switchProngReturnsErrorEnum() { | |
| 23 | @setFnTest(this); | |
| 24 | ||
| 25 | %%doThing(17); | |
| 26 | assert(read_count == 1); | |
| 27 | } | |
| 28 | ||
| 29 | // TODO const assert = @import("std").debug.assert; | |
| 30 | fn assert(ok: bool) { | |
| 31 | if (!ok) | |
| 32 | @unreachable(); | |
| 33 | } |
test/cases/switch_prong_implicit_cast.zig created+30| ... | ... | @@ -0,0 +1,30 @@ |
| 1 | const FormValue = enum { | |
| 2 | One, | |
| 3 | Two: bool, | |
| 4 | }; | |
| 5 | ||
| 6 | error Whatever; | |
| 7 | ||
| 8 | fn foo(id: u64) -> %FormValue { | |
| 9 | switch (id) { | |
| 10 | 2 => FormValue.Two { true }, | |
| 11 | 1 => FormValue.One, | |
| 12 | else => return error.Whatever, | |
| 13 | } | |
| 14 | } | |
| 15 | ||
| 16 | fn switchProngImplicitCast() { | |
| 17 | @setFnTest(this); | |
| 18 | ||
| 19 | const result = switch (%%foo(2)) { | |
| 20 | FormValue.One => false, | |
| 21 | FormValue.Two => |x| x, | |
| 22 | }; | |
| 23 | assert(result); | |
| 24 | } | |
| 25 | ||
| 26 | // TODO const assert = @import("std").debug.assert; | |
| 27 | fn assert(ok: bool) { | |
| 28 | if (!ok) | |
| 29 | @unreachable(); | |
| 30 | } |
test/cases/this.zig created+57| ... | ... | @@ -0,0 +1,57 @@ |
| 1 | const module = this; | |
| 2 | ||
| 3 | fn Point(inline T: type) -> type { | |
| 4 | struct { | |
| 5 | const Self = this; | |
| 6 | x: T, | |
| 7 | y: T, | |
| 8 | ||
| 9 | fn addOne(self: &Self) { | |
| 10 | self.x += 1; | |
| 11 | self.y += 1; | |
| 12 | } | |
| 13 | } | |
| 14 | } | |
| 15 | ||
| 16 | fn add(x: i32, y: i32) -> i32 { | |
| 17 | x + y | |
| 18 | } | |
| 19 | ||
| 20 | fn factorial(x: i32) -> i32 { | |
| 21 | const selfFn = this; | |
| 22 | if (x == 0) { | |
| 23 | 1 | |
| 24 | } else { | |
| 25 | x * selfFn(x - 1) | |
| 26 | } | |
| 27 | } | |
| 28 | ||
| 29 | fn thisReferToModuleCallPrivateFn() { | |
| 30 | @setFnTest(this); | |
| 31 | ||
| 32 | assert(module.add(1, 2) == 3); | |
| 33 | } | |
| 34 | ||
| 35 | fn thisReferToContainer() { | |
| 36 | @setFnTest(this); | |
| 37 | ||
| 38 | var pt = Point(i32) { | |
| 39 | .x = 12, | |
| 40 | .y = 34, | |
| 41 | }; | |
| 42 | pt.addOne(); | |
| 43 | assert(pt.x == 13); | |
| 44 | assert(pt.y == 35); | |
| 45 | } | |
| 46 | ||
| 47 | fn thisReferToFn() { | |
| 48 | @setFnTest(this); | |
| 49 | ||
| 50 | assert(factorial(5) == 120); | |
| 51 | } | |
| 52 | ||
| 53 | // TODO const assert = @import("std").debug.assert; | |
| 54 | fn assert(ok: bool) { | |
| 55 | if (!ok) | |
| 56 | @unreachable(); | |
| 57 | } |
test/cases/while.zig created+82| ... | ... | @@ -0,0 +1,82 @@ |
| 1 | fn whileLoop() { | |
| 2 | @setFnTest(this); | |
| 3 | ||
| 4 | var i : i32 = 0; | |
| 5 | while (i < 4) { | |
| 6 | i += 1; | |
| 7 | } | |
| 8 | assert(i == 4); | |
| 9 | assert(whileLoop1() == 1); | |
| 10 | } | |
| 11 | fn whileLoop1() -> i32 { | |
| 12 | return whileLoop2(); | |
| 13 | } | |
| 14 | fn whileLoop2() -> i32 { | |
| 15 | while (true) { | |
| 16 | return 1; | |
| 17 | } | |
| 18 | } | |
| 19 | fn staticEvalWhile() { | |
| 20 | @setFnTest(this); | |
| 21 | ||
| 22 | assert(static_eval_while_number == 1); | |
| 23 | } | |
| 24 | const static_eval_while_number = staticWhileLoop1(); | |
| 25 | fn staticWhileLoop1() -> i32 { | |
| 26 | return whileLoop2(); | |
| 27 | } | |
| 28 | fn staticWhileLoop2() -> i32 { | |
| 29 | while (true) { | |
| 30 | return 1; | |
| 31 | } | |
| 32 | } | |
| 33 | ||
| 34 | fn continueAndBreak() { | |
| 35 | @setFnTest(this); | |
| 36 | ||
| 37 | runContinueAndBreakTest(); | |
| 38 | assert(continue_and_break_counter == 8); | |
| 39 | } | |
| 40 | var continue_and_break_counter: i32 = 0; | |
| 41 | fn runContinueAndBreakTest() { | |
| 42 | var i : i32 = 0; | |
| 43 | while (true) { | |
| 44 | continue_and_break_counter += 2; | |
| 45 | i += 1; | |
| 46 | if (i < 4) { | |
| 47 | continue; | |
| 48 | } | |
| 49 | break; | |
| 50 | } | |
| 51 | assert(i == 4); | |
| 52 | } | |
| 53 | ||
| 54 | fn returnWithImplicitCastFromWhileLoop() { | |
| 55 | @setFnTest(this); | |
| 56 | ||
| 57 | %%returnWithImplicitCastFromWhileLoopTest(); | |
| 58 | } | |
| 59 | fn returnWithImplicitCastFromWhileLoopTest() -> %void { | |
| 60 | while (true) { | |
| 61 | return; | |
| 62 | } | |
| 63 | } | |
| 64 | ||
| 65 | fn whileWithContinueExpr() { | |
| 66 | @setFnTest(this); | |
| 67 | ||
| 68 | var sum: i32 = 0; | |
| 69 | {var i: i32 = 0; while (i < 10; i += 1) { | |
| 70 | if (i == 5) continue; | |
| 71 | sum += i; | |
| 72 | }} | |
| 73 | assert(sum == 40); | |
| 74 | } | |
| 75 | ||
| 76 | ||
| 77 | ||
| 78 | // TODO const assert = @import("std").debug.assert; | |
| 79 | fn assert(ok: bool) { | |
| 80 | if (!ok) | |
| 81 | @unreachable(); | |
| 82 | } |
test/cases3/array.zig deleted-64| ... | ... | @@ -1,64 +0,0 @@ |
| 1 | fn arrays() { | |
| 2 | @setFnTest(this); | |
| 3 | ||
| 4 | var array : [5]u32 = undefined; | |
| 5 | ||
| 6 | var i : u32 = 0; | |
| 7 | while (i < 5) { | |
| 8 | array[i] = i + 1; | |
| 9 | i = array[i]; | |
| 10 | } | |
| 11 | ||
| 12 | i = 0; | |
| 13 | var accumulator = u32(0); | |
| 14 | while (i < 5) { | |
| 15 | accumulator += array[i]; | |
| 16 | ||
| 17 | i += 1; | |
| 18 | } | |
| 19 | ||
| 20 | assert(accumulator == 15); | |
| 21 | assert(getArrayLen(array) == 5); | |
| 22 | } | |
| 23 | fn getArrayLen(a: []u32) -> usize { | |
| 24 | a.len | |
| 25 | } | |
| 26 | ||
| 27 | fn voidArrays() { | |
| 28 | @setFnTest(this); | |
| 29 | ||
| 30 | var array: [4]void = undefined; | |
| 31 | array[0] = void{}; | |
| 32 | array[1] = array[2]; | |
| 33 | assert(@sizeOf(@typeOf(array)) == 0); | |
| 34 | assert(array.len == 4); | |
| 35 | } | |
| 36 | ||
| 37 | fn arrayLiteral() { | |
| 38 | @setFnTest(this); | |
| 39 | ||
| 40 | const hex_mult = []u16{4096, 256, 16, 1}; | |
| 41 | ||
| 42 | assert(hex_mult.len == 4); | |
| 43 | assert(hex_mult[1] == 256); | |
| 44 | } | |
| 45 | ||
| 46 | fn arrayDotLenConstExpr() { | |
| 47 | @setFnTest(this); | |
| 48 | ||
| 49 | assert(@staticEval(some_array.len) == 4); | |
| 50 | } | |
| 51 | ||
| 52 | const ArrayDotLenConstExpr = struct { | |
| 53 | y: [some_array.len]u8, | |
| 54 | }; | |
| 55 | const some_array = []u8 {0, 1, 2, 3}; | |
| 56 | ||
| 57 | ||
| 58 | ||
| 59 | ||
| 60 | // TODO const assert = @import("std").debug.assert; | |
| 61 | fn assert(ok: bool) { | |
| 62 | if (!ok) | |
| 63 | @unreachable(); | |
| 64 | } |
test/cases3/atomics.zig deleted-21| ... | ... | @@ -1,21 +0,0 @@ |
| 1 | fn cmpxchg() { | |
| 2 | @setFnTest(this); | |
| 3 | ||
| 4 | var x: i32 = 1234; | |
| 5 | while (!@cmpxchg(&x, 1234, 5678, AtomicOrder.SeqCst, AtomicOrder.SeqCst)) {} | |
| 6 | assert(x == 5678); | |
| 7 | } | |
| 8 | ||
| 9 | fn fence() { | |
| 10 | @setFnTest(this); | |
| 11 | ||
| 12 | var x: i32 = 1234; | |
| 13 | @fence(AtomicOrder.SeqCst); | |
| 14 | x = 5678; | |
| 15 | } | |
| 16 | ||
| 17 | // TODO const assert = @import("std").debug.assert; | |
| 18 | fn assert(ok: bool) { | |
| 19 | if (!ok) | |
| 20 | @unreachable(); | |
| 21 | } |
test/cases3/bool.zig deleted-36| ... | ... | @@ -1,36 +0,0 @@ |
| 1 | fn boolLiterals() { | |
| 2 | @setFnTest(this); | |
| 3 | ||
| 4 | assert(true); | |
| 5 | assert(!false); | |
| 6 | } | |
| 7 | ||
| 8 | fn castBoolToInt() { | |
| 9 | @setFnTest(this); | |
| 10 | ||
| 11 | const t = true; | |
| 12 | const f = false; | |
| 13 | assert(i32(t) == i32(1)); | |
| 14 | assert(i32(f) == i32(0)); | |
| 15 | nonConstCastBoolToInt(t, f); | |
| 16 | } | |
| 17 | ||
| 18 | fn nonConstCastBoolToInt(t: bool, f: bool) { | |
| 19 | assert(i32(t) == i32(1)); | |
| 20 | assert(i32(f) == i32(0)); | |
| 21 | } | |
| 22 | ||
| 23 | fn boolCmp() { | |
| 24 | @setFnTest(this); | |
| 25 | ||
| 26 | assert(testBoolCmp(true, false) == false); | |
| 27 | } | |
| 28 | fn testBoolCmp(a: bool, b: bool) -> bool { | |
| 29 | a == b | |
| 30 | } | |
| 31 | ||
| 32 | // TODO const assert = @import("std").debug.assert; | |
| 33 | fn assert(ok: bool) { | |
| 34 | if (!ok) | |
| 35 | @unreachable(); | |
| 36 | } |
test/cases3/cast.zig deleted-14| ... | ... | @@ -1,14 +0,0 @@ |
| 1 | //fn intToPtrCast() { | |
| 2 | // @setFnTest(this); | |
| 3 | // | |
| 4 | // const x = isize(13); | |
| 5 | // const y = (&u8)(x); | |
| 6 | // const z = usize(y); | |
| 7 | // assert(z == 13); | |
| 8 | //} | |
| 9 | ||
| 10 | // TODO const assert = @import("std").debug.assert; | |
| 11 | fn assert(ok: bool) { | |
| 12 | if (!ok) | |
| 13 | @unreachable(); | |
| 14 | } |
test/cases3/const_slice_child.zig deleted-49| ... | ... | @@ -1,49 +0,0 @@ |
| 1 | var argv: &&const u8 = undefined; | |
| 2 | ||
| 3 | fn constSliceChild() { | |
| 4 | @setFnTest(this); | |
| 5 | ||
| 6 | const strs = ([]&const u8) { | |
| 7 | c"one", | |
| 8 | c"two", | |
| 9 | c"three", | |
| 10 | }; | |
| 11 | argv = &strs[0]; | |
| 12 | bar(strs.len); | |
| 13 | } | |
| 14 | ||
| 15 | fn foo(args: [][]const u8) { | |
| 16 | assert(args.len == 3); | |
| 17 | assert(streql(args[0], "one")); | |
| 18 | assert(streql(args[1], "two")); | |
| 19 | assert(streql(args[2], "three")); | |
| 20 | } | |
| 21 | ||
| 22 | fn bar(argc: usize) { | |
| 23 | const args = @alloca([]u8, argc); | |
| 24 | for (args) |_, i| { | |
| 25 | const ptr = argv[i]; | |
| 26 | args[i] = ptr[0...strlen(ptr)]; | |
| 27 | } | |
| 28 | foo(args); | |
| 29 | } | |
| 30 | ||
| 31 | fn strlen(ptr: &const u8) -> usize { | |
| 32 | var count: usize = 0; | |
| 33 | while (ptr[count] != 0; count += 1) {} | |
| 34 | return count; | |
| 35 | } | |
| 36 | ||
| 37 | fn streql(a: []const u8, b: []const u8) -> bool { | |
| 38 | if (a.len != b.len) return false; | |
| 39 | for (a) |item, index| { | |
| 40 | if (b[index] != item) return false; | |
| 41 | } | |
| 42 | return true; | |
| 43 | } | |
| 44 | ||
| 45 | // TODO const assert = @import("std").debug.assert; | |
| 46 | fn assert(ok: bool) { | |
| 47 | if (!ok) | |
| 48 | @unreachable(); | |
| 49 | } |
test/cases3/defer.zig deleted-57| ... | ... | @@ -1,57 +0,0 @@ |
| 1 | var result: [3]u8 = undefined; | |
| 2 | var index: usize = undefined; | |
| 3 | ||
| 4 | error FalseNotAllowed; | |
| 5 | ||
| 6 | fn runSomeErrorDefers(x: bool) -> %bool { | |
| 7 | index = 0; | |
| 8 | defer {result[index] = 'a'; index += 1;}; | |
| 9 | %defer {result[index] = 'b'; index += 1;}; | |
| 10 | defer {result[index] = 'c'; index += 1;}; | |
| 11 | return if (x) x else error.FalseNotAllowed; | |
| 12 | } | |
| 13 | ||
| 14 | fn runSomeMaybeDefers(x: bool) -> ?bool { | |
| 15 | index = 0; | |
| 16 | defer {result[index] = 'a'; index += 1;}; | |
| 17 | ?defer {result[index] = 'b'; index += 1;}; | |
| 18 | defer {result[index] = 'c'; index += 1;}; | |
| 19 | return if (x) x else null; | |
| 20 | } | |
| 21 | ||
| 22 | fn mixingNormalAndErrorDefers() { | |
| 23 | @setFnTest(this); | |
| 24 | ||
| 25 | assert(%%runSomeErrorDefers(true)); | |
| 26 | assert(result[0] == 'c'); | |
| 27 | assert(result[1] == 'a'); | |
| 28 | ||
| 29 | const ok = runSomeErrorDefers(false) %% |err| { | |
| 30 | assert(err == error.FalseNotAllowed); | |
| 31 | true | |
| 32 | }; | |
| 33 | assert(ok); | |
| 34 | assert(result[0] == 'c'); | |
| 35 | assert(result[1] == 'b'); | |
| 36 | assert(result[2] == 'a'); | |
| 37 | } | |
| 38 | ||
| 39 | fn mixingNormalAndMaybeDefers() { | |
| 40 | @setFnTest(this); | |
| 41 | ||
| 42 | assert(??runSomeMaybeDefers(true)); | |
| 43 | assert(result[0] == 'c'); | |
| 44 | assert(result[1] == 'a'); | |
| 45 | ||
| 46 | const ok = runSomeMaybeDefers(false) ?? true; | |
| 47 | assert(ok); | |
| 48 | assert(result[0] == 'c'); | |
| 49 | assert(result[1] == 'b'); | |
| 50 | assert(result[2] == 'a'); | |
| 51 | } | |
| 52 | ||
| 53 | // TODO const assert = @import("std").debug.assert; | |
| 54 | fn assert(ok: bool) { | |
| 55 | if (!ok) | |
| 56 | @unreachable(); | |
| 57 | } |
test/cases3/enum.zig deleted-105| ... | ... | @@ -1,105 +0,0 @@ |
| 1 | fn enumType() { | |
| 2 | @setFnTest(this); | |
| 3 | ||
| 4 | const foo1 = Foo.One {13}; | |
| 5 | const foo2 = Foo.Two { Point { .x = 1234, .y = 5678, }}; | |
| 6 | const bar = Bar.B; | |
| 7 | ||
| 8 | assert(bar == Bar.B); | |
| 9 | assert(@memberCount(Foo) == 3); | |
| 10 | assert(@memberCount(Bar) == 4); | |
| 11 | const expected_foo_size = 16 + @sizeOf(usize); | |
| 12 | assert(@sizeOf(Foo) == expected_foo_size); | |
| 13 | assert(@sizeOf(Bar) == 1); | |
| 14 | } | |
| 15 | ||
| 16 | fn enumAsReturnValue () { | |
| 17 | @setFnTest(this); | |
| 18 | ||
| 19 | switch (returnAnInt(13)) { | |
| 20 | Foo.One => |value| assert(value == 13), | |
| 21 | else => @unreachable(), | |
| 22 | } | |
| 23 | } | |
| 24 | ||
| 25 | const Point = struct { | |
| 26 | x: u64, | |
| 27 | y: u64, | |
| 28 | }; | |
| 29 | const Foo = enum { | |
| 30 | One: i32, | |
| 31 | Two: Point, | |
| 32 | Three: void, | |
| 33 | }; | |
| 34 | const Bar = enum { | |
| 35 | A, | |
| 36 | B, | |
| 37 | C, | |
| 38 | D, | |
| 39 | }; | |
| 40 | ||
| 41 | fn returnAnInt(x: i32) -> Foo { | |
| 42 | Foo.One { x } | |
| 43 | } | |
| 44 | ||
| 45 | ||
| 46 | fn constantEnumWithPayload() { | |
| 47 | @setFnTest(this); | |
| 48 | ||
| 49 | var empty = AnEnumWithPayload.Empty; | |
| 50 | var full = AnEnumWithPayload.Full {13}; | |
| 51 | shouldBeEmpty(empty); | |
| 52 | shouldBeNotEmpty(full); | |
| 53 | } | |
| 54 | ||
| 55 | fn shouldBeEmpty(x: AnEnumWithPayload) { | |
| 56 | switch (x) { | |
| 57 | AnEnumWithPayload.Empty => {}, | |
| 58 | else => @unreachable(), | |
| 59 | } | |
| 60 | } | |
| 61 | ||
| 62 | fn shouldBeNotEmpty(x: AnEnumWithPayload) { | |
| 63 | switch (x) { | |
| 64 | AnEnumWithPayload.Empty => @unreachable(), | |
| 65 | else => {}, | |
| 66 | } | |
| 67 | } | |
| 68 | ||
| 69 | const AnEnumWithPayload = enum { | |
| 70 | Empty, | |
| 71 | Full: i32, | |
| 72 | }; | |
| 73 | ||
| 74 | ||
| 75 | ||
| 76 | const Number = enum { | |
| 77 | Zero, | |
| 78 | One, | |
| 79 | Two, | |
| 80 | Three, | |
| 81 | Four, | |
| 82 | }; | |
| 83 | ||
| 84 | fn enumToInt() { | |
| 85 | @setFnTest(this); | |
| 86 | ||
| 87 | shouldEqual(Number.Zero, 0); | |
| 88 | shouldEqual(Number.One, 1); | |
| 89 | shouldEqual(Number.Two, 2); | |
| 90 | shouldEqual(Number.Three, 3); | |
| 91 | shouldEqual(Number.Four, 4); | |
| 92 | } | |
| 93 | ||
| 94 | fn shouldEqual(n: Number, expected: usize) { | |
| 95 | assert(usize(n) == expected); | |
| 96 | } | |
| 97 | ||
| 98 | // TODO import from std | |
| 99 | fn assert(ok: bool) { | |
| 100 | if (!ok) | |
| 101 | @unreachable(); | |
| 102 | } | |
| 103 | ||
| 104 | ||
| 105 |
test/cases3/enum_with_members.zig deleted-83| ... | ... | @@ -1,83 +0,0 @@ |
| 1 | const ET = enum { | |
| 2 | SINT: i32, | |
| 3 | UINT: u32, | |
| 4 | ||
| 5 | pub fn print(a: &ET, buf: []u8) -> %usize { | |
| 6 | return switch (*a) { | |
| 7 | ET.SINT => |x| { bufPrintInt(i32, buf, x) }, | |
| 8 | ET.UINT => |x| { bufPrintInt(u32, buf, x) }, | |
| 9 | } | |
| 10 | } | |
| 11 | }; | |
| 12 | ||
| 13 | fn enumWithMembers() { | |
| 14 | @setFnTest(this); | |
| 15 | ||
| 16 | const a = ET.SINT { -42 }; | |
| 17 | const b = ET.UINT { 42 }; | |
| 18 | var buf: [20]u8 = undefined; | |
| 19 | ||
| 20 | assert(%%a.print(buf) == 3); | |
| 21 | assert(memeql(buf[0...3], "-42")); | |
| 22 | ||
| 23 | assert(%%b.print(buf) == 2); | |
| 24 | assert(memeql(buf[0...2], "42")); | |
| 25 | } | |
| 26 | ||
| 27 | // TODO all the below should be imported from std | |
| 28 | ||
| 29 | const max_u64_base10_digits = 20; | |
| 30 | pub fn bufPrintInt(inline T: type, out_buf: []u8, x: T) -> usize { | |
| 31 | if (T.is_signed) bufPrintSigned(T, out_buf, x) else bufPrintUnsigned(T, out_buf, x) | |
| 32 | } | |
| 33 | ||
| 34 | fn bufPrintSigned(inline T: type, out_buf: []u8, x: T) -> usize { | |
| 35 | const uint = @intType(false, T.bit_count); | |
| 36 | if (x < 0) { | |
| 37 | out_buf[0] = '-'; | |
| 38 | return 1 + bufPrintUnsigned(uint, out_buf[1...], uint(-(x + 1)) + 1); | |
| 39 | } else { | |
| 40 | return bufPrintUnsigned(uint, out_buf, uint(x)); | |
| 41 | } | |
| 42 | } | |
| 43 | ||
| 44 | fn bufPrintUnsigned(inline T: type, out_buf: []u8, x: T) -> usize { | |
| 45 | var buf: [max_u64_base10_digits]u8 = undefined; | |
| 46 | var a = x; | |
| 47 | var index: usize = buf.len; | |
| 48 | ||
| 49 | while (true) { | |
| 50 | const digit = a % 10; | |
| 51 | index -= 1; | |
| 52 | buf[index] = '0' + u8(digit); | |
| 53 | a /= 10; | |
| 54 | if (a == 0) | |
| 55 | break; | |
| 56 | } | |
| 57 | ||
| 58 | const len = buf.len - index; | |
| 59 | ||
| 60 | @memcpy(&out_buf[0], &buf[index], len); | |
| 61 | ||
| 62 | return len; | |
| 63 | } | |
| 64 | ||
| 65 | // TODO const assert = @import("std").debug.assert; | |
| 66 | fn assert(ok: bool) { | |
| 67 | if (!ok) | |
| 68 | @unreachable(); | |
| 69 | } | |
| 70 | ||
| 71 | // TODO import from std.str | |
| 72 | pub fn memeql(a: []const u8, b: []const u8) -> bool { | |
| 73 | sliceEql(u8, a, b) | |
| 74 | } | |
| 75 | ||
| 76 | // TODO import from std.str | |
| 77 | pub fn sliceEql(inline T: type, a: []const T, b: []const T) -> bool { | |
| 78 | if (a.len != b.len) return false; | |
| 79 | for (a) |item, index| { | |
| 80 | if (b[index] != item) return false; | |
| 81 | } | |
| 82 | return true; | |
| 83 | } |
test/cases3/error.zig deleted-122| ... | ... | @@ -1,122 +0,0 @@ |
| 1 | pub fn foo() -> %i32 { | |
| 2 | const x = %return bar(); | |
| 3 | return x + 1 | |
| 4 | } | |
| 5 | ||
| 6 | pub fn bar() -> %i32 { | |
| 7 | return 13; | |
| 8 | } | |
| 9 | ||
| 10 | pub fn baz() -> %i32 { | |
| 11 | const y = foo() %% 1234; | |
| 12 | return y + 1; | |
| 13 | } | |
| 14 | ||
| 15 | fn errorWrapping() { | |
| 16 | @setFnTest(this); | |
| 17 | ||
| 18 | assert(%%baz() == 15); | |
| 19 | } | |
| 20 | ||
| 21 | error ItBroke; | |
| 22 | fn gimmeItBroke() -> []const u8 { | |
| 23 | @errorName(error.ItBroke) | |
| 24 | } | |
| 25 | ||
| 26 | fn errorName() { | |
| 27 | @setFnTest(this); | |
| 28 | assert(memeql(@errorName(error.AnError), "AnError")); | |
| 29 | assert(memeql(@errorName(error.ALongerErrorName), "ALongerErrorName")); | |
| 30 | } | |
| 31 | error AnError; | |
| 32 | error ALongerErrorName; | |
| 33 | ||
| 34 | ||
| 35 | fn errorValues() { | |
| 36 | @setFnTest(this); | |
| 37 | ||
| 38 | const a = i32(error.err1); | |
| 39 | const b = i32(error.err2); | |
| 40 | assert(a != b); | |
| 41 | } | |
| 42 | error err1; | |
| 43 | error err2; | |
| 44 | ||
| 45 | ||
| 46 | fn redefinitionOfErrorValuesAllowed() { | |
| 47 | @setFnTest(this); | |
| 48 | ||
| 49 | shouldBeNotEqual(error.AnError, error.SecondError); | |
| 50 | } | |
| 51 | error AnError; | |
| 52 | error AnError; | |
| 53 | error SecondError; | |
| 54 | fn shouldBeNotEqual(a: error, b: error) { | |
| 55 | if (a == b) @unreachable() | |
| 56 | } | |
| 57 | ||
| 58 | ||
| 59 | fn errBinaryOperator() { | |
| 60 | @setFnTest(this); | |
| 61 | ||
| 62 | const a = errBinaryOperatorG(true) %% 3; | |
| 63 | const b = errBinaryOperatorG(false) %% 3; | |
| 64 | assert(a == 3); | |
| 65 | assert(b == 10); | |
| 66 | } | |
| 67 | error ItBroke; | |
| 68 | fn errBinaryOperatorG(x: bool) -> %isize { | |
| 69 | if (x) { | |
| 70 | error.ItBroke | |
| 71 | } else { | |
| 72 | isize(10) | |
| 73 | } | |
| 74 | } | |
| 75 | ||
| 76 | ||
| 77 | fn unwrapSimpleValueFromError() { | |
| 78 | @setFnTest(this); | |
| 79 | ||
| 80 | const i = %%unwrapSimpleValueFromErrorDo(); | |
| 81 | assert(i == 13); | |
| 82 | } | |
| 83 | fn unwrapSimpleValueFromErrorDo() -> %isize { 13 } | |
| 84 | ||
| 85 | ||
| 86 | fn errReturnInAssignment() { | |
| 87 | @setFnTest(this); | |
| 88 | ||
| 89 | %%doErrReturnInAssignment(); | |
| 90 | } | |
| 91 | ||
| 92 | fn doErrReturnInAssignment() -> %void { | |
| 93 | var x : i32 = undefined; | |
| 94 | x = %return makeANonErr(); | |
| 95 | } | |
| 96 | ||
| 97 | fn makeANonErr() -> %i32 { | |
| 98 | return 1; | |
| 99 | } | |
| 100 | ||
| 101 | ||
| 102 | ||
| 103 | // TODO const assert = @import("std").debug.assert; | |
| 104 | fn assert(ok: bool) { | |
| 105 | if (!ok) | |
| 106 | @unreachable(); | |
| 107 | } | |
| 108 | ||
| 109 | // TODO import from std.str | |
| 110 | pub fn memeql(a: []const u8, b: []const u8) -> bool { | |
| 111 | sliceEql(u8, a, b) | |
| 112 | } | |
| 113 | ||
| 114 | // TODO import from std.str | |
| 115 | pub fn sliceEql(inline T: type, a: []const T, b: []const T) -> bool { | |
| 116 | if (a.len != b.len) return false; | |
| 117 | for (a) |item, index| { | |
| 118 | if (b[index] != item) return false; | |
| 119 | } | |
| 120 | return true; | |
| 121 | } | |
| 122 |
test/cases3/eval.zig deleted-82| ... | ... | @@ -1,82 +0,0 @@ |
| 1 | fn compileTimeRecursion() { | |
| 2 | @setFnTest(this); | |
| 3 | ||
| 4 | assert(some_data.len == 21); | |
| 5 | } | |
| 6 | var some_data: [usize(fibbonaci(7))]u8 = undefined; | |
| 7 | fn fibbonaci(x: i32) -> i32 { | |
| 8 | if (x <= 1) return 1; | |
| 9 | return fibbonaci(x - 1) + fibbonaci(x - 2); | |
| 10 | } | |
| 11 | ||
| 12 | ||
| 13 | ||
| 14 | fn unwrapAndAddOne(blah: ?i32) -> i32 { | |
| 15 | return ??blah + 1; | |
| 16 | } | |
| 17 | const should_be_1235 = unwrapAndAddOne(1234); | |
| 18 | fn testStaticAddOne() { | |
| 19 | @setFnTest(this); | |
| 20 | assert(should_be_1235 == 1235); | |
| 21 | } | |
| 22 | ||
| 23 | fn inlinedLoop() { | |
| 24 | @setFnTest(this); | |
| 25 | ||
| 26 | inline var i = 0; | |
| 27 | inline var sum = 0; | |
| 28 | inline while (i <= 5; i += 1) | |
| 29 | sum += i; | |
| 30 | assert(sum == 15); | |
| 31 | } | |
| 32 | ||
| 33 | fn gimme1or2(inline a: bool) -> i32 { | |
| 34 | const x: i32 = 1; | |
| 35 | const y: i32 = 2; | |
| 36 | inline var z: i32 = if (a) x else y; | |
| 37 | return z; | |
| 38 | } | |
| 39 | fn inlineVariableGetsResultOfConstIf() { | |
| 40 | @setFnTest(this); | |
| 41 | assert(gimme1or2(true) == 1); | |
| 42 | assert(gimme1or2(false) == 2); | |
| 43 | } | |
| 44 | ||
| 45 | ||
| 46 | fn staticFunctionEvaluation() { | |
| 47 | @setFnTest(this); | |
| 48 | ||
| 49 | assert(statically_added_number == 3); | |
| 50 | } | |
| 51 | const statically_added_number = staticAdd(1, 2); | |
| 52 | fn staticAdd(a: i32, b: i32) -> i32 { a + b } | |
| 53 | ||
| 54 | ||
| 55 | fn constExprEvalOnSingleExprBlocks() { | |
| 56 | @setFnTest(this); | |
| 57 | ||
| 58 | assert(constExprEvalOnSingleExprBlocksFn(1, true) == 3); | |
| 59 | } | |
| 60 | ||
| 61 | fn constExprEvalOnSingleExprBlocksFn(x: i32, b: bool) -> i32 { | |
| 62 | const literal = 3; | |
| 63 | ||
| 64 | const result = if (b) { | |
| 65 | literal | |
| 66 | } else { | |
| 67 | x | |
| 68 | }; | |
| 69 | ||
| 70 | return result; | |
| 71 | } | |
| 72 | ||
| 73 | ||
| 74 | ||
| 75 | ||
| 76 | ||
| 77 | // TODO const assert = @import("std").debug.assert; | |
| 78 | fn assert(ok: bool) { | |
| 79 | if (!ok) | |
| 80 | @unreachable(); | |
| 81 | } | |
| 82 |
test/cases3/fn.zig deleted-94| ... | ... | @@ -1,94 +0,0 @@ |
| 1 | fn params() { | |
| 2 | @setFnTest(this); | |
| 3 | ||
| 4 | assert(testParamsAdd(22, 11) == 33); | |
| 5 | } | |
| 6 | fn testParamsAdd(a: i32, b: i32) -> i32 { | |
| 7 | a + b | |
| 8 | } | |
| 9 | ||
| 10 | ||
| 11 | fn localVariables() { | |
| 12 | @setFnTest(this); | |
| 13 | ||
| 14 | testLocVars(2); | |
| 15 | } | |
| 16 | fn testLocVars(b: i32) { | |
| 17 | const a: i32 = 1; | |
| 18 | if (a + b != 3) @unreachable(); | |
| 19 | } | |
| 20 | ||
| 21 | ||
| 22 | fn voidParameters() { | |
| 23 | @setFnTest(this); | |
| 24 | ||
| 25 | voidFun(1, void{}, 2, {}); | |
| 26 | } | |
| 27 | fn voidFun(a: i32, b: void, c: i32, d: void) { | |
| 28 | const v = b; | |
| 29 | const vv: void = if (a == 1) {v} else {}; | |
| 30 | assert(a + c == 3); | |
| 31 | return vv; | |
| 32 | } | |
| 33 | ||
| 34 | ||
| 35 | fn mutableLocalVariables() { | |
| 36 | @setFnTest(this); | |
| 37 | ||
| 38 | var zero : i32 = 0; | |
| 39 | assert(zero == 0); | |
| 40 | ||
| 41 | var i = i32(0); | |
| 42 | while (i != 3) { | |
| 43 | i += 1; | |
| 44 | } | |
| 45 | assert(i == 3); | |
| 46 | } | |
| 47 | ||
| 48 | fn separateBlockScopes() { | |
| 49 | @setFnTest(this); | |
| 50 | ||
| 51 | { | |
| 52 | const no_conflict : i32 = 5; | |
| 53 | assert(no_conflict == 5); | |
| 54 | } | |
| 55 | ||
| 56 | const c = { | |
| 57 | const no_conflict = i32(10); | |
| 58 | no_conflict | |
| 59 | }; | |
| 60 | assert(c == 10); | |
| 61 | } | |
| 62 | ||
| 63 | fn callFnWithEmptyString() { | |
| 64 | @setFnTest(this); | |
| 65 | ||
| 66 | acceptsString(""); | |
| 67 | } | |
| 68 | ||
| 69 | fn acceptsString(foo: []u8) { } | |
| 70 | ||
| 71 | ||
| 72 | fn @"weird function name"() { | |
| 73 | @setFnTest(this); | |
| 74 | } | |
| 75 | ||
| 76 | fn implicitCastFnUnreachableReturn() { | |
| 77 | @setFnTest(this); | |
| 78 | ||
| 79 | wantsFnWithVoid(fnWithUnreachable); | |
| 80 | } | |
| 81 | ||
| 82 | fn wantsFnWithVoid(f: fn()) { } | |
| 83 | ||
| 84 | fn fnWithUnreachable() -> unreachable { | |
| 85 | @unreachable() | |
| 86 | } | |
| 87 | ||
| 88 | ||
| 89 | ||
| 90 | // TODO const assert = @import("std").debug.assert; | |
| 91 | fn assert(ok: bool) { | |
| 92 | if (!ok) | |
| 93 | @unreachable(); | |
| 94 | } |
test/cases3/for.zig deleted-14| ... | ... | @@ -1,14 +0,0 @@ |
| 1 | fn continueInForLoop() { | |
| 2 | @setFnTest(this); | |
| 3 | ||
| 4 | const array = []i32 {1, 2, 3, 4, 5}; | |
| 5 | var sum : i32 = 0; | |
| 6 | for (array) |x| { | |
| 7 | sum += x; | |
| 8 | if (x < 3) { | |
| 9 | continue; | |
| 10 | } | |
| 11 | break; | |
| 12 | } | |
| 13 | if (sum != 6) @unreachable() | |
| 14 | } |
test/cases3/generics.zig deleted-96| ... | ... | @@ -1,96 +0,0 @@ |
| 1 | fn simpleGenericFn() { | |
| 2 | @setFnTest(this); | |
| 3 | ||
| 4 | assert(max(i32, 3, -1) == 3); | |
| 5 | assert(max(f32, 0.123, 0.456) == 0.456); | |
| 6 | assert(add(2, 3) == 5); | |
| 7 | } | |
| 8 | ||
| 9 | fn max(inline T: type, a: T, b: T) -> T { | |
| 10 | return if (a > b) a else b; | |
| 11 | } | |
| 12 | ||
| 13 | fn add(inline a: i32, b: i32) -> i32 { | |
| 14 | return @staticEval(a) + b; | |
| 15 | } | |
| 16 | ||
| 17 | const the_max = max(u32, 1234, 5678); | |
| 18 | fn compileTimeGenericEval() { | |
| 19 | @setFnTest(this); | |
| 20 | assert(the_max == 5678); | |
| 21 | } | |
| 22 | ||
| 23 | fn gimmeTheBigOne(a: u32, b: u32) -> u32 { | |
| 24 | max(u32, a, b) | |
| 25 | } | |
| 26 | ||
| 27 | fn shouldCallSameInstance(a: u32, b: u32) -> u32 { | |
| 28 | max(u32, a, b) | |
| 29 | } | |
| 30 | ||
| 31 | fn sameButWithFloats(a: f64, b: f64) -> f64 { | |
| 32 | max(f64, a, b) | |
| 33 | } | |
| 34 | ||
| 35 | fn fnWithInlineArgs() { | |
| 36 | @setFnTest(this); | |
| 37 | ||
| 38 | assert(gimmeTheBigOne(1234, 5678) == 5678); | |
| 39 | assert(shouldCallSameInstance(34, 12) == 34); | |
| 40 | assert(sameButWithFloats(0.43, 0.49) == 0.49); | |
| 41 | } | |
| 42 | ||
| 43 | ||
| 44 | fn varParams() { | |
| 45 | @setFnTest(this); | |
| 46 | ||
| 47 | assert(max_i32(12, 34) == 34); | |
| 48 | assert(max_f64(1.2, 3.4) == 3.4); | |
| 49 | } | |
| 50 | ||
| 51 | // TODO `_` | |
| 52 | const _1 = assert(max_i32(12, 34) == 34); | |
| 53 | const _2 = assert(max_f64(1.2, 3.4) == 3.4); | |
| 54 | ||
| 55 | fn max_var(a: var, b: var) -> @typeOf(a + b) { | |
| 56 | if (a > b) a else b | |
| 57 | } | |
| 58 | ||
| 59 | fn max_i32(a: i32, b: i32) -> i32 { | |
| 60 | max_var(a, b) | |
| 61 | } | |
| 62 | ||
| 63 | fn max_f64(a: f64, b: f64) -> f64 { | |
| 64 | max_var(a, b) | |
| 65 | } | |
| 66 | ||
| 67 | ||
| 68 | pub fn List(inline T: type) -> type { | |
| 69 | SmallList(T, 8) | |
| 70 | } | |
| 71 | ||
| 72 | pub fn SmallList(inline T: type, inline STATIC_SIZE: usize) -> type { | |
| 73 | struct { | |
| 74 | items: []T, | |
| 75 | length: usize, | |
| 76 | prealloc_items: [STATIC_SIZE]T, | |
| 77 | } | |
| 78 | } | |
| 79 | ||
| 80 | fn functionWithReturnTypeType() { | |
| 81 | @setFnTest(this); | |
| 82 | ||
| 83 | var list: List(i32) = undefined; | |
| 84 | var list2: List(i32) = undefined; | |
| 85 | list.length = 10; | |
| 86 | list2.length = 10; | |
| 87 | assert(list.prealloc_items.len == 8); | |
| 88 | assert(list2.prealloc_items.len == 8); | |
| 89 | } | |
| 90 | ||
| 91 | // TODO const assert = @import("std").debug.assert; | |
| 92 | fn assert(ok: bool) { | |
| 93 | if (!ok) | |
| 94 | @unreachable(); | |
| 95 | } | |
| 96 |
test/cases3/goto.zig deleted-45| ... | ... | @@ -1,45 +0,0 @@ |
| 1 | fn gotoAndLabels() { | |
| 2 | @setFnTest(this); | |
| 3 | ||
| 4 | gotoLoop(); | |
| 5 | assert(goto_counter == 10); | |
| 6 | } | |
| 7 | fn gotoLoop() { | |
| 8 | var i: i32 = 0; | |
| 9 | goto cond; | |
| 10 | loop: | |
| 11 | i += 1; | |
| 12 | cond: | |
| 13 | if (!(i < 10)) goto end; | |
| 14 | goto_counter += 1; | |
| 15 | goto loop; | |
| 16 | end: | |
| 17 | } | |
| 18 | var goto_counter: i32 = 0; | |
| 19 | ||
| 20 | ||
| 21 | ||
| 22 | fn gotoLeaveDeferScope() { | |
| 23 | @setFnTest(this); | |
| 24 | ||
| 25 | testGotoLeaveDeferScope(true); | |
| 26 | } | |
| 27 | fn testGotoLeaveDeferScope(b: bool) { | |
| 28 | var it_worked = false; | |
| 29 | ||
| 30 | goto entry; | |
| 31 | exit: | |
| 32 | if (it_worked) { | |
| 33 | return; | |
| 34 | } | |
| 35 | @unreachable(); | |
| 36 | entry: | |
| 37 | defer it_worked = true; | |
| 38 | if (b) goto exit; | |
| 39 | } | |
| 40 | ||
| 41 | // TODO const assert = @import("std").debug.assert; | |
| 42 | fn assert(ok: bool) { | |
| 43 | if (!ok) | |
| 44 | @unreachable(); | |
| 45 | } |
test/cases3/if.zig deleted-46| ... | ... | @@ -1,46 +0,0 @@ |
| 1 | fn ifStatements() { | |
| 2 | @setFnTest(this); | |
| 3 | ||
| 4 | shouldBeEqual(1, 1); | |
| 5 | firstEqlThird(2, 1, 2); | |
| 6 | } | |
| 7 | fn shouldBeEqual(a: i32, b: i32) { | |
| 8 | if (a != b) { | |
| 9 | @unreachable(); | |
| 10 | } else { | |
| 11 | return; | |
| 12 | } | |
| 13 | } | |
| 14 | fn firstEqlThird(a: i32, b: i32, c: i32) { | |
| 15 | if (a == b) { | |
| 16 | @unreachable(); | |
| 17 | } else if (b == c) { | |
| 18 | @unreachable(); | |
| 19 | } else if (a == c) { | |
| 20 | return; | |
| 21 | } else { | |
| 22 | @unreachable(); | |
| 23 | } | |
| 24 | } | |
| 25 | ||
| 26 | ||
| 27 | fn elseIfExpression() { | |
| 28 | @setFnTest(this); | |
| 29 | ||
| 30 | assert(elseIfExpressionF(1) == 1); | |
| 31 | } | |
| 32 | fn elseIfExpressionF(c: u8) -> u8 { | |
| 33 | if (c == 0) { | |
| 34 | 0 | |
| 35 | } else if (c == 1) { | |
| 36 | 1 | |
| 37 | } else { | |
| 38 | u8(2) | |
| 39 | } | |
| 40 | } | |
| 41 | ||
| 42 | // TODO const assert = @import("std").debug.assert; | |
| 43 | fn assert(ok: bool) { | |
| 44 | if (!ok) | |
| 45 | @unreachable(); | |
| 46 | } |
test/cases3/import.zig deleted-13| ... | ... | @@ -1,13 +0,0 @@ |
| 1 | const a_namespace = @import("cases3/import/a_namespace.zig"); | |
| 2 | ||
| 3 | fn callFnViaNamespaceLookup() { | |
| 4 | @setFnTest(this); | |
| 5 | ||
| 6 | assert(a_namespace.foo() == 1234); | |
| 7 | } | |
| 8 | ||
| 9 | // TODO const assert = @import("std").debug.assert; | |
| 10 | fn assert(ok: bool) { | |
| 11 | if (!ok) | |
| 12 | @unreachable(); | |
| 13 | } |
test/cases3/import/a_namespace.zig deleted-1| ... | ... | @@ -1 +0,0 @@ |
| 1 | pub fn foo() -> i32 { 1234 } |
test/cases3/math.zig deleted-109| ... | ... | @@ -1,109 +0,0 @@ |
| 1 | fn exactDivision() { | |
| 2 | @setFnTest(this); | |
| 3 | ||
| 4 | assert(divExact(55, 11) == 5); | |
| 5 | } | |
| 6 | fn divExact(a: u32, b: u32) -> u32 { | |
| 7 | @divExact(a, b) | |
| 8 | } | |
| 9 | ||
| 10 | fn floatDivision() { | |
| 11 | @setFnTest(this); | |
| 12 | ||
| 13 | assert(fdiv32(12.0, 3.0) == 4.0); | |
| 14 | } | |
| 15 | fn fdiv32(a: f32, b: f32) -> f32 { | |
| 16 | a / b | |
| 17 | } | |
| 18 | ||
| 19 | fn overflowIntrinsics() { | |
| 20 | @setFnTest(this); | |
| 21 | ||
| 22 | var result: u8 = undefined; | |
| 23 | assert(@addWithOverflow(u8, 250, 100, &result)); | |
| 24 | assert(!@addWithOverflow(u8, 100, 150, &result)); | |
| 25 | assert(result == 250); | |
| 26 | } | |
| 27 | ||
| 28 | fn shlWithOverflow() { | |
| 29 | @setFnTest(this); | |
| 30 | ||
| 31 | var result: u16 = undefined; | |
| 32 | assert(@shlWithOverflow(u16, 0b0010111111111111, 3, &result)); | |
| 33 | assert(!@shlWithOverflow(u16, 0b0010111111111111, 2, &result)); | |
| 34 | assert(result == 0b1011111111111100); | |
| 35 | } | |
| 36 | ||
| 37 | fn countLeadingZeroes() { | |
| 38 | @setFnTest(this); | |
| 39 | ||
| 40 | assert(@clz(u8(0b00001010)) == 4); | |
| 41 | assert(@clz(u8(0b10001010)) == 0); | |
| 42 | assert(@clz(u8(0b00000000)) == 8); | |
| 43 | } | |
| 44 | ||
| 45 | fn countTrailingZeroes() { | |
| 46 | @setFnTest(this); | |
| 47 | ||
| 48 | assert(@ctz(u8(0b10100000)) == 5); | |
| 49 | assert(@ctz(u8(0b10001010)) == 1); | |
| 50 | assert(@ctz(u8(0b00000000)) == 8); | |
| 51 | } | |
| 52 | ||
| 53 | fn modifyOperators() { | |
| 54 | @setFnTest(this); | |
| 55 | ||
| 56 | var i : i32 = 0; | |
| 57 | i += 5; assert(i == 5); | |
| 58 | i -= 2; assert(i == 3); | |
| 59 | i *= 20; assert(i == 60); | |
| 60 | i /= 3; assert(i == 20); | |
| 61 | i %= 11; assert(i == 9); | |
| 62 | i <<= 1; assert(i == 18); | |
| 63 | i >>= 2; assert(i == 4); | |
| 64 | i = 6; | |
| 65 | i &= 5; assert(i == 4); | |
| 66 | i ^= 6; assert(i == 2); | |
| 67 | i = 6; | |
| 68 | i |= 3; assert(i == 7); | |
| 69 | } | |
| 70 | ||
| 71 | fn threeExprInARow() { | |
| 72 | @setFnTest(this); | |
| 73 | ||
| 74 | assertFalse(false || false || false); | |
| 75 | assertFalse(true && true && false); | |
| 76 | assertFalse(1 | 2 | 4 != 7); | |
| 77 | assertFalse(3 ^ 6 ^ 8 != 13); | |
| 78 | assertFalse(7 & 14 & 28 != 4); | |
| 79 | assertFalse(9 << 1 << 2 != 9 << 3); | |
| 80 | assertFalse(90 >> 1 >> 2 != 90 >> 3); | |
| 81 | assertFalse(100 - 1 + 1000 != 1099); | |
| 82 | assertFalse(5 * 4 / 2 % 3 != 1); | |
| 83 | assertFalse(i32(i32(5)) != 5); | |
| 84 | assertFalse(!!false); | |
| 85 | assertFalse(i32(7) != --(i32(7))); | |
| 86 | } | |
| 87 | fn assertFalse(b: bool) { | |
| 88 | assert(!b); | |
| 89 | } | |
| 90 | ||
| 91 | ||
| 92 | fn constNumberLiteral() { | |
| 93 | @setFnTest(this); | |
| 94 | ||
| 95 | const one = 1; | |
| 96 | const eleven = ten + one; | |
| 97 | ||
| 98 | assert(eleven == 11); | |
| 99 | } | |
| 100 | const ten = 10; | |
| 101 | ||
| 102 | ||
| 103 | ||
| 104 | // TODO const assert = @import("std").debug.assert; | |
| 105 | fn assert(ok: bool) { | |
| 106 | if (!ok) | |
| 107 | @unreachable(); | |
| 108 | } | |
| 109 |
test/cases3/misc.zig deleted-305| ... | ... | @@ -1,305 +0,0 @@ |
| 1 | // normal comment | |
| 2 | /// this is a documentation comment | |
| 3 | /// doc comment line 2 | |
| 4 | fn emptyFunctionWithComments() { | |
| 5 | @setFnTest(this); | |
| 6 | } | |
| 7 | ||
| 8 | export fn disabledExternFn() { | |
| 9 | @setFnVisible(this, false); | |
| 10 | } | |
| 11 | ||
| 12 | fn callDisabledExternFn() { | |
| 13 | @setFnTest(this); | |
| 14 | ||
| 15 | disabledExternFn(); | |
| 16 | } | |
| 17 | ||
| 18 | fn intTypeBuiltin() { | |
| 19 | @setFnTest(this); | |
| 20 | ||
| 21 | assert(@intType(true, 8) == i8); | |
| 22 | assert(@intType(true, 16) == i16); | |
| 23 | assert(@intType(true, 32) == i32); | |
| 24 | assert(@intType(true, 64) == i64); | |
| 25 | ||
| 26 | assert(@intType(false, 8) == u8); | |
| 27 | assert(@intType(false, 16) == u16); | |
| 28 | assert(@intType(false, 32) == u32); | |
| 29 | assert(@intType(false, 64) == u64); | |
| 30 | ||
| 31 | assert(i8.bit_count == 8); | |
| 32 | assert(i16.bit_count == 16); | |
| 33 | assert(i32.bit_count == 32); | |
| 34 | assert(i64.bit_count == 64); | |
| 35 | ||
| 36 | assert(i8.is_signed); | |
| 37 | assert(i16.is_signed); | |
| 38 | assert(i32.is_signed); | |
| 39 | assert(i64.is_signed); | |
| 40 | assert(isize.is_signed); | |
| 41 | ||
| 42 | assert(!u8.is_signed); | |
| 43 | assert(!u16.is_signed); | |
| 44 | assert(!u32.is_signed); | |
| 45 | assert(!u64.is_signed); | |
| 46 | assert(!usize.is_signed); | |
| 47 | } | |
| 48 | ||
| 49 | fn minValueAndMaxValue() { | |
| 50 | @setFnTest(this); | |
| 51 | ||
| 52 | assert(@maxValue(u8) == 255); | |
| 53 | assert(@maxValue(u16) == 65535); | |
| 54 | assert(@maxValue(u32) == 4294967295); | |
| 55 | assert(@maxValue(u64) == 18446744073709551615); | |
| 56 | ||
| 57 | assert(@maxValue(i8) == 127); | |
| 58 | assert(@maxValue(i16) == 32767); | |
| 59 | assert(@maxValue(i32) == 2147483647); | |
| 60 | assert(@maxValue(i64) == 9223372036854775807); | |
| 61 | ||
| 62 | assert(@minValue(u8) == 0); | |
| 63 | assert(@minValue(u16) == 0); | |
| 64 | assert(@minValue(u32) == 0); | |
| 65 | assert(@minValue(u64) == 0); | |
| 66 | ||
| 67 | assert(@minValue(i8) == -128); | |
| 68 | assert(@minValue(i16) == -32768); | |
| 69 | assert(@minValue(i32) == -2147483648); | |
| 70 | assert(@minValue(i64) == -9223372036854775808); | |
| 71 | } | |
| 72 | ||
| 73 | fn maxValueType() { | |
| 74 | @setFnTest(this); | |
| 75 | ||
| 76 | // If the type of @maxValue(i32) was i32 then this implicit cast to | |
| 77 | // u32 would not work. But since the value is a number literal, | |
| 78 | // it works fine. | |
| 79 | const x: u32 = @maxValue(i32); | |
| 80 | assert(x == 2147483647); | |
| 81 | } | |
| 82 | ||
| 83 | fn shortCircuit() { | |
| 84 | @setFnTest(this); | |
| 85 | ||
| 86 | var hit_1 = false; | |
| 87 | var hit_2 = false; | |
| 88 | var hit_3 = false; | |
| 89 | var hit_4 = false; | |
| 90 | ||
| 91 | if (true || {assert(false); false}) { | |
| 92 | hit_1 = true; | |
| 93 | } | |
| 94 | if (false || { hit_2 = true; false }) { | |
| 95 | assert(false); | |
| 96 | } | |
| 97 | ||
| 98 | if (true && { hit_3 = true; false }) { | |
| 99 | assert(false); | |
| 100 | } | |
| 101 | if (false && {assert(false); false}) { | |
| 102 | assert(false); | |
| 103 | } else { | |
| 104 | hit_4 = true; | |
| 105 | } | |
| 106 | assert(hit_1); | |
| 107 | assert(hit_2); | |
| 108 | assert(hit_3); | |
| 109 | assert(hit_4); | |
| 110 | } | |
| 111 | ||
| 112 | fn truncate() { | |
| 113 | @setFnTest(this); | |
| 114 | ||
| 115 | assert(testTruncate(0x10fd) == 0xfd); | |
| 116 | } | |
| 117 | fn testTruncate(x: u32) -> u8 { | |
| 118 | @truncate(u8, x) | |
| 119 | } | |
| 120 | ||
| 121 | fn assignToIfVarPtr() { | |
| 122 | @setFnTest(this); | |
| 123 | ||
| 124 | var maybe_bool: ?bool = true; | |
| 125 | ||
| 126 | if (const *b ?= maybe_bool) { | |
| 127 | *b = false; | |
| 128 | } | |
| 129 | ||
| 130 | assert(??maybe_bool == false); | |
| 131 | } | |
| 132 | ||
| 133 | fn first4KeysOfHomeRow() -> []const u8 { | |
| 134 | "aoeu" | |
| 135 | } | |
| 136 | ||
| 137 | fn ReturnStringFromFunction() { | |
| 138 | @setFnTest(this); | |
| 139 | ||
| 140 | assert(memeql(first4KeysOfHomeRow(), "aoeu")); | |
| 141 | } | |
| 142 | ||
| 143 | const g1 : i32 = 1233 + 1; | |
| 144 | var g2 : i32 = 0; | |
| 145 | ||
| 146 | fn globalVariables() { | |
| 147 | @setFnTest(this); | |
| 148 | ||
| 149 | assert(g2 == 0); | |
| 150 | g2 = g1; | |
| 151 | assert(g2 == 1234); | |
| 152 | } | |
| 153 | ||
| 154 | ||
| 155 | fn memcpyAndMemsetIntrinsics() { | |
| 156 | @setFnTest(this); | |
| 157 | ||
| 158 | var foo : [20]u8 = undefined; | |
| 159 | var bar : [20]u8 = undefined; | |
| 160 | ||
| 161 | @memset(&foo[0], 'A', foo.len); | |
| 162 | @memcpy(&bar[0], &foo[0], bar.len); | |
| 163 | ||
| 164 | if (bar[11] != 'A') @unreachable(); | |
| 165 | } | |
| 166 | ||
| 167 | fn builtinStaticEval() { | |
| 168 | @setFnTest(this); | |
| 169 | ||
| 170 | const x : i32 = @staticEval(1 + 2 + 3); | |
| 171 | assert(x == @staticEval(6)); | |
| 172 | } | |
| 173 | ||
| 174 | fn slicing() { | |
| 175 | @setFnTest(this); | |
| 176 | ||
| 177 | var array : [20]i32 = undefined; | |
| 178 | ||
| 179 | array[5] = 1234; | |
| 180 | ||
| 181 | var slice = array[5...10]; | |
| 182 | ||
| 183 | if (slice.len != 5) @unreachable(); | |
| 184 | ||
| 185 | const ptr = &slice[0]; | |
| 186 | if (ptr[0] != 1234) @unreachable(); | |
| 187 | ||
| 188 | var slice_rest = array[10...]; | |
| 189 | if (slice_rest.len != 10) @unreachable(); | |
| 190 | } | |
| 191 | ||
| 192 | ||
| 193 | fn constantEqualFunctionPointers() { | |
| 194 | @setFnTest(this); | |
| 195 | ||
| 196 | const alias = emptyFn; | |
| 197 | assert(@staticEval(emptyFn == alias)); | |
| 198 | } | |
| 199 | ||
| 200 | fn emptyFn() {} | |
| 201 | ||
| 202 | ||
| 203 | fn hexEscape() { | |
| 204 | @setFnTest(this); | |
| 205 | ||
| 206 | assert(memeql("\x68\x65\x6c\x6c\x6f", "hello")); | |
| 207 | } | |
| 208 | ||
| 209 | fn stringConcatenation() { | |
| 210 | @setFnTest(this); | |
| 211 | ||
| 212 | assert(memeql("OK" ++ " IT " ++ "WORKED", "OK IT WORKED")); | |
| 213 | } | |
| 214 | ||
| 215 | fn arrayMultOperator() { | |
| 216 | @setFnTest(this); | |
| 217 | ||
| 218 | assert(memeql("ab" ** 5, "ababababab")); | |
| 219 | } | |
| 220 | ||
| 221 | fn stringEscapes() { | |
| 222 | @setFnTest(this); | |
| 223 | ||
| 224 | assert(memeql("\"", "\x22")); | |
| 225 | assert(memeql("\'", "\x27")); | |
| 226 | assert(memeql("\n", "\x0a")); | |
| 227 | assert(memeql("\r", "\x0d")); | |
| 228 | assert(memeql("\t", "\x09")); | |
| 229 | assert(memeql("\\", "\x5c")); | |
| 230 | assert(memeql("\u1234\u0069", "\xe1\x88\xb4\x69")); | |
| 231 | } | |
| 232 | ||
| 233 | fn multilineString() { | |
| 234 | @setFnTest(this); | |
| 235 | ||
| 236 | const s1 = | |
| 237 | \\one | |
| 238 | \\two) | |
| 239 | \\three | |
| 240 | ; | |
| 241 | const s2 = "one\ntwo)\nthree"; | |
| 242 | assert(memeql(s1, s2)); | |
| 243 | } | |
| 244 | ||
| 245 | fn multilineCString() { | |
| 246 | @setFnTest(this); | |
| 247 | ||
| 248 | const s1 = | |
| 249 | c\\one | |
| 250 | c\\two) | |
| 251 | c\\three | |
| 252 | ; | |
| 253 | const s2 = c"one\ntwo)\nthree"; | |
| 254 | assert(cstrcmp(s1, s2) == 0); | |
| 255 | } | |
| 256 | ||
| 257 | ||
| 258 | fn typeEquality() { | |
| 259 | @setFnTest(this); | |
| 260 | ||
| 261 | assert(&const u8 != &u8); | |
| 262 | } | |
| 263 | ||
| 264 | ||
| 265 | const global_a: i32 = 1234; | |
| 266 | const global_b: &const i32 = &global_a; | |
| 267 | const global_c: &const f32 = (&const f32)(global_b); | |
| 268 | fn compileTimeGlobalReinterpret() { | |
| 269 | @setFnTest(this); | |
| 270 | const d = (&const i32)(global_c); | |
| 271 | assert(*d == 1234); | |
| 272 | } | |
| 273 | ||
| 274 | // TODO import from std.str | |
| 275 | pub fn memeql(a: []const u8, b: []const u8) -> bool { | |
| 276 | sliceEql(u8, a, b) | |
| 277 | } | |
| 278 | ||
| 279 | // TODO import from std.str | |
| 280 | pub fn sliceEql(inline T: type, a: []const T, b: []const T) -> bool { | |
| 281 | if (a.len != b.len) return false; | |
| 282 | for (a) |item, index| { | |
| 283 | if (b[index] != item) return false; | |
| 284 | } | |
| 285 | return true; | |
| 286 | } | |
| 287 | ||
| 288 | // TODO import from std.cstr | |
| 289 | pub fn cstrcmp(a: &const u8, b: &const u8) -> i8 { | |
| 290 | var index: usize = 0; | |
| 291 | while (a[index] == b[index] && a[index] != 0; index += 1) {} | |
| 292 | return if (a[index] > b[index]) { | |
| 293 | 1 | |
| 294 | } else if (a[index] < b[index]) { | |
| 295 | -1 | |
| 296 | } else { | |
| 297 | i8(0) | |
| 298 | }; | |
| 299 | } | |
| 300 | ||
| 301 | // TODO const assert = @import("std").debug.assert; | |
| 302 | fn assert(ok: bool) { | |
| 303 | if (!ok) | |
| 304 | @unreachable(); | |
| 305 | } |
test/cases3/namespace_depends_on_compile_var/a.zig deleted-1| ... | ... | @@ -1 +0,0 @@ |
| 1 | pub const a_bool = true; |
test/cases3/namespace_depends_on_compile_var/b.zig deleted-1| ... | ... | @@ -1 +0,0 @@ |
| 1 | pub const a_bool = false; |
test/cases3/namespace_depends_on_compile_var/index.zig deleted-19| ... | ... | @@ -1,19 +0,0 @@ |
| 1 | fn namespaceDependsOnCompileVar() { | |
| 2 | @setFnTest(this); | |
| 3 | ||
| 4 | if (some_namespace.a_bool) { | |
| 5 | assert(some_namespace.a_bool); | |
| 6 | } else { | |
| 7 | assert(!some_namespace.a_bool); | |
| 8 | } | |
| 9 | } | |
| 10 | const some_namespace = switch(@compileVar("os")) { | |
| 11 | Os.linux => @import("cases3/namespace_depends_on_compile_var/a.zig"), | |
| 12 | else => @import("cases3/namespace_depends_on_compile_var/b.zig"), | |
| 13 | }; | |
| 14 | ||
| 15 | // TODO const assert = @import("std").debug.assert; | |
| 16 | fn assert(ok: bool) { | |
| 17 | if (!ok) | |
| 18 | @unreachable(); | |
| 19 | } |
test/cases3/null.zig deleted-68| ... | ... | @@ -1,68 +0,0 @@ |
| 1 | fn nullableType() { | |
| 2 | @setFnTest(this); | |
| 3 | ||
| 4 | const x : ?bool = true; | |
| 5 | ||
| 6 | if (const y ?= x) { | |
| 7 | if (y) { | |
| 8 | // OK | |
| 9 | } else { | |
| 10 | @unreachable(); | |
| 11 | } | |
| 12 | } else { | |
| 13 | @unreachable(); | |
| 14 | } | |
| 15 | ||
| 16 | const next_x : ?i32 = null; | |
| 17 | ||
| 18 | const z = next_x ?? 1234; | |
| 19 | ||
| 20 | assert(z == 1234); | |
| 21 | ||
| 22 | const final_x : ?i32 = 13; | |
| 23 | ||
| 24 | const num = final_x ?? @unreachable(); | |
| 25 | ||
| 26 | assert(num == 13); | |
| 27 | } | |
| 28 | ||
| 29 | fn assignToIfVarPtr() { | |
| 30 | @setFnTest(this); | |
| 31 | ||
| 32 | var maybe_bool: ?bool = true; | |
| 33 | ||
| 34 | if (const *b ?= maybe_bool) { | |
| 35 | *b = false; | |
| 36 | } | |
| 37 | ||
| 38 | assert(??maybe_bool == false); | |
| 39 | } | |
| 40 | ||
| 41 | fn rhsMaybeUnwrapReturn() { | |
| 42 | @setFnTest(this); | |
| 43 | ||
| 44 | const x: ?bool = true; | |
| 45 | const y = x ?? return; | |
| 46 | } | |
| 47 | ||
| 48 | ||
| 49 | fn maybeReturn() { | |
| 50 | @setFnTest(this); | |
| 51 | ||
| 52 | assert(??foo(1235)); | |
| 53 | assert(if (const _ ?= foo(null)) false else true); | |
| 54 | assert(!??foo(1234)); | |
| 55 | } | |
| 56 | ||
| 57 | // TODO test static eval maybe return | |
| 58 | fn foo(x: ?i32) -> ?bool { | |
| 59 | const value = ?return x; | |
| 60 | return value > 1234; | |
| 61 | } | |
| 62 | ||
| 63 | // TODO const assert = @import("std").debug.assert; | |
| 64 | fn assert(ok: bool) { | |
| 65 | if (!ok) | |
| 66 | @unreachable(); | |
| 67 | } | |
| 68 |
test/cases3/pub_enum/index.zig deleted-23| ... | ... | @@ -1,23 +0,0 @@ |
| 1 | const other = @import("cases3/pub_enum/other.zig"); | |
| 2 | ||
| 3 | fn pubEnum() { | |
| 4 | @setFnTest(this); | |
| 5 | ||
| 6 | pubEnumTest(other.APubEnum.Two); | |
| 7 | } | |
| 8 | fn pubEnumTest(foo: other.APubEnum) { | |
| 9 | assert(foo == other.APubEnum.Two); | |
| 10 | } | |
| 11 | ||
| 12 | fn castWithImportedSymbol() { | |
| 13 | @setFnTest(this); | |
| 14 | ||
| 15 | assert(other.size_t(42) == 42); | |
| 16 | } | |
| 17 | ||
| 18 | ||
| 19 | // TODO const assert = @import("std").debug.assert; | |
| 20 | fn assert(ok: bool) { | |
| 21 | if (!ok) | |
| 22 | @unreachable(); | |
| 23 | } |
test/cases3/pub_enum/other.zig deleted-6| ... | ... | @@ -1,6 +0,0 @@ |
| 1 | pub const APubEnum = enum { | |
| 2 | One, | |
| 3 | Two, | |
| 4 | Three, | |
| 5 | }; | |
| 6 | pub const size_t = u64; |
test/cases3/sizeof_and_typeof.zig deleted-14| ... | ... | @@ -1,14 +0,0 @@ |
| 1 | fn sizeofAndTypeOf() { | |
| 2 | @setFnTest(this); | |
| 3 | ||
| 4 | const y: @typeOf(x) = 120; | |
| 5 | assert(@sizeOf(@typeOf(y)) == 2); | |
| 6 | } | |
| 7 | const x: u16 = 13; | |
| 8 | const z: @typeOf(x) = 19; | |
| 9 | ||
| 10 | // TODO const assert = @import("std").debug.assert; | |
| 11 | fn assert(ok: bool) { | |
| 12 | if (!ok) | |
| 13 | @unreachable(); | |
| 14 | } |
test/cases3/struct.zig deleted-166| ... | ... | @@ -1,166 +0,0 @@ |
| 1 | const StructWithNoFields = struct { | |
| 2 | fn add(a: i32, b: i32) -> i32 { a + b } | |
| 3 | }; | |
| 4 | const empty_global_instance = StructWithNoFields {}; | |
| 5 | ||
| 6 | fn callStructStaticMethod() { | |
| 7 | @setFnTest(this); | |
| 8 | const result = StructWithNoFields.add(3, 4); | |
| 9 | assert(result == 7); | |
| 10 | } | |
| 11 | ||
| 12 | fn returnEmptyStructInstance() -> StructWithNoFields { | |
| 13 | @setFnTest(this); | |
| 14 | return empty_global_instance; | |
| 15 | } | |
| 16 | ||
| 17 | const should_be_11 = StructWithNoFields.add(5, 6); | |
| 18 | ||
| 19 | fn invokeStaticMethodInGlobalScope() { | |
| 20 | @setFnTest(this); | |
| 21 | assert(should_be_11 == 11); | |
| 22 | } | |
| 23 | ||
| 24 | fn voidStructFields() { | |
| 25 | @setFnTest(this); | |
| 26 | ||
| 27 | const foo = VoidStructFieldsFoo { | |
| 28 | .a = void{}, | |
| 29 | .b = 1, | |
| 30 | .c = void{}, | |
| 31 | }; | |
| 32 | assert(foo.b == 1); | |
| 33 | assert(@sizeOf(VoidStructFieldsFoo) == 4); | |
| 34 | } | |
| 35 | const VoidStructFieldsFoo = struct { | |
| 36 | a : void, | |
| 37 | b : i32, | |
| 38 | c : void, | |
| 39 | }; | |
| 40 | ||
| 41 | ||
| 42 | pub fn structs() { | |
| 43 | @setFnTest(this); | |
| 44 | ||
| 45 | var foo: StructFoo = undefined; | |
| 46 | @memset((&u8)(&foo), 0, @sizeOf(StructFoo)); | |
| 47 | foo.a += 1; | |
| 48 | foo.b = foo.a == 1; | |
| 49 | testFoo(foo); | |
| 50 | testMutation(&foo); | |
| 51 | assert(foo.c == 100); | |
| 52 | } | |
| 53 | const StructFoo = struct { | |
| 54 | a : i32, | |
| 55 | b : bool, | |
| 56 | c : f32, | |
| 57 | }; | |
| 58 | fn testFoo(foo : StructFoo) { | |
| 59 | assert(foo.b); | |
| 60 | } | |
| 61 | fn testMutation(foo : &StructFoo) { | |
| 62 | foo.c = 100; | |
| 63 | } | |
| 64 | ||
| 65 | ||
| 66 | const Node = struct { | |
| 67 | val: Val, | |
| 68 | next: &Node, | |
| 69 | }; | |
| 70 | ||
| 71 | const Val = struct { | |
| 72 | x: i32, | |
| 73 | }; | |
| 74 | ||
| 75 | fn structPointToSelf() { | |
| 76 | @setFnTest(this); | |
| 77 | ||
| 78 | var root : Node = undefined; | |
| 79 | root.val.x = 1; | |
| 80 | ||
| 81 | var node : Node = undefined; | |
| 82 | node.next = &root; | |
| 83 | node.val.x = 2; | |
| 84 | ||
| 85 | root.next = &node; | |
| 86 | ||
| 87 | assert(node.next.next.next.val.x == 1); | |
| 88 | } | |
| 89 | ||
| 90 | fn structByvalAssign() { | |
| 91 | @setFnTest(this); | |
| 92 | ||
| 93 | var foo1 : StructFoo = undefined; | |
| 94 | var foo2 : StructFoo = undefined; | |
| 95 | ||
| 96 | foo1.a = 1234; | |
| 97 | foo2.a = 0; | |
| 98 | assert(foo2.a == 0); | |
| 99 | foo2 = foo1; | |
| 100 | assert(foo2.a == 1234); | |
| 101 | } | |
| 102 | ||
| 103 | fn structInitializer() { | |
| 104 | const val = Val { .x = 42 }; | |
| 105 | assert(val.x == 42); | |
| 106 | } | |
| 107 | ||
| 108 | ||
| 109 | fn fnCallOfStructField() { | |
| 110 | @setFnTest(this); | |
| 111 | ||
| 112 | assert(callStructField(Foo {.ptr = aFunc,}) == 13); | |
| 113 | } | |
| 114 | ||
| 115 | const Foo = struct { | |
| 116 | ptr: fn() -> i32, | |
| 117 | }; | |
| 118 | ||
| 119 | fn aFunc() -> i32 { 13 } | |
| 120 | ||
| 121 | fn callStructField(foo: Foo) -> i32 { | |
| 122 | return foo.ptr(); | |
| 123 | } | |
| 124 | ||
| 125 | ||
| 126 | fn storeMemberFunctionInVariable() { | |
| 127 | @setFnTest(this); | |
| 128 | ||
| 129 | const instance = MemberFnTestFoo { .x = 1234, }; | |
| 130 | const memberFn = MemberFnTestFoo.member; | |
| 131 | const result = memberFn(instance); | |
| 132 | assert(result == 1234); | |
| 133 | } | |
| 134 | const MemberFnTestFoo = struct { | |
| 135 | x: i32, | |
| 136 | fn member(foo: MemberFnTestFoo) -> i32 { foo.x } | |
| 137 | }; | |
| 138 | ||
| 139 | ||
| 140 | fn callMemberFunctionDirectly() { | |
| 141 | @setFnTest(this); | |
| 142 | ||
| 143 | const instance = MemberFnTestFoo { .x = 1234, }; | |
| 144 | const result = MemberFnTestFoo.member(instance); | |
| 145 | assert(result == 1234); | |
| 146 | } | |
| 147 | ||
| 148 | fn memberFunctions() { | |
| 149 | @setFnTest(this); | |
| 150 | ||
| 151 | const r = MemberFnRand {.seed = 1234}; | |
| 152 | assert(r.getSeed() == 1234); | |
| 153 | } | |
| 154 | const MemberFnRand = struct { | |
| 155 | seed: u32, | |
| 156 | pub fn getSeed(r: MemberFnRand) -> u32 { | |
| 157 | r.seed | |
| 158 | } | |
| 159 | }; | |
| 160 | ||
| 161 | ||
| 162 | // TODO const assert = @import("std").debug.assert; | |
| 163 | fn assert(ok: bool) { | |
| 164 | if (!ok) | |
| 165 | @unreachable(); | |
| 166 | } |
test/cases3/struct_contains_slice_of_itself.zig deleted-48| ... | ... | @@ -1,48 +0,0 @@ |
| 1 | const Node = struct { | |
| 2 | payload: i32, | |
| 3 | children: []Node, | |
| 4 | }; | |
| 5 | ||
| 6 | fn structContainsSliceOfItself() { | |
| 7 | @setFnTest(this); | |
| 8 | ||
| 9 | var nodes = []Node { | |
| 10 | Node { | |
| 11 | .payload = 1, | |
| 12 | .children = []Node{}, | |
| 13 | }, | |
| 14 | Node { | |
| 15 | .payload = 2, | |
| 16 | .children = []Node{}, | |
| 17 | }, | |
| 18 | Node { | |
| 19 | .payload = 3, | |
| 20 | .children = []Node{ | |
| 21 | Node { | |
| 22 | .payload = 31, | |
| 23 | .children = []Node{}, | |
| 24 | }, | |
| 25 | Node { | |
| 26 | .payload = 32, | |
| 27 | .children = []Node{}, | |
| 28 | }, | |
| 29 | }, | |
| 30 | }, | |
| 31 | }; | |
| 32 | const root = Node { | |
| 33 | .payload = 1234, | |
| 34 | .children = nodes[0...], | |
| 35 | }; | |
| 36 | assert(root.payload == 1234); | |
| 37 | assert(root.children[0].payload == 1); | |
| 38 | assert(root.children[1].payload == 2); | |
| 39 | assert(root.children[2].payload == 3); | |
| 40 | assert(root.children[2].children[0].payload == 31); | |
| 41 | assert(root.children[2].children[1].payload == 32); | |
| 42 | } | |
| 43 | ||
| 44 | // TODO const assert = @import("std").debug.assert; | |
| 45 | fn assert(ok: bool) { | |
| 46 | if (!ok) | |
| 47 | @unreachable(); | |
| 48 | } |
test/cases3/switch.zig deleted-123| ... | ... | @@ -1,123 +0,0 @@ |
| 1 | fn switchWithNumbers() { | |
| 2 | @setFnTest(this); | |
| 3 | ||
| 4 | testSwitchWithNumbers(13); | |
| 5 | } | |
| 6 | ||
| 7 | fn testSwitchWithNumbers(x: u32) { | |
| 8 | const result = switch (x) { | |
| 9 | 1, 2, 3, 4 ... 8 => false, | |
| 10 | 13 => true, | |
| 11 | else => false, | |
| 12 | }; | |
| 13 | assert(result); | |
| 14 | } | |
| 15 | ||
| 16 | fn switchWithAllRanges() { | |
| 17 | @setFnTest(this); | |
| 18 | ||
| 19 | assert(testSwitchWithAllRanges(50, 3) == 1); | |
| 20 | assert(testSwitchWithAllRanges(101, 0) == 2); | |
| 21 | assert(testSwitchWithAllRanges(300, 5) == 3); | |
| 22 | assert(testSwitchWithAllRanges(301, 6) == 6); | |
| 23 | } | |
| 24 | ||
| 25 | fn testSwitchWithAllRanges(x: u32, y: u32) -> u32 { | |
| 26 | switch (x) { | |
| 27 | 0 ... 100 => 1, | |
| 28 | 101 ... 200 => 2, | |
| 29 | 201 ... 300 => 3, | |
| 30 | else => y, | |
| 31 | } | |
| 32 | } | |
| 33 | ||
| 34 | fn inlineSwitch() { | |
| 35 | @setFnTest(this); | |
| 36 | ||
| 37 | const x = 3 + 4; | |
| 38 | const result = inline switch (x) { | |
| 39 | 3 => 10, | |
| 40 | 4 => 11, | |
| 41 | 5, 6 => 12, | |
| 42 | 7, 8 => 13, | |
| 43 | else => 14, | |
| 44 | }; | |
| 45 | assert(result + 1 == 14); | |
| 46 | } | |
| 47 | ||
| 48 | fn switchOnEnum() { | |
| 49 | @setFnTest(this); | |
| 50 | ||
| 51 | const fruit = Fruit.Orange; | |
| 52 | nonConstSwitchOnEnum(fruit); | |
| 53 | } | |
| 54 | const Fruit = enum { | |
| 55 | Apple, | |
| 56 | Orange, | |
| 57 | Banana, | |
| 58 | }; | |
| 59 | fn nonConstSwitchOnEnum(fruit: Fruit) { | |
| 60 | switch (fruit) { | |
| 61 | Fruit.Apple => @unreachable(), | |
| 62 | Fruit.Orange => {}, | |
| 63 | Fruit.Banana => @unreachable(), | |
| 64 | } | |
| 65 | } | |
| 66 | ||
| 67 | ||
| 68 | fn switchStatement() { | |
| 69 | @setFnTest(this); | |
| 70 | ||
| 71 | nonConstSwitch(SwitchStatmentFoo.C); | |
| 72 | } | |
| 73 | fn nonConstSwitch(foo: SwitchStatmentFoo) { | |
| 74 | const val = switch (foo) { | |
| 75 | SwitchStatmentFoo.A => i32(1), | |
| 76 | SwitchStatmentFoo.B => 2, | |
| 77 | SwitchStatmentFoo.C => 3, | |
| 78 | SwitchStatmentFoo.D => 4, | |
| 79 | }; | |
| 80 | if (val != 3) @unreachable(); | |
| 81 | } | |
| 82 | const SwitchStatmentFoo = enum { | |
| 83 | A, | |
| 84 | B, | |
| 85 | C, | |
| 86 | D, | |
| 87 | }; | |
| 88 | ||
| 89 | ||
| 90 | fn switchProngWithVar() { | |
| 91 | @setFnTest(this); | |
| 92 | ||
| 93 | switchProngWithVarFn(SwitchProngWithVarEnum.One {13}); | |
| 94 | switchProngWithVarFn(SwitchProngWithVarEnum.Two {13.0}); | |
| 95 | switchProngWithVarFn(SwitchProngWithVarEnum.Meh); | |
| 96 | } | |
| 97 | const SwitchProngWithVarEnum = enum { | |
| 98 | One: i32, | |
| 99 | Two: f32, | |
| 100 | Meh, | |
| 101 | }; | |
| 102 | fn switchProngWithVarFn(a: SwitchProngWithVarEnum) { | |
| 103 | switch(a) { | |
| 104 | SwitchProngWithVarEnum.One => |x| { | |
| 105 | if (x != 13) @unreachable(); | |
| 106 | }, | |
| 107 | SwitchProngWithVarEnum.Two => |x| { | |
| 108 | if (x != 13.0) @unreachable(); | |
| 109 | }, | |
| 110 | SwitchProngWithVarEnum.Meh => |x| { | |
| 111 | const v: void = x; | |
| 112 | }, | |
| 113 | } | |
| 114 | } | |
| 115 | ||
| 116 | ||
| 117 | ||
| 118 | ||
| 119 | // TODO const assert = @import("std").debug.assert; | |
| 120 | fn assert(ok: bool) { | |
| 121 | if (!ok) | |
| 122 | @unreachable(); | |
| 123 | } |
test/cases3/switch_prong_err_enum.zig deleted-33| ... | ... | @@ -1,33 +0,0 @@ |
| 1 | var read_count: u64 = 0; | |
| 2 | ||
| 3 | fn readOnce() -> %u64 { | |
| 4 | read_count += 1; | |
| 5 | return read_count; | |
| 6 | } | |
| 7 | ||
| 8 | error InvalidDebugInfo; | |
| 9 | ||
| 10 | const FormValue = enum { | |
| 11 | Address: u64, | |
| 12 | Other: bool, | |
| 13 | }; | |
| 14 | ||
| 15 | fn doThing(form_id: u64) -> %FormValue { | |
| 16 | return switch (form_id) { | |
| 17 | 17 => FormValue.Address { %return readOnce() }, | |
| 18 | else => error.InvalidDebugInfo, | |
| 19 | } | |
| 20 | } | |
| 21 | ||
| 22 | fn switchProngReturnsErrorEnum() { | |
| 23 | @setFnTest(this); | |
| 24 | ||
| 25 | %%doThing(17); | |
| 26 | assert(read_count == 1); | |
| 27 | } | |
| 28 | ||
| 29 | // TODO const assert = @import("std").debug.assert; | |
| 30 | fn assert(ok: bool) { | |
| 31 | if (!ok) | |
| 32 | @unreachable(); | |
| 33 | } |
test/cases3/switch_prong_implicit_cast.zig deleted-30| ... | ... | @@ -1,30 +0,0 @@ |
| 1 | const FormValue = enum { | |
| 2 | One, | |
| 3 | Two: bool, | |
| 4 | }; | |
| 5 | ||
| 6 | error Whatever; | |
| 7 | ||
| 8 | fn foo(id: u64) -> %FormValue { | |
| 9 | switch (id) { | |
| 10 | 2 => FormValue.Two { true }, | |
| 11 | 1 => FormValue.One, | |
| 12 | else => return error.Whatever, | |
| 13 | } | |
| 14 | } | |
| 15 | ||
| 16 | fn switchProngImplicitCast() { | |
| 17 | @setFnTest(this); | |
| 18 | ||
| 19 | const result = switch (%%foo(2)) { | |
| 20 | FormValue.One => false, | |
| 21 | FormValue.Two => |x| x, | |
| 22 | }; | |
| 23 | assert(result); | |
| 24 | } | |
| 25 | ||
| 26 | // TODO const assert = @import("std").debug.assert; | |
| 27 | fn assert(ok: bool) { | |
| 28 | if (!ok) | |
| 29 | @unreachable(); | |
| 30 | } |
test/cases3/this.zig deleted-57| ... | ... | @@ -1,57 +0,0 @@ |
| 1 | const module = this; | |
| 2 | ||
| 3 | fn Point(inline T: type) -> type { | |
| 4 | struct { | |
| 5 | const Self = this; | |
| 6 | x: T, | |
| 7 | y: T, | |
| 8 | ||
| 9 | fn addOne(self: &Self) { | |
| 10 | self.x += 1; | |
| 11 | self.y += 1; | |
| 12 | } | |
| 13 | } | |
| 14 | } | |
| 15 | ||
| 16 | fn add(x: i32, y: i32) -> i32 { | |
| 17 | x + y | |
| 18 | } | |
| 19 | ||
| 20 | fn factorial(x: i32) -> i32 { | |
| 21 | const selfFn = this; | |
| 22 | if (x == 0) { | |
| 23 | 1 | |
| 24 | } else { | |
| 25 | x * selfFn(x - 1) | |
| 26 | } | |
| 27 | } | |
| 28 | ||
| 29 | fn thisReferToModuleCallPrivateFn() { | |
| 30 | @setFnTest(this); | |
| 31 | ||
| 32 | assert(module.add(1, 2) == 3); | |
| 33 | } | |
| 34 | ||
| 35 | fn thisReferToContainer() { | |
| 36 | @setFnTest(this); | |
| 37 | ||
| 38 | var pt = Point(i32) { | |
| 39 | .x = 12, | |
| 40 | .y = 34, | |
| 41 | }; | |
| 42 | pt.addOne(); | |
| 43 | assert(pt.x == 13); | |
| 44 | assert(pt.y == 35); | |
| 45 | } | |
| 46 | ||
| 47 | fn thisReferToFn() { | |
| 48 | @setFnTest(this); | |
| 49 | ||
| 50 | assert(factorial(5) == 120); | |
| 51 | } | |
| 52 | ||
| 53 | // TODO const assert = @import("std").debug.assert; | |
| 54 | fn assert(ok: bool) { | |
| 55 | if (!ok) | |
| 56 | @unreachable(); | |
| 57 | } |
test/cases3/while.zig deleted-82| ... | ... | @@ -1,82 +0,0 @@ |
| 1 | fn whileLoop() { | |
| 2 | @setFnTest(this); | |
| 3 | ||
| 4 | var i : i32 = 0; | |
| 5 | while (i < 4) { | |
| 6 | i += 1; | |
| 7 | } | |
| 8 | assert(i == 4); | |
| 9 | assert(whileLoop1() == 1); | |
| 10 | } | |
| 11 | fn whileLoop1() -> i32 { | |
| 12 | return whileLoop2(); | |
| 13 | } | |
| 14 | fn whileLoop2() -> i32 { | |
| 15 | while (true) { | |
| 16 | return 1; | |
| 17 | } | |
| 18 | } | |
| 19 | fn staticEvalWhile() { | |
| 20 | @setFnTest(this); | |
| 21 | ||
| 22 | assert(static_eval_while_number == 1); | |
| 23 | } | |
| 24 | const static_eval_while_number = staticWhileLoop1(); | |
| 25 | fn staticWhileLoop1() -> i32 { | |
| 26 | return whileLoop2(); | |
| 27 | } | |
| 28 | fn staticWhileLoop2() -> i32 { | |
| 29 | while (true) { | |
| 30 | return 1; | |
| 31 | } | |
| 32 | } | |
| 33 | ||
| 34 | fn continueAndBreak() { | |
| 35 | @setFnTest(this); | |
| 36 | ||
| 37 | runContinueAndBreakTest(); | |
| 38 | assert(continue_and_break_counter == 8); | |
| 39 | } | |
| 40 | var continue_and_break_counter: i32 = 0; | |
| 41 | fn runContinueAndBreakTest() { | |
| 42 | var i : i32 = 0; | |
| 43 | while (true) { | |
| 44 | continue_and_break_counter += 2; | |
| 45 | i += 1; | |
| 46 | if (i < 4) { | |
| 47 | continue; | |
| 48 | } | |
| 49 | break; | |
| 50 | } | |
| 51 | assert(i == 4); | |
| 52 | } | |
| 53 | ||
| 54 | fn returnWithImplicitCastFromWhileLoop() { | |
| 55 | @setFnTest(this); | |
| 56 | ||
| 57 | %%returnWithImplicitCastFromWhileLoopTest(); | |
| 58 | } | |
| 59 | fn returnWithImplicitCastFromWhileLoopTest() -> %void { | |
| 60 | while (true) { | |
| 61 | return; | |
| 62 | } | |
| 63 | } | |
| 64 | ||
| 65 | fn whileWithContinueExpr() { | |
| 66 | @setFnTest(this); | |
| 67 | ||
| 68 | var sum: i32 = 0; | |
| 69 | {var i: i32 = 0; while (i < 10; i += 1) { | |
| 70 | if (i == 5) continue; | |
| 71 | sum += i; | |
| 72 | }} | |
| 73 | assert(sum == 40); | |
| 74 | } | |
| 75 | ||
| 76 | ||
| 77 | ||
| 78 | // TODO const assert = @import("std").debug.assert; | |
| 79 | fn assert(ok: bool) { | |
| 80 | if (!ok) | |
| 81 | @unreachable(); | |
| 82 | } |
test/self_hosted3.zig+29-29| ... | ... | @@ -1,30 +1,30 @@ |
| 1 | 1 | // TODO '_' identifier for unused variable bindings |
| 2 | const test_array = @import("cases3/array.zig"); | |
| 3 | const test_atomics = @import("cases3/atomics.zig"); | |
| 4 | const test_bool = @import("cases3/bool.zig"); | |
| 5 | const test_cast= @import("cases3/cast.zig"); | |
| 6 | const test_const_slice_child = @import("cases3/const_slice_child.zig"); | |
| 7 | const test_defer = @import("cases3/defer.zig"); | |
| 8 | const test_enum = @import("cases3/enum.zig"); | |
| 9 | const test_enum_with_members = @import("cases3/enum_with_members.zig"); | |
| 10 | const test_error = @import("cases3/error.zig"); | |
| 11 | const test_eval = @import("cases3/eval.zig"); | |
| 12 | const test_fn = @import("cases3/fn.zig"); | |
| 13 | const test_for = @import("cases3/for.zig"); | |
| 14 | const test_generics = @import("cases3/generics.zig"); | |
| 15 | const test_goto = @import("cases3/goto.zig"); | |
| 16 | const test_if = @import("cases3/if.zig"); | |
| 17 | const test_import = @import("cases3/import.zig"); | |
| 18 | const test_math = @import("cases3/math.zig"); | |
| 19 | const test_misc = @import("cases3/misc.zig"); | |
| 20 | const test_namespace_depends_on_compile_var = @import("cases3/namespace_depends_on_compile_var/index.zig"); | |
| 21 | const test_null = @import("cases3/null.zig"); | |
| 22 | const test_pub_enum = @import("cases3/pub_enum/index.zig"); | |
| 23 | const test_sizeof_and_typeof = @import("cases3/sizeof_and_typeof.zig"); | |
| 24 | const test_struct = @import("cases3/struct.zig"); | |
| 25 | const test_struct_contains_slice_of_itself = @import("cases3/struct_contains_slice_of_itself.zig"); | |
| 26 | const test_switch = @import("cases3/switch.zig"); | |
| 27 | const test_switch_prong_err_enum = @import("cases3/switch_prong_err_enum.zig"); | |
| 28 | const test_switch_prong_implicit_cast = @import("cases3/switch_prong_implicit_cast.zig"); | |
| 29 | const test_this = @import("cases3/this.zig"); | |
| 30 | const test_while = @import("cases3/while.zig"); | |
| 2 | const test_array = @import("cases/array.zig"); | |
| 3 | const test_atomics = @import("cases/atomics.zig"); | |
| 4 | const test_bool = @import("cases/bool.zig"); | |
| 5 | const test_cast= @import("cases/cast.zig"); | |
| 6 | const test_const_slice_child = @import("cases/const_slice_child.zig"); | |
| 7 | const test_defer = @import("cases/defer.zig"); | |
| 8 | const test_enum = @import("cases/enum.zig"); | |
| 9 | const test_enum_with_members = @import("cases/enum_with_members.zig"); | |
| 10 | const test_error = @import("cases/error.zig"); | |
| 11 | const test_eval = @import("cases/eval.zig"); | |
| 12 | const test_fn = @import("cases/fn.zig"); | |
| 13 | const test_for = @import("cases/for.zig"); | |
| 14 | const test_generics = @import("cases/generics.zig"); | |
| 15 | const test_goto = @import("cases/goto.zig"); | |
| 16 | const test_if = @import("cases/if.zig"); | |
| 17 | const test_import = @import("cases/import.zig"); | |
| 18 | const test_math = @import("cases/math.zig"); | |
| 19 | const test_misc = @import("cases/misc.zig"); | |
| 20 | const test_namespace_depends_on_compile_var = @import("cases/namespace_depends_on_compile_var/index.zig"); | |
| 21 | const test_null = @import("cases/null.zig"); | |
| 22 | const test_pub_enum = @import("cases/pub_enum/index.zig"); | |
| 23 | const test_sizeof_and_typeof = @import("cases/sizeof_and_typeof.zig"); | |
| 24 | const test_struct = @import("cases/struct.zig"); | |
| 25 | const test_struct_contains_slice_of_itself = @import("cases/struct_contains_slice_of_itself.zig"); | |
| 26 | const test_switch = @import("cases/switch.zig"); | |
| 27 | const test_switch_prong_err_enum = @import("cases/switch_prong_err_enum.zig"); | |
| 28 | const test_switch_prong_implicit_cast = @import("cases/switch_prong_implicit_cast.zig"); | |
| 29 | const test_this = @import("cases/this.zig"); | |
| 30 | const test_while = @import("cases/while.zig"); |