more eval tests and fix eval call analyze code
parent
69109bc270
commit
3c27cb2527
|
@ -4504,28 +4504,23 @@ static TypeTableEntry *analyze_fn_call_ptr(CodeGen *g, ImportTableEntry *import,
|
|||
}
|
||||
|
||||
FnTableEntry *fn_table_entry = node->data.fn_call_expr.fn_entry;
|
||||
if (ok_invocation && fn_table_entry && fn_table_entry->is_pure && all_args_const_expr) {
|
||||
if (ok_invocation && fn_table_entry && fn_table_entry->is_pure) {
|
||||
if (fn_table_entry->anal_state == FnAnalStateReady) {
|
||||
analyze_fn_body(g, fn_table_entry);
|
||||
} else if (fn_table_entry->anal_state == FnAnalStateProbing) {
|
||||
mark_impure_fn(context);
|
||||
}
|
||||
if (fn_table_entry->is_pure) {
|
||||
if (fn_table_entry->anal_state == FnAnalStateComplete) {
|
||||
if (all_args_const_expr) {
|
||||
if (fn_table_entry->is_pure && fn_table_entry->anal_state == FnAnalStateComplete) {
|
||||
ConstExprValue *result_val = &get_resolved_expr(node)->const_val;
|
||||
if (eval_fn(g, node, fn_table_entry, result_val, 1000, struct_node)) {
|
||||
// function evaluation generated an error
|
||||
return g->builtin_types.entry_invalid;
|
||||
}
|
||||
return return_type;
|
||||
} else if (fn_table_entry->anal_state == FnAnalStateSkipped) {
|
||||
return g->builtin_types.entry_invalid;
|
||||
}
|
||||
} else {
|
||||
// calling an impure fn is impure
|
||||
mark_impure_fn(context);
|
||||
}
|
||||
} else {
|
||||
}
|
||||
if (!ok_invocation || !fn_table_entry || !fn_table_entry->is_pure) {
|
||||
// calling an impure fn is impure
|
||||
mark_impure_fn(context);
|
||||
}
|
||||
|
||||
|
|
|
@ -713,7 +713,9 @@ static bool eval_fn_call_expr(EvalFn *ef, AstNode *node, ConstExprValue *out_val
|
|||
}
|
||||
|
||||
if (!fn_table_entry) {
|
||||
zig_panic("TODO");
|
||||
ConstExprValue fn_val = {0};
|
||||
if (eval_expr(ef, fn_ref_expr, &fn_val)) return true;
|
||||
fn_table_entry = fn_val.data.x_fn;
|
||||
}
|
||||
|
||||
int param_count = node->data.fn_call_expr.params.length;
|
||||
|
|
|
@ -1491,6 +1491,21 @@ fn foo(x: i32) -> i32 {
|
|||
".tmp_source.zig:3:1: error: function evaluation caused division by zero",
|
||||
".tmp_source.zig:2:14: note: called from here",
|
||||
".tmp_source.zig:4:7: note: division by zero here");
|
||||
|
||||
add_compile_fail_case("branch on undefined value", R"SOURCE(
|
||||
const x = if (undefined) true else false;
|
||||
)SOURCE", 1, ".tmp_source.zig:2:15: error: branch on undefined value");
|
||||
|
||||
|
||||
add_compile_fail_case("endless loop in function evaluation", R"SOURCE(
|
||||
const seventh_fib_number = fibbonaci(7);
|
||||
fn fibbonaci(x: i32) -> i32 {
|
||||
return fibbonaci(x - 1) + fibbonaci(x - 2);
|
||||
}
|
||||
)SOURCE", 3,
|
||||
".tmp_source.zig:3:1: error: function evaluation exceeded 1000 branches",
|
||||
".tmp_source.zig:2:37: note: called from here",
|
||||
".tmp_source.zig:4:40: note: quota exceeded here");
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -415,9 +415,7 @@ error err2;
|
|||
|
||||
#attribute("test")
|
||||
fn fn_call_of_struct_field() {
|
||||
if (call_struct_field(Foo {.ptr = a_func,}) != 13) {
|
||||
unreachable{};
|
||||
}
|
||||
assert(call_struct_field(Foo {.ptr = a_func,}) == 13);
|
||||
}
|
||||
|
||||
struct Foo {
|
||||
|
@ -911,3 +909,55 @@ struct MemberFnRand {
|
|||
r.seed
|
||||
}
|
||||
}
|
||||
|
||||
#attribute("test")
|
||||
fn static_function_evaluation() {
|
||||
assert(statically_added_number == 3);
|
||||
}
|
||||
const statically_added_number = static_add(1, 2);
|
||||
fn static_add(a: i32, b: i32) -> i32 { a + b }
|
||||
|
||||
|
||||
#attribute("test")
|
||||
fn statically_initalized_list() {
|
||||
assert(static_point_list[0].x == 1);
|
||||
assert(static_point_list[0].y == 2);
|
||||
assert(static_point_list[1].x == 3);
|
||||
assert(static_point_list[1].y == 4);
|
||||
}
|
||||
struct Point {
|
||||
x: i32,
|
||||
y: i32,
|
||||
}
|
||||
const static_point_list = []Point { make_point(1, 2), make_point(3, 4) };
|
||||
fn make_point(x: i32, y: i32) -> Point {
|
||||
return Point {
|
||||
.x = x,
|
||||
.y = y,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#attribute("test")
|
||||
fn static_eval_recursive() {
|
||||
assert(seventh_fib_number == 21);
|
||||
}
|
||||
const seventh_fib_number = fibbonaci(7);
|
||||
fn fibbonaci(x: i32) -> i32 {
|
||||
if (x <= 1) return 1;
|
||||
return fibbonaci(x - 1) + fibbonaci(x - 2);
|
||||
}
|
||||
|
||||
#attribute("test")
|
||||
fn static_eval_while() {
|
||||
assert(static_eval_while_number == 1);
|
||||
}
|
||||
const static_eval_while_number = static_while_loop_1();
|
||||
fn static_while_loop_1() -> i32 {
|
||||
return while_loop_2();
|
||||
}
|
||||
fn static_while_loop_2() -> i32 {
|
||||
while (true) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue