mirror of
https://github.com/ziglang/zig.git
synced 2026-02-13 12:59:04 +00:00
codegen: fix else if expression and maybe unwrap expr
This commit is contained in:
parent
e1f498212c
commit
0c84ecd19d
@ -30,23 +30,24 @@ pub fn main(argc: isize, argv: &&u8, env: &&u8) -> i32 {
|
||||
while (true) {
|
||||
print_str("\nGuess a number between 1 and 100: ");
|
||||
var line_buf : [20]u8;
|
||||
const line = readline(line_buf) ?? {
|
||||
var line_len : usize;
|
||||
// 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 1;
|
||||
};
|
||||
}
|
||||
|
||||
if (const guess ?= parse_u64(line)) {
|
||||
if (guess > answer) {
|
||||
print_str("Guess lower.\n");
|
||||
} else if (guess < answer) {
|
||||
print_str("Guess higher.\n");
|
||||
} else {
|
||||
print_str("You win!\n");
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
var guess : u64;
|
||||
if (parse_u64(line_buf, 10, &guess)) {
|
||||
print_str("Invalid number format.\n");
|
||||
} else if (guess > answer) {
|
||||
print_str("Guess lower.\n");
|
||||
} else if (guess < answer) {
|
||||
print_str("Guess higher.\n");
|
||||
} else {
|
||||
print_str("You win!\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -209,7 +209,6 @@ struct CodeGen {
|
||||
|
||||
OutType out_type;
|
||||
FnTableEntry *cur_fn;
|
||||
LLVMBasicBlockRef cur_basic_block;
|
||||
BlockContext *cur_block_context;
|
||||
ZigList<LLVMBasicBlockRef> break_block_stack;
|
||||
ZigList<LLVMBasicBlockRef> continue_block_stack;
|
||||
|
||||
@ -905,6 +905,7 @@ static LLVMValueRef gen_unwrap_maybe_expr(CodeGen *g, AstNode *node) {
|
||||
add_debug_source_node(g, node);
|
||||
LLVMBuildBr(g->builder, end_block);
|
||||
}
|
||||
LLVMBasicBlockRef post_non_null_result_block = LLVMGetInsertBlock(g->builder);
|
||||
|
||||
LLVMPositionBuilderAtEnd(g->builder, null_block);
|
||||
LLVMValueRef null_result = gen_expr(g, op2_node);
|
||||
@ -912,6 +913,7 @@ static LLVMValueRef gen_unwrap_maybe_expr(CodeGen *g, AstNode *node) {
|
||||
add_debug_source_node(g, node);
|
||||
LLVMBuildBr(g->builder, end_block);
|
||||
}
|
||||
LLVMBasicBlockRef post_null_result_block = LLVMGetInsertBlock(g->builder);
|
||||
|
||||
if (end_reachable) {
|
||||
LLVMPositionBuilderAtEnd(g->builder, end_block);
|
||||
@ -919,7 +921,7 @@ static LLVMValueRef gen_unwrap_maybe_expr(CodeGen *g, AstNode *node) {
|
||||
add_debug_source_node(g, node);
|
||||
LLVMValueRef phi = LLVMBuildPhi(g->builder, LLVMTypeOf(non_null_result), "");
|
||||
LLVMValueRef incoming_values[2] = {non_null_result, null_result};
|
||||
LLVMBasicBlockRef incoming_blocks[2] = {non_null_block, null_block};
|
||||
LLVMBasicBlockRef incoming_blocks[2] = {post_non_null_result_block, post_null_result_block};
|
||||
LLVMAddIncoming(phi, incoming_values, incoming_blocks, 2);
|
||||
return phi;
|
||||
} else {
|
||||
@ -1015,19 +1017,21 @@ static LLVMValueRef gen_if_bool_expr_raw(CodeGen *g, AstNode *source_node, LLVMV
|
||||
if (then_endif_reachable) {
|
||||
LLVMBuildBr(g->builder, endif_block);
|
||||
}
|
||||
LLVMBasicBlockRef after_then_block = LLVMGetInsertBlock(g->builder);
|
||||
|
||||
LLVMPositionBuilderAtEnd(g->builder, else_block);
|
||||
LLVMValueRef else_expr_result = gen_expr(g, else_node);
|
||||
if (else_endif_reachable) {
|
||||
LLVMBuildBr(g->builder, endif_block);
|
||||
}
|
||||
LLVMBasicBlockRef after_else_block = LLVMGetInsertBlock(g->builder);
|
||||
|
||||
if (then_endif_reachable || else_endif_reachable) {
|
||||
LLVMPositionBuilderAtEnd(g->builder, endif_block);
|
||||
if (use_expr_value) {
|
||||
LLVMValueRef phi = LLVMBuildPhi(g->builder, LLVMTypeOf(then_expr_result), "");
|
||||
LLVMValueRef incoming_values[2] = {then_expr_result, else_expr_result};
|
||||
LLVMBasicBlockRef incoming_blocks[2] = {then_block, else_block};
|
||||
LLVMBasicBlockRef incoming_blocks[2] = {after_then_block, after_else_block};
|
||||
LLVMAddIncoming(phi, incoming_values, incoming_blocks, 2);
|
||||
|
||||
return phi;
|
||||
|
||||
73
std/std.zig
73
std/std.zig
@ -39,28 +39,63 @@ pub fn print_i64(x: i64) -> isize {
|
||||
return write(stdout_fileno, buf.ptr, len);
|
||||
}
|
||||
|
||||
/*
|
||||
// TODO error handling
|
||||
pub fn readline(buf: []u8) -> ?[]u8 {
|
||||
var index : usize = 0;
|
||||
while (index < buf.len) {
|
||||
// TODO unknown size array indexing operator
|
||||
const err = read(stdin_fileno, &buf.ptr[index], 1);
|
||||
if (err != 0) {
|
||||
return null;
|
||||
}
|
||||
// TODO unknown size array indexing operator
|
||||
if (buf.ptr[index] == '\n') {
|
||||
return buf[0...index + 1];
|
||||
}
|
||||
index += 1;
|
||||
pub fn readline(buf: []u8, out_len: &usize) -> bool {
|
||||
// TODO unknown size array indexing operator
|
||||
const amt_read = read(stdin_fileno, buf.ptr, buf.len);
|
||||
if (amt_read < 0) {
|
||||
return true;
|
||||
}
|
||||
return null;
|
||||
*out_len = amt_read as usize;
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
|
||||
fn digit_to_char(digit: u64) -> u8 {
|
||||
'0' + (digit as u8)
|
||||
// TODO return ?u64 when we support returning struct byval
|
||||
pub fn parse_u64(buf: []u8, radix: u8, result: &u64) -> bool {
|
||||
var x : u64 = 0;
|
||||
|
||||
var i : #typeof(buf.len) = 0;
|
||||
while (i < buf.len) {
|
||||
// TODO array indexing operator
|
||||
const c = buf.ptr[i];
|
||||
const digit = char_to_digit(c);
|
||||
|
||||
if (digit > radix) {
|
||||
return true;
|
||||
}
|
||||
|
||||
x *= radix;
|
||||
x += digit;
|
||||
|
||||
/* TODO intrinsics mul and add with overflow
|
||||
// x *= radix
|
||||
if (@mul_with_overflow_u64(x, radix, &x)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// x += digit
|
||||
if (@add_with_overflow_u64(x, digit, &x)) {
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
|
||||
i += 1;
|
||||
}
|
||||
|
||||
*result = x;
|
||||
return false;
|
||||
}
|
||||
|
||||
fn char_to_digit(c: u8) -> u8 {
|
||||
if ('0' <= c && c <= '9') {
|
||||
c - '0'
|
||||
} else if ('A' <= c && c <= 'Z') {
|
||||
c - 'A' + 10
|
||||
} else if ('a' <= c && c <= 'z') {
|
||||
c - 'a' + 10
|
||||
} else {
|
||||
#max_value(u8)
|
||||
}
|
||||
}
|
||||
|
||||
const max_u64_base10_digits: usize = 20;
|
||||
@ -86,7 +121,7 @@ fn buf_print_u64(out_buf: &u8, x: u64) -> usize {
|
||||
while (true) {
|
||||
const digit = a % 10;
|
||||
index -= 1;
|
||||
buf[index] = digit_to_char(digit);
|
||||
buf[index] = '0' + (digit as u8);
|
||||
a /= 10;
|
||||
if (a == 0)
|
||||
break;
|
||||
|
||||
@ -936,7 +936,27 @@ pub fn main(argc: isize, argv: &&u8, env: &&u8) -> i32 {
|
||||
}
|
||||
)SOURCE", "OK\n");
|
||||
|
||||
|
||||
add_simple_case("else if expression", R"SOURCE(
|
||||
use "std.zig";
|
||||
pub fn main(argc: isize, argv: &&u8, env: &&u8) -> i32 {
|
||||
if (f(1) == 1) {
|
||||
print_str("OK\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
fn f(c: u8) -> u8 {
|
||||
if (c == 0) {
|
||||
0
|
||||
} else if (c == 1) {
|
||||
1
|
||||
} else {
|
||||
2
|
||||
}
|
||||
}
|
||||
)SOURCE", "OK\n");
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user