Mercurial > projects > ddmd
comparison dmd/CompoundStatement.d @ 0:10317f0c89a5
Initial commit
author | korDen |
---|---|
date | Sat, 24 Oct 2009 08:42:06 +0400 |
parents | |
children | 3f834bed4f13 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:10317f0c89a5 |
---|---|
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 | |
49 Statement syntaxCopy() | |
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 | |
65 void toCBuffer(OutBuffer buf, HdrGenState* hgs) | |
66 { | |
67 assert(false); | |
68 } | |
69 | |
70 static int indent = 0; | |
71 static int depth = 0; | |
72 | |
73 Statement semantic(Scope sc) | |
74 { | |
75 Statement s; | |
76 | |
77 //printf("CompoundStatement.semantic(this = %p, sc = %p)\n", this, sc); | |
78 | |
79 for (size_t i = 0; i < statements.dim; ) | |
80 { | |
81 s = cast(Statement) statements.data[i]; | |
82 if (s) | |
83 { | |
84 Statements a = s.flatten(sc); | |
85 | |
86 if (a) | |
87 { | |
88 statements.remove(i); | |
89 statements.insert(i, a); | |
90 continue; | |
91 } | |
92 | |
93 s = s.semantic(sc); | |
94 | |
95 statements.data[i] = cast(void*)s; | |
96 if (s) | |
97 { | |
98 Statement sentry; | |
99 Statement sexception; | |
100 Statement sfinally; | |
101 | |
102 s.scopeCode(sc, &sentry, &sexception, &sfinally); | |
103 if (sentry) | |
104 { | |
105 sentry = sentry.semantic(sc); | |
106 if (s.isDeclarationStatement()) | |
107 { | |
108 statements.insert(i, cast(void*)sentry); | |
109 i++; | |
110 } | |
111 else | |
112 statements.data[i] = cast(void*)sentry; | |
113 } | |
114 if (sexception) | |
115 { | |
116 if (i + 1 == statements.dim && !sfinally) | |
117 { | |
118 static if (true) { | |
119 sexception = sexception.semantic(sc); | |
120 } else { | |
121 statements.push(sexception); | |
122 if (sfinally) | |
123 // Assume sexception does not throw | |
124 statements.push(sfinally); | |
125 } | |
126 } | |
127 else | |
128 { | |
129 /* Rewrite: | |
130 * s; s1; s2; | |
131 * As: | |
132 * s; | |
133 * try { s1; s2; } | |
134 * catch (Object __o) | |
135 * { sexception; throw __o; } | |
136 */ | |
137 Statement body_; | |
138 Statements aa = new Statements(); | |
139 | |
140 for (int j = i + 1; j < statements.dim; j++) | |
141 { | |
142 aa.push(statements.data[j]); | |
143 } | |
144 body_ = new CompoundStatement(Loc(0), aa); | |
145 body_ = new ScopeStatement(Loc(0), body_); | |
146 | |
147 Identifier id = Lexer.uniqueId("__o"); | |
148 | |
149 Statement handler = new ThrowStatement(Loc(0), new IdentifierExp(Loc(0), id)); | |
150 handler = new CompoundStatement(Loc(0), sexception, handler); | |
151 | |
152 Array catches = new Array(); | |
153 Catch ctch = new Catch(Loc(0), null, id, handler); | |
154 catches.push(cast(void*)ctch); | |
155 s = new TryCatchStatement(Loc(0), body_, catches); | |
156 | |
157 if (sfinally) | |
158 s = new TryFinallyStatement(Loc(0), s, sfinally); | |
159 s = s.semantic(sc); | |
160 statements.setDim(i + 1); | |
161 statements.push(cast(void*)s); | |
162 break; | |
163 } | |
164 } | |
165 else if (sfinally) | |
166 { | |
167 if (0 && i + 1 == statements.dim) | |
168 { | |
169 statements.push(cast(void*)sfinally); | |
170 } | |
171 else | |
172 { | |
173 /* Rewrite: | |
174 * s; s1; s2; | |
175 * As: | |
176 * s; try { s1; s2; } finally { sfinally; } | |
177 */ | |
178 Statement body_; | |
179 Statements aa = new Statements(); | |
180 | |
181 for (int j = i + 1; j < statements.dim; j++) | |
182 { | |
183 aa.push(statements.data[j]); | |
184 } | |
185 body_ = new CompoundStatement(Loc(0), aa); | |
186 s = new TryFinallyStatement(Loc(0), body_, sfinally); | |
187 s = s.semantic(sc); | |
188 statements.setDim(i + 1); | |
189 statements.push(cast(void*)s); | |
190 break; | |
191 } | |
192 } | |
193 } | |
194 } | |
195 i++; | |
196 } | |
197 if (statements.dim == 1) | |
198 { | |
199 return cast(Statement)statements.data[0]; | |
200 } | |
201 return this; | |
202 } | |
203 | |
204 bool usesEH() | |
205 { | |
206 assert(false); | |
207 } | |
208 | |
209 BE blockExit() | |
210 { | |
211 //printf("CompoundStatement::blockExit(%p) %d\n", this, statements->dim); | |
212 BE result = BE.BEfallthru; | |
213 for (size_t i = 0; i < statements.dim; i++) | |
214 { Statement s = cast(Statement)statements.data[i]; | |
215 if (s) | |
216 { | |
217 //printf("result = x%x\n", result); | |
218 //printf("%s\n", s->toChars()); | |
219 if (!(result & BE.BEfallthru) && !s.comeFrom()) | |
220 { | |
221 if (s.blockExit() != BE.BEhalt) | |
222 s.warning("statement is not reachable"); | |
223 } | |
224 | |
225 result &= ~BE.BEfallthru; | |
226 result |= s.blockExit(); | |
227 } | |
228 } | |
229 | |
230 return result; | |
231 } | |
232 | |
233 bool comeFrom() | |
234 { | |
235 assert(false); | |
236 } | |
237 | |
238 bool isEmpty() | |
239 { | |
240 for (int i = 0; i < statements.dim; i++) | |
241 { | |
242 Statement s = cast(Statement) statements.data[i]; | |
243 if (s && !s.isEmpty()) | |
244 return false; | |
245 } | |
246 return true; | |
247 } | |
248 | |
249 Statements flatten(Scope sc) | |
250 { | |
251 return statements; | |
252 } | |
253 | |
254 ReturnStatement isReturnStatement() | |
255 { | |
256 ReturnStatement rs = null; | |
257 | |
258 for (int i = 0; i < statements.dim; i++) | |
259 { | |
260 Statement s = cast(Statement) statements.data[i]; | |
261 if (s) | |
262 { | |
263 rs = s.isReturnStatement(); | |
264 if (rs) | |
265 break; | |
266 } | |
267 } | |
268 return rs; | |
269 } | |
270 | |
271 Expression interpret(InterState* istate) | |
272 { | |
273 assert(false); | |
274 } | |
275 | |
276 int inlineCost(InlineCostState* ics) | |
277 { | |
278 int cost = 0; | |
279 | |
280 for (size_t i = 0; i < statements.dim; i++) | |
281 { | |
282 Statement s = cast(Statement)statements.data[i]; | |
283 if (s) | |
284 { | |
285 cost += s.inlineCost(ics); | |
286 if (cost >= COST_MAX) | |
287 break; | |
288 } | |
289 } | |
290 | |
291 return cost; | |
292 } | |
293 | |
294 Expression doInline(InlineDoState ids) | |
295 { | |
296 Expression e = null; | |
297 | |
298 //printf("CompoundStatement.doInline() %d\n", statements.dim); | |
299 for (size_t i = 0; i < statements.dim; i++) | |
300 { | |
301 Statement s = cast(Statement)statements.data[i]; | |
302 if (s) | |
303 { | |
304 Expression e2 = s.doInline(ids); | |
305 e = Expression.combine(e, e2); | |
306 if (s.isReturnStatement()) | |
307 break; | |
308 | |
309 /* Check for: | |
310 * if (condition) | |
311 * return exp1; | |
312 * else | |
313 * return exp2; | |
314 */ | |
315 IfStatement ifs = s.isIfStatement(); | |
316 if (ifs && ifs.elsebody && ifs.ifbody && | |
317 ifs.ifbody.isReturnStatement() && | |
318 ifs.elsebody.isReturnStatement() | |
319 ) | |
320 break; | |
321 } | |
322 } | |
323 return e; | |
324 } | |
325 | |
326 Statement inlineScan(InlineScanState* iss) | |
327 { | |
328 for (size_t i = 0; i < statements.dim; i++) | |
329 { | |
330 Statement s = cast(Statement) statements.data[i]; | |
331 if (s) | |
332 statements.data[i] = cast(void*)s.inlineScan(iss); | |
333 } | |
334 | |
335 return this; | |
336 } | |
337 | |
338 void toIR(IRState* irs) | |
339 { | |
340 if (statements) | |
341 { | |
342 size_t dim = statements.dim; | |
343 for (size_t i = 0 ; i < dim ; i++) | |
344 { | |
345 Statement s = cast(Statement)statements.data[i]; | |
346 if (s !is null) | |
347 { | |
348 s.toIR(irs); | |
349 } | |
350 } | |
351 } | |
352 } | |
353 | |
354 CompoundStatement isCompoundStatement() { return this; } | |
355 } |