From bcb18338cd15dfd7a4e3e80e74d1fe395870fa48 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 24 Jan 2016 22:53:00 -0700 Subject: [PATCH] update std lib to use error type and global variables --- example/guess_number/main.zig | 34 +-- example/hello_world/hello.zig | 3 +- example/multiple_files/foo.zig | 2 +- example/multiple_files/main.zig | 2 +- example/shared_library/mathtest.zig | 6 +- src/analyze.cpp | 4 + src/codegen.cpp | 43 +++- std/std.zig | 119 ++++----- std/syscall.zig | 14 +- test/run_tests.cpp | 370 ++++++++++++++-------------- 10 files changed, 295 insertions(+), 302 deletions(-) diff --git a/example/guess_number/main.zig b/example/guess_number/main.zig index f770704dab..1edbda5c69 100644 --- a/example/guess_number/main.zig +++ b/example/guess_number/main.zig @@ -3,45 +3,33 @@ export executable "guess_number"; import "std.zig"; import "rand.zig"; -error GetRandomFail; -error ReadInputFail; - pub fn main(args: [][]u8) %void => { - print_str("Welcome to the Guess Number Game in Zig.\n"); + stderr.print_str("Welcome to the Guess Number Game in Zig.\n"); var seed : u32; - const seed_bytes = (&u8)(&seed)[0...@sizeof(u32)]; - const err = os_get_random_bytes(seed_bytes); - if (err != @sizeof(u32)) { - // TODO full error message - fprint_str(stderr_fileno, "unable to get random bytes\n"); - return error.GetRandomFail; - } + const seed_bytes = (&u8)(&seed)[0...4]; + os_get_random_bytes(seed_bytes); var rand = rand_new(seed); const answer = rand.range_u64(0, 100) + 1; while (true) { - print_str("\nGuess a number between 1 and 100: "); + stderr.print_str("\nGuess a number between 1 and 100: "); var line_buf : [20]u8; - var line_len : isize; - // TODO fix this awkward error handling - if (readline(line_buf, &line_len) || line_len == line_buf.len) { - // TODO full error message - fprint_str(stderr_fileno, "unable to read input\n"); - return error.ReadInputFail; - } + + // TODO print error message instead of returning + const line_len = %return stdin.readline(line_buf); var guess : u64; if (parse_u64(line_buf[0...line_len - 1], 10, &guess)) { - print_str("Invalid number format.\n"); + stderr.print_str("Invalid number format.\n"); } else if (guess > answer) { - print_str("Guess lower.\n"); + stderr.print_str("Guess lower.\n"); } else if (guess < answer) { - print_str("Guess higher.\n"); + stderr.print_str("Guess higher.\n"); } else { - print_str("You win!\n"); + stderr.print_str("You win!\n"); return; } } diff --git a/example/hello_world/hello.zig b/example/hello_world/hello.zig index c116eeea7b..42c72e6fb2 100644 --- a/example/hello_world/hello.zig +++ b/example/hello_world/hello.zig @@ -3,6 +3,5 @@ export executable "hello"; import "std.zig"; pub fn main(args: [][]u8) %void => { - //stderr.print_str("Hello, world!\n"); - print_str("Hello, world!\n"); + stdout.printf("Hello, world!\n"); } diff --git a/example/multiple_files/foo.zig b/example/multiple_files/foo.zig index 2ab13b2457..c4e39c36d6 100644 --- a/example/multiple_files/foo.zig +++ b/example/multiple_files/foo.zig @@ -3,7 +3,7 @@ import "std.zig"; // purposefully conflicting function with main.zig // but it's private so it should be OK fn private_function() => { - print_str("OK 1\n"); + stdout.printf("OK 1\n"); } pub fn print_text() => { diff --git a/example/multiple_files/main.zig b/example/multiple_files/main.zig index f7c2cbba30..57a8c600a1 100644 --- a/example/multiple_files/main.zig +++ b/example/multiple_files/main.zig @@ -5,7 +5,7 @@ import "foo.zig"; pub fn main(args: [][]u8) i32 => { private_function(); - print_str("OK 2\n"); + stdout.printf("OK 2\n"); return 0; } diff --git a/example/shared_library/mathtest.zig b/example/shared_library/mathtest.zig index b513f9cee4..92bef37fbd 100644 --- a/example/shared_library/mathtest.zig +++ b/example/shared_library/mathtest.zig @@ -1,10 +1,10 @@ #version("2.0.0") export library "mathtest"; -export fn add(a: i32, b: i32) -> i32 { +export fn add(a: i32, b: i32) i32 => { a + b } -export fn hang() -> unreachable { -entry: goto entry; +export fn hang() unreachable => { + while (true) { } } diff --git a/src/analyze.cpp b/src/analyze.cpp index 9e0d315c0a..6a81ad8047 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -3058,6 +3058,7 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B if (wanted_type->id == TypeTableEntryIdMaybe) { if (types_match_const_cast_only(wanted_type->data.maybe.child_type, actual_type)) { node->data.fn_call_expr.cast_op = CastOpMaybeWrap; + context->cast_alloca_list.append(node); eval_const_expr_implicit_cast(g, node, expr_node); return wanted_type; } else if (actual_type->id == TypeTableEntryIdNumLitInt || @@ -3065,6 +3066,7 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B { if (num_lit_fits_in_other_type(g, expr_node, wanted_type->data.maybe.child_type)) { node->data.fn_call_expr.cast_op = CastOpMaybeWrap; + context->cast_alloca_list.append(node); eval_const_expr_implicit_cast(g, node, expr_node); return wanted_type; } else { @@ -3077,6 +3079,7 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B if (wanted_type->id == TypeTableEntryIdErrorUnion) { if (types_match_const_cast_only(wanted_type->data.error.child_type, actual_type)) { node->data.fn_call_expr.cast_op = CastOpErrorWrap; + context->cast_alloca_list.append(node); eval_const_expr_implicit_cast(g, node, expr_node); return wanted_type; } else if (actual_type->id == TypeTableEntryIdNumLitInt || @@ -3084,6 +3087,7 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B { if (num_lit_fits_in_other_type(g, expr_node, wanted_type->data.error.child_type)) { node->data.fn_call_expr.cast_op = CastOpErrorWrap; + context->cast_alloca_list.append(node); eval_const_expr_implicit_cast(g, node, expr_node); return wanted_type; } else { diff --git a/src/codegen.cpp b/src/codegen.cpp index 01771f96b9..3497bbdee2 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -325,11 +325,28 @@ static LLVMValueRef gen_cast_expr(CodeGen *g, AstNode *node) { return cast_expr->tmp_ptr; } case CastOpErrorWrap: - assert(wanted_type->id == TypeTableEntryIdErrorUnion); - if (wanted_type->data.error.child_type->size_in_bits == 0) { - return LLVMConstNull(g->err_tag_type->type_ref); - } else { - zig_panic("TODO"); + { + assert(wanted_type->id == TypeTableEntryIdErrorUnion); + TypeTableEntry *child_type = wanted_type->data.error.child_type; + LLVMValueRef ok_err_val = LLVMConstNull(g->err_tag_type->type_ref); + + if (child_type->size_in_bits == 0) { + return ok_err_val; + } else { + assert(cast_expr->tmp_ptr); + assert(wanted_type->id == TypeTableEntryIdErrorUnion); + assert(actual_type); + + add_debug_source_node(g, node); + LLVMValueRef err_tag_ptr = LLVMBuildStructGEP(g->builder, cast_expr->tmp_ptr, 0, ""); + LLVMBuildStore(g->builder, ok_err_val, err_tag_ptr); + + LLVMValueRef payload_ptr = LLVMBuildStructGEP(g->builder, cast_expr->tmp_ptr, 1, ""); + gen_assign_raw(g, node, BinOpTypeAssign, + payload_ptr, expr_val, child_type, actual_type); + + return cast_expr->tmp_ptr; + } } case CastOpPureErrorWrap: assert(wanted_type->id == TypeTableEntryIdErrorUnion); @@ -1286,12 +1303,16 @@ static LLVMValueRef gen_return_expr(CodeGen *g, AstNode *node) { if (return_type->id == TypeTableEntryIdPureError) { gen_return(g, node, err_val); } else if (return_type->id == TypeTableEntryIdErrorUnion) { - assert(g->cur_ret_ptr); + if (return_type->data.error.child_type->size_in_bits > 0) { + assert(g->cur_ret_ptr); - add_debug_source_node(g, node); - LLVMValueRef tag_ptr = LLVMBuildStructGEP(g->builder, g->cur_ret_ptr, 0, ""); - LLVMBuildStore(g->builder, err_val, tag_ptr); - LLVMBuildRetVoid(g->builder); + add_debug_source_node(g, node); + LLVMValueRef tag_ptr = LLVMBuildStructGEP(g->builder, g->cur_ret_ptr, 0, ""); + LLVMBuildStore(g->builder, err_val, tag_ptr); + LLVMBuildRetVoid(g->builder); + } else { + gen_return(g, node, err_val); + } } else { zig_unreachable(); } @@ -2011,7 +2032,7 @@ static LLVMValueRef gen_switch_expr(CodeGen *g, AstNode *node) { LLVMPositionBuilderAtEnd(g->builder, end_block); add_debug_source_node(g, node); - LLVMValueRef phi = LLVMBuildPhi(g->builder, get_expr_type(node)->type_ref, ""); + LLVMValueRef phi = LLVMBuildPhi(g->builder, LLVMTypeOf(incoming_values.at(0)), ""); LLVMAddIncoming(phi, incoming_values.items, incoming_blocks.items, incoming_values.length); return phi; diff --git a/std/std.zig b/std/std.zig index 8cc75a30fe..83ae7d9f57 100644 --- a/std/std.zig +++ b/std/std.zig @@ -5,7 +5,6 @@ pub const stdin_fileno = 0; pub const stdout_fileno = 1; pub const stderr_fileno = 2; -/* pub var stdin = InStream { .fd = stdin_fileno, }; @@ -23,9 +22,16 @@ pub var stderr = OutStream { .index = 0, .buffered = false, }; -*/ +/// The function received invalid input at runtime. An Invalid error means a +/// bug in the program that called the function. +pub error Invalid; + +/// When an Unexpected error occurs, code that emitted the error likely needs +/// a patch to recognize the unexpected case so that it can handle it and emit +/// a more specific error. pub error Unexpected; + pub error DiskQuota; pub error FileTooBig; pub error SigInterrupt; @@ -33,26 +39,25 @@ pub error Io; pub error NoSpaceLeft; pub error BadPerm; pub error PipeFail; -pub error Invalid; +pub error BadFd; const buffer_size = 4 * 1024; const max_u64_base10_digits = 20; -/* pub struct OutStream { fd: isize, buffer: [buffer_size]u8, - index: @typeof(buffer_size), + index: isize, buffered: bool, pub fn print_str(os: &OutStream, str: []const u8) %isize => { var src_bytes_left = str.len; var src_index: @typeof(str.len) = 0; - const dest_space_left = os.buffer.len - index; + const dest_space_left = os.buffer.len - os.index; while (src_bytes_left > 0) { const copy_amt = min_isize(dest_space_left, src_bytes_left); - @memcpy(&buffer[os.index], &str[src_index], copy_amt); + @memcpy(&os.buffer[os.index], &str[src_index], copy_amt); os.index += copy_amt; if (os.index == os.buffer.len) { %return os.flush(); @@ -65,11 +70,19 @@ pub struct OutStream { return str.len; } + /// Prints a byte buffer, flushes the buffer, then returns the number of + /// bytes printed. The "f" is for "flush". + pub fn printf(os: &OutStream, str: []const u8) %isize => { + const byte_count = %return os.print_str(str); + %return os.flush(); + return byte_count; + } + pub fn print_u64(os: &OutStream, x: u64) %isize => { if (os.index + max_u64_base10_digits >= os.buffer.len) { %return os.flush(); } - const amt_printed = buf_print_u64(buf[os.index...], x); + const amt_printed = buf_print_u64(os.buffer[os.index...], x); os.index += amt_printed; if (!os.buffered) { @@ -84,7 +97,7 @@ pub struct OutStream { if (os.index + max_u64_base10_digits >= os.buffer.len) { %return os.flush(); } - const amt_printed = buf_print_i64(buf[os.index...], x); + const amt_printed = buf_print_i64(os.buffer[os.index...], x); os.index += amt_printed; if (!os.buffered) { @@ -96,18 +109,20 @@ pub struct OutStream { pub fn flush(os: &OutStream) %void => { - const amt_to_write = os.index; + const amt_written = write(os.fd, os.buffer.ptr, os.index); os.index = 0; - switch (write(os.fd, os.buffer.ptr, amt_to_write)) { - EINVAL => unreachable{}, - EDQUOT => error.DiskQuota, - EFBIG => error.FileTooBig, - EINTR => error.SigInterrupt, - EIO => error.Io, - ENOSPC => error.NoSpaceLeft, - EPERM => error.BadPerm, - EPIPE => error.PipeFail, - else => error.Unexpected, + if (amt_written < 0) { + return switch (-amt_written) { + EINVAL => unreachable{}, + EDQUOT => error.DiskQuota, + EFBIG => error.FileTooBig, + EINTR => error.SigInterrupt, + EIO => error.Io, + ENOSPC => error.NoSpaceLeft, + EPERM => error.BadPerm, + EPIPE => error.PipeFail, + else => error.Unexpected, + } } } } @@ -115,10 +130,10 @@ pub struct OutStream { pub struct InStream { fd: isize, - pub fn readline(buf: []u8) %isize => { - const amt_read = read(stdin_fileno, buf.ptr, buf.len); + pub fn readline(is: &InStream, buf: []u8) %isize => { + const amt_read = read(is.fd, buf.ptr, buf.len); if (amt_read < 0) { - switch (-amt_read) { + return switch (-amt_read) { EINVAL => unreachable{}, EFAULT => unreachable{}, EBADF => error.BadFd, @@ -133,54 +148,16 @@ pub struct InStream { } pub fn os_get_random_bytes(buf: []u8) %void => { - switch (getrandom(buf.ptr, buf.len, 0)) { - EINVAL => unreachable{}, - EFAULT => unreachable{}, - EINTR => error.SigInterrupt, - else => error.Unexpected, + const amt_got = getrandom(buf.ptr, buf.len, 0); + if (amt_got < 0) { + return switch (-amt_got) { + EINVAL => unreachable{}, + EFAULT => unreachable{}, + EINTR => error.SigInterrupt, + else => error.Unexpected, + } } } -*/ - - -// TODO remove this -pub fn print_str(str: []const u8) isize => { - fprint_str(stdout_fileno, str) -} - -// TODO remove this -pub fn fprint_str(fd: isize, str: []const u8) isize => { - write(fd, str.ptr, str.len) -} - -// TODO remove this -pub fn os_get_random_bytes(buf: []u8) isize => { - getrandom(buf.ptr, buf.len, 0) -} - -// TODO remove this -pub fn print_u64(x: u64) isize => { - var buf: [max_u64_base10_digits]u8; - const len = buf_print_u64(buf, x); - return write(stdout_fileno, buf.ptr, len); -} - -// TODO remove this -pub fn print_i64(x: i64) isize => { - var buf: [max_u64_base10_digits]u8; - const len = buf_print_i64(buf, x); - return write(stdout_fileno, buf.ptr, len); -} - -// TODO remove this -pub fn readline(buf: []u8, out_len: &isize) bool => { - const amt_read = read(stdin_fileno, buf.ptr, buf.len); - if (amt_read < 0) { - return true; - } - *out_len = isize(amt_read); - return false; -} // TODO return %u64 when we support errors @@ -251,3 +228,7 @@ fn buf_print_u64(out_buf: []u8, x: u64) isize => { return len; } + +fn min_isize(x: isize, y: isize) isize => { + if (x < y) x else y +} diff --git a/std/syscall.zig b/std/syscall.zig index 43a1c8a6f9..9768ab710d 100644 --- a/std/syscall.zig +++ b/std/syscall.zig @@ -1,7 +1,7 @@ -const SYS_read : isize = 0; -const SYS_write : isize = 1; -const SYS_exit : isize = 60; -const SYS_getrandom : isize = 318; +const SYS_read = 0; +const SYS_write = 1; +const SYS_exit = 60; +const SYS_getrandom = 318; fn syscall1(number: isize, arg1: isize) isize => { asm volatile ("syscall" @@ -18,11 +18,11 @@ fn syscall3(number: isize, arg1: isize, arg2: isize, arg3: isize) isize => { } pub fn read(fd: isize, buf: &u8, count: isize) isize => { - isize(syscall3(SYS_read, isize(fd), isize(buf), count)) + syscall3(SYS_read, isize(fd), isize(buf), count) } pub fn write(fd: isize, buf: &const u8, count: isize) isize => { - isize(syscall3(SYS_write, isize(fd), isize(buf), count)) + syscall3(SYS_write, isize(fd), isize(buf), count) } pub fn exit(status: i32) unreachable => { @@ -31,5 +31,5 @@ pub fn exit(status: i32) unreachable => { } pub fn getrandom(buf: &u8, count: isize, flags: u32) isize => { - isize(syscall3(SYS_getrandom, isize(buf), count, isize(flags))) + syscall3(SYS_getrandom, isize(buf), count, isize(flags)) } diff --git a/test/run_tests.cpp b/test/run_tests.cpp index 684ec820d7..39c6e6c8e1 100644 --- a/test/run_tests.cpp +++ b/test/run_tests.cpp @@ -121,7 +121,7 @@ pub fn main(args: [][]u8) %void => { } fn this_is_a_function() unreachable => { - print_str("OK\n"); + stdout.printf("OK\n"); exit(0); } )SOURCE", "OK\n"); @@ -137,7 +137,7 @@ fn another_function() => {} /// this is a documentation comment /// doc comment line 2 pub fn main(args: [][]u8) %void => { - print_str(/* mid-line comment /* nested */ */ "OK\n"); + stdout.printf(/* mid-line comment /* nested */ */ "OK\n"); } )SOURCE", "OK\n"); @@ -148,7 +148,7 @@ import "foo.zig"; pub fn main(args: [][]u8) %void => { private_function(); - print_str("OK 2\n"); + stdout.printf("OK 2\n"); } fn private_function() => { @@ -162,7 +162,7 @@ import "std.zig"; // purposefully conflicting function with main.zig // but it's private so it should be OK fn private_function() => { - print_str("OK 1\n"); + stdout.printf("OK 1\n"); } pub fn print_text() => { @@ -185,7 +185,7 @@ pub fn main(args: [][]u8) %void => { add_source_file(tc, "foo.zig", R"SOURCE( import "std.zig"; pub fn foo_function() => { - print_str("OK\n"); + stdout.printf("OK\n"); } )SOURCE"); @@ -195,7 +195,7 @@ import "std.zig"; pub fn bar_function() => { if (foo_function()) { - print_str("OK\n"); + stdout.printf("OK\n"); } } )SOURCE"); @@ -213,17 +213,17 @@ import "std.zig"; pub fn main(args: [][]u8) %void => { if (1 != 0) { - print_str("1 is true\n"); + stdout.printf("1 is true\n"); } else { - print_str("1 is false\n"); + stdout.printf("1 is false\n"); } if (0 != 0) { - print_str("0 is true\n"); + stdout.printf("0 is true\n"); } else if (1 - 1 != 0) { - print_str("1 - 1 is true\n"); + stdout.printf("1 - 1 is true\n"); } if (!(0 != 0)) { - print_str("!0 is true\n"); + stdout.printf("!0 is true\n"); } } )SOURCE", "1 is true\n!0 is true\n"); @@ -237,7 +237,7 @@ fn add(a: i32, b: i32) i32 => { pub fn main(args: [][]u8) %void => { if (add(22, 11) == 33) { - print_str("pass\n"); + stdout.printf("pass\n"); } } )SOURCE", "pass\n"); @@ -249,7 +249,7 @@ fn loop(a : i32) => { if (a == 0) { goto done; } - print_str("loop\n"); + stdout.printf("loop\n"); loop(a - 1); done: @@ -268,7 +268,7 @@ pub fn main(args: [][]u8) %void => { const a : i32 = 1; const b = i32(2); if (a + b == 3) { - print_str("OK\n"); + stdout.printf("OK\n"); } } )SOURCE", "OK\n"); @@ -277,10 +277,10 @@ pub fn main(args: [][]u8) %void => { import "std.zig"; pub fn main(args: [][]u8) %void => { - if (true) { print_str("OK 1\n"); } - if (false) { print_str("BAD 1\n"); } - if (!true) { print_str("BAD 2\n"); } - if (!false) { print_str("OK 2\n"); } + if (true) { stdout.printf("OK 1\n"); } + if (false) { stdout.printf("BAD 1\n"); } + if (!true) { stdout.printf("BAD 2\n"); } + if (!false) { stdout.printf("OK 2\n"); } } )SOURCE", "OK 1\nOK 2\n"); @@ -290,14 +290,14 @@ import "std.zig"; pub fn main(args: [][]u8) %void => { if (true) { const no_conflict : i32 = 5; - if (no_conflict == 5) { print_str("OK 1\n"); } + if (no_conflict == 5) { stdout.printf("OK 1\n"); } } const c = { const no_conflict = i32(10); no_conflict }; - if (c == 10) { print_str("OK 2\n"); } + if (c == 10) { stdout.printf("OK 2\n"); } } )SOURCE", "OK 1\nOK 2\n"); @@ -311,7 +311,7 @@ pub fn main(args: [][]u8) %void => { fn void_fun(a : i32, b : void, c : i32) => { const v = b; const vv : void = if (a == 1) {v} else {}; - if (a + c == 3) { print_str("OK\n"); } + if (a + c == 3) { stdout.printf("OK\n"); } return vv; } )SOURCE", "OK\n"); @@ -330,12 +330,12 @@ pub fn main(args: [][]u8) %void => { .c = void{}, }; if (foo.b != 1) { - print_str("BAD\n"); + stdout.printf("BAD\n"); } if (@sizeof(Foo) != 4) { - print_str("BAD\n"); + stdout.printf("BAD\n"); } - print_str("OK\n"); + stdout.printf("OK\n"); } )SOURCE", "OK\n"); @@ -348,12 +348,12 @@ pub fn main(args: [][]u8) %void => { array[0] = void{}; array[1] = array[2]; if (@sizeof(@typeof(array)) != 0) { - print_str("BAD\n"); + stdout.printf("BAD\n"); } if (array.len != 4) { - print_str("BAD\n"); + stdout.printf("BAD\n"); } - print_str("OK\n"); + stdout.printf("OK\n"); } )SOURCE", "OK\n"); @@ -363,11 +363,11 @@ import "std.zig"; pub fn main(args: [][]u8) %void => { var zero : i32 = 0; - if (zero == 0) { print_str("zero\n"); } + if (zero == 0) { stdout.printf("zero\n"); } var i = i32(0); while (i != 3) { - print_str("loop\n"); + stdout.printf("loop\n"); i += 1; } } @@ -394,11 +394,11 @@ pub fn main(args: [][]u8) %void => { } if (accumulator == 15) { - print_str("OK\n"); + stdout.printf("OK\n"); } if (get_array_len(array) != 5) { - print_str("BAD\n"); + stdout.printf("BAD\n"); } } fn get_array_len(a: []i32) isize => { @@ -411,7 +411,7 @@ fn get_array_len(a: []i32) isize => { import "std.zig"; pub fn main(args: [][]u8) %void => { - print_str("Hello, world!\n"); + stdout.printf("Hello, world!\n"); } )SOURCE", "Hello, world!\n"); @@ -420,20 +420,20 @@ pub fn main(args: [][]u8) %void => { import "std.zig"; pub fn main(args: [][]u8) %void => { - if (false || false || false) { print_str("BAD 1\n"); } - if (true && true && false) { print_str("BAD 2\n"); } - if (1 | 2 | 4 != 7) { print_str("BAD 3\n"); } - if (3 ^ 6 ^ 8 != 13) { print_str("BAD 4\n"); } - if (7 & 14 & 28 != 4) { print_str("BAD 5\n"); } - if (9 << 1 << 2 != 9 << 3) { print_str("BAD 6\n"); } - if (90 >> 1 >> 2 != 90 >> 3) { print_str("BAD 7\n"); } - if (100 - 1 + 1000 != 1099) { print_str("BAD 8\n"); } - if (5 * 4 / 2 % 3 != 1) { print_str("BAD 9\n"); } - if (i32(i32(5)) != 5) { print_str("BAD 10\n"); } - if (!!false) { print_str("BAD 11\n"); } - if (i32(7) != --(i32(7))) { print_str("BAD 12\n"); } + if (false || false || false) { stdout.printf("BAD 1\n"); } + if (true && true && false) { stdout.printf("BAD 2\n"); } + if (1 | 2 | 4 != 7) { stdout.printf("BAD 3\n"); } + if (3 ^ 6 ^ 8 != 13) { stdout.printf("BAD 4\n"); } + if (7 & 14 & 28 != 4) { stdout.printf("BAD 5\n"); } + if (9 << 1 << 2 != 9 << 3) { stdout.printf("BAD 6\n"); } + if (90 >> 1 >> 2 != 90 >> 3) { stdout.printf("BAD 7\n"); } + if (100 - 1 + 1000 != 1099) { stdout.printf("BAD 8\n"); } + if (5 * 4 / 2 % 3 != 1) { stdout.printf("BAD 9\n"); } + if (i32(i32(5)) != 5) { stdout.printf("BAD 10\n"); } + if (!!false) { stdout.printf("BAD 11\n"); } + if (i32(7) != --(i32(7))) { stdout.printf("BAD 12\n"); } - print_str("OK\n"); + stdout.printf("OK\n"); } )SOURCE", "OK\n"); @@ -441,19 +441,19 @@ pub fn main(args: [][]u8) %void => { import "std.zig"; pub fn main(args: [][]u8) %void => { - if (true || { print_str("BAD 1\n"); false }) { - print_str("OK 1\n"); + if (true || { stdout.printf("BAD 1\n"); false }) { + stdout.printf("OK 1\n"); } - if (false || { print_str("OK 2\n"); false }) { - print_str("BAD 2\n"); + if (false || { stdout.printf("OK 2\n"); false }) { + stdout.printf("BAD 2\n"); } - if (true && { print_str("OK 3\n"); false }) { - print_str("BAD 3\n"); + if (true && { stdout.printf("OK 3\n"); false }) { + stdout.printf("BAD 3\n"); } - if (false && { print_str("BAD 4\n"); false }) { + if (false && { stdout.printf("BAD 4\n"); false }) { } else { - print_str("OK 4\n"); + stdout.printf("OK 4\n"); } } )SOURCE", "OK 1\nOK 2\nOK 3\nOK 4\n"); @@ -463,20 +463,20 @@ import "std.zig"; pub fn main(args: [][]u8) %void => { var i : i32 = 0; - i += 5; if (i != 5) { print_str("BAD +=\n"); } - i -= 2; if (i != 3) { print_str("BAD -=\n"); } - i *= 20; if (i != 60) { print_str("BAD *=\n"); } - i /= 3; if (i != 20) { print_str("BAD /=\n"); } - i %= 11; if (i != 9) { print_str("BAD %=\n"); } - i <<= 1; if (i != 18) { print_str("BAD <<=\n"); } - i >>= 2; if (i != 4) { print_str("BAD >>=\n"); } + i += 5; if (i != 5) { stdout.printf("BAD +=\n"); } + i -= 2; if (i != 3) { stdout.printf("BAD -=\n"); } + i *= 20; if (i != 60) { stdout.printf("BAD *=\n"); } + i /= 3; if (i != 20) { stdout.printf("BAD /=\n"); } + i %= 11; if (i != 9) { stdout.printf("BAD %=\n"); } + i <<= 1; if (i != 18) { stdout.printf("BAD <<=\n"); } + i >>= 2; if (i != 4) { stdout.printf("BAD >>=\n"); } i = 6; - i &= 5; if (i != 4) { print_str("BAD &=\n"); } - i ^= 6; if (i != 2) { print_str("BAD ^=\n"); } + i &= 5; if (i != 4) { stdout.printf("BAD &=\n"); } + i ^= 6; if (i != 2) { stdout.printf("BAD ^=\n"); } i = 6; - i |= 3; if (i != 7) { print_str("BAD |=\n"); } + i |= 3; if (i != 7) { stdout.printf("BAD |=\n"); } - print_str("OK\n"); + stdout.printf("OK\n"); } )SOURCE", "OK\n"); @@ -620,12 +620,12 @@ pub fn main(args: [][]u8) %void => { test_foo(foo); test_mutation(&foo); if (foo.c != 100) { - print_str("BAD\n"); + stdout.printf("BAD\n"); } test_point_to_self(); test_byval_assign(); test_initializer(); - print_str("OK\n"); + stdout.printf("OK\n"); } struct Foo { a : i32, @@ -634,7 +634,7 @@ struct Foo { } fn test_foo(foo : Foo) => { if (!foo.b) { - print_str("BAD\n"); + stdout.printf("BAD\n"); } } fn test_mutation(foo : &Foo) => { @@ -659,7 +659,7 @@ fn test_point_to_self() => { root.next = &node; if (node.next.next.next.val.x != 1) { - print_str("BAD\n"); + stdout.printf("BAD\n"); } } fn test_byval_assign() => { @@ -668,15 +668,15 @@ fn test_byval_assign() => { foo1.a = 1234; - if (foo2.a != 0) { print_str("BAD\n"); } + if (foo2.a != 0) { stdout.printf("BAD\n"); } foo2 = foo1; - if (foo2.a != 1234) { print_str("BAD - byval assignment failed\n"); } + if (foo2.a != 1234) { stdout.printf("BAD - byval assignment failed\n"); } } fn test_initializer() => { const val = Val { .x = 42 }; - if (val.x != 42) { print_str("BAD\n"); } + if (val.x != 42) { stdout.printf("BAD\n"); } } )SOURCE", "OK\n"); @@ -687,10 +687,10 @@ const g1 : i32 = 1233 + 1; var g2 : i32 = 0; pub fn main(args: [][]u8) %void => { - if (g2 != 0) { print_str("BAD\n"); } + if (g2 != 0) { stdout.printf("BAD\n"); } g2 = g1; - if (g2 != 1234) { print_str("BAD\n"); } - print_str("OK\n"); + if (g2 != 1234) { stdout.printf("BAD\n"); } + stdout.printf("OK\n"); } )SOURCE", "OK\n"); @@ -699,7 +699,7 @@ import "std.zig"; pub fn main(args: [][]u8) %void => { var i : i32 = 0; while (i < 4) { - print_str("loop\n"); + stdout.printf("loop\n"); i += 1; } g(); @@ -719,7 +719,7 @@ import "std.zig"; pub fn main(args: [][]u8) %void => { var i : i32 = 0; while (true) { - print_str("loop\n"); + stdout.printf("loop\n"); i += 1; if (i < 4) { continue; @@ -736,12 +736,12 @@ pub fn main(args: [][]u8) %void => { if (const y ?= x) { if (y) { - print_str("x is true\n"); + stdout.printf("x is true\n"); } else { - print_str("x is false\n"); + stdout.printf("x is false\n"); } } else { - print_str("x is none\n"); + stdout.printf("x is none\n"); } const next_x : ?i32 = null; @@ -749,7 +749,7 @@ pub fn main(args: [][]u8) %void => { const z = next_x ?? 1234; if (z != 1234) { - print_str("BAD\n"); + stdout.printf("BAD\n"); } const final_x : ?i32 = 13; @@ -757,7 +757,7 @@ pub fn main(args: [][]u8) %void => { const num = final_x ?? unreachable{}; if (num != 13) { - print_str("BAD\n"); + stdout.printf("BAD\n"); } } )SOURCE", "x is true\n"); @@ -767,7 +767,7 @@ import "std.zig"; pub fn main(args: [][]u8) %void => { const x = outer(); if (x == 1234) { - print_str("OK\n"); + stdout.printf("OK\n"); } } fn inner() i32 => { 1234 } @@ -782,8 +782,8 @@ const x: u16 = 13; const z: @typeof(x) = 19; pub fn main(args: [][]u8) %void => { const y: @typeof(x) = 120; - print_u64(@sizeof(@typeof(y))); - print_str("\n"); + stdout.print_u64(@sizeof(@typeof(y))); + stdout.printf("\n"); } )SOURCE", "2\n"); @@ -798,9 +798,9 @@ struct Rand { pub fn main(args: [][]u8) %void => { const r = Rand {.seed = 1234}; if (r.get_seed() != 1234) { - print_str("BAD seed\n"); + stdout.printf("BAD seed\n"); } - print_str("OK\n"); + stdout.printf("OK\n"); } )SOURCE", "OK\n"); @@ -814,12 +814,12 @@ pub fn main(args: [][]u8) %void => { *y += 1; if (x != 4) { - print_str("BAD\n"); + stdout.printf("BAD\n"); } if (*y != 4) { - print_str("BAD\n"); + stdout.printf("BAD\n"); } - print_str("OK\n"); + stdout.printf("OK\n"); } )SOURCE", "OK\n"); @@ -830,77 +830,77 @@ const ARRAY_SIZE : i8 = 20; pub fn main(args: [][]u8) %void => { var array : [ARRAY_SIZE]u8; - print_u64(@sizeof(@typeof(array))); - print_str("\n"); + stdout.print_u64(@sizeof(@typeof(array))); + stdout.printf("\n"); } )SOURCE", "20\n"); add_simple_case("@min_value() and @max_value()", R"SOURCE( import "std.zig"; pub fn main(args: [][]u8) %void => { - print_str("max u8: "); - print_u64(@max_value(u8)); - print_str("\n"); + stdout.printf("max u8: "); + stdout.print_u64(@max_value(u8)); + stdout.printf("\n"); - print_str("max u16: "); - print_u64(@max_value(u16)); - print_str("\n"); + stdout.printf("max u16: "); + stdout.print_u64(@max_value(u16)); + stdout.printf("\n"); - print_str("max u32: "); - print_u64(@max_value(u32)); - print_str("\n"); + stdout.printf("max u32: "); + stdout.print_u64(@max_value(u32)); + stdout.printf("\n"); - print_str("max u64: "); - print_u64(@max_value(u64)); - print_str("\n"); + stdout.printf("max u64: "); + stdout.print_u64(@max_value(u64)); + stdout.printf("\n"); - print_str("max i8: "); - print_i64(@max_value(i8)); - print_str("\n"); + stdout.printf("max i8: "); + stdout.print_i64(@max_value(i8)); + stdout.printf("\n"); - print_str("max i16: "); - print_i64(@max_value(i16)); - print_str("\n"); + stdout.printf("max i16: "); + stdout.print_i64(@max_value(i16)); + stdout.printf("\n"); - print_str("max i32: "); - print_i64(@max_value(i32)); - print_str("\n"); + stdout.printf("max i32: "); + stdout.print_i64(@max_value(i32)); + stdout.printf("\n"); - print_str("max i64: "); - print_i64(@max_value(i64)); - print_str("\n"); + stdout.printf("max i64: "); + stdout.print_i64(@max_value(i64)); + stdout.printf("\n"); - print_str("min u8: "); - print_u64(@min_value(u8)); - print_str("\n"); + stdout.printf("min u8: "); + stdout.print_u64(@min_value(u8)); + stdout.printf("\n"); - print_str("min u16: "); - print_u64(@min_value(u16)); - print_str("\n"); + stdout.printf("min u16: "); + stdout.print_u64(@min_value(u16)); + stdout.printf("\n"); - print_str("min u32: "); - print_u64(@min_value(u32)); - print_str("\n"); + stdout.printf("min u32: "); + stdout.print_u64(@min_value(u32)); + stdout.printf("\n"); - print_str("min u64: "); - print_u64(@min_value(u64)); - print_str("\n"); + stdout.printf("min u64: "); + stdout.print_u64(@min_value(u64)); + stdout.printf("\n"); - print_str("min i8: "); - print_i64(@min_value(i8)); - print_str("\n"); + stdout.printf("min i8: "); + stdout.print_i64(@min_value(i8)); + stdout.printf("\n"); - print_str("min i16: "); - print_i64(@min_value(i16)); - print_str("\n"); + stdout.printf("min i16: "); + stdout.print_i64(@min_value(i16)); + stdout.printf("\n"); - print_str("min i32: "); - print_i64(@min_value(i32)); - print_str("\n"); + stdout.printf("min i32: "); + stdout.print_i64(@min_value(i32)); + stdout.printf("\n"); - print_str("min i64: "); - print_i64(@min_value(i64)); - print_str("\n"); + stdout.printf("min i64: "); + stdout.print_i64(@min_value(i64)); + stdout.printf("\n"); } )SOURCE", "max u8: 255\n" @@ -931,19 +931,19 @@ pub fn main(args: [][]u8) %void => { var slice = array[5...10]; if (slice.len != 5) { - print_str("BAD\n"); + stdout.printf("BAD\n"); } if (slice.ptr[0] != 1234) { - print_str("BAD\n"); + stdout.printf("BAD\n"); } var slice_rest = array[10...]; if (slice_rest.len != 10) { - print_str("BAD\n"); + stdout.printf("BAD\n"); } - print_str("OK\n"); + stdout.printf("OK\n"); } )SOURCE", "OK\n"); @@ -952,7 +952,7 @@ pub fn main(args: [][]u8) %void => { import "std.zig"; pub fn main(args: [][]u8) %void => { if (f(1) == 1) { - print_str("OK\n"); + stdout.printf("OK\n"); } } fn f(c: u8) u8 => { @@ -971,15 +971,15 @@ import "std.zig"; pub fn main(args: [][]u8) %void => { var result: u8; if (!@add_with_overflow(u8, 250, 100, &result)) { - print_str("BAD\n"); + stdout.printf("BAD\n"); } if (@add_with_overflow(u8, 100, 150, &result)) { - print_str("BAD\n"); + stdout.printf("BAD\n"); } if (result != 250) { - print_str("BAD\n"); + stdout.printf("BAD\n"); } - print_str("OK\n"); + stdout.printf("OK\n"); } )SOURCE", "OK\n"); @@ -993,10 +993,10 @@ pub fn main(args: [][]u8) %void => { @memcpy(bar.ptr, foo.ptr, bar.len); if (bar[11] != 'A') { - print_str("BAD\n"); + stdout.printf("BAD\n"); } - print_str("OK\n"); + stdout.printf("OK\n"); } )SOURCE", "OK\n"); @@ -1009,7 +1009,7 @@ pub fn main(args: [][]u8) %void => { var x : i32 = print_ok(x); } fn print_ok(val: @typeof(x)) @typeof(foo) => { - print_str("OK\n"); + stdout.printf("OK\n"); return 0; } const foo : i32 = 0; @@ -1042,25 +1042,25 @@ pub fn main(args: [][]u8) %void => { const bar = Bar.B; if (bar != Bar.B) { - print_str("BAD\n"); + stdout.printf("BAD\n"); } if (@member_count(Foo) != 3) { - print_str("BAD\n"); + stdout.printf("BAD\n"); } if (@member_count(Bar) != 4) { - print_str("BAD\n"); + stdout.printf("BAD\n"); } if (@sizeof(Foo) != 17) { - print_str("BAD\n"); + stdout.printf("BAD\n"); } if (@sizeof(Bar) != 1) { - print_str("BAD\n"); + stdout.printf("BAD\n"); } - print_str("OK\n"); + stdout.printf("OK\n"); } )SOURCE", "OK\n"); @@ -1071,14 +1071,14 @@ pub fn main(args: [][]u8) %void => { const HEX_MULT = []u16{4096, 256, 16, 1}; if (HEX_MULT.len != 4) { - print_str("BAD\n"); + stdout.printf("BAD\n"); } if (HEX_MULT[1] != 256) { - print_str("BAD\n"); + stdout.printf("BAD\n"); } - print_str("OK\n"); + stdout.printf("OK\n"); } )SOURCE", "OK\n"); @@ -1089,8 +1089,8 @@ pub fn main(args: [][]u8) %void => { const array_of_strings = [][]u8 {"hello", "this", "is", "my", "thing"}; var i: @typeof(array_of_strings.len) = 0; while (i < array_of_strings.len) { - print_str(array_of_strings[i]); - print_str("\n"); + stdout.printf(array_of_strings[i]); + stdout.printf("\n"); i += 1; } } @@ -1102,21 +1102,21 @@ import "std.zig"; pub fn main(args: [][]u8) %void => { const array = []u8 {9, 8, 7, 6}; for (item, array) { - print_u64(item); - print_str("\n"); + stdout.print_u64(item); + stdout.printf("\n"); } for (item, array, index) { - print_i64(index); - print_str("\n"); + stdout.print_i64(index); + stdout.printf("\n"); } const unknown_size: []u8 = array; for (item, unknown_size) { - print_u64(item); - print_str("\n"); + stdout.print_u64(item); + stdout.printf("\n"); } for (item, unknown_size, index) { - print_i64(index); - print_str("\n"); + stdout.print_i64(index); + stdout.printf("\n"); } } )SOURCE", "9\n8\n7\n6\n0\n1\n2\n3\n9\n8\n7\n6\n0\n1\n2\n3\n"); @@ -1127,8 +1127,8 @@ import "std.zig"; pub fn main(args: [][]u8) %void => { const fns = []@typeof(fn1) { fn1, fn2, fn3, fn4, }; for (f, fns) { - print_u64(f()); - print_str("\n"); + stdout.print_u64(f()); + stdout.printf("\n"); } } @@ -1157,10 +1157,10 @@ pub fn main(args: [][]u8) %void => { Foo.D => 4, }; if (val != 3) { - print_str("BAD\n"); + stdout.printf("BAD\n"); } - print_str("OK\n"); + stdout.printf("OK\n"); } )SOURCE", "OK\n"); @@ -1174,10 +1174,10 @@ pub fn main(args: [][]u8) %void => { const eleven = ten + one; if (eleven != 11) { - print_str("BAD\n"); + stdout.printf("BAD\n"); } - print_str("OK\n"); + stdout.printf("OK\n"); } )SOURCE", "OK\n"); @@ -1191,10 +1191,10 @@ var foo = Foo { .x = 13, .y = true, }; pub fn main(args: [][]u8) %void => { foo.x += 1; if (foo.x != 14) { - print_str("BAD\n"); + stdout.printf("BAD\n"); } - print_str("OK\n"); + stdout.printf("OK\n"); } )SOURCE", "OK\n"); @@ -1204,10 +1204,10 @@ const x = []u8{1,2,3,4}; pub fn main(args: [][]u8) %void => { const y : [4]u8 = x; if (y[3] != 4) { - print_str("BAD\n"); + stdout.printf("BAD\n"); } - print_str("OK\n"); + stdout.printf("OK\n"); } )SOURCE", "OK\n"); @@ -1219,10 +1219,10 @@ pub fn main(args: [][]u8) %void => { const a = i32(error.err1); const b = i32(error.err2); if (a == b) { - print_str("BAD\n"); + stdout.printf("BAD\n"); } - print_str("OK\n"); + stdout.printf("OK\n"); } )SOURCE", "OK\n"); @@ -1230,7 +1230,7 @@ pub fn main(args: [][]u8) %void => { import "std.zig"; pub fn main(args: [][]u8) %void => { while (true) { - print_str("OK\n"); + stdout.printf("OK\n"); return; } } @@ -1251,9 +1251,9 @@ fn make_foo(x: i32, y: i32) Foo => { pub fn main(args: [][]u8) %void => { const foo = make_foo(1234, 5678); if (foo.y != 5678) { - print_str("BAD\n"); + stdout.printf("BAD\n"); } - print_str("OK\n"); + stdout.printf("OK\n"); } )SOURCE", "OK\n"); }