Mercurial > projects > ddmd
annotate dmd/DoStatement.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.DoStatement; |
2 | |
114 | 3 import dmd.common; |
0 | 4 import dmd.Statement; |
5 import dmd.Expression; | |
6 import dmd.Loc; | |
7 import dmd.Scope; | |
8 import dmd.InterState; | |
155 | 9 import dmd.GlobalExpressions; |
0 | 10 import dmd.HdrGenState; |
11 import dmd.OutBuffer; | |
12 import dmd.InlineScanState; | |
13 import dmd.IRState; | |
14 import dmd.BE; | |
15 import dmd.WANT; | |
16 | |
17 import dmd.backend.block; | |
18 import dmd.backend.Blockx; | |
19 import dmd.backend.Util; | |
20 import dmd.backend.BC; | |
21 | |
187
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
22 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
|
23 |
0 | 24 class DoStatement : Statement |
25 { | |
187
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
26 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
|
27 |
0 | 28 Statement body_; |
29 Expression condition; | |
30 | |
31 this(Loc loc, Statement b, Expression c) | |
32 { | |
178 | 33 register(); |
0 | 34 super(loc); |
35 body_ = b; | |
36 condition = c; | |
37 } | |
38 | |
72 | 39 override Statement syntaxCopy() |
0 | 40 { |
41 DoStatement s = new DoStatement(loc, body_ ? body_.syntaxCopy() : null, condition.syntaxCopy()); | |
42 return s; | |
43 } | |
44 | |
72 | 45 override Statement semantic(Scope sc) |
0 | 46 { |
47 sc.noctor++; | |
48 if (body_) | |
49 body_ = body_.semanticScope(sc, this, this); | |
50 sc.noctor--; | |
51 condition = condition.semantic(sc); | |
52 condition = resolveProperties(sc, condition); | |
53 condition = condition.optimize(WANTvalue); | |
54 | |
55 condition = condition.checkToBoolean(); | |
56 | |
57 return this; | |
58 } | |
59 | |
72 | 60 override bool hasBreak() |
0 | 61 { |
62 return true; | |
63 } | |
64 | |
72 | 65 override bool hasContinue() |
0 | 66 { |
67 return true; | |
68 } | |
69 | |
72 | 70 override bool usesEH() |
0 | 71 { |
72 return body_ ? body_.usesEH() : false; | |
73 } | |
74 | |
72 | 75 override BE blockExit() |
0 | 76 { |
77 BE result; | |
78 | |
79 if (body_) | |
80 { | |
81 result = body_.blockExit(); | |
82 if (result == BE.BEbreak) | |
83 return BE.BEfallthru; | |
84 if (result & BE.BEcontinue) | |
85 result |= BE.BEfallthru; | |
86 } | |
87 else | |
88 result = BE.BEfallthru; | |
89 | |
90 if (result & BE.BEfallthru) | |
91 { | |
92 if (condition.canThrow()) | |
93 result |= BE.BEthrow; | |
94 if (!(result & BE.BEbreak) && condition.isBool(true)) | |
95 result &= ~BE.BEfallthru; | |
96 } | |
97 result &= ~(BE.BEbreak | BE.BEcontinue); | |
98 | |
99 return result; | |
100 } | |
101 | |
72 | 102 override bool comeFrom() |
0 | 103 { |
104 assert(false); | |
105 } | |
106 | |
72 | 107 override Expression interpret(InterState istate) |
0 | 108 { |
155 | 109 version(LOG) |
110 writef("DoStatement::interpret()\n"); | |
111 | |
112 if (istate.start == this) | |
113 istate.start = null; | |
114 Expression e; | |
115 | |
116 if (istate.start) | |
117 { | |
118 e = body_ ? body_.interpret(istate) : null; | |
119 if (istate.start) | |
120 return null; | |
121 if (e is EXP_CANT_INTERPRET) | |
122 return e; | |
123 if (e is EXP_BREAK_INTERPRET) | |
124 return null; | |
125 if (e is EXP_CONTINUE_INTERPRET) | |
126 goto Lcontinue; | |
127 if (e) | |
128 return e; | |
129 } | |
130 | |
131 while (1) | |
132 { | |
133 e = body_ ? body_.interpret(istate) : null; | |
134 if (e is EXP_CANT_INTERPRET) | |
135 break; | |
136 if (e is EXP_BREAK_INTERPRET) | |
137 { | |
138 e = null; | |
139 break; | |
140 } | |
141 if (e && e !is EXP_CONTINUE_INTERPRET) | |
142 break; | |
143 | |
144 Lcontinue: | |
145 e = condition.interpret(istate); | |
146 if (e is EXP_CANT_INTERPRET) | |
147 break; | |
148 if (!e.isConst()) | |
149 { | |
150 e = EXP_CANT_INTERPRET; | |
151 break; | |
152 } | |
153 if (e.isBool(true)) | |
154 { | |
155 } | |
156 else if (e.isBool(false)) | |
157 { | |
158 e = null; | |
159 break; | |
160 } | |
161 else | |
162 assert(0); | |
163 } | |
164 return e; | |
0 | 165 } |
166 | |
72 | 167 override void toCBuffer(OutBuffer buf, HdrGenState* hgs) |
0 | 168 { |
174 | 169 buf.writestring("do"); |
170 buf.writenl(); | |
171 if (body_) | |
172 body_.toCBuffer(buf, hgs); | |
173 buf.writestring("while ("); | |
174 condition.toCBuffer(buf, hgs); | |
175 buf.writebyte(')'); | |
0 | 176 } |
177 | |
72 | 178 override Statement inlineScan(InlineScanState* iss) |
0 | 179 { |
180 body_ = body_ ? body_.inlineScan(iss) : null; | |
181 condition = condition.inlineScan(iss); | |
182 return this; | |
183 } | |
184 | |
72 | 185 override void toIR(IRState* irs) |
0 | 186 { |
187 Blockx *blx = irs.blx; | |
188 | |
189 IRState mystate = IRState(irs,this); | |
190 mystate.breakBlock = block_calloc(blx); | |
191 mystate.contBlock = block_calloc(blx); | |
192 | |
193 block* bpre = blx.curblock; | |
194 block_next(blx, BCgoto, null); | |
195 list_append(&bpre.Bsucc, blx.curblock); | |
196 | |
197 list_append(&mystate.contBlock.Bsucc, blx.curblock); | |
198 list_append(&mystate.contBlock.Bsucc, mystate.breakBlock); | |
199 | |
200 if (body_) | |
201 body_.toIR(&mystate); | |
202 list_append(&blx.curblock.Bsucc, mystate.contBlock); | |
203 | |
204 block_next(blx, BCgoto, mystate.contBlock); | |
205 incUsage(irs, condition.loc); | |
206 block_appendexp(mystate.contBlock, condition.toElem(&mystate)); | |
207 block_next(blx, BCiftrue, mystate.breakBlock); | |
208 } | |
72 | 209 } |