1
2
3
4
5
6 #include <sngcpp/binder/StatementBinder.hpp>
7 #include <sngcpp/binder/ExpressionBinder.hpp>
8 #include <sngcpp/ast/SourceFile.hpp>
9
10 namespace sngcpp { namespace binder {
11
12 StatementBinder::StatementBinder(SymbolTable& symbolTable_, const std::std::unordered_map<SourceFileNode*, BoundSourceFile*>&sourceFileMap_):
13 symbolTable(symbolTable_), sourceFileMap(sourceFileMap_), currentSourceFile(nullptr), containerScope(nullptr), currentFunction(nullptr)
14 {
15 }
16
17 void StatementBinder::Visit(SourceFileNode& sourceFileNode)
18 {
19 if (sourceFileNode.SourceFilePath().find("Lexer.cpp") != std::string::npos)
20 {
21 int x = 0;
22 }
23 auto it = sourceFileMap.find(&sourceFileNode);
24 if (it != sourceFileMap.cend())
25 {
26 currentSourceFile = it->second;
27 }
28 else
29 {
30 throw std::runtime_error("source file not found");
31 }
32 containerScope = symbolTable.GlobalNs()->GetContainerScope();
33 sourceFileNode.GlobalNs()->Accept(*this);
34 }
35
36 void StatementBinder::Visit(SourceFileSequenceNode& sourceFileSequenceNode)
37 {
38 sourceFileSequenceNode.Left()->Accept(*this);
39 sourceFileSequenceNode.Right()->Accept(*this);
40 }
41
42 void StatementBinder::Visit(SimpleDeclarationNode& simpleDeclarationNode)
43 {
44 BindExpression(simpleDeclarationNode.TypeExpr(), symbolTable, containerScope, std::vector<ContainerScope*>(), currentSourceFile, currentFunction, this);
45 BindExpression(simpleDeclarationNode.Declarator(), symbolTable, containerScope, std::vector<ContainerScope*>(), currentSourceFile, currentFunction, this);
46 }
47
48 void StatementBinder::Visit(NamespaceNode& namespaceNode)
49 {
50 if (namespaceNode.Child())
51 {
52 namespaceNode.Child()->Accept(*this);
53 }
54 }
55
56 void StatementBinder::Visit(MemberAccessDeclarationNode& memberAccessDeclarationNode)
57 {
58 memberAccessDeclarationNode.Declaration()->Accept(*this);
59 }
60
61 void StatementBinder::Visit(MemberDeclarationNode& memberDeclarationNode)
62 {
63 if (memberDeclarationNode.TypeExpr())
64 {
65 BindExpression(memberDeclarationNode.TypeExpr(), symbolTable, containerScope, std::vector<ContainerScope*>(), currentSourceFile, currentFunction, this);
66 }
67 BindExpression(memberDeclarationNode.Declarator(), symbolTable, containerScope, std::vector<ContainerScope*>(), currentSourceFile, currentFunction, this);
68 if (memberDeclarationNode.Initializer())
69 {
70 BindExpression(memberDeclarationNode.Initializer(), symbolTable, containerScope, std::vector<ContainerScope*>(), currentSourceFile, currentFunction, this);
71 }
72 }
73
74 void StatementBinder::Visit(DeclarationSequenceNode& declarationSequenceNode)
75 {
76 declarationSequenceNode.Left()->Accept(*this);
77 declarationSequenceNode.Right()->Accept(*this);
78 }
79
80 void StatementBinder::Visit(LinkageSpecificationNode& linkageSpecificationNode)
81 {
82 linkageSpecificationNode.Declarations()->Accept(*this);
83 }
84
85 void StatementBinder::Visit(TemplateDeclarationNode& templateDeclarationNode)
86 {
87 templateDeclarationNode.Declaration()->Accept(*this);
88 }
89
90 void StatementBinder::Visit(ClassNode& classNode)
91 {
92 Symbol* symbol = symbolTable.GetSymbol(&classNode);
93 if (symbol->IsClassTypeSymbol())
94 {
95 ClassTypeSymbol* classTypeSymbol = static_cast<ClassTypeSymbol*>(symbol);
96 ContainerScope* prevContainerScope = containerScope;
97 containerScope = classTypeSymbol->GetContainerScope();
98 if (classNode.Declarations())
99 {
100 classNode.Declarations()->Accept(*this);
101 }
102 containerScope = prevContainerScope;
103 }
104 else
105 {
106 throw std::runtime_error("class type symbol expected");
107 }
108 }
109
110 void StatementBinder::Visit(FunctionNode& functionNode)
111 {
112 Symbol* symbol = symbolTable.GetSymbolNothrow(&functionNode);
113 if (symbol)
114 {
115 if (symbol->IsFunctionSymbol())
116 {
117 FunctionSymbol* prevFunction = currentFunction;
118 currentFunction = static_cast<FunctionSymbol*>(symbol);
119 if (currentFunction->GroupName() == U"MakeCanonicalClasses")
120 {
121 int x = 0;
122 }
123 ContainerScope* prevContainerScope = containerScope;
124 containerScope = currentFunction->GetContainerScope();
125 if (functionNode.Body())
126 {
127 functionNode.Body()->Accept(*this);
128 }
129 currentFunction = prevFunction;
130 containerScope = prevContainerScope;
131 }
132 else
133 {
134 throw std::runtime_error("function symbol expected");
135 }
136 }
137 }
138
139 void StatementBinder::Visit(SpecialMemberFunctionNode& specialMemberFunctionNode)
140 {
141 Symbol* symbol = symbolTable.GetSymbolNothrow(&specialMemberFunctionNode);
142 if (symbol)
143 {
144 if (symbol->IsFunctionSymbol())
145 {
146 FunctionSymbol* prevFunction = currentFunction;
147 currentFunction = static_cast<FunctionSymbol*>(symbol);
148 ContainerScope* prevContainerScope = containerScope;
149 containerScope = currentFunction->GetContainerScope();
150 if (specialMemberFunctionNode.CtorInitializer())
151 {
152 BindExpression(specialMemberFunctionNode.CtorInitializer(), symbolTable, containerScope, std::vector<ContainerScope*>(), currentSourceFile, currentFunction, this);
153 }
154 if (specialMemberFunctionNode.FunctionBody())
155 {
156 specialMemberFunctionNode.FunctionBody()->Accept(*this);
157 }
158 currentFunction = prevFunction;
159 containerScope = prevContainerScope;
160 }
161 else
162 {
163 throw std::runtime_error("function symbol expected");
164 }
165 }
166 }
167
168 void StatementBinder::Visit(CompoundStatementNode& compoundStatementNode)
169 {
170 Symbol* symbol = symbolTable.GetSymbol(&compoundStatementNode);
171 if (symbol->IsDeclarationBlockSymbol())
172 {
173 DeclarationBlockSymbol* declarationBlock = static_cast<DeclarationBlockSymbol*>(symbol);
174 ContainerScope* prevContainerScope = containerScope;
175 containerScope = declarationBlock->GetContainerScope();
176 if (compoundStatementNode.Child())
177 {
178 compoundStatementNode.Child()->Accept(*this);
179 }
180 containerScope = prevContainerScope;
181 }
182 else
183 {
184 throw std::runtime_error("declaration block expected");
185 }
186 }
187
188 void StatementBinder::Visit(StatementSequenceNode& statementSequenceNode)
189 {
190 statementSequenceNode.Left()->Accept(*this);
191 statementSequenceNode.Right()->Accept(*this);
192 }
193
194 void StatementBinder::Visit(LabeledStatementNode& labeledStatementNode)
195 {
196 labeledStatementNode.Child()->Accept(*this);
197 }
198
199 void StatementBinder::Visit(IfStatementNode& ifStatementNode)
200 {
201 BindExpression(ifStatementNode.Condition(), symbolTable, containerScope, std::vector<ContainerScope*>(), currentSourceFile, currentFunction, this);
202 ifStatementNode.ThenS()->Accept(*this);
203 if (ifStatementNode.ElseS())
204 {
205 ifStatementNode.ElseS()->Accept(*this);
206 }
207 }
208
209 void StatementBinder::Visit(SwitchStatementNode& switchStatementNode)
210 {
211 BindExpression(switchStatementNode.Condition(), symbolTable, containerScope, std::vector<ContainerScope*>(), currentSourceFile, currentFunction, this);
212 switchStatementNode.Statement()->Accept(*this);
213 }
214
215 void StatementBinder::Visit(CaseStatementNode& caseStatementNode)
216 {
217 BindExpression(caseStatementNode.CaseExpr(), symbolTable, containerScope, std::vector<ContainerScope*>(), currentSourceFile, currentFunction, this);
218 caseStatementNode.Child()->Accept(*this);
219 }
220
221 void StatementBinder::Visit(DefaultStatementNode& defaultStatementNode)
222 {
223 defaultStatementNode.Child()->Accept(*this);
224 }
225
226 void StatementBinder::Visit(ExpressionStatementNode& expressionStatementNode)
227 {
228 if (expressionStatementNode.Child())
229 {
230 BindExpression(expressionStatementNode.Child(), symbolTable, containerScope, std::vector<ContainerScope*>(), currentSourceFile, currentFunction, this);
231 }
232 }
233
234 void StatementBinder::Visit(WhileStatementNode& whileStatementNode)
235 {
236 BindExpression(whileStatementNode.Condition(), symbolTable, containerScope, std::vector<ContainerScope*>(), currentSourceFile, currentFunction, this);
237 whileStatementNode.Statement()->Accept(*this);
238 }
239
240 void StatementBinder::Visit(DoStatementNode& doStatementNode)
241 {
242 doStatementNode.Statement()->Accept(*this);
243 BindExpression(doStatementNode.Condition(), symbolTable, containerScope, std::vector<ContainerScope*>(), currentSourceFile, currentFunction, this);
244 }
245
246 void StatementBinder::Visit(RangeForStatementNode& rangeForStatementNode)
247 {
248 Symbol* symbol = symbolTable.GetSymbol(&rangeForStatementNode);
249 if (symbol->IsDeclarationBlockSymbol())
250 {
251 DeclarationBlockSymbol* declarationBlock = static_cast<DeclarationBlockSymbol*>(symbol);
252 ContainerScope* prevContainerScope = containerScope;
253 containerScope = declarationBlock->GetContainerScope();
254 BindExpression(rangeForStatementNode.ForRangeDeclaration(), symbolTable, containerScope, std::vector<ContainerScope*>(), currentSourceFile, currentFunction, this);
255 BindExpression(rangeForStatementNode.ForRangeInitializer(), symbolTable, containerScope, std::vector<ContainerScope*>(), currentSourceFile, currentFunction, this);
256 rangeForStatementNode.Statement()->Accept(*this);
257 containerScope = prevContainerScope;
258 }
259 else
260 {
261 throw std::runtime_error("declaration block expected");
262 }
263 }
264
265 void StatementBinder::Visit(ForStatementNode& forStatementNode)
266 {
267 Symbol* symbol = symbolTable.GetSymbol(&forStatementNode);
268 if (symbol->IsDeclarationBlockSymbol())
269 {
270 DeclarationBlockSymbol* declarationBlock = static_cast<DeclarationBlockSymbol*>(symbol);
271 ContainerScope* prevContainerScope = containerScope;
272 containerScope = declarationBlock->GetContainerScope();
273 if (forStatementNode.InitS())
274 {
275 forStatementNode.InitS()->Accept(*this);
276 }
277 if (forStatementNode.Condition())
278 {
279 BindExpression(forStatementNode.Condition(), symbolTable, containerScope, std::vector<ContainerScope*>(), currentSourceFile, currentFunction, this);
280 }
281 if (forStatementNode.LoopExpr())
282 {
283 BindExpression(forStatementNode.LoopExpr(), symbolTable, containerScope, std::vector<ContainerScope*>(), currentSourceFile, currentFunction, this);
284 }
285 forStatementNode.ActionS()->Accept(*this);
286 containerScope = prevContainerScope;
287 }
288 else
289 {
290 throw std::runtime_error("declaration block expected");
291 }
292 }
293
294 void StatementBinder::Visit(ReturnStatementNode& returnStatementNode)
295 {
296 if (returnStatementNode.ReturnExpr())
297 {
298 BindExpression(returnStatementNode.ReturnExpr(), symbolTable, containerScope, std::vector<ContainerScope*>(), currentSourceFile, currentFunction, this);
299 }
300 }
301
302 void StatementBinder::Visit(DeclarationStatementNode& declarationStatementNode)
303 {
304 BindExpression(declarationStatementNode.Child(), symbolTable, containerScope, std::vector<ContainerScope*>(), currentSourceFile, currentFunction, this);
305 }
306
307 void StatementBinder::Visit(TryStatementNode& tryStatementNode)
308 {
309 tryStatementNode.TryBlock()->Accept(*this);
310 tryStatementNode.Handlers()->Accept(*this);
311 }
312
313 void StatementBinder::Visit(HandlerNode& handlerNode)
314 {
315 BindExpression(handlerNode.ExceptionDeclaration(), symbolTable, containerScope, std::vector<ContainerScope*>(), currentSourceFile, currentFunction, this);
316 handlerNode.CatchBlock()->Accept(*this);
317 }
318
319 void StatementBinder::Visit(HandlerSequenceNode& handlerSequenceNode)
320 {
321 handlerSequenceNode.Left()->Accept(*this);
322 handlerSequenceNode.Right()->Accept(*this);
323 }
324
325 } }