1 // =================================
  2 // Copyright (c) 2021 Seppo Laakko
  3 // Distributed under the MIT license
  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 leftBoundStatementFlags right)
 33 {
 34     return BoundStatementFlags(uint8_t(left) | uint8_t(right));
 35 }
 36 
 37 inline BoundStatementFlags operator&(BoundStatementFlags leftBoundStatementFlags 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& emitterOperationFlags flags) override;
 49     void Store(Emitter& emitterOperationFlags 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&spanconstboost::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&spanconstboost::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&spanconstboost::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 } } // namespace cmajor::binder
382 
383 #endif // CMAJOR_BINDER_BOUND_STATEMENT_INCLUDED