authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-04-11 22:41:26-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-04-12 09:35:33-07:00
logaa89fd3b3e4522fe9199049a4fcc6bdc69f4bfde
treed93fec6d41037ce8c355f41a7798a2e87c984fd7
parentfa605485ea94ae9a59c8c1c0d66ee263e0bfa722

eval: ability to eval more things


7 files changed, 337 insertions(+), 114 deletions(-)

src/all_types.hpp+1-1
......@@ -65,7 +65,6 @@ struct ConstExprValue {
6565 bool ok; // true if constant expression evalution worked
6666 bool depends_on_compile_var;
6767 bool undef;
68 bool deep_const;
6968
7069 union {
7170 BigNum x_bignum;
......@@ -961,6 +960,7 @@ struct TypeTableEntry {
961960 LLVMZigDIType *di_type;
962961
963962 bool zero_bits;
963 bool deep_const;
964964
965965 union {
966966 TypeTableEntryPointer pointer;
src/analyze.cpp+39-96
......@@ -207,6 +207,7 @@ TypeTableEntry *get_smallest_unsigned_int_type(CodeGen *g, uint64_t x) {
207207static TypeTableEntry *get_generic_fn_type(CodeGen *g, AstNode *decl_node) {
208208 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdGenericFn);
209209 buf_init_from_str(&entry->name, "(generic function)");
210 entry->deep_const = true;
210211 entry->zero_bits = true;
211212 entry->data.generic_fn.decl_node = decl_node;
212213 return entry;
......@@ -220,6 +221,8 @@ TypeTableEntry *get_pointer_to_type(CodeGen *g, TypeTableEntry *child_type, bool
220221 } else {
221222 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdPointer);
222223
224 entry->deep_const = is_const && child_type->deep_const;
225
223226 const char *const_str = is_const ? "const " : "";
224227 buf_resize(&entry->name, 0);
225228 buf_appendf(&entry->name, "&%s%s", const_str, buf_ptr(&child_type->name));
......@@ -261,6 +264,8 @@ TypeTableEntry *get_maybe_type(CodeGen *g, TypeTableEntry *child_type) {
261264 assert(child_type->type_ref);
262265 assert(child_type->di_type);
263266
267 entry->deep_const = child_type->deep_const;
268
264269 buf_resize(&entry->name, 0);
265270 buf_appendf(&entry->name, "?%s", buf_ptr(&child_type->name));
266271
......@@ -344,6 +349,8 @@ static TypeTableEntry *get_error_type(CodeGen *g, TypeTableEntry *child_type) {
344349
345350 entry->data.error.child_type = child_type;
346351
352 entry->deep_const = child_type->deep_const;
353
347354 if (!type_has_bits(child_type)) {
348355 entry->type_ref = g->err_tag_type->type_ref;
349356 entry->di_type = g->err_tag_type->di_type;
......@@ -415,6 +422,7 @@ TypeTableEntry *get_array_type(CodeGen *g, TypeTableEntry *child_type, uint64_t
415422 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdArray);
416423 entry->type_ref = LLVMArrayType(child_type->type_ref, array_size);
417424 entry->zero_bits = (array_size == 0) || child_type->zero_bits;
425 entry->deep_const = child_type->deep_const;
418426
419427 buf_resize(&entry->name, 0);
420428 buf_appendf(&entry->name, "[%" PRIu64 "]%s", array_size, buf_ptr(&child_type->name));
......@@ -465,6 +473,8 @@ TypeTableEntry *get_slice_type(CodeGen *g, TypeTableEntry *child_type, bool is_c
465473 TypeTableEntry *var_peer = get_slice_type(g, child_type, false);
466474 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdStruct);
467475
476 entry->deep_const = child_type->deep_const;
477
468478 buf_resize(&entry->name, 0);
469479 buf_appendf(&entry->name, "[]const %s", buf_ptr(&child_type->name));
470480
......@@ -550,6 +560,7 @@ TypeTableEntry *get_typedecl_type(CodeGen *g, const char *name, TypeTableEntry *
550560
551561 buf_init_from_str(&entry->name, name);
552562
563 entry->deep_const = child_type->deep_const;
553564 entry->type_ref = child_type->type_ref;
554565 entry->di_type = child_type->di_type;
555566 entry->zero_bits = child_type->zero_bits;
......@@ -573,6 +584,7 @@ TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) {
573584 }
574585
575586 TypeTableEntry *fn_type = new_type_table_entry(TypeTableEntryIdFn);
587 fn_type->deep_const = true;
576588 fn_type->data.fn.fn_type_id = *fn_type_id;
577589 if (fn_type_id->param_info == &fn_type_id->prealloc_param_info[0]) {
578590 fn_type->data.fn.fn_type_id.param_info = &fn_type->data.fn.fn_type_id.prealloc_param_info[0];
......@@ -1038,6 +1050,8 @@ static void resolve_enum_type(CodeGen *g, ImportTableEntry *import, TypeTableEnt
10381050
10391051 assert(enum_type->di_type);
10401052
1053 enum_type->deep_const = true;
1054
10411055 uint32_t field_count = decl_node->data.struct_decl.fields.length;
10421056
10431057 enum_type->data.enumeration.field_count = field_count;
......@@ -1065,6 +1079,10 @@ static void resolve_enum_type(CodeGen *g, ImportTableEntry *import, TypeTableEnt
10651079 type_enum_field->type_entry = field_type;
10661080 type_enum_field->value = i;
10671081
1082 if (!field_type->deep_const) {
1083 enum_type->deep_const = false;
1084 }
1085
10681086
10691087 di_enumerators[i] = LLVMZigCreateDebugEnumerator(g->dbuilder, buf_ptr(type_enum_field->name), i);
10701088
......@@ -1225,6 +1243,8 @@ static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableE
12251243
12261244 assert(struct_type->di_type);
12271245
1246 struct_type->deep_const = true;
1247
12281248 int field_count = decl_node->data.struct_decl.fields.length;
12291249
12301250 struct_type->data.structure.src_field_count = field_count;
......@@ -1248,6 +1268,10 @@ static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableE
12481268 type_struct_field->src_index = i;
12491269 type_struct_field->gen_index = -1;
12501270
1271 if (!field_type->deep_const) {
1272 struct_type->deep_const = false;
1273 }
1274
12511275 if (field_type->id == TypeTableEntryIdStruct) {
12521276 resolve_struct_type(g, import, field_type);
12531277 } else if (field_type->id == TypeTableEntryIdEnum) {
......@@ -2486,7 +2510,6 @@ static TypeTableEntry *analyze_array_access_expr(CodeGen *g, ImportTableEntry *i
24862510static TypeTableEntry *resolve_expr_const_val_as_void(CodeGen *g, AstNode *node) {
24872511 Expr *expr = get_resolved_expr(node);
24882512 expr->const_val.ok = true;
2489 expr->const_val.deep_const = true;
24902513 return g->builtin_types.entry_void;
24912514}
24922515
......@@ -2494,7 +2517,6 @@ static TypeTableEntry *resolve_expr_const_val_as_type(CodeGen *g, AstNode *node,
24942517 Expr *expr = get_resolved_expr(node);
24952518 expr->const_val.ok = true;
24962519 expr->const_val.data.x_type = type;
2497 expr->const_val.deep_const = true;
24982520 return g->builtin_types.entry_type;
24992521}
25002522
......@@ -2509,7 +2531,6 @@ static TypeTableEntry *resolve_expr_const_val_as_fn(CodeGen *g, AstNode *node, F
25092531 Expr *expr = get_resolved_expr(node);
25102532 expr->const_val.ok = true;
25112533 expr->const_val.data.x_fn = fn;
2512 expr->const_val.deep_const = true;
25132534 return fn->type_entry;
25142535}
25152536
......@@ -2519,7 +2540,6 @@ static TypeTableEntry *resolve_expr_const_val_as_generic_fn(CodeGen *g, AstNode
25192540 Expr *expr = get_resolved_expr(node);
25202541 expr->const_val.ok = true;
25212542 expr->const_val.data.x_type = type_entry;
2522 expr->const_val.deep_const = true;
25232543 return type_entry;
25242544}
25252545
......@@ -2527,7 +2547,6 @@ static TypeTableEntry *resolve_expr_const_val_as_err(CodeGen *g, AstNode *node,
25272547 Expr *expr = get_resolved_expr(node);
25282548 expr->const_val.ok = true;
25292549 expr->const_val.data.x_err.err = err;
2530 expr->const_val.deep_const = true;
25312550 return g->builtin_types.entry_pure_error;
25322551}
25332552
......@@ -2538,7 +2557,6 @@ static TypeTableEntry *resolve_expr_const_val_as_bool(CodeGen *g, AstNode *node,
25382557 expr->const_val.ok = true;
25392558 expr->const_val.depends_on_compile_var = depends_on_compile_var;
25402559 expr->const_val.data.x_bool = value;
2541 expr->const_val.deep_const = true;
25422560 return g->builtin_types.entry_bool;
25432561}
25442562
......@@ -2546,7 +2564,6 @@ static TypeTableEntry *resolve_expr_const_val_as_null(CodeGen *g, AstNode *node,
25462564 Expr *expr = get_resolved_expr(node);
25472565 expr->const_val.ok = true;
25482566 expr->const_val.data.x_maybe = nullptr;
2549 expr->const_val.deep_const = true;
25502567 return type;
25512568}
25522569
......@@ -2557,14 +2574,12 @@ static TypeTableEntry *resolve_expr_const_val_as_non_null(CodeGen *g, AstNode *n
25572574 Expr *expr = get_resolved_expr(node);
25582575 expr->const_val.ok = true;
25592576 expr->const_val.data.x_maybe = other_val;
2560 expr->const_val.deep_const = other_val->deep_const;
25612577 return type;
25622578}
25632579
25642580static TypeTableEntry *resolve_expr_const_val_as_c_string_lit(CodeGen *g, AstNode *node, Buf *str) {
25652581 Expr *expr = get_resolved_expr(node);
25662582 expr->const_val.ok = true;
2567 expr->const_val.deep_const = true;
25682583
25692584 int len_with_null = buf_len(str) + 1;
25702585 expr->const_val.data.x_ptr.ptr = allocate<ConstExprValue*>(len_with_null);
......@@ -2574,14 +2589,12 @@ static TypeTableEntry *resolve_expr_const_val_as_c_string_lit(CodeGen *g, AstNod
25742589 for (int i = 0; i < buf_len(str); i += 1) {
25752590 ConstExprValue *this_char = &all_chars[i];
25762591 this_char->ok = true;
2577 this_char->deep_const = true;
25782592 bignum_init_unsigned(&this_char->data.x_bignum, buf_ptr(str)[i]);
25792593 expr->const_val.data.x_ptr.ptr[i] = this_char;
25802594 }
25812595
25822596 ConstExprValue *null_char = &all_chars[len_with_null - 1];
25832597 null_char->ok = true;
2584 null_char->deep_const = true;
25852598 bignum_init_unsigned(&null_char->data.x_bignum, 0);
25862599 expr->const_val.data.x_ptr.ptr[len_with_null - 1] = null_char;
25872600
......@@ -2591,14 +2604,12 @@ static TypeTableEntry *resolve_expr_const_val_as_c_string_lit(CodeGen *g, AstNod
25912604static TypeTableEntry *resolve_expr_const_val_as_string_lit(CodeGen *g, AstNode *node, Buf *str) {
25922605 Expr *expr = get_resolved_expr(node);
25932606 expr->const_val.ok = true;
2594 expr->const_val.deep_const = true;
25952607 expr->const_val.data.x_array.fields = allocate<ConstExprValue*>(buf_len(str));
25962608
25972609 ConstExprValue *all_chars = allocate<ConstExprValue>(buf_len(str));
25982610 for (int i = 0; i < buf_len(str); i += 1) {
25992611 ConstExprValue *this_char = &all_chars[i];
26002612 this_char->ok = true;
2601 this_char->deep_const = true;
26022613 bignum_init_unsigned(&this_char->data.x_bignum, buf_ptr(str)[i]);
26032614 expr->const_val.data.x_array.fields[i] = this_char;
26042615 }
......@@ -2611,7 +2622,6 @@ static TypeTableEntry *resolve_expr_const_val_as_unsigned_num_lit(CodeGen *g, As
26112622{
26122623 Expr *expr = get_resolved_expr(node);
26132624 expr->const_val.ok = true;
2614 expr->const_val.deep_const = true;
26152625
26162626 bignum_init_unsigned(&expr->const_val.data.x_bignum, x);
26172627
......@@ -2623,7 +2633,6 @@ static TypeTableEntry *resolve_expr_const_val_as_float_num_lit(CodeGen *g, AstNo
26232633{
26242634 Expr *expr = get_resolved_expr(node);
26252635 expr->const_val.ok = true;
2626 expr->const_val.deep_const = true;
26272636
26282637 bignum_init_float(&expr->const_val.data.x_bignum, x);
26292638
......@@ -2639,7 +2648,6 @@ static TypeTableEntry *resolve_expr_const_val_as_bignum_op(CodeGen *g, AstNode *
26392648 ConstExprValue *op2_val = &get_resolved_expr(op2)->const_val;
26402649
26412650 const_val->ok = true;
2642 const_val->deep_const = true;
26432651
26442652 if (bignum_fn(&const_val->data.x_bignum, &op1_val->data.x_bignum, &op2_val->data.x_bignum)) {
26452653 add_node_error(g, node,
......@@ -2713,12 +2721,7 @@ static bool var_is_pure(VariableTableEntry *var, TypeTableEntry *var_type, Block
27132721 // variable was declared in the current function, so it's OK.
27142722 return true;
27152723 }
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;
2724 return var->is_const && var->type->deep_const;
27222725}
27232726
27242727static TypeTableEntry *analyze_symbol_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
......@@ -3714,17 +3717,6 @@ static TypeTableEntry *analyze_if_var_expr(CodeGen *g, ImportTableEntry *import,
37143717 node, then_node, else_node, cond_is_const, cond_bool_val);
37153718}
37163719
3717static bool int_type_depends_on_compile_var(CodeGen *g, TypeTableEntry *int_type) {
3718 assert(int_type->id == TypeTableEntryIdInt);
3719
3720 for (int i = 0; i < CIntTypeCount; i += 1) {
3721 if (int_type == g->builtin_types.entry_c_int[i]) {
3722 return true;
3723 }
3724 }
3725 return false;
3726}
3727
37283720static TypeTableEntry *analyze_min_max_value(CodeGen *g, ImportTableEntry *import, BlockContext *context,
37293721 AstNode *node, const char *err_format, bool is_max)
37303722{
......@@ -3733,67 +3725,15 @@ static TypeTableEntry *analyze_min_max_value(CodeGen *g, ImportTableEntry *impor
37333725
37343726 AstNode *type_node = node->data.fn_call_expr.params.at(0);
37353727 TypeTableEntry *type_entry = analyze_type_expr(g, import, context, type_node);
3728
37363729 if (type_entry->id == TypeTableEntryIdInvalid) {
37373730 return g->builtin_types.entry_invalid;
3738 } else if (type_entry->id == TypeTableEntryIdInt) {
3739 ConstExprValue *const_val = &get_resolved_expr(node)->const_val;
3740 const_val->ok = true;
3741 const_val->depends_on_compile_var = int_type_depends_on_compile_var(g, type_entry);
3742 if (is_max) {
3743 if (type_entry->data.integral.is_signed) {
3744 int64_t val;
3745 if (type_entry->data.integral.bit_count == 64) {
3746 val = INT64_MAX;
3747 } else if (type_entry->data.integral.bit_count == 32) {
3748 val = INT32_MAX;
3749 } else if (type_entry->data.integral.bit_count == 16) {
3750 val = INT16_MAX;
3751 } else if (type_entry->data.integral.bit_count == 8) {
3752 val = INT8_MAX;
3753 } else {
3754 zig_unreachable();
3755 }
3756 bignum_init_signed(&const_val->data.x_bignum, val);
3757 } else {
3758 uint64_t val;
3759 if (type_entry->data.integral.bit_count == 64) {
3760 val = UINT64_MAX;
3761 } else if (type_entry->data.integral.bit_count == 32) {
3762 val = UINT32_MAX;
3763 } else if (type_entry->data.integral.bit_count == 16) {
3764 val = UINT16_MAX;
3765 } else if (type_entry->data.integral.bit_count == 8) {
3766 val = UINT8_MAX;
3767 } else {
3768 zig_unreachable();
3769 }
3770 bignum_init_unsigned(&const_val->data.x_bignum, val);
3771 }
3772 } else {
3773 if (type_entry->data.integral.is_signed) {
3774 int64_t val;
3775 if (type_entry->data.integral.bit_count == 64) {
3776 val = INT64_MIN;
3777 } else if (type_entry->data.integral.bit_count == 32) {
3778 val = INT32_MIN;
3779 } else if (type_entry->data.integral.bit_count == 16) {
3780 val = INT16_MIN;
3781 } else if (type_entry->data.integral.bit_count == 8) {
3782 val = INT8_MIN;
3783 } else {
3784 zig_unreachable();
3785 }
3786 bignum_init_signed(&const_val->data.x_bignum, val);
3787 } else {
3788 bignum_init_unsigned(&const_val->data.x_bignum, 0);
3789 }
3790 }
3791 return type_entry;
3792 } else if (type_entry->id == TypeTableEntryIdFloat) {
3793 zig_panic("TODO analyze_min_max_value float");
3731 } else if (type_entry->id == TypeTableEntryIdInt ||
3732 type_entry->id == TypeTableEntryIdFloat ||
3733 type_entry->id == TypeTableEntryIdBool)
3734 {
3735 eval_min_max_value(g, type_entry, &get_resolved_expr(node)->const_val, is_max);
37943736 return type_entry;
3795 } else if (type_entry->id == TypeTableEntryIdBool) {
3796 return resolve_expr_const_val_as_bool(g, node, is_max, false);
37973737 } else {
37983738 add_node_error(g, node,
37993739 buf_sprintf(err_format, buf_ptr(&type_entry->name)));
......@@ -3810,7 +3750,8 @@ static TypeTableEntry *resolve_cast(CodeGen *g, BlockContext *context, AstNode *
38103750 TypeTableEntry *other_type = get_resolved_expr(expr_node)->type_entry;
38113751 ConstExprValue *const_val = &get_resolved_expr(node)->const_val;
38123752 if (other_val->ok) {
3813 eval_const_expr_implicit_cast(node->data.fn_call_expr.cast_op, other_val, other_type, const_val);
3753 eval_const_expr_implicit_cast(node->data.fn_call_expr.cast_op, other_val, other_type,
3754 const_val, wanted_type);
38143755 }
38153756
38163757 if (need_alloca) {
......@@ -4238,8 +4179,6 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry
42384179 }
42394180 case BuiltinFnIdMemcpy:
42404181 {
4241 mark_impure_fn(context);
4242
42434182 AstNode *dest_node = node->data.fn_call_expr.params.at(0);
42444183 AstNode *src_node = node->data.fn_call_expr.params.at(1);
42454184 AstNode *len_node = node->data.fn_call_expr.params.at(2);
......@@ -4278,8 +4217,6 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry
42784217 }
42794218 case BuiltinFnIdMemset:
42804219 {
4281 mark_impure_fn(context);
4282
42834220 AstNode *dest_node = node->data.fn_call_expr.params.at(0);
42844221 AstNode *char_node = node->data.fn_call_expr.params.at(1);
42854222 AstNode *len_node = node->data.fn_call_expr.params.at(2);
......@@ -4601,6 +4538,8 @@ static TypeTableEntry *analyze_fn_call_ptr(CodeGen *g, ImportTableEntry *import,
46014538 // calling an impure fn is impure
46024539 mark_impure_fn(context);
46034540 }
4541 } else {
4542 mark_impure_fn(context);
46044543 }
46054544
46064545 if (handle_is_ptr(return_type)) {
......@@ -5602,6 +5541,10 @@ static void analyze_fn_body(CodeGen *g, FnTableEntry *fn_table_entry) {
56025541 param_decl_node->data.param_decl.variable = var;
56035542
56045543 var->gen_arg_index = fn_type->data.fn.gen_param_info[i].gen_index;
5544
5545 if (!type->deep_const) {
5546 fn_table_entry->is_pure = false;
5547 }
56055548 }
56065549
56075550 TypeTableEntry *expected_type = fn_type->data.fn.fn_type_id.return_type;
src/bignum.cpp+5
......@@ -71,6 +71,11 @@ bool bignum_fits_in_bits(BigNum *bn, int bit_count, bool is_signed) {
7171 }
7272}
7373
74void bignum_truncate(BigNum *bn, int bit_count) {
75 assert(bn->kind == BigNumKindInt);
76 bn->data.x_uint &= (1LL << bit_count) - 1;
77}
78
7479uint64_t bignum_to_twos_complement(BigNum *bn) {
7580 assert(bn->kind == BigNumKindInt);
7681
src/bignum.hpp+2
......@@ -47,6 +47,8 @@ void bignum_negate(BigNum *dest, BigNum *op);
4747void bignum_cast_to_float(BigNum *dest, BigNum *op);
4848void bignum_cast_to_int(BigNum *dest, BigNum *op);
4949
50void bignum_truncate(BigNum *dest, int bit_count);
51
5052// returns the result of the comparison
5153bool bignum_cmp_eq(BigNum *op1, BigNum *op2);
5254bool bignum_cmp_neq(BigNum *op1, BigNum *op2);
src/codegen.cpp+19
......@@ -3463,23 +3463,27 @@ static void define_builtin_types(CodeGen *g) {
34633463 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdNamespace);
34643464 buf_init_from_str(&entry->name, "(namespace)");
34653465 entry->zero_bits = true;
3466 entry->deep_const = true;
34663467 g->builtin_types.entry_namespace = entry;
34673468 }
34683469 {
34693470 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdNumLitFloat);
34703471 buf_init_from_str(&entry->name, "(float literal)");
34713472 entry->zero_bits = true;
3473 entry->deep_const = true;
34723474 g->builtin_types.entry_num_lit_float = entry;
34733475 }
34743476 {
34753477 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdNumLitInt);
34763478 buf_init_from_str(&entry->name, "(integer literal)");
34773479 entry->zero_bits = true;
3480 entry->deep_const = true;
34783481 g->builtin_types.entry_num_lit_int = entry;
34793482 }
34803483 {
34813484 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdUndefLit);
34823485 buf_init_from_str(&entry->name, "(undefined)");
3486 entry->deep_const = true;
34833487 g->builtin_types.entry_undef = entry;
34843488 }
34853489
......@@ -3489,6 +3493,7 @@ static void define_builtin_types(CodeGen *g) {
34893493 for (;;) {
34903494 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt);
34913495 entry->type_ref = LLVMIntType(size_in_bits);
3496 entry->deep_const = true;
34923497
34933498 const char u_or_i = is_signed ? 'i' : 'u';
34943499 buf_resize(&entry->name, 0);
......@@ -3534,6 +3539,7 @@ static void define_builtin_types(CodeGen *g) {
35343539
35353540 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt);
35363541 entry->type_ref = LLVMIntType(size_in_bits);
3542 entry->deep_const = true;
35373543
35383544 buf_init_from_str(&entry->name, info->name);
35393545
......@@ -3553,6 +3559,7 @@ static void define_builtin_types(CodeGen *g) {
35533559 {
35543560 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdBool);
35553561 entry->type_ref = LLVMInt1Type();
3562 entry->deep_const = true;
35563563 buf_init_from_str(&entry->name, "bool");
35573564 uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, entry->type_ref);
35583565 uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, entry->type_ref);
......@@ -3565,6 +3572,7 @@ static void define_builtin_types(CodeGen *g) {
35653572 }
35663573 {
35673574 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt);
3575 entry->deep_const = true;
35683576 entry->type_ref = LLVMIntType(g->pointer_size_bytes * 8);
35693577 buf_init_from_str(&entry->name, "isize");
35703578 entry->data.integral.is_signed = true;
......@@ -3581,6 +3589,7 @@ static void define_builtin_types(CodeGen *g) {
35813589 }
35823590 {
35833591 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt);
3592 entry->deep_const = true;
35843593 entry->type_ref = LLVMIntType(g->pointer_size_bytes * 8);
35853594 buf_init_from_str(&entry->name, "usize");
35863595 entry->data.integral.is_signed = false;
......@@ -3597,6 +3606,7 @@ static void define_builtin_types(CodeGen *g) {
35973606 }
35983607 {
35993608 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdFloat);
3609 entry->deep_const = true;
36003610 entry->type_ref = LLVMFloatType();
36013611 buf_init_from_str(&entry->name, "f32");
36023612 entry->data.floating.bit_count = 32;
......@@ -3612,6 +3622,7 @@ static void define_builtin_types(CodeGen *g) {
36123622 }
36133623 {
36143624 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdFloat);
3625 entry->deep_const = true;
36153626 entry->type_ref = LLVMDoubleType();
36163627 buf_init_from_str(&entry->name, "f64");
36173628 entry->data.floating.bit_count = 64;
......@@ -3627,6 +3638,7 @@ static void define_builtin_types(CodeGen *g) {
36273638 }
36283639 {
36293640 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdFloat);
3641 entry->deep_const = true;
36303642 entry->type_ref = LLVMX86FP80Type();
36313643 buf_init_from_str(&entry->name, "c_long_double");
36323644 entry->data.floating.bit_count = 80;
......@@ -3642,6 +3654,7 @@ static void define_builtin_types(CodeGen *g) {
36423654 }
36433655 {
36443656 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdVoid);
3657 entry->deep_const = true;
36453658 entry->type_ref = LLVMVoidType();
36463659 entry->zero_bits = true;
36473660 buf_init_from_str(&entry->name, "void");
......@@ -3654,6 +3667,7 @@ static void define_builtin_types(CodeGen *g) {
36543667 }
36553668 {
36563669 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdUnreachable);
3670 entry->deep_const = true;
36573671 entry->type_ref = LLVMVoidType();
36583672 entry->zero_bits = true;
36593673 buf_init_from_str(&entry->name, "unreachable");
......@@ -3663,6 +3677,7 @@ static void define_builtin_types(CodeGen *g) {
36633677 }
36643678 {
36653679 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdMetaType);
3680 entry->deep_const = true;
36663681 buf_init_from_str(&entry->name, "type");
36673682 entry->zero_bits = true;
36683683 g->builtin_types.entry_type = entry;
......@@ -3685,6 +3700,7 @@ static void define_builtin_types(CodeGen *g) {
36853700
36863701 {
36873702 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdPureError);
3703 entry->deep_const = true;
36883704 buf_init_from_str(&entry->name, "error");
36893705
36903706 // TODO allow overriding this type and keep track of max value and emit an
......@@ -3700,6 +3716,7 @@ static void define_builtin_types(CodeGen *g) {
37003716
37013717 {
37023718 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdEnum);
3719 entry->deep_const = true;
37033720 entry->zero_bits = true; // only allowed at compile time
37043721 buf_init_from_str(&entry->name, "@OS");
37053722 uint32_t field_count = target_os_count();
......@@ -3725,6 +3742,7 @@ static void define_builtin_types(CodeGen *g) {
37253742
37263743 {
37273744 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdEnum);
3745 entry->deep_const = true;
37283746 entry->zero_bits = true; // only allowed at compile time
37293747 buf_init_from_str(&entry->name, "@Arch");
37303748 uint32_t field_count = target_arch_count();
......@@ -3756,6 +3774,7 @@ static void define_builtin_types(CodeGen *g) {
37563774
37573775 {
37583776 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdEnum);
3777 entry->deep_const = true;
37593778 entry->zero_bits = true; // only allowed at compile time
37603779 buf_init_from_str(&entry->name, "@Environ");
37613780 uint32_t field_count = target_environ_count();
src/eval.cpp+268-16
......@@ -360,7 +360,7 @@ static bool eval_if_bool_expr(EvalFn *ef, AstNode *node, ConstExprValue *out_val
360360
361361void eval_const_expr_implicit_cast(CastOp cast_op,
362362 ConstExprValue *other_val, TypeTableEntry *other_type,
363 ConstExprValue *const_val)
363 ConstExprValue *const_val, TypeTableEntry *new_type)
364364{
365365 const_val->depends_on_compile_var = other_val->depends_on_compile_var;
366366 const_val->undef = other_val->undef;
......@@ -371,9 +371,30 @@ void eval_const_expr_implicit_cast(CastOp cast_op,
371371 zig_unreachable();
372372 case CastOpNoop:
373373 case CastOpWidenOrShorten:
374 case CastOpPointerReinterpret:
375374 *const_val = *other_val;
376375 break;
376 case CastOpPointerReinterpret:
377 {
378 TypeTableEntry *other_child_type = other_type->data.pointer.child_type;
379 TypeTableEntry *new_child_type = new_type->data.pointer.child_type;
380
381 if ((other_child_type->id == TypeTableEntryIdInt ||
382 other_child_type->id == TypeTableEntryIdFloat) &&
383 (new_child_type->id == TypeTableEntryIdInt ||
384 new_child_type->id == TypeTableEntryIdFloat))
385 {
386 ConstExprValue **ptr_val = allocate<ConstExprValue*>(1);
387 *ptr_val = other_val->data.x_ptr.ptr[0];
388 const_val->data.x_ptr.ptr = ptr_val;
389 const_val->data.x_ptr.len = 1;
390 const_val->ok = true;
391 const_val->undef = other_val->undef;
392 const_val->depends_on_compile_var = other_val->depends_on_compile_var;
393 } else {
394 zig_panic("TODO");
395 }
396 break;
397 }
377398 case CastOpPtrToInt:
378399 case CastOpIntToPtr:
379400 // can't do it
......@@ -435,20 +456,184 @@ void eval_const_expr_implicit_cast(CastOp cast_op,
435456 }
436457}
437458
459static bool int_type_depends_on_compile_var(CodeGen *g, TypeTableEntry *int_type) {
460 assert(int_type->id == TypeTableEntryIdInt);
461
462 for (int i = 0; i < CIntTypeCount; i += 1) {
463 if (int_type == g->builtin_types.entry_c_int[i]) {
464 return true;
465 }
466 }
467 return false;
468}
469
470void eval_min_max_value(CodeGen *g, TypeTableEntry *type_entry, ConstExprValue *const_val, bool is_max) {
471 if (type_entry->id == TypeTableEntryIdInt) {
472 const_val->ok = true;
473 const_val->depends_on_compile_var = int_type_depends_on_compile_var(g, type_entry);
474 if (is_max) {
475 if (type_entry->data.integral.is_signed) {
476 int64_t val;
477 if (type_entry->data.integral.bit_count == 64) {
478 val = INT64_MAX;
479 } else if (type_entry->data.integral.bit_count == 32) {
480 val = INT32_MAX;
481 } else if (type_entry->data.integral.bit_count == 16) {
482 val = INT16_MAX;
483 } else if (type_entry->data.integral.bit_count == 8) {
484 val = INT8_MAX;
485 } else {
486 zig_unreachable();
487 }
488 bignum_init_signed(&const_val->data.x_bignum, val);
489 } else {
490 uint64_t val;
491 if (type_entry->data.integral.bit_count == 64) {
492 val = UINT64_MAX;
493 } else if (type_entry->data.integral.bit_count == 32) {
494 val = UINT32_MAX;
495 } else if (type_entry->data.integral.bit_count == 16) {
496 val = UINT16_MAX;
497 } else if (type_entry->data.integral.bit_count == 8) {
498 val = UINT8_MAX;
499 } else {
500 zig_unreachable();
501 }
502 bignum_init_unsigned(&const_val->data.x_bignum, val);
503 }
504 } else {
505 if (type_entry->data.integral.is_signed) {
506 int64_t val;
507 if (type_entry->data.integral.bit_count == 64) {
508 val = INT64_MIN;
509 } else if (type_entry->data.integral.bit_count == 32) {
510 val = INT32_MIN;
511 } else if (type_entry->data.integral.bit_count == 16) {
512 val = INT16_MIN;
513 } else if (type_entry->data.integral.bit_count == 8) {
514 val = INT8_MIN;
515 } else {
516 zig_unreachable();
517 }
518 bignum_init_signed(&const_val->data.x_bignum, val);
519 } else {
520 bignum_init_unsigned(&const_val->data.x_bignum, 0);
521 }
522 }
523 } else if (type_entry->id == TypeTableEntryIdFloat) {
524 zig_panic("TODO analyze_min_max_value float");
525 } else if (type_entry->id == TypeTableEntryIdBool) {
526 const_val->ok = true;
527 const_val->data.x_bool = is_max;
528 } else {
529 zig_unreachable();
530 }
531}
532
533static bool eval_min_max(EvalFn *ef, AstNode *node, ConstExprValue *out_val, bool is_max) {
534 assert(node->type == NodeTypeFnCallExpr);
535 AstNode *type_node = node->data.fn_call_expr.params.at(0);
536 TypeTableEntry *type_entry = resolve_expr_type(type_node);
537 eval_min_max_value(ef->root->codegen, type_entry, out_val, is_max);
538 return false;
539}
540
541static bool eval_fn_with_overflow(EvalFn *ef, AstNode *node, ConstExprValue *out_val,
542 bool (*bignum_fn)(BigNum *dest, BigNum *op1, BigNum *op2))
543{
544 assert(node->type == NodeTypeFnCallExpr);
545
546 AstNode *type_node = node->data.fn_call_expr.params.at(0);
547 TypeTableEntry *int_type = resolve_expr_type(type_node);
548 assert(int_type->id == TypeTableEntryIdInt);
549
550 AstNode *op1_node = node->data.fn_call_expr.params.at(1);
551 AstNode *op2_node = node->data.fn_call_expr.params.at(2);
552 AstNode *result_node = node->data.fn_call_expr.params.at(3);
553
554 ConstExprValue op1_val = {0};
555 if (eval_expr(ef, op1_node, &op1_val)) return true;
556
557 ConstExprValue op2_val = {0};
558 if (eval_expr(ef, op2_node, &op2_val)) return true;
559
560 ConstExprValue result_ptr_val = {0};
561 if (eval_expr(ef, result_node, &result_ptr_val)) return true;
562
563 ConstExprValue *result_val = result_ptr_val.data.x_ptr.ptr[0];
564
565 out_val->ok = true;
566 bool overflow = bignum_fn(&result_val->data.x_bignum, &op1_val.data.x_bignum, &op2_val.data.x_bignum);
567
568 overflow = overflow || !bignum_fits_in_bits(&result_val->data.x_bignum,
569 int_type->data.integral.bit_count, int_type->data.integral.is_signed);
570
571 out_val->data.x_bool = overflow;
572
573 if (overflow) {
574 bignum_truncate(&result_val->data.x_bignum, int_type->data.integral.bit_count);
575 }
576
577 return false;
578}
579
580static bool eval_fn_call_builtin(EvalFn *ef, AstNode *node, ConstExprValue *out_val) {
581 assert(node->type == NodeTypeFnCallExpr);
582
583 BuiltinFnEntry *builtin_fn = node->data.fn_call_expr.builtin_fn;
584 switch (builtin_fn->id) {
585 case BuiltinFnIdMaxValue:
586 return eval_min_max(ef, node, out_val, true);
587 case BuiltinFnIdMinValue:
588 return eval_min_max(ef, node, out_val, false);
589 case BuiltinFnIdMulWithOverflow:
590 return eval_fn_with_overflow(ef, node, out_val, bignum_mul);
591 case BuiltinFnIdAddWithOverflow:
592 return eval_fn_with_overflow(ef, node, out_val, bignum_add);
593 case BuiltinFnIdSubWithOverflow:
594 return eval_fn_with_overflow(ef, node, out_val, bignum_sub);
595 case BuiltinFnIdMemcpy:
596 case BuiltinFnIdMemset:
597 case BuiltinFnIdSizeof:
598 case BuiltinFnIdAlignof:
599 case BuiltinFnIdMemberCount:
600 case BuiltinFnIdTypeof:
601 case BuiltinFnIdCInclude:
602 case BuiltinFnIdCDefine:
603 case BuiltinFnIdCUndef:
604 case BuiltinFnIdCompileVar:
605 case BuiltinFnIdConstEval:
606 case BuiltinFnIdCtz:
607 case BuiltinFnIdClz:
608 case BuiltinFnIdImport:
609 case BuiltinFnIdCImport:
610 case BuiltinFnIdErrName:
611 zig_panic("TODO");
612 case BuiltinFnIdBreakpoint:
613 case BuiltinFnIdInvalid:
614 zig_unreachable();
615 }
616
617 return false;
618}
619
438620static bool eval_fn_call_expr(EvalFn *ef, AstNode *node, ConstExprValue *out_val) {
439621 assert(node->type == NodeTypeFnCallExpr);
440622
623 AstNode *fn_ref_expr = node->data.fn_call_expr.fn_ref_expr;
441624 CastOp cast_op = node->data.fn_call_expr.cast_op;
442625 if (node->data.fn_call_expr.is_builtin) {
443 zig_panic("TODO");
626 return eval_fn_call_builtin(ef, node, out_val);
444627 } else if (cast_op != CastOpNoCast) {
445 AstNode *expr_node = node->data.fn_call_expr.params.at(0);
446 Expr *expr = get_resolved_expr(expr_node);
447 eval_const_expr_implicit_cast(cast_op, &expr->const_val, expr->type_entry, out_val);
628 TypeTableEntry *new_type = resolve_expr_type(fn_ref_expr);
629 AstNode *param_node = node->data.fn_call_expr.params.at(0);
630 TypeTableEntry *old_type = get_resolved_expr(param_node)->type_entry;
631 ConstExprValue param_val = {0};
632 if (eval_expr(ef, param_node, &param_val)) return true;
633 eval_const_expr_implicit_cast(cast_op, &param_val, old_type, out_val, new_type);
448634 return false;
449635 }
450636
451 AstNode *fn_ref_expr = node->data.fn_call_expr.fn_ref_expr;
452637 if (node->data.fn_call_expr.enum_type) {
453638 zig_panic("TODO");
454639 }
......@@ -503,7 +688,12 @@ static bool eval_field_access_expr(EvalFn *ef, AstNode *node, ConstExprValue *ou
503688 zig_panic("TODO");
504689 }
505690 } else if (struct_type->id == TypeTableEntryIdMetaType) {
506 zig_panic("TODO");
691 TypeTableEntry *child_type = resolve_expr_type(struct_expr);
692 if (child_type->id == TypeTableEntryIdPureError) {
693 *out_val = get_resolved_expr(node)->const_val;
694 } else {
695 zig_panic("TODO");
696 }
507697 } else if (struct_type->id == TypeTableEntryIdNamespace) {
508698 zig_panic("TODO");
509699 } else {
......@@ -630,7 +820,6 @@ static bool eval_bool_literal_expr(EvalFn *ef, AstNode *node, ConstExprValue *ou
630820 assert(node->type == NodeTypeBoolLiteral);
631821
632822 out_val->ok = true;
633 out_val->deep_const = true;
634823 out_val->data.x_bool = node->data.bool_literal.value;
635824
636825 return false;
......@@ -640,20 +829,38 @@ static bool eval_prefix_op_expr(EvalFn *ef, AstNode *node, ConstExprValue *out_v
640829 assert(node->type == NodeTypePrefixOpExpr);
641830
642831 PrefixOp prefix_op = node->data.prefix_op_expr.prefix_op;
832 AstNode *expr_node = node->data.prefix_op_expr.primary_expr;
643833
644834 ConstExprValue expr_val = {0};
645 if (eval_expr(ef, node->data.prefix_op_expr.primary_expr, &expr_val)) return true;
835 if (eval_expr(ef, expr_node, &expr_val)) return true;
836
837 TypeTableEntry *expr_type = get_resolved_expr(expr_node)->type_entry;
646838
647839 switch (prefix_op) {
648840 case PrefixOpBoolNot:
649841 *out_val = expr_val;
650842 out_val->data.x_bool = !out_val->data.x_bool;
651843 break;
652 case PrefixOpBinNot:
653 case PrefixOpNegation:
844 case PrefixOpDereference:
845 assert(expr_type->id == TypeTableEntryIdPointer);
846 *out_val = *expr_val.data.x_ptr.ptr[0];
847 break;
654848 case PrefixOpAddressOf:
655849 case PrefixOpConstAddressOf:
656 case PrefixOpDereference:
850 {
851 ConstExprValue *child_val = allocate<ConstExprValue>(1);
852 *child_val = expr_val;
853
854 ConstExprValue **ptr_val = allocate<ConstExprValue*>(1);
855 *ptr_val = child_val;
856
857 out_val->data.x_ptr.ptr = ptr_val;
858 out_val->data.x_ptr.len = 1;
859 out_val->ok = true;
860 break;
861 }
862 case PrefixOpBinNot:
863 case PrefixOpNegation:
657864 case PrefixOpMaybe:
658865 case PrefixOpError:
659866 case PrefixOpUnwrapError:
......@@ -666,6 +873,48 @@ static bool eval_prefix_op_expr(EvalFn *ef, AstNode *node, ConstExprValue *out_v
666873 return false;
667874}
668875
876static bool eval_var_decl_expr(EvalFn *ef, AstNode *node, ConstExprValue *out_val) {
877 assert(node->type == NodeTypeVariableDeclaration);
878
879 assert(node->data.variable_declaration.expr);
880
881 EvalScope *my_scope = ef->scope_stack.at(ef->scope_stack.length - 1);
882
883 my_scope->vars.add_one();
884 EvalVar *var = &my_scope->vars.last();
885 var->name = &node->data.variable_declaration.symbol;
886
887 if (eval_expr(ef, node->data.variable_declaration.expr, &var->value)) return true;
888
889 out_val->ok = true;
890
891 return false;
892}
893
894static bool eval_number_literal_expr(EvalFn *ef, AstNode *node, ConstExprValue *out_val) {
895 assert(node->type == NodeTypeNumberLiteral);
896 assert(!node->data.number_literal.overflow);
897
898 out_val->ok = true;
899 if (node->data.number_literal.kind == NumLitUInt) {
900 bignum_init_unsigned(&out_val->data.x_bignum, node->data.number_literal.data.x_uint);
901 } else if (node->data.number_literal.kind == NumLitFloat) {
902 bignum_init_float(&out_val->data.x_bignum, node->data.number_literal.data.x_float);
903 } else {
904 zig_unreachable();
905 }
906
907 return false;
908}
909
910static bool eval_char_literal_expr(EvalFn *ef, AstNode *node, ConstExprValue *out_val) {
911 assert(node->type == NodeTypeCharLiteral);
912
913 out_val->ok = true;
914 bignum_init_unsigned(&out_val->data.x_bignum, node->data.char_literal.value);
915
916 return false;
917}
669918
670919static bool eval_expr(EvalFn *ef, AstNode *node, ConstExprValue *out) {
671920 if (ef->root->branches_used > ef->root->branch_quota) {
......@@ -697,6 +946,12 @@ static bool eval_expr(EvalFn *ef, AstNode *node, ConstExprValue *out) {
697946 return eval_bool_literal_expr(ef, node, out);
698947 case NodeTypePrefixOpExpr:
699948 return eval_prefix_op_expr(ef, node, out);
949 case NodeTypeVariableDeclaration:
950 return eval_var_decl_expr(ef, node, out);
951 case NodeTypeNumberLiteral:
952 return eval_number_literal_expr(ef, node, out);
953 case NodeTypeCharLiteral:
954 return eval_char_literal_expr(ef, node, out);
700955 case NodeTypeRoot:
701956 case NodeTypeFnProto:
702957 case NodeTypeFnDef:
......@@ -704,13 +959,10 @@ static bool eval_expr(EvalFn *ef, AstNode *node, ConstExprValue *out) {
704959 case NodeTypeParamDecl:
705960 case NodeTypeDirective:
706961 case NodeTypeDefer:
707 case NodeTypeVariableDeclaration:
708962 case NodeTypeTypeDecl:
709963 case NodeTypeErrorValueDecl:
710964 case NodeTypeUnwrapErrorExpr:
711 case NodeTypeNumberLiteral:
712965 case NodeTypeStringLiteral:
713 case NodeTypeCharLiteral:
714966 case NodeTypeSliceExpr:
715967 case NodeTypeUse:
716968 case NodeTypeNullLiteral:
src/eval.hpp+3-1
......@@ -19,6 +19,8 @@ void eval_const_expr_bin_op(ConstExprValue *op1_val, TypeTableEntry *op1_type,
1919
2020void eval_const_expr_implicit_cast(CastOp cast_op,
2121 ConstExprValue *other_val, TypeTableEntry *other_type,
22 ConstExprValue *const_val);
22 ConstExprValue *const_val, TypeTableEntry *new_type);
23
24void eval_min_max_value(CodeGen *g, TypeTableEntry *type_entry, ConstExprValue *const_val, bool is_max);
2325
2426#endif