authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-01-23 02:45:54-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-01-23 02:46:24-07:00
log706f72f1b47ace8c6c9eecde2682ac46389af1ca
tree18700cad180b70e3a01406e0ffdaf6ed1e2aca69
parentc0ea9290c4576f2111c8fc6b2d448f278effd80e

fix hang when returning from while loop

also fixes duplicate error message for function missing return type. also makes guess number game use %void for main return type. closes #58

3 files changed, 32 insertions(+), 18 deletions(-)

example/guess_number/main.zig+7-4
...@@ -3,7 +3,10 @@ export executable "guess_number";...@@ -3,7 +3,10 @@ export executable "guess_number";
3import "std.zig";3import "std.zig";
4import "rand.zig";4import "rand.zig";
55
6pub fn main(args: [][]u8) i32 => {6%.GetRandomFail;
7%.ReadInputFail;
8
9pub fn main(args: [][]u8) %void => {
7 print_str("Welcome to the Guess Number Game in Zig.\n");10 print_str("Welcome to the Guess Number Game in Zig.\n");
811
9 var seed : u32;12 var seed : u32;
...@@ -12,7 +15,7 @@ pub fn main(args: [][]u8) i32 => {...@@ -12,7 +15,7 @@ pub fn main(args: [][]u8) i32 => {
12 if (err != @sizeof(u32)) {15 if (err != @sizeof(u32)) {
13 // TODO full error message16 // TODO full error message
14 fprint_str(stderr_fileno, "unable to get random bytes\n");17 fprint_str(stderr_fileno, "unable to get random bytes\n");
15 return 1;18 return %.GetRandomFail;
16 }19 }
1720
18 var rand : Rand;21 var rand : Rand;
...@@ -28,7 +31,7 @@ pub fn main(args: [][]u8) i32 => {...@@ -28,7 +31,7 @@ pub fn main(args: [][]u8) i32 => {
28 if (readline(line_buf, &line_len) || line_len == line_buf.len) {31 if (readline(line_buf, &line_len) || line_len == line_buf.len) {
29 // TODO full error message32 // TODO full error message
30 fprint_str(stderr_fileno, "unable to read input\n");33 fprint_str(stderr_fileno, "unable to read input\n");
31 return 1;34 return %.ReadInputFail;
32 }35 }
3336
34 var guess : u64;37 var guess : u64;
...@@ -40,7 +43,7 @@ pub fn main(args: [][]u8) i32 => {...@@ -40,7 +43,7 @@ pub fn main(args: [][]u8) i32 => {
40 print_str("Guess higher.\n");43 print_str("Guess higher.\n");
41 } else {44 } else {
42 print_str("You win!\n");45 print_str("You win!\n");
43 return 0;46 return;
44 }47 }
45 }48 }
46}49}
src/analyze.cpp+16-14
...@@ -1344,6 +1344,16 @@ static AstNode *create_ast_type_node(CodeGen *g, ImportTableEntry *import, TypeT...@@ -1344,6 +1344,16 @@ static AstNode *create_ast_type_node(CodeGen *g, ImportTableEntry *import, TypeT
1344 return node;1344 return node;
1345}1345}
13461346
1347static AstNode *create_ast_void_node(CodeGen *g, ImportTableEntry *import, AstNode *source_node) {
1348 AstNode *node = create_ast_node(g, import, NodeTypeContainerInitExpr);
1349 node->data.container_init_expr.kind = ContainerInitKindArray;
1350 node->data.container_init_expr.type = create_ast_type_node(g, import, g->builtin_types.entry_void);
1351 node->line = source_node->line;
1352 node->column = source_node->column;
1353 normalize_parent_ptrs(node);
1354 return node;
1355}
1356
1347static TypeTableEntry *create_and_analyze_cast_node(CodeGen *g, ImportTableEntry *import,1357static TypeTableEntry *create_and_analyze_cast_node(CodeGen *g, ImportTableEntry *import,
1348 BlockContext *context, TypeTableEntry *cast_to_type, AstNode *node)1358 BlockContext *context, TypeTableEntry *cast_to_type, AstNode *node)
1349{1359{
...@@ -3596,25 +3606,17 @@ static TypeTableEntry *analyze_return_expr(CodeGen *g, ImportTableEntry *import,...@@ -3596,25 +3606,17 @@ static TypeTableEntry *analyze_return_expr(CodeGen *g, ImportTableEntry *import,
3596 return g->builtin_types.entry_invalid;3606 return g->builtin_types.entry_invalid;
3597 }3607 }
35983608
3609 if (!node->data.return_expr.expr) {
3610 node->data.return_expr.expr = create_ast_void_node(g, import, node);
3611 normalize_parent_ptrs(node);
3612 }
3613
3599 if (node->data.return_expr.kind != ReturnKindUnconditional) {3614 if (node->data.return_expr.kind != ReturnKindUnconditional) {
3600 zig_panic("TODO analyze_return_expr conditional");3615 zig_panic("TODO analyze_return_expr conditional");
3601 }3616 }
36023617
3603 TypeTableEntry *expected_return_type = get_return_type(context);3618 TypeTableEntry *expected_return_type = get_return_type(context);
3604 TypeTableEntry *actual_return_type;3619 analyze_expression(g, import, context, expected_return_type, node->data.return_expr.expr);
3605 if (node->data.return_expr.expr) {
3606 actual_return_type = analyze_expression(g, import, context, expected_return_type, node->data.return_expr.expr);
3607 } else {
3608 actual_return_type = g->builtin_types.entry_void;
3609 }
3610
3611 if (actual_return_type->id == TypeTableEntryIdUnreachable) {
3612 // "return exit(0)" should just be "exit(0)".
3613 add_node_error(g, node, buf_sprintf("returning is unreachable"));
3614 actual_return_type = g->builtin_types.entry_invalid;
3615 }
3616
3617 resolve_type_compatibility(g, import, context, node, expected_return_type, actual_return_type);
36183620
3619 return g->builtin_types.entry_unreachable;3621 return g->builtin_types.entry_unreachable;
3620}3622}
test/run_tests.cpp+9
...@@ -1226,6 +1226,15 @@ pub fn main(args: [][]u8) %void => {...@@ -1226,6 +1226,15 @@ pub fn main(args: [][]u8) %void => {
1226}1226}
1227 )SOURCE", "OK\n");1227 )SOURCE", "OK\n");
12281228
1229 add_simple_case("return with implicit cast from while loop", R"SOURCE(
1230import "std.zig";
1231pub fn main(args: [][]u8) %void => {
1232 while (true) {
1233 print_str("OK\n");
1234 return;
1235 }
1236}
1237 )SOURCE", "OK\n");
1229}1238}
12301239
12311240