Browse Source

For `bit_set`, allow `+` and `-` to be aliases for `|` and `&~`, respectively

gingerBill 4 years ago
parent
commit
fc1a352285
3 changed files with 31 additions and 2 deletions
  1. 15 2
      src/check_expr.cpp
  2. 9 0
      src/ir.cpp
  3. 7 0
      src/llvm_backend.cpp

+ 15 - 2
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)) {

+ 9 - 0
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:
 		{

+ 7 - 0
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: