GCC Code Coverage Report


Directory: ./
File: openvdb_ax/openvdb_ax/ast/PrintTree.cc
Date: 2022-07-25 17:40:05
Exec Total Coverage
Lines: 152 434 35.0%
Functions: 23 76 30.3%
Branches: 66 224 29.5%

Line Branch Exec Source
1 // Copyright Contributors to the OpenVDB Project
2 // SPDX-License-Identifier: MPL-2.0
3
4 /// @file ast/PrintTree.cc
5
6 #include "AST.h"
7 #include "PrintTree.h"
8 #include "Tokens.h"
9 #include "Visitor.h"
10
11 #include <ostream>
12
13 namespace openvdb {
14 OPENVDB_USE_VERSION_NAMESPACE
15 namespace OPENVDB_VERSION_NAME {
16
17 namespace ax {
18 namespace ast {
19
20 struct PrintVisitor : public ast::Visitor<PrintVisitor>
21 {
22 PrintVisitor(std::ostream& os,
23 const bool numberStatements = true,
24 const char* indent = " ")
25 : mOs(os)
26 , mLevel(0)
27 , mStatementNumber(numberStatements ? 0 : -1)
28 , mIndent(indent) {}
29 ~PrintVisitor() = default;
30
31 using ast::Visitor<PrintVisitor>::traverse;
32 using ast::Visitor<PrintVisitor>::visit;
33
34 inline bool postOrderNodes() const { return false; }
35
36 inline void indent() {
37 for (int i(0); i < mLevel; ++i) mOs << mIndent;
38 }
39
40 bool traverse(NodeType<ast::StatementList>* stmntl) {
41 this->visit(stmntl);
42
43 const size_t children = stmntl->children();
44 ++mLevel;
45 if (children == 0) {
46 indent();
47 mOs << "<empty>\n";
48 }
49 else {
50 for (size_t i = 0; i < children; ++i) {
51 indent();
52 if (mStatementNumber >= 0) {
53 mOs << '[' << mStatementNumber++ << "] ";
54 }
55 this->derived().traverse(stmntl->child(i));
56 mOs << '\n';
57 }
58 }
59 --mLevel;
60 return true;
61 }
62
63 bool traverse(NodeType<ast::Block>* block) {
64 indent();
65 this->visit(block);
66
67 const size_t children = block->children();
68 ++mLevel;
69 if (children == 0) {
70 indent();
71 mOs << "<empty>\n";
72 }
73 else {
74 for (size_t i = 0; i < children; ++i) {
75 indent();
76 if (mStatementNumber >= 0) {
77 mOs << '[' << mStatementNumber++ << "] ";
78 }
79 this->derived().traverse(block->child(i));
80 mOs << '\n';
81 }
82 }
83 --mLevel;
84 return true;
85 }
86
87 bool traverse(NodeType<ast::CommaOperator>* comma) {
88 this->visit(comma);
89 const size_t children = comma->children();
90 ++mLevel;
91 if (children == 0) {
92 indent();
93 mOs << "<empty>\n";
94 }
95 else {
96 for (size_t i = 0; i < children; ++i) {
97 indent();
98 this->derived().traverse(comma->child(i));
99 }
100 }
101 --mLevel;
102 return true;
103 }
104
105 bool traverse(NodeType<ast::ConditionalStatement>* cond) {
106 this->visit(cond);
107 ++mLevel;
108
109 indent();
110 mOs << "condition:\n";
111
112 ++mLevel;
113 indent();
114 this->traverse(cond->condition());
115 --mLevel;
116
117 indent();
118 mOs << "branch [true]:\n";
119
120 this->traverse(cond->trueBranch());
121
122 if (cond->hasFalse()) {
123 indent();
124 mOs << "branch [false]:\n";
125
126 this->traverse(cond->falseBranch());
127 }
128 --mLevel;
129 return true;
130 }
131
132 bool traverse(NodeType<ast::TernaryOperator>* tern) {
133 this->visit(tern);
134 ++mLevel;
135
136 indent();
137 mOs << "condition:\n";
138
139 ++mLevel;
140 indent();
141 this->traverse(tern->condition());
142 --mLevel;
143
144 indent();
145 mOs << "true:\n";
146 if (tern->hasTrue()) {
147 ++mLevel;
148 indent();
149 this->traverse(tern->trueBranch());
150 --mLevel;
151 }
152
153 indent();
154 mOs << "false:\n";
155 ++mLevel;
156 indent();
157 this->traverse(tern->falseBranch());
158 --mLevel;
159
160 --mLevel;
161 return true;
162 }
163
164
165 bool traverse(NodeType<ast::Loop>* loop) {
166 this->visit(loop);
167 ++mLevel;
168
169 if (loop->hasInit()) {
170 indent();
171 mOs << "init:\n";
172
173 ++mLevel;
174 indent();
175 this->traverse(loop->initial());
176 --mLevel;
177 }
178
179 indent();
180 mOs << "conditional:\n";
181
182 ++mLevel;
183 indent();
184 this->traverse(loop->condition());
185 --mLevel;
186
187 if (loop->hasIter()) {
188 indent();
189 mOs << "iterator:\n";
190 ++mLevel;
191 indent();
192 this->traverse(loop->iteration());
193 --mLevel;
194 }
195
196 indent();
197 mOs << "body:\n";
198 this->traverse(loop->body());
199
200 --mLevel;
201 return true;
202 }
203
204 bool traverse(NodeType<ast::AssignExpression>* asgn) {
205 this->visit(asgn);
206 ++mLevel;
207 indent();
208 this->traverse(asgn->lhs());
209 indent();
210 this->traverse(asgn->rhs());
211 --mLevel;
212 return true;
213 }
214
215 bool traverse(NodeType<ast::DeclareLocal>* asgn) {
216 this->visit(asgn);
217 ++mLevel;
218 indent();
219 this->traverse(asgn->local());
220 if(asgn->hasInit()) {
221 indent();
222 mOs << "init:\n";
223 ++mLevel;
224 indent();
225 this->traverse(asgn->init());
226 --mLevel;
227 }
228 --mLevel;
229 return true;
230 }
231
232 bool traverse(NodeType<ast::Crement>* crmt) {
233 this->visit(crmt);
234 ++mLevel;
235 indent();
236 this->traverse(crmt->expression());
237 --mLevel;
238 return true;
239 }
240
241 bool traverse(NodeType<ast::UnaryOperator>* unry) {
242 this->visit(unry);
243 ++mLevel;
244 indent();
245 this->traverse(unry->expression());
246 --mLevel;
247 return true;
248 }
249
250 bool traverse(NodeType<ast::BinaryOperator>* bin) {
251 this->visit(bin);
252 ++mLevel;
253 indent();
254 this->traverse(bin->lhs());
255 indent();
256 this->traverse(bin->rhs());
257 --mLevel;
258 return true;
259 }
260
261 bool traverse(NodeType<ast::Cast>* cast) {
262 this->visit(cast);
263 ++mLevel;
264 indent();
265 this->traverse(cast->expression());
266 --mLevel;
267 return true;
268 }
269
270 bool traverse(NodeType<ast::FunctionCall>* call) {
271 this->visit(call);
272 const size_t children = call->children();
273 ++mLevel;
274 if (children == 0) {
275 indent();
276 mOs << "<empty>\n";
277 }
278 else {
279 for (size_t i = 0; i < children; ++i) {
280 indent();
281 this->derived().traverse(call->child(i));
282 }
283 }
284 --mLevel;
285 return true;
286 }
287
288 bool traverse(NodeType<ast::ArrayPack>* pack) {
289 this->visit(pack);
290 const size_t children = pack->children();
291 ++mLevel;
292 if (children == 0) {
293 indent();
294 mOs << "<empty>\n";
295 }
296 else {
297 for (size_t i = 0; i < children; ++i) {
298 indent();
299 this->derived().traverse(pack->child(i));
300 }
301 }
302 --mLevel;
303 return true;
304 }
305
306 bool traverse(NodeType<ast::ArrayUnpack>* pack) {
307 this->visit(pack);
308 ++mLevel;
309 indent();
310 mOs << "expression: ";
311 this->traverse(pack->expression());
312 indent();
313 mOs << "component(s) : ";
314 this->traverse(pack->component0());
315 this->traverse(pack->component1());
316 --mLevel;
317 return true;
318 }
319
320 bool visit(const ast::StatementList* node);
321 bool visit(const ast::Block* node);
322 bool visit(const ast::ConditionalStatement* node);
323 bool visit(const ast::Loop* node);
324 bool visit(const ast::Keyword* node);
325 bool visit(const ast::AssignExpression* node);
326 bool visit(const ast::Crement* node);
327 bool visit(const ast::CommaOperator* node);
328 bool visit(const ast::UnaryOperator* node);
329 bool visit(const ast::BinaryOperator* node);
330 bool visit(const ast::TernaryOperator* node);
331 bool visit(const ast::Cast* node);
332 bool visit(const ast::FunctionCall* node);
333 bool visit(const ast::Attribute* node);
334 bool visit(const ast::ExternalVariable* node);
335 bool visit(const ast::DeclareLocal* node);
336 bool visit(const ast::Local* node);
337 bool visit(const ast::ArrayUnpack* node);
338 bool visit(const ast::ArrayPack* node);
339
340 bool visit(const ast::Value<bool>* node) {
341 return this->visitValue(node);
342 }
343 bool visit(const ast::Value<int16_t>* node) {
344 return this->visitValue(node);
345 }
346 bool visit(const ast::Value<int32_t>* node) {
347 return this->visitValue(node);
348 }
349 bool visit(const ast::Value<int64_t>* node) {
350 return this->visitValue(node);
351 }
352 bool visit(const ast::Value<float>* node) {
353 return this->visitValue(node);
354 }
355 bool visit(const ast::Value<double>* node) {
356 return this->visitValue(node);
357 }
358 bool visit(const ast::Value<std::string>* node) {
359 return this->visitValue(node);
360 }
361
362 protected:
363 template <typename T>
364 bool visitValue(const ast::Value<T>* node);
365
366 private:
367 std::ostream& mOs;
368 int mLevel;
369 int64_t mStatementNumber;
370 const char* mIndent;
371 };
372
373 bool PrintVisitor::visit(const ast::StatementList* node)
374 {
375 mOs << node->nodename() << ": " << node->size() << " statement(s)" << '\n';
376 return true;
377 }
378
379
380 bool PrintVisitor::visit(const ast::Block* node)
381 {
382 mOs << node->nodename() << ": " << node->size() << " statement(s)" << '\n';
383 return true;
384 }
385
386 bool PrintVisitor::visit(const ast::ConditionalStatement* node)
387 {
388 mOs << node->nodename() << ": " << (node->hasFalse() ? "two branches " : "one branch") << '\n';
389 return true;
390 }
391
392 bool PrintVisitor::visit(const ast::AssignExpression* node)
393 {
394 mOs << node->nodename() << ": " << tokens::operatorNameFromToken(node->operation());
395 if (node->isCompound()) mOs << '=';
396 mOs << '\n';
397 return true;
398 }
399
400 bool PrintVisitor::visit(const ast::Loop* node)
401 {
402 mOs << tokens::loopNameFromToken(node->loopType()) <<" "<< node->nodename() << ":" << '\n';
403 return true;
404 }
405
406 bool PrintVisitor::visit(const ast::Keyword* node)
407 {
408 mOs << node->nodename() << ": " << tokens::keywordNameFromToken(node->keyword()) << '\n';
409 return true;
410 }
411
412 bool PrintVisitor::visit(const ast::Crement* node)
413 {
414 mOs << node->nodename() << ':';
415 if (node->post()) mOs << " post-";
416 else mOs << " pre-";
417 if (node->increment()) mOs << "increment";
418 else mOs << "decrement";
419 mOs << '\n';
420 return true;
421 }
422
423 bool PrintVisitor::visit(const ast::CommaOperator* node)
424 {
425 mOs << node->nodename() << ": " << node->size() << " element(s)" << '\n';
426 return true;
427 }
428
429 bool PrintVisitor::visit(const ast::UnaryOperator* node)
430 {
431 mOs << node->nodename() << ": " << tokens::operatorNameFromToken(node->operation()) << '\n';
432 return true;
433 }
434
435 bool PrintVisitor::visit(const ast::BinaryOperator* node)
436 {
437 mOs << node->nodename() << ": " << tokens::operatorNameFromToken(node->operation()) << '\n';
438 return true;
439 }
440
441 bool PrintVisitor::visit(const ast::TernaryOperator* node)
442 {
443 mOs << node->nodename() << ":\n";
444 return true;
445 }
446
447 bool PrintVisitor::visit(const ast::Cast* node)
448 {
449 mOs << node->nodename() << ": " << tokens::typeStringFromToken(node->type()) << '\n';
450 return true;
451 }
452
453 bool PrintVisitor::visit(const ast::FunctionCall* node)
454 {
455 mOs << node->nodename() << ": " << node->name() << '\n';
456 return true;
457 }
458
459 bool PrintVisitor::visit(const ast::Attribute* node)
460 {
461 mOs << node->nodename() << ": " << node->symbolseparator()
462 << '(' << node->typestr() << (node->inferred() ? " - inferred": "")
463 << ") " << node->name() << '\n';
464 return true;
465 }
466
467 bool PrintVisitor::visit(const ast::DeclareLocal* node)
468 {
469 mOs << node->nodename() << ": "<< node->typestr() << '\n';
470 return true;
471 }
472
473 bool PrintVisitor::visit(const ast::Local* node)
474 {
475 mOs << node->nodename() << ' ' << node->name() << '\n';
476 return true;
477 }
478
479 bool PrintVisitor::visit(const ast::ArrayUnpack* node)
480 {
481 mOs << node->nodename() << '\n';
482 return true;
483 }
484
485 bool PrintVisitor::visit(const ast::ArrayPack* node)
486 {
487 mOs << node->nodename() << ": " << node->children() << " element(s)" << '\n';
488 return true;
489 }
490
491 bool PrintVisitor::visit(const ast::ExternalVariable* node)
492 {
493 mOs << node->nodename() << ": " << node->symbolseparator()
494 << '(' << node->typestr() << ") " << node->name() << '\n';
495 return true;
496 }
497
498 template <typename T>
499 bool PrintVisitor::visitValue(const ast::Value<T>* node)
500 {
501 mOs << node->nodename() << ": " << node->value() << '\n';
502 return true;
503 }
504
505
506 ////////////////////////////////////////////////////////////////////////////////
507
508
509 void print(const ast::Node& node,
510 const bool numberStatements,
511 std::ostream& os,
512 const char* indent)
513 {
514 PrintVisitor visitor(os, numberStatements, indent);
515 visitor.traverse(&node);
516 }
517
518
519 ////////////////////////////////////////////////////////////////////////////////
520 ////////////////////////////////////////////////////////////////////////////////
521
522 struct ReprintVisitor : public ast::Visitor<ReprintVisitor>
523 {
524 ReprintVisitor(std::ostream& os, const char* indent = " ")
525 15 : mOs(os)
526 , mLevel(0)
527 15 , mIndent(indent) {}
528 ~ReprintVisitor() = default;
529
530 using ast::Visitor<ReprintVisitor>::traverse;
531 using ast::Visitor<ReprintVisitor>::visit;
532
533 inline bool postOrderNodes() const { return false; }
534
535 inline void indent() {
536
10/10
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 2 times.
✓ Branch 3 taken 5 times.
✓ Branch 4 taken 3 times.
✓ Branch 6 taken 23 times.
✓ Branch 7 taken 28 times.
✓ Branch 9 taken 96 times.
✓ Branch 10 taken 73 times.
✓ Branch 12 taken 23 times.
✓ Branch 13 taken 28 times.
287 for (int i = 0; i < mLevel; ++i) mOs << mIndent;
537 }
538
539 28 bool traverse(NodeType<ast::Block>* block) {
540 const size_t children = block->children();
541 indent();
542 28 mOs << '{' << '\n';
543 28 ++mLevel;
544
2/2
✓ Branch 0 taken 73 times.
✓ Branch 1 taken 28 times.
101 for (size_t i = 0; i < children; ++i) {
545 indent();
546 73 this->derived().traverse(block->child(i));
547 73 const auto type = block->child(i)->nodetype();
548 73 if (type != ast::Node::ConditionalStatementNode &&
549
2/2
✓ Branch 0 taken 63 times.
✓ Branch 1 taken 10 times.
73 type != ast::Node::LoopNode) {
550 63 mOs << ';' << '\n';
551 }
552 }
553 28 --mLevel;
554 indent();
555 28 mOs << '}' << '\n';
556 28 return true;
557 }
558
559
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 bool traverse(NodeType<ast::StatementList>* stmtl) {
560 const size_t children = stmtl->children();
561
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 if (children == 0) return true;
562
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if (children == 1) {
563 this->derived().traverse(stmtl->child(0));
564 mOs << ';';
565 return true;
566 }
567
568 // multiple statments
569
570
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
5 if (stmtl->child(0)->nodetype() == ast::Node::DeclareLocalNode) {
571 // it's a declaration list, manually handle the child nodes.
572 // This is to handle declarations within loop inits such as
573 // "for (int a = 0, b = 1;;)". Without this, it would be
574 // reprinted as "for (int a=0; int b=1; ;;)"
575
576 // visit the first child completely
577 5 this->derived().traverse(stmtl->child(0));
578
579
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 5 times.
10 for (size_t i = 1; i < children; ++i) {
580 // all child statements should be declare locals
581
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
5 assert(stmtl->child(i)->nodetype() ==
582 ast::Node::DeclareLocalNode);
583
584 5 mOs << ", ";
585 5 this->derived().traverse(stmtl->child(i)->child(0)); // local
586 5 auto* init = stmtl->child(i)->child(1); // init
587
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
5 if (init) {
588 1 mOs << " = ";
589 1 this->derived().traverse(init);
590 }
591 }
592 return true;
593 }
594
595 // otherwise traverse as normal
596
597 for (size_t i = 0; i < children; ++i) {
598 this->derived().traverse(stmtl->child(i));
599 if (i != children-1) mOs << ';' << ' ';
600 }
601 return true;
602 }
603
604 9 bool traverse(NodeType<ast::CommaOperator>* exprl) {
605 9 mOs << '(';
606 const size_t children = exprl->children();
607
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 9 times.
30 for (size_t i = 0; i < children; ++i) {
608 21 this->derived().traverse(exprl->child(i));
609
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 9 times.
21 if (i != children-1) mOs << ',' << ' ';
610 }
611 9 mOs << ')';
612 9 return true;
613 }
614
615 4 bool traverse(NodeType<ast::ConditionalStatement>* cond) {
616 4 mOs << "if (";
617 4 this->traverse(cond->condition());
618 4 mOs << ")\n";
619 4 this->traverse(cond->trueBranch());
620
621
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 times.
4 if (cond->hasFalse()) {
622 indent();
623 3 mOs << "else\n";
624 3 this->traverse(cond->falseBranch());
625 }
626 4 return true;
627 }
628
629
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 4 times.
6 bool traverse(NodeType<ast::Loop>* loop) {
630 const ast::tokens::LoopToken loopType = loop->loopType();
631
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 4 times.
6 if (loopType == ast::tokens::LoopToken::FOR) {
632 2 mOs << "for (";
633
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (loop->hasInit()) this->traverse(loop->initial());
634 2 mOs << "; ";
635 2 this->traverse(loop->condition());
636 2 mOs << "; ";
637
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (loop->hasIter()) this->traverse(loop->iteration());
638 2 mOs << ")\n";
639 2 this->traverse(loop->body());
640 }
641
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4 else if (loopType == ast::tokens::LoopToken::DO) {
642 2 mOs << "do\n";
643 2 this->traverse(loop->body());
644 indent();
645 2 mOs << "while (";
646 2 this->traverse(loop->condition());
647 2 mOs << ")\n";
648 }
649 else {
650 2 mOs << "while (";
651 2 this->traverse(loop->condition());
652 2 mOs << ")\n";
653 2 this->traverse(loop->body());
654 }
655 6 return true;
656 }
657
658 16 bool traverse(NodeType<ast::AssignExpression>* asgn) {
659 16 this->traverse(asgn->lhs());
660 16 this->visit(asgn);
661 16 this->traverse(asgn->rhs());
662 16 return true;
663 }
664
665 8 bool traverse(NodeType<ast::DeclareLocal>* decl) {
666 8 this->visit(decl);
667 8 this->visit(decl->local());
668
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 7 times.
8 if (decl->hasInit()) {
669 1 mOs <<" = ";
670 1 this->traverse(decl->init());
671 }
672 8 return true;
673 }
674
675
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
6 bool traverse(NodeType<ast::Crement>* crmt) {
676
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
6 if (crmt->pre()) this->visit(crmt);
677 6 this->traverse(crmt->expression());
678
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 4 times.
6 if (crmt->post()) this->visit(crmt);
679 6 return true;
680 }
681
682 bool traverse(NodeType<ast::UnaryOperator>* unry) {
683 this->visit(unry);
684 this->traverse(unry->expression());
685 return true;
686 }
687
688 28 bool traverse(NodeType<ast::BinaryOperator>* bin) {
689 // The AST currently doesn't store what expressions were encapsulated
690 // by parenthesis and instead infers precedences from the token order
691 // set out in the parser. This means that traversal determines precedence.
692 // Unfortunately, statements like "a+b+c" and "a+(b+c)" both get re-printed
693 // as "a+b+c". For now, every binary expression is encapsulated to
694 // ensure the operation order is preserved, resulting in (a+(b+c)) for
695 // the above example.
696 28 mOs << '(';
697 28 this->traverse(bin->lhs());
698 28 this->visit(bin);
699 28 this->traverse(bin->rhs());
700 28 mOs << ')';
701 28 return true;
702 }
703
704 4 bool traverse(NodeType<ast::TernaryOperator>* tern) {
705 4 this->traverse(tern->condition());
706 4 mOs << " ?";
707
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 times.
4 if (tern->hasTrue()) {
708 3 mOs << ' ';
709 3 this->traverse(tern->trueBranch());
710 3 mOs << ' ';
711 }
712 4 mOs << ": ";
713 4 this->traverse(tern->falseBranch());
714 4 return true;
715 }
716
717 bool traverse(NodeType<ast::Cast>* cast) {
718 this->visit(cast);
719 mOs << '(';
720 this->traverse(cast->expression());
721 mOs << ')';
722 return true;
723 }
724
725 bool traverse(NodeType<ast::FunctionCall>* call) {
726 this->visit(call);
727 mOs << '(';
728 const size_t children = call->children();
729 for (size_t i = 0; i < children; ++i) {
730 this->derived().traverse(call->child(i));
731 if (i != children-1) mOs << ',' << ' ';
732 }
733 mOs << ')';
734 return true;
735 }
736
737 3 bool traverse(NodeType<ast::ArrayPack>* pack) {
738 3 mOs << '{';
739 const size_t children = pack->children();
740
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 3 times.
11 for (size_t i = 0; i < children; ++i) {
741 8 this->derived().traverse(pack->child(i));
742
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 3 times.
8 if (i != children-1) mOs << ',' << ' ';
743 }
744 3 mOs << '}';
745 3 return true;
746 }
747
748 9 bool traverse(NodeType<ast::ArrayUnpack>* pack) {
749 9 this->traverse(pack->expression());
750 9 mOs << '[';
751 9 this->traverse(pack->component0());
752
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 7 times.
9 if (pack->component1()) {
753 2 mOs << ',' << ' ';
754 2 this->traverse(pack->component1());
755 }
756 9 mOs << ']';
757 9 return true;
758 }
759
760 bool visit(const ast::AssignExpression* node);
761 bool visit(const ast::Crement* node);
762 bool visit(const ast::UnaryOperator* node);
763 bool visit(const ast::BinaryOperator* node);
764 bool visit(const ast::Cast* node);
765 bool visit(const ast::FunctionCall* node);
766 bool visit(const ast::Attribute* node);
767 bool visit(const ast::ExternalVariable* node);
768 bool visit(const ast::DeclareLocal* node);
769 bool visit(const ast::Local* node);
770 bool visit(const ast::Keyword* node);
771
772 bool visit(const ast::Value<bool>* node) {
773 4 return this->visitValue(node);
774 }
775 bool visit(const ast::Value<int16_t>* node) {
776 return this->visitValue(node);
777 }
778 bool visit(const ast::Value<int32_t>* node) {
779 22 return this->visitValue(node);
780 }
781 bool visit(const ast::Value<int64_t>* node) {
782 return this->visitValue(node);
783 }
784 bool visit(const ast::Value<float>* node) {
785 return this->visitValue(node);
786 }
787 bool visit(const ast::Value<double>* node) {
788 return this->visitValue(node);
789 }
790 bool visit(const ast::Value<std::string>* node) {
791 return this->visitValue(node);
792 }
793
794 protected:
795 template <typename T>
796 bool visitValue(const ast::Value<T>* node);
797 private:
798 std::ostream& mOs;
799 int mLevel;
800 const char* mIndent;
801 };
802
803
804 16 bool ReprintVisitor::visit(const ast::AssignExpression* node)
805 {
806
2/2
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 6 times.
32 mOs << ' ' << tokens::operatorNameFromToken(node->operation());
807
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 6 times.
16 if (node->isCompound()) mOs << '=';
808 16 mOs << ' ';
809 16 return true;
810 }
811
812
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 bool ReprintVisitor::visit(const ast::Crement* node)
813 {
814
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 if (node->increment()) mOs << "++";
815
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 if (node->decrement()) mOs << "--";
816 6 return true;
817 }
818
819 bool ReprintVisitor::visit(const ast::UnaryOperator* node)
820 {
821 mOs << tokens::operatorNameFromToken(node->operation());
822 return true;
823 }
824
825 28 bool ReprintVisitor::visit(const ast::BinaryOperator* node)
826 {
827 56 mOs << ' ' << tokens::operatorNameFromToken(node->operation()) << ' ';
828 28 return true;
829 }
830
831 bool ReprintVisitor::visit(const ast::Cast* node)
832 {
833 mOs << node->typestr();
834 return true;
835 }
836
837 bool ReprintVisitor::visit(const ast::FunctionCall* node)
838 {
839 mOs << node->name();
840 return true;
841 }
842
843 5 bool ReprintVisitor::visit(const ast::Attribute* node)
844 {
845
1/2
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
10 mOs << node->typestr() << node->symbolseparator() << node->name();
846 5 return true;
847 }
848
849 8 bool ReprintVisitor::visit(const ast::DeclareLocal* node)
850 {
851
1/2
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
16 mOs << node->typestr() << " ";
852 8 return true;
853 }
854
855 122 bool ReprintVisitor::visit(const ast::Local* node)
856 {
857 122 mOs << node->name();
858 122 return true;
859 }
860
861 3 bool ReprintVisitor::visit(const ast::Keyword* node)
862 {
863 3 mOs << tokens::keywordNameFromToken(node->keyword());
864 3 return true;
865 }
866
867 5 bool ReprintVisitor::visit(const ast::ExternalVariable* node)
868 {
869
1/2
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
10 mOs << node->typestr() << node->symbolseparator() << node->name();
870 5 return true;
871 }
872
873 template <typename T>
874 52 bool ReprintVisitor::visitValue(const ast::Value<T>* node)
875 {
876 8 if (std::is_same<T, bool>::value) mOs << std::boolalpha;
877 if (std::is_same<T, std::string>::value) mOs << '"';
878 52 mOs << node->value();
879 8 if (std::is_same<T, bool>::value) mOs << std::noboolalpha;
880 if (std::is_same<T, std::string>::value) mOs << '"';
881 if (std::is_same<T, int16_t>::value) mOs << 's';
882 if (std::is_same<T, int64_t>::value) mOs << 'l';
883 if (std::is_same<T, float>::value) mOs << 'f';
884 52 return true;
885 }
886
887 ////////////////////////////////////////////////////////////////////////////////
888
889
890 15 void reprint(const ast::Node& node, std::ostream& os, const char* indent)
891 {
892 ReprintVisitor visitor(os, indent);
893 15 visitor.traverse(&node);
894 15 }
895
896
897 } // namespace ast
898 } // namespace ax
899
900 } // namespace OPENVDB_VERSION_NAME
901 } // namespace openvdb
902
903
904