Skip to content

Commit

Permalink
Added support for bitwise negation and xor. Added support for compoun…
Browse files Browse the repository at this point in the history
…d assignment by bitwise AND, XOR, and OR
  • Loading branch information
FilippoCarloni committed Aug 27, 2024
1 parent e487e03 commit 3bb5f66
Show file tree
Hide file tree
Showing 12 changed files with 220 additions and 0 deletions.
2 changes: 2 additions & 0 deletions include/blocks/block_replacer.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,12 @@ class block_replacer : public block_visitor {
virtual void visit(std::shared_ptr<unary_expr>) override;
virtual void visit(std::shared_ptr<binary_expr>) override;
virtual void visit(std::shared_ptr<not_expr>) override;
virtual void visit(std::shared_ptr<bitwise_not_expr>) override;
virtual void visit(std::shared_ptr<and_expr>) override;
virtual void visit(std::shared_ptr<bitwise_and_expr>) override;
virtual void visit(std::shared_ptr<or_expr>) override;
virtual void visit(std::shared_ptr<bitwise_or_expr>) override;
virtual void visit(std::shared_ptr<bitwise_xor_expr>) override;
virtual void visit(std::shared_ptr<plus_expr>) override;
virtual void visit(std::shared_ptr<minus_expr>) override;
virtual void visit(std::shared_ptr<mul_expr>) override;
Expand Down
4 changes: 4 additions & 0 deletions include/blocks/block_visitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@ class expr;
class unary_expr;
class binary_expr;
class not_expr;
class bitwise_not_expr;
class and_expr;
class bitwise_and_expr;
class or_expr;
class bitwise_or_expr;
class bitwise_xor_expr;
class plus_expr;
class minus_expr;
class mul_expr;
Expand Down Expand Up @@ -72,10 +74,12 @@ class block_visitor {
virtual void visit(std::shared_ptr<unary_expr>);
virtual void visit(std::shared_ptr<binary_expr>);
virtual void visit(std::shared_ptr<not_expr>);
virtual void visit(std::shared_ptr<bitwise_not_expr>);
virtual void visit(std::shared_ptr<and_expr>);
virtual void visit(std::shared_ptr<bitwise_and_expr>);
virtual void visit(std::shared_ptr<or_expr>);
virtual void visit(std::shared_ptr<bitwise_or_expr>);
virtual void visit(std::shared_ptr<bitwise_xor_expr>);
virtual void visit(std::shared_ptr<plus_expr>);
virtual void visit(std::shared_ptr<minus_expr>);
virtual void visit(std::shared_ptr<mul_expr>);
Expand Down
2 changes: 2 additions & 0 deletions include/blocks/c_code_generator.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,12 @@ class c_code_generator : public block_visitor {
void nextl(void);

virtual void visit(not_expr::Ptr);
virtual void visit(bitwise_not_expr::Ptr);
virtual void visit(and_expr::Ptr);
virtual void visit(bitwise_and_expr::Ptr);
virtual void visit(or_expr::Ptr);
virtual void visit(bitwise_or_expr::Ptr);
virtual void visit(bitwise_xor_expr::Ptr);
virtual void visit(plus_expr::Ptr);
virtual void visit(minus_expr::Ptr);
virtual void visit(mul_expr::Ptr);
Expand Down
25 changes: 25 additions & 0 deletions include/blocks/expr.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,19 @@ class not_expr : public unary_expr {
}
};

// For the bitwise not operator
class bitwise_not_expr : public unary_expr {
public:
typedef std::shared_ptr<bitwise_not_expr> Ptr;
virtual void dump(std::ostream &, int) override;
virtual void accept(block_visitor *a) override {
a->visit(self<bitwise_not_expr>());
}
virtual bool is_same(block::Ptr other) override {
return unary_is_same(self<bitwise_not_expr>(), other);
}
};

class and_expr : public binary_expr {
public:
typedef std::shared_ptr<and_expr> Ptr;
Expand Down Expand Up @@ -131,6 +144,18 @@ class bitwise_or_expr : public binary_expr {
}
};

class bitwise_xor_expr : public binary_expr {
public:
typedef std::shared_ptr<bitwise_xor_expr> Ptr;
virtual void dump(std::ostream &, int) override;
virtual void accept(block_visitor *a) override {
a->visit(self<bitwise_xor_expr>());
}
virtual bool is_same(block::Ptr other) override {
return binary_is_same(self<bitwise_xor_expr>(), other);
}
};

class plus_expr : public binary_expr {
public:
typedef std::shared_ptr<plus_expr> Ptr;
Expand Down
23 changes: 23 additions & 0 deletions include/builder/operator_overload.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@ typename allowed_builder_return<T1, T2>::type operator|(const T1 &a, const T2 &b
typedef typename allowed_builder_return<T1, T2>::type ret_type;
return ret_type(a).template builder_binary_op<block::bitwise_or_expr>((ret_type)b);
}
template <typename T1, typename T2>
typename allowed_builder_return<T1, T2>::type operator^(const T1 &a, const T2 &b) {
typedef typename allowed_builder_return<T1, T2>::type ret_type;
return ret_type(a).template builder_binary_op<block::bitwise_xor_expr>((ret_type)b);
}

template <typename T1, typename T2>
typename allowed_builder_return<T1, T2>::type operator+(const T1 &a, const T2 &b) {
Expand Down Expand Up @@ -146,6 +151,12 @@ typename return_type_helper<T>::type operator!(const T &a) {
return ret_type(a).template builder_unary_op<block::not_expr>();
}

template <typename T>
typename return_type_helper<T>::type operator~(const T &a) {
typedef typename return_type_helper<T>::type ret_type;
return ret_type(a).template builder_unary_op<block::bitwise_not_expr>();
}

template <typename T>
typename return_type_helper<T>::type operator&(const T &a) {
typedef typename return_type_helper<T>::type ret_type;
Expand Down Expand Up @@ -191,6 +202,18 @@ template <typename T1, typename T2>
typename allowed_builder_return<typename std::remove_reference<T1>::type, T2>::type operator/=(T1 &&a, const T2 &b) {
return (a = a / b);
}
template <typename T1, typename T2>
typename allowed_builder_return<typename std::remove_reference<T1>::type, T2>::type operator&=(T1 &&a, const T2 &b) {
return (a = a & b);
}
template <typename T1, typename T2>
typename allowed_builder_return<typename std::remove_reference<T1>::type, T2>::type operator|=(T1 &&a, const T2 &b) {
return (a = a | b);
}
template <typename T1, typename T2>
typename allowed_builder_return<typename std::remove_reference<T1>::type, T2>::type operator^=(T1 &&a, const T2 &b) {
return (a = a ^ b);
}

} // namespace builder

Expand Down
62 changes: 62 additions & 0 deletions samples/outputs.var_names/sample1
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,61 @@ STMT_BLOCK
VAR_EXPR
VAR (b_1)
INT_CONST (3)
EXPR_STMT
BITWISE_xOR_EXPR
VAR_EXPR
VAR (a_0)
VAR_EXPR
VAR (b_1)
EXPR_STMT
ASSIGN_EXPR
VAR_EXPR
VAR (a_0)
PLUS_EXPR
VAR_EXPR
VAR (a_0)
VAR_EXPR
VAR (b_1)
EXPR_STMT
ASSIGN_EXPR
VAR_EXPR
VAR (b_1)
MUL_EXPR
VAR_EXPR
VAR (b_1)
VAR_EXPR
VAR (b_1)
EXPR_STMT
ASSIGN_EXPR
VAR_EXPR
VAR (a_0)
BITWISE_AND_EXPR
VAR_EXPR
VAR (a_0)
VAR_EXPR
VAR (b_1)
EXPR_STMT
ASSIGN_EXPR
VAR_EXPR
VAR (a_0)
BITWISE_OR_EXPR
VAR_EXPR
VAR (a_0)
VAR_EXPR
VAR (b_1)
EXPR_STMT
ASSIGN_EXPR
VAR_EXPR
VAR (a_0)
BITWISE_xOR_EXPR
VAR_EXPR
VAR (a_0)
VAR_EXPR
VAR (b_1)
EXPR_STMT
BITWISE_NOT_EXPR
VAR_EXPR
VAR (b_1)
{
int a_0 = 0;
int b_1 = a_0;
Expand All @@ -61,4 +116,11 @@ STMT_BLOCK
a_0 | 2;
a_0 >> 2;
b_1 << 3;
a_0 ^ b_1;
a_0 = a_0 + b_1;
b_1 = b_1 * b_1;
a_0 = a_0 & b_1;
a_0 = a_0 | b_1;
a_0 = a_0 ^ b_1;
~(b_1);
}
62 changes: 62 additions & 0 deletions samples/outputs/sample1
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,61 @@ STMT_BLOCK
VAR_EXPR
VAR (var1)
INT_CONST (3)
EXPR_STMT
BITWISE_xOR_EXPR
VAR_EXPR
VAR (var0)
VAR_EXPR
VAR (var1)
EXPR_STMT
ASSIGN_EXPR
VAR_EXPR
VAR (var0)
PLUS_EXPR
VAR_EXPR
VAR (var0)
VAR_EXPR
VAR (var1)
EXPR_STMT
ASSIGN_EXPR
VAR_EXPR
VAR (var1)
MUL_EXPR
VAR_EXPR
VAR (var1)
VAR_EXPR
VAR (var1)
EXPR_STMT
ASSIGN_EXPR
VAR_EXPR
VAR (var0)
BITWISE_AND_EXPR
VAR_EXPR
VAR (var0)
VAR_EXPR
VAR (var1)
EXPR_STMT
ASSIGN_EXPR
VAR_EXPR
VAR (var0)
BITWISE_OR_EXPR
VAR_EXPR
VAR (var0)
VAR_EXPR
VAR (var1)
EXPR_STMT
ASSIGN_EXPR
VAR_EXPR
VAR (var0)
BITWISE_xOR_EXPR
VAR_EXPR
VAR (var0)
VAR_EXPR
VAR (var1)
EXPR_STMT
BITWISE_NOT_EXPR
VAR_EXPR
VAR (var1)
{
int var0 = 0;
int var1 = var0;
Expand All @@ -61,4 +116,11 @@ STMT_BLOCK
var0 | 2;
var0 >> 2;
var1 << 3;
var0 ^ var1;
var0 = var0 + var1;
var1 = var1 * var1;
var0 = var0 & var1;
var0 = var0 | var1;
var0 = var0 ^ var1;
~(var1);
}
7 changes: 7 additions & 0 deletions samples/sample1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,13 @@ static void foo(void) {
a | 2;
a >> 2;
b << 3;
a ^ b;
a+=b;
b*=b;
a&=b;
a|=b;
a^=b;
~b;
}
int main(int argc, char *argv[]) {
builder::builder_context context;
Expand Down
6 changes: 6 additions & 0 deletions src/blocks/block_replacer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ void block_replacer::visit(binary_expr::Ptr a) {
void block_replacer::visit(not_expr::Ptr a) {
unary_helper(a);
}
void block_replacer::visit(bitwise_not_expr::Ptr a) {
unary_helper(a);
}
void block_replacer::visit(and_expr::Ptr a) {
binary_helper(a);
}
Expand All @@ -39,6 +42,9 @@ void block_replacer::visit(or_expr::Ptr a) {
void block_replacer::visit(bitwise_or_expr::Ptr a) {
binary_helper(a);
}
void block_replacer::visit(bitwise_xor_expr::Ptr a) {
binary_helper(a);
}
void block_replacer::visit(plus_expr::Ptr a) {
binary_helper(a);
}
Expand Down
7 changes: 7 additions & 0 deletions src/blocks/block_visitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ void block_visitor::visit(binary_expr::Ptr a) {
void block_visitor::visit(not_expr::Ptr a) {
a->expr1->accept(this);
}
void block_visitor::visit(bitwise_not_expr::Ptr a) {
a->expr1->accept(this);
}
void block_visitor::visit(and_expr::Ptr a) {
a->expr1->accept(this);
a->expr2->accept(this);
Expand All @@ -30,6 +33,10 @@ void block_visitor::visit(bitwise_or_expr::Ptr a) {
a->expr1->accept(this);
a->expr2->accept(this);
}
void block_visitor::visit(bitwise_xor_expr::Ptr a) {
a->expr1->accept(this);
a->expr2->accept(this);
}
void block_visitor::visit(plus_expr::Ptr a) {
a->expr1->accept(this);
a->expr2->accept(this);
Expand Down
9 changes: 9 additions & 0 deletions src/blocks/c_code_generator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@ void c_code_generator::visit(not_expr::Ptr a) {
oss << ")";
}

void c_code_generator::visit(bitwise_not_expr::Ptr a) {
oss << "~(";
a->expr1->accept(this);
oss << ")";
}

static bool expr_needs_bracket(expr::Ptr a) {
if (isa<binary_expr>(a))
return true;
Expand Down Expand Up @@ -82,6 +88,9 @@ void c_code_generator::visit(or_expr::Ptr a) {
void c_code_generator::visit(bitwise_or_expr::Ptr a) {
emit_binary_expr(a, "|");
}
void c_code_generator::visit(bitwise_xor_expr::Ptr a) {
emit_binary_expr(a, "^");
}
void c_code_generator::visit(plus_expr::Ptr a) {
emit_binary_expr(a, "+");
}
Expand Down
11 changes: 11 additions & 0 deletions src/blocks/expr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ void not_expr::dump(std::ostream &oss, int indent) {
oss << "NOT_EXPR" << std::endl;
expr1->dump(oss, indent + 1);
}
void bitwise_not_expr::dump(std::ostream &oss, int indent) {
printer::indent(oss, indent);
oss << "BITWISE_NOT_EXPR" << std::endl;
expr1->dump(oss, indent + 1);
}
void and_expr::dump(std::ostream &oss, int indent) {
printer::indent(oss, indent);
oss << "AND_EXPR" << std::endl;
Expand All @@ -54,6 +59,12 @@ void bitwise_or_expr::dump(std::ostream &oss, int indent) {
expr1->dump(oss, indent + 1);
expr2->dump(oss, indent + 1);
}
void bitwise_xor_expr::dump(std::ostream &oss, int indent) {
printer::indent(oss, indent);
oss << "BITWISE_xOR_EXPR" << std::endl;
expr1->dump(oss, indent + 1);
expr2->dump(oss, indent + 1);
}
void plus_expr::dump(std::ostream &oss, int indent) {
printer::indent(oss, indent);
oss << "PLUS_EXPR" << std::endl;
Expand Down

0 comments on commit 3bb5f66

Please sign in to comment.