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