diff --git a/include/blocks/block_replacer.h b/include/blocks/block_replacer.h index d6ffa3b..2b7ff49 100644 --- a/include/blocks/block_replacer.h +++ b/include/blocks/block_replacer.h @@ -25,10 +25,12 @@ class block_replacer : public block_visitor { virtual void visit(std::shared_ptr) override; virtual void visit(std::shared_ptr) override; virtual void visit(std::shared_ptr) override; + virtual void visit(std::shared_ptr) override; virtual void visit(std::shared_ptr) override; virtual void visit(std::shared_ptr) override; virtual void visit(std::shared_ptr) override; virtual void visit(std::shared_ptr) override; + virtual void visit(std::shared_ptr) override; virtual void visit(std::shared_ptr) override; virtual void visit(std::shared_ptr) override; virtual void visit(std::shared_ptr) override; diff --git a/include/blocks/block_visitor.h b/include/blocks/block_visitor.h index 5639a25..ac27d69 100644 --- a/include/blocks/block_visitor.h +++ b/include/blocks/block_visitor.h @@ -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; @@ -72,10 +74,12 @@ class block_visitor { virtual void visit(std::shared_ptr); virtual void visit(std::shared_ptr); virtual void visit(std::shared_ptr); + virtual void visit(std::shared_ptr); virtual void visit(std::shared_ptr); virtual void visit(std::shared_ptr); virtual void visit(std::shared_ptr); virtual void visit(std::shared_ptr); + virtual void visit(std::shared_ptr); virtual void visit(std::shared_ptr); virtual void visit(std::shared_ptr); virtual void visit(std::shared_ptr); diff --git a/include/blocks/c_code_generator.h b/include/blocks/c_code_generator.h index 85203b4..c3b6147 100644 --- a/include/blocks/c_code_generator.h +++ b/include/blocks/c_code_generator.h @@ -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); diff --git a/include/blocks/expr.h b/include/blocks/expr.h index e8fd41a..7a59e2d 100644 --- a/include/blocks/expr.h +++ b/include/blocks/expr.h @@ -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 Ptr; + virtual void dump(std::ostream &, int) override; + virtual void accept(block_visitor *a) override { + a->visit(self()); + } + virtual bool is_same(block::Ptr other) override { + return unary_is_same(self(), other); + } +}; + class and_expr : public binary_expr { public: typedef std::shared_ptr Ptr; @@ -131,6 +144,18 @@ class bitwise_or_expr : public binary_expr { } }; +class bitwise_xor_expr : public binary_expr { +public: + typedef std::shared_ptr Ptr; + virtual void dump(std::ostream &, int) override; + virtual void accept(block_visitor *a) override { + a->visit(self()); + } + virtual bool is_same(block::Ptr other) override { + return binary_is_same(self(), other); + } +}; + class plus_expr : public binary_expr { public: typedef std::shared_ptr Ptr; diff --git a/include/builder/operator_overload.h b/include/builder/operator_overload.h index dea9877..8726202 100644 --- a/include/builder/operator_overload.h +++ b/include/builder/operator_overload.h @@ -60,6 +60,11 @@ typename allowed_builder_return::type operator|(const T1 &a, const T2 &b typedef typename allowed_builder_return::type ret_type; return ret_type(a).template builder_binary_op((ret_type)b); } +template +typename allowed_builder_return::type operator^(const T1 &a, const T2 &b) { + typedef typename allowed_builder_return::type ret_type; + return ret_type(a).template builder_binary_op((ret_type)b); +} template typename allowed_builder_return::type operator+(const T1 &a, const T2 &b) { @@ -146,6 +151,12 @@ typename return_type_helper::type operator!(const T &a) { return ret_type(a).template builder_unary_op(); } +template +typename return_type_helper::type operator~(const T &a) { + typedef typename return_type_helper::type ret_type; + return ret_type(a).template builder_unary_op(); +} + template typename return_type_helper::type operator&(const T &a) { typedef typename return_type_helper::type ret_type; @@ -191,6 +202,18 @@ template typename allowed_builder_return::type, T2>::type operator/=(T1 &&a, const T2 &b) { return (a = a / b); } +template +typename allowed_builder_return::type, T2>::type operator&=(T1 &&a, const T2 &b) { + return (a = a & b); +} +template +typename allowed_builder_return::type, T2>::type operator|=(T1 &&a, const T2 &b) { + return (a = a | b); +} +template +typename allowed_builder_return::type, T2>::type operator^=(T1 &&a, const T2 &b) { + return (a = a ^ b); +} } // namespace builder diff --git a/samples/outputs.var_names/sample1 b/samples/outputs.var_names/sample1 index 4a92a81..d54bb1d 100644 --- a/samples/outputs.var_names/sample1 +++ b/samples/outputs.var_names/sample1 @@ -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; @@ -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); } diff --git a/samples/outputs/sample1 b/samples/outputs/sample1 index dc4f9fb..6f32cc9 100644 --- a/samples/outputs/sample1 +++ b/samples/outputs/sample1 @@ -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; @@ -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); } diff --git a/samples/sample1.cpp b/samples/sample1.cpp index 6001e40..6704c99 100644 --- a/samples/sample1.cpp +++ b/samples/sample1.cpp @@ -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; diff --git a/src/blocks/block_replacer.cpp b/src/blocks/block_replacer.cpp index be3d0ec..6a000df 100644 --- a/src/blocks/block_replacer.cpp +++ b/src/blocks/block_replacer.cpp @@ -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); } @@ -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); } diff --git a/src/blocks/block_visitor.cpp b/src/blocks/block_visitor.cpp index 0f27303..5a19c68 100644 --- a/src/blocks/block_visitor.cpp +++ b/src/blocks/block_visitor.cpp @@ -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); @@ -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); diff --git a/src/blocks/c_code_generator.cpp b/src/blocks/c_code_generator.cpp index 2d37647..b155501 100644 --- a/src/blocks/c_code_generator.cpp +++ b/src/blocks/c_code_generator.cpp @@ -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(a)) return true; @@ -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, "+"); } diff --git a/src/blocks/expr.cpp b/src/blocks/expr.cpp index be69f45..8e31da6 100644 --- a/src/blocks/expr.cpp +++ b/src/blocks/expr.cpp @@ -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; @@ -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;