| author | |
| committer | |
| log | 0c84ecd19d0dbe6a98dd5e3f440cc9d7a78ea7d9 |
| tree | c05148fa68edb77dbdedb501d590e469e41f8567 |
| parent | e1f498212c74c48d740b959484123478dec748ff |
5 files changed, 92 insertions(+), 33 deletions(-)
example/guess_number/main.zig+14-13| ... | ... | @@ -30,23 +30,24 @@ pub fn main(argc: isize, argv: &&u8, env: &&u8) -> i32 { |
| 30 | 30 | while (true) { |
| 31 | 31 | print_str("\nGuess a number between 1 and 100: "); |
| 32 | 32 | var line_buf : [20]u8; |
| 33 | const line = readline(line_buf) ?? { | |
| 33 | var line_len : usize; | |
| 34 | // TODO fix this awkward error handling | |
| 35 | if (readline(line_buf, &line_len) || line_len == line_buf.len) { | |
| 34 | 36 | // TODO full error message |
| 35 | 37 | fprint_str(stderr_fileno, "unable to read input\n"); |
| 36 | 38 | return 1; |
| 37 | }; | |
| 38 | ||
| 39 | if (const guess ?= parse_u64(line)) { | |
| 40 | if (guess > answer) { | |
| 41 | print_str("Guess lower.\n"); | |
| 42 | } else if (guess < answer) { | |
| 43 | print_str("Guess higher.\n"); | |
| 44 | } else { | |
| 45 | print_str("You win!\n"); | |
| 46 | return 0; | |
| 47 | } | |
| 48 | } else { | |
| 39 | } | |
| 40 | ||
| 41 | var guess : u64; | |
| 42 | if (parse_u64(line_buf, 10, &guess)) { | |
| 49 | 43 | print_str("Invalid number format.\n"); |
| 44 | } else if (guess > answer) { | |
| 45 | print_str("Guess lower.\n"); | |
| 46 | } else if (guess < answer) { | |
| 47 | print_str("Guess higher.\n"); | |
| 48 | } else { | |
| 49 | print_str("You win!\n"); | |
| 50 | return 0; | |
| 50 | 51 | } |
| 51 | 52 | } |
| 52 | 53 | } |
src/analyze.hpp-1| ... | ... | @@ -209,7 +209,6 @@ struct CodeGen { |
| 209 | 209 | |
| 210 | 210 | OutType out_type; |
| 211 | 211 | FnTableEntry *cur_fn; |
| 212 | LLVMBasicBlockRef cur_basic_block; | |
| 213 | 212 | BlockContext *cur_block_context; |
| 214 | 213 | ZigList<LLVMBasicBlockRef> break_block_stack; |
| 215 | 214 | ZigList<LLVMBasicBlockRef> continue_block_stack; |
src/codegen.cpp+6-2| ... | ... | @@ -905,6 +905,7 @@ static LLVMValueRef gen_unwrap_maybe_expr(CodeGen *g, AstNode *node) { |
| 905 | 905 | add_debug_source_node(g, node); |
| 906 | 906 | LLVMBuildBr(g->builder, end_block); |
| 907 | 907 | } |
| 908 | LLVMBasicBlockRef post_non_null_result_block = LLVMGetInsertBlock(g->builder); | |
| 908 | 909 | |
| 909 | 910 | LLVMPositionBuilderAtEnd(g->builder, null_block); |
| 910 | 911 | LLVMValueRef null_result = gen_expr(g, op2_node); |
| ... | ... | @@ -912,6 +913,7 @@ static LLVMValueRef gen_unwrap_maybe_expr(CodeGen *g, AstNode *node) { |
| 912 | 913 | add_debug_source_node(g, node); |
| 913 | 914 | LLVMBuildBr(g->builder, end_block); |
| 914 | 915 | } |
| 916 | LLVMBasicBlockRef post_null_result_block = LLVMGetInsertBlock(g->builder); | |
| 915 | 917 | |
| 916 | 918 | if (end_reachable) { |
| 917 | 919 | LLVMPositionBuilderAtEnd(g->builder, end_block); |
| ... | ... | @@ -919,7 +921,7 @@ static LLVMValueRef gen_unwrap_maybe_expr(CodeGen *g, AstNode *node) { |
| 919 | 921 | add_debug_source_node(g, node); |
| 920 | 922 | LLVMValueRef phi = LLVMBuildPhi(g->builder, LLVMTypeOf(non_null_result), ""); |
| 921 | 923 | LLVMValueRef incoming_values[2] = {non_null_result, null_result}; |
| 922 | LLVMBasicBlockRef incoming_blocks[2] = {non_null_block, null_block}; | |
| 924 | LLVMBasicBlockRef incoming_blocks[2] = {post_non_null_result_block, post_null_result_block}; | |
| 923 | 925 | LLVMAddIncoming(phi, incoming_values, incoming_blocks, 2); |
| 924 | 926 | return phi; |
| 925 | 927 | } else { |
| ... | ... | @@ -1015,19 +1017,21 @@ static LLVMValueRef gen_if_bool_expr_raw(CodeGen *g, AstNode *source_node, LLVMV |
| 1015 | 1017 | if (then_endif_reachable) { |
| 1016 | 1018 | LLVMBuildBr(g->builder, endif_block); |
| 1017 | 1019 | } |
| 1020 | LLVMBasicBlockRef after_then_block = LLVMGetInsertBlock(g->builder); | |
| 1018 | 1021 | |
| 1019 | 1022 | LLVMPositionBuilderAtEnd(g->builder, else_block); |
| 1020 | 1023 | LLVMValueRef else_expr_result = gen_expr(g, else_node); |
| 1021 | 1024 | if (else_endif_reachable) { |
| 1022 | 1025 | LLVMBuildBr(g->builder, endif_block); |
| 1023 | 1026 | } |
| 1027 | LLVMBasicBlockRef after_else_block = LLVMGetInsertBlock(g->builder); | |
| 1024 | 1028 | |
| 1025 | 1029 | if (then_endif_reachable || else_endif_reachable) { |
| 1026 | 1030 | LLVMPositionBuilderAtEnd(g->builder, endif_block); |
| 1027 | 1031 | if (use_expr_value) { |
| 1028 | 1032 | LLVMValueRef phi = LLVMBuildPhi(g->builder, LLVMTypeOf(then_expr_result), ""); |
| 1029 | 1033 | LLVMValueRef incoming_values[2] = {then_expr_result, else_expr_result}; |
| 1030 | LLVMBasicBlockRef incoming_blocks[2] = {then_block, else_block}; | |
| 1034 | LLVMBasicBlockRef incoming_blocks[2] = {after_then_block, after_else_block}; | |
| 1031 | 1035 | LLVMAddIncoming(phi, incoming_values, incoming_blocks, 2); |
| 1032 | 1036 | |
| 1033 | 1037 | return phi; |
std/std.zig+52-17| ... | ... | @@ -39,28 +39,63 @@ pub fn print_i64(x: i64) -> isize { |
| 39 | 39 | return write(stdout_fileno, buf.ptr, len); |
| 40 | 40 | } |
| 41 | 41 | |
| 42 | /* | |
| 43 | 42 | // TODO error handling |
| 44 | pub fn readline(buf: []u8) -> ?[]u8 { | |
| 45 | var index : usize = 0; | |
| 46 | while (index < buf.len) { | |
| 47 | // TODO unknown size array indexing operator | |
| 48 | const err = read(stdin_fileno, &buf.ptr[index], 1); | |
| 49 | if (err != 0) { | |
| 50 | return null; | |
| 43 | pub fn readline(buf: []u8, out_len: &usize) -> bool { | |
| 44 | // TODO unknown size array indexing operator | |
| 45 | const amt_read = read(stdin_fileno, buf.ptr, buf.len); | |
| 46 | if (amt_read < 0) { | |
| 47 | return true; | |
| 48 | } | |
| 49 | *out_len = amt_read as usize; | |
| 50 | return false; | |
| 51 | } | |
| 52 | ||
| 53 | // TODO return ?u64 when we support returning struct byval | |
| 54 | pub fn parse_u64(buf: []u8, radix: u8, result: &u64) -> bool { | |
| 55 | var x : u64 = 0; | |
| 56 | ||
| 57 | var i : #typeof(buf.len) = 0; | |
| 58 | while (i < buf.len) { | |
| 59 | // TODO array indexing operator | |
| 60 | const c = buf.ptr[i]; | |
| 61 | const digit = char_to_digit(c); | |
| 62 | ||
| 63 | if (digit > radix) { | |
| 64 | return true; | |
| 65 | } | |
| 66 | ||
| 67 | x *= radix; | |
| 68 | x += digit; | |
| 69 | ||
| 70 | /* TODO intrinsics mul and add with overflow | |
| 71 | // x *= radix | |
| 72 | if (@mul_with_overflow_u64(x, radix, &x)) { | |
| 73 | return true; | |
| 51 | 74 | } |
| 52 | // TODO unknown size array indexing operator | |
| 53 | if (buf.ptr[index] == '\n') { | |
| 54 | return buf[0...index + 1]; | |
| 75 | ||
| 76 | // x += digit | |
| 77 | if (@add_with_overflow_u64(x, digit, &x)) { | |
| 78 | return true; | |
| 55 | 79 | } |
| 56 | index += 1; | |
| 80 | */ | |
| 81 | ||
| 82 | i += 1; | |
| 57 | 83 | } |
| 58 | return null; | |
| 84 | ||
| 85 | *result = x; | |
| 86 | return false; | |
| 59 | 87 | } |
| 60 | */ | |
| 61 | 88 | |
| 62 | fn digit_to_char(digit: u64) -> u8 { | |
| 63 | '0' + (digit as u8) | |
| 89 | fn char_to_digit(c: u8) -> u8 { | |
| 90 | if ('0' <= c && c <= '9') { | |
| 91 | c - '0' | |
| 92 | } else if ('A' <= c && c <= 'Z') { | |
| 93 | c - 'A' + 10 | |
| 94 | } else if ('a' <= c && c <= 'z') { | |
| 95 | c - 'a' + 10 | |
| 96 | } else { | |
| 97 | #max_value(u8) | |
| 98 | } | |
| 64 | 99 | } |
| 65 | 100 | |
| 66 | 101 | const max_u64_base10_digits: usize = 20; |
| ... | ... | @@ -86,7 +121,7 @@ fn buf_print_u64(out_buf: &u8, x: u64) -> usize { |
| 86 | 121 | while (true) { |
| 87 | 122 | const digit = a % 10; |
| 88 | 123 | index -= 1; |
| 89 | buf[index] = digit_to_char(digit); | |
| 124 | buf[index] = '0' + (digit as u8); | |
| 90 | 125 | a /= 10; |
| 91 | 126 | if (a == 0) |
| 92 | 127 | break; |
test/run_tests.cpp+20| ... | ... | @@ -936,7 +936,27 @@ pub fn main(argc: isize, argv: &&u8, env: &&u8) -> i32 { |
| 936 | 936 | } |
| 937 | 937 | )SOURCE", "OK\n"); |
| 938 | 938 | |
| 939 | ||
| 940 | add_simple_case("else if expression", R"SOURCE( | |
| 941 | use "std.zig"; | |
| 942 | pub fn main(argc: isize, argv: &&u8, env: &&u8) -> i32 { | |
| 943 | if (f(1) == 1) { | |
| 944 | print_str("OK\n"); | |
| 945 | } | |
| 946 | return 0; | |
| 939 | 947 | } |
| 948 | fn f(c: u8) -> u8 { | |
| 949 | if (c == 0) { | |
| 950 | 0 | |
| 951 | } else if (c == 1) { | |
| 952 | 1 | |
| 953 | } else { | |
| 954 | 2 | |
| 955 | } | |
| 956 | } | |
| 957 | )SOURCE", "OK\n"); | |
| 958 | } | |
| 959 | ||
| 940 | 960 | |
| 941 | 961 | //////////////////////////////////////////////////////////////////////////////////// |
| 942 | 962 |