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