blob: 9bce5489e53a71cbfb4d4f5d8f6d5b15595e0ca0 [file] [log] [blame]
dan sinclair1c9b4862020-04-07 19:27:41 +00001// Copyright 2020 The Tint Authors.
2//
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#ifndef SRC_AST_BINARY_EXPRESSION_H_
16#define SRC_AST_BINARY_EXPRESSION_H_
17
18#include <memory>
19#include <utility>
20
21#include "src/ast/expression.h"
22#include "src/ast/literal.h"
23
24namespace tint {
25namespace ast {
26
27/// The operator type
28enum class BinaryOp {
29 kNone = 0,
30 kAnd,
31 kOr,
32 kXor,
33 kLogicalAnd,
34 kLogicalOr,
35 kEqual,
36 kNotEqual,
37 kLessThan,
38 kGreaterThan,
39 kLessThanEqual,
40 kGreaterThanEqual,
41 kShiftLeft,
42 kShiftRight,
dan sinclair1c9b4862020-04-07 19:27:41 +000043 kAdd,
44 kSubtract,
45 kMultiply,
46 kDivide,
47 kModulo,
48};
49
50/// An binary expression
Ben Claytone319d7f2020-11-30 23:30:58 +000051class BinaryExpression : public Castable<BinaryExpression, Expression> {
dan sinclair1c9b4862020-04-07 19:27:41 +000052 public:
53 /// Constructor
dan sinclair1c9b4862020-04-07 19:27:41 +000054 /// @param source the binary expression source
55 /// @param op the operation type
56 /// @param lhs the left side of the expression
57 /// @param rhs the right side of the expression
58 BinaryExpression(const Source& source,
59 BinaryOp op,
Ben Claytonb053acf2020-11-16 16:31:07 +000060 Expression* lhs,
61 Expression* rhs);
dan sinclair1c9b4862020-04-07 19:27:41 +000062 /// Move constructor
Ryan Harrison4d32be42020-04-09 18:52:06 +000063 BinaryExpression(BinaryExpression&&);
dan sinclair1c9b4862020-04-07 19:27:41 +000064 ~BinaryExpression() override;
65
dan sinclair1c9b4862020-04-07 19:27:41 +000066 /// @returns the binary op type
67 BinaryOp op() const { return op_; }
68
69 /// @returns true if the op is and
70 bool IsAnd() const { return op_ == BinaryOp::kAnd; }
71 /// @returns true if the op is or
72 bool IsOr() const { return op_ == BinaryOp::kOr; }
73 /// @returns true if the op is xor
74 bool IsXor() const { return op_ == BinaryOp::kXor; }
75 /// @returns true if the op is logical and
76 bool IsLogicalAnd() const { return op_ == BinaryOp::kLogicalAnd; }
77 /// @returns true if the op is logical or
78 bool IsLogicalOr() const { return op_ == BinaryOp::kLogicalOr; }
79 /// @returns true if the op is equal
80 bool IsEqual() const { return op_ == BinaryOp::kEqual; }
81 /// @returns true if the op is not equal
82 bool IsNotEqual() const { return op_ == BinaryOp::kNotEqual; }
83 /// @returns true if the op is less than
84 bool IsLessThan() const { return op_ == BinaryOp::kLessThan; }
85 /// @returns true if the op is greater than
86 bool IsGreaterThan() const { return op_ == BinaryOp::kGreaterThan; }
87 /// @returns true if the op is less than equal
88 bool IsLessThanEqual() const { return op_ == BinaryOp::kLessThanEqual; }
89 /// @returns true if the op is greater than equal
90 bool IsGreaterThanEqual() const { return op_ == BinaryOp::kGreaterThanEqual; }
91 /// @returns true if the op is shift left
92 bool IsShiftLeft() const { return op_ == BinaryOp::kShiftLeft; }
93 /// @returns true if the op is shift right
94 bool IsShiftRight() const { return op_ == BinaryOp::kShiftRight; }
dan sinclair1c9b4862020-04-07 19:27:41 +000095 /// @returns true if the op is add
96 bool IsAdd() const { return op_ == BinaryOp::kAdd; }
97 /// @returns true if the op is subtract
98 bool IsSubtract() const { return op_ == BinaryOp::kSubtract; }
99 /// @returns true if the op is multiply
100 bool IsMultiply() const { return op_ == BinaryOp::kMultiply; }
101 /// @returns true if the op is divide
102 bool IsDivide() const { return op_ == BinaryOp::kDivide; }
103 /// @returns true if the op is modulo
104 bool IsModulo() const { return op_ == BinaryOp::kModulo; }
105
dan sinclair1c9b4862020-04-07 19:27:41 +0000106 /// @returns the left side expression
Ben Claytonb053acf2020-11-16 16:31:07 +0000107 Expression* lhs() const { return lhs_; }
dan sinclair1c9b4862020-04-07 19:27:41 +0000108 /// @returns the right side expression
Ben Claytonb053acf2020-11-16 16:31:07 +0000109 Expression* rhs() const { return rhs_; }
dan sinclair1c9b4862020-04-07 19:27:41 +0000110
Ben Claytoned2b9782020-12-01 18:04:17 +0000111 /// Clones this node and all transitive child nodes using the `CloneContext`
112 /// `ctx`.
113 /// @note Semantic information such as resolved expression type and intrinsic
114 /// information is not cloned.
115 /// @param ctx the clone context
116 /// @return the newly cloned node
117 BinaryExpression* Clone(CloneContext* ctx) const override;
118
dan sinclair1c9b4862020-04-07 19:27:41 +0000119 /// @returns true if the node is valid
120 bool IsValid() const override;
121
122 /// Writes a representation of the node to the output stream
123 /// @param out the stream to write to
124 /// @param indent number of spaces to indent the node when writing
125 void to_str(std::ostream& out, size_t indent) const override;
126
127 private:
128 BinaryExpression(const BinaryExpression&) = delete;
129
Ben Claytonbe963762020-12-15 14:52:38 +0000130 BinaryOp const op_;
131 Expression* const lhs_;
132 Expression* const rhs_;
dan sinclair1c9b4862020-04-07 19:27:41 +0000133};
134
135inline std::ostream& operator<<(std::ostream& out, BinaryOp op) {
136 switch (op) {
137 case BinaryOp::kNone:
138 out << "none";
139 break;
140 case BinaryOp::kAnd:
141 out << "and";
142 break;
143 case BinaryOp::kOr:
144 out << "or";
145 break;
146 case BinaryOp::kXor:
147 out << "xor";
148 break;
149 case BinaryOp::kLogicalAnd:
150 out << "logical_and";
151 break;
152 case BinaryOp::kLogicalOr:
153 out << "logical_or";
154 break;
155 case BinaryOp::kEqual:
156 out << "equal";
157 break;
158 case BinaryOp::kNotEqual:
159 out << "not_equal";
160 break;
161 case BinaryOp::kLessThan:
162 out << "less_than";
163 break;
164 case BinaryOp::kGreaterThan:
165 out << "greater_than";
166 break;
167 case BinaryOp::kLessThanEqual:
168 out << "less_than_equal";
169 break;
170 case BinaryOp::kGreaterThanEqual:
171 out << "greater_than_equal";
172 break;
173 case BinaryOp::kShiftLeft:
174 out << "shift_left";
175 break;
176 case BinaryOp::kShiftRight:
177 out << "shift_right";
178 break;
dan sinclair1c9b4862020-04-07 19:27:41 +0000179 case BinaryOp::kAdd:
180 out << "add";
181 break;
182 case BinaryOp::kSubtract:
183 out << "subtract";
184 break;
185 case BinaryOp::kMultiply:
186 out << "multiply";
187 break;
188 case BinaryOp::kDivide:
189 out << "divide";
190 break;
191 case BinaryOp::kModulo:
192 out << "modulo";
193 break;
194 }
195 return out;
196}
197
198} // namespace ast
199} // namespace tint
200
201#endif // SRC_AST_BINARY_EXPRESSION_H_