diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/rust/backend/rust-compile-expr.h | 17 | ||||
-rw-r--r-- | gcc/rust/hir/rust-ast-lower-expr.h | 16 | ||||
-rw-r--r-- | gcc/rust/hir/tree/rust-hir-expr.h | 74 | ||||
-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/lint/rust-lint-marklive-base.h | 2 | ||||
-rw-r--r-- | gcc/rust/lint/rust-lint-marklive.h | 6 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-const-fold-base.h | 2 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-base.h | 2 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-expr.h | 23 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-util.h | 2 |
11 files changed, 196 insertions, 16 deletions
diff --git a/gcc/rust/backend/rust-compile-expr.h b/gcc/rust/backend/rust-compile-expr.h index c9d3c30..8ed84c7 100644 --- a/gcc/rust/backend/rust-compile-expr.h +++ b/gcc/rust/backend/rust-compile-expr.h @@ -388,6 +388,23 @@ public: ctx->add_statement (assignment); } + void visit (HIR::CompoundAssignmentExpr &expr) override + { + fncontext fn = ctx->peek_fn (); + auto lvalue = CompileExpr::Compile (expr.get_left_expr ().get (), ctx); + auto rvalue = CompileExpr::Compile (expr.get_right_expr ().get (), ctx); + + auto op = expr.get_expr_type (); + auto operator_expr = ctx->get_backend ()->arithmetic_or_logical_expression ( + op, lvalue, rvalue, expr.get_locus ()); + + Bstatement *assignment + = ctx->get_backend ()->assignment_statement (fn.fndecl, lvalue, + operator_expr, + expr.get_locus ()); + ctx->add_statement (assignment); + } + void visit (HIR::ArrayIndexExpr &expr) override { Bexpression *array = CompileExpr::Compile (expr.get_array_expr (), ctx); diff --git a/gcc/rust/hir/rust-ast-lower-expr.h b/gcc/rust/hir/rust-ast-lower-expr.h index 54cb6113..f36096b 100644 --- a/gcc/rust/hir/rust-ast-lower-expr.h +++ b/gcc/rust/hir/rust-ast-lower-expr.h @@ -452,11 +452,8 @@ public: expr.get_locus ()); } - /* Compound assignment expression is compiled away. */ void visit (AST::CompoundAssignmentExpr &expr) override { - /* First we need to find the corresponding arithmetic or logical operator. - */ ArithmeticOrLogicalOperator op; switch (expr.get_expr_type ()) { @@ -503,15 +500,10 @@ public: 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), - op, 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 ()); + + translated = new HIR::CompoundAssignmentExpr ( + mapping, std::unique_ptr<HIR::Expr> (asignee_expr), + std::unique_ptr<HIR::Expr> (value), op, expr.get_locus ()); } void visit (AST::StructExprStruct &struct_expr) override diff --git a/gcc/rust/hir/tree/rust-hir-expr.h b/gcc/rust/hir/tree/rust-hir-expr.h index 37ec15d..901feda 100644 --- a/gcc/rust/hir/tree/rust-hir-expr.h +++ b/gcc/rust/hir/tree/rust-hir-expr.h @@ -666,6 +666,80 @@ protected: } }; +class CompoundAssignmentExpr : public OperatorExpr +{ +public: + using ExprType = ArithmeticOrLogicalOperator; + +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), + AST::AttrVec (), 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; + + std::unique_ptr<Expr> &get_left_expr () + { + rust_assert (main_or_left_expr != nullptr); + return main_or_left_expr; + } + + std::unique_ptr<Expr> &get_right_expr () + { + rust_assert (right_expr != nullptr); + return right_expr; + } + + void visit_lhs (HIRVisitor &vis) { main_or_left_expr->accept_vis (vis); } + void visit_rhs (HIRVisitor &vis) { right_expr->accept_vis (vis); } + +protected: + /* 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 bacef82..843e32c 100644 --- a/gcc/rust/hir/tree/rust-hir-full-test.cc +++ b/gcc/rust/hir/tree/rust-hir-full-test.cc @@ -1316,6 +1316,67 @@ AssignmentExpr::as_string () const } std::string +CompoundAssignmentExpr::as_string () const +{ + std::string operator_str; + operator_str.reserve (1); + + // get operator string + switch (expr_type) + { + case ArithmeticOrLogicalOperator::ADD: + operator_str = "+"; + break; + case ArithmeticOrLogicalOperator::SUBTRACT: + operator_str = "-"; + break; + case ArithmeticOrLogicalOperator::MULTIPLY: + operator_str = "*"; + break; + case ArithmeticOrLogicalOperator::DIVIDE: + operator_str = "/"; + break; + case ArithmeticOrLogicalOperator::MODULUS: + operator_str = "%"; + break; + case ArithmeticOrLogicalOperator::BITWISE_AND: + operator_str = "&"; + break; + case ArithmeticOrLogicalOperator::BITWISE_OR: + operator_str = "|"; + break; + case ArithmeticOrLogicalOperator::BITWISE_XOR: + operator_str = "^"; + break; + case ArithmeticOrLogicalOperator::LEFT_SHIFT: + operator_str = "<<"; + break; + case ArithmeticOrLogicalOperator::RIGHT_SHIFT: + operator_str = ">>"; + break; + default: + gcc_unreachable (); + 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 AsyncBlockExpr::as_string () const { std::string str = "AsyncBlockExpr: "; @@ -3819,6 +3880,12 @@ 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 0487446..ea125d9 100644 --- a/gcc/rust/hir/tree/rust-hir-visitor.h +++ b/gcc/rust/hir/tree/rust-hir-visitor.h @@ -47,6 +47,7 @@ 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 (ArrayElemsValues &elems) = 0; virtual void visit (ArrayElemsCopied &elems) = 0; diff --git a/gcc/rust/lint/rust-lint-marklive-base.h b/gcc/rust/lint/rust-lint-marklive-base.h index b67705b..e0494d7 100644 --- a/gcc/rust/lint/rust-lint-marklive-base.h +++ b/gcc/rust/lint/rust-lint-marklive-base.h @@ -53,7 +53,7 @@ public: virtual void visit (HIR::LazyBooleanExpr &) override {} virtual void visit (HIR::TypeCastExpr &) override {} virtual void visit (HIR::AssignmentExpr &) override {} - + virtual void visit (HIR::CompoundAssignmentExpr &) override {} virtual void visit (HIR::GroupedExpr &) override {} virtual void visit (HIR::ArrayElemsValues &) override {} diff --git a/gcc/rust/lint/rust-lint-marklive.h b/gcc/rust/lint/rust-lint-marklive.h index ca5d894..bcf792b 100644 --- a/gcc/rust/lint/rust-lint-marklive.h +++ b/gcc/rust/lint/rust-lint-marklive.h @@ -186,6 +186,12 @@ public: expr.visit_rhs (*this); } + void visit (HIR::CompoundAssignmentExpr &expr) override + { + expr.visit_lhs (*this); + expr.visit_rhs (*this); + } + void visit (HIR::IfExpr &expr) override { expr.get_if_condition ()->accept_vis (*this); diff --git a/gcc/rust/typecheck/rust-hir-const-fold-base.h b/gcc/rust/typecheck/rust-hir-const-fold-base.h index 9cbf1ab..0b41053 100644 --- a/gcc/rust/typecheck/rust-hir-const-fold-base.h +++ b/gcc/rust/typecheck/rust-hir-const-fold-base.h @@ -56,7 +56,7 @@ public: virtual void visit (HIR::LazyBooleanExpr &) override {} virtual void visit (HIR::TypeCastExpr &) override {} virtual void visit (HIR::AssignmentExpr &) override {} - + virtual void visit (HIR::CompoundAssignmentExpr &) override {} virtual void visit (HIR::GroupedExpr &) override {} virtual void visit (HIR::ArrayElemsValues &) override {} diff --git a/gcc/rust/typecheck/rust-hir-type-check-base.h b/gcc/rust/typecheck/rust-hir-type-check-base.h index eb96fd1..52dea21 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-base.h +++ b/gcc/rust/typecheck/rust-hir-type-check-base.h @@ -58,7 +58,7 @@ public: virtual void visit (HIR::LazyBooleanExpr &) override {} virtual void visit (HIR::TypeCastExpr &) override {} virtual void visit (HIR::AssignmentExpr &) override {} - + virtual void visit (HIR::CompoundAssignmentExpr &) override {} virtual void visit (HIR::GroupedExpr &) override {} virtual void visit (HIR::ArrayElemsValues &) override {} diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.h b/gcc/rust/typecheck/rust-hir-type-check-expr.h index b332a68..2594a41 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-expr.h +++ b/gcc/rust/typecheck/rust-hir-type-check-expr.h @@ -470,6 +470,29 @@ public: result->clone ()); } + void visit (HIR::CompoundAssignmentExpr &expr) override + { + infered = new TyTy::TupleType (expr.get_mappings ().get_hirid ()); + + auto lhs = TypeCheckExpr::Resolve (expr.get_left_expr ().get (), false); + auto rhs = TypeCheckExpr::Resolve (expr.get_right_expr ().get (), false); + + bool valid_lhs = validate_arithmetic_type (lhs, expr.get_expr_type ()); + bool valid_rhs = validate_arithmetic_type (rhs, expr.get_expr_type ()); + bool valid = valid_lhs && valid_rhs; + if (!valid) + { + rust_error_at (expr.get_locus (), + "cannot apply this operator to types %s and %s", + lhs->as_string ().c_str (), rhs->as_string ().c_str ()); + return; + } + + auto result = lhs->unify (rhs); + if (result->get_kind () == TyTy::TypeKind::ERROR) + return; + } + void visit (HIR::IdentifierExpr &expr) override { NodeId ast_node_id = expr.get_mappings ().get_nodeid (); diff --git a/gcc/rust/typecheck/rust-hir-type-check-util.h b/gcc/rust/typecheck/rust-hir-type-check-util.h index 4595ca3..f078df6 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-util.h +++ b/gcc/rust/typecheck/rust-hir-type-check-util.h @@ -51,7 +51,7 @@ public: virtual void visit (HIR::LazyBooleanExpr &) override {} virtual void visit (HIR::TypeCastExpr &) override {} virtual void visit (HIR::AssignmentExpr &) override {} - + virtual void visit (HIR::CompoundAssignmentExpr &) override {} virtual void visit (HIR::GroupedExpr &) override {} virtual void visit (HIR::ArrayElemsValues &) override {} |