diff options
| author | gingerBill <bill@gingerbill.org> | 2018-08-26 18:05:59 +0100 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2018-08-26 18:05:59 +0100 |
| commit | 1830c1e57c5301151c26c0996ea5789b3b75a44f (patch) | |
| tree | d9544b0a3e35866313a0b8aae8fee41c8fd0cc82 /src/check_expr.cpp | |
| parent | e5735af6d6001a2a8b8df08d45ac1778dcc7b6f3 (diff) | |
Allow bitwise operation on enums
Diffstat (limited to 'src/check_expr.cpp')
| -rw-r--r-- | src/check_expr.cpp | 27 |
1 files changed, 13 insertions, 14 deletions
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); |