Bash++
Bash++ compiler internal documentation
BaseListener.h
Go to the documentation of this file.
1
7#pragma once
8
9#include <memory>
10#include <type_traits>
11
12#include <AST/ASTNode.h>
13#include <AST/NodeTypes.h>
14#include <AST/Nodes/Nodes.h>
15#include <error/InternalError.h>
16#include <error/SyntaxError.h>
17#include <error/ParserError.h>
18
19namespace AST {
20
21// Single source of truth for node list (used to generate wrappers + map)
22#define AST_LISTENER_NODE_LIST(X) \
23 X(ArrayAssignment) \
24 X(ArrayIndex) \
25 X(Bash53NativeSupershell) \
26 X(BashArithmeticForCondition) \
27 X(BashArithmeticForStatement) \
28 X(BashArithmeticStatement) \
29 X(BashArithmeticSubstitution) \
30 X(BashCaseInput) \
31 X(BashCasePattern) \
32 X(BashCasePatternHeader) \
33 X(BashCaseStatement) \
34 X(BashCommand) \
35 X(BashCommandSequence) \
36 X(BashForStatement) \
37 X(BashFunction) \
38 X(BashIfCondition) \
39 X(BashIfElseBranch) \
40 X(BashIfRootBranch) \
41 X(BashIfStatement) \
42 X(BashInCondition) \
43 X(BashPipeline) \
44 X(BashRedirection) \
45 X(BashSelectStatement) \
46 X(BashTestConditionCommand) \
47 X(BashUntilStatement) \
48 X(BashVariable) \
49 X(BashWhileOrUntilCondition) \
50 X(BashWhileStatement) \
51 X(Block) \
52 X(ClassDefinition) \
53 X(Connective) \
54 X(ConstructorDefinition) \
55 X(DatamemberDeclaration) \
56 X(DeleteStatement) \
57 X(DestructorDefinition) \
58 X(DoublequotedString) \
59 X(DynamicCast) \
60 X(DynamicCastTarget) \
61 X(HeredocBody) \
62 X(HereString) \
63 X(IncludeStatement) \
64 X(MethodDefinition) \
65 X(NewStatement) \
66 X(ObjectAssignment) \
67 X(ObjectInstantiation) \
68 X(ObjectReference) \
69 X(ParameterExpansion) \
70 X(PointerDeclaration) \
71 X(PrimitiveAssignment) \
72 X(ProcessSubstitution) \
73 X(Program) \
74 X(RawSubshell) \
75 X(RawText) \
76 X(Rvalue) \
77 X(SubshellSubstitution) \
78 X(Supershell) \
79 X(TypeofExpression) \
80 X(ValueAssignment) \
81
111template <class Derived>
113 private:
114 Derived& self() {
115 return static_cast<Derived&>(*this);
116 }
117
118 protected:
119 bool program_has_errors = false;
120 std::vector<AST::ParserError> parser_errors;
121
122 public:
123 virtual ~BaseListener() = default;
124
125 void walk(std::shared_ptr<AST::ASTNode> node) {
126 try {
127 switch (node->getType()) {
128 #define AST_CASE(Name) \
129 case AST::NodeType::Name: \
130 if constexpr (requires(Derived& d, std::shared_ptr<AST::Name> x) { d.enter##Name(x); }) { \
131 self().enter##Name(std::static_pointer_cast<AST::Name>(node)); \
132 } \
133 for (const auto& child : node->getChildren()) { \
134 walk(child); \
135 } \
136 if constexpr (requires(Derived& d, std::shared_ptr<AST::Name> x) { d.exit##Name(x); }) { \
137 self().exit##Name(std::static_pointer_cast<AST::Name>(node)); \
138 } \
139 break;
140
142
143 #undef AST_CASE
144
145 default:
146 throw bpp::ErrorHandling::InternalError("Unknown AST node type encountered in listener walk");
147 }
148 } catch (const bpp::ErrorHandling::SyntaxError& e) {
149 // Cancel traversal of this node and its children, but continue to traverse the rest of the tree
150 this->program_has_errors = true;
151 e.print();
152 return;
153 }
154 }
155 #undef AST_LISTENER_NODE_LIST
156
157 inline void set_has_errors(bool has_errors) {
158 this->program_has_errors = has_errors;
159 }
160
161 inline void set_parser_errors(const std::vector<AST::ParserError>& errors) {
162 this->parser_errors = errors;
163 if (!errors.empty()) this->program_has_errors = true;
164 }
165};
166
167} // namespace AST
#define AST_CASE(Name)
#define AST_LISTENER_NODE_LIST(X)
Definition BaseListener.h:22
CRTP base class for AST listeners. CRTP is a kind of language hack that makes static polymorphism pos...
Definition BaseListener.h:112
void set_parser_errors(const std::vector< AST::ParserError > &errors)
Definition BaseListener.h:161
bool program_has_errors
Definition BaseListener.h:119
virtual ~BaseListener()=default
void walk(std::shared_ptr< AST::ASTNode > node)
Definition BaseListener.h:125
std::vector< AST::ParserError > parser_errors
Definition BaseListener.h:120
void set_has_errors(bool has_errors)
Definition BaseListener.h:157
Derived & self()
Definition BaseListener.h:114
void print() const
Definition SyntaxError.h:104
An exception thrown when a syntax error is encountered This exception can be constructed from any lis...
Definition SyntaxError.h:127
Definition AccessModifier.h:9
An exception thrown when an internal error occurs.
Definition InternalError.h:22