Mercurial > projects > ddmd
annotate dmd/TupleExp.d @ 113:3482c73a991b
More cleanup for arrays
author | Eldar Insafutdinov <e.insafutdinov@gmail.com> |
---|---|
date | Tue, 31 Aug 2010 23:57:32 +0100 |
parents | 39648eb578f6 |
children | e28b18c23469 |
rev | line source |
---|---|
72 | 1 module dmd.TupleExp; |
2 | |
3 import dmd.Expression; | |
4 import dmd.TupleDeclaration; | |
5 import dmd.backend.elem; | |
6 import dmd.InterState; | |
7 import dmd.WANT; | |
8 import dmd.Type; | |
9 import dmd.OutBuffer; | |
10 import dmd.Loc; | |
11 import dmd.Scope; | |
12 import dmd.InlineCostState; | |
13 import dmd.IRState; | |
14 import dmd.InlineDoState; | |
15 import dmd.HdrGenState; | |
16 import dmd.InlineScanState; | |
17 import dmd.ArrayTypes; | |
18 import dmd.TypeExp; | |
19 import dmd.TypeTuple; | |
20 import dmd.TOK; | |
21 import dmd.TY; | |
22 import dmd.Dsymbol; | |
23 import dmd.DsymbolExp; | |
24 import dmd.DYNCAST; | |
25 import dmd.expression.Util; | |
26 | |
27 /**************************************** | |
28 * Expand tuples. | |
29 */ | |
30 /+ | |
31 void expandTuples(Expressions exps) | |
32 { | |
33 //printf("expandTuples()\n"); | |
34 if (exps) | |
35 { | |
36 for (size_t i = 0; i < exps.dim; i++) | |
37 { Expression arg = cast(Expression)exps.data[i]; | |
38 if (!arg) | |
39 continue; | |
40 | |
41 // Look for tuple with 0 members | |
42 if (arg.op == TOKtype) | |
43 { TypeExp e = cast(TypeExp)arg; | |
44 if (e.type.toBasetype().ty == Ttuple) | |
45 { TypeTuple tt = cast(TypeTuple)e.type.toBasetype(); | |
46 | |
47 if (!tt.arguments || tt.arguments.dim == 0) | |
48 { | |
49 exps.remove(i); | |
50 if (i == exps.dim) | |
51 return; | |
52 i--; | |
53 continue; | |
54 } | |
55 } | |
56 } | |
57 | |
58 // Inline expand all the tuples | |
59 while (arg.op == TOKtuple) | |
60 { TupleExp te = cast(TupleExp)arg; | |
61 | |
62 exps.remove(i); // remove arg | |
63 exps.insert(i, te.exps); // replace with tuple contents | |
64 if (i == exps.dim) | |
65 return; // empty tuple, no more arguments | |
66 arg = cast(Expression)exps.data[i]; | |
67 } | |
68 } | |
69 } | |
70 } | |
71 +/ | |
72 class TupleExp : Expression | |
73 { | |
74 Expressions exps; | |
75 | |
76 this(Loc loc, Expressions exps) | |
77 { | |
78 super(loc, TOKtuple, TupleExp.sizeof); | |
79 | |
80 this.exps = exps; | |
81 this.type = null; | |
82 } | |
83 | |
84 this(Loc loc, TupleDeclaration tup) | |
85 { | |
86 super(loc, TOKtuple, TupleExp.sizeof); | |
87 exps = new Expressions(); | |
88 type = null; | |
89 | |
90 exps.reserve(tup.objects.dim); | |
113
3482c73a991b
More cleanup for arrays
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
90
diff
changeset
|
91 foreach (o; tup.objects) |
72 | 92 { |
93 if (auto e = cast(Expression)o) | |
94 { | |
95 e = e.syntaxCopy(); | |
84
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
72
diff
changeset
|
96 exps.push(e); |
72 | 97 } |
98 else if (auto s = cast(Dsymbol)o) | |
99 { | |
84
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
72
diff
changeset
|
100 auto e = new DsymbolExp(loc, s); |
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
72
diff
changeset
|
101 exps.push(e); |
72 | 102 } |
103 else if (auto t = cast(Type)o) | |
104 { | |
84
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
72
diff
changeset
|
105 auto e = new TypeExp(loc, t); |
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
72
diff
changeset
|
106 exps.push(e); |
72 | 107 } |
108 else | |
109 { | |
110 error("%s is not an expression", o.toString()); | |
111 } | |
112 } | |
113 } | |
114 | |
115 override Expression syntaxCopy() | |
116 { | |
117 return new TupleExp(loc, arraySyntaxCopy(exps)); | |
118 } | |
119 | |
120 override bool equals(Object o) | |
121 { | |
122 TupleExp ne; | |
123 | |
124 if (this == o) | |
125 return 1; | |
126 if ((cast(Expression)o).op == TOKtuple) | |
127 { | |
90
39648eb578f6
more Expressions work
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
84
diff
changeset
|
128 auto te = cast(TupleExp)o; |
72 | 129 if (exps.dim != te.exps.dim) |
130 return 0; | |
131 for (size_t i = 0; i < exps.dim; i++) | |
90
39648eb578f6
more Expressions work
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
84
diff
changeset
|
132 { auto e1 = exps[i]; |
39648eb578f6
more Expressions work
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
84
diff
changeset
|
133 auto e2 = te.exps[i]; |
72 | 134 |
135 if (!e1.equals(e2)) | |
136 return 0; | |
137 } | |
138 return 1; | |
139 } | |
140 return 0; | |
141 } | |
142 | |
143 override Expression semantic(Scope sc) | |
144 { | |
145 version (LOGSEMANTIC) { | |
146 printf("+TupleExp::semantic(%s)\n", toChars()); | |
147 } | |
148 if (type) | |
149 return this; | |
150 | |
151 // Run semantic() on each argument | |
90
39648eb578f6
more Expressions work
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
84
diff
changeset
|
152 foreach (ref Expression e; exps) |
39648eb578f6
more Expressions work
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
84
diff
changeset
|
153 { |
72 | 154 e = e.semantic(sc); |
155 if (!e.type) | |
156 { error("%s has no value", e.toChars()); | |
157 e.type = Type.terror; | |
158 } | |
159 } | |
160 | |
161 expandTuples(exps); | |
162 if (0 && exps.dim == 1) | |
163 { | |
90
39648eb578f6
more Expressions work
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
84
diff
changeset
|
164 return exps[0]; |
72 | 165 } |
166 type = new TypeTuple(exps); | |
167 type = type.semantic(loc, sc); | |
168 //printf("-TupleExp::semantic(%s)\n", toChars()); | |
169 return this; | |
170 } | |
171 | |
172 override void toCBuffer(OutBuffer buf, HdrGenState* hgs) | |
173 { | |
174 buf.writestring("tuple("); | |
175 argsToCBuffer(buf, exps, hgs); | |
176 buf.writeByte(')'); | |
177 } | |
178 | |
179 override void scanForNestedRef(Scope sc) | |
180 { | |
181 assert(false); | |
182 } | |
183 | |
184 override void checkEscape() | |
185 { | |
90
39648eb578f6
more Expressions work
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
84
diff
changeset
|
186 foreach(e; exps) |
39648eb578f6
more Expressions work
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
84
diff
changeset
|
187 { |
72 | 188 e.checkEscape(); |
189 } | |
190 } | |
191 | |
192 override bool checkSideEffect(int flag) | |
193 { | |
194 bool f = false; | |
195 | |
90
39648eb578f6
more Expressions work
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
84
diff
changeset
|
196 foreach(e; exps) |
39648eb578f6
more Expressions work
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
84
diff
changeset
|
197 { |
72 | 198 f |= e.checkSideEffect(2); |
199 } | |
200 if (flag == 0 && f == 0) | |
201 Expression.checkSideEffect(0); | |
202 return f; | |
203 } | |
204 | |
205 override Expression optimize(int result) | |
206 { | |
90
39648eb578f6
more Expressions work
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
84
diff
changeset
|
207 foreach(ref Expression e; exps) |
72 | 208 { |
209 e = e.optimize(WANTvalue | (result & WANTinterpret)); | |
210 } | |
211 return this; | |
212 } | |
213 | |
214 override Expression interpret(InterState istate) | |
215 { | |
216 assert(false); | |
217 } | |
218 | |
219 override Expression castTo(Scope sc, Type t) | |
220 { | |
221 assert(false); | |
222 } | |
223 | |
224 override elem* toElem(IRState* irs) | |
225 { | |
226 assert(false); | |
227 } | |
228 | |
229 override bool canThrow() | |
230 { | |
231 return arrayExpressionCanThrow(exps); | |
232 } | |
233 | |
234 override int inlineCost(InlineCostState* ics) | |
235 { | |
236 assert(false); | |
237 } | |
238 | |
239 override Expression doInline(InlineDoState ids) | |
240 { | |
241 assert(false); | |
242 } | |
243 | |
244 override Expression inlineScan(InlineScanState* iss) | |
245 { | |
246 assert(false); | |
247 } | |
248 } | |
249 |