1 /** 2 * Copyright (c) 2021 - 2023 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef ES2PANDA_IR_EXPRESSION_BINARY_EXPRESSION_H 17 #define ES2PANDA_IR_EXPRESSION_BINARY_EXPRESSION_H 18 19 #include "ir/expression.h" 20 #include "lexer/token/tokenType.h" 21 22 namespace panda::es2panda::checker { 23 class ETSAnalyzer; 24 } // namespace panda::es2panda::checker 25 26 namespace panda::es2panda::ir { 27 class BinaryExpression : public Expression { 28 public: 29 BinaryExpression() = delete; 30 ~BinaryExpression() override = default; 31 32 NO_COPY_SEMANTIC(BinaryExpression); 33 NO_MOVE_SEMANTIC(BinaryExpression); 34 BinaryExpression(Expression * const left,Expression * const right,lexer::TokenType const operatorType)35 explicit BinaryExpression(Expression *const left, Expression *const right, lexer::TokenType const operatorType) 36 : Expression(AstNodeType::BINARY_EXPRESSION), left_(left), right_(right), operator_(operatorType) 37 { 38 } 39 40 // NOTE (csabahurton): friend relationship can be removed once there are getters for private fields 41 friend class checker::ETSAnalyzer; 42 Left()43 [[nodiscard]] const Expression *Left() const noexcept 44 { 45 return left_; 46 } 47 Left()48 [[nodiscard]] Expression *Left() noexcept 49 { 50 return left_; 51 } 52 Right()53 [[nodiscard]] const Expression *Right() const noexcept 54 { 55 return right_; 56 } 57 Right()58 [[nodiscard]] Expression *Right() noexcept 59 { 60 return right_; 61 } 62 Result()63 [[nodiscard]] const Expression *Result() const noexcept 64 { 65 return result_; 66 } 67 Result()68 [[nodiscard]] Expression *Result() noexcept 69 { 70 return result_; 71 } 72 OperatorType()73 [[nodiscard]] lexer::TokenType OperatorType() const noexcept 74 { 75 return operator_; 76 } 77 IsLogical()78 [[nodiscard]] bool IsLogical() const noexcept 79 { 80 return operator_ <= lexer::TokenType::PUNCTUATOR_LOGICAL_AND; 81 } 82 IsLogicalExtended()83 [[nodiscard]] bool IsLogicalExtended() const noexcept 84 { 85 return operator_ == lexer::TokenType::PUNCTUATOR_LOGICAL_AND || 86 operator_ == lexer::TokenType::PUNCTUATOR_LOGICAL_OR; 87 } 88 IsArithmetic()89 [[nodiscard]] bool IsArithmetic() const noexcept 90 { 91 return operator_ == lexer::TokenType::PUNCTUATOR_PLUS || operator_ == lexer::TokenType::PUNCTUATOR_MINUS || 92 operator_ == lexer::TokenType::PUNCTUATOR_MULTIPLY || operator_ == lexer::TokenType::PUNCTUATOR_DIVIDE || 93 operator_ == lexer::TokenType::PUNCTUATOR_MOD || operator_ == lexer::TokenType::PUNCTUATOR_BITWISE_OR || 94 operator_ == lexer::TokenType::PUNCTUATOR_BITWISE_XOR || 95 operator_ == lexer::TokenType::PUNCTUATOR_BITWISE_AND || 96 operator_ == lexer::TokenType::PUNCTUATOR_PLUS_EQUAL || 97 operator_ == lexer::TokenType::PUNCTUATOR_MINUS_EQUAL || 98 operator_ == lexer::TokenType::PUNCTUATOR_MULTIPLY_EQUAL || 99 operator_ == lexer::TokenType::PUNCTUATOR_DIVIDE_EQUAL || 100 operator_ == lexer::TokenType::PUNCTUATOR_MOD_EQUAL || 101 operator_ == lexer::TokenType::PUNCTUATOR_BITWISE_AND_EQUAL || 102 operator_ == lexer::TokenType::PUNCTUATOR_BITWISE_OR_EQUAL || 103 operator_ == lexer::TokenType::PUNCTUATOR_BITWISE_XOR_EQUAL; 104 } 105 SetLeft(Expression * expr)106 void SetLeft(Expression *expr) noexcept 107 { 108 left_ = expr; 109 SetStart(left_->Start()); 110 } 111 SetRight(Expression * expr)112 void SetRight(Expression *expr) noexcept 113 { 114 right_ = expr; 115 SetEnd(right_->End()); 116 } 117 SetResult(Expression * expr)118 void SetResult(Expression *expr) noexcept 119 { 120 left_ = expr; 121 SetStart(left_->Start()); 122 } 123 SetOperator(lexer::TokenType operatorType)124 void SetOperator(lexer::TokenType operatorType) noexcept 125 { 126 operator_ = operatorType; 127 type_ = AstNodeType::BINARY_EXPRESSION; 128 } 129 OperationType()130 [[nodiscard]] checker::Type *OperationType() noexcept 131 { 132 return operationType_; 133 } 134 SetOperationType(checker::Type * const operationType)135 void SetOperationType(checker::Type *const operationType) noexcept 136 { 137 operationType_ = operationType; 138 } 139 OperationType()140 [[nodiscard]] const checker::Type *OperationType() const noexcept 141 { 142 return operationType_; 143 } 144 145 // NOLINTNEXTLINE(google-default-arguments) 146 [[nodiscard]] BinaryExpression *Clone(ArenaAllocator *allocator, AstNode *parent = nullptr) override; 147 148 void TransformChildren(const NodeTransformer &cb) override; 149 void Iterate(const NodeTraverser &cb) const override; 150 void Dump(ir::AstDumper *dumper) const override; 151 void Dump(ir::SrcDumper *dumper) const override; 152 void Compile(compiler::PandaGen *pg) const override; 153 void Compile(compiler::ETSGen *etsg) const override; 154 checker::Type *Check(checker::TSChecker *checker) override; 155 checker::Type *Check(checker::ETSChecker *checker) override; 156 Accept(ASTVisitorT * v)157 void Accept(ASTVisitorT *v) override 158 { 159 v->Accept(this); 160 } 161 162 private: 163 Expression *left_ = nullptr; 164 Expression *right_ = nullptr; 165 Expression *result_ = nullptr; 166 lexer::TokenType operator_; 167 checker::Type *operationType_ {}; 168 }; 169 } // namespace panda::es2panda::ir 170 171 #endif 172