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