aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2018-08-26 18:05:59 +0100
committergingerBill <bill@gingerbill.org>2018-08-26 18:05:59 +0100
commit1830c1e57c5301151c26c0996ea5789b3b75a44f (patch)
treed9544b0a3e35866313a0b8aae8fee41c8fd0cc82
parente5735af6d6001a2a8b8df08d45ac1778dcc7b6f3 (diff)
Allow bitwise operation on enums
-rw-r--r--src/check_expr.cpp27
-rw-r--r--src/exact_value.cpp29
2 files changed, 32 insertions, 24 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);
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) {