1 // =================================
  2 // Copyright (c) 2021 Seppo Laakko
  3 // Distributed under the MIT license
  4 // =================================
  5 
  6 #ifndef SNGCM_AST_STATEMENT_INCLUDED
  7 #define SNGCM_AST_STATEMENT_INCLUDED
  8 #include <sngcm/ast/Node.hpp>
  9 #include <sngcm/ast/NodeList.hpp>
 10 
 11 namespace sngcm { namespace ast {
 12 
 13 class IdentifierNode;
 14 
 15 class LabelNode public Node
 16 {
 17 public:
 18     LabelNode(const Span& span_const boost::uuids::uuid& moduleId_);
 19     LabelNode(const Span& span_const boost::uuids::uuid& moduleId_const std::u32string& label_);
 20     Node* Clone(CloneContext& cloneContext) const override;
 21     void Accept(Visitor& visitor) override;
 22     void Write(AstWriter& writer) override;
 23     void Read(AstReader& reader) override;
 24     const std::u32string& Label() const { return label; }
 25 private:
 26     std::u32string label;
 27 };
 28 
 29 class StatementNode public Node
 30 {
 31 public:
 32     StatementNode(NodeType nodeType_const Span& span_const boost::uuids::uuid& moduleId_);
 33     void Write(AstWriter& writer) override;
 34     void Read(AstReader& reader) override;
 35     bool IsStatementNode() const override { return true; }
 36     virtual bool IsFunctionTerminatingNode() const { return false; }
 37     virtual bool IsCaseTerminatingNode() const { return false; }
 38     virtual bool IsDefaultTerminatingNode() const { return false; }
 39     virtual bool IsBreakEnclosingStatementNode() const { return false; }
 40     virtual bool IsContinueEnclosingStatementNode() const { return false; }
 41 };
 42 
 43 class LabeledStatementNode public StatementNode
 44 {
 45 public:
 46     LabeledStatementNode(const Span& span_const boost::uuids::uuid& moduleId_);
 47     LabeledStatementNode(const Span& span_const boost::uuids::uuid& moduleId_StatementNode* stmt_);
 48     Node* Clone(CloneContext& cloneContext) const override;
 49     void Accept(Visitor& visitor) override;
 50     void Write(AstWriter& writer) override;
 51     void Read(AstReader& reader) override;
 52     const LabelNode* Label() const { return labelNode.get(); }
 53     LabelNode* Label() { return labelNode.get(); }
 54     void SetLabelNode(LabelNode* labelNode_);
 55     StatementNode* Stmt() { return stmt.get(); }
 56 private:
 57     std::unique_ptr<LabelNode> labelNode;
 58     std::unique_ptr<StatementNode> stmt;
 59 };
 60 
 61 class SyncStatementNode public StatementNode
 62 {
 63 public:
 64     SyncStatementNode(const Span& span_const boost::uuids::uuid& moduleId_);
 65     Node* Clone(CloneContext& cloneContext) const override;
 66     void Accept(Visitor& visitor) override;
 67 };
 68 
 69 
 70 class CompoundStatementNode public StatementNode
 71 {
 72 public:
 73     CompoundStatementNode(const Span& span_const boost::uuids::uuid& moduleId_);
 74     Node* Clone(CloneContext& cloneContext) const override;
 75     void Accept(Visitor& visitor) override;
 76     void Write(AstWriter& writer) override;
 77     void Read(AstReader& reader) override;
 78     void AddStatement(StatementNode* statement);
 79     NodeList<StatementNode>& Statements() { return statements; }
 80     void SetBeginBraceSpan(const Span& beginBraceSpan_) { beginBraceSpan = beginBraceSpan_; }
 81     const Span& BeginBraceSpan() const { return beginBraceSpan; }
 82     void SetEndBraceSpan(const Span& endBraceSpan_) { endBraceSpan = endBraceSpan_; }
 83     const Span& EndBraceSpan() const { return endBraceSpan; }
 84     bool TracerInserted() const { return tracerInserted; }
 85     void SetTracerInserted() { tracerInserted = true; }
 86 private:
 87     NodeList<StatementNode> statements;
 88     Span beginBraceSpan;
 89     Span endBraceSpan;
 90     bool tracerInserted;
 91 };
 92 
 93 class ReturnStatementNode public StatementNode
 94 {
 95 public:
 96     ReturnStatementNode(const Span& span_const boost::uuids::uuid& moduleId_);
 97     ReturnStatementNode(const Span& span_const boost::uuids::uuid& moduleId_Node* expression_);
 98     Node* Clone(CloneContext& cloneContext) const override;
 99     void Accept(Visitor& visitor) override;
100     void Write(AstWriter& writer) override;
101     void Read(AstReader& reader) override;
102     bool IsFunctionTerminatingNode() const override { return true; }
103     bool IsCaseTerminatingNode() const override { return true; }
104     bool IsDefaultTerminatingNode() const override { return true; }
105     const Node* Expression() const { return expression.get(); }
106     Node* Expression() { return expression.get(); }
107 private:
108     std::unique_ptr<Node> expression;
109 };
110 
111 class IfStatementNode public StatementNode
112 {
113 public:
114     IfStatementNode(const Span& span_const boost::uuids::uuid& moduleId_);
115     IfStatementNode(const Span& span_const boost::uuids::uuid& moduleId_Node* condition_StatementNode* thenS_StatementNode* elseS_);
116     Node* Clone(CloneContext& cloneContext) const override;
117     void Accept(Visitor& visitor) override;
118     void Write(AstWriter& writer) override;
119     void Read(AstReader& reader) override;
120     const Node* Condition() const { return condition.get(); }
121     Node* Condition() { return condition.get(); }
122     const StatementNode* ThenS() const { return thenS.get(); }
123     StatementNode* ThenS() { return thenS.get(); }
124     const StatementNode* ElseS() const { return elseS.get(); }
125     StatementNode* ElseS() { return elseS.get(); }
126     void SetLeftParenSpan(const Span& leftParenSpan_) { leftParenSpan = leftParenSpan_; }
127     const Span& LeftParenSpan() const { return leftParenSpan; }
128     void SetRightParenSpan(const Span& rightParenSpan_) { rightParenSpan = rightParenSpan_; }
129     const Span& RightParenSpan() const { return rightParenSpan; }
130     void SetElseSpan(const Span& elseSpan_) { elseSpan = elseSpan_; }
131     const Span& ElseSpan() const { return elseSpan; }
132 private:
133     std::unique_ptr<Node> condition;
134     std::unique_ptr<StatementNode> thenS;
135     std::unique_ptr<StatementNode> elseS;
136     Span leftParenSpan;
137     Span rightParenSpan;
138     Span elseSpan;
139 };
140 
141 class WhileStatementNode public StatementNode
142 {
143 public:
144     WhileStatementNode(const Span& span_const boost::uuids::uuid& moduleId_);
145     WhileStatementNode(const Span& span_const boost::uuids::uuid& moduleId_Node* condition_StatementNode* statement_);
146     Node* Clone(CloneContext& cloneContext) const override;
147     void Accept(Visitor& visitor) override;
148     void Write(AstWriter& writer) override;
149     void Read(AstReader& reader) override;
150     bool IsBreakEnclosingStatementNode() const override { return true; }
151     bool IsContinueEnclosingStatementNode() const override { return true; }
152     const Node* Condition() const { return condition.get(); }
153     Node* Condition() { return condition.get(); }
154     const StatementNode* Statement() const { return statement.get(); }
155     StatementNode* Statement() { return statement.get(); }
156     void SetLeftParenSpan(const Span& leftParenSpan_) { leftParenSpan = leftParenSpan_; }
157     const Span& LeftParenSpan() const { return leftParenSpan; }
158     void SetRightParenSpan(const Span& rightParenSpan_) { rightParenSpan = rightParenSpan_; }
159     const Span& RightParenSpan() const { return rightParenSpan; }
160 private:
161     std::unique_ptr<Node> condition;
162     std::unique_ptr<StatementNode> statement;
163     Span leftParenSpan;
164     Span rightParenSpan;
165 };
166 
167 class DoStatementNode public StatementNode
168 {
169 public:
170     DoStatementNode(const Span& span_const boost::uuids::uuid& moduleId_);
171     DoStatementNode(const Span& span_const boost::uuids::uuid& moduleId_StatementNode* statement_Node* condition_);
172     Node* Clone(CloneContext& cloneContext) const override;
173     void Accept(Visitor& visitor) override;
174     void Write(AstWriter& writer) override;
175     void Read(AstReader& reader) override;
176     bool IsBreakEnclosingStatementNode() const override { return true; }
177     bool IsContinueEnclosingStatementNode() const override { return true; }
178     const StatementNode* Statement() const { return statement.get(); }
179     StatementNode* Statement() { return statement.get(); }
180     const Node* Condition() const { return condition.get(); }
181     Node* Condition() { return condition.get(); }
182     void SetWhileSpan(const Span& whileSpan_) { whileSpan = whileSpan_; }
183     const Span& WhileSpan() const { return whileSpan; }
184     void SetLeftParenSpan(const Span& leftParenSpan_) { leftParenSpan = leftParenSpan_; }
185     const Span& LeftParenSpan() const { return leftParenSpan; }
186     void SetRightParenSpan(const Span& rightParenSpan_) { rightParenSpan = rightParenSpan_; }
187     const Span& RightParenSpan() const { return rightParenSpan; }
188 private:
189     std::unique_ptr<StatementNode> statement;
190     std::unique_ptr<Node> condition;
191     Span whileSpan;
192     Span leftParenSpan;
193     Span rightParenSpan;
194 };
195 
196 class ForStatementNode public StatementNode
197 {
198 public:
199     ForStatementNode(const Span& span_const boost::uuids::uuid& moduleId_);
200     ForStatementNode(const Span& span_const boost::uuids::uuid& moduleId_StatementNode* initS_Node* condition_StatementNode* loopS_StatementNode* actionS_);
201     Node* Clone(CloneContext& cloneContext) const override;
202     void Accept(Visitor& visitor) override;
203     void Write(AstWriter& writer) override;
204     void Read(AstReader& reader) override;
205     bool IsBreakEnclosingStatementNode() const override { return true; }
206     bool IsContinueEnclosingStatementNode() const override { return true; }
207     const StatementNode* InitS() const { return initS.get(); }
208     StatementNode* InitS() { return initS.get(); }
209     const Node* Condition() const { return condition.get(); }
210     Node* Condition() { return condition.get(); }
211     const StatementNode* LoopS() const { return loopS.get(); }
212     StatementNode* LoopS() { return loopS.get(); }
213     const StatementNode* ActionS() const { return actionS.get(); }
214     StatementNode* ActionS() { return actionS.get(); }
215     void SetLeftParenSpan(const Span& leftParenSpan_) { leftParenSpan = leftParenSpan_; }
216     const Span& LeftParenSpan() const { return leftParenSpan; }
217     void SetRightParenSpan(const Span& rightParenSpan_) { rightParenSpan = rightParenSpan_; }
218     const Span& RightParenSpan() const { return rightParenSpan; }
219 private:
220     std::unique_ptr<StatementNode> initS;
221     std::unique_ptr<Node> condition;
222     std::unique_ptr<StatementNode> loopS;
223     std::unique_ptr<StatementNode> actionS;
224     Span leftParenSpan;
225     Span rightParenSpan;
226 };
227 
228 class BreakStatementNode public StatementNode
229 {
230 public:
231     BreakStatementNode(const Span& span_const boost::uuids::uuid& moduleId_);
232     Node* Clone(CloneContext& cloneContext) const override;
233     void Accept(Visitor& visitor) override;
234     bool IsCaseTerminatingNode() const override { return true; }
235     bool IsDefaultTerminatingNode() const override { return true; }
236 };
237 
238 class ContinueStatementNode public StatementNode
239 {
240 public:
241     ContinueStatementNode(const Span& span_const boost::uuids::uuid& moduleId_);
242     Node* Clone(CloneContext& cloneContext) const override;
243     void Accept(Visitor& visitor) override;
244     bool IsCaseTerminatingNode() const override { return true; }
245     bool IsDefaultTerminatingNode() const override { return true; }
246 };
247 
248 class GotoStatementNode public StatementNode
249 {
250 public:
251     GotoStatementNode(const Span& span_const boost::uuids::uuid& moduleId_);
252     GotoStatementNode(const Span& span_const boost::uuids::uuid& moduleId_const std::u32string& target_);
253     Node* Clone(CloneContext& cloneContext) const override;
254     void Accept(Visitor& visitor) override;
255     void Write(AstWriter& writer) override;
256     void Read(AstReader& reader) override;
257     const std::u32string& Target() const { return target; }
258 private:
259     std::u32string target;
260 };
261 
262 class ConstructionStatementNode public StatementNode
263 {
264 public:
265     ConstructionStatementNode(const Span& span_const boost::uuids::uuid& moduleId_);
266     ConstructionStatementNode(const Span& span_const boost::uuids::uuid& moduleId_Node* typeExpr_IdentifierNode* id_);
267     Node* Clone(CloneContext& cloneContext) const override;
268     void Accept(Visitor& visitor) override;
269     void Write(AstWriter& writer) override;
270     void Read(AstReader& reader) override;
271     void AddArgument(Node* argument) override;
272     const Node* TypeExpr() const { return typeExpr.get(); }
273     Node* TypeExpr() { return typeExpr.get(); }
274     const IdentifierNode* Id() const { return id.get(); }
275     IdentifierNode* Id() { return id.get(); }
276     const NodeList<Node>& Arguments() const { return arguments; }
277     void SetAssignment() { assignment = true; }
278     bool Assignment() const { return assignment; }
279     void SetEmpty() { empty = true; }
280     bool Empty() const { return empty; }
281 private:
282     std::unique_ptr<Node> typeExpr;
283     std::unique_ptr<IdentifierNode> id;
284     NodeList<Node> arguments;
285     bool assignment;
286     bool empty;
287 };
288 
289 class DeleteStatementNode public StatementNode
290 {
291 public:
292     DeleteStatementNode(const Span& span_const boost::uuids::uuid& moduleId_);
293     DeleteStatementNode(const Span& span_const boost::uuids::uuid& moduleId_Node* expression_);
294     Node* Clone(CloneContext& cloneContext) const override;
295     void Accept(Visitor& visitor) override;
296     void Write(AstWriter& writer) override;
297     void Read(AstReader& reader) override;
298     const Node* Expression() const { return expression.get(); }
299     Node* Expression() { return expression.get(); }
300 private:
301     std::unique_ptr<Node> expression;
302 };
303 
304 class DestroyStatementNode public StatementNode
305 {
306 public:
307     DestroyStatementNode(const Span& span_const boost::uuids::uuid& moduleId_);
308     DestroyStatementNode(const Span&const boost::uuids::uuid& moduleId_span_Node* expression_);
309     Node* Clone(CloneContext& cloneContext) const override;
310     void Accept(Visitor& visitor) override;
311     void Write(AstWriter& writer) override;
312     void Read(AstReader& reader) override;
313     const Node* Expression() const { return expression.get(); }
314     Node* Expression() { return expression.get(); }
315 private:
316     std::unique_ptr<Node> expression;
317 };
318 
319 class AssignmentStatementNode public StatementNode
320 {
321 public:
322     AssignmentStatementNode(const Span& span_const boost::uuids::uuid& moduleId_);
323     AssignmentStatementNode(const Span& span_const boost::uuids::uuid& moduleId_Node* targetExpr_Node* sourceExpr_);
324     Node* Clone(CloneContext& cloneContext) const override;
325     void Accept(Visitor& visitor) override;
326     void Write(AstWriter& writer) override;
327     void Read(AstReader& reader) override;
328     const Node* TargetExpr() const { return targetExpr.get(); }
329     Node* TargetExpr() { return targetExpr.get(); }
330     const Node* SourceExpr() const { return sourceExpr.get(); }
331     Node* SourceExpr() { return sourceExpr.get(); }
332 private:
333     std::unique_ptr<Node> targetExpr;
334     std::unique_ptr<Node> sourceExpr;
335 };
336 
337 class ExpressionStatementNode public StatementNode
338 {
339 public:
340     ExpressionStatementNode(const Span& span_const boost::uuids::uuid& moduleId_);
341     ExpressionStatementNode(const Span& span_const boost::uuids::uuid& moduleId_Node* expression_);
342     Node* Clone(CloneContext& cloneContext) const override;
343     void Accept(Visitor& visitor) override;
344     void Write(AstWriter& writer) override;
345     void Read(AstReader& reader) override;
346     const Node* Expression() const { return expression.get(); }
347     Node* Expression() { return expression.get(); }
348 private:
349     std::unique_ptr<Node> expression;
350 };
351 
352 class EmptyStatementNode public StatementNode
353 {
354 public:
355     EmptyStatementNode(const Span& span_const boost::uuids::uuid& moduleId_);
356     Node* Clone(CloneContext& cloneContext) const override;
357     void Accept(Visitor& visitor) override;
358 };
359 
360 class RangeForStatementNode public StatementNode
361 {
362 public:
363     RangeForStatementNode(const Span& span_const boost::uuids::uuid& moduleId_);
364     RangeForStatementNode(const Span& span_const boost::uuids::uuid& moduleId_Node* typeExpr_IdentifierNode* id_Node* container_StatementNode* action_);
365     Node* Clone(CloneContext& cloneContext) const override;
366     void Accept(Visitor& visitor) override;
367     void Write(AstWriter& writer) override;
368     void Read(AstReader& reader) override;
369     bool IsBreakEnclosingStatementNode() const override { return true; }
370     bool IsContinueEnclosingStatementNode() const override { return true; }
371     const Node* TypeExpr() const { return typeExpr.get(); }
372     Node* TypeExpr() { return typeExpr.get(); }
373     const IdentifierNode* Id() const { return id.get(); }
374     IdentifierNode* Id() { return id.get(); }
375     const Node* Container() const { return container.get(); }
376     Node* Container() { return container.get(); }
377     const StatementNode* Action() const { return action.get(); }
378     StatementNode* Action() { return action.get(); }
379     void SetLeftParenSpan(const Span& leftParenSpan_) { leftParenSpan = leftParenSpan_; }
380     const Span& LeftParenSpan() const { return leftParenSpan; }
381     void SetRightParenSpan(const Span& rightParenSpan_) { rightParenSpan = rightParenSpan_; }
382     const Span& RightParenSpan() const { return rightParenSpan; }
383     void SetColonSpan(const Span& colonSpan_) { colonSpan = colonSpan_; }
384     const Span& ColonSpan() const { return colonSpan; }
385 private:
386     std::unique_ptr<Node> typeExpr;
387     std::unique_ptr<IdentifierNode> id;
388     std::unique_ptr<Node> container;
389     std::unique_ptr<StatementNode> action;
390     Span leftParenSpan;
391     Span rightParenSpan;
392     Span colonSpan;
393 };
394 
395 class CaseStatementNode;
396 class DefaultStatementNode;
397 
398 class SwitchStatementNode public StatementNode
399 {
400 public:
401     SwitchStatementNode(const Span& span_const boost::uuids::uuid& moduleId_);
402     SwitchStatementNode(const Span& span_const boost::uuids::uuid& moduleId_Node* condition_);
403     Node* Clone(CloneContext& cloneContext) const override;
404     void Accept(Visitor& visitor) override;
405     void Write(AstWriter& writer) override;
406     void Read(AstReader& reader) override;
407     bool IsBreakEnclosingStatementNode() const override { return true; }
408     const Node* Condition() const { return condition.get(); }
409     Node* Condition() { return condition.get(); }
410     void AddCase(CaseStatementNode* caseS);
411     const NodeList<CaseStatementNode>& Cases() const { return cases; }
412     void SetDefault(DefaultStatementNode* defaultS_);
413     const DefaultStatementNode* Default() const { return defaultS.get(); }
414     DefaultStatementNode* Default() { return defaultS.get(); }
415     void SetLeftParenSpan(const Span& leftParenSpan_) { leftParenSpan = leftParenSpan_; }
416     const Span& LeftParenSpan() const { return leftParenSpan; }
417     void SetRightParenSpan(const Span& rightParenSpan_) { rightParenSpan = rightParenSpan_; }
418     const Span& RightParenSpan() const { return rightParenSpan; }
419     void SetBeginBraceSpan(const Span& beginBraceSpan_) { beginBraceSpan = beginBraceSpan_; }
420     const Span& BeginBraceSpan() const { return beginBraceSpan; }
421     void SetEndBraceSpan(const Span& endBraceSpan_) { endBraceSpan = endBraceSpan_; }
422     const Span& EndBraceSpan() const { return endBraceSpan; }
423 private:
424     std::unique_ptr<Node> condition;
425     NodeList<CaseStatementNode> cases;
426     std::unique_ptr<DefaultStatementNode> defaultS;
427     Span leftParenSpan;
428     Span rightParenSpan;
429     Span beginBraceSpan;
430     Span endBraceSpan;
431 };
432 
433 class CaseStatementNode public StatementNode
434 {
435 public:
436     CaseStatementNode(const Span& span_const boost::uuids::uuid& moduleId_);
437     Node* Clone(CloneContext& cloneContext) const override;
438     void Accept(Visitor& visitor) override;
439     void Write(AstWriter& writer) override;
440     void Read(AstReader& reader) override;
441     void AddCaseExpr(Node* caseExpr);
442     const NodeList<Node>& CaseExprs() const { return caseExprs; }
443     void AddStatement(StatementNode* statement);
444     const NodeList<StatementNode>& Statements() const { return statements; }
445     void AddCaseSpan(const Span& caseSpan);
446     const std::std::vector<Span>&CaseSpans() const{returncaseSpans;}
447 private:
448     NodeList<Node> caseExprs;
449     NodeList<StatementNode> statements;
450     std::vector<Span> caseSpans;
451 };
452 
453 class DefaultStatementNode public StatementNode
454 {
455 public:
456     DefaultStatementNode(const Span& span_const boost::uuids::uuid& moduleId_);
457     Node* Clone(CloneContext& cloneContext) const override;
458     void Accept(Visitor& visitor) override;
459     void Write(AstWriter& writer) override;
460     void Read(AstReader& reader) override;
461     const NodeList<StatementNode>& Statements() const { return statements; }
462     void AddStatement(StatementNode* statement);
463 private:
464     NodeList<StatementNode> statements;
465 };
466 
467 class GotoCaseStatementNode public StatementNode
468 {
469 public:
470     GotoCaseStatementNode(const Span& span_const boost::uuids::uuid& moduleId_);
471     GotoCaseStatementNode(const Span& span_const boost::uuids::uuid& moduleId_Node* caseExpr_);
472     Node* Clone(CloneContext& cloneContext) const override;
473     void Accept(Visitor& visitor) override;
474     void Write(AstWriter& writer) override;
475     void Read(AstReader& reader) override;
476     bool IsCaseTerminatingNode() const override { return true; }
477     bool IsDefaultTerminatingNode() const override { return true; }
478     const Node* CaseExpr() const { return caseExpr.get(); }
479     Node* CaseExpr() { return caseExpr.get(); }
480 private:
481     std::unique_ptr<Node> caseExpr;
482 };
483 
484 class GotoDefaultStatementNode public StatementNode
485 {
486 public:
487     GotoDefaultStatementNode(const Span& span_const boost::uuids::uuid& moduleId_);
488     Node* Clone(CloneContext& cloneContext) const override;
489     void Accept(Visitor& visitor) override;
490     bool IsCaseTerminatingNode() const override { return true; }
491 };
492 
493 class ThrowStatementNode public StatementNode
494 {
495 public:
496     ThrowStatementNode(const Span& span_const boost::uuids::uuid& moduleId_);
497     ThrowStatementNode(const Span& span_const boost::uuids::uuid& moduleId_Node* expression_);
498     Node* Clone(CloneContext& cloneContext) const override;
499     void Accept(Visitor& visitor) override;
500     void Write(AstWriter& writer) override;
501     void Read(AstReader& reader) override;
502     bool IsFunctionTerminatingNode() const override { return true; }
503     bool IsCaseTerminatingNode() const override { return true; }
504     bool IsDefaultTerminatingNode() const override { return true; }
505     const Node* Expression() const { return expression.get(); }
506     Node* Expression() { return expression.get(); }
507 private:
508     std::unique_ptr<Node> expression;
509 };
510 
511 class CatchNode;
512 
513 class TryStatementNode public StatementNode
514 {
515 public:
516     TryStatementNode(const Span& span_const boost::uuids::uuid& moduleId_);
517     TryStatementNode(const Span& span_const boost::uuids::uuid& moduleId_CompoundStatementNode* tryBlock_);
518     Node* Clone(CloneContext& cloneContext) const override;
519     void Accept(Visitor& visitor) override;
520     void Write(AstWriter& writer) override;
521     void Read(AstReader& reader) override;
522     const CompoundStatementNode* TryBlock() const { return tryBlock.get(); }
523     CompoundStatementNode* TryBlock() { return tryBlock.get(); }
524     const NodeList<CatchNode>& Catches() const { return catches; }
525     void AddCatch(CatchNode* catch_);
526 private:
527     std::unique_ptr<CompoundStatementNode> tryBlock;
528     NodeList<CatchNode> catches;
529 };
530 
531 class CatchNode public Node
532 {
533 public:
534     CatchNode(const Span& span_const boost::uuids::uuid& moduleId_);
535     CatchNode(const Span& span_const boost::uuids::uuid& moduleId_Node* typeExpr_IdentifierNode* id_CompoundStatementNode* catchBlock_);
536     Node* Clone(CloneContext& cloneContext) const override;
537     void Accept(Visitor& visitor) override;
538     void Write(AstWriter& writer) override;
539     void Read(AstReader& reader) override;
540     const Node* TypeExpr() const { return typeExpr.get(); }
541     Node* TypeExpr() { return typeExpr.get(); }
542     const IdentifierNode* Id() const { return id.get(); }
543     IdentifierNode* Id() { return id.get(); }
544     const CompoundStatementNode* CatchBlock() const { return catchBlock.get(); }
545     CompoundStatementNode* CatchBlock() { return catchBlock.get(); }
546     void SetLeftParenSpan(const Span& leftParenSpan_) { leftParenSpan = leftParenSpan_; }
547     const Span& LeftParenSpan() const { return leftParenSpan; }
548     void SetRightParenSpan(const Span& rightParenSpan_) { rightParenSpan = rightParenSpan_; }
549     const Span& RightParenSpan() const { return rightParenSpan; }
550 private:
551     std::unique_ptr<Node> typeExpr;
552     std::unique_ptr<IdentifierNode> id;
553     std::unique_ptr<CompoundStatementNode> catchBlock;
554     Span leftParenSpan;
555     Span rightParenSpan;
556 };
557 
558 class AssertStatementNode public StatementNode
559 {
560 public:
561     AssertStatementNode(const Span& span_const boost::uuids::uuid& moduleId_);
562     AssertStatementNode(const Span& span_const boost::uuids::uuid& moduleId_Node* assertExpr_);
563     Node* Clone(CloneContext& cloneContext) const override;
564     void Accept(Visitor& visitor) override;
565     void Write(AstWriter& writer) override;
566     void Read(AstReader& reader) override;
567     const Node* AssertExpr() const { return assertExpr.get(); }
568     Node* AssertExpr() { return assertExpr.get(); }
569 private:
570     std::unique_ptr<Node> assertExpr;
571 };
572 
573 class ConditionalCompilationExpressionNode public Node
574 {
575 public:
576     ConditionalCompilationExpressionNode(NodeType nodeType_const Span& span_const boost::uuids::uuid& moduleId_);
577     bool IsConditionalCompilationExpressionNode() const override { return true; }
578 };
579 
580 class ConditionalCompilationBinaryExpressionNode public ConditionalCompilationExpressionNode
581 {
582 public:
583     ConditionalCompilationBinaryExpressionNode(NodeType nodeType_const Span& span_const boost::uuids::uuid& moduleId_);
584     ConditionalCompilationBinaryExpressionNode(NodeType nodeType_const Span& span_const boost::uuids::uuid& moduleId_ConditionalCompilationExpressionNode* left_ConditionalCompilationExpressionNode* right_);
585     void Write(AstWriter& writer) override;
586     void Read(AstReader& reader) override;
587     ConditionalCompilationExpressionNode* Left() const { return left.get(); }
588     ConditionalCompilationExpressionNode* Right() const { return right.get(); }
589 private:
590     std::unique_ptr<ConditionalCompilationExpressionNode> left;
591     std::unique_ptr<ConditionalCompilationExpressionNode> right;
592 };
593 
594 class ConditionalCompilationDisjunctionNode public ConditionalCompilationBinaryExpressionNode
595 {
596 public:
597     ConditionalCompilationDisjunctionNode(const Span& span_const boost::uuids::uuid& moduleId_);
598     ConditionalCompilationDisjunctionNode(const Span& span_const boost::uuids::uuid& moduleId_ConditionalCompilationExpressionNode* left_ConditionalCompilationExpressionNode* right_);
599     Node* Clone(CloneContext& cloneContext) const override;
600     void Accept(Visitor& visitor) override;
601 };
602 
603 class ConditionalCompilationConjunctionNode public ConditionalCompilationBinaryExpressionNode
604 {
605 public:
606     ConditionalCompilationConjunctionNode(const Span& span_const boost::uuids::uuid& moduleId_);
607     ConditionalCompilationConjunctionNode(const Span& span_const boost::uuids::uuid& moduleId_ConditionalCompilationExpressionNode* left_ConditionalCompilationExpressionNode* right_);
608     Node* Clone(CloneContext& cloneContext) const override;
609     void Accept(Visitor& visitor) override;
610 };
611 
612 class ConditionalCompilationNotNode public ConditionalCompilationExpressionNode
613 {
614 public:
615     ConditionalCompilationNotNode(const Span& span_const boost::uuids::uuid& moduleId_);
616     ConditionalCompilationNotNode(const Span& span_const boost::uuids::uuid& moduleId_ConditionalCompilationExpressionNode* expr_);
617     Node* Clone(CloneContext& cloneContext) const override;
618     void Accept(Visitor& visitor) override;
619     void Write(AstWriter& writer) override;
620     void Read(AstReader& reader) override;
621     ConditionalCompilationExpressionNode* Expr() const { return expr.get(); }
622 private:
623     std::unique_ptr<ConditionalCompilationExpressionNode> expr;
624 };
625 
626 class ConditionalCompilationPrimaryNode public ConditionalCompilationExpressionNode
627 {
628 public:
629     ConditionalCompilationPrimaryNode(const Span& span_const boost::uuids::uuid& moduleId_);
630     ConditionalCompilationPrimaryNode(const Span& span_const boost::uuids::uuid& moduleId_const std::u32string& symbol_);
631     Node* Clone(CloneContext& cloneContext) const override;
632     void Accept(Visitor& visitor) override;
633     void Write(AstWriter& writer) override;
634     void Read(AstReader& reader) override;
635     const std::u32string& Symbol() const { return symbol; }
636 private:
637     std::u32string symbol;
638 };
639 
640 class ParenthesizedConditionalCompilationExpressionNode public ConditionalCompilationExpressionNode
641 {
642 public:
643     ParenthesizedConditionalCompilationExpressionNode(const Span& span_const boost::uuids::uuid& moduleId_);
644     ParenthesizedConditionalCompilationExpressionNode(const Span& span_const boost::uuids::uuid& moduleId_ConditionalCompilationExpressionNode* expr_);
645     Node* Clone(CloneContext& cloneContext) const override;
646     void Accept(Visitor& visitor) override;
647     void Write(AstWriter& writer) override;
648     void Read(AstReader& reader) override;
649     ConditionalCompilationExpressionNode* Expr() const { return expr.get(); }
650 private:
651     std::unique_ptr<ConditionalCompilationExpressionNode> expr;
652 };
653 
654 class ConditionalCompilationPartNode public Node
655 {
656 public:
657     ConditionalCompilationPartNode(const Span& span_const boost::uuids::uuid& moduleId_);
658     ConditionalCompilationPartNode(const Span& span_const boost::uuids::uuid& moduleId_ConditionalCompilationExpressionNode* expr_);
659     void AddStatement(StatementNode* statement);
660     Node* Clone(CloneContext& cloneContext) const override;
661     void Accept(Visitor& visitor) override;
662     void Write(AstWriter& writer) override;
663     void Read(AstReader& reader) override;
664     ConditionalCompilationExpressionNode* Expr() const { return expr.get();  }
665     const NodeList<StatementNode>& Statements() const { return statements; }
666     void SetKeywordSpan(const Span& keywordSpan_) { keywordSpan = keywordSpan_; }
667     const Span& KeywordSpan() const { return keywordSpan; }
668     void SetLeftParenSpan(const Span& leftParenSpan_) { leftParenSpan = leftParenSpan_; }
669     const Span& LeftParenSpan() const { return leftParenSpan; }
670     void SetRightParenSpan(const Span& rightParenSpan_) { rightParenSpan = rightParenSpan_; }
671     const Span& RightParenSpan() const { return rightParenSpan; }
672 private:
673     std::unique_ptr<ConditionalCompilationExpressionNode> expr;
674     NodeList<StatementNode> statements;
675     Span keywordSpan;
676     Span leftParenSpan;
677     Span rightParenSpan;
678 };
679 
680 class ConditionalCompilationStatementNode public StatementNode
681 {
682 public:
683     ConditionalCompilationStatementNode(const Span& span_const boost::uuids::uuid& moduleId_);
684     ConditionalCompilationStatementNode(const Span& span_const boost::uuids::uuid& moduleId_ConditionalCompilationExpressionNode* ifExpr_);
685     Node* Clone(CloneContext& cloneContext) const override;
686     void Accept(Visitor& visitor) override;
687     void Write(AstWriter& writer) override;
688     void Read(AstReader& reader) override;
689     void AddIfStatement(StatementNode* statement);
690     void AddElifExpr(const Span& spanconst boost::uuids::uuid& moduleId_ConditionalCompilationExpressionNode* expr);
691     void AddElifStatement(StatementNode* statement);
692     void AddElseStatement(const Span& spanconst boost::uuids::uuid& moduleId_StatementNode* statement);
693     ConditionalCompilationPartNode* IfPart() { return ifPart.get(); }
694     const NodeList<ConditionalCompilationPartNode>& ElifParts() const { return elifParts; }
695     ConditionalCompilationPartNode* ElsePart() { return elsePart.get(); }
696     void SetElifLeftParenSpan(const Span& span);
697     void SetElifRightParenSpan(const Span& span);
698     void SetElifKeywordSpan(const Span& span);
699     void SetEndIfSpan(const Span& endifSpan_) { endifSpan = endifSpan_; }
700     const Span& EndIfSpan() const { return endifSpan; }
701     void SetIfPart(ConditionalCompilationPartNode* ifPart_);
702     void AddElifPart(ConditionalCompilationPartNode* elifPart);
703     void SetElsePart(ConditionalCompilationPartNode* elsePart_);
704 private:
705     std::unique_ptr<ConditionalCompilationPartNode> ifPart;
706     NodeList<ConditionalCompilationPartNode> elifParts;
707     std::unique_ptr<ConditionalCompilationPartNode> elsePart;
708     Span endifSpan;
709 };
710 
711 } } // namespace sngcm::ast
712 
713 #endif // SNGCM_AST_STATEMENT_INCLUDED