diff --git a/src/check_expr.cpp b/src/check_expr.cpp index bf9de13e7..93f2f5fe9 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -1158,6 +1158,7 @@ bool check_unary_op(CheckerContext *c, Operand *o, Token op) { bool check_binary_op(CheckerContext *c, Operand *o, Token op) { // TODO(bill): Handle errors correctly Type *type = base_type(core_array_type(o->type)); + Type *ct = core_type(type); switch (op.kind) { case Token_Sub: case Token_SubEq: @@ -1197,7 +1198,7 @@ bool check_binary_op(CheckerContext *c, Operand *o, Token op) { case Token_OrEq: case Token_Xor: case Token_XorEq: - if (!is_type_integer(type) && !is_type_boolean(type) && !is_type_bit_set(type)) { + if (!is_type_integer(ct) && !is_type_boolean(ct) && !is_type_bit_set(ct)) { error(op, "Operator '%.*s' is only allowed with integers, booleans, or bit sets", LIT(op.string)); return false; } @@ -1215,7 +1216,7 @@ bool check_binary_op(CheckerContext *c, Operand *o, Token op) { case Token_AndNot: case Token_AndNotEq: - if (!is_type_integer(type) && !is_type_bit_set(type)) { + if (!is_type_integer(ct) && !is_type_bit_set(ct)) { error(op, "Operator '%.*s' is only allowed with integers and bit sets", LIT(op.string)); return false; } @@ -3746,18 +3747,16 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 operand->mode = Addressing_Value; operand->type = type; - convert_to_typed(c, &x, y.type); - if (x.mode == Addressing_Invalid) { return false; } - convert_to_typed(c, &y, x.type); - if (y.mode == Addressing_Invalid) { return false; } - convert_to_typed(c, &x, z.type); - if (x.mode == Addressing_Invalid) { return false; } - convert_to_typed(c, &z, x.type); - if (z.mode == Addressing_Invalid) { return false; } - convert_to_typed(c, &y, z.type); - if (y.mode == Addressing_Invalid) { return false; } - convert_to_typed(c, &z, y.type); - if (z.mode == Addressing_Invalid) { return false; } + Operand *ops[3] = {&x, &y, &z}; + for (isize i = 0; i < 3; i++) { + Operand *a = ops[i]; + for (isize j = 0; j < 3; j++) { + if (i == j) continue; + Operand *b = ops[j]; + convert_to_typed(c, a, b->type); + if (a->mode == Addressing_Invalid) { return false; } + } + } if (!are_types_identical(x.type, y.type) || !are_types_identical(x.type, z.type)) { gbString type_x = type_to_string(x.type); diff --git a/src/exact_value.cpp b/src/exact_value.cpp index fb392c831..a4ceb5fa0 100644 --- a/src/exact_value.cpp +++ b/src/exact_value.cpp @@ -298,16 +298,6 @@ ExactValue exact_value_to_integer(ExactValue v) { return r; } -i64 exact_value_to_i64(ExactValue v) { - v = exact_value_to_integer(v); - i64 result = 0; - if (v.kind == ExactValue_Integer) { - return big_int_to_i64(&v.value_integer); - } - return result; -} - - ExactValue exact_value_to_float(ExactValue v) { switch (v.kind) { case ExactValue_Integer: @@ -370,6 +360,25 @@ ExactValue exact_value_make_imag(ExactValue v) { return r; } +i64 exact_value_to_i64(ExactValue v) { + v = exact_value_to_integer(v); + if (v.kind == ExactValue_Integer) { + return big_int_to_i64(&v.value_integer); + } + return 0; +} +f64 exact_value_to_f64(ExactValue v) { + v = exact_value_to_float(v); + if (v.kind == ExactValue_Float) { + return v.value_float; + } + return 0.0; +} + + + + + ExactValue exact_unary_operator_value(TokenKind op, ExactValue v, i32 precision, bool is_unsigned) { switch (op) {