BashSpark
Loading...
Searching...
No Matches
shell_node_visitor.h
Go to the documentation of this file.
1
30#pragma once
31
33
34namespace bs {
45 template<typename visit_t>
47 static_assert(std::is_default_constructible_v<visit_t>,
48 "visit_t must be default-constructible");
49
50 public:
52 using visit_type = visit_t;
53
54 virtual ~shell_node_visitor() = default;
55
68 virtual visit_t visit_node(shell_session &oSession,
69 const shell_node *pRawNode);
70
71 protected:
75
82 virtual visit_t visit(shell_session &oSession, const shell_node_word *pNode) = 0;
83
90 virtual visit_t visit(shell_session &oSession, const shell_node_unicode *pNode) = 0;
91
98 virtual visit_t visit(shell_session &oSession, const shell_node_str_simple *pNode) = 0;
99
106 virtual visit_t visit(shell_session &oSession, const shell_node_str_double *pNode) = 0;
107
114 virtual visit_t visit(shell_session &oSession, const shell_node_str_back *pNode) = 0;
115
122 virtual visit_t visit(shell_session &oSession, const shell_node_null_command *pNode) = 0;
123
130 virtual visit_t visit(shell_session &oSession, const shell_node_command *pNode) = 0;
131
138 virtual visit_t visit(shell_session &oSession, const shell_node_command_expression *pNode) = 0;
139
146 virtual visit_t visit(shell_session &oSession, const shell_node_command_block *pNode) = 0;
147
154 virtual visit_t visit(shell_session &oSession, const shell_node_command_block_subshell *pNode) = 0;
155
162 virtual visit_t visit(shell_session &oSession, const shell_node_arg *pNode) = 0;
163
170 virtual visit_t visit(shell_session &oSession, const shell_node_variable *pNode) = 0;
171
178 virtual visit_t visit(shell_session &oSession, const shell_node_dollar_arg *pNode) = 0;
179
186 virtual visit_t visit(shell_session &oSession, const shell_node_dollar_variable *pNode) = 0;
187
194 virtual visit_t visit(shell_session &oSession, const shell_node_dollar_arg_dhop *pNode) = 0;
195
202 virtual visit_t visit(shell_session &oSession, const shell_node_dollar_variable_dhop *pNode) = 0;
203
210 virtual visit_t visit(shell_session &oSession, const shell_node_dollar_command *pNode) = 0;
211
218 virtual visit_t visit(shell_session &oSession, const shell_node_dollar_special *pNode) = 0;
219
226 virtual visit_t visit(shell_session &oSession, const shell_node_background *pNode) = 0;
227
234 virtual visit_t visit(shell_session &oSession, const shell_node_pipe *pNode) = 0;
235
242 virtual visit_t visit(shell_session &oSession, const shell_node_or *pNode) = 0;
243
250 virtual visit_t visit(shell_session &oSession, const shell_node_and *pNode) = 0;
251
258 virtual visit_t visit(shell_session &oSession, const shell_node_test *pNode) = 0;
259
266 virtual visit_t visit(shell_session &oSession, const shell_node_if *pNode) = 0;
267
274 virtual visit_t visit(shell_session &oSession, const shell_node_break *pNode) = 0;
275
282 virtual visit_t visit(shell_session &oSession, const shell_node_continue *pNode) = 0;
283
290 virtual visit_t visit(shell_session &oSession, const shell_node_for *pNode) = 0;
291
298 virtual visit_t visit(shell_session &oSession, const shell_node_while *pNode) = 0;
299
306 virtual visit_t visit(shell_session &oSession, const shell_node_until *pNode) = 0;
307
314 virtual visit_t visit(shell_session &oSession, const shell_node_function *pNode) = 0;
315
317 };
318
319 template<typename visit_t>
321 shell_session &oSession, const shell_node *pRawNode) {
322 switch (pRawNode->get_type()) {
323 case shell_node_type::SNT_COMMAND_EXPRESSION: {
324 if (
325 const auto pNode = dynamic_cast<const shell_node_command_expression *>(pRawNode);
326 pNode != nullptr
327 ) {
328 if constexpr (std::is_same_v<visit_t, void>) {
329 this->visit(oSession, pNode);
330 return;
331 } else {
332 return this->visit(oSession, pNode);
333 }
334 }
335 break;
336 }
337 case shell_node_type::SNT_STR_SIMPLE: {
338 if (
339 const auto pNode = dynamic_cast<const shell_node_str_simple *>(pRawNode);
340 pNode != nullptr
341 ) {
342 if constexpr (std::is_same_v<visit_t, void>) {
343 this->visit(oSession, pNode);
344 return;
345 } else {
346 return this->visit(oSession, pNode);
347 }
348 }
349 break;
350 }
351 case shell_node_type::SNT_STR_DOUBLE: {
352 if (
353 const auto pNode = dynamic_cast<const shell_node_str_double *>(pRawNode);
354 pNode != nullptr
355 ) {
356 if constexpr (std::is_same_v<visit_t, void>) {
357 this->visit(oSession, pNode);
358 return;
359 } else {
360 return this->visit(oSession, pNode);
361 }
362 }
363 break;
364 }
365 case shell_node_type::SNT_STR_BACK: {
366 if (
367 const auto pNode = dynamic_cast<const shell_node_str_back *>(pRawNode);
368 pNode != nullptr
369 ) {
370 if constexpr (std::is_same_v<visit_t, void>) {
371 this->visit(oSession, pNode);
372 return;
373 } else {
374 return this->visit(oSession, pNode);
375 }
376 }
377 break;
378 }
379 case shell_node_type::SNT_WORD: {
380 if (
381 const auto pNode = dynamic_cast<const shell_node_word *>(pRawNode);
382 pNode != nullptr
383 ) {
384 if constexpr (std::is_same_v<visit_t, void>) {
385 this->visit(oSession, pNode);
386 return;
387 } else {
388 return this->visit(oSession, pNode);
389 }
390 }
391 break;
392 }
393 case shell_node_type::SNT_UNICODE: {
394 if (
395 const auto pNode = dynamic_cast<const shell_node_unicode *>(pRawNode);
396 pNode != nullptr
397 ) {
398 if constexpr (std::is_same_v<visit_t, void>) {
399 this->visit(oSession, pNode);
400 return;
401 } else {
402 return this->visit(oSession, pNode);
403 }
404 }
405 break;
406 }
407 case shell_node_type::SNT_ARG: {
408 if (
409 const auto pNode = dynamic_cast<const shell_node_arg *>(pRawNode);
410
411 pNode != nullptr
412 ) {
413 if constexpr (std::is_same_v<visit_t, void>) {
414 this->visit(oSession, pNode);
415 return;
416 } else {
417 return this->visit(oSession, pNode);
418 }
419 }
420 break;
421 }
422 case shell_node_type::SNT_VARIABLE: {
423 if (
424 const auto pNode = dynamic_cast<const shell_node_variable *>(pRawNode);
425 pNode != nullptr
426 ) {
427 if constexpr (std::is_same_v<visit_t, void>) {
428 this->visit(oSession, pNode);
429 return;
430 } else {
431 return this->visit(oSession, pNode);
432 }
433 }
434 break;
435 }
436 case shell_node_type::SNT_DOLLAR_SPECIAL: {
437 if (
438 const auto pNode = dynamic_cast<const shell_node_dollar_special *>(pRawNode);
439 pNode != nullptr
440 ) {
441 if constexpr (std::is_same_v<visit_t, void>) {
442 this->visit(oSession, pNode);
443 return;
444 } else {
445 return this->visit(oSession, pNode);
446 }
447 }
448 break;
449 }
450 case shell_node_type::SNT_DOLLAR_VARIABLE: {
451 if (
452 const auto pNode = dynamic_cast<const shell_node_dollar_variable *>(pRawNode);
453 pNode != nullptr
454 ) {
455 if constexpr (std::is_same_v<visit_t, void>) {
456 this->visit(oSession, pNode);
457 return;
458 } else {
459 return this->visit(oSession, pNode);
460 }
461 }
462 break;
463 }
464 case shell_node_type::SNT_DOLLAR_VARIABLE_DHOP: {
465 if (
466 const auto pNode = dynamic_cast<const shell_node_dollar_variable_dhop *>(pRawNode);
467 pNode != nullptr
468 ) {
469 if constexpr (std::is_same_v<visit_t, void>) {
470 this->visit(oSession, pNode);
471 return;
472 } else {
473 return this->visit(oSession, pNode);
474 }
475 }
476 break;
477 }
478 case shell_node_type::SNT_DOLLAR_ARG: {
479 if (
480 const auto pNode = dynamic_cast<const shell_node_dollar_arg *>(pRawNode);
481 pNode != nullptr
482 ) {
483 if constexpr (std::is_same_v<visit_t, void>) {
484 this->visit(oSession, pNode);
485 return;
486 } else {
487 return this->visit(oSession, pNode);
488 }
489 }
490 break;
491 }
492 case shell_node_type::SNT_DOLLAR_ARG_DHOP: {
493 if (
494 const auto pNode = dynamic_cast<const shell_node_dollar_arg_dhop *>(pRawNode);
495 pNode != nullptr
496 ) {
497 if constexpr (std::is_same_v<visit_t, void>) {
498 this->visit(oSession, pNode);
499 return;
500 } else {
501 return this->visit(oSession, pNode);
502 }
503 }
504 break;
505 }
506 case shell_node_type::SNT_DOLLAR_COMMAND: {
507 if (
508 const auto pNode = dynamic_cast<const shell_node_dollar_command *>(pRawNode);
509 pNode != nullptr
510 ) {
511 if constexpr (std::is_same_v<visit_t, void>) {
512 this->visit(oSession, pNode);
513 return;
514 } else {
515 return this->visit(oSession, pNode);
516 }
517 }
518 break;
519 }
520 case shell_node_type::SNT_BACKGROUND: {
521 if (
522 const auto pNode = dynamic_cast<const shell_node_background *>(pRawNode);
523 pNode != nullptr
524 ) {
525 if constexpr (std::is_same_v<visit_t, void>) {
526 this->visit(oSession, pNode);
527 return;
528 } else {
529 return this->visit(oSession, pNode);
530 }
531 }
532 break;
533 }
534 case shell_node_type::SNT_AND: {
535 if (
536 const auto pNode = dynamic_cast<const shell_node_and *>(pRawNode);
537 pNode != nullptr
538 ) {
539 if constexpr (std::is_same_v<visit_t, void>) {
540 this->visit(oSession, pNode);
541 return;
542 } else {
543 return this->visit(oSession, pNode);
544 }
545 }
546 break;
547 }
548 case shell_node_type::SNT_PIPE: {
549 if (
550 const auto pNode = dynamic_cast<const shell_node_pipe *>(pRawNode);
551 pNode != nullptr
552 ) {
553 if constexpr (std::is_same_v<visit_t, void>) {
554 this->visit(oSession, pNode);
555 return;
556 } else {
557 return this->visit(oSession, pNode);
558 }
559 }
560 break;
561 }
562 case shell_node_type::SNT_OR: {
563 if (
564 const auto pNode = dynamic_cast<const shell_node_or *>(pRawNode);
565 pNode != nullptr
566 ) {
567 if constexpr (std::is_same_v<visit_t, void>) {
568 this->visit(oSession, pNode);
569 return;
570 } else {
571 return this->visit(oSession, pNode);
572 }
573 }
574 break;
575 }
576 case shell_node_type::SNT_IF: {
577 if (
578 const auto pNode = dynamic_cast<const shell_node_if *>(pRawNode);
579 pNode != nullptr
580 ) {
581 if constexpr (std::is_same_v<visit_t, void>) {
582 this->visit(oSession, pNode);
583 return;
584 } else {
585 return this->visit(oSession, pNode);
586 }
587 }
588 break;
589 }
590 case shell_node_type::SNT_TEST: {
591 if (
592 const auto pNode = dynamic_cast<const shell_node_test *>(pRawNode);
593 pNode != nullptr
594 ) {
595 if constexpr (std::is_same_v<visit_t, void>) {
596 this->visit(oSession, pNode);
597 return;
598 } else {
599 return this->visit(oSession, pNode);
600 }
601 }
602 break;
603 }
604 case shell_node_type::SNT_FOR: {
605 if (
606 const auto pNode = dynamic_cast<const shell_node_for *>(pRawNode);
607 pNode != nullptr
608 ) {
609 if constexpr (std::is_same_v<visit_t, void>) {
610 this->visit(oSession, pNode);
611 return;
612 } else {
613 return this->visit(oSession, pNode);
614 }
615 }
616 break;
617 }
618 case shell_node_type::SNT_WHILE: {
619 if (
620 const auto pNode = dynamic_cast<const shell_node_while *>(pRawNode);
621 pNode != nullptr
622 ) {
623 if constexpr (std::is_same_v<visit_t, void>) {
624 this->visit(oSession, pNode);
625 return;
626 } else {
627 return this->visit(oSession, pNode);
628 }
629 }
630 break;
631 }
632 case shell_node_type::SNT_UNTIL: {
633 if (
634 const auto pNode = dynamic_cast<const shell_node_until *>(pRawNode);
635 pNode != nullptr
636 ) {
637 if constexpr (std::is_same_v<visit_t, void>) {
638 this->visit(oSession, pNode);
639 return;
640 } else {
641 return this->visit(oSession, pNode);
642 }
643 }
644 break;
645 }
646 case shell_node_type::SNT_BREAK: {
647 if (
648 const auto pNode = dynamic_cast<const shell_node_break *>(pRawNode);
649 pNode != nullptr
650 ) {
651 if constexpr (std::is_same_v<visit_t, void>) {
652 this->visit(oSession, pNode);
653 return;
654 } else {
655 return this->visit(oSession, pNode);
656 }
657 }
658 break;
659 }
660 case shell_node_type::SNT_CONTINUE: {
661 if (
662 const auto pNode = dynamic_cast<const shell_node_continue *>(pRawNode);
663 pNode != nullptr
664 ) {
665 if constexpr (std::is_same_v<visit_t, void>) {
666 this->visit(oSession, pNode);
667 return;
668 } else {
669 return this->visit(oSession, pNode);
670 }
671 }
672 break;
673 }
674 case shell_node_type::SNT_NULL_COMMAND: {
675 if (
676 const auto pNode = dynamic_cast<const shell_node_null_command *>(pRawNode);
677 pNode != nullptr
678 ) {
679 if constexpr (std::is_same_v<visit_t, void>) {
680 this->visit(oSession, pNode);
681 return;
682 } else {
683 return this->visit(oSession, pNode);
684 }
685 }
686 break;
687 }
688 case shell_node_type::SNT_COMMAND: {
689 if (
690 const auto pNode = dynamic_cast<const shell_node_command *>(pRawNode);
691 pNode != nullptr
692 ) {
693 if constexpr (std::is_same_v<visit_t, void>) {
694 this->visit(oSession, pNode);
695 return;
696 } else {
697 return this->visit(oSession, pNode);
698 }
699 }
700 break;
701 }
702 case shell_node_type::SNT_COMMAND_BLOCK: {
703 if (
704 const auto pNode = dynamic_cast<const shell_node_command_block *>(pRawNode);
705 pNode != nullptr
706 ) {
707 if constexpr (std::is_same_v<visit_t, void>) {
708 this->visit(oSession, pNode);
709 return;
710 } else {
711 return this->visit(oSession, pNode);
712 }
713 }
714 break;
715 }
716 case shell_node_type::SNT_COMMAND_BLOCK_SUBSHELL: {
717 if (
718 const auto pNode = dynamic_cast<const shell_node_command_block_subshell *>(pRawNode);
719 pNode != nullptr
720 ) {
721 if constexpr (std::is_same_v<visit_t, void>) {
722 this->visit(oSession, pNode);
723 return;
724 } else {
725 return this->visit(oSession, pNode);
726 }
727 }
728 break;
729 }
730 case shell_node_type::SNT_FUNCTION: {
731 if (
732 const auto pNode = dynamic_cast<const shell_node_function *>(pRawNode);
733 pNode != nullptr
734 ) {
735 if constexpr (std::is_same_v<visit_t, void>) {
736 this->visit(oSession, pNode);
737 return;
738 } else {
739 return this->visit(oSession, pNode);
740 }
741 }
742 break;
743 }
744 }
745
746 if constexpr (std::is_same_v<visit_t, void>) {
747 return;
748 } else {
749 return visit_t();
750 }
751 }
752}
Logical AND operator node (executes right only if left succeeded).
Definition shell_node.h:1159
Extract positional argument from the session (e.g. $1, $2).
Definition shell_node.h:536
Evaluates a subcommand in background semantics (implementation-specific).
Definition shell_node.h:1002
Represents a break statement inside a loop.
Definition shell_node.h:1466
Command block executed in a subshell (may isolate environment changes).
Definition shell_node.h:960
A sequence of evaluable nodes executed in order (a block).
Definition shell_node.h:920
Represents a command expression composed of expandable children.
Definition shell_node.h:229
Wraps a command expression and executes it as a command.
Definition shell_node.h:885
Represents a continue statement inside a loop.
Definition shell_node.h:1418
Dollar-argument with "double-hop" semantics (implementation-specific).
Definition shell_node.h:696
Extract an argument referenced with a leading $ (e.g. $@, $* or $1).
Definition shell_node.h:657
Command-substitution node used in $() or backticks when appearing inside other contexts.
Definition shell_node.h:776
Special dollar items such as $?, $#, $$, etc. (implementation-specific).
Definition shell_node.h:816
Dollar-variable with double-hop lookup semantics.
Definition shell_node.h:735
Dollar-prefixed variable node (may have different semantics).
Definition shell_node.h:618
Iterative 'for' loop node that iterates over an expandable sequence.
Definition shell_node.h:1513
Create function and adds to the shell session.
Definition shell_node.h:1702
Conditional execution node (if-then-else).
Definition shell_node.h:1345
Represents a no-op command node (useful as placeholder).
Definition shell_node.h:856
Logical OR operator node (executes right only if left failed).
Definition shell_node.h:1247
Pipe operator node (connects stdout of left to stdin of right).
Definition shell_node.h:1203
Command-substitution string node (backticks or $(...)).
Definition shell_node.h:362
Double-quoted string node.
Definition shell_node.h:339
Simple (unquoted) string node.
Definition shell_node.h:317
Node that evaluates an expandable expression as a test/condition.
Definition shell_node.h:1296
A single Unicode codepoint node.
Definition shell_node.h:450
'Until' loop node that executes the iterative block until the condition succeeds.
Definition shell_node.h:1646
Extract a named shell variable from the session environment.
Definition shell_node.h:577
Generic visitor for shell AST nodes.
Definition shell_node_visitor.h:46
virtual visit_t visit(shell_session &oSession, const shell_node_until *pNode)=0
Visit an until-loop node.
visit_t visit_type
Type of data resulting of visit.
Definition shell_node_visitor.h:52
virtual visit_t visit(shell_session &oSession, const shell_node_str_back *pNode)=0
Visit a backtick command string node.
virtual visit_t visit(shell_session &oSession, const shell_node_variable *pNode)=0
Visit a variable node.
virtual visit_t visit(shell_session &oSession, const shell_node_dollar_variable *pNode)=0
Visit a $var variable reference node.
virtual visit_t visit(shell_session &oSession, const shell_node_and *pNode)=0
Visit a logical AND operator node.
virtual visit_t visit(shell_session &oSession, const shell_node_continue *pNode)=0
Visit a continue statement node.
virtual visit_t visit(shell_session &oSession, const shell_node_str_double *pNode)=0
Visit a double-quoted string node.
virtual visit_t visit(shell_session &oSession, const shell_node_dollar_variable_dhop *pNode)=0
Visit a ${var} variable reference node.
virtual visit_t visit(shell_session &oSession, const shell_node_or *pNode)=0
Visit a logical OR operator node.
virtual visit_t visit(shell_session &oSession, const shell_node_dollar_command *pNode)=0
Visit a command substitution node ($(...)).
virtual visit_t visit(shell_session &oSession, const shell_node_for *pNode)=0
Visit a for-loop node.
virtual visit_t visit(shell_session &oSession, const shell_node_unicode *pNode)=0
Visit a Unicode node.
virtual visit_t visit(shell_session &oSession, const shell_node_command_block_subshell *pNode)=0
Visit a subshell command block node.
virtual visit_t visit(shell_session &oSession, const shell_node_function *pNode)=0
Visit a function node.
virtual visit_t visit(shell_session &oSession, const shell_node_pipe *pNode)=0
Visit a pipe operator node.
virtual visit_t visit(shell_session &oSession, const shell_node_while *pNode)=0
Visit a while-loop node.
virtual visit_t visit_node(shell_session &oSession, const shell_node *pRawNode)
Dispatch a node to the correct visit function.
Definition shell_node_visitor.h:320
virtual visit_t visit(shell_session &oSession, const shell_node_command_block *pNode)=0
Visit a command block node.
virtual visit_t visit(shell_session &oSession, const shell_node_if *pNode)=0
Visit an if-statement node.
virtual visit_t visit(shell_session &oSession, const shell_node_dollar_arg_dhop *pNode)=0
Visit a ${N} argument reference node.
virtual visit_t visit(shell_session &oSession, const shell_node_str_simple *pNode)=0
Visit a simple quoted string node.
virtual visit_t visit(shell_session &oSession, const shell_node_dollar_special *pNode)=0
Visit a special variable node ($?, $#, etc.).
virtual visit_t visit(shell_session &oSession, const shell_node_null_command *pNode)=0
Visit a null command node.
virtual visit_t visit(shell_session &oSession, const shell_node_test *pNode)=0
Visit a test command node.
virtual visit_t visit(shell_session &oSession, const shell_node_dollar_arg *pNode)=0
Visit a $N argument reference node.
virtual visit_t visit(shell_session &oSession, const shell_node_command *pNode)=0
Visit a command node.
virtual visit_t visit(shell_session &oSession, const shell_node_command_expression *pNode)=0
Visit a command expression node.
virtual visit_t visit(shell_session &oSession, const shell_node_background *pNode)=0
Visit a background operator node.
virtual visit_t visit(shell_session &oSession, const shell_node_word *pNode)=0
Visit a word node.
virtual visit_t visit(shell_session &oSession, const shell_node_arg *pNode)=0
Visit an argument node.
virtual visit_t visit(shell_session &oSession, const shell_node_break *pNode)=0
Visit a break statement node.
While-loop node executing the iterative block while the condition succeeds.
Definition shell_node.h:1586
A plain word token node.
Definition shell_node.h:404
Base class for all parser nodes.
Definition shell_node.h:116
shell_node_type get_type() const noexcept
Get the node type.
Definition shell_node.h:140
Represents an execution environment for a shell instance.
Definition shell_session.h:57
BashSpark main namespace.
Definition command.h:39
Defines the shell node hierarchy used by the parser.