Mercurial > projects > dil
comparison src/dil/ast/DefaultVisitor.d @ 806:bcb74c9b895c
Moved out files in the trunk folder to the root.
author | Aziz K?ksal <aziz.koeksal@gmail.com> |
---|---|
date | Sun, 09 Mar 2008 00:12:19 +0100 |
parents | trunk/src/dil/ast/DefaultVisitor.d@9e6c6bb73e5f |
children |
comparison
equal
deleted
inserted
replaced
805:a3fab8b74a7d | 806:bcb74c9b895c |
---|---|
1 /++ | |
2 Author: Aziz Köksal | |
3 License: GPL3 | |
4 +/ | |
5 module dil.ast.DefaultVisitor; | |
6 | |
7 import dil.ast.Visitor; | |
8 | |
9 import dil.ast.Node; | |
10 import dil.ast.Declarations, | |
11 dil.ast.Expressions, | |
12 dil.ast.Statements, | |
13 dil.ast.Types, | |
14 dil.ast.Parameters; | |
15 import common; | |
16 | |
17 /// This huge template function, when instantiated for a certain node class, | |
18 /// generates a body of calls to visit() on the subnodes. | |
19 returnType!(T.stringof) visitDefault(T)(T t) | |
20 { | |
21 assert(t !is null, "node passed to visitDefault() is null"); | |
22 //Stdout(t).newline; | |
23 | |
24 alias t d, s, e, n; // Variable aliases of t. | |
25 | |
26 static if (is(T : Declaration)) | |
27 { | |
28 alias T D; | |
29 static if (is(D == CompoundDeclaration)) | |
30 foreach (decl; d.decls) | |
31 visitD(decl); | |
32 //EmptyDeclaration, | |
33 //IllegalDeclaration, | |
34 //ModuleDeclaration have no subnodes. | |
35 static if (is(D == AliasDeclaration) || | |
36 is(D == TypedefDeclaration)) | |
37 visitD(d.decl); | |
38 static if (is(D == EnumDeclaration)) | |
39 { | |
40 d.baseType && visitT(d.baseType); | |
41 foreach (member; d.members) | |
42 visitD(member); | |
43 } | |
44 static if (is(D == EnumMemberDeclaration)) | |
45 d.value && visitE(d.value); | |
46 static if (is(D == ClassDeclaration) || is( D == InterfaceDeclaration)) | |
47 { | |
48 // visitN(d.tparams); | |
49 foreach (base; d.bases) | |
50 visitT(base); | |
51 d.decls && visitD(d.decls); | |
52 } | |
53 static if (is(D == StructDeclaration) || is(D == UnionDeclaration)) | |
54 // visitN(d.tparams), | |
55 d.decls && visitD(d.decls); | |
56 static if (is(D == ConstructorDeclaration)) | |
57 visitN(d.params), visitS(d.funcBody); | |
58 static if (is(D == StaticConstructorDeclaration) || | |
59 is(D == DestructorDeclaration) || | |
60 is(D == StaticDestructorDeclaration) || | |
61 is(D == InvariantDeclaration) || | |
62 is(D == UnittestDeclaration)) | |
63 visitS(d.funcBody); | |
64 static if (is(D == FunctionDeclaration)) | |
65 visitT(d.returnType), | |
66 // visitN(d.tparams), | |
67 visitN(d.params), | |
68 visitS(d.funcBody); | |
69 static if (is(D == VariablesDeclaration)) | |
70 { | |
71 d.typeNode && visitT(d.typeNode); | |
72 foreach(init; d.inits) | |
73 init && visitE(init); | |
74 } | |
75 static if (is(D == DebugDeclaration) || is(D == VersionDeclaration)) | |
76 d.decls && visitD(d.decls), | |
77 d.elseDecls && visitD(d.elseDecls); | |
78 static if (is(D == StaticIfDeclaration)) | |
79 visitE(d.condition), | |
80 visitD(d.ifDecls), | |
81 d.elseDecls && visitD(d.elseDecls); | |
82 static if (is(D == StaticAssertDeclaration)) | |
83 visitE(d.condition), | |
84 d.message && visitE(d.message); | |
85 static if (is(D == TemplateDeclaration)) | |
86 visitN(d.tparams), | |
87 visitD(d.decls); | |
88 static if (is(D == NewDeclaration) || is(D == DeleteDeclaration)) | |
89 visitN(d.params), | |
90 visitS(d.funcBody); | |
91 static if (is(D == ProtectionDeclaration) || | |
92 is(D == StorageClassDeclaration) || | |
93 is(D == LinkageDeclaration) || | |
94 is(D == AlignDeclaration)) | |
95 visitD(d.decls); | |
96 static if (is(D == PragmaDeclaration)) | |
97 { | |
98 foreach (arg; d.args) | |
99 visitE(arg); | |
100 visitD(d.decls); | |
101 } | |
102 static if (is(D == MixinDeclaration)) | |
103 d.templateExpr ? visitE(d.templateExpr) : visitE(d.argument); | |
104 } | |
105 else | |
106 static if (is(T : Expression)) | |
107 { | |
108 alias T E; | |
109 static if (is(E == IllegalExpression)) | |
110 {} | |
111 else | |
112 static if (is(E == CondExpression)) | |
113 visitE(e.condition), visitE(e.lhs), visitE(e.rhs); | |
114 else | |
115 static if (is(E : BinaryExpression)) | |
116 visitE(e.lhs), visitE(e.rhs); | |
117 else | |
118 static if (is(E : UnaryExpression)) | |
119 { | |
120 static if (is(E == CastExpression)) | |
121 visitT(e.type); | |
122 visitE(e.e); // Visit member in base class UnaryExpression. | |
123 static if (is(E == IndexExpression)) | |
124 foreach (arg; e.args) | |
125 visitE(arg); | |
126 static if (is(E == SliceExpression)) | |
127 e.left && (visitE(e.left), visitE(e.right)); | |
128 static if (is(E == AsmPostBracketExpression)) | |
129 visitE(e.e2); | |
130 } | |
131 else | |
132 { | |
133 static if (is(E == NewExpression)) | |
134 { | |
135 foreach (arg; e.newArgs) | |
136 visitE(arg); | |
137 visitT(e.type); | |
138 foreach (arg; e.ctorArgs) | |
139 visitE(arg); | |
140 } | |
141 static if (is(E == NewAnonClassExpression)) | |
142 { | |
143 foreach (arg; e.newArgs) | |
144 visitE(arg); | |
145 foreach (base; e.bases) | |
146 visitT(base); | |
147 foreach (arg; e.ctorArgs) | |
148 visitE(arg); | |
149 visitD(e.decls); | |
150 } | |
151 static if (is(E == AsmBracketExpression)) | |
152 visitE(e.e); | |
153 static if (is(E == TemplateInstanceExpression)) | |
154 e.targs && visitN(e.targs); | |
155 static if (is(E == ArrayLiteralExpression)) | |
156 foreach (value; e.values) | |
157 visitE(value); | |
158 static if (is(E == AArrayLiteralExpression)) | |
159 foreach (i, key; e.keys) | |
160 visitE(key), visitE(e.values[i]); | |
161 static if (is(E == AssertExpression)) | |
162 visitE(e.expr), e.msg && visitE(e.msg); | |
163 static if (is(E == MixinExpression) || | |
164 is(E == ImportExpression)) | |
165 visitE(e.expr); | |
166 static if (is(E == TypeofExpression) || | |
167 is(E == TypeDotIdExpression) || | |
168 is(E == TypeidExpression)) | |
169 visitT(e.type); | |
170 static if (is(E == IsExpression)) | |
171 visitT(e.type), e.specType && visitT(e.specType), | |
172 e.tparams && visitN(e.tparams); | |
173 static if (is(E == FunctionLiteralExpression)) | |
174 e.returnType && visitT(e.returnType), | |
175 e.params && visitN(e.params), | |
176 visitS(e.funcBody); | |
177 static if (is(E == ParenExpression)) | |
178 visitE(e.next); | |
179 static if (is(E == TraitsExpression)) | |
180 visitN(e.targs); | |
181 // VoidInitializer has no subnodes. | |
182 static if (is(E == ArrayInitExpression)) | |
183 foreach (i, key; e.keys) | |
184 key && visitE(key), visitE(e.values[i]); | |
185 static if (is(E == StructInitExpression)) | |
186 foreach (value; e.values) | |
187 visitE(value); | |
188 } | |
189 } | |
190 else | |
191 static if (is(T : Statement)) | |
192 { | |
193 alias T S; | |
194 static if (is(S == CompoundStatement)) | |
195 foreach (stmnt; s.stmnts) | |
196 visitS(stmnt); | |
197 //IllegalStatement has no subnodes. | |
198 static if (is(S == FuncBodyStatement)) | |
199 s.funcBody && visitS(s.funcBody), | |
200 s.inBody && visitS(s.inBody), | |
201 s.outBody && visitS(s.outBody); | |
202 static if (is(S == ScopeStatement) || is(S == LabeledStatement)) | |
203 visitS(s.s); | |
204 static if (is(S == ExpressionStatement)) | |
205 visitE(s.e); | |
206 static if (is(S == DeclarationStatement)) | |
207 visitD(s.decl); | |
208 static if (is(S == IfStatement)) | |
209 { | |
210 s.variable ? cast(Node)visitS(s.variable) : visitE(s.condition); | |
211 visitS(s.ifBody), s.elseBody && visitS(s.elseBody); | |
212 } | |
213 static if (is(S == WhileStatement)) | |
214 visitE(s.condition), visitS(s.whileBody); | |
215 static if (is(S == DoWhileStatement)) | |
216 visitS(s.doBody), visitE(s.condition); | |
217 static if (is(S == ForStatement)) | |
218 s.init && visitS(s.init), | |
219 s.condition && visitE(s.condition), | |
220 s.increment && visitE(s.increment), | |
221 visitS(s.forBody); | |
222 static if (is(S == ForeachStatement)) | |
223 visitN(s.params), visitE(s.aggregate), visitS(s.forBody); | |
224 static if (is(S == ForeachRangeStatement)) | |
225 visitN(s.params), visitE(s.lower), visitE(s.upper), visitS(s.forBody); | |
226 static if (is(S == SwitchStatement)) | |
227 visitE(s.condition), visitS(s.switchBody); | |
228 static if (is(S == CaseStatement)) | |
229 { | |
230 foreach (value; s.values) | |
231 visitE(value); | |
232 visitS(s.caseBody); | |
233 } | |
234 static if (is(S == DefaultStatement)) | |
235 visitS(s.defaultBody); | |
236 //ContinueStatement, | |
237 //BreakStatement have no subnodes. | |
238 static if (is(S == ReturnStatement)) | |
239 s.e && visitE(s.e); | |
240 static if (is(S == GotoStatement)) | |
241 s.caseExpr && visitE(s.caseExpr); | |
242 static if (is(S == WithStatement)) | |
243 visitE(s.e), visitS(s.withBody); | |
244 static if (is(S == SynchronizedStatement)) | |
245 s.e && visitE(s.e), visitS(s.syncBody); | |
246 static if (is(S == TryStatement)) | |
247 { | |
248 visitS(s.tryBody); | |
249 foreach (catchBody; s.catchBodies) | |
250 visitS(catchBody); | |
251 s.finallyBody && visitS(s.finallyBody); | |
252 } | |
253 static if (is(S == CatchStatement)) | |
254 s.param && visitN(s.param), visitS(s.catchBody); | |
255 static if (is(S == FinallyStatement)) | |
256 visitS(s.finallyBody); | |
257 static if (is(S == ScopeGuardStatement)) | |
258 visitS(s.scopeBody); | |
259 static if (is(S == ThrowStatement)) | |
260 visitE(s.e); | |
261 static if (is(S == VolatileStatement)) | |
262 s.volatileBody && visitS(s.volatileBody); | |
263 static if (is(S == AsmBlockStatement)) | |
264 visitS(s.statements); | |
265 static if (is(S == AsmStatement)) | |
266 foreach (op; s.operands) | |
267 visitE(op); | |
268 //AsmAlignStatement, | |
269 //IllegalAsmStatement have no subnodes. | |
270 static if (is(S == PragmaStatement)) | |
271 { | |
272 foreach (arg; s.args) | |
273 visitE(arg); | |
274 visitS(s.pragmaBody); | |
275 } | |
276 static if (is(S == MixinStatement)) | |
277 visitE(s.templateExpr); | |
278 static if (is(S == StaticIfStatement)) | |
279 visitE(s.condition), visitS(s.ifBody), s.elseBody && visitS(s.elseBody); | |
280 static if (is(S == StaticAssertStatement)) | |
281 visitE(s.condition), s.message && visitE(s.message); | |
282 static if (is(S == DebugStatement) || is(S == VersionStatement)) | |
283 visitS(s.mainBody), s.elseBody && visitS(s.elseBody); | |
284 } | |
285 else | |
286 static if (is(T : TypeNode)) | |
287 { | |
288 //IllegalType, | |
289 //IntegralType, | |
290 //ModuleScopeType, | |
291 //IdentifierType have no subnodes. | |
292 static if (is(T == QualifiedType)) | |
293 visitT(t.lhs), visitT(t.rhs); | |
294 static if (is(T == TypeofType)) | |
295 visitE(t.e); | |
296 static if (is(T == TemplateInstanceType)) | |
297 t.targs && visitN(t.targs); | |
298 static if (is(T == PointerType)) | |
299 visitT(t.next); | |
300 static if (is(T == ArrayType)) | |
301 { | |
302 visitT(t.next); | |
303 if (t.assocType) | |
304 visitT(t.assocType); | |
305 else if (t.e1) | |
306 visitE(t.e1), t.e2 && visitE(t.e2); | |
307 } | |
308 static if (is(T == FunctionType) || is(T == DelegateType)) | |
309 visitT(t.returnType), visitN(t.params); | |
310 static if (is(T == CFuncPointerType)) | |
311 visitT(t.next), t.params && visitN(t.params); | |
312 static if (is(T == BaseClassType) || | |
313 is(T == ConstType) || | |
314 is(T == InvariantType)) | |
315 visitT(t.next); | |
316 } | |
317 else | |
318 static if (is(T == Parameter)) | |
319 { | |
320 n.type && visitT(n.type); | |
321 n.defValue && visitE(n.defValue); | |
322 } | |
323 else | |
324 static if (is(T == Parameters) || | |
325 is(T == TemplateParameters) || | |
326 is(T == TemplateArguments)) | |
327 { | |
328 foreach (node; n.children) | |
329 visitN(node); | |
330 } | |
331 else | |
332 static if (is(T : TemplateParameter)) | |
333 { | |
334 static if (is(N == TemplateAliasParameter) || | |
335 is(N == TemplateTypeParameter) || | |
336 is(N == TemplateThisParameter)) | |
337 n.specType && visitN(n.specType), | |
338 n.defType && visitN(n.defType); | |
339 static if (is(N == TemplateValueParameter)) | |
340 visitT(n.valueType), | |
341 n.specValue && visitN(n.specValue), | |
342 n.defValue && visitN(n.defValue); | |
343 //TemplateTupleParameter has no subnodes. | |
344 } | |
345 else | |
346 static assert(0, "Missing default visit method for: "~typeof(t).stringof); | |
347 return t; | |
348 } | |
349 | |
350 /// Generates the default visit methods. | |
351 /// | |
352 /// E.g: | |
353 /// --- | |
354 /// private mixin .visitDefault!(ClassDeclaration) _ClassDeclaration; | |
355 /// override returnType!("ClassDeclaration") visit(ClassDeclaration node) | |
356 /// { return _ClassDeclaration.visitDefault(node); } | |
357 /// --- | |
358 char[] generateDefaultVisitMethods() | |
359 { | |
360 char[] text; | |
361 foreach (className; g_classNames) | |
362 text ~= "private mixin .visitDefault!("~className~") _"~className~";\n" | |
363 "override returnType!(\""~className~"\") visit("~className~" node)" | |
364 "{return _"~className~".visitDefault(node);}\n"; | |
365 return text; | |
366 } | |
367 // pragma(msg, generateDefaultVisitMethods()); | |
368 | |
369 /// This class provides default methods for | |
370 /// traversing nodes and their sub-nodes. | |
371 class DefaultVisitor : Visitor | |
372 { | |
373 // Comment out if too many errors are shown. | |
374 mixin(generateDefaultVisitMethods()); | |
375 } |