Mercurial > projects > ddmd
annotate dmd/CompoundStatement.d @ 187:b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
author | Abscissa |
---|---|
date | Tue, 07 Jun 2011 23:37:34 -0400 |
parents | e3afd1303184 |
children |
rev | line source |
---|---|
0 | 1 module dmd.CompoundStatement; |
2 | |
114 | 3 import dmd.common; |
0 | 4 import dmd.Loc; |
5 import dmd.Statement; | |
6 import dmd.Array; | |
7 import dmd.TryCatchStatement; | |
8 import dmd.TryFinallyStatement; | |
9 import dmd.Catch; | |
10 import dmd.ScopeStatement; | |
11 import dmd.Identifier; | |
12 import dmd.Lexer; | |
13 import dmd.ThrowStatement; | |
14 import dmd.IdentifierExp; | |
15 import dmd.Scope; | |
16 import dmd.OutBuffer; | |
17 import dmd.HdrGenState; | |
18 import dmd.ArrayTypes; | |
19 import dmd.ReturnStatement; | |
20 import dmd.Expression; | |
21 import dmd.InterState; | |
22 import dmd.InlineDoState; | |
23 import dmd.InlineCostState; | |
24 import dmd.InlineScanState; | |
25 import dmd.IfStatement; | |
26 import dmd.IRState; | |
27 import dmd.BE; | |
28 import dmd.Util; | |
29 | |
187
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
30 import dmd.DDMDExtensions; |
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
31 |
0 | 32 class CompoundStatement : Statement |
33 { | |
187
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
34 mixin insertMemberExtension!(typeof(this)); |
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
35 |
0 | 36 Statements statements; |
37 | |
38 this(Loc loc, Statements s) | |
39 { | |
178 | 40 register(); |
0 | 41 super(loc); |
42 statements = s; | |
43 } | |
44 | |
45 this(Loc loc, Statement s1, Statement s2) | |
46 { | |
178 | 47 register(); |
0 | 48 super(loc); |
49 | |
50 statements = new Statements(); | |
51 statements.reserve(2); | |
122
c77e9f4f1793
Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
52 statements.push(s1); |
c77e9f4f1793
Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
53 statements.push(s2); |
0 | 54 } |
55 | |
72 | 56 override Statement syntaxCopy() |
0 | 57 { |
58 Statements a = new Statements(); | |
59 a.setDim(statements.dim); | |
60 | |
122
c77e9f4f1793
Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
61 foreach (size_t i, Statement s; statements) |
0 | 62 { |
63 if (s) | |
64 s = s.syntaxCopy(); | |
122
c77e9f4f1793
Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
65 a[i] = s; |
0 | 66 } |
67 | |
68 return new CompoundStatement(loc, a); | |
69 } | |
70 | |
93
df6d0f967680
implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents:
79
diff
changeset
|
71 override void toCBuffer(OutBuffer buf, HdrGenState* hgs) |
0 | 72 { |
122
c77e9f4f1793
Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
73 foreach (s; statements) |
c77e9f4f1793
Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
74 { |
177 | 75 if (s) |
93
df6d0f967680
implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents:
79
diff
changeset
|
76 s.toCBuffer(buf, hgs); |
df6d0f967680
implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents:
79
diff
changeset
|
77 } |
0 | 78 } |
79 | |
167
50a6d232176c
rewrite GlobalExpressions, moved DsymbolTable to Global, some cleanup
korDen
parents:
123
diff
changeset
|
80 override Statement semantic(Scope sc) |
0 | 81 { |
82 Statement s; | |
83 | |
84 //printf("CompoundStatement.semantic(this = %p, sc = %p)\n", this, sc); | |
85 | |
86 for (size_t i = 0; i < statements.dim; ) | |
87 { | |
122
c77e9f4f1793
Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
88 s = statements[i]; |
0 | 89 if (s) |
90 { | |
91 Statements a = s.flatten(sc); | |
92 | |
93 if (a) | |
94 { | |
95 statements.remove(i); | |
96 statements.insert(i, a); | |
97 continue; | |
98 } | |
27 | 99 |
100 s = s.semantic(sc); | |
0 | 101 |
122
c77e9f4f1793
Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
102 statements[i] = s; |
0 | 103 if (s) |
104 { | |
105 Statement sentry; | |
106 Statement sexception; | |
107 Statement sfinally; | |
108 | |
109 s.scopeCode(sc, &sentry, &sexception, &sfinally); | |
110 if (sentry) | |
111 { | |
112 sentry = sentry.semantic(sc); | |
113 if (s.isDeclarationStatement()) | |
114 { | |
122
c77e9f4f1793
Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
115 statements.insert(i, sentry); |
0 | 116 i++; |
117 } | |
118 else | |
122
c77e9f4f1793
Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
119 statements[i] = sentry; |
0 | 120 } |
121 if (sexception) | |
122 { | |
123 if (i + 1 == statements.dim && !sfinally) | |
124 { | |
125 static if (true) { | |
126 sexception = sexception.semantic(sc); | |
127 } else { | |
128 statements.push(sexception); | |
129 if (sfinally) | |
130 // Assume sexception does not throw | |
131 statements.push(sfinally); | |
132 } | |
133 } | |
134 else | |
135 { | |
136 /* Rewrite: | |
137 * s; s1; s2; | |
138 * As: | |
139 * s; | |
140 * try { s1; s2; } | |
141 * catch (Object __o) | |
142 * { sexception; throw __o; } | |
143 */ | |
144 Statement body_; | |
145 Statements aa = new Statements(); | |
146 | |
147 for (int j = i + 1; j < statements.dim; j++) | |
148 { | |
122
c77e9f4f1793
Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
149 aa.push(statements[j]); |
0 | 150 } |
151 body_ = new CompoundStatement(Loc(0), aa); | |
152 body_ = new ScopeStatement(Loc(0), body_); | |
153 | |
154 Identifier id = Lexer.uniqueId("__o"); | |
155 | |
156 Statement handler = new ThrowStatement(Loc(0), new IdentifierExp(Loc(0), id)); | |
157 handler = new CompoundStatement(Loc(0), sexception, handler); | |
158 | |
159 Array catches = new Array(); | |
160 Catch ctch = new Catch(Loc(0), null, id, handler); | |
161 catches.push(cast(void*)ctch); | |
162 s = new TryCatchStatement(Loc(0), body_, catches); | |
163 | |
164 if (sfinally) | |
165 s = new TryFinallyStatement(Loc(0), s, sfinally); | |
166 s = s.semantic(sc); | |
167 statements.setDim(i + 1); | |
122
c77e9f4f1793
Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
168 statements.push(s); |
0 | 169 break; |
170 } | |
171 } | |
172 else if (sfinally) | |
173 { | |
174 if (0 && i + 1 == statements.dim) | |
175 { | |
122
c77e9f4f1793
Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
176 statements.push(sfinally); |
0 | 177 } |
178 else | |
179 { | |
180 /* Rewrite: | |
181 * s; s1; s2; | |
182 * As: | |
183 * s; try { s1; s2; } finally { sfinally; } | |
184 */ | |
185 Statement body_; | |
186 Statements aa = new Statements(); | |
187 | |
188 for (int j = i + 1; j < statements.dim; j++) | |
189 { | |
122
c77e9f4f1793
Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
190 aa.push(statements[j]); |
0 | 191 } |
192 body_ = new CompoundStatement(Loc(0), aa); | |
193 s = new TryFinallyStatement(Loc(0), body_, sfinally); | |
194 s = s.semantic(sc); | |
195 statements.setDim(i + 1); | |
122
c77e9f4f1793
Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
196 statements.push(s); |
0 | 197 break; |
198 } | |
199 } | |
200 } | |
201 } | |
202 i++; | |
203 } | |
204 if (statements.dim == 1) | |
205 { | |
122
c77e9f4f1793
Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
206 return statements[0]; |
0 | 207 } |
208 return this; | |
209 } | |
210 | |
72 | 211 override bool usesEH() |
0 | 212 { |
123 | 213 foreach (Statement s; statements) |
214 { | |
215 if (s && s.usesEH()) | |
216 return true; | |
217 } | |
218 | |
219 return false; | |
0 | 220 } |
221 | |
72 | 222 override BE blockExit() |
0 | 223 { |
224 //printf("CompoundStatement::blockExit(%p) %d\n", this, statements->dim); | |
225 BE result = BE.BEfallthru; | |
122
c77e9f4f1793
Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
226 foreach (s; statements) |
c77e9f4f1793
Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
227 { |
0 | 228 if (s) |
229 { | |
230 //printf("result = x%x\n", result); | |
231 //printf("%s\n", s->toChars()); | |
232 if (!(result & BE.BEfallthru) && !s.comeFrom()) | |
233 { | |
79 | 234 if (s.blockExit() != BE.BEhalt && !s.isEmpty()) |
0 | 235 s.warning("statement is not reachable"); |
236 } | |
79 | 237 else |
238 { | |
239 result &= ~BE.BEfallthru; | |
240 result |= s.blockExit(); | |
241 } | |
0 | 242 } |
243 } | |
244 | |
245 return result; | |
246 } | |
247 | |
72 | 248 override bool comeFrom() |
0 | 249 { |
250 assert(false); | |
251 } | |
252 | |
72 | 253 override bool isEmpty() |
0 | 254 { |
122
c77e9f4f1793
Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
255 foreach (s; statements) |
0 | 256 { |
257 if (s && !s.isEmpty()) | |
258 return false; | |
259 } | |
260 return true; | |
261 } | |
262 | |
72 | 263 override Statements flatten(Scope sc) |
0 | 264 { |
265 return statements; | |
266 } | |
267 | |
72 | 268 override ReturnStatement isReturnStatement() |
0 | 269 { |
270 ReturnStatement rs = null; | |
271 | |
122
c77e9f4f1793
Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
272 foreach(s; statements) |
0 | 273 { |
274 if (s) | |
275 { | |
276 rs = s.isReturnStatement(); | |
277 if (rs) | |
278 break; | |
279 } | |
280 } | |
281 return rs; | |
282 } | |
283 | |
72 | 284 override Expression interpret(InterState istate) |
0 | 285 { |
63 | 286 Expression e = null; |
287 | |
288 version (LOG) { | |
289 printf("CompoundStatement.interpret()\n"); | |
290 } | |
291 if (istate.start == this) | |
292 istate.start = null; | |
293 if (statements) | |
294 { | |
122
c77e9f4f1793
Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
295 foreach(s; statements) |
63 | 296 { |
297 if (s) | |
298 { | |
299 e = s.interpret(istate); | |
300 if (e) | |
301 break; | |
302 } | |
303 } | |
304 } | |
305 version (LOG) { | |
306 printf("-CompoundStatement.interpret() %p\n", e); | |
307 } | |
308 return e; | |
0 | 309 } |
310 | |
72 | 311 override int inlineCost(InlineCostState* ics) |
0 | 312 { |
313 int cost = 0; | |
314 | |
122
c77e9f4f1793
Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
315 foreach(s; statements) |
0 | 316 { |
317 if (s) | |
318 { | |
319 cost += s.inlineCost(ics); | |
320 if (cost >= COST_MAX) | |
321 break; | |
322 } | |
323 } | |
324 | |
325 return cost; | |
326 } | |
327 | |
72 | 328 override Expression doInline(InlineDoState ids) |
0 | 329 { |
330 Expression e = null; | |
331 | |
332 //printf("CompoundStatement.doInline() %d\n", statements.dim); | |
122
c77e9f4f1793
Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
333 foreach(s; statements) |
0 | 334 { |
335 if (s) | |
336 { | |
337 Expression e2 = s.doInline(ids); | |
338 e = Expression.combine(e, e2); | |
339 if (s.isReturnStatement()) | |
340 break; | |
341 | |
342 /* Check for: | |
343 * if (condition) | |
344 * return exp1; | |
345 * else | |
346 * return exp2; | |
347 */ | |
348 IfStatement ifs = s.isIfStatement(); | |
349 if (ifs && ifs.elsebody && ifs.ifbody && | |
350 ifs.ifbody.isReturnStatement() && | |
351 ifs.elsebody.isReturnStatement() | |
352 ) | |
353 break; | |
354 } | |
355 } | |
356 return e; | |
357 } | |
358 | |
72 | 359 override Statement inlineScan(InlineScanState* iss) |
0 | 360 { |
122
c77e9f4f1793
Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
361 foreach(ref Statement s; statements) |
0 | 362 { |
363 if (s) | |
122
c77e9f4f1793
Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
364 s = s.inlineScan(iss); |
0 | 365 } |
366 | |
367 return this; | |
368 } | |
369 | |
72 | 370 override void toIR(IRState* irs) |
0 | 371 { |
372 if (statements) | |
373 { | |
122
c77e9f4f1793
Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
374 foreach(s; statements) |
0 | 375 { |
376 if (s !is null) | |
377 { | |
174 | 378 //writeln(s.classinfo.name); |
0 | 379 s.toIR(irs); |
380 } | |
381 } | |
382 } | |
383 } | |
384 | |
72 | 385 override CompoundStatement isCompoundStatement() { return this; } |
386 } |