1 // =================================
  2 // Copyright (c) 2021 Seppo Laakko
  3 // Distributed under the MIT license
  4 // =================================
  5 
  6 #include <cmajor/binder/BoundStatement.hpp>
  7 #include <cmajor/binder/BoundNodeVisitor.hpp>
  8 #include <cmajor/binder/BoundExpression.hpp>
  9 #include <cmajor/symbols/Exception.hpp>
 10 
 11 namespace cmajor { namespace binder {
 12 
 13 BoundStatement::BoundStatement(const Span& span_const boost::uuids::uuid& moduleId_BoundNodeType boundNodeType_) :
 14     BoundNode(span_moduleId_boundNodeType_)parent(nullptr)flags(BoundStatementFlags::none)
 15 {
 16 }
 17 
 18 BoundCompoundStatement* BoundStatement::Block()
 19 {
 20     if (GetBoundNodeType() == BoundNodeType::boundCompoundStatement)
 21     {
 22         return static_cast<BoundCompoundStatement*>(this);
 23     }
 24     return parent->Block();
 25 }
 26 
 27 void BoundStatement::Load(Emitter& emitterOperationFlags flags)
 28 {
 29     throw Exception("cannot load from statement"GetSpan()ModuleId());
 30 }
 31 
 32 void BoundStatement::Store(Emitter& emitterOperationFlags flags)
 33 {
 34     throw Exception("cannot store to statement"GetSpan()ModuleId());
 35 }
 36 
 37 void BoundStatement::SetLabel(const std::u32string& label_)
 38 {
 39     label = label_;
 40 }
 41 
 42 BoundSequenceStatement::BoundSequenceStatement(const Span& span_const boost::uuids::uuid& moduleId_std::std::unique_ptr<BoundStatement>&&first_std::std::unique_ptr<BoundStatement>&&second_):
 43     BoundStatement(span_moduleId_BoundNodeType::boundSequenceStatement)first(std::move(first_))second(std::move(second_))
 44 {
 45     first->SetParent(this);
 46     second->SetParent(this);
 47 }
 48 
 49 void BoundSequenceStatement::Accept(BoundNodeVisitor& visitor)
 50 {
 51     visitor.Visit(*this);
 52 }
 53 
 54 void BoundSequenceStatement::SetForLoopStatementNode()
 55 {
 56     first->SetForLoopStatementNode();
 57 }
 58 
 59 BoundCompoundStatement::BoundCompoundStatement(const Span& span_const boost::uuids::uuid& moduleId_) : BoundStatement(span_moduleId_BoundNodeType::boundCompoundStatement)endSpan()
 60 {
 61 }
 62 
 63 BoundCompoundStatement::BoundCompoundStatement(const Span& span_const Span& endSpan_const boost::uuids::uuid& moduleId_) :
 64     BoundStatement(span_moduleId_BoundNodeType::boundCompoundStatement)endSpan(endSpan_)
 65 {
 66 }
 67 
 68 void BoundCompoundStatement::Accept(BoundNodeVisitor& visitor)
 69 {
 70     visitor.Visit(*this);
 71 }
 72 
 73 void BoundCompoundStatement::InsertStatementToFront(std::std::unique_ptr<BoundStatement>&&statement)
 74 {
 75     statement->SetParent(this);
 76     statements.insert(statements.begin()std::move(statement));
 77 }
 78 
 79 void BoundCompoundStatement::AddStatement(std::std::unique_ptr<BoundStatement>&&statement)
 80 {
 81     statement->SetParent(this);
 82     statements.push_back(std::move(statement));
 83 }
 84 
 85 BoundReturnStatement::BoundReturnStatement(std::std::unique_ptr<BoundFunctionCall>&&returnFunctionCall_constSpan&span_constboost::uuids::uuid&moduleId_) :
 86     BoundStatement(span_moduleId_BoundNodeType::boundReturnStatement)returnFunctionCall(std::move(returnFunctionCall_))
 87 {
 88 }
 89 
 90 void BoundReturnStatement::Accept(BoundNodeVisitor& visitor)
 91 {
 92     visitor.Visit(*this);
 93 }
 94 
 95 BoundIfStatement::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_):
 96     BoundStatement(span_moduleId_BoundNodeType::boundIfStatement)condition(std::move(condition_))thenS(std::move(thenS_))elseS(std::move(elseS_))
 97 {
 98     thenS->SetParent(this);
 99     if (elseS)
100     {
101         elseS->SetParent(this);
102     }
103 }
104 
105 void BoundIfStatement::Accept(BoundNodeVisitor& visitor)
106 {
107     visitor.Visit(*this);
108 }
109 
110 BoundWhileStatement::BoundWhileStatement(const Span& span_const boost::uuids::uuid& moduleId_std::std::unique_ptr<BoundExpression>&&condition_std::std::unique_ptr<BoundStatement>&&statement_):
111     BoundStatement(span_moduleId_BoundNodeType::boundWhileStatement)condition(std::move(condition_))statement(std::move(statement_))
112 {
113     statement->SetParent(this);
114 }
115 
116 void BoundWhileStatement::Accept(BoundNodeVisitor& visitor)
117 {
118     visitor.Visit(*this);
119 }
120 
121 BoundDoStatement::BoundDoStatement(const Span& span_const boost::uuids::uuid& moduleId_std::std::unique_ptr<BoundStatement>&&statement_std::std::unique_ptr<BoundExpression>&&condition_):
122     BoundStatement(span_moduleId_BoundNodeType::boundDoStatement)statement(std::move(statement_))condition(std::move(condition_))
123 {
124     statement->SetParent(this);
125 }
126 
127 void BoundDoStatement::Accept(BoundNodeVisitor& visitor)
128 {
129     visitor.Visit(*this);
130 }
131 
132 BoundForStatement::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_
133     std::std::unique_ptr<BoundStatement>&&actionS_):BoundStatement(span_moduleId_BoundNodeType::boundForStatement)initS(std::move(initS_))condition(std::move(condition_))loopS(std::move(loopS_))
134     actionS(std::move(actionS_))
135 {
136     initS->SetParent(this);
137     loopS->SetParent(this);
138     actionS->SetParent(this);
139 }
140 
141 void BoundForStatement::Accept(BoundNodeVisitor& visitor)
142 {
143     visitor.Visit(*this);
144 }
145 
146 BoundSwitchStatement::BoundSwitchStatement(const Span& span_const boost::uuids::uuid& moduleId_std::std::unique_ptr<BoundExpression>&&condition_):
147     BoundStatement(span_moduleId_BoundNodeType::boundSwitchStatement)condition(std::move(condition_))
148 {
149 }
150 
151 void BoundSwitchStatement::AddCaseStatement(std::std::unique_ptr<BoundCaseStatement>&&caseStatement)
152 {
153     caseStatement->SetParent(this);
154     caseStatements.push_back(std::move(caseStatement));
155 }
156 
157 void BoundSwitchStatement::SetDefaultStatement(std::std::unique_ptr<BoundDefaultStatement>&&defaultStatement_)
158 {
159     defaultStatement = std::move(defaultStatement_);
160     defaultStatement->SetParent(this);
161 }
162 
163 void BoundSwitchStatement::Accept(BoundNodeVisitor& visitor)
164 {
165     visitor.Visit(*this);
166 }
167 
168 BoundCaseStatement::BoundCaseStatement(const Span& span_const boost::uuids::uuid& moduleId_) : BoundStatement(span_moduleId_BoundNodeType::boundCaseStatement)
169 {
170 }
171 
172 void BoundCaseStatement::AddCaseValue(std::std::unique_ptr<Value>&&caseValue)
173 {
174     caseValues.push_back(std::move(caseValue));
175 }
176 
177 void BoundCaseStatement::AddStatement(std::std::unique_ptr<BoundStatement>&&statement)
178 {
179     if (compoundStatement)
180     {
181         compoundStatement->AddStatement(std::move(statement));
182     }
183     else if (statement->GetBoundNodeType() == BoundNodeType::boundCompoundStatement)
184     {
185         compoundStatement.reset(static_cast<BoundCompoundStatement*>(statement.release()));
186         compoundStatement->SetParent(this);
187     }
188     else
189     {
190         compoundStatement.reset(new BoundCompoundStatement(GetSpan()ModuleId()));
191         compoundStatement->SetParent(this);
192         compoundStatement->AddStatement(std::move(statement));
193     }
194 }
195 
196 void BoundCaseStatement::Accept(BoundNodeVisitor& visitor)
197 {
198     visitor.Visit(*this);
199 }
200 
201 BoundDefaultStatement::BoundDefaultStatement(const Span& span_const boost::uuids::uuid& moduleId_) :
202     BoundStatement(span_moduleId_BoundNodeType::boundDefaultStatement)
203 {
204 }
205 
206 void BoundDefaultStatement::AddStatement(std::std::unique_ptr<BoundStatement>&&statement)
207 {
208     if (compoundStatement)
209     {
210         compoundStatement->AddStatement(std::move(statement));
211     }
212     else if (statement->GetBoundNodeType() == BoundNodeType::boundCompoundStatement)
213     {
214         compoundStatement.reset(static_cast<BoundCompoundStatement*>(statement.release()));
215         compoundStatement->SetParent(this);
216     }
217     else
218     {
219         compoundStatement.reset(new BoundCompoundStatement(GetSpan()ModuleId()));
220         compoundStatement->SetParent(this);
221         compoundStatement->AddStatement(std::move(statement));
222     }
223 }
224 
225 void BoundDefaultStatement::Accept(BoundNodeVisitor& visitor)
226 {
227     visitor.Visit(*this);
228 }
229 
230 BoundGotoCaseStatement::BoundGotoCaseStatement(const Span& span_const boost::uuids::uuid& moduleId_std::std::unique_ptr<Value>&&caseValue_):
231     BoundStatement(span_moduleId_BoundNodeType::boundGotoCaseStatement)caseValue(std::move(caseValue_))
232 {
233 }
234 
235 void BoundGotoCaseStatement::Accept(BoundNodeVisitor& visitor)
236 {
237     visitor.Visit(*this);
238 }
239 
240 BoundGotoDefaultStatement::BoundGotoDefaultStatement(const Span& span_const boost::uuids::uuid& moduleId_) : BoundStatement(span_moduleId_BoundNodeType::boundGotoDefaultStatement)
241 {
242 }
243 
244 void BoundGotoDefaultStatement::Accept(BoundNodeVisitor& visitor)
245 {
246     visitor.Visit(*this);
247 }
248 
249 BoundBreakStatement::BoundBreakStatement(const Span& span_const boost::uuids::uuid& moduleId_) : BoundStatement(span_moduleId_BoundNodeType::boundBreakStatement)
250 {
251 }
252 
253 void BoundBreakStatement::Accept(BoundNodeVisitor& visitor)
254 {
255     visitor.Visit(*this);
256 }
257 
258 BoundContinueStatement::BoundContinueStatement(const Span& span_const boost::uuids::uuid& moduleId_) : BoundStatement(span_moduleId_BoundNodeType::boundContinueStatement)
259 {
260 }
261 
262 void BoundContinueStatement::Accept(BoundNodeVisitor& visitor)
263 {
264     visitor.Visit(*this);
265 }
266 
267 BoundGotoStatement::BoundGotoStatement(const Span& span_const boost::uuids::uuid& moduleId_const std::u32string& target_) :
268     BoundStatement(span_moduleId_BoundNodeType::boundGotoStatement)target(target_)targetStatement(nullptr)targetBlock(nullptr)
269 {
270 }
271 
272 void BoundGotoStatement::Accept(BoundNodeVisitor& visitor)
273 {
274     visitor.Visit(*this);
275 }
276 
277 BoundConstructionStatement::BoundConstructionStatement(std::std::unique_ptr<BoundFunctionCall>&&constructorCall_constSpan&spanconstboost::uuids::uuid&moduleId_) :
278     BoundStatement(spanmoduleId_BoundNodeType::boundConstructionStatement)constructorCall(std::move(constructorCall_))localVariable(nullptr)
279 {
280 }
281 
282 void BoundConstructionStatement::SetLocalVariable(LocalVariableSymbol* localVariable_)
283 {
284     localVariable = localVariable_;
285 }
286 
287 void BoundConstructionStatement::Accept(BoundNodeVisitor& visitor)
288 {
289     visitor.Visit(*this);
290 }
291 
292 BoundAssignmentStatement::BoundAssignmentStatement(std::std::unique_ptr<BoundFunctionCall>&&assignmentCall_constSpan&spanconstboost::uuids::uuid&moduleId_) :
293     BoundStatement(spanmoduleId_BoundNodeType::boundAssignmentStatement)assignmentCall(std::move(assignmentCall_))
294 {
295 }
296 
297 void BoundAssignmentStatement::Accept(BoundNodeVisitor& visitor)
298 {
299     visitor.Visit(*this);
300 }
301 
302 BoundExpressionStatement::BoundExpressionStatement(std::std::unique_ptr<BoundExpression>&&expression_constSpan&spanconstboost::uuids::uuid&moduleId_) :
303     BoundStatement(spanmoduleId_BoundNodeType::boundExpressionStatement)expression(std::move(expression_))
304 {
305 }
306 
307 void BoundExpressionStatement::Accept(BoundNodeVisitor& visitor)
308 {
309     visitor.Visit(*this);
310 }
311 
312 BoundInitializationStatement::BoundInitializationStatement(std::std::unique_ptr<BoundExpression>&&initializationExpression_):
313     BoundStatement(initializationExpression_->GetSpan()initializationExpression_->ModuleId()BoundNodeType::boundInitializationStatement)
314     initializationExpression(std::move(initializationExpression_))
315 {
316 }
317 
318 void BoundInitializationStatement::Accept(BoundNodeVisitor& visitor)
319 {
320     visitor.Visit(*this);
321 }
322 
323 BoundEmptyStatement::BoundEmptyStatement(const Span& span_const boost::uuids::uuid& moduleId_) : BoundStatement(span_moduleId_BoundNodeType::boundEmptyStatement)
324 {
325 }
326 
327 void BoundEmptyStatement::Accept(BoundNodeVisitor& visitor)
328 {
329     visitor.Visit(*this);
330 }
331 
332 BoundSetVmtPtrStatement::BoundSetVmtPtrStatement(std::std::unique_ptr<BoundExpression>&&classPtr_ClassTypeSymbol*classType_):
333     BoundStatement(classPtr_->GetSpan()classPtr_->ModuleId()BoundNodeType::boundSetVmtPtrStatement)classPtr(std::move(classPtr_))classType(classType_)
334 {
335 }
336 
337 void BoundSetVmtPtrStatement::Accept(BoundNodeVisitor& visitor)
338 {
339     visitor.Visit(*this);
340 }
341 
342 BoundThrowStatement::BoundThrowStatement(const Span& span_const boost::uuids::uuid& moduleId_std::std::unique_ptr<BoundExpression>&&throwCallExpr_):
343     BoundStatement(span_moduleId_BoundNodeType::boundThrowStatement)throwCallExpr(std::move(throwCallExpr_))
344 {
345 }
346 
347 void BoundThrowStatement::Accept(BoundNodeVisitor& visitor)
348 {
349     visitor.Visit(*this);
350 }
351 
352 BoundRethrowStatement::BoundRethrowStatement(const Span& span_const boost::uuids::uuid& moduleId_std::std::unique_ptr<BoundExpression>&&releaseCall_):
353     BoundStatement(span_moduleId_BoundNodeType::boundRethrowStatement)releaseCall(std::move(releaseCall_))
354 {
355 }
356 
357 void BoundRethrowStatement::Accept(BoundNodeVisitor& visitor)
358 {
359     visitor.Visit(*this);
360 }
361 
362 BoundTryStatement::BoundTryStatement(const Span& span_const boost::uuids::uuid& moduleId_) : BoundStatement(span_moduleId_BoundNodeType::boundTryStatement)
363 {
364 }
365 
366 void BoundTryStatement::SetTryBlock(std::std::unique_ptr<BoundStatement>&&tryBlock_)
367 {
368     tryBlock = std::move(tryBlock_);
369     tryBlock->SetParent(this);
370 }
371 
372 void BoundTryStatement::AddCatch(std::std::unique_ptr<BoundCatchStatement>&&catchStatement)
373 {
374     catchStatement->SetParent(this);
375     catches.push_back(std::move(catchStatement));
376 }
377 
378 void BoundTryStatement::Accept(BoundNodeVisitor& visitor)
379 {
380     visitor.Visit(*this);
381 }
382 
383 BoundCatchStatement::BoundCatchStatement(const Span& span_const boost::uuids::uuid& moduleId_) :
384     BoundStatement(span_moduleId_BoundNodeType::boundCatchStatement)catchedType(nullptr)catchTypeUuidId(-1)catchVar(nullptr)
385 {
386 }
387 
388 void BoundCatchStatement::SetCatchBlock(std::std::unique_ptr<BoundStatement>&&catchBlock_)
389 {
390     catchBlock = std::move(catchBlock_);
391     catchBlock->SetParent(this);
392 }
393 
394 void BoundCatchStatement::Accept(BoundNodeVisitor& visitor)
395 {
396     visitor.Visit(*this);
397 }
398 
399 } } // namespace cmajor::binder