123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553 |
- const std = @import("std") ;
- const expect = std.testing.expect;
- // By specifying explicitly.
- const constant: i32 = 5 ;
- var variable : u32 = 5000 ;
- // From right value type.
- const inferred_constant = @as(i32, 5) ;
- var inferred_variable = @as(i32, 5000) ;
- const a1 = [5]u8{'h', 'e', 'l', 'l', 'o'} ;
- const a2 = [5]u8{'w', 'o', 'r', 'l', 'd'} ;
- const a2_length = a2.len ;
- pub fn main() void {
- std.debug.print("Hello, {s}!\n", .{"World"});
- }
- test "always succeeds" {
- std.debug.print("value\n", .{});
- try expect(true);
- }
- test "if statement" {
- const a = true ;
- var x: u16 = 0 ;
- if (a) {
- x += 1 ;
- } else {
- x += 2 ;
- }
- try expect(x == 1) ;
- }
- test "if statement expression" {
- const a = true ;
- var x: u16 = 0 ;
- x += if (a) 1 else 2 ;
- try expect(x == 1) ;
- }
- test "while" {
- var i: u8 = 2 ;
- while (i < 100) {
- i *= 2 ;
- }
- try expect(i == 128) ;
- }
- test "while with continue expression" {
- var sum: u8 = 0 ;
- var i: u8 = 1 ;
- while (i <= 10) : (i +=1) {
- sum += i ;
- }
- try expect(sum == 55) ;
- }
- test "while with continue" {
- var sum: u8 = 0 ;
- var i: u8 = 0 ;
- while (i <= 3) : (i += 1) {
- if (i == 2) continue ;
- sum += i ;
- }
- try expect(sum == 4) ;
- }
- test "while with break" {
- var sum: u8 = 0 ;
- var i: u8 = 0 ;
- while (i <= 3) : (i += 1) {
- if (i == 2) break ;
- sum += i ;
- }
- try expect(sum == 1) ;
- }
- test "for" {
- const string = [_]u8{'a', 'b', 'c'} ;
- for (string, 0..) |character, index| {
- _ = character ;
- _ = index ;
- }
- for (string) |character| {
- _ = character ;
- }
- for (string, 0..) |_, index| {
- _ = index ;
- }
- for (string) |_| {
- }
- }
- fn addFive(x : u32) u32 {
- return x + 5 ;
- }
- test "function" {
- const y = addFive(0) ;
- try expect(@TypeOf(y) == u32) ;
- std.debug.print("{d}\n", .{y});
- try expect(y == 5) ;
- }
- fn fibo(n: u16) u16 {
- if (n == 0 or n == 1) return n ;
- return fibo(n-1) + fibo(n - 2) ;
- }
- test "function recursion" {
- const x = fibo(10) ;
- try expect(x == 55) ;
- }
- test "defer" {
- var x: f32 = 5 ;
- {
- defer x += 2 ;
- try expect(x == 5) ;
- }
- try expect(x == 7) ;
- }
- test "multi defer" {
- var x: f32 = 5 ;
- {
- defer x += 2 ;
- defer x /= 2 ;
- }
- try expect(x == 4.5) ;
- }
- const FileOpenError = error{
- AccessDenied,
- OutOfMemory,
- FileNotFond,
- };
- const AllocationError = error{OutOfMemory} ;
- test "coerce error from a subset to a superset" {
- const err: FileOpenError = AllocationError.OutOfMemory;
- try expect(err == FileOpenError.OutOfMemory) ;
- }
- test "error union" {
- const maybe_error: AllocationError!u16 = 10 ;
- const no_error = maybe_error catch 0 ;
- try expect(@TypeOf(no_error) == u16) ;
- try expect(no_error == 10) ;
- }
- fn failingFunction() error{Oops}!void {
- return error.Oops ;
- }
- test "returning an error" {
- failingFunction() catch |err| {
- try expect(err == error.Oops) ;
- return;
- } ;
- }
- fn failFn() error{Oops}!i32 {
- try failingFunction() ;
- return 12 ;
- }
- test "try" {
- const v = failFn() catch |err| {
- try expect(err == error.Oops);
- return;
- };
- try expect(v == 12) ;
- }
- var problems: u32 = 98 ;
- fn failFnCounter() error{Oops}!void {
- errdefer problems += 1 ;
- try failingFunction();
- }
- test "errdefer" {
- failFnCounter() catch |err| {
- try expect(err == error.Oops) ;
- try expect(problems == 99);
- return;
- };
- }
- fn createFile() !void {
- return error.AccessDenied ;
- }
- test "inferred error set" {
- const x: error{AccessDenied}!void = createFile() ;
- _ = x catch {} ;
- }
- const a_err = error{NotDir, PathNotFound} ;
- const b_err = error{ OutOfMemory, PathNotFound} ;
- const c_err = a_err || b_err ;
- test "switch statement" {
- var x: i8 = 10 ;
- switch (x) {
- -1...1 => {
- x = -x ;
- },
- 10, 100 => {
- // Check out special
- // requirements when dividing signed
- // integers.
- x = @divExact(x, 10) ;
- },
- else => {},
- }
- try expect(x == 1) ;
- }
- test "switch expression" {
- var x: i8 = 10 ;
- x = switch(x) {
- -1...1 => -x,
- 10, 100 => @divExact(x, 10),
- else => x,
- };
- try expect(x == 1) ;
- }
- test "out of bounds" {
- //const a = [3]u8{ 1, 2, 3 } ;
- //var index: u8 = 5 ;
- //index = index ;
- // The code below will call ""index out of bounds" error.
- // const b = a[index] ;
- // _ = b ;
- }
- test "out of bounds, no safety" {
- @setRuntimeSafety(false);
- const a = [3]u8{ 1, 2, 3 } ;
- var index: u8 = 5 ;
- index = index ;
- // The code below will call ""index out of bounds" error.
- const b = a[index] ;
- _ = b ;
- }
- test "unreachable" {
- //const x: i32 = 1 ;
- // The code below will cause the "reached unreachable code".
- //const y: u32 = if (x == 2) 5 else unreachable ;
- //_ = y ;
- }
- fn asciiToUpper(x: u8) u8 {
- return switch (x) {
- 'a'...'z' => x + 'A' - 'a',
- 'A'...'Z' => x,
- else => unreachable,
- } ;
- }
- test "unreachable switch" {
- try expect(asciiToUpper('a') == 'A') ;
- try expect(asciiToUpper('A') == 'A') ;
- }
- fn increment(num: *u8) void {
- num.* += 1 ;
- }
- test "pointers" {
- var x: u8 = 1 ;
- increment(&x);
- try expect(x == 2) ;
- }
- test "naughty pointer" {
- const x: u8 = 1 ;
- const y: *u8 = @ptrFromInt(x);
- _ = y ;
- }
- test "constant pointers" {
- //const x: u8 = 1 ;
- // does not work for now.
- //var y = &x ;
- //y.* += 1 ;
- }
- test "usize" {
- try expect(@sizeOf(usize) == @sizeOf(*u8)) ;
- try expect(@sizeOf(isize) == @sizeOf(*u8)) ;
- }
- fn total(values: []const u8) usize {
- var sum: usize = 0 ;
- for (values) |v|
- sum += v ;
- return sum ;
- }
- test "slices" {
- const array = [_]u8{ 1, 2, 3, 4, 5 } ;
- const slice = array[0..3] ;
- try expect(total(slice) == 6) ;
- }
- test "slices 2" {
- const array = [_]u8{ 1, 2, 3, 4, 5 } ;
- const slice = array[0..3] ;
- try expect(@TypeOf(slice) == *const [3]u8) ;
- }
- test "slices 3" {
- var array = [_]u8{ 1, 2, 3, 4, 5 } ;
- const slice = array[0..] ;
- _ = slice ;
- }
- const Direction = enum{
- north,
- south,
- east,
- west,
- } ;
- const Value = enum(u2) {zero, one, two} ;
- test "enum ordinal value" {
- try expect(@intFromEnum(Value.zero) == 0) ;
- try expect(@intFromEnum(Value.one) == 1) ;
- try expect(@intFromEnum(Value.two) == 2) ;
- }
- const Value2 = enum(u32) {
- hundred = 100,
- thousand = 1000,
- million = 1000000,
- next,
- } ;
- test "set enum ordinal value" {
- try expect(@intFromEnum(Value2.hundred) == 100) ;
- try expect(@intFromEnum(Value2.thousand) == 1000) ;
- try expect(@intFromEnum(Value2.million) == 1000000) ;
- }
- const Suit = enum {
- clubs,
- spades,
- diamonds,
- hearts,
- pub fn isClubs(self: Suit) bool {
- return self == Suit.clubs ;
- }
- } ;
- test "enum method" {
- try expect(
- Suit.spades.isClubs() ==
- Suit.isClubs(.spades),
- ) ;
- }
- const Mode = enum {
- var count: u32 = 0 ;
- on,
- off,
- };
- test "hmm" {
- Mode.count += 1 ;
- try expect(Mode.count == 1) ;
- }
- // Structs.
- const Vec3 = struct{
- x : f32,
- y : f32,
- z : f32,
- } ;
- test "struct usage" {
- const my_vector = Vec3{
- .x = 0,
- .y = 100,
- .z = 50,
- } ;
- _ = my_vector ;
- }
- test "missing struct field" {
- //const my_vector = Vec3{
- //.x = 0,
- //.z = 50,
- //} ;
- //_ = my_vector ;
- }
- const Vec2 = struct{
- x: i32 = 0,
- y: i32 = 0,
- } ;
- test "struct defaults" {
- const my_vector = Vec2{
- .x = 25,
- } ;
- try expect(my_vector.y == 0) ;
- }
- const Stuff = struct{
- x: i32,
- y: i32,
- fn swap(self: *Stuff) void {
- const tmp = self.x;
- self.x = self.y ;
- self.y = tmp ;
- }
- } ;
- test "automatic dereference" {
- var thing = Stuff{
- .x = 10,
- .y = 20,
- } ;
- thing.swap();
- try expect(
- thing.x == 20 and
- thing.y == 10,
- ) ;
- }
- const Result = union{
- int: i64,
- float: f64,
- bool: bool,
- } ;
- test "simple union" {
- const result = Result{
- .int = 1234,
- } ;
- // error
- //result.float = 12.34 ;
- _ = result ;
- }
- const Tag = enum{a, b, c} ;
- const Tagged = union(Tag){
- a: u8,
- b: f32,
- c: bool,
- } ;
- test "switch on tagged union" {
- var value = Tagged{ .b = 1.5} ;
- switch (value) {
- .a => |*byte| byte.* += 1,
- .b => |*float| float.* *= 2,
- .c => |*b| b.* = !(b.*),
- }
- try expect(value.b == 3) ;
- }
- test "labeled blocks" {
- const count = blk: {
- var sum: u32 = 0 ;
- var i: u32 = 0 ;
- while (i < 10) : ({
- i += 1;
- }) {
- sum += i ;
- }
- break :blk sum ;
- } ;
- try expect(count == 45) ;
- try expect(@TypeOf(count) == u32) ;
- }
- test "nested continue" {
- var count: usize = 0;
- outer: for ([_]i32{ 1, 2, 3, 4, 5, 6, 7, 8 }) |_| {
- for ([_]i32{ 1, 2, 3, 4, 5 }) |_| {
- count += 1;
- continue :outer;
- }
- }
- try expect(count == 8);
- }
- fn rangeHasNumber(begin: usize, end: usize, number: usize) bool {
- var i = begin;
- return while (i < end) : (i += 1) {
- if (i == number) {
- break true;
- }
- } else false;
- }
- test "while loop expression" {
- try expect(rangeHasNumber(0, 10, 3));
- }
- test "if optional payload capture" {
- const a: ?i32 = 5;
- if (a != null) {
- const value = a.?;
- _ = value;
- }
- var b: ?i32 = 5;
- if (b) |*value| {
- value.* += 1;
- }
- try expect(b.? == 6);
- }
- var numbers_left: u32 = 4;
- fn eventuallyNullSequence() ?u32 {
- if (numbers_left == 0) return null;
- numbers_left -= 1;
- return numbers_left;
- }
- test "while null capture" {
- var sum: u32 = 0;
- while (eventuallyNullSequence()) |value| {
- sum += value;
- }
- try expect(sum == 6); // 3 + 2 + 1
- }
|