| ... | @@ -2929,6 +2929,27 @@ static TypeTableEntry *analyze_bin_op_expr(CodeGen *g, ImportTableEntry *import, | ... | @@ -2929,6 +2929,27 @@ static TypeTableEntry *analyze_bin_op_expr(CodeGen *g, ImportTableEntry *import, |
| 2929 | return resolved_type; | 2929 | return resolved_type; |
| 2930 | } | 2930 | } |
| 2931 | | 2931 | |
| | 2932 | bool is_int = false; |
| | 2933 | bool is_float = false; |
| | 2934 | if (resolved_type->id == TypeTableEntryIdInt || |
| | 2935 | resolved_type->id == TypeTableEntryIdNumLitInt) |
| | 2936 | { |
| | 2937 | is_int = true; |
| | 2938 | } else if ((resolved_type->id == TypeTableEntryIdFloat || |
| | 2939 | resolved_type->id == TypeTableEntryIdNumLitFloat) && |
| | 2940 | (bin_op_type == BinOpTypeAdd || |
| | 2941 | bin_op_type == BinOpTypeSub || |
| | 2942 | bin_op_type == BinOpTypeMult || |
| | 2943 | bin_op_type == BinOpTypeDiv || |
| | 2944 | bin_op_type == BinOpTypeMod)) |
| | 2945 | { |
| | 2946 | is_float = true; |
| | 2947 | } else { |
| | 2948 | add_node_error(g, node, buf_sprintf("invalid operands to binary expression: '%s' and '%s'", |
| | 2949 | buf_ptr(&lhs_type->name), buf_ptr(&rhs_type->name))); |
| | 2950 | return g->builtin_types.entry_invalid; |
| | 2951 | } |
| | 2952 | |
| 2932 | ConstExprValue *op1_val = &get_resolved_expr(*op1)->const_val; | 2953 | ConstExprValue *op1_val = &get_resolved_expr(*op1)->const_val; |
| 2933 | ConstExprValue *op2_val = &get_resolved_expr(*op2)->const_val; | 2954 | ConstExprValue *op2_val = &get_resolved_expr(*op2)->const_val; |
| 2934 | if (!op1_val->ok || !op2_val->ok) { | 2955 | if (!op1_val->ok || !op2_val->ok) { |
| ... | @@ -2942,7 +2963,15 @@ static TypeTableEntry *analyze_bin_op_expr(CodeGen *g, ImportTableEntry *import, | ... | @@ -2942,7 +2963,15 @@ static TypeTableEntry *analyze_bin_op_expr(CodeGen *g, ImportTableEntry *import, |
| 2942 | } else if (bin_op_type == BinOpTypeMult) { | 2963 | } else if (bin_op_type == BinOpTypeMult) { |
| 2943 | return resolve_expr_const_val_as_bignum_op(g, node, bignum_mul, *op1, *op2, resolved_type); | 2964 | return resolve_expr_const_val_as_bignum_op(g, node, bignum_mul, *op1, *op2, resolved_type); |
| 2944 | } else if (bin_op_type == BinOpTypeDiv) { | 2965 | } else if (bin_op_type == BinOpTypeDiv) { |
| 2945 | return resolve_expr_const_val_as_bignum_op(g, node, bignum_div, *op1, *op2, resolved_type); | 2966 | ConstExprValue *op2_val = &get_resolved_expr(*op2)->const_val; |
| | 2967 | if ((is_int && op2_val->data.x_bignum.data.x_uint == 0) || |
| | 2968 | (is_float && op2_val->data.x_bignum.data.x_float == 0.0)) |
| | 2969 | { |
| | 2970 | add_node_error(g, node, buf_sprintf("division by zero is undefined")); |
| | 2971 | return g->builtin_types.entry_invalid; |
| | 2972 | } else { |
| | 2973 | return resolve_expr_const_val_as_bignum_op(g, node, bignum_div, *op1, *op2, resolved_type); |
| | 2974 | } |
| 2946 | } else if (bin_op_type == BinOpTypeMod) { | 2975 | } else if (bin_op_type == BinOpTypeMod) { |
| 2947 | return resolve_expr_const_val_as_bignum_op(g, node, bignum_mod, *op1, *op2, resolved_type); | 2976 | return resolve_expr_const_val_as_bignum_op(g, node, bignum_mod, *op1, *op2, resolved_type); |
| 2948 | } else if (bin_op_type == BinOpTypeBinOr) { | 2977 | } else if (bin_op_type == BinOpTypeBinOr) { |