authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-04-12 17:33:46-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-04-12 17:33:46-07:00
log3c27cb25279049cfdcde99d49045f5b8ec8981ba
tree7a9b9ba96c7f18096a669b3daa450fcc30ce6175
parent69109bc270c3167a3534dd32fc4f4def855e0be9

more eval tests and fix eval call analyze code


4 files changed, 77 insertions(+), 15 deletions(-)

src/analyze.cpp+6-11
......@@ -4504,28 +4504,23 @@ static TypeTableEntry *analyze_fn_call_ptr(CodeGen *g, ImportTableEntry *import,
45044504 }
45054505
45064506 FnTableEntry *fn_table_entry = node->data.fn_call_expr.fn_entry;
4507 if (ok_invocation && fn_table_entry && fn_table_entry->is_pure && all_args_const_expr) {
4507 if (ok_invocation && fn_table_entry && fn_table_entry->is_pure) {
45084508 if (fn_table_entry->anal_state == FnAnalStateReady) {
45094509 analyze_fn_body(g, fn_table_entry);
4510 } else if (fn_table_entry->anal_state == FnAnalStateProbing) {
4511 mark_impure_fn(context);
45124510 }
4513 if (fn_table_entry->is_pure) {
4514 if (fn_table_entry->anal_state == FnAnalStateComplete) {
4511 if (all_args_const_expr) {
4512 if (fn_table_entry->is_pure && fn_table_entry->anal_state == FnAnalStateComplete) {
45154513 ConstExprValue *result_val = &get_resolved_expr(node)->const_val;
45164514 if (eval_fn(g, node, fn_table_entry, result_val, 1000, struct_node)) {
45174515 // function evaluation generated an error
45184516 return g->builtin_types.entry_invalid;
45194517 }
45204518 return return_type;
4521 } else if (fn_table_entry->anal_state == FnAnalStateSkipped) {
4522 return g->builtin_types.entry_invalid;
45234519 }
4524 } else {
4525 // calling an impure fn is impure
4526 mark_impure_fn(context);
45274520 }
4528 } else {
4521 }
4522 if (!ok_invocation || !fn_table_entry || !fn_table_entry->is_pure) {
4523 // calling an impure fn is impure
45294524 mark_impure_fn(context);
45304525 }
45314526
src/eval.cpp+3-1
......@@ -713,7 +713,9 @@ static bool eval_fn_call_expr(EvalFn *ef, AstNode *node, ConstExprValue *out_val
713713 }
714714
715715 if (!fn_table_entry) {
716 zig_panic("TODO");
716 ConstExprValue fn_val = {0};
717 if (eval_expr(ef, fn_ref_expr, &fn_val)) return true;
718 fn_table_entry = fn_val.data.x_fn;
717719 }
718720
719721 int param_count = node->data.fn_call_expr.params.length;
test/run_tests.cpp+15
......@@ -1491,6 +1491,21 @@ fn foo(x: i32) -> i32 {
14911491 ".tmp_source.zig:3:1: error: function evaluation caused division by zero",
14921492 ".tmp_source.zig:2:14: note: called from here",
14931493 ".tmp_source.zig:4:7: note: division by zero here");
1494
1495 add_compile_fail_case("branch on undefined value", R"SOURCE(
1496const x = if (undefined) true else false;
1497 )SOURCE", 1, ".tmp_source.zig:2:15: error: branch on undefined value");
1498
1499
1500 add_compile_fail_case("endless loop in function evaluation", R"SOURCE(
1501const seventh_fib_number = fibbonaci(7);
1502fn fibbonaci(x: i32) -> i32 {
1503 return fibbonaci(x - 1) + fibbonaci(x - 2);
1504}
1505 )SOURCE", 3,
1506 ".tmp_source.zig:3:1: error: function evaluation exceeded 1000 branches",
1507 ".tmp_source.zig:2:37: note: called from here",
1508 ".tmp_source.zig:4:40: note: quota exceeded here");
14941509}
14951510
14961511//////////////////////////////////////////////////////////////////////////////
test/self_hosted.zig+53-3
......@@ -415,9 +415,7 @@ error err2;
415415
416416#attribute("test")
417417fn fn_call_of_struct_field() {
418 if (call_struct_field(Foo {.ptr = a_func,}) != 13) {
419 unreachable{};
420 }
418 assert(call_struct_field(Foo {.ptr = a_func,}) == 13);
421419}
422420
423421struct Foo {
......@@ -911,3 +909,55 @@ struct MemberFnRand {
911909 r.seed
912910 }
913911}
912
913#attribute("test")
914fn static_function_evaluation() {
915 assert(statically_added_number == 3);
916}
917const statically_added_number = static_add(1, 2);
918fn static_add(a: i32, b: i32) -> i32 { a + b }
919
920
921#attribute("test")
922fn statically_initalized_list() {
923 assert(static_point_list[0].x == 1);
924 assert(static_point_list[0].y == 2);
925 assert(static_point_list[1].x == 3);
926 assert(static_point_list[1].y == 4);
927}
928struct Point {
929 x: i32,
930 y: i32,
931}
932const static_point_list = []Point { make_point(1, 2), make_point(3, 4) };
933fn make_point(x: i32, y: i32) -> Point {
934 return Point {
935 .x = x,
936 .y = y,
937 };
938}
939
940
941#attribute("test")
942fn static_eval_recursive() {
943 assert(seventh_fib_number == 21);
944}
945const seventh_fib_number = fibbonaci(7);
946fn fibbonaci(x: i32) -> i32 {
947 if (x <= 1) return 1;
948 return fibbonaci(x - 1) + fibbonaci(x - 2);
949}
950
951#attribute("test")
952fn static_eval_while() {
953 assert(static_eval_while_number == 1);
954}
955const static_eval_while_number = static_while_loop_1();
956fn static_while_loop_1() -> i32 {
957 return while_loop_2();
958}
959fn static_while_loop_2() -> i32 {
960 while (true) {
961 return 1;
962 }
963}