| ... | @@ -13,6 +13,7 @@ | ... | @@ -13,6 +13,7 @@ |
| 13 | #include "parseh.hpp" | 13 | #include "parseh.hpp" |
| 14 | #include "config.h" | 14 | #include "config.h" |
| 15 | #include "ast_render.hpp" | 15 | #include "ast_render.hpp" |
| | 16 | #include "eval.hpp" |
| 16 | | 17 | |
| 17 | static TypeTableEntry *analyze_expression(CodeGen *g, ImportTableEntry *import, BlockContext *context, | 18 | static TypeTableEntry *analyze_expression(CodeGen *g, ImportTableEntry *import, BlockContext *context, |
| 18 | TypeTableEntry *expected_type, AstNode *node); | 19 | TypeTableEntry *expected_type, AstNode *node); |
| ... | @@ -1374,6 +1375,7 @@ static void preview_fn_proto_instance(CodeGen *g, ImportTableEntry *import, AstN | ... | @@ -1374,6 +1375,7 @@ static void preview_fn_proto_instance(CodeGen *g, ImportTableEntry *import, AstN |
| 1374 | fn_table_entry->proto_node = proto_node; | 1375 | fn_table_entry->proto_node = proto_node; |
| 1375 | fn_table_entry->fn_def_node = fn_def_node; | 1376 | fn_table_entry->fn_def_node = fn_def_node; |
| 1376 | fn_table_entry->is_extern = is_extern; | 1377 | fn_table_entry->is_extern = is_extern; |
| | 1378 | fn_table_entry->is_pure = !is_extern; |
| 1377 | | 1379 | |
| 1378 | get_fully_qualified_decl_name(&fn_table_entry->symbol_name, proto_node, '_'); | 1380 | get_fully_qualified_decl_name(&fn_table_entry->symbol_name, proto_node, '_'); |
| 1379 | | 1381 | |
| ... | @@ -2443,6 +2445,12 @@ static TypeTableEntry *analyze_slice_expr(CodeGen *g, ImportTableEntry *import, | ... | @@ -2443,6 +2445,12 @@ static TypeTableEntry *analyze_slice_expr(CodeGen *g, ImportTableEntry *import, |
| 2443 | return return_type; | 2445 | return return_type; |
| 2444 | } | 2446 | } |
| 2445 | | 2447 | |
| | 2448 | static void mark_impure_fn(BlockContext *context) { |
| | 2449 | if (context->fn_entry) { |
| | 2450 | context->fn_entry->is_pure = false; |
| | 2451 | } |
| | 2452 | } |
| | 2453 | |
| 2446 | static TypeTableEntry *analyze_array_access_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context, | 2454 | static TypeTableEntry *analyze_array_access_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context, |
| 2447 | AstNode *node) | 2455 | AstNode *node) |
| 2448 | { | 2456 | { |
| ... | @@ -2478,6 +2486,7 @@ static TypeTableEntry *analyze_array_access_expr(CodeGen *g, ImportTableEntry *i | ... | @@ -2478,6 +2486,7 @@ static TypeTableEntry *analyze_array_access_expr(CodeGen *g, ImportTableEntry *i |
| 2478 | static TypeTableEntry *resolve_expr_const_val_as_void(CodeGen *g, AstNode *node) { | 2486 | static TypeTableEntry *resolve_expr_const_val_as_void(CodeGen *g, AstNode *node) { |
| 2479 | Expr *expr = get_resolved_expr(node); | 2487 | Expr *expr = get_resolved_expr(node); |
| 2480 | expr->const_val.ok = true; | 2488 | expr->const_val.ok = true; |
| | 2489 | expr->const_val.deep_const = true; |
| 2481 | return g->builtin_types.entry_void; | 2490 | return g->builtin_types.entry_void; |
| 2482 | } | 2491 | } |
| 2483 | | 2492 | |
| ... | @@ -2485,6 +2494,7 @@ static TypeTableEntry *resolve_expr_const_val_as_type(CodeGen *g, AstNode *node, | ... | @@ -2485,6 +2494,7 @@ static TypeTableEntry *resolve_expr_const_val_as_type(CodeGen *g, AstNode *node, |
| 2485 | Expr *expr = get_resolved_expr(node); | 2494 | Expr *expr = get_resolved_expr(node); |
| 2486 | expr->const_val.ok = true; | 2495 | expr->const_val.ok = true; |
| 2487 | expr->const_val.data.x_type = type; | 2496 | expr->const_val.data.x_type = type; |
| | 2497 | expr->const_val.deep_const = true; |
| 2488 | return g->builtin_types.entry_type; | 2498 | return g->builtin_types.entry_type; |
| 2489 | } | 2499 | } |
| 2490 | | 2500 | |
| ... | @@ -2499,6 +2509,7 @@ static TypeTableEntry *resolve_expr_const_val_as_fn(CodeGen *g, AstNode *node, F | ... | @@ -2499,6 +2509,7 @@ static TypeTableEntry *resolve_expr_const_val_as_fn(CodeGen *g, AstNode *node, F |
| 2499 | Expr *expr = get_resolved_expr(node); | 2509 | Expr *expr = get_resolved_expr(node); |
| 2500 | expr->const_val.ok = true; | 2510 | expr->const_val.ok = true; |
| 2501 | expr->const_val.data.x_fn = fn; | 2511 | expr->const_val.data.x_fn = fn; |
| | 2512 | expr->const_val.deep_const = true; |
| 2502 | return fn->type_entry; | 2513 | return fn->type_entry; |
| 2503 | } | 2514 | } |
| 2504 | | 2515 | |
| ... | @@ -2508,6 +2519,7 @@ static TypeTableEntry *resolve_expr_const_val_as_generic_fn(CodeGen *g, AstNode | ... | @@ -2508,6 +2519,7 @@ static TypeTableEntry *resolve_expr_const_val_as_generic_fn(CodeGen *g, AstNode |
| 2508 | Expr *expr = get_resolved_expr(node); | 2519 | Expr *expr = get_resolved_expr(node); |
| 2509 | expr->const_val.ok = true; | 2520 | expr->const_val.ok = true; |
| 2510 | expr->const_val.data.x_type = type_entry; | 2521 | expr->const_val.data.x_type = type_entry; |
| | 2522 | expr->const_val.deep_const = true; |
| 2511 | return type_entry; | 2523 | return type_entry; |
| 2512 | } | 2524 | } |
| 2513 | | 2525 | |
| ... | @@ -2515,6 +2527,7 @@ static TypeTableEntry *resolve_expr_const_val_as_err(CodeGen *g, AstNode *node, | ... | @@ -2515,6 +2527,7 @@ static TypeTableEntry *resolve_expr_const_val_as_err(CodeGen *g, AstNode *node, |
| 2515 | Expr *expr = get_resolved_expr(node); | 2527 | Expr *expr = get_resolved_expr(node); |
| 2516 | expr->const_val.ok = true; | 2528 | expr->const_val.ok = true; |
| 2517 | expr->const_val.data.x_err.err = err; | 2529 | expr->const_val.data.x_err.err = err; |
| | 2530 | expr->const_val.deep_const = true; |
| 2518 | return g->builtin_types.entry_pure_error; | 2531 | return g->builtin_types.entry_pure_error; |
| 2519 | } | 2532 | } |
| 2520 | | 2533 | |
| ... | @@ -2525,6 +2538,7 @@ static TypeTableEntry *resolve_expr_const_val_as_bool(CodeGen *g, AstNode *node, | ... | @@ -2525,6 +2538,7 @@ static TypeTableEntry *resolve_expr_const_val_as_bool(CodeGen *g, AstNode *node, |
| 2525 | expr->const_val.ok = true; | 2538 | expr->const_val.ok = true; |
| 2526 | expr->const_val.depends_on_compile_var = depends_on_compile_var; | 2539 | expr->const_val.depends_on_compile_var = depends_on_compile_var; |
| 2527 | expr->const_val.data.x_bool = value; | 2540 | expr->const_val.data.x_bool = value; |
| | 2541 | expr->const_val.deep_const = true; |
| 2528 | return g->builtin_types.entry_bool; | 2542 | return g->builtin_types.entry_bool; |
| 2529 | } | 2543 | } |
| 2530 | | 2544 | |
| ... | @@ -2532,6 +2546,7 @@ static TypeTableEntry *resolve_expr_const_val_as_null(CodeGen *g, AstNode *node, | ... | @@ -2532,6 +2546,7 @@ static TypeTableEntry *resolve_expr_const_val_as_null(CodeGen *g, AstNode *node, |
| 2532 | Expr *expr = get_resolved_expr(node); | 2546 | Expr *expr = get_resolved_expr(node); |
| 2533 | expr->const_val.ok = true; | 2547 | expr->const_val.ok = true; |
| 2534 | expr->const_val.data.x_maybe = nullptr; | 2548 | expr->const_val.data.x_maybe = nullptr; |
| | 2549 | expr->const_val.deep_const = true; |
| 2535 | return type; | 2550 | return type; |
| 2536 | } | 2551 | } |
| 2537 | | 2552 | |
| ... | @@ -2542,12 +2557,14 @@ static TypeTableEntry *resolve_expr_const_val_as_non_null(CodeGen *g, AstNode *n | ... | @@ -2542,12 +2557,14 @@ static TypeTableEntry *resolve_expr_const_val_as_non_null(CodeGen *g, AstNode *n |
| 2542 | Expr *expr = get_resolved_expr(node); | 2557 | Expr *expr = get_resolved_expr(node); |
| 2543 | expr->const_val.ok = true; | 2558 | expr->const_val.ok = true; |
| 2544 | expr->const_val.data.x_maybe = other_val; | 2559 | expr->const_val.data.x_maybe = other_val; |
| | 2560 | expr->const_val.deep_const = other_val->deep_const; |
| 2545 | return type; | 2561 | return type; |
| 2546 | } | 2562 | } |
| 2547 | | 2563 | |
| 2548 | static TypeTableEntry *resolve_expr_const_val_as_c_string_lit(CodeGen *g, AstNode *node, Buf *str) { | 2564 | static TypeTableEntry *resolve_expr_const_val_as_c_string_lit(CodeGen *g, AstNode *node, Buf *str) { |
| 2549 | Expr *expr = get_resolved_expr(node); | 2565 | Expr *expr = get_resolved_expr(node); |
| 2550 | expr->const_val.ok = true; | 2566 | expr->const_val.ok = true; |
| | 2567 | expr->const_val.deep_const = true; |
| 2551 | | 2568 | |
| 2552 | int len_with_null = buf_len(str) + 1; | 2569 | int len_with_null = buf_len(str) + 1; |
| 2553 | expr->const_val.data.x_ptr.ptr = allocate<ConstExprValue*>(len_with_null); | 2570 | expr->const_val.data.x_ptr.ptr = allocate<ConstExprValue*>(len_with_null); |
| ... | @@ -2557,12 +2574,14 @@ static TypeTableEntry *resolve_expr_const_val_as_c_string_lit(CodeGen *g, AstNod | ... | @@ -2557,12 +2574,14 @@ static TypeTableEntry *resolve_expr_const_val_as_c_string_lit(CodeGen *g, AstNod |
| 2557 | for (int i = 0; i < buf_len(str); i += 1) { | 2574 | for (int i = 0; i < buf_len(str); i += 1) { |
| 2558 | ConstExprValue *this_char = &all_chars[i]; | 2575 | ConstExprValue *this_char = &all_chars[i]; |
| 2559 | this_char->ok = true; | 2576 | this_char->ok = true; |
| | 2577 | this_char->deep_const = true; |
| 2560 | bignum_init_unsigned(&this_char->data.x_bignum, buf_ptr(str)[i]); | 2578 | bignum_init_unsigned(&this_char->data.x_bignum, buf_ptr(str)[i]); |
| 2561 | expr->const_val.data.x_ptr.ptr[i] = this_char; | 2579 | expr->const_val.data.x_ptr.ptr[i] = this_char; |
| 2562 | } | 2580 | } |
| 2563 | | 2581 | |
| 2564 | ConstExprValue *null_char = &all_chars[len_with_null - 1]; | 2582 | ConstExprValue *null_char = &all_chars[len_with_null - 1]; |
| 2565 | null_char->ok = true; | 2583 | null_char->ok = true; |
| | 2584 | null_char->deep_const = true; |
| 2566 | bignum_init_unsigned(&null_char->data.x_bignum, 0); | 2585 | bignum_init_unsigned(&null_char->data.x_bignum, 0); |
| 2567 | expr->const_val.data.x_ptr.ptr[len_with_null - 1] = null_char; | 2586 | expr->const_val.data.x_ptr.ptr[len_with_null - 1] = null_char; |
| 2568 | | 2587 | |
| ... | @@ -2572,12 +2591,14 @@ static TypeTableEntry *resolve_expr_const_val_as_c_string_lit(CodeGen *g, AstNod | ... | @@ -2572,12 +2591,14 @@ static TypeTableEntry *resolve_expr_const_val_as_c_string_lit(CodeGen *g, AstNod |
| 2572 | static TypeTableEntry *resolve_expr_const_val_as_string_lit(CodeGen *g, AstNode *node, Buf *str) { | 2591 | static TypeTableEntry *resolve_expr_const_val_as_string_lit(CodeGen *g, AstNode *node, Buf *str) { |
| 2573 | Expr *expr = get_resolved_expr(node); | 2592 | Expr *expr = get_resolved_expr(node); |
| 2574 | expr->const_val.ok = true; | 2593 | expr->const_val.ok = true; |
| | 2594 | expr->const_val.deep_const = true; |
| 2575 | expr->const_val.data.x_array.fields = allocate<ConstExprValue*>(buf_len(str)); | 2595 | expr->const_val.data.x_array.fields = allocate<ConstExprValue*>(buf_len(str)); |
| 2576 | | 2596 | |
| 2577 | ConstExprValue *all_chars = allocate<ConstExprValue>(buf_len(str)); | 2597 | ConstExprValue *all_chars = allocate<ConstExprValue>(buf_len(str)); |
| 2578 | for (int i = 0; i < buf_len(str); i += 1) { | 2598 | for (int i = 0; i < buf_len(str); i += 1) { |
| 2579 | ConstExprValue *this_char = &all_chars[i]; | 2599 | ConstExprValue *this_char = &all_chars[i]; |
| 2580 | this_char->ok = true; | 2600 | this_char->ok = true; |
| | 2601 | this_char->deep_const = true; |
| 2581 | bignum_init_unsigned(&this_char->data.x_bignum, buf_ptr(str)[i]); | 2602 | bignum_init_unsigned(&this_char->data.x_bignum, buf_ptr(str)[i]); |
| 2582 | expr->const_val.data.x_array.fields[i] = this_char; | 2603 | expr->const_val.data.x_array.fields[i] = this_char; |
| 2583 | } | 2604 | } |
| ... | @@ -2590,6 +2611,7 @@ static TypeTableEntry *resolve_expr_const_val_as_unsigned_num_lit(CodeGen *g, As | ... | @@ -2590,6 +2611,7 @@ static TypeTableEntry *resolve_expr_const_val_as_unsigned_num_lit(CodeGen *g, As |
| 2590 | { | 2611 | { |
| 2591 | Expr *expr = get_resolved_expr(node); | 2612 | Expr *expr = get_resolved_expr(node); |
| 2592 | expr->const_val.ok = true; | 2613 | expr->const_val.ok = true; |
| | 2614 | expr->const_val.deep_const = true; |
| 2593 | | 2615 | |
| 2594 | bignum_init_unsigned(&expr->const_val.data.x_bignum, x); | 2616 | bignum_init_unsigned(&expr->const_val.data.x_bignum, x); |
| 2595 | | 2617 | |
| ... | @@ -2601,6 +2623,7 @@ static TypeTableEntry *resolve_expr_const_val_as_float_num_lit(CodeGen *g, AstNo | ... | @@ -2601,6 +2623,7 @@ static TypeTableEntry *resolve_expr_const_val_as_float_num_lit(CodeGen *g, AstNo |
| 2601 | { | 2623 | { |
| 2602 | Expr *expr = get_resolved_expr(node); | 2624 | Expr *expr = get_resolved_expr(node); |
| 2603 | expr->const_val.ok = true; | 2625 | expr->const_val.ok = true; |
| | 2626 | expr->const_val.deep_const = true; |
| 2604 | | 2627 | |
| 2605 | bignum_init_float(&expr->const_val.data.x_bignum, x); | 2628 | bignum_init_float(&expr->const_val.data.x_bignum, x); |
| 2606 | | 2629 | |
| ... | @@ -2616,6 +2639,7 @@ static TypeTableEntry *resolve_expr_const_val_as_bignum_op(CodeGen *g, AstNode * | ... | @@ -2616,6 +2639,7 @@ static TypeTableEntry *resolve_expr_const_val_as_bignum_op(CodeGen *g, AstNode * |
| 2616 | ConstExprValue *op2_val = &get_resolved_expr(op2)->const_val; | 2639 | ConstExprValue *op2_val = &get_resolved_expr(op2)->const_val; |
| 2617 | | 2640 | |
| 2618 | const_val->ok = true; | 2641 | const_val->ok = true; |
| | 2642 | const_val->deep_const = true; |
| 2619 | | 2643 | |
| 2620 | if (bignum_fn(&const_val->data.x_bignum, &op1_val->data.x_bignum, &op2_val->data.x_bignum)) { | 2644 | if (bignum_fn(&const_val->data.x_bignum, &op1_val->data.x_bignum, &op2_val->data.x_bignum)) { |
| 2621 | add_node_error(g, node, | 2645 | add_node_error(g, node, |
| ... | @@ -2684,6 +2708,19 @@ static TypeTableEntry *analyze_decl_ref(CodeGen *g, AstNode *source_node, AstNod | ... | @@ -2684,6 +2708,19 @@ static TypeTableEntry *analyze_decl_ref(CodeGen *g, AstNode *source_node, AstNod |
| 2684 | } | 2708 | } |
| 2685 | } | 2709 | } |
| 2686 | | 2710 | |
| | 2711 | static bool var_is_pure(VariableTableEntry *var, TypeTableEntry *var_type, BlockContext *context) { |
| | 2712 | if (var->block_context->fn_entry == context->fn_entry) { |
| | 2713 | // variable was declared in the current function, so it's OK. |
| | 2714 | return true; |
| | 2715 | } |
| | 2716 | if (!var->is_const) { |
| | 2717 | return false; |
| | 2718 | } |
| | 2719 | |
| | 2720 | ConstExprValue *const_val = &get_resolved_expr(var->val_node)->const_val; |
| | 2721 | return const_val->deep_const; |
| | 2722 | } |
| | 2723 | |
| 2687 | static TypeTableEntry *analyze_symbol_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context, | 2724 | static TypeTableEntry *analyze_symbol_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context, |
| 2688 | TypeTableEntry *expected_type, AstNode *node, bool pointer_only) | 2725 | TypeTableEntry *expected_type, AstNode *node, bool pointer_only) |
| 2689 | { | 2726 | { |
| ... | @@ -2700,7 +2737,11 @@ static TypeTableEntry *analyze_symbol_expr(CodeGen *g, ImportTableEntry *import, | ... | @@ -2700,7 +2737,11 @@ static TypeTableEntry *analyze_symbol_expr(CodeGen *g, ImportTableEntry *import, |
| 2700 | | 2737 | |
| 2701 | VariableTableEntry *var = find_variable(g, context, variable_name); | 2738 | VariableTableEntry *var = find_variable(g, context, variable_name); |
| 2702 | if (var) { | 2739 | if (var) { |
| 2703 | return analyze_var_ref(g, node, var); | 2740 | TypeTableEntry *var_type = analyze_var_ref(g, node, var); |
| | 2741 | if (!var_is_pure(var, var_type, context)) { |
| | 2742 | mark_impure_fn(context); |
| | 2743 | } |
| | 2744 | return var_type; |
| 2704 | } | 2745 | } |
| 2705 | | 2746 | |
| 2706 | AstNode *decl_node = find_decl(context, variable_name); | 2747 | AstNode *decl_node = find_decl(context, variable_name); |
| ... | @@ -2840,71 +2881,6 @@ static TypeTableEntry *analyze_lvalue(CodeGen *g, ImportTableEntry *import, Bloc | ... | @@ -2840,71 +2881,6 @@ static TypeTableEntry *analyze_lvalue(CodeGen *g, ImportTableEntry *import, Bloc |
| 2840 | return expected_rhs_type; | 2881 | return expected_rhs_type; |
| 2841 | } | 2882 | } |
| 2842 | | 2883 | |
| 2843 | static bool eval_bool_bin_op_bool(bool a, BinOpType bin_op, bool b) { | | |
| 2844 | if (bin_op == BinOpTypeBoolOr) { | | |
| 2845 | return a || b; | | |
| 2846 | } else if (bin_op == BinOpTypeBoolAnd) { | | |
| 2847 | return a && b; | | |
| 2848 | } else { | | |
| 2849 | zig_unreachable(); | | |
| 2850 | } | | |
| 2851 | } | | |
| 2852 | | | |
| 2853 | static bool const_values_equal(ConstExprValue *a, ConstExprValue *b, TypeTableEntry *type_entry) { | | |
| 2854 | switch (type_entry->id) { | | |
| 2855 | case TypeTableEntryIdEnum: | | |
| 2856 | { | | |
| 2857 | ConstEnumValue *enum1 = &a->data.x_enum; | | |
| 2858 | ConstEnumValue *enum2 = &b->data.x_enum; | | |
| 2859 | if (enum1->tag == enum2->tag) { | | |
| 2860 | TypeEnumField *enum_field = &type_entry->data.enumeration.fields[enum1->tag]; | | |
| 2861 | if (type_has_bits(enum_field->type_entry)) { | | |
| 2862 | zig_panic("TODO const expr analyze enum special value for equality"); | | |
| 2863 | } else { | | |
| 2864 | return true; | | |
| 2865 | } | | |
| 2866 | } | | |
| 2867 | return false; | | |
| 2868 | } | | |
| 2869 | case TypeTableEntryIdMetaType: | | |
| 2870 | return a->data.x_type == b->data.x_type; | | |
| 2871 | case TypeTableEntryIdVoid: | | |
| 2872 | return true; | | |
| 2873 | case TypeTableEntryIdPureError: | | |
| 2874 | return a->data.x_err.err == b->data.x_err.err; | | |
| 2875 | case TypeTableEntryIdFn: | | |
| 2876 | return a->data.x_fn == b->data.x_fn; | | |
| 2877 | case TypeTableEntryIdBool: | | |
| 2878 | return a->data.x_bool == b->data.x_bool; | | |
| 2879 | case TypeTableEntryIdInt: | | |
| 2880 | case TypeTableEntryIdFloat: | | |
| 2881 | case TypeTableEntryIdNumLitFloat: | | |
| 2882 | case TypeTableEntryIdNumLitInt: | | |
| 2883 | return bignum_cmp_eq(&a->data.x_bignum, &b->data.x_bignum); | | |
| 2884 | case TypeTableEntryIdPointer: | | |
| 2885 | zig_panic("TODO"); | | |
| 2886 | case TypeTableEntryIdArray: | | |
| 2887 | zig_panic("TODO"); | | |
| 2888 | case TypeTableEntryIdStruct: | | |
| 2889 | zig_panic("TODO"); | | |
| 2890 | case TypeTableEntryIdUndefLit: | | |
| 2891 | zig_panic("TODO"); | | |
| 2892 | case TypeTableEntryIdMaybe: | | |
| 2893 | zig_panic("TODO"); | | |
| 2894 | case TypeTableEntryIdErrorUnion: | | |
| 2895 | zig_panic("TODO"); | | |
| 2896 | case TypeTableEntryIdTypeDecl: | | |
| 2897 | zig_panic("TODO"); | | |
| 2898 | case TypeTableEntryIdNamespace: | | |
| 2899 | zig_panic("TODO"); | | |
| 2900 | case TypeTableEntryIdGenericFn: | | |
| 2901 | case TypeTableEntryIdInvalid: | | |
| 2902 | case TypeTableEntryIdUnreachable: | | |
| 2903 | zig_unreachable(); | | |
| 2904 | } | | |
| 2905 | zig_unreachable(); | | |
| 2906 | } | | |
| 2907 | | | |
| 2908 | static TypeTableEntry *analyze_bool_bin_op_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context, | 2884 | static TypeTableEntry *analyze_bool_bin_op_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context, |
| 2909 | AstNode *node) | 2885 | AstNode *node) |
| 2910 | { | 2886 | { |
| ... | @@ -2944,39 +2920,11 @@ static TypeTableEntry *analyze_bool_bin_op_expr(CodeGen *g, ImportTableEntry *im | ... | @@ -2944,39 +2920,11 @@ static TypeTableEntry *analyze_bool_bin_op_expr(CodeGen *g, ImportTableEntry *im |
| 2944 | return g->builtin_types.entry_bool; | 2920 | return g->builtin_types.entry_bool; |
| 2945 | } | 2921 | } |
| 2946 | | 2922 | |
| 2947 | bool answer; | | |
| 2948 | if (type_can_gt_lt_cmp) { | | |
| 2949 | bool (*bignum_cmp)(BigNum *, BigNum *); | | |
| 2950 | if (bin_op_type == BinOpTypeCmpEq) { | | |
| 2951 | bignum_cmp = bignum_cmp_eq; | | |
| 2952 | } else if (bin_op_type == BinOpTypeCmpNotEq) { | | |
| 2953 | bignum_cmp = bignum_cmp_neq; | | |
| 2954 | } else if (bin_op_type == BinOpTypeCmpLessThan) { | | |
| 2955 | bignum_cmp = bignum_cmp_lt; | | |
| 2956 | } else if (bin_op_type == BinOpTypeCmpGreaterThan) { | | |
| 2957 | bignum_cmp = bignum_cmp_gt; | | |
| 2958 | } else if (bin_op_type == BinOpTypeCmpLessOrEq) { | | |
| 2959 | bignum_cmp = bignum_cmp_lte; | | |
| 2960 | } else if (bin_op_type == BinOpTypeCmpGreaterOrEq) { | | |
| 2961 | bignum_cmp = bignum_cmp_gte; | | |
| 2962 | } else { | | |
| 2963 | zig_unreachable(); | | |
| 2964 | } | | |
| 2965 | | 2923 | |
| 2966 | answer = bignum_cmp(&op1_val->data.x_bignum, &op2_val->data.x_bignum); | 2924 | ConstExprValue *out_val = &get_resolved_expr(node)->const_val; |
| 2967 | } else { | 2925 | eval_const_expr_bin_op(op1_val, op1_type, bin_op_type, op2_val, op2_type, out_val); |
| 2968 | bool are_equal = const_values_equal(op1_val, op2_val, resolved_type); | 2926 | return g->builtin_types.entry_bool; |
| 2969 | if (bin_op_type == BinOpTypeCmpEq) { | | |
| 2970 | answer = are_equal; | | |
| 2971 | } else if (bin_op_type == BinOpTypeCmpNotEq) { | | |
| 2972 | answer = !are_equal; | | |
| 2973 | } else { | | |
| 2974 | zig_unreachable(); | | |
| 2975 | } | | |
| 2976 | } | | |
| 2977 | | 2927 | |
| 2978 | bool depends_on_compile_var = op1_val->depends_on_compile_var || op2_val->depends_on_compile_var; | | |
| 2979 | return resolve_expr_const_val_as_bool(g, node, answer, depends_on_compile_var); | | |
| 2980 | } | 2928 | } |
| 2981 | | 2929 | |
| 2982 | static TypeTableEntry *analyze_logic_bin_op_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context, | 2930 | static TypeTableEntry *analyze_logic_bin_op_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context, |
| ... | @@ -3002,9 +2950,9 @@ static TypeTableEntry *analyze_logic_bin_op_expr(CodeGen *g, ImportTableEntry *i | ... | @@ -3002,9 +2950,9 @@ static TypeTableEntry *analyze_logic_bin_op_expr(CodeGen *g, ImportTableEntry *i |
| 3002 | return g->builtin_types.entry_bool; | 2950 | return g->builtin_types.entry_bool; |
| 3003 | } | 2951 | } |
| 3004 | | 2952 | |
| 3005 | bool answer = eval_bool_bin_op_bool(op1_val->data.x_bool, bin_op_type, op2_val->data.x_bool); | 2953 | ConstExprValue *out_val = &get_resolved_expr(node)->const_val; |
| 3006 | bool depends_on_compile_var = op1_val->depends_on_compile_var || op2_val->depends_on_compile_var; | 2954 | eval_const_expr_bin_op(op1_val, op1_type, bin_op_type, op2_val, op2_type, out_val); |
| 3007 | return resolve_expr_const_val_as_bool(g, node, answer, depends_on_compile_var); | 2955 | return g->builtin_types.entry_bool; |
| 3008 | } | 2956 | } |
| 3009 | | 2957 | |
| 3010 | static TypeTableEntry *analyze_bin_op_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context, | 2958 | static TypeTableEntry *analyze_bin_op_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context, |
| ... | @@ -3041,7 +2989,7 @@ static TypeTableEntry *analyze_bin_op_expr(CodeGen *g, ImportTableEntry *import, | ... | @@ -3041,7 +2989,7 @@ static TypeTableEntry *analyze_bin_op_expr(CodeGen *g, ImportTableEntry *import, |
| 3041 | } | 2989 | } |
| 3042 | | 2990 | |
| 3043 | analyze_expression(g, import, context, expected_rhs_type, node->data.bin_op_expr.op2); | 2991 | analyze_expression(g, import, context, expected_rhs_type, node->data.bin_op_expr.op2); |
| 3044 | return g->builtin_types.entry_void; | 2992 | return resolve_expr_const_val_as_void(g, node); |
| 3045 | } | 2993 | } |
| 3046 | case BinOpTypeBoolOr: | 2994 | case BinOpTypeBoolOr: |
| 3047 | case BinOpTypeBoolAnd: | 2995 | case BinOpTypeBoolAnd: |
| ... | @@ -3720,6 +3668,10 @@ static TypeTableEntry *analyze_if_bool_expr(CodeGen *g, ImportTableEntry *import | ... | @@ -3720,6 +3668,10 @@ static TypeTableEntry *analyze_if_bool_expr(CodeGen *g, ImportTableEntry *import |
| 3720 | } | 3668 | } |
| 3721 | | 3669 | |
| 3722 | ConstExprValue *cond_val = &get_resolved_expr(*cond)->const_val; | 3670 | ConstExprValue *cond_val = &get_resolved_expr(*cond)->const_val; |
| | 3671 | if (cond_val->undef) { |
| | 3672 | add_node_error(g, first_executing_node(*cond), buf_sprintf("branch on undefined value")); |
| | 3673 | return cond_type; |
| | 3674 | } |
| 3723 | if (cond_val->ok && !cond_val->depends_on_compile_var) { | 3675 | if (cond_val->ok && !cond_val->depends_on_compile_var) { |
| 3724 | const char *str_val = cond_val->data.x_bool ? "true" : "false"; | 3676 | const char *str_val = cond_val->data.x_bool ? "true" : "false"; |
| 3725 | add_node_error(g, first_executing_node(*cond), | 3677 | add_node_error(g, first_executing_node(*cond), |
| ... | @@ -3849,92 +3801,18 @@ static TypeTableEntry *analyze_min_max_value(CodeGen *g, ImportTableEntry *impor | ... | @@ -3849,92 +3801,18 @@ static TypeTableEntry *analyze_min_max_value(CodeGen *g, ImportTableEntry *impor |
| 3849 | } | 3801 | } |
| 3850 | } | 3802 | } |
| 3851 | | 3803 | |
| 3852 | static void eval_const_expr_implicit_cast(CodeGen *g, AstNode *node, AstNode *expr_node) { | | |
| 3853 | assert(node->type == NodeTypeFnCallExpr); | | |
| 3854 | ConstExprValue *other_val = &get_resolved_expr(expr_node)->const_val; | | |
| 3855 | ConstExprValue *const_val = &get_resolved_expr(node)->const_val; | | |
| 3856 | if (!other_val->ok) { | | |
| 3857 | return; | | |
| 3858 | } | | |
| 3859 | const_val->depends_on_compile_var = other_val->depends_on_compile_var; | | |
| 3860 | const_val->undef = other_val->undef; | | |
| 3861 | | | |
| 3862 | assert(other_val != const_val); | | |
| 3863 | switch (node->data.fn_call_expr.cast_op) { | | |
| 3864 | case CastOpNoCast: | | |
| 3865 | zig_unreachable(); | | |
| 3866 | case CastOpNoop: | | |
| 3867 | case CastOpWidenOrShorten: | | |
| 3868 | case CastOpPointerReinterpret: | | |
| 3869 | *const_val = *other_val; | | |
| 3870 | break; | | |
| 3871 | case CastOpPtrToInt: | | |
| 3872 | case CastOpIntToPtr: | | |
| 3873 | // can't do it | | |
| 3874 | break; | | |
| 3875 | case CastOpToUnknownSizeArray: | | |
| 3876 | { | | |
| 3877 | TypeTableEntry *other_type = get_resolved_expr(expr_node)->type_entry; | | |
| 3878 | assert(other_type->id == TypeTableEntryIdArray); | | |
| 3879 | | | |
| 3880 | ConstExprValue *all_fields = allocate<ConstExprValue>(2); | | |
| 3881 | ConstExprValue *ptr_field = &all_fields[0]; | | |
| 3882 | ConstExprValue *len_field = &all_fields[1]; | | |
| 3883 | | | |
| 3884 | const_val->data.x_struct.fields = allocate<ConstExprValue*>(2); | | |
| 3885 | const_val->data.x_struct.fields[0] = ptr_field; | | |
| 3886 | const_val->data.x_struct.fields[1] = len_field; | | |
| 3887 | | | |
| 3888 | ptr_field->ok = true; | | |
| 3889 | ptr_field->data.x_ptr.ptr = other_val->data.x_array.fields; | | |
| 3890 | ptr_field->data.x_ptr.len = other_type->data.array.len; | | |
| 3891 | | | |
| 3892 | len_field->ok = true; | | |
| 3893 | bignum_init_unsigned(&len_field->data.x_bignum, other_type->data.array.len); | | |
| 3894 | | | |
| 3895 | const_val->ok = true; | | |
| 3896 | break; | | |
| 3897 | } | | |
| 3898 | case CastOpMaybeWrap: | | |
| 3899 | const_val->data.x_maybe = other_val; | | |
| 3900 | const_val->ok = true; | | |
| 3901 | break; | | |
| 3902 | case CastOpErrorWrap: | | |
| 3903 | const_val->data.x_err.err = nullptr; | | |
| 3904 | const_val->data.x_err.payload = other_val; | | |
| 3905 | const_val->ok = true; | | |
| 3906 | break; | | |
| 3907 | case CastOpPureErrorWrap: | | |
| 3908 | const_val->data.x_err.err = other_val->data.x_err.err; | | |
| 3909 | const_val->ok = true; | | |
| 3910 | break; | | |
| 3911 | case CastOpErrToInt: | | |
| 3912 | { | | |
| 3913 | uint64_t value = other_val->data.x_err.err ? other_val->data.x_err.err->value : 0; | | |
| 3914 | bignum_init_unsigned(&const_val->data.x_bignum, value); | | |
| 3915 | const_val->ok = true; | | |
| 3916 | break; | | |
| 3917 | } | | |
| 3918 | case CastOpIntToFloat: | | |
| 3919 | bignum_cast_to_float(&const_val->data.x_bignum, &other_val->data.x_bignum); | | |
| 3920 | const_val->ok = true; | | |
| 3921 | break; | | |
| 3922 | case CastOpFloatToInt: | | |
| 3923 | bignum_cast_to_int(&const_val->data.x_bignum, &other_val->data.x_bignum); | | |
| 3924 | const_val->ok = true; | | |
| 3925 | break; | | |
| 3926 | case CastOpBoolToInt: | | |
| 3927 | bignum_init_unsigned(&const_val->data.x_bignum, other_val->data.x_bool ? 1 : 0); | | |
| 3928 | const_val->ok = true; | | |
| 3929 | break; | | |
| 3930 | } | | |
| 3931 | } | | |
| 3932 | | | |
| 3933 | static TypeTableEntry *resolve_cast(CodeGen *g, BlockContext *context, AstNode *node, | 3804 | static TypeTableEntry *resolve_cast(CodeGen *g, BlockContext *context, AstNode *node, |
| 3934 | AstNode *expr_node, TypeTableEntry *wanted_type, CastOp op, bool need_alloca) | 3805 | AstNode *expr_node, TypeTableEntry *wanted_type, CastOp op, bool need_alloca) |
| 3935 | { | 3806 | { |
| 3936 | node->data.fn_call_expr.cast_op = op; | 3807 | node->data.fn_call_expr.cast_op = op; |
| 3937 | eval_const_expr_implicit_cast(g, node, expr_node); | 3808 | |
| | 3809 | ConstExprValue *other_val = &get_resolved_expr(expr_node)->const_val; |
| | 3810 | TypeTableEntry *other_type = get_resolved_expr(expr_node)->type_entry; |
| | 3811 | ConstExprValue *const_val = &get_resolved_expr(node)->const_val; |
| | 3812 | if (other_val->ok) { |
| | 3813 | eval_const_expr_implicit_cast(node->data.fn_call_expr.cast_op, other_val, other_type, const_val); |
| | 3814 | } |
| | 3815 | |
| 3938 | if (need_alloca) { | 3816 | if (need_alloca) { |
| 3939 | if (context->fn_entry) { | 3817 | if (context->fn_entry) { |
| 3940 | context->fn_entry->cast_alloca_list.append(node); | 3818 | context->fn_entry->cast_alloca_list.append(node); |
| ... | @@ -4360,6 +4238,8 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry | ... | @@ -4360,6 +4238,8 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry |
| 4360 | } | 4238 | } |
| 4361 | case BuiltinFnIdMemcpy: | 4239 | case BuiltinFnIdMemcpy: |
| 4362 | { | 4240 | { |
| | 4241 | mark_impure_fn(context); |
| | 4242 | |
| 4363 | AstNode *dest_node = node->data.fn_call_expr.params.at(0); | 4243 | AstNode *dest_node = node->data.fn_call_expr.params.at(0); |
| 4364 | AstNode *src_node = node->data.fn_call_expr.params.at(1); | 4244 | AstNode *src_node = node->data.fn_call_expr.params.at(1); |
| 4365 | AstNode *len_node = node->data.fn_call_expr.params.at(2); | 4245 | AstNode *len_node = node->data.fn_call_expr.params.at(2); |
| ... | @@ -4398,6 +4278,8 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry | ... | @@ -4398,6 +4278,8 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry |
| 4398 | } | 4278 | } |
| 4399 | case BuiltinFnIdMemset: | 4279 | case BuiltinFnIdMemset: |
| 4400 | { | 4280 | { |
| | 4281 | mark_impure_fn(context); |
| | 4282 | |
| 4401 | AstNode *dest_node = node->data.fn_call_expr.params.at(0); | 4283 | AstNode *dest_node = node->data.fn_call_expr.params.at(0); |
| 4402 | AstNode *char_node = node->data.fn_call_expr.params.at(1); | 4284 | AstNode *char_node = node->data.fn_call_expr.params.at(1); |
| 4403 | AstNode *len_node = node->data.fn_call_expr.params.at(2); | 4285 | AstNode *len_node = node->data.fn_call_expr.params.at(2); |
| ... | @@ -4630,13 +4512,15 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry | ... | @@ -4630,13 +4512,15 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry |
| 4630 | case BuiltinFnIdErrName: | 4512 | case BuiltinFnIdErrName: |
| 4631 | return analyze_err_name(g, import, context, node); | 4513 | return analyze_err_name(g, import, context, node); |
| 4632 | case BuiltinFnIdBreakpoint: | 4514 | case BuiltinFnIdBreakpoint: |
| | 4515 | mark_impure_fn(context); |
| 4633 | return g->builtin_types.entry_void; | 4516 | return g->builtin_types.entry_void; |
| 4634 | } | 4517 | } |
| 4635 | zig_unreachable(); | 4518 | zig_unreachable(); |
| 4636 | } | 4519 | } |
| 4637 | | 4520 | |
| 4638 | static TypeTableEntry *analyze_fn_call_ptr(CodeGen *g, ImportTableEntry *import, BlockContext *context, | 4521 | static TypeTableEntry *analyze_fn_call_ptr(CodeGen *g, ImportTableEntry *import, BlockContext *context, |
| 4639 | TypeTableEntry *expected_type, AstNode *node, TypeTableEntry *fn_type, TypeTableEntry *struct_type) | 4522 | TypeTableEntry *expected_type, AstNode *node, TypeTableEntry *fn_type, |
| | 4523 | AstNode *struct_node) |
| 4640 | { | 4524 | { |
| 4641 | assert(node->type == NodeTypeFnCallExpr); | 4525 | assert(node->type == NodeTypeFnCallExpr); |
| 4642 | | 4526 | |
| ... | @@ -4648,7 +4532,7 @@ static TypeTableEntry *analyze_fn_call_ptr(CodeGen *g, ImportTableEntry *import, | ... | @@ -4648,7 +4532,7 @@ static TypeTableEntry *analyze_fn_call_ptr(CodeGen *g, ImportTableEntry *import, |
| 4648 | int src_param_count = fn_type->data.fn.fn_type_id.param_count; | 4532 | int src_param_count = fn_type->data.fn.fn_type_id.param_count; |
| 4649 | int actual_param_count = node->data.fn_call_expr.params.length; | 4533 | int actual_param_count = node->data.fn_call_expr.params.length; |
| 4650 | | 4534 | |
| 4651 | if (struct_type) { | 4535 | if (struct_node) { |
| 4652 | actual_param_count += 1; | 4536 | actual_param_count += 1; |
| 4653 | } | 4537 | } |
| 4654 | | 4538 | |
| ... | @@ -4662,17 +4546,31 @@ static TypeTableEntry *analyze_fn_call_ptr(CodeGen *g, ImportTableEntry *import, | ... | @@ -4662,17 +4546,31 @@ static TypeTableEntry *analyze_fn_call_ptr(CodeGen *g, ImportTableEntry *import, |
| 4662 | buf_sprintf("expected %d arguments, got %d", src_param_count, actual_param_count)); | 4546 | buf_sprintf("expected %d arguments, got %d", src_param_count, actual_param_count)); |
| 4663 | } | 4547 | } |
| 4664 | | 4548 | |
| | 4549 | bool all_args_const_expr = true; |
| | 4550 | |
| | 4551 | if (struct_node) { |
| | 4552 | ConstExprValue *struct_const_val = &get_resolved_expr(struct_node)->const_val; |
| | 4553 | if (!struct_const_val->ok) { |
| | 4554 | all_args_const_expr = false; |
| | 4555 | } |
| | 4556 | } |
| | 4557 | |
| 4665 | // analyze each parameter. in the case of a method, we already analyzed the | 4558 | // analyze each parameter. in the case of a method, we already analyzed the |
| 4666 | // first parameter in order to figure out which struct we were calling a method on. | 4559 | // first parameter in order to figure out which struct we were calling a method on. |
| 4667 | for (int i = 0; i < node->data.fn_call_expr.params.length; i += 1) { | 4560 | for (int i = 0; i < node->data.fn_call_expr.params.length; i += 1) { |
| 4668 | AstNode *child = node->data.fn_call_expr.params.at(i); | 4561 | AstNode **child = &node->data.fn_call_expr.params.at(i); |
| 4669 | // determine the expected type for each parameter | 4562 | // determine the expected type for each parameter |
| 4670 | TypeTableEntry *expected_param_type = nullptr; | 4563 | TypeTableEntry *expected_param_type = nullptr; |
| 4671 | int fn_proto_i = i + (struct_type ? 1 : 0); | 4564 | int fn_proto_i = i + (struct_node ? 1 : 0); |
| 4672 | if (fn_proto_i < src_param_count) { | 4565 | if (fn_proto_i < src_param_count) { |
| 4673 | expected_param_type = fn_type->data.fn.fn_type_id.param_info[fn_proto_i].type; | 4566 | expected_param_type = fn_type->data.fn.fn_type_id.param_info[fn_proto_i].type; |
| 4674 | } | 4567 | } |
| 4675 | analyze_expression(g, import, context, expected_param_type, child); | 4568 | analyze_expression(g, import, context, expected_param_type, *child); |
| | 4569 | |
| | 4570 | ConstExprValue *const_arg_val = &get_resolved_expr(*child)->const_val; |
| | 4571 | if (!const_arg_val->ok) { |
| | 4572 | all_args_const_expr = false; |
| | 4573 | } |
| 4676 | } | 4574 | } |
| 4677 | | 4575 | |
| 4678 | TypeTableEntry *return_type = fn_type->data.fn.fn_type_id.return_type; | 4576 | TypeTableEntry *return_type = fn_type->data.fn.fn_type_id.return_type; |
| ... | @@ -4681,6 +4579,30 @@ static TypeTableEntry *analyze_fn_call_ptr(CodeGen *g, ImportTableEntry *import, | ... | @@ -4681,6 +4579,30 @@ static TypeTableEntry *analyze_fn_call_ptr(CodeGen *g, ImportTableEntry *import, |
| 4681 | return return_type; | 4579 | return return_type; |
| 4682 | } | 4580 | } |
| 4683 | | 4581 | |
| | 4582 | FnTableEntry *fn_table_entry = node->data.fn_call_expr.fn_entry; |
| | 4583 | if (fn_table_entry && fn_table_entry->is_pure && all_args_const_expr) { |
| | 4584 | if (fn_table_entry->anal_state == FnAnalStateReady) { |
| | 4585 | analyze_fn_body(g, fn_table_entry); |
| | 4586 | } else if (fn_table_entry->anal_state == FnAnalStateProbing) { |
| | 4587 | mark_impure_fn(context); |
| | 4588 | } |
| | 4589 | if (fn_table_entry->is_pure) { |
| | 4590 | if (fn_table_entry->anal_state == FnAnalStateComplete) { |
| | 4591 | ConstExprValue *result_val = &get_resolved_expr(node)->const_val; |
| | 4592 | if (eval_fn(g, node, fn_table_entry, result_val, 1000, struct_node)) { |
| | 4593 | // function evaluation generated an error |
| | 4594 | return g->builtin_types.entry_invalid; |
| | 4595 | } |
| | 4596 | return return_type; |
| | 4597 | } else if (fn_table_entry->anal_state == FnAnalStateSkipped) { |
| | 4598 | return g->builtin_types.entry_invalid; |
| | 4599 | } |
| | 4600 | } else { |
| | 4601 | // calling an impure fn is impure |
| | 4602 | mark_impure_fn(context); |
| | 4603 | } |
| | 4604 | } |
| | 4605 | |
| 4684 | if (handle_is_ptr(return_type)) { | 4606 | if (handle_is_ptr(return_type)) { |
| 4685 | context->fn_entry->cast_alloca_list.append(node); | 4607 | context->fn_entry->cast_alloca_list.append(node); |
| 4686 | } | 4608 | } |
| ... | @@ -4689,13 +4611,13 @@ static TypeTableEntry *analyze_fn_call_ptr(CodeGen *g, ImportTableEntry *import, | ... | @@ -4689,13 +4611,13 @@ static TypeTableEntry *analyze_fn_call_ptr(CodeGen *g, ImportTableEntry *import, |
| 4689 | } | 4611 | } |
| 4690 | | 4612 | |
| 4691 | static TypeTableEntry *analyze_fn_call_raw(CodeGen *g, ImportTableEntry *import, BlockContext *context, | 4613 | static TypeTableEntry *analyze_fn_call_raw(CodeGen *g, ImportTableEntry *import, BlockContext *context, |
| 4692 | TypeTableEntry *expected_type, AstNode *node, FnTableEntry *fn_table_entry, TypeTableEntry *struct_type) | 4614 | TypeTableEntry *expected_type, AstNode *node, FnTableEntry *fn_table_entry, AstNode *struct_node) |
| 4693 | { | 4615 | { |
| 4694 | assert(node->type == NodeTypeFnCallExpr); | 4616 | assert(node->type == NodeTypeFnCallExpr); |
| 4695 | | 4617 | |
| 4696 | node->data.fn_call_expr.fn_entry = fn_table_entry; | 4618 | node->data.fn_call_expr.fn_entry = fn_table_entry; |
| 4697 | | 4619 | |
| 4698 | return analyze_fn_call_ptr(g, import, context, expected_type, node, fn_table_entry->type_entry, struct_type); | 4620 | return analyze_fn_call_ptr(g, import, context, expected_type, node, fn_table_entry->type_entry, struct_node); |
| 4699 | } | 4621 | } |
| 4700 | | 4622 | |
| 4701 | static TypeTableEntry *analyze_generic_fn_call(CodeGen *g, ImportTableEntry *import, BlockContext *parent_context, | 4623 | static TypeTableEntry *analyze_generic_fn_call(CodeGen *g, ImportTableEntry *import, BlockContext *parent_context, |
| ... | @@ -4861,17 +4783,17 @@ static TypeTableEntry *analyze_fn_call_expr(CodeGen *g, ImportTableEntry *import | ... | @@ -4861,17 +4783,17 @@ static TypeTableEntry *analyze_fn_call_expr(CodeGen *g, ImportTableEntry *import |
| 4861 | return analyze_cast_expr(g, import, context, node); | 4783 | return analyze_cast_expr(g, import, context, node); |
| 4862 | } | 4784 | } |
| 4863 | } else if (invoke_type_entry->id == TypeTableEntryIdFn) { | 4785 | } else if (invoke_type_entry->id == TypeTableEntryIdFn) { |
| 4864 | TypeTableEntry *bare_struct_type; | 4786 | AstNode *struct_node; |
| 4865 | if (fn_ref_expr->type == NodeTypeFieldAccessExpr && | 4787 | if (fn_ref_expr->type == NodeTypeFieldAccessExpr && |
| 4866 | fn_ref_expr->data.field_access_expr.is_member_fn) | 4788 | fn_ref_expr->data.field_access_expr.is_member_fn) |
| 4867 | { | 4789 | { |
| 4868 | bare_struct_type = fn_ref_expr->data.field_access_expr.bare_struct_type; | 4790 | struct_node = fn_ref_expr; |
| 4869 | } else { | 4791 | } else { |
| 4870 | bare_struct_type = nullptr; | 4792 | struct_node = nullptr; |
| 4871 | } | 4793 | } |
| 4872 | | 4794 | |
| 4873 | return analyze_fn_call_raw(g, import, context, expected_type, node, | 4795 | return analyze_fn_call_raw(g, import, context, expected_type, node, |
| 4874 | const_val->data.x_fn, bare_struct_type); | 4796 | const_val->data.x_fn, struct_node); |
| 4875 | } else if (invoke_type_entry->id == TypeTableEntryIdGenericFn) { | 4797 | } else if (invoke_type_entry->id == TypeTableEntryIdGenericFn) { |
| 4876 | return analyze_generic_fn_call(g, import, context, expected_type, node, const_val->data.x_type); | 4798 | return analyze_generic_fn_call(g, import, context, expected_type, node, const_val->data.x_type); |
| 4877 | } else { | 4799 | } else { |
| ... | @@ -5421,6 +5343,8 @@ static TypeTableEntry *analyze_block_expr(CodeGen *g, ImportTableEntry *import, | ... | @@ -5421,6 +5343,8 @@ static TypeTableEntry *analyze_block_expr(CodeGen *g, ImportTableEntry *import, |
| 5421 | static TypeTableEntry *analyze_asm_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context, | 5343 | static TypeTableEntry *analyze_asm_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context, |
| 5422 | TypeTableEntry *expected_type, AstNode *node) | 5344 | TypeTableEntry *expected_type, AstNode *node) |
| 5423 | { | 5345 | { |
| | 5346 | mark_impure_fn(context); |
| | 5347 | |
| 5424 | node->data.asm_expr.return_count = 0; | 5348 | node->data.asm_expr.return_count = 0; |
| 5425 | TypeTableEntry *return_type = g->builtin_types.entry_void; | 5349 | TypeTableEntry *return_type = g->builtin_types.entry_void; |
| 5426 | for (int i = 0; i < node->data.asm_expr.output_list.length; i += 1) { | 5350 | for (int i = 0; i < node->data.asm_expr.output_list.length; i += 1) { |
| ... | @@ -5641,8 +5565,10 @@ static void analyze_fn_body(CodeGen *g, FnTableEntry *fn_table_entry) { | ... | @@ -5641,8 +5565,10 @@ static void analyze_fn_body(CodeGen *g, FnTableEntry *fn_table_entry) { |
| 5641 | if (fn_proto_node->data.fn_proto.skip) { | 5565 | if (fn_proto_node->data.fn_proto.skip) { |
| 5642 | // we detected an error with this function definition which prevents us | 5566 | // we detected an error with this function definition which prevents us |
| 5643 | // from further analyzing it. | 5567 | // from further analyzing it. |
| | 5568 | fn_table_entry->anal_state = FnAnalStateSkipped; |
| 5644 | return; | 5569 | return; |
| 5645 | } | 5570 | } |
| | 5571 | fn_table_entry->anal_state = FnAnalStateProbing; |
| 5646 | | 5572 | |
| 5647 | BlockContext *context = node->data.fn_def.block_context; | 5573 | BlockContext *context = node->data.fn_def.block_context; |
| 5648 | | 5574 | |
| ... | @@ -5697,6 +5623,8 @@ static void analyze_fn_body(CodeGen *g, FnTableEntry *fn_table_entry) { | ... | @@ -5697,6 +5623,8 @@ static void analyze_fn_body(CodeGen *g, FnTableEntry *fn_table_entry) { |
| 5697 | buf_ptr(&label->decl_node->data.label.name))); | 5623 | buf_ptr(&label->decl_node->data.label.name))); |
| 5698 | } | 5624 | } |
| 5699 | } | 5625 | } |
| | 5626 | |
| | 5627 | fn_table_entry->anal_state = FnAnalStateComplete; |
| 5700 | } | 5628 | } |
| 5701 | | 5629 | |
| 5702 | static void add_top_level_decl(CodeGen *g, ImportTableEntry *import, BlockContext *block_context, | 5630 | static void add_top_level_decl(CodeGen *g, ImportTableEntry *import, BlockContext *block_context, |
| ... | @@ -6005,7 +5933,9 @@ void semantic_analyze(CodeGen *g) { | ... | @@ -6005,7 +5933,9 @@ void semantic_analyze(CodeGen *g) { |
| 6005 | | 5933 | |
| 6006 | for (int i = 0; i < g->fn_defs.length; i += 1) { | 5934 | for (int i = 0; i < g->fn_defs.length; i += 1) { |
| 6007 | FnTableEntry *fn_entry = g->fn_defs.at(i); | 5935 | FnTableEntry *fn_entry = g->fn_defs.at(i); |
| 6008 | analyze_fn_body(g, fn_entry); | 5936 | if (fn_entry->anal_state == FnAnalStateReady) { |
| | 5937 | analyze_fn_body(g, fn_entry); |
| | 5938 | } |
| 6009 | } | 5939 | } |
| 6010 | } | 5940 | } |
| 6011 | | 5941 | |