zig/test/self_hosted.zig

1717 lines
34 KiB
Zig
Raw Normal View History

2016-04-18 16:42:56 -07:00
const std = @import("std");
const assert = std.debug.assert;
2016-04-18 16:42:56 -07:00
const str = std.str;
2016-05-07 10:52:52 -07:00
const cstr = std.cstr;
2016-04-19 17:19:18 -07:00
const other = @import("other.zig");
2016-09-07 21:24:48 -07:00
// TODO '_' identifier for unused variable bindings
2016-08-16 22:42:50 -07:00
const test_return_type_type = @import("cases/return_type_type.zig");
2016-08-08 20:43:38 -07:00
const test_zeroes = @import("cases/zeroes.zig");
2016-08-16 22:42:50 -07:00
const test_sizeof_and_typeof = @import("cases/sizeof_and_typeof.zig");
2016-08-23 15:05:26 -07:00
const test_maybe_return = @import("cases/maybe_return.zig");
const test_max_value_type = @import("cases/max_value_type.zig");
2016-09-07 21:24:48 -07:00
const test_var_params = @import("cases/var_params.zig");
const test_const_slice_child = @import("cases/const_slice_child.zig");
2016-07-27 23:26:12 -07:00
// normal comment
/// this is a documentation comment
/// doc comment line 2
#attribute("test")
2016-08-16 22:42:50 -07:00
fn emptyFunctionWithComments() {}
#attribute("test")
2016-08-16 22:42:50 -07:00
fn ifStatements() {
shouldBeEqual(1, 1);
firstEqlThird(2, 1, 2);
}
2016-08-16 22:42:50 -07:00
fn shouldBeEqual(a: i32, b: i32) {
if (a != b) {
@unreachable();
} else {
return;
}
}
2016-08-16 22:42:50 -07:00
fn firstEqlThird(a: i32, b: i32, c: i32) {
if (a == b) {
@unreachable();
} else if (b == c) {
@unreachable();
} else if (a == c) {
return;
} else {
@unreachable();
}
}
2016-04-10 13:58:04 -07:00
#attribute("test")
fn params() {
2016-08-16 22:42:50 -07:00
assert(testParamsAdd(22, 11) == 33);
2016-04-10 13:58:04 -07:00
}
2016-08-16 22:42:50 -07:00
fn testParamsAdd(a: i32, b: i32) -> i32 {
2016-04-10 13:58:04 -07:00
a + b
}
#attribute("test")
2016-08-16 22:42:50 -07:00
fn localVariables() {
testLocVars(2);
}
2016-08-16 22:42:50 -07:00
fn testLocVars(b: i32) {
const a: i32 = 1;
if (a + b != 3) @unreachable();
}
#attribute("test")
2016-08-16 22:42:50 -07:00
fn boolLiterals() {
assert(true);
assert(!false);
}
2016-04-10 13:58:04 -07:00
#attribute("test")
2016-08-16 22:42:50 -07:00
fn voidParameters() {
voidFun(1, void{}, 2, {});
2016-04-10 13:58:04 -07:00
}
2016-08-16 22:42:50 -07:00
fn voidFun(a : i32, b : void, c : i32, d : void) {
2016-04-10 13:58:04 -07:00
const v = b;
const vv : void = if (a == 1) {v} else {};
assert(a + c == 3);
return vv;
}
#attribute("test")
2016-08-16 22:42:50 -07:00
fn mutableLocalVariables() {
2016-04-10 13:58:04 -07:00
var zero : i32 = 0;
assert(zero == 0);
var i = i32(0);
while (i != 3) {
i += 1;
}
assert(i == 3);
}
#attribute("test")
fn arrays() {
var array : [5]u32 = undefined;
2016-04-10 13:58:04 -07:00
var i : u32 = 0;
2016-04-10 13:58:04 -07:00
while (i < 5) {
array[i] = i + 1;
i = array[i];
}
i = 0;
var accumulator = u32(0);
2016-04-10 13:58:04 -07:00
while (i < 5) {
accumulator += array[i];
i += 1;
}
assert(accumulator == 15);
2016-08-16 22:42:50 -07:00
assert(getArrayLen(array) == 5);
2016-04-10 13:58:04 -07:00
}
2016-08-16 22:42:50 -07:00
fn getArrayLen(a: []u32) -> usize {
2016-04-10 13:58:04 -07:00
a.len
}
#attribute("test")
2016-08-16 22:42:50 -07:00
fn shortCircuit() {
2016-04-10 13:58:04 -07:00
var hit_1 = false;
var hit_2 = false;
var hit_3 = false;
var hit_4 = false;
2016-08-16 22:42:50 -07:00
if (true || {assertRuntime(false); false}) {
2016-04-10 13:58:04 -07:00
hit_1 = true;
}
if (false || { hit_2 = true; false }) {
2016-08-16 22:42:50 -07:00
assertRuntime(false);
2016-04-10 13:58:04 -07:00
}
if (true && { hit_3 = true; false }) {
2016-08-16 22:42:50 -07:00
assertRuntime(false);
2016-04-10 13:58:04 -07:00
}
2016-08-16 22:42:50 -07:00
if (false && {assertRuntime(false); false}) {
assertRuntime(false);
2016-04-10 13:58:04 -07:00
} else {
hit_4 = true;
}
assert(hit_1);
assert(hit_2);
assert(hit_3);
assert(hit_4);
}
2016-04-12 13:30:52 -07:00
#static_eval_enable(false)
2016-08-16 22:42:50 -07:00
fn assertRuntime(b: bool) {
if (!b) @unreachable()
2016-04-12 13:30:52 -07:00
}
2016-04-10 13:58:04 -07:00
#attribute("test")
2016-08-16 22:42:50 -07:00
fn modifyOperators() {
2016-04-10 13:58:04 -07:00
var i : i32 = 0;
i += 5; assert(i == 5);
i -= 2; assert(i == 3);
i *= 20; assert(i == 60);
i /= 3; assert(i == 20);
i %= 11; assert(i == 9);
i <<= 1; assert(i == 18);
i >>= 2; assert(i == 4);
i = 6;
i &= 5; assert(i == 4);
i ^= 6; assert(i == 2);
i = 6;
i |= 3; assert(i == 7);
}
#attribute("test")
2016-08-16 22:42:50 -07:00
fn separateBlockScopes() {
{
const no_conflict : i32 = 5;
assert(no_conflict == 5);
}
const c = {
const no_conflict = i32(10);
no_conflict
};
assert(c == 10);
}
#attribute("test")
2016-08-16 22:42:50 -07:00
fn voidStructFields() {
const foo = VoidStructFieldsFoo {
.a = void{},
.b = 1,
.c = void{},
};
assert(foo.b == 1);
2016-08-16 22:42:50 -07:00
assert(@sizeOf(VoidStructFieldsFoo) == 4);
}
struct VoidStructFieldsFoo {
a : void,
b : i32,
c : void,
}
2016-04-10 13:58:04 -07:00
#attribute("test")
pub fn structs() {
var foo : StructFoo = undefined;
2016-08-16 22:42:50 -07:00
@memset(&foo, 0, @sizeOf(StructFoo));
2016-04-10 13:58:04 -07:00
foo.a += 1;
foo.b = foo.a == 1;
2016-08-16 22:42:50 -07:00
testFoo(foo);
testMutation(&foo);
2016-04-10 13:58:04 -07:00
assert(foo.c == 100);
}
struct StructFoo {
a : i32,
b : bool,
c : f32,
}
2016-08-16 22:42:50 -07:00
fn testFoo(foo : StructFoo) {
2016-04-10 13:58:04 -07:00
assert(foo.b);
}
2016-08-16 22:42:50 -07:00
fn testMutation(foo : &StructFoo) {
2016-04-10 13:58:04 -07:00
foo.c = 100;
}
struct Node {
val: Val,
next: &Node,
}
struct Val {
x: i32,
}
#attribute("test")
2016-08-16 22:42:50 -07:00
fn structPointToSelf() {
2016-04-10 13:58:04 -07:00
var root : Node = undefined;
root.val.x = 1;
var node : Node = undefined;
node.next = &root;
node.val.x = 2;
root.next = &node;
assert(node.next.next.next.val.x == 1);
}
#attribute("test")
2016-08-16 22:42:50 -07:00
fn structByvalAssign() {
2016-04-10 13:58:04 -07:00
var foo1 : StructFoo = undefined;
var foo2 : StructFoo = undefined;
foo1.a = 1234;
foo2.a = 0;
assert(foo2.a == 0);
foo2 = foo1;
assert(foo2.a == 1234);
}
2016-08-16 22:42:50 -07:00
fn structInitializer() {
2016-04-10 13:58:04 -07:00
const val = Val { .x = 42 };
assert(val.x == 42);
}
const g1 : i32 = 1233 + 1;
var g2 : i32 = 0;
#attribute("test")
2016-08-16 22:42:50 -07:00
fn globalVariables() {
2016-04-10 13:58:04 -07:00
assert(g2 == 0);
g2 = g1;
assert(g2 == 1234);
}
#attribute("test")
2016-08-16 22:42:50 -07:00
fn whileLoop() {
2016-04-10 13:58:04 -07:00
var i : i32 = 0;
while (i < 4) {
i += 1;
}
assert(i == 4);
2016-08-16 22:42:50 -07:00
assert(whileLoop1() == 1);
2016-04-10 13:58:04 -07:00
}
2016-08-16 22:42:50 -07:00
fn whileLoop1() -> i32 {
return whileLoop2();
2016-04-10 13:58:04 -07:00
}
2016-08-16 22:42:50 -07:00
fn whileLoop2() -> i32 {
2016-04-10 13:58:04 -07:00
while (true) {
return 1;
}
}
#attribute("test")
2016-08-16 22:42:50 -07:00
fn voidArrays() {
var array: [4]void = undefined;
array[0] = void{};
array[1] = array[2];
2016-08-16 22:42:50 -07:00
assert(@sizeOf(@typeOf(array)) == 0);
assert(array.len == 4);
}
#attribute("test")
2016-08-16 22:42:50 -07:00
fn threeExprInARow() {
assertFalse(false || false || false);
assertFalse(true && true && false);
assertFalse(1 | 2 | 4 != 7);
assertFalse(3 ^ 6 ^ 8 != 13);
assertFalse(7 & 14 & 28 != 4);
assertFalse(9 << 1 << 2 != 9 << 3);
assertFalse(90 >> 1 >> 2 != 90 >> 3);
assertFalse(100 - 1 + 1000 != 1099);
assertFalse(5 * 4 / 2 % 3 != 1);
assertFalse(i32(i32(5)) != 5);
assertFalse(!!false);
assertFalse(i32(7) != --(i32(7)));
}
2016-08-16 22:42:50 -07:00
fn assertFalse(b: bool) {
assert(!b);
}
#attribute("test")
2016-08-16 22:42:50 -07:00
fn maybeType() {
const x : ?bool = true;
if (const y ?= x) {
if (y) {
// OK
} else {
@unreachable();
}
} else {
@unreachable();
}
const next_x : ?i32 = null;
const z = next_x ?? 1234;
assert(z == 1234);
const final_x : ?i32 = 13;
const num = final_x ?? @unreachable();
assert(num == 13);
}
#attribute("test")
2016-08-16 22:42:50 -07:00
fn enumType() {
const foo1 = EnumTypeFoo.One {13};
const foo2 = EnumTypeFoo.Two {EnumType { .x = 1234, .y = 5678, }};
const bar = EnumTypeBar.B;
assert(bar == EnumTypeBar.B);
2016-08-16 22:42:50 -07:00
assert(@memberCount(EnumTypeFoo) == 3);
assert(@memberCount(EnumTypeBar) == 4);
const expected_foo_size = switch (@compileVar("arch")) {
i386 => 20,
x86_64 => 24,
else => @unreachable(),
};
2016-08-16 22:42:50 -07:00
assert(@sizeOf(EnumTypeFoo) == expected_foo_size);
assert(@sizeOf(EnumTypeBar) == 1);
}
struct EnumType {
x: u64,
y: u64,
}
enum EnumTypeFoo {
One: i32,
Two: EnumType,
Three: void,
}
enum EnumTypeBar {
A,
B,
C,
D,
}
#attribute("test")
2016-08-16 22:42:50 -07:00
fn arrayLiteral() {
const hex_mult = []u16{4096, 256, 16, 1};
2016-08-16 22:42:50 -07:00
assert(hex_mult.len == 4);
assert(hex_mult[1] == 256);
}
#attribute("test")
2016-08-16 22:42:50 -07:00
fn constNumberLiteral() {
const one = 1;
const eleven = ten + one;
assert(eleven == 11);
}
const ten = 10;
#attribute("test")
2016-08-16 22:42:50 -07:00
fn errorValues() {
const a = i32(error.err1);
const b = i32(error.err2);
assert(a != b);
}
error err1;
error err2;
#attribute("test")
2016-08-16 22:42:50 -07:00
fn fnCallOfStructField() {
assert(callStructField(Foo {.ptr = aFunc,}) == 13);
}
struct Foo {
ptr: fn() -> i32,
}
2016-08-16 22:42:50 -07:00
fn aFunc() -> i32 { 13 }
2016-08-16 22:42:50 -07:00
fn callStructField(foo: Foo) -> i32 {
return foo.ptr();
}
#attribute("test")
2016-08-16 22:42:50 -07:00
fn redefinitionOfErrorValuesAllowed() {
shouldBeNotEqual(error.AnError, error.SecondError);
}
error AnError;
error AnError;
error SecondError;
2016-08-16 22:42:50 -07:00
fn shouldBeNotEqual(a: error, b: error) {
if (a == b) @unreachable()
}
#attribute("test")
2016-08-16 22:42:50 -07:00
fn constantEnumWithPayload() {
var empty = AnEnumWithPayload.Empty;
var full = AnEnumWithPayload.Full {13};
2016-08-16 22:42:50 -07:00
shouldBeEmpty(empty);
shouldBeNotEmpty(full);
}
2016-08-16 22:42:50 -07:00
fn shouldBeEmpty(x: AnEnumWithPayload) {
switch (x) {
Empty => {},
else => @unreachable(),
}
}
2016-08-16 22:42:50 -07:00
fn shouldBeNotEmpty(x: AnEnumWithPayload) {
switch (x) {
Empty => @unreachable(),
else => {},
}
}
enum AnEnumWithPayload {
Empty,
Full: i32,
}
#attribute("test")
2016-08-16 22:42:50 -07:00
fn continueInForLoop() {
const array = []i32 {1, 2, 3, 4, 5};
var sum : i32 = 0;
for (array) |x| {
sum += x;
if (x < 3) {
continue;
}
break;
}
if (sum != 6) @unreachable()
}
2016-02-04 11:59:06 -08:00
#attribute("test")
2016-08-16 22:42:50 -07:00
fn castBoolToInt() {
2016-02-04 11:59:06 -08:00
const t = true;
const f = false;
assert(i32(t) == i32(1));
assert(i32(f) == i32(0));
2016-08-16 22:42:50 -07:00
nonConstCastBoolToInt(t, f);
2016-02-04 11:59:06 -08:00
}
2016-08-16 22:42:50 -07:00
fn nonConstCastBoolToInt(t: bool, f: bool) {
assert(i32(t) == i32(1));
assert(i32(f) == i32(0));
2016-02-04 11:59:06 -08:00
}
#attribute("test")
2016-08-16 22:42:50 -07:00
fn switchOnEnum() {
const fruit = Fruit.Orange;
2016-08-16 22:42:50 -07:00
nonConstSwitchOnEnum(fruit);
}
enum Fruit {
Apple,
Orange,
Banana,
}
2016-04-12 13:30:52 -07:00
#static_eval_enable(false)
2016-08-16 22:42:50 -07:00
fn nonConstSwitchOnEnum(fruit: Fruit) {
switch (fruit) {
Apple => @unreachable(),
Orange => {},
Banana => @unreachable(),
}
}
#attribute("test")
2016-08-16 22:42:50 -07:00
fn switchStatement() {
nonConstSwitch(SwitchStatmentFoo.C);
}
2016-04-12 13:30:52 -07:00
#static_eval_enable(false)
2016-08-16 22:42:50 -07:00
fn nonConstSwitch(foo: SwitchStatmentFoo) {
const val: i32 = switch (foo) {
A => 1,
B => 2,
C => 3,
D => 4,
};
if (val != 3) @unreachable();
}
enum SwitchStatmentFoo {
A,
B,
C,
D,
}
#attribute("test")
2016-08-16 22:42:50 -07:00
fn switchProngWithVar() {
switchProngWithVarFn(SwitchProngWithVarEnum.One {13});
switchProngWithVarFn(SwitchProngWithVarEnum.Two {13.0});
switchProngWithVarFn(SwitchProngWithVarEnum.Meh);
}
enum SwitchProngWithVarEnum {
One: i32,
Two: f32,
Meh,
}
2016-04-12 13:30:52 -07:00
#static_eval_enable(false)
2016-08-16 22:42:50 -07:00
fn switchProngWithVarFn(a: SwitchProngWithVarEnum) {
switch(a) {
One => |x| {
if (x != 13) @unreachable();
},
Two => |x| {
if (x != 13.0) @unreachable();
},
Meh => |x| {
const v: void = x;
},
}
}
#attribute("test")
2016-08-16 22:42:50 -07:00
fn errReturnInAssignment() {
%%doErrReturnInAssignment();
}
2016-04-12 13:30:52 -07:00
#static_eval_enable(false)
2016-08-16 22:42:50 -07:00
fn doErrReturnInAssignment() -> %void {
var x : i32 = undefined;
2016-08-16 22:42:50 -07:00
x = %return makeANonErr();
}
2016-08-16 22:42:50 -07:00
fn makeANonErr() -> %i32 {
return 1;
}
#attribute("test")
2016-08-16 22:42:50 -07:00
fn rhsMaybeUnwrapReturn() {
const x = ?true;
const y = x ?? return;
}
#attribute("test")
2016-08-16 22:42:50 -07:00
fn implicitCastFnUnreachableReturn() {
wantsFnWithVoid(fnWithUnreachable);
}
2016-08-16 22:42:50 -07:00
fn wantsFnWithVoid(f: fn()) { }
2016-08-16 22:42:50 -07:00
fn fnWithUnreachable() -> unreachable {
@unreachable()
}
#attribute("test")
2016-08-16 22:42:50 -07:00
fn explicitCastMaybePointers() {
const a: ?&i32 = undefined;
const b: ?&f32 = (?&f32)(a);
}
#attribute("test")
2016-08-16 22:42:50 -07:00
fn constExprEvalOnSingleExprBlocks() {
assert(constExprEvalOnSingleExprBlocksFn(1, true) == 3);
}
2016-08-16 22:42:50 -07:00
fn constExprEvalOnSingleExprBlocksFn(x: i32, b: bool) -> i32 {
const literal = 3;
const result = if (b) {
literal
} else {
x
};
return result;
}
2016-02-07 14:11:20 -08:00
#attribute("test")
2016-08-16 22:42:50 -07:00
fn builtinConstEval() {
const x : i32 = @constEval(1 + 2 + 3);
assert(x == @constEval(6));
2016-02-07 14:11:20 -08:00
}
#attribute("test")
fn slicing() {
var array : [20]i32 = undefined;
array[5] = 1234;
var slice = array[5...10];
if (slice.len != 5) @unreachable();
const ptr = &slice[0];
if (ptr[0] != 1234) @unreachable();
var slice_rest = array[10...];
if (slice_rest.len != 10) @unreachable();
}
#attribute("test")
2016-08-16 22:42:50 -07:00
fn memcpyAndMemsetIntrinsics() {
var foo : [20]u8 = undefined;
var bar : [20]u8 = undefined;
@memset(&foo[0], 'A', foo.len);
@memcpy(&bar[0], &foo[0], bar.len);
if (bar[11] != 'A') @unreachable();
}
#attribute("test")
2016-08-16 22:42:50 -07:00
fn arrayDotLenConstExpr() { }
struct ArrayDotLenConstExpr {
2016-08-16 22:42:50 -07:00
y: [@constEval(some_array.len)]u8,
}
const some_array = []u8 {0, 1, 2, 3};
#attribute("test")
2016-08-16 22:42:50 -07:00
fn countLeadingZeroes() {
assert(@clz(u8, 0b00001010) == 4);
assert(@clz(u8, 0b10001010) == 0);
assert(@clz(u8, 0b00000000) == 8);
}
#attribute("test")
2016-08-16 22:42:50 -07:00
fn countTrailingZeroes() {
assert(@ctz(u8, 0b10100000) == 5);
assert(@ctz(u8, 0b10001010) == 1);
assert(@ctz(u8, 0b00000000) == 8);
}
#attribute("test")
2016-08-16 22:42:50 -07:00
fn multilineString() {
const s1 =
\\one
\\two)
\\three
;
const s2 = "one\ntwo)\nthree";
2016-04-18 16:42:56 -07:00
assert(str.eql(s1, s2));
}
2016-08-04 23:10:12 -07:00
#attribute("test")
2016-08-16 22:42:50 -07:00
fn multilineCString() {
2016-08-04 23:10:12 -07:00
const s1 =
c\\one
c\\two)
c\\three
;
const s2 = c"one\ntwo)\nthree";
assert(cstr.cmp(s1, s2) == 0);
}
2016-04-06 11:38:12 -07:00
#attribute("test")
2016-08-16 22:42:50 -07:00
fn simpleGenericFn() {
assert(max(i32, 3, -1) == 3);
assert(max(f32, 0.123, 0.456) == 0.456);
assert(add(2, 3) == 5);
2016-04-06 11:38:12 -07:00
}
fn max(inline T: type, a: T, b: T) -> T {
2016-04-06 11:38:12 -07:00
return if (a > b) a else b;
}
fn add(inline a: i32, b: i32) -> i32 {
2016-08-16 22:42:50 -07:00
return @constEval(a) + b;
}
2016-04-06 11:38:12 -07:00
#attribute("test")
2016-08-16 22:42:50 -07:00
fn constantEqualFunctionPointers() {
const alias = emptyFn;
assert(@constEval(emptyFn == alias));
}
2016-08-16 22:42:50 -07:00
fn emptyFn() {}
#attribute("test")
2016-08-16 22:42:50 -07:00
fn genericMallocFree() {
const a = %%memAlloc(u8, 10);
memFree(u8, a);
}
const some_mem : [100]u8 = undefined;
2016-04-12 13:30:52 -07:00
#static_eval_enable(false)
2016-08-16 22:42:50 -07:00
fn memAlloc(inline T: type, n: usize) -> %[]T {
return (&T)(&some_mem[0])[0...n];
}
2016-08-16 22:42:50 -07:00
fn memFree(inline T: type, mem: []T) { }
#attribute("test")
2016-08-16 22:42:50 -07:00
fn callFnWithEmptyString() {
acceptsString("");
}
2016-08-16 22:42:50 -07:00
fn acceptsString(foo: []u8) { }
2016-04-08 17:30:26 -07:00
#attribute("test")
2016-08-16 22:42:50 -07:00
fn hexEscape() {
2016-04-18 16:42:56 -07:00
assert(str.eql("\x68\x65\x6c\x6c\x6f", "hello"));
2016-04-08 17:30:26 -07:00
}
2016-04-09 08:55:53 -07:00
error AnError;
error ALongerErrorName;
#attribute("test")
2016-08-16 22:42:50 -07:00
fn errorNameString() {
2016-09-05 14:03:11 -07:00
assert(str.eql(@errorName(error.AnError), "AnError"));
assert(str.eql(@errorName(error.ALongerErrorName), "ALongerErrorName"));
2016-04-09 08:55:53 -07:00
}
2016-04-09 16:41:17 -07:00
#attribute("test")
2016-08-16 22:42:50 -07:00
fn gotoAndLabels() {
gotoLoop();
2016-04-09 16:41:17 -07:00
assert(goto_counter == 10);
}
2016-08-16 22:42:50 -07:00
fn gotoLoop() {
2016-04-09 16:41:17 -07:00
var i: i32 = 0;
goto cond;
loop:
i += 1;
cond:
if (!(i < 10)) goto end;
goto_counter += 1;
goto loop;
end:
}
var goto_counter: i32 = 0;
#attribute("test")
2016-08-16 22:42:50 -07:00
fn gotoLeaveDeferScope() {
testGotoLeaveDeferScope(true);
}
2016-04-12 13:30:52 -07:00
#static_eval_enable(false)
2016-08-16 22:42:50 -07:00
fn testGotoLeaveDeferScope(b: bool) {
var it_worked = false;
goto entry;
exit:
if (it_worked) {
return;
}
@unreachable();
entry:
defer it_worked = true;
if (b) goto exit;
}
#attribute("test")
2016-08-16 22:42:50 -07:00
fn castUndefined() {
const array: [100]u8 = undefined;
const slice = ([]u8)(array);
2016-08-16 22:42:50 -07:00
testCastUndefined(slice);
}
2016-08-16 22:42:50 -07:00
fn testCastUndefined(x: []u8) {}
#attribute("test")
2016-08-16 22:42:50 -07:00
fn castSmallUnsignedToLargerSigned() {
assert(castSmallUnsignedToLargerSigned1(200) == i16(200));
assert(castSmallUnsignedToLargerSigned2(9999) == i64(9999));
}
2016-08-16 22:42:50 -07:00
fn castSmallUnsignedToLargerSigned1(x: u8) -> i16 { x }
fn castSmallUnsignedToLargerSigned2(x: u16) -> i64 { x }
2016-04-12 13:30:52 -07:00
#attribute("test")
2016-08-16 22:42:50 -07:00
fn implicitCastAfterUnreachable() {
2016-04-12 13:30:52 -07:00
assert(outer() == 1234);
}
fn inner() -> i32 { 1234 }
fn outer() -> i64 {
2016-04-12 13:30:52 -07:00
return inner();
}
#attribute("test")
2016-08-16 22:42:50 -07:00
fn elseIfExpression() {
assert(elseIfExpressionF(1) == 1);
2016-04-12 13:30:52 -07:00
}
2016-08-16 22:42:50 -07:00
fn elseIfExpressionF(c: u8) -> u8 {
2016-04-12 13:30:52 -07:00
if (c == 0) {
0
} else if (c == 1) {
1
} else {
2
}
}
#attribute("test")
2016-08-16 22:42:50 -07:00
fn errBinaryOperator() {
const a = errBinaryOperatorG(true) %% 3;
const b = errBinaryOperatorG(false) %% 3;
2016-04-12 13:30:52 -07:00
assert(a == 3);
assert(b == 10);
}
error ItBroke;
2016-08-16 22:42:50 -07:00
fn errBinaryOperatorG(x: bool) -> %isize {
2016-04-12 13:30:52 -07:00
if (x) {
error.ItBroke
} else {
10
}
}
#attribute("test")
2016-08-16 22:42:50 -07:00
fn unwrapSimpleValueFromError() {
const i = %%unwrapSimpleValueFromErrorDo();
2016-04-12 13:30:52 -07:00
assert(i == 13);
}
2016-08-16 22:42:50 -07:00
fn unwrapSimpleValueFromErrorDo() -> %isize { 13 }
2016-04-12 13:30:52 -07:00
#attribute("test")
2016-08-16 22:42:50 -07:00
fn storeMemberFunctionInVariable() {
2016-04-12 13:30:52 -07:00
const instance = MemberFnTestFoo { .x = 1234, };
2016-08-16 22:42:50 -07:00
const memberFn = MemberFnTestFoo.member;
const result = memberFn(instance);
2016-04-12 13:30:52 -07:00
assert(result == 1234);
}
struct MemberFnTestFoo {
x: i32,
fn member(foo: MemberFnTestFoo) -> i32 { foo.x }
}
#attribute("test")
2016-08-16 22:42:50 -07:00
fn callMemberFunctionDirectly() {
2016-04-12 13:30:52 -07:00
const instance = MemberFnTestFoo { .x = 1234, };
const result = MemberFnTestFoo.member(instance);
assert(result == 1234);
}
#attribute("test")
2016-08-16 22:42:50 -07:00
fn memberFunctions() {
2016-04-12 13:30:52 -07:00
const r = MemberFnRand {.seed = 1234};
2016-08-16 22:42:50 -07:00
assert(r.getSeed() == 1234);
2016-04-12 13:30:52 -07:00
}
struct MemberFnRand {
seed: u32,
2016-08-16 22:42:50 -07:00
pub fn getSeed(r: MemberFnRand) -> u32 {
2016-04-12 13:30:52 -07:00
r.seed
}
}
#attribute("test")
2016-08-16 22:42:50 -07:00
fn staticFunctionEvaluation() {
assert(statically_added_number == 3);
}
2016-08-16 22:42:50 -07:00
const statically_added_number = staticAdd(1, 2);
fn staticAdd(a: i32, b: i32) -> i32 { a + b }
#attribute("test")
2016-08-16 22:42:50 -07:00
fn staticallyInitalizedList() {
assert(static_point_list[0].x == 1);
assert(static_point_list[0].y == 2);
assert(static_point_list[1].x == 3);
assert(static_point_list[1].y == 4);
}
struct Point {
x: i32,
y: i32,
}
2016-08-16 22:42:50 -07:00
const static_point_list = []Point { makePoint(1, 2), makePoint(3, 4) };
fn makePoint(x: i32, y: i32) -> Point {
return Point {
.x = x,
.y = y,
};
}
#attribute("test")
2016-08-16 22:42:50 -07:00
fn staticEvalRecursive() {
2016-08-30 16:06:02 -07:00
assert(some_data.len == 21);
}
2016-08-30 16:06:02 -07:00
var some_data: [usize(fibbonaci(7))]u8 = undefined;
fn fibbonaci(x: i32) -> i32 {
if (x <= 1) return 1;
return fibbonaci(x - 1) + fibbonaci(x - 2);
}
#attribute("test")
2016-08-16 22:42:50 -07:00
fn staticEvalWhile() {
assert(static_eval_while_number == 1);
}
2016-08-16 22:42:50 -07:00
const static_eval_while_number = staticWhileLoop1();
fn staticWhileLoop1() -> i32 {
return whileLoop2();
}
2016-08-16 22:42:50 -07:00
fn staticWhileLoop2() -> i32 {
while (true) {
return 1;
}
}
2016-04-13 10:13:49 -07:00
#attribute("test")
2016-08-16 22:42:50 -07:00
fn staticEvalListInit() {
2016-04-13 10:13:49 -07:00
assert(static_vec3.data[2] == 1.0);
}
const static_vec3 = vec3(0.0, 0.0, 1.0);
pub struct Vec3 {
data: [3]f32,
}
pub fn vec3(x: f32, y: f32, z: f32) -> Vec3 {
Vec3 {
.data = []f32 { x, y, z, },
}
}
#attribute("test")
2016-08-16 22:42:50 -07:00
fn genericFnWithImplicitCast() {
assert(getFirstByte(u8, []u8 {13}) == 13);
assert(getFirstByte(u16, []u16 {0, 13}) == 0);
}
2016-08-16 22:42:50 -07:00
fn getByte(ptr: ?&u8) -> u8 {*??ptr}
fn getFirstByte(inline T: type, mem: []T) -> u8 {
getByte((&u8)(&mem[0]))
}
2016-04-14 10:52:47 -07:00
#attribute("test")
2016-08-16 22:42:50 -07:00
fn continueAndBreak() {
runContinueAndBreakTest();
2016-04-14 10:52:47 -07:00
assert(continue_and_break_counter == 8);
}
var continue_and_break_counter: i32 = 0;
2016-08-16 22:42:50 -07:00
fn runContinueAndBreakTest() {
2016-04-14 10:52:47 -07:00
var i : i32 = 0;
while (true) {
continue_and_break_counter += 2;
i += 1;
if (i < 4) {
continue;
}
break;
}
assert(i == 4);
}
#attribute("test")
2016-08-16 22:42:50 -07:00
fn pointerDereferencing() {
2016-04-14 10:52:47 -07:00
var x = i32(3);
const y = &x;
*y += 1;
assert(x == 4);
assert(*y == 4);
}
#attribute("test")
2016-08-16 22:42:50 -07:00
fn constantExpressions() {
var array : [array_size]u8 = undefined;
assert(@sizeOf(@typeOf(array)) == 20);
2016-04-14 10:52:47 -07:00
}
2016-08-16 22:42:50 -07:00
const array_size : u8 = 20;
2016-04-14 10:52:47 -07:00
#attribute("test")
2016-08-16 22:42:50 -07:00
fn minValueAndMaxValue() {
assert(@maxValue(u8) == 255);
assert(@maxValue(u16) == 65535);
assert(@maxValue(u32) == 4294967295);
assert(@maxValue(u64) == 18446744073709551615);
2016-04-14 10:52:47 -07:00
2016-08-16 22:42:50 -07:00
assert(@maxValue(i8) == 127);
assert(@maxValue(i16) == 32767);
assert(@maxValue(i32) == 2147483647);
assert(@maxValue(i64) == 9223372036854775807);
2016-04-14 10:52:47 -07:00
2016-08-16 22:42:50 -07:00
assert(@minValue(u8) == 0);
assert(@minValue(u16) == 0);
assert(@minValue(u32) == 0);
assert(@minValue(u64) == 0);
2016-04-14 10:52:47 -07:00
2016-08-16 22:42:50 -07:00
assert(@minValue(i8) == -128);
assert(@minValue(i16) == -32768);
assert(@minValue(i32) == -2147483648);
assert(@minValue(i64) == -9223372036854775808);
2016-04-14 10:52:47 -07:00
}
#attribute("test")
2016-08-16 22:42:50 -07:00
fn overflowIntrinsics() {
2016-04-14 10:52:47 -07:00
var result: u8 = undefined;
2016-08-16 22:42:50 -07:00
assert(@addWithOverflow(u8, 250, 100, &result));
assert(!@addWithOverflow(u8, 100, 150, &result));
2016-04-14 10:52:47 -07:00
assert(result == 250);
}
#attribute("test")
2016-08-16 22:42:50 -07:00
fn nestedArrays() {
2016-04-14 10:52:47 -07:00
const array_of_strings = [][]u8 {"hello", "this", "is", "my", "thing"};
2016-04-18 16:42:56 -07:00
for (array_of_strings) |s, i| {
if (i == 0) assert(str.eql(s, "hello"));
if (i == 1) assert(str.eql(s, "this"));
if (i == 2) assert(str.eql(s, "is"));
if (i == 3) assert(str.eql(s, "my"));
if (i == 4) assert(str.eql(s, "thing"));
2016-04-14 10:52:47 -07:00
}
}
#attribute("test")
2016-08-16 22:42:50 -07:00
fn intToPtrCast() {
2016-04-14 10:52:47 -07:00
const x = isize(13);
const y = (&u8)(x);
const z = usize(y);
assert(z == 13);
}
#attribute("test")
2016-08-16 22:42:50 -07:00
fn stringConcatenation() {
2016-04-18 16:42:56 -07:00
assert(str.eql("OK" ++ " IT " ++ "WORKED", "OK IT WORKED"));
2016-04-14 10:52:47 -07:00
}
#attribute("test")
2016-08-16 22:42:50 -07:00
fn constantStructWithNegation() {
2016-04-14 10:52:47 -07:00
assert(vertices[0].x == -0.6);
}
struct Vertex {
x: f32,
y: f32,
r: f32,
g: f32,
b: f32,
}
const vertices = []Vertex {
Vertex { .x = -0.6, .y = -0.4, .r = 1.0, .g = 0.0, .b = 0.0 },
Vertex { .x = 0.6, .y = -0.4, .r = 0.0, .g = 1.0, .b = 0.0 },
Vertex { .x = 0.0, .y = 0.6, .r = 0.0, .g = 0.0, .b = 1.0 },
};
#attribute("test")
2016-08-16 22:42:50 -07:00
fn returnWithImplicitCastFromWhileLoop() {
%%returnWithImplicitCastFromWhileLoopTest();
2016-04-14 10:52:47 -07:00
}
2016-08-16 22:42:50 -07:00
fn returnWithImplicitCastFromWhileLoopTest() -> %void {
2016-04-14 10:52:47 -07:00
while (true) {
return;
}
}
#attribute("test")
2016-08-16 22:42:50 -07:00
fn returnStructByvalFromFunction() {
const bar = makeBar(1234, 5678);
2016-04-14 10:52:47 -07:00
assert(bar.y == 5678);
}
struct Bar {
x: i32,
y: i32,
}
2016-08-16 22:42:50 -07:00
fn makeBar(x: i32, y: i32) -> Bar {
2016-04-14 10:52:47 -07:00
Bar {
.x = x,
.y = y,
}
}
#attribute("test")
2016-08-16 22:42:50 -07:00
fn functionPointers() {
const fns = []@typeOf(fn1) { fn1, fn2, fn3, fn4, };
2016-04-14 10:52:47 -07:00
for (fns) |f, i| {
assert(f() == u32(i) + 5);
}
}
fn fn1() -> u32 {5}
fn fn2() -> u32 {6}
fn fn3() -> u32 {7}
fn fn4() -> u32 {8}
#attribute("test")
2016-08-16 22:42:50 -07:00
fn staticallyInitalizedStruct() {
2016-04-14 10:52:47 -07:00
st_init_str_foo.x += 1;
assert(st_init_str_foo.x == 14);
}
struct StInitStrFoo {
x: i32,
y: bool,
}
var st_init_str_foo = StInitStrFoo { .x = 13, .y = true, };
#attribute("test")
2016-08-16 22:42:50 -07:00
fn staticallyInitializedArrayLiteral() {
2016-04-14 10:52:47 -07:00
const y : [4]u8 = st_init_arr_lit_x;
assert(y[3] == 4);
}
const st_init_arr_lit_x = []u8{1,2,3,4};
2016-04-18 13:06:17 -07:00
#attribute("test")
2016-08-16 22:42:50 -07:00
fn pointerToVoidReturnType() {
%%testPointerToVoidReturnType();
2016-04-18 13:06:17 -07:00
}
2016-08-16 22:42:50 -07:00
fn testPointerToVoidReturnType() -> %void {
const a = testPointerToVoidReturnType2();
2016-04-18 13:06:17 -07:00
return *a;
}
const test_pointer_to_void_return_type_x = void{};
2016-08-16 22:42:50 -07:00
fn testPointerToVoidReturnType2() -> &void {
2016-04-18 13:06:17 -07:00
return &test_pointer_to_void_return_type_x;
}
#attribute("test")
2016-08-16 22:42:50 -07:00
fn callResultOfIfElseExpression() {
2016-04-18 16:42:56 -07:00
assert(str.eql(f2(true), "a"));
assert(str.eql(f2(false), "b"));
2016-04-18 13:06:17 -07:00
}
fn f2(x: bool) -> []u8 {
2016-08-16 22:42:50 -07:00
return (if (x) fA else fB)();
2016-04-18 13:06:17 -07:00
}
2016-08-16 22:42:50 -07:00
fn fA() -> []u8 { "a" }
fn fB() -> []u8 { "b" }
2016-04-18 13:06:17 -07:00
#attribute("test")
2016-08-16 22:42:50 -07:00
fn constExpressionEvalHandlingOfVariables() {
2016-04-18 13:06:17 -07:00
var x = true;
while (x) {
x = false;
}
}
#attribute("test")
2016-08-16 22:42:50 -07:00
fn constantEnumInitializationWithDifferingSizes() {
test3_1(test3_foo);
test3_2(test3_bar);
}
enum Test3Foo {
One,
Two: f32,
Three: Test3Point,
}
struct Test3Point {
x: i32,
y: i32,
}
const test3_foo = Test3Foo.Three{Test3Point {.x = 3, .y = 4}};
const test3_bar = Test3Foo.Two{13};
#static_eval_enable(false)
fn test3_1(f: Test3Foo) {
switch (f) {
Three => |pt| {
assert(pt.x == 3);
assert(pt.y == 4);
},
else => @unreachable(),
}
}
#static_eval_enable(false)
fn test3_2(f: Test3Foo) {
switch (f) {
Two => |x| {
assert(x == 13);
},
else => @unreachable(),
}
}
2016-04-19 17:19:18 -07:00
#attribute("test")
2016-08-16 22:42:50 -07:00
fn pubEnum() {
pubEnumTest(other.APubEnum.Two);
2016-04-19 17:19:18 -07:00
}
2016-08-16 22:42:50 -07:00
fn pubEnumTest(foo: other.APubEnum) {
2016-04-19 17:19:18 -07:00
assert(foo == other.APubEnum.Two);
}
#attribute("test")
2016-08-16 22:42:50 -07:00
fn castWithImportedSymbol() {
assert(other.size_t(42) == 42);
}
#attribute("test")
2016-08-16 22:42:50 -07:00
fn whileWithContinueExpr() {
var sum: i32 = 0;
{var i: i32 = 0; while (i < 10; i += 1) {
if (i == 5) continue;
sum += i;
}}
assert(sum == 40);
}
#attribute("test")
2016-08-16 22:42:50 -07:00
fn forLoopWithPointerElemVar() {
const source = "abcdefg";
var target: [source.len]u8 = undefined;
@memcpy(&target[0], &source[0], source.len);
2016-08-16 22:42:50 -07:00
mangleString(target);
assert(str.eql(target, "bcdefgh"));
}
#static_eval_enable(false)
2016-08-16 22:42:50 -07:00
fn mangleString(s: []u8) {
for (s) |*c| {
*c += 1;
}
}
2016-04-21 09:47:41 -07:00
#attribute("test")
2016-08-16 22:42:50 -07:00
fn emptyStructMethodCall() {
2016-04-21 09:47:41 -07:00
const es = EmptyStruct{};
assert(es.method() == 1234);
}
struct EmptyStruct {
#static_eval_enable(false)
fn method(es: EmptyStruct) -> i32 { 1234 }
}
#attribute("test")
fn @"weird function name"() { }
#attribute("test")
2016-08-16 22:42:50 -07:00
fn returnEmptyStructFromFn() {
testReturnEmptyStructFromFn();
testReturnEmptyStructFromFnNoeval();
}
struct EmptyStruct2 {}
2016-08-16 22:42:50 -07:00
fn testReturnEmptyStructFromFn() -> EmptyStruct2 {
EmptyStruct2 {}
}
#static_eval_enable(false)
2016-08-16 22:42:50 -07:00
fn testReturnEmptyStructFromFnNoeval() -> EmptyStruct2 {
EmptyStruct2 {}
}
#attribute("test")
2016-08-16 22:42:50 -07:00
fn passSliceOfEmptyStructToFn() {
assert(testPassSliceOfEmptyStructToFn([]EmptyStruct2{ EmptyStruct2{} }) == 1);
}
2016-08-16 22:42:50 -07:00
fn testPassSliceOfEmptyStructToFn(slice: []EmptyStruct2) -> usize {
slice.len
}
#attribute("test")
2016-08-16 22:42:50 -07:00
fn pointerComparison() {
const a = ([]u8)("a");
const b = &a;
2016-08-16 22:42:50 -07:00
assert(ptrEql(b, b));
}
2016-08-16 22:42:50 -07:00
fn ptrEql(a: &[]u8, b: &[]u8) -> bool {
a == b
}
#attribute("test")
2016-08-16 22:42:50 -07:00
fn characterLiterals() {
assert('\'' == single_quote);
}
const single_quote = '\'';
#attribute("test")
2016-08-16 22:42:50 -07:00
fn switchWithMultipleExpressions() {
const x: i32 = switch (returnsFive()) {
1, 2, 3 => 1,
4, 5, 6 => 2,
else => 3,
};
assert(x == 2);
}
#static_eval_enable(false)
2016-08-16 22:42:50 -07:00
fn returnsFive() -> i32 { 5 }
#attribute("test")
2016-08-16 22:42:50 -07:00
fn switchOnErrorUnion() {
const x = switch (returnsTen()) {
Ok => |val| val + 1,
ItBroke, NoMem => 1,
CrappedOut => 2,
};
assert(x == 11);
}
error ItBroke;
error NoMem;
error CrappedOut;
#static_eval_enable(false)
2016-08-16 22:42:50 -07:00
fn returnsTen() -> %i32 { 10 }
2016-04-26 11:39:31 -07:00
#attribute("test")
2016-08-16 22:42:50 -07:00
fn boolCmp() {
assert(testBoolCmp(true, false) == false);
2016-04-26 11:39:31 -07:00
}
#static_eval_enable(false)
2016-08-16 22:42:50 -07:00
fn testBoolCmp(a: bool, b: bool) -> bool { a == b }
#attribute("test")
2016-08-16 22:42:50 -07:00
fn takeAddressOfParameter() {
testTakeAddressOfParameter(12.34);
testTakeAddressOfParameterNoeval(12.34);
}
2016-08-16 22:42:50 -07:00
fn testTakeAddressOfParameter(f: f32) {
const f_ptr = &f;
assert(*f_ptr == 12.34);
}
#static_eval_enable(false)
2016-08-16 22:42:50 -07:00
fn testTakeAddressOfParameterNoeval(f: f32) {
const f_ptr = &f;
assert(*f_ptr == 12.34);
}
2016-04-28 18:03:44 -07:00
#attribute("test")
2016-08-16 22:42:50 -07:00
fn arrayMultOperator() {
2016-04-28 18:03:44 -07:00
assert(str.eql("ab" ** 5, "ababababab"));
}
2016-05-01 14:53:48 -07:00
#attribute("test")
2016-08-16 22:42:50 -07:00
fn stringEscapes() {
2016-05-01 14:53:48 -07:00
assert(str.eql("\"", "\x22"));
assert(str.eql("\'", "\x27"));
assert(str.eql("\n", "\x0a"));
assert(str.eql("\r", "\x0d"));
assert(str.eql("\t", "\x09"));
assert(str.eql("\\", "\x5c"));
assert(str.eql("\u1234\u0069", "\xe1\x88\xb4\x69"));
}
#attribute("test")
2016-08-16 22:42:50 -07:00
fn ifVarMaybePointer() {
assert(shouldBeAPlus1(Particle {.a = 14, .b = 1, .c = 1, .d = 1}) == 15);
}
#static_eval_enable(false)
2016-08-16 22:42:50 -07:00
fn shouldBeAPlus1(p: Particle) -> u64 {
var maybe_particle: ?Particle = p;
if (const *particle ?= maybe_particle) {
particle.a += 1;
}
if (const particle ?= maybe_particle) {
return particle.a;
}
return 0;
}
struct Particle {
a: u64,
b: u64,
c: u64,
d: u64,
}
#attribute("test")
2016-08-16 22:42:50 -07:00
fn assignToIfVarPtr() {
var maybe_bool: ?bool = true;
if (const *b ?= maybe_bool) {
*b = false;
}
assert(??maybe_bool == false);
}
2016-05-04 18:19:49 -07:00
#attribute("test")
fn cmpxchg() {
var x: i32 = 1234;
while (!@cmpxchg(&x, 1234, 5678, AtomicOrder.SeqCst, AtomicOrder.SeqCst)) {}
assert(x == 5678);
}
2016-05-04 18:34:17 -07:00
#attribute("test")
fn fence() {
var x: i32 = 1234;
@fence(AtomicOrder.SeqCst);
x = 5678;
}
2016-05-06 15:02:02 -07:00
#attribute("test")
2016-08-16 22:42:50 -07:00
fn unsignedWrapping() {
testUnsignedWrappingEval(@maxValue(u32));
testUnsignedWrappingNoeval(@maxValue(u32));
2016-05-06 15:02:02 -07:00
}
2016-08-16 22:42:50 -07:00
fn testUnsignedWrappingEval(x: u32) {
const zero = x +% 1;
assert(zero == 0);
const orig = zero -% 1;
2016-08-16 22:42:50 -07:00
assert(orig == @maxValue(u32));
}
2016-05-06 15:02:02 -07:00
#static_eval_enable(false)
2016-08-16 22:42:50 -07:00
fn testUnsignedWrappingNoeval(x: u32) {
const zero = x +% 1;
assert(zero == 0);
const orig = zero -% 1;
2016-08-16 22:42:50 -07:00
assert(orig == @maxValue(u32));
2016-05-06 15:02:02 -07:00
}
#attribute("test")
2016-08-16 22:42:50 -07:00
fn signedWrapping() {
testSignedWrappingEval(@maxValue(i32));
testSignedWrappingNoeval(@maxValue(i32));
2016-05-06 15:02:02 -07:00
}
2016-08-16 22:42:50 -07:00
fn testSignedWrappingEval(x: i32) {
const min_val = x +% 1;
2016-08-16 22:42:50 -07:00
assert(min_val == @minValue(i32));
const max_val = min_val -% 1;
2016-08-16 22:42:50 -07:00
assert(max_val == @maxValue(i32));
}
2016-05-06 15:02:02 -07:00
#static_eval_enable(false)
2016-08-16 22:42:50 -07:00
fn testSignedWrappingNoeval(x: i32) {
const min_val = x +% 1;
2016-08-16 22:42:50 -07:00
assert(min_val == @minValue(i32));
const max_val = min_val -% 1;
2016-08-16 22:42:50 -07:00
assert(max_val == @maxValue(i32));
2016-05-06 15:02:02 -07:00
}
#attribute("test")
2016-08-16 22:42:50 -07:00
fn negationWrapping() {
testNegationWrappingEval(@minValue(i16));
testNegationWrappingNoeval(@minValue(i16));
2016-05-06 15:02:02 -07:00
}
2016-08-16 22:42:50 -07:00
fn testNegationWrappingEval(x: i16) {
assert(x == -32768);
const neg = -%x;
assert(neg == -32768);
}
2016-05-06 15:02:02 -07:00
#static_eval_enable(false)
2016-08-16 22:42:50 -07:00
fn testNegationWrappingNoeval(x: i16) {
assert(x == -32768);
const neg = -%x;
assert(neg == -32768);
2016-05-06 15:02:02 -07:00
}
#attribute("test")
2016-08-16 22:42:50 -07:00
fn shlWrapping() {
testShlWrappingEval(@maxValue(u16));
testShlWrappingNoeval(@maxValue(u16));
2016-05-06 15:02:02 -07:00
}
2016-08-16 22:42:50 -07:00
fn testShlWrappingEval(x: u16) {
const shifted = x <<% 1;
assert(shifted == 65534);
}
2016-05-06 15:02:02 -07:00
#static_eval_enable(false)
2016-08-16 22:42:50 -07:00
fn testShlWrappingNoeval(x: u16) {
const shifted = x <<% 1;
assert(shifted == 65534);
2016-05-06 15:02:02 -07:00
}
#attribute("test")
2016-08-16 22:42:50 -07:00
fn shlWithOverflow() {
var result: u16 = undefined;
2016-08-16 22:42:50 -07:00
assert(@shlWithOverflow(u16, 0b0010111111111111, 3, &result));
assert(!@shlWithOverflow(u16, 0b0010111111111111, 2, &result));
assert(result == 0b1011111111111100);
}
#attribute("test")
2016-08-16 22:42:50 -07:00
fn cStringConcatenation() {
const a = c"OK" ++ c" IT " ++ c"WORKED";
const b = c"OK IT WORKED";
2016-05-07 10:52:52 -07:00
const len = cstr.len(b);
const len_with_null = len + 1;
{var i: u32 = 0; while (i < len_with_null; i += 1) {
assert(a[i] == b[i]);
}}
assert(a[len] == 0);
assert(b[len] == 0);
}
#attribute("test")
2016-08-16 22:42:50 -07:00
fn genericStruct() {
var a1 = GenNode(i32) {.value = 13, .next = null,};
var b1 = GenNode(bool) {.value = true, .next = null,};
assert(a1.value == 13);
2016-08-16 22:42:50 -07:00
assert(a1.value == a1.getVal());
assert(b1.getVal());
}
struct GenNode(T: type) {
value: T,
next: ?&GenNode(T),
2016-08-16 22:42:50 -07:00
fn getVal(n: &const GenNode(T)) -> T { n.value }
}
2016-05-07 18:45:28 -07:00
#attribute("test")
2016-08-16 22:42:50 -07:00
fn castSliceToU8Slice() {
assert(@sizeOf(i32) == 4);
2016-05-07 18:45:28 -07:00
var big_thing_array = []i32{1, 2, 3, 4};
const big_thing_slice: []i32 = big_thing_array;
const bytes = ([]u8)(big_thing_slice);
assert(bytes.len == 4 * 4);
bytes[4] = 0;
bytes[5] = 0;
bytes[6] = 0;
bytes[7] = 0;
assert(big_thing_slice[1] == 0);
const big_thing_again = ([]i32)(bytes);
assert(big_thing_again[2] == 3);
big_thing_again[2] = -1;
2016-08-16 22:42:50 -07:00
assert(bytes[8] == @maxValue(u8));
assert(bytes[9] == @maxValue(u8));
assert(bytes[10] == @maxValue(u8));
assert(bytes[11] == @maxValue(u8));
2016-05-07 18:45:28 -07:00
}
2016-05-07 19:58:02 -07:00
#attribute("test")
2016-08-16 22:42:50 -07:00
fn floatDivision() {
2016-05-07 19:58:02 -07:00
assert(fdiv32(12.0, 3.0) == 4.0);
}
#static_eval_enable(false)
fn fdiv32(a: f32, b: f32) -> f32 {
a / b
}
2016-05-07 20:53:16 -07:00
#attribute("test")
2016-08-16 22:42:50 -07:00
fn exactDivision() {
assert(divExact(55, 11) == 5);
2016-05-07 20:53:16 -07:00
}
#static_eval_enable(false)
2016-08-16 22:42:50 -07:00
fn divExact(a: u32, b: u32) -> u32 {
@divExact(a, b)
2016-05-07 20:53:16 -07:00
}
2016-05-08 00:15:05 -07:00
#attribute("test")
2016-08-16 22:42:50 -07:00
fn nullLiteralOutsideFunction() {
const is_null = if (const _ ?= here_is_a_null_literal.context) false else true;
assert(is_null);
2016-05-08 00:15:05 -07:00
}
struct SillyStruct {
context: ?i32,
}
const here_is_a_null_literal = SillyStruct {
.context = null,
};
#attribute("test")
fn truncate() {
2016-08-16 22:42:50 -07:00
assert(testTruncate(0x10fd) == 0xfd);
}
#static_eval_enable(false)
2016-08-16 22:42:50 -07:00
fn testTruncate(x: u32) -> u8 {
@truncate(u8, x)
}
#attribute("test")
2016-08-16 22:42:50 -07:00
fn constDeclsInStruct() {
assert(GenericDataThing(3).count_plus_one == 4);
}
struct GenericDataThing(count: isize) {
const count_plus_one = count + 1;
}
#attribute("test")
2016-08-16 22:42:50 -07:00
fn useGenericParamInGenericParam() {
assert(aGenericFn(i32, 3, 4) == 7);
}
2016-08-16 22:42:50 -07:00
fn aGenericFn(inline T: type, inline a: T, b: T) -> T {
return a + b;
}
#attribute("test")
2016-08-16 22:42:50 -07:00
fn namespaceDependsOnCompileVar() {
if (some_namespace.a_bool) {
assert(some_namespace.a_bool);
} else {
assert(!some_namespace.a_bool);
}
}
2016-08-16 22:42:50 -07:00
const some_namespace = switch(@compileVar("os")) {
linux => @import("a.zig"),
else => @import("b.zig"),
};
2016-05-15 00:42:48 -07:00
#attribute("test")
2016-08-16 22:42:50 -07:00
fn unsigned64BitDivision() {
2016-05-15 00:42:48 -07:00
const result = div(1152921504606846976, 34359738365);
assert(result.quotient == 33554432);
assert(result.remainder == 100663296);
}
#static_eval_enable(false)
fn div(a: u64, b: u64) -> DivResult {
DivResult {
.quotient = a / b,
.remainder = a % b,
}
}
struct DivResult {
quotient: u64,
remainder: u64,
}
2016-05-15 01:05:24 -07:00
#attribute("test")
2016-08-16 22:42:50 -07:00
fn intTypeBuiltin() {
assert(@intType(true, 8) == i8);
assert(@intType(true, 16) == i16);
assert(@intType(true, 32) == i32);
assert(@intType(true, 64) == i64);
2016-08-16 22:42:50 -07:00
assert(@intType(false, 8) == u8);
assert(@intType(false, 16) == u16);
assert(@intType(false, 32) == u32);
assert(@intType(false, 64) == u64);
assert(i8.bit_count == 8);
assert(i16.bit_count == 16);
assert(i32.bit_count == 32);
assert(i64.bit_count == 64);
assert(i8.is_signed);
assert(i16.is_signed);
assert(i32.is_signed);
assert(i64.is_signed);
assert(isize.is_signed);
assert(!u8.is_signed);
assert(!u16.is_signed);
assert(!u32.is_signed);
assert(!u64.is_signed);
assert(!usize.is_signed);
2016-05-15 01:05:24 -07:00
}
#attribute("test")
2016-08-16 22:42:50 -07:00
fn intToEnum() {
testIntToEnumEval(3);
testIntToEnumNoeval(3);
}
2016-08-16 22:42:50 -07:00
fn testIntToEnumEval(x: i32) {
assert(IntToEnumNumber(x) == IntToEnumNumber.Three);
}
#static_eval_enable(false)
2016-08-16 22:42:50 -07:00
fn testIntToEnumNoeval(x: i32) {
assert(IntToEnumNumber(x) == IntToEnumNumber.Three);
}
enum IntToEnumNumber {
Zero,
One,
Two,
Three,
Four,
}