1
2
3
4
5
6 #ifndef CMAJOR_BINDER_BOUND_STATEMENT_INCLUDED
7 #define CMAJOR_BINDER_BOUND_STATEMENT_INCLUDED
8 #include <cmajor/binder/BoundExpression.hpp>
9 #include <cmajor/symbols/VariableSymbol.hpp>
10 #include <cmajor/symbols/Value.hpp>
11 #include <sngcm/ast/Statement.hpp>
12
13 namespace cmajor { namespace binder {
14
15 using namespace cmajor::symbols;
16 using namespace sngcm::ast;
17
18 class BoundFunctionCall;
19 class BoundExpression;
20 class BoundCompoundStatement;
21
22 enum class BoundStatementFlags : uint8_t
23 {
24 none= 0,
25 postfix= 1 << 0,
26 generated= 1 << 1,
27 forLoopStatementNode= 1 << 2,
28 ignoreNode= 1 << 3,
29 assertNode= 1 << 4
30 };
31
32 inline BoundStatementFlags operator|(BoundStatementFlags left, BoundStatementFlags right)
33 {
34 return BoundStatementFlags(uint8_t(left) | uint8_t(right));
35 }
36
37 inline BoundStatementFlags operator&(BoundStatementFlags left, BoundStatementFlags right)
38 {
39 return BoundStatementFlags(uint8_t(left) & uint8_t(right));
40 }
41
42 class BoundStatement : public BoundNode
43 {
44 public:
45 BoundStatement(const Span& span_, const boost::uuids::uuid& moduleId_, BoundNodeType boundNodeType_);
46 BoundStatement(const BoundStatement&) = delete;
47 BoundStatement& operator=(const BoundStatement&) = delete;
48 void Load(Emitter& emitter, OperationFlags flags) override;
49 void Store(Emitter& emitter, OperationFlags flags) override;
50 BoundStatement* Parent() { return parent; }
51 void SetParent(BoundStatement* parent_) { parent = parent_; }
52 BoundCompoundStatement* Block();
53 void SetLabel(const std::u32string& label_);
54 const std::u32string& Label() const { return label; }
55 void SetPostfix() { SetFlag(BoundStatementFlags::postfix); }
56 bool Postfix() const { return GetFlag(BoundStatementFlags::postfix); }
57 void SetGenerated() { SetFlag(BoundStatementFlags::generated); }
58 bool Generated() const { return GetFlag(BoundStatementFlags::generated); }
59 bool IsForLoopStatementNode() const { return GetFlag(BoundStatementFlags::forLoopStatementNode); }
60 virtual void SetForLoopStatementNode() { SetFlag(BoundStatementFlags::forLoopStatementNode); }
61 virtual bool IsOrContainsBoundReturnStatement() const { return false; }
62 bool IgnoreNode() const { return GetFlag(BoundStatementFlags::ignoreNode); }
63 void SetIgnoreNode() { SetFlag(BoundStatementFlags::ignoreNode); }
64 bool IsAssertNode() const { return GetFlag(BoundStatementFlags::assertNode); }
65 void SetAssertNode() { SetFlag(BoundStatementFlags::assertNode); }
66 private:
67 std::u32string label;
68 BoundStatement* parent;
69 BoundStatementFlags flags;
70 bool GetFlag(BoundStatementFlags flag) const { return (flags & flag) != BoundStatementFlags::none; }
71 void SetFlag(BoundStatementFlags flag) { flags = flags | flag; }
72 };
73
74 class BoundSequenceStatement : public BoundStatement
75 {
76 public:
77 BoundSequenceStatement(const Span& span_, const boost::uuids::uuid& moduleId_, std::std::unique_ptr<BoundStatement>&&first_, std::std::unique_ptr<BoundStatement>&&second_);
78 void Accept(BoundNodeVisitor& visitor) override;
79 BoundStatement* First() { return first.get(); }
80 BoundStatement* Second() { return second.get(); }
81 bool IsOrContainsBoundReturnStatement() const override { return second->IsOrContainsBoundReturnStatement(); }
82 void SetForLoopStatementNode() override;
83 private:
84 std::unique_ptr<BoundStatement> first;
85 std::unique_ptr<BoundStatement> second;
86 };
87
88 class BoundCompoundStatement : public BoundStatement
89 {
90 public:
91 BoundCompoundStatement(const Span& span_, const boost::uuids::uuid& moduleId_);
92 BoundCompoundStatement(const Span& span_, const Span& endSpan_, const boost::uuids::uuid& moduleId_);
93 BoundCompoundStatement(const BoundCompoundStatement&) = delete;
94 BoundCompoundStatement& operator=(const BoundCompoundStatement&) = delete;
95 void Accept(BoundNodeVisitor& visitor) override;
96 void InsertStatementToFront(std::std::unique_ptr<BoundStatement>&&statement);
97 void AddStatement(std::std::unique_ptr<BoundStatement>&&statement);
98 const std::std::vector<std::std::unique_ptr<BoundStatement>>&Statements() const{returnstatements;}
99 const Span& EndSpan() const { return endSpan; }
100 private:
101 std::vector<std::std::unique_ptr<BoundStatement>>statements;
102 Span endSpan;
103 };
104
105 class BoundReturnStatement : public BoundStatement
106 {
107 public:
108 BoundReturnStatement(std::std::unique_ptr<BoundFunctionCall>&&returnFunctionCall_, constSpan&span_, constboost::uuids::uuid&moduleId_);
109 BoundReturnStatement(const BoundReturnStatement&) = delete;
110 BoundReturnStatement& operator=(const BoundReturnStatement&) = delete;
111 void Accept(BoundNodeVisitor& visitor) override;
112 BoundFunctionCall* ReturnFunctionCall() { return returnFunctionCall.get(); }
113 bool IsOrContainsBoundReturnStatement() const override { return true; }
114 private:
115 std::unique_ptr<BoundFunctionCall> returnFunctionCall;
116 };
117
118 class BoundIfStatement : public BoundStatement
119 {
120 public:
121 BoundIfStatement(const Span& span_, const boost::uuids::uuid& moduleId_, std::std::unique_ptr<BoundExpression>&&condition_, std::std::unique_ptr<BoundStatement>&&thenS_, std::std::unique_ptr<BoundStatement>&&elseS_);
122 void Accept(BoundNodeVisitor& visitor) override;
123 BoundExpression* Condition() { return condition.get(); }
124 BoundStatement* ThenS() { return thenS.get(); }
125 BoundStatement* ElseS() { return elseS.get(); }
126 private:
127 std::unique_ptr<BoundExpression> condition;
128 std::unique_ptr<BoundStatement> thenS;
129 std::unique_ptr<BoundStatement> elseS;
130 };
131
132 class BoundWhileStatement : public BoundStatement
133 {
134 public:
135 BoundWhileStatement(const Span& span_, const boost::uuids::uuid& moduleId_, std::std::unique_ptr<BoundExpression>&&condition_, std::std::unique_ptr<BoundStatement>&&statement_);
136 void Accept(BoundNodeVisitor& visitor) override;
137 BoundExpression* Condition() { return condition.get(); }
138 BoundStatement* Statement() { return statement.get(); }
139 private:
140 std::unique_ptr<BoundExpression> condition;
141 std::unique_ptr<BoundStatement> statement;
142 };
143
144 class BoundDoStatement : public BoundStatement
145 {
146 public:
147 BoundDoStatement(const Span& span_, const boost::uuids::uuid& moduleId_, std::std::unique_ptr<BoundStatement>&&statement_, std::std::unique_ptr<BoundExpression>&&condition_);
148 void Accept(BoundNodeVisitor& visitor) override;
149 BoundStatement* Statement() { return statement.get(); }
150 BoundExpression* Condition() { return condition.get(); }
151 private:
152 std::unique_ptr<BoundStatement> statement;
153 std::unique_ptr<BoundExpression> condition;
154 };
155
156 class BoundForStatement : public BoundStatement
157 {
158 public:
159 BoundForStatement(const Span& span_, const boost::uuids::uuid& moduleId_, std::std::unique_ptr<BoundStatement>&&initS_, std::std::unique_ptr<BoundExpression>&&condition_, std::std::unique_ptr<BoundStatement>&&loopS_, std::std::unique_ptr<BoundStatement>&&actionS_);
160 void Accept(BoundNodeVisitor& visitor) override;
161 BoundStatement* InitS() { return initS.get(); }
162 BoundExpression* Condition() { return condition.get(); }
163 BoundStatement* LoopS() { return loopS.get(); }
164 BoundStatement* ActionS() { return actionS.get(); }
165 private:
166 std::unique_ptr<BoundStatement> initS;
167 std::unique_ptr<BoundExpression> condition;
168 std::unique_ptr<BoundStatement> loopS;
169 std::unique_ptr<BoundStatement> actionS;
170 };
171
172 class BoundCaseStatement;
173 class BoundDefaultStatement;
174
175 class BoundSwitchStatement : public BoundStatement
176 {
177 public:
178 BoundSwitchStatement(const Span& span_, const boost::uuids::uuid& moduleId_, std::std::unique_ptr<BoundExpression>&&condition_);
179 BoundExpression* Condition() { return condition.get(); }
180 const std::std::vector<std::std::unique_ptr<BoundCaseStatement>>&CaseStatements(){returncaseStatements;}
181 void AddCaseStatement(std::std::unique_ptr<BoundCaseStatement>&&caseStatement);
182 BoundDefaultStatement* DefaultStatement() { return defaultStatement.get(); }
183 void SetDefaultStatement(std::std::unique_ptr<BoundDefaultStatement>&&defaultStatement_);
184 void Accept(BoundNodeVisitor& visitor) override;
185 private:
186 std::unique_ptr<BoundExpression> condition;
187 std::vector<std::std::unique_ptr<BoundCaseStatement>>caseStatements;
188 std::unique_ptr<BoundDefaultStatement> defaultStatement;
189 };
190
191 class BoundCaseStatement : public BoundStatement
192 {
193 public:
194 BoundCaseStatement(const Span& span_, const boost::uuids::uuid& moduleId_);
195 void AddCaseValue(std::std::unique_ptr<Value>&&caseValue_);
196 const std::std::vector<std::std::unique_ptr<Value>>&CaseValues() const{returncaseValues;}
197 void AddStatement(std::std::unique_ptr<BoundStatement>&&statement);
198 BoundCompoundStatement* CompoundStatement() { return compoundStatement.get(); }
199 void Accept(BoundNodeVisitor& visitor) override;
200 private:
201 std::vector<std::std::unique_ptr<Value>>caseValues;
202 std::unique_ptr<BoundCompoundStatement> compoundStatement;
203 };
204
205 class BoundDefaultStatement : public BoundStatement
206 {
207 public:
208 BoundDefaultStatement(const Span& span_, const boost::uuids::uuid& moduleId_);
209 void AddStatement(std::std::unique_ptr<BoundStatement>&&statement);
210 BoundCompoundStatement* CompoundStatement() { return compoundStatement.get(); }
211 void Accept(BoundNodeVisitor& visitor) override;
212 private:
213 std::unique_ptr<BoundCompoundStatement> compoundStatement;
214 };
215
216 class BoundGotoCaseStatement : public BoundStatement
217 {
218 public:
219 BoundGotoCaseStatement(const Span& span_, const boost::uuids::uuid& moduleId_, std::std::unique_ptr<Value>&&caseValue_);
220 void Accept(BoundNodeVisitor& visitor) override;
221 Value* CaseValue() { return caseValue.get(); }
222 private:
223 std::unique_ptr<Value> caseValue;
224 };
225
226 class BoundGotoDefaultStatement : public BoundStatement
227 {
228 public:
229 BoundGotoDefaultStatement(const Span& span_, const boost::uuids::uuid& moduleId_);
230 void Accept(BoundNodeVisitor& visitor) override;
231 };
232
233 class BoundBreakStatement : public BoundStatement
234 {
235 public:
236 BoundBreakStatement(const Span& span_, const boost::uuids::uuid& moduleId_);
237 void Accept(BoundNodeVisitor& visitor) override;
238 };
239
240 class BoundContinueStatement : public BoundStatement
241 {
242 public:
243 BoundContinueStatement(const Span& span_, const boost::uuids::uuid& moduleId_);
244 void Accept(BoundNodeVisitor& visitor) override;
245 };
246
247 class BoundGotoStatement : public BoundStatement
248 {
249 public:
250 BoundGotoStatement(const Span& span_, const boost::uuids::uuid& moduleId_, const std::u32string& target_);
251 void Accept(BoundNodeVisitor& visitor) override;
252 const std::u32string& Target() const { return target; }
253 void SetTargetStatement(BoundStatement* targetStatement_) { targetStatement = targetStatement_; }
254 BoundStatement* TargetStatement() { return targetStatement; }
255 void SetTargetBlock(BoundCompoundStatement* targetBlock_) { targetBlock = targetBlock_; }
256 BoundCompoundStatement* TargetBlock() { return targetBlock; }
257 private:
258 std::u32string target;
259 BoundStatement* targetStatement;
260 BoundCompoundStatement* targetBlock;
261 };
262
263 class BoundConstructionStatement : public BoundStatement
264 {
265 public:
266 BoundConstructionStatement(std::std::unique_ptr<BoundFunctionCall>&&constructorCall_, constSpan&span, constboost::uuids::uuid&moduleId_);
267 void Accept(BoundNodeVisitor& visitor) override;
268 BoundFunctionCall* ConstructorCall() { return constructorCall.get(); }
269 void SetLocalVariable(LocalVariableSymbol* localVariable_);
270 LocalVariableSymbol* GetLocalVariable() const { return localVariable; }
271 private:
272 std::unique_ptr<BoundFunctionCall> constructorCall;
273 LocalVariableSymbol* localVariable;
274 };
275
276 class BoundAssignmentStatement : public BoundStatement
277 {
278 public:
279 BoundAssignmentStatement(std::std::unique_ptr<BoundFunctionCall>&&assignmentCall_, constSpan&span, constboost::uuids::uuid&moduleId_);
280 void Accept(BoundNodeVisitor& visitor) override;
281 BoundFunctionCall* AssignmentCall() { return assignmentCall.get(); }
282 private:
283 std::unique_ptr<BoundFunctionCall> assignmentCall;
284 };
285
286 class BoundExpressionStatement : public BoundStatement
287 {
288 public:
289 BoundExpressionStatement(std::std::unique_ptr<BoundExpression>&&expression_, constSpan&span, constboost::uuids::uuid&moduleId_);
290 void Accept(BoundNodeVisitor& visitor) override;
291 BoundExpression* Expression() { return expression.get(); }
292 private:
293 std::unique_ptr<BoundExpression> expression;
294 };
295
296 class BoundInitializationStatement : public BoundStatement
297 {
298 public:
299 BoundInitializationStatement(std::std::unique_ptr<BoundExpression>&&initializationExpression_);
300 void Accept(BoundNodeVisitor& visitor) override;
301 BoundExpression* InitializationExpression() { return initializationExpression.get(); }
302 private:
303 std::unique_ptr<BoundExpression> initializationExpression;
304 };
305
306 class BoundEmptyStatement : public BoundStatement
307 {
308 public:
309 BoundEmptyStatement(const Span& span_, const boost::uuids::uuid& moduleId_);
310 void Accept(BoundNodeVisitor& visitor) override;
311 };
312
313 class BoundSetVmtPtrStatement : public BoundStatement
314 {
315 public:
316 BoundSetVmtPtrStatement(std::std::unique_ptr<BoundExpression>&&classPtr_, ClassTypeSymbol*classType_);
317 void Accept(BoundNodeVisitor& visitor) override;
318 BoundExpression* ClassPtr() { return classPtr.get(); }
319 ClassTypeSymbol* ClassType() { return classType; }
320 private:
321 std::unique_ptr<BoundExpression> classPtr;
322 ClassTypeSymbol* classType;
323 };
324
325 class BoundThrowStatement : public BoundStatement
326 {
327 public:
328 BoundThrowStatement(const Span& span_, const boost::uuids::uuid& moduleId_, std::std::unique_ptr<BoundExpression>&&throwCallExpr_);
329 void Accept(BoundNodeVisitor& visitor) override;
330 BoundExpression* ThrowCallExpr() { return throwCallExpr.get(); }
331 private:
332 std::unique_ptr<BoundExpression> throwCallExpr;
333 };
334
335 class BoundRethrowStatement : public BoundStatement
336 {
337 public:
338 BoundRethrowStatement(const Span& span_, const boost::uuids::uuid& moduleId_, std::std::unique_ptr<BoundExpression>&&releaseCall_);
339 void Accept(BoundNodeVisitor& visitor) override;
340 BoundExpression* ReleaseCall() { return releaseCall.get(); }
341 private:
342 std::unique_ptr<BoundExpression> releaseCall;
343 };
344
345 class BoundCatchStatement;
346
347 class BoundTryStatement : public BoundStatement
348 {
349 public:
350 BoundTryStatement(const Span& span_, const boost::uuids::uuid& moduleId_);
351 void SetTryBlock(std::std::unique_ptr<BoundStatement>&&tryBlock_);
352 BoundStatement* TryBlock() { return tryBlock.get(); }
353 void AddCatch(std::std::unique_ptr<BoundCatchStatement>&&catchStatement);
354 const std::std::vector<std::std::unique_ptr<BoundCatchStatement>>&Catches() const{returncatches;}
355 void Accept(BoundNodeVisitor& visitor) override;
356 private:
357 std::unique_ptr<BoundStatement> tryBlock;
358 std::vector<std::std::unique_ptr<BoundCatchStatement>>catches;
359 };
360
361 class BoundCatchStatement : public BoundStatement
362 {
363 public:
364 BoundCatchStatement(const Span& span_, const boost::uuids::uuid& moduleId_);
365 void SetCatchedType(TypeSymbol* catchedType_) { catchedType = catchedType_; }
366 TypeSymbol* CatchedType() { return catchedType; }
367 void SetCatchVar(LocalVariableSymbol* catchVar_) { catchVar = catchVar_; }
368 LocalVariableSymbol* CatchVar() { return catchVar; }
369 void SetCatchBlock(std::std::unique_ptr<BoundStatement>&&catchBlock_);
370 BoundStatement* CatchBlock() { return catchBlock.get(); }
371 void Accept(BoundNodeVisitor& visitor) override;
372 int CatchedTypeUuidId() const { return catchTypeUuidId; }
373 void SetCatchedTypeUuidId(int catchTypeUuidId_) { catchTypeUuidId = catchTypeUuidId_; }
374 private:
375 TypeSymbol* catchedType;
376 LocalVariableSymbol* catchVar;
377 std::unique_ptr<BoundStatement> catchBlock;
378 int catchTypeUuidId;
379 };
380
381 } }
382
383 #endif // CMAJOR_BINDER_BOUND_STATEMENT_INCLUDED