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)) { diff --git a/src/ir.cpp b/src/ir.cpp index 5e91d4f30..d17951f9f 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -4621,6 +4621,15 @@ irValue *ir_emit_arith(irProcedure *proc, TokenKind op, irValue *left, irValue * } handle_op: + + // NOTE(bill): Bit Set Aliases for + and - + if (is_type_bit_set(type)) { + switch (op) { + case Token_Add: op = Token_Or; break; + case Token_Sub: op = Token_AndNot; break; + } + } + switch (op) { case Token_Shl: { diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index acb60a88e..736af41c1 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -6311,6 +6311,13 @@ handle_op: lbValue res = {}; res.type = type; + // NOTE(bill): Bit Set Aliases for + and - + if (is_type_bit_set(type)) { + switch (op) { + case Token_Add: op = Token_Or; break; + case Token_Sub: op = Token_AndNot; break; + } + } switch (op) { case Token_Add: