Mercurial > projects > ddmd
annotate dmd/ForeachRangeStatement.d @ 178:e3afd1303184
Many small bugs fixed
Made all classes derive from TObject to detect memory leaks (functionality is disabled for now)
Began work on overriding backend memory allocations (to avoid memory leaks)
author | korDen |
---|---|
date | Sun, 17 Oct 2010 07:42:00 +0400 |
parents | 60bb0fe4563e |
children | b0d41ff5e0df |
rev | line source |
---|---|
0 | 1 module dmd.ForeachRangeStatement; |
2 | |
114 | 3 import dmd.common; |
0 | 4 import dmd.Statement; |
5 import dmd.TOK; | |
93
df6d0f967680
implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents:
72
diff
changeset
|
6 import dmd.Token; |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
122
diff
changeset
|
7 import dmd.Parameter; |
0 | 8 import dmd.Expression; |
9 import dmd.Statement; | |
10 import dmd.VarDeclaration; | |
11 import dmd.Scope; | |
12 import dmd.ExpInitializer; | |
13 import dmd.Identifier; | |
14 import dmd.Lexer; | |
15 import dmd.ArrayTypes; | |
16 import dmd.DeclarationStatement; | |
17 import dmd.CompoundDeclarationStatement; | |
18 import dmd.DeclarationExp; | |
19 import dmd.PostExp; | |
20 import dmd.VarExp; | |
21 import dmd.ForStatement; | |
22 import dmd.IntegerExp; | |
23 import dmd.AddAssignExp; | |
24 import dmd.CmpExp; | |
25 import dmd.IRState; | |
26 import dmd.InterState; | |
27 import dmd.OutBuffer; | |
28 import dmd.AddExp; | |
29 import dmd.WANT; | |
30 import dmd.ScopeDsymbol; | |
31 import dmd.HdrGenState; | |
32 import dmd.InlineScanState; | |
33 import dmd.Loc; | |
34 import dmd.BE; | |
35 | |
93
df6d0f967680
implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents:
72
diff
changeset
|
36 version(DMDV2) |
0 | 37 class ForeachRangeStatement : Statement |
38 { | |
39 TOK op; // TOK.TOKforeach or TOK.TOKforeach_reverse | |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
122
diff
changeset
|
40 Parameter arg; // loop index variable |
0 | 41 Expression lwr; |
42 Expression upr; | |
43 Statement body_; | |
44 | |
45 VarDeclaration key = null; | |
46 | |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
122
diff
changeset
|
47 this(Loc loc, TOK op, Parameter arg, Expression lwr, Expression upr, Statement body_) |
0 | 48 { |
178 | 49 register(); |
0 | 50 super(loc); |
51 this.op = op; | |
52 this.arg = arg; | |
53 this.lwr = lwr; | |
54 this.upr = upr; | |
55 this.body_ = body_; | |
56 } | |
57 | |
72 | 58 override Statement syntaxCopy() |
0 | 59 { |
60 ForeachRangeStatement s = new ForeachRangeStatement(loc, op, | |
61 arg.syntaxCopy(), | |
62 lwr.syntaxCopy(), | |
63 upr.syntaxCopy(), | |
64 body_ ? body_.syntaxCopy() : null); | |
65 | |
66 return s; | |
67 } | |
68 | |
72 | 69 override Statement semantic(Scope sc) |
0 | 70 { |
71 //printf("ForeachRangeStatement.semantic() %p\n", this); | |
72 ScopeDsymbol sym; | |
73 Statement s = this; | |
74 | |
75 lwr = lwr.semantic(sc); | |
76 lwr = resolveProperties(sc, lwr); | |
77 lwr = lwr.optimize(WANTvalue); | |
78 if (!lwr.type) | |
79 { | |
80 error("invalid range lower bound %s", lwr.toChars()); | |
81 return this; | |
82 } | |
83 | |
84 upr = upr.semantic(sc); | |
85 upr = resolveProperties(sc, upr); | |
86 upr = upr.optimize(WANTvalue); | |
87 if (!upr.type) | |
88 { | |
89 error("invalid range upper bound %s", upr.toChars()); | |
90 return this; | |
91 } | |
92 | |
93 if (arg.type) | |
94 { | |
95 arg.type = arg.type.semantic(loc, sc); | |
96 lwr = lwr.implicitCastTo(sc, arg.type); | |
97 upr = upr.implicitCastTo(sc, arg.type); | |
98 } | |
99 else | |
100 { | |
101 /* Must infer types from lwr and upr | |
102 */ | |
103 scope AddExp ea = new AddExp(loc, lwr, upr); | |
104 ea.typeCombine(sc); | |
105 arg.type = ea.type.mutableOf(); | |
106 lwr = ea.e1; | |
107 upr = ea.e2; | |
108 } | |
109 static if (true) { | |
110 /* Convert to a for loop: | |
111 * foreach (key; lwr .. upr) => | |
112 * for (auto key = lwr, auto tmp = upr; key < tmp; ++key) | |
113 * | |
114 * foreach_reverse (key; lwr .. upr) => | |
115 * for (auto tmp = lwr, auto key = upr; key-- > tmp;) | |
116 */ | |
117 | |
118 ExpInitializer ie = new ExpInitializer(loc, (op == TOKforeach) ? lwr : upr); | |
119 key = new VarDeclaration(loc, arg.type, arg.ident, ie); | |
120 | |
121 Identifier id = Lexer.uniqueId("__limit"); | |
122 ie = new ExpInitializer(loc, (op == TOKforeach) ? upr : lwr); | |
123 VarDeclaration tmp = new VarDeclaration(loc, arg.type, id, ie); | |
124 | |
122
c77e9f4f1793
Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
125 auto cs = new Statements(); |
0 | 126 // Keep order of evaluation as lwr, then upr |
127 if (op == TOKforeach) | |
128 { | |
122
c77e9f4f1793
Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
129 cs.push(new DeclarationStatement(loc, new DeclarationExp(loc, key))); |
c77e9f4f1793
Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
130 cs.push(new DeclarationStatement(loc, new DeclarationExp(loc, tmp))); |
0 | 131 } |
132 else | |
133 { | |
122
c77e9f4f1793
Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
134 cs.push(new DeclarationStatement(loc, new DeclarationExp(loc, tmp))); |
c77e9f4f1793
Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
135 cs.push(new DeclarationStatement(loc, new DeclarationExp(loc, key))); |
0 | 136 } |
137 Statement forinit = new CompoundDeclarationStatement(loc, cs); | |
138 | |
139 Expression cond; | |
140 if (op == TOKforeach_reverse) | |
141 { // key-- > tmp | |
142 cond = new PostExp(TOKminusminus, loc, new VarExp(loc, key)); | |
143 cond = new CmpExp(TOKgt, loc, cond, new VarExp(loc, tmp)); | |
144 } | |
145 else | |
146 // key < tmp | |
147 cond = new CmpExp(TOKlt, loc, new VarExp(loc, key), new VarExp(loc, tmp)); | |
148 | |
149 Expression increment = null; | |
150 if (op == TOKforeach) | |
151 // key += 1 | |
152 increment = new AddAssignExp(loc, new VarExp(loc, key), new IntegerExp(1)); | |
153 | |
154 ForStatement fs = new ForStatement(loc, forinit, cond, increment, body_); | |
155 s = fs.semantic(sc); | |
156 return s; | |
157 } else { | |
158 if (!arg.type.isscalar()) | |
159 error("%s is not a scalar type", arg.type.toChars()); | |
160 | |
161 sym = new ScopeDsymbol(); | |
162 sym.parent = sc.scopesym; | |
163 sc = sc.push(sym); | |
164 | |
165 sc.noctor++; | |
166 | |
167 key = new VarDeclaration(loc, arg.type, arg.ident, null); | |
168 DeclarationExp de = new DeclarationExp(loc, key); | |
169 de.semantic(sc); | |
170 | |
171 if (key.storage_class) | |
172 error("foreach range: key cannot have storage class"); | |
173 | |
174 sc.sbreak = this; | |
175 sc.scontinue = this; | |
176 body_ = body_.semantic(sc); | |
177 | |
178 sc.noctor--; | |
179 sc.pop(); | |
180 return s; | |
181 } | |
182 } | |
183 | |
93
df6d0f967680
implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents:
72
diff
changeset
|
184 override bool hasBreak() |
0 | 185 { |
93
df6d0f967680
implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents:
72
diff
changeset
|
186 return true; |
df6d0f967680
implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents:
72
diff
changeset
|
187 } |
df6d0f967680
implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents:
72
diff
changeset
|
188 |
df6d0f967680
implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents:
72
diff
changeset
|
189 override bool hasContinue() |
df6d0f967680
implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents:
72
diff
changeset
|
190 { |
df6d0f967680
implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents:
72
diff
changeset
|
191 return true; |
0 | 192 } |
193 | |
93
df6d0f967680
implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents:
72
diff
changeset
|
194 override bool usesEH() |
df6d0f967680
implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents:
72
diff
changeset
|
195 { |
df6d0f967680
implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents:
72
diff
changeset
|
196 assert(false); // from dmd |
df6d0f967680
implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents:
72
diff
changeset
|
197 return body_.usesEH(); |
df6d0f967680
implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents:
72
diff
changeset
|
198 } |
df6d0f967680
implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents:
72
diff
changeset
|
199 |
df6d0f967680
implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents:
72
diff
changeset
|
200 override BE blockExit() |
0 | 201 { |
93
df6d0f967680
implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents:
72
diff
changeset
|
202 assert(false); // from dmd |
df6d0f967680
implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents:
72
diff
changeset
|
203 BE result = BE.BEfallthru; |
df6d0f967680
implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents:
72
diff
changeset
|
204 |
df6d0f967680
implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents:
72
diff
changeset
|
205 if (lwr && lwr.canThrow()) |
df6d0f967680
implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents:
72
diff
changeset
|
206 result |= BE.BEthrow; |
df6d0f967680
implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents:
72
diff
changeset
|
207 else if (upr && upr.canThrow()) |
df6d0f967680
implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents:
72
diff
changeset
|
208 result |= BE.BEthrow; |
df6d0f967680
implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents:
72
diff
changeset
|
209 |
df6d0f967680
implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents:
72
diff
changeset
|
210 if (body_) |
df6d0f967680
implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents:
72
diff
changeset
|
211 { |
df6d0f967680
implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents:
72
diff
changeset
|
212 result |= body_.blockExit() & ~(BE.BEbreak | BE.BEcontinue); |
df6d0f967680
implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents:
72
diff
changeset
|
213 } |
df6d0f967680
implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents:
72
diff
changeset
|
214 return result; |
df6d0f967680
implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents:
72
diff
changeset
|
215 } |
df6d0f967680
implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents:
72
diff
changeset
|
216 |
df6d0f967680
implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents:
72
diff
changeset
|
217 override bool comeFrom() |
df6d0f967680
implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents:
72
diff
changeset
|
218 { |
df6d0f967680
implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents:
72
diff
changeset
|
219 assert(false); // from dmd |
df6d0f967680
implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents:
72
diff
changeset
|
220 if (body_) |
df6d0f967680
implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents:
72
diff
changeset
|
221 return body_.comeFrom(); |
df6d0f967680
implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents:
72
diff
changeset
|
222 return false; |
0 | 223 } |
224 | |
93
df6d0f967680
implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents:
72
diff
changeset
|
225 override Expression interpret(InterState istate) |
0 | 226 { |
227 assert(false); | |
228 } | |
229 | |
93
df6d0f967680
implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents:
72
diff
changeset
|
230 override void toCBuffer(OutBuffer buf, HdrGenState* hgs) |
0 | 231 { |
93
df6d0f967680
implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents:
72
diff
changeset
|
232 buf.writestring(Token.toChars(op)); |
df6d0f967680
implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents:
72
diff
changeset
|
233 buf.writestring(" ("); |
df6d0f967680
implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents:
72
diff
changeset
|
234 |
df6d0f967680
implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents:
72
diff
changeset
|
235 if (arg.type) |
df6d0f967680
implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents:
72
diff
changeset
|
236 arg.type.toCBuffer(buf, arg.ident, hgs); |
df6d0f967680
implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents:
72
diff
changeset
|
237 else |
df6d0f967680
implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents:
72
diff
changeset
|
238 buf.writestring(arg.ident.toChars()); |
df6d0f967680
implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents:
72
diff
changeset
|
239 |
df6d0f967680
implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents:
72
diff
changeset
|
240 buf.writestring("; "); |
df6d0f967680
implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents:
72
diff
changeset
|
241 lwr.toCBuffer(buf, hgs); |
df6d0f967680
implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents:
72
diff
changeset
|
242 buf.writestring(" .. "); |
df6d0f967680
implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents:
72
diff
changeset
|
243 upr.toCBuffer(buf, hgs); |
df6d0f967680
implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents:
72
diff
changeset
|
244 buf.writebyte(')'); |
df6d0f967680
implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents:
72
diff
changeset
|
245 buf.writenl(); |
df6d0f967680
implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents:
72
diff
changeset
|
246 buf.writebyte('{'); |
df6d0f967680
implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents:
72
diff
changeset
|
247 buf.writenl(); |
df6d0f967680
implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents:
72
diff
changeset
|
248 if (body_) |
df6d0f967680
implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents:
72
diff
changeset
|
249 body_.toCBuffer(buf, hgs); |
df6d0f967680
implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents:
72
diff
changeset
|
250 buf.writebyte('}'); |
df6d0f967680
implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents:
72
diff
changeset
|
251 buf.writenl(); |
0 | 252 } |
253 | |
93
df6d0f967680
implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents:
72
diff
changeset
|
254 override Statement inlineScan(InlineScanState* iss) |
0 | 255 { |
93
df6d0f967680
implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents:
72
diff
changeset
|
256 lwr = lwr.inlineScan(iss); |
df6d0f967680
implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents:
72
diff
changeset
|
257 upr = upr.inlineScan(iss); |
df6d0f967680
implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents:
72
diff
changeset
|
258 if (body_) |
df6d0f967680
implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents:
72
diff
changeset
|
259 body_ = body_.inlineScan(iss); |
df6d0f967680
implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents:
72
diff
changeset
|
260 return this; |
0 | 261 } |
262 | |
72 | 263 override void toIR(IRState* irs) |
0 | 264 { |
265 assert(false); | |
266 } | |
72 | 267 } |