aboutsummaryrefslogtreecommitdiff
path: root/src/check_expr.cpp
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2021-03-23 23:34:01 +0000
committergingerBill <bill@gingerbill.org>2021-03-23 23:34:01 +0000
commitfc1a352285bab119752ff32edd44f8fe4260c352 (patch)
treed080e93bef2c4011a8ce7f37d185acc27e71494f /src/check_expr.cpp
parent082381284c36c605431d023ed9ae797678d65731 (diff)
For `bit_set`, allow `+` and `-` to be aliases for `|` and `&~`, respectively
Diffstat (limited to 'src/check_expr.cpp')
-rw-r--r--src/check_expr.cpp17
1 files changed, 15 insertions, 2 deletions
diff --git a/src/check_expr.cpp b/src/check_expr.cpp
index d185df9b5..8f5acfe20 100644
--- a/src/check_expr.cpp
+++ b/src/check_expr.cpp
@@ -1269,7 +1269,9 @@ bool check_binary_op(CheckerContext *c, Operand *o, Token op) {
switch (op.kind) {
case Token_Sub:
case Token_SubEq:
- if (!is_type_numeric(type)) {
+ if (is_type_bit_set(type)) {
+ return true;
+ } else if (!is_type_numeric(type)) {
error(op, "Operator '%.*s' is only allowed with numeric expressions", LIT(op.string));
return false;
}
@@ -1280,7 +1282,9 @@ bool check_binary_op(CheckerContext *c, Operand *o, Token op) {
case Token_MulEq:
case Token_QuoEq:
case Token_AddEq:
- if (!is_type_numeric(type)) {
+ if (is_type_bit_set(type)) {
+ return true;
+ } else if (!is_type_numeric(type)) {
error(op, "Operator '%.*s' is only allowed with numeric expressions", LIT(op.string));
return false;
}
@@ -1293,6 +1297,8 @@ bool check_binary_op(CheckerContext *c, Operand *o, Token op) {
}
error(op, "String concatenation is only allowed with constant strings");
return false;
+ } else if (is_type_bit_set(type)) {
+ return true;
} else if (!is_type_numeric(type)) {
error(op, "Operator '%.*s' is only allowed with numeric expressions", LIT(op.string));
return false;
@@ -2682,6 +2688,13 @@ void check_binary_expr(CheckerContext *c, Operand *x, Ast *node, Type *type_hint
op.kind = Token_QuoEq; // NOTE(bill): Hack to get division of integers
}
+ if (is_type_bit_set(type)) {
+ switch (op.kind) {
+ case Token_Add: op.kind = Token_Or; break;
+ case Token_Sub: op.kind = Token_AndNot; break;
+ }
+ }
+
x->value = exact_binary_operator_value(op.kind, a, b);
if (is_type_typed(type)) {