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