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