diff options
author | Philip Herron <philip.herron@embecosm.com> | 2021-01-19 15:48:51 +0000 |
---|---|---|
committer | Philip Herron <herron.philip@googlemail.com> | 2021-01-20 10:15:56 +0000 |
commit | e2b761b13e6ccd3a7af4100183bb13e32b5b0da0 (patch) | |
tree | 19df974672d967ed79ab9674c379a9f0484cded5 | |
parent | 85d8754632d597fe3d94404406082bcbb2f5ff94 (diff) | |
download | gcc-e2b761b13e6ccd3a7af4100183bb13e32b5b0da0.zip gcc-e2b761b13e6ccd3a7af4100183bb13e32b5b0da0.tar.gz gcc-e2b761b13e6ccd3a7af4100183bb13e32b5b0da0.tar.bz2 |
Implement CompoundAssignmentExpressions
This expands the AST::CompoundAssignmentExpr into and HIR::AssignmentExpr
with the asignee being referenced for lhs and a new artificial
HIR::ArithmeticOrLogicalExpression with lhs asignee and rhs the rhs
of the original CompoundAssignment expr.
-rw-r--r-- | gcc/rust/hir/rust-ast-lower-expr.h | 58 | ||||
-rw-r--r-- | gcc/rust/hir/tree/rust-hir-expr.h | 80 | ||||
-rw-r--r-- | gcc/rust/hir/tree/rust-hir-full-test.cc | 67 | ||||
-rw-r--r-- | gcc/rust/hir/tree/rust-hir-visitor.h | 1 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve-expr.h | 6 | ||||
-rw-r--r-- | gcc/testsuite/rust.test/compilable/compound_assignment_expr1.rs | 24 |
6 files changed, 88 insertions, 148 deletions
diff --git a/gcc/rust/hir/rust-ast-lower-expr.h b/gcc/rust/hir/rust-ast-lower-expr.h index a924ef2..fc18e27 100644 --- a/gcc/rust/hir/rust-ast-lower-expr.h +++ b/gcc/rust/hir/rust-ast-lower-expr.h @@ -532,6 +532,64 @@ public: std::move (outer_attribs), expr.get_locus ()); } + void visit (AST::CompoundAssignmentExpr &expr) + { + HIR::ArithmeticOrLogicalExpr::ExprType kind + = HIR::ArithmeticOrLogicalExpr::ExprType::ADD; + switch (expr.get_expr_type ()) + { + case AST::CompoundAssignmentExpr::ExprType::ADD: + kind = HIR::ArithmeticOrLogicalExpr::ExprType::ADD; + break; + case AST::CompoundAssignmentExpr::ExprType::SUBTRACT: + kind = HIR::ArithmeticOrLogicalExpr::ExprType::SUBTRACT; + break; + case AST::CompoundAssignmentExpr::ExprType::MULTIPLY: + kind = HIR::ArithmeticOrLogicalExpr::ExprType::MULTIPLY; + break; + case AST::CompoundAssignmentExpr::ExprType::DIVIDE: + kind = HIR::ArithmeticOrLogicalExpr::ExprType::DIVIDE; + break; + case AST::CompoundAssignmentExpr::ExprType::MODULUS: + kind = HIR::ArithmeticOrLogicalExpr::ExprType::MODULUS; + break; + case AST::CompoundAssignmentExpr::ExprType::BITWISE_AND: + kind = HIR::ArithmeticOrLogicalExpr::ExprType::BITWISE_AND; + break; + case AST::CompoundAssignmentExpr::ExprType::BITWISE_OR: + kind = HIR::ArithmeticOrLogicalExpr::ExprType::BITWISE_OR; + break; + case AST::CompoundAssignmentExpr::ExprType::BITWISE_XOR: + kind = HIR::ArithmeticOrLogicalExpr::ExprType::BITWISE_XOR; + break; + case AST::CompoundAssignmentExpr::ExprType::LEFT_SHIFT: + kind = HIR::ArithmeticOrLogicalExpr::ExprType::LEFT_SHIFT; + break; + case AST::CompoundAssignmentExpr::ExprType::RIGHT_SHIFT: + kind = HIR::ArithmeticOrLogicalExpr::ExprType::RIGHT_SHIFT; + break; + } + + HIR::Expr *asignee_expr + = ASTLoweringExpr::translate (expr.get_left_expr ().get ()); + HIR::Expr *value + = ASTLoweringExpr::translate (expr.get_right_expr ().get ()); + + auto crate_num = mappings->get_current_crate (); + Analysis::NodeMapping mapping (crate_num, expr.get_node_id (), + mappings->get_next_hir_id (crate_num), + UNKNOWN_LOCAL_DEFID); + HIR::Expr *operator_expr + = new HIR::ArithmeticOrLogicalExpr (mapping, asignee_expr->clone_expr (), + std::unique_ptr<HIR::Expr> (value), + kind, expr.get_locus ()); + translated + = new HIR::AssignmentExpr (mapping, + std::unique_ptr<HIR::Expr> (asignee_expr), + std::unique_ptr<HIR::Expr> (operator_expr), + expr.get_locus ()); + } + void visit (AST::StructExprStructFields &struct_expr) { std::vector<HIR::Attribute> inner_attribs; diff --git a/gcc/rust/hir/tree/rust-hir-expr.h b/gcc/rust/hir/tree/rust-hir-expr.h index 0b2b542..0ce678b 100644 --- a/gcc/rust/hir/tree/rust-hir-expr.h +++ b/gcc/rust/hir/tree/rust-hir-expr.h @@ -751,86 +751,6 @@ protected: } }; -/* Binary infix compound assignment (arithmetic or logic then assignment) - * expressions. */ -class CompoundAssignmentExpr : public OperatorExpr -{ -public: - enum ExprType - { - ADD, // std::ops::AddAssign - SUBTRACT, // std::ops::SubAssign - MULTIPLY, // std::ops::MulAssign - DIVIDE, // std::ops::DivAssign - MODULUS, // std::ops::RemAssign - BITWISE_AND, // std::ops::BitAndAssign - BITWISE_OR, // std::ops::BitOrAssign - BITWISE_XOR, // std::ops::BitXorAssign - LEFT_SHIFT, // std::ops::ShlAssign - RIGHT_SHIFT // std::ops::ShrAssign - }; - -private: - // Note: overloading trait specified in comments - ExprType expr_type; - std::unique_ptr<Expr> right_expr; - -public: - std::string as_string () const override; - - ExprType get_expr_type () const { return expr_type; } - - // Use pointers in constructor to enable polymorphism - CompoundAssignmentExpr (Analysis::NodeMapping mappings, - std::unique_ptr<Expr> value_to_assign_to, - std::unique_ptr<Expr> value_to_assign, - ExprType expr_kind, Location locus) - : OperatorExpr (std::move (mappings), std::move (value_to_assign_to), - std::vector<Attribute> (), locus), - expr_type (expr_kind), right_expr (std::move (value_to_assign)) - {} - // outer attributes not allowed - - // Have clone in copy constructor - CompoundAssignmentExpr (CompoundAssignmentExpr const &other) - : OperatorExpr (other), expr_type (other.expr_type), - right_expr (other.right_expr->clone_expr ()) - {} - - // Overload assignment operator to clone - CompoundAssignmentExpr &operator= (CompoundAssignmentExpr const &other) - { - OperatorExpr::operator= (other); - // main_or_left_expr = other.main_or_left_expr->clone_expr(); - right_expr = other.right_expr->clone_expr (); - expr_type = other.expr_type; - // outer_attrs = other.outer_attrs; - - return *this; - } - - // move constructors - CompoundAssignmentExpr (CompoundAssignmentExpr &&other) = default; - CompoundAssignmentExpr &operator= (CompoundAssignmentExpr &&other) = default; - - void accept_vis (HIRVisitor &vis) override; - -protected: - /* Use covariance to implement clone function as returning this object rather - * than base */ - CompoundAssignmentExpr *clone_expr_impl () const override - { - return new CompoundAssignmentExpr (*this); - } - - /* Use covariance to implement clone function as returning this object rather - * than base */ - CompoundAssignmentExpr *clone_expr_without_block_impl () const override - { - return new CompoundAssignmentExpr (*this); - } -}; - // Expression in parentheses (i.e. like literally just any 3 + (2 * 6)) class GroupedExpr : public ExprWithoutBlock { diff --git a/gcc/rust/hir/tree/rust-hir-full-test.cc b/gcc/rust/hir/tree/rust-hir-full-test.cc index b935376..f4e9f5a 100644 --- a/gcc/rust/hir/tree/rust-hir-full-test.cc +++ b/gcc/rust/hir/tree/rust-hir-full-test.cc @@ -2033,67 +2033,6 @@ ErrorPropagationExpr::as_string () const } std::string -CompoundAssignmentExpr::as_string () const -{ - std::string operator_str; - operator_str.reserve (1); - - // get operator string - switch (expr_type) - { - case ADD: - operator_str = "+"; - break; - case SUBTRACT: - operator_str = "-"; - break; - case MULTIPLY: - operator_str = "*"; - break; - case DIVIDE: - operator_str = "/"; - break; - case MODULUS: - operator_str = "%"; - break; - case BITWISE_AND: - operator_str = "&"; - break; - case BITWISE_OR: - operator_str = "|"; - break; - case BITWISE_XOR: - operator_str = "^"; - break; - case LEFT_SHIFT: - operator_str = "<<"; - break; - case RIGHT_SHIFT: - operator_str = ">>"; - break; - default: - operator_str = "invalid operator. wtf"; - break; - } - - operator_str += "="; - - std::string str ("CompoundAssignmentExpr: "); - if (main_or_left_expr == nullptr || right_expr == nullptr) - { - str += "error. this is probably a parsing failure."; - } - else - { - str += "\n left: " + main_or_left_expr->as_string (); - str += "\n right: " + right_expr->as_string (); - str += "\n operator: " + operator_str; - } - - return str; -} - -std::string ArithmeticOrLogicalExpr::as_string () const { std::string operator_str; @@ -5241,12 +5180,6 @@ AssignmentExpr::accept_vis (HIRVisitor &vis) } void -CompoundAssignmentExpr::accept_vis (HIRVisitor &vis) -{ - vis.visit (*this); -} - -void GroupedExpr::accept_vis (HIRVisitor &vis) { vis.visit (*this); diff --git a/gcc/rust/hir/tree/rust-hir-visitor.h b/gcc/rust/hir/tree/rust-hir-visitor.h index abb84f5..7fefb69 100644 --- a/gcc/rust/hir/tree/rust-hir-visitor.h +++ b/gcc/rust/hir/tree/rust-hir-visitor.h @@ -77,7 +77,6 @@ public: virtual void visit (LazyBooleanExpr &expr) = 0; virtual void visit (TypeCastExpr &expr) = 0; virtual void visit (AssignmentExpr &expr) = 0; - virtual void visit (CompoundAssignmentExpr &expr) = 0; virtual void visit (GroupedExpr &expr) = 0; // virtual void visit(ArrayElems& elems) = 0; virtual void visit (ArrayElemsValues &elems) = 0; diff --git a/gcc/rust/resolve/rust-ast-resolve-expr.h b/gcc/rust/resolve/rust-ast-resolve-expr.h index 03b3496..229b26a 100644 --- a/gcc/rust/resolve/rust-ast-resolve-expr.h +++ b/gcc/rust/resolve/rust-ast-resolve-expr.h @@ -116,6 +116,12 @@ public: ResolveExpr::go (expr.get_right_expr ().get (), expr.get_node_id ()); } + void visit (AST::CompoundAssignmentExpr &expr) + { + ResolveExpr::go (expr.get_left_expr ().get (), expr.get_node_id ()); + ResolveExpr::go (expr.get_right_expr ().get (), expr.get_node_id ()); + } + void visit (AST::ComparisonExpr &expr) { ResolveExpr::go (expr.get_left_expr ().get (), expr.get_node_id ()); diff --git a/gcc/testsuite/rust.test/compilable/compound_assignment_expr1.rs b/gcc/testsuite/rust.test/compilable/compound_assignment_expr1.rs new file mode 100644 index 0000000..add4a5f --- /dev/null +++ b/gcc/testsuite/rust.test/compilable/compound_assignment_expr1.rs @@ -0,0 +1,24 @@ +fn main() { + let mut a = 1; + let mut b = 2; + let mut c = 3; + let mut d = 4; + let mut e = 5; + let mut f = 6; + let mut g = 7; + let mut h = 8; + let mut i = 9; + let mut j = 10; + + a += 1; + b -= 2; + c *= 3; + d /= 4; + e %= 5; + f &= 6; + // https://github.com/Rust-GCC/gccrs/issues/173 + // g |= 7; + h ^= 8; + i <<= 9; + j >>= 10; +} |