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