Mercurial > projects > ddmd
annotate dmd/IsExp.d @ 113:3482c73a991b
More cleanup for arrays
author | Eldar Insafutdinov <e.insafutdinov@gmail.com> |
---|---|
date | Tue, 31 Aug 2010 23:57:32 +0100 |
parents | 12c0c84d13fd |
children | e28b18c23469 |
rev | line source |
---|---|
72 | 1 module dmd.IsExp; |
2 | |
3 import dmd.Expression; | |
4 import dmd.Identifier; | |
5 import dmd.ArrayTypes; | |
6 import dmd.Type; | |
7 import dmd.TOK; | |
8 import dmd.OutBuffer; | |
9 import dmd.Loc; | |
10 import dmd.Scope; | |
0 | 11 import dmd.HdrGenState; |
12 import dmd.TY; | |
13 import dmd.TypeEnum; | |
14 import dmd.STC; | |
15 import dmd.TypeClass; | |
16 import dmd.TemplateParameter; | |
17 import dmd.BaseClass; | |
18 import dmd.ClassDeclaration; | |
19 import dmd.TypeStruct; | |
20 import dmd.TypeTypedef; | |
21 import dmd.IntegerExp; | |
22 import dmd.AliasDeclaration; | |
23 import dmd.Dsymbol; | |
24 import dmd.TypeTuple; | |
25 import dmd.TypeDelegate; | |
26 import dmd.Declaration; | |
27 import dmd.TypeFunction; | |
28 import dmd.MATCH; | |
29 import dmd.TypePointer; | |
72 | 30 import dmd.Argument; |
31 import dmd.Token; | |
32 | |
0 | 33 class IsExp : Expression |
34 { | |
35 /* is(targ id tok tspec) | |
36 * is(targ id == tok2) | |
37 */ | |
38 Type targ; | |
39 Identifier id; // can be null | |
40 TOK tok; // ':' or '==' | |
41 Type tspec; // can be null | |
42 TOK tok2; // 'struct', 'union', 'typedef', etc. | |
43 TemplateParameters parameters; | |
44 | |
45 this(Loc loc, Type targ, Identifier id, TOK tok, Type tspec, TOK tok2, TemplateParameters parameters) | |
46 { | |
47 super(loc, TOK.TOKis, IsExp.sizeof); | |
48 | |
49 this.targ = targ; | |
50 this.id = id; | |
51 this.tok = tok; | |
52 this.tspec = tspec; | |
53 this.tok2 = tok2; | |
54 this.parameters = parameters; | |
55 } | |
56 | |
72 | 57 override Expression syntaxCopy() |
0 | 58 { |
72 | 59 // This section is identical to that in TemplateDeclaration.syntaxCopy() |
60 TemplateParameters p = null; | |
61 if (parameters) | |
62 { | |
63 p = new TemplateParameters(); | |
64 p.setDim(parameters.dim); | |
65 for (int i = 0; i < p.dim; i++) | |
66 { | |
67 TemplateParameter tp = cast(TemplateParameter)parameters.data[i]; | |
68 p.data[i] = cast(void*)tp.syntaxCopy(); | |
69 } | |
70 } | |
71 | |
72 return new IsExp(loc, | |
73 targ.syntaxCopy(), | |
74 id, | |
75 tok, | |
76 tspec ? tspec.syntaxCopy() : null, | |
77 tok2, | |
42 | 78 p); |
0 | 79 } |
80 | |
72 | 81 override Expression semantic(Scope sc) |
0 | 82 { |
83 Type tded; | |
84 | |
85 /* is(targ id tok tspec) | |
109 | 86 * is(targ id : tok2) |
0 | 87 * is(targ id == tok2) |
88 */ | |
89 | |
90 //printf("IsExp.semantic(%s)\n", toChars()); | |
91 if (id && !(sc.flags & SCOPE.SCOPEstaticif)) | |
92 error("can only declare type aliases within static if conditionals"); | |
93 | |
94 Type t = targ.trySemantic(loc, sc); | |
95 if (!t) | |
96 goto Lno; // errors, so condition is false | |
97 targ = t; | |
98 if (tok2 != TOK.TOKreserved) | |
99 { | |
100 switch (tok2) | |
101 { | |
102 case TOKtypedef: | |
103 if (targ.ty != Ttypedef) | |
104 goto Lno; | |
105 tded = (cast(TypeTypedef)targ).sym.basetype; | |
106 break; | |
107 | |
108 case TOKstruct: | |
109 if (targ.ty != Tstruct) | |
110 goto Lno; | |
111 if ((cast(TypeStruct)targ).sym.isUnionDeclaration()) | |
112 goto Lno; | |
113 tded = targ; | |
114 break; | |
115 | |
116 case TOKunion: | |
117 if (targ.ty != Tstruct) | |
118 goto Lno; | |
119 if (!(cast(TypeStruct)targ).sym.isUnionDeclaration()) | |
120 goto Lno; | |
121 tded = targ; | |
122 break; | |
123 | |
124 case TOKclass: | |
125 if (targ.ty != Tclass) | |
126 goto Lno; | |
127 if ((cast(TypeClass)targ).sym.isInterfaceDeclaration()) | |
128 goto Lno; | |
129 tded = targ; | |
130 break; | |
131 | |
132 case TOKinterface: | |
133 if (targ.ty != Tclass) | |
134 goto Lno; | |
135 if (!(cast(TypeClass)targ).sym.isInterfaceDeclaration()) | |
136 goto Lno; | |
137 tded = targ; | |
138 break; | |
139 version (DMDV2) { | |
140 case TOKconst: | |
141 if (!targ.isConst()) | |
142 goto Lno; | |
143 tded = targ; | |
144 break; | |
145 | |
146 case TOKinvariant: | |
147 case TOKimmutable: | |
148 if (!targ.isInvariant()) | |
149 goto Lno; | |
150 tded = targ; | |
151 break; | |
152 | |
153 case TOKshared: | |
154 if (!targ.isShared()) | |
155 goto Lno; | |
156 tded = targ; | |
157 break; | |
158 } | |
159 | |
160 case TOKsuper: | |
161 // If class or interface, get the base class and interfaces | |
162 if (targ.ty != Tclass) | |
163 goto Lno; | |
164 else | |
165 { ClassDeclaration cd = (cast(TypeClass)targ).sym; | |
166 Arguments args = new Arguments; | |
167 args.reserve(cd.baseclasses.dim); | |
168 for (size_t i = 0; i < cd.baseclasses.dim; i++) | |
169 { | |
170 BaseClass b = cast(BaseClass)cd.baseclasses.data[i]; | |
171 args.push(cast(void*)new Argument(STCin, b.type, null, null)); | |
172 } | |
173 tded = new TypeTuple(args); | |
174 } | |
175 break; | |
176 | |
177 case TOKenum: | |
178 if (targ.ty != Tenum) | |
179 goto Lno; | |
180 tded = (cast(TypeEnum)targ).sym.memtype; | |
181 break; | |
182 | |
183 case TOKdelegate: | |
184 if (targ.ty != Tdelegate) | |
185 goto Lno; | |
186 tded = (cast(TypeDelegate)targ).next; // the underlying function type | |
187 break; | |
188 | |
189 case TOKfunction: | |
190 { | |
191 if (targ.ty != Tfunction) | |
192 goto Lno; | |
193 tded = targ; | |
194 | |
195 /* Generate tuple from function parameter types. | |
196 */ | |
197 assert(tded.ty == Tfunction); | |
198 Arguments params = (cast(TypeFunction)tded).parameters; | |
199 size_t dim = Argument.dim(params); | |
200 Arguments args = new Arguments; | |
201 args.reserve(dim); | |
202 for (size_t i = 0; i < dim; i++) | |
203 { | |
204 Argument arg = Argument.getNth(params, i); | |
205 assert(arg && arg.type); | |
206 args.push(cast(void*)new Argument(arg.storageClass, arg.type, null, null)); | |
207 } | |
208 tded = new TypeTuple(args); | |
209 break; | |
210 } | |
211 | |
212 case TOKreturn: | |
213 /* Get the 'return type' for the function, | |
214 * delegate, or pointer to function. | |
215 */ | |
216 if (targ.ty == Tfunction) | |
217 tded = (cast(TypeFunction)targ).next; | |
218 else if (targ.ty == Tdelegate) | |
219 { tded = (cast(TypeDelegate)targ).next; | |
220 tded = (cast(TypeFunction)tded).next; | |
221 } | |
222 else if (targ.ty == Tpointer && | |
223 (cast(TypePointer)targ).next.ty == Tfunction) | |
224 { tded = (cast(TypePointer)targ).next; | |
225 tded = (cast(TypeFunction)tded).next; | |
226 } | |
227 else | |
228 goto Lno; | |
229 break; | |
230 | |
231 default: | |
232 assert(0); | |
233 } | |
234 goto Lyes; | |
235 } | |
236 else if (id && tspec) | |
237 { | |
238 /* Evaluate to true if targ matches tspec. | |
239 * If true, declare id as an alias for the specialized type. | |
240 */ | |
241 | |
242 assert(parameters && parameters.dim); | |
243 | |
94
3a0b150c9841
Objects -> Vector!Object iteration 1
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
72
diff
changeset
|
244 scope dedtypes = new Objects(); |
0 | 245 dedtypes.setDim(parameters.dim); |
246 dedtypes.zero(); | |
247 | |
109 | 248 MATCH m = targ.deduceType(null, tspec, parameters, dedtypes); |
0 | 249 if (m == MATCHnomatch || |
250 (m != MATCHexact && tok == TOKequal)) | |
251 { | |
252 goto Lno; | |
253 } | |
254 else | |
255 { | |
113
3482c73a991b
More cleanup for arrays
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
110
diff
changeset
|
256 tded = cast(Type)dedtypes[0]; |
0 | 257 if (!tded) |
258 tded = targ; | |
259 | |
260 scope Objects tiargs = new Objects(); | |
261 tiargs.setDim(1); | |
94
3a0b150c9841
Objects -> Vector!Object iteration 1
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
72
diff
changeset
|
262 tiargs[0] = targ; |
0 | 263 |
264 /* Declare trailing parameters | |
265 */ | |
266 for (int i = 1; i < parameters.dim; i++) | |
267 { | |
268 TemplateParameter tp = cast(TemplateParameter)parameters.data[i]; | |
269 Declaration s = null; | |
270 | |
271 m = tp.matchArg(sc, tiargs, i, parameters, dedtypes, &s); | |
272 if (m == MATCHnomatch) | |
273 goto Lno; | |
274 s.semantic(sc); | |
275 if (!sc.insert(s)) | |
276 error("declaration %s is already defined", s.toChars()); | |
277 static if (false) { | |
278 Object o = cast(Object)dedtypes.data[i]; | |
279 Dsymbol s = TemplateDeclaration.declareParameter(loc, sc, tp, o); | |
280 } | |
281 if (sc.sd) | |
13 | 282 s.addMember(sc, sc.sd, true); |
0 | 283 } |
284 | |
285 goto Lyes; | |
286 } | |
287 } | |
288 else if (id) | |
289 { | |
290 /* Declare id as an alias for type targ. Evaluate to true | |
291 */ | |
292 tded = targ; | |
293 goto Lyes; | |
294 } | |
295 else if (tspec) | |
296 { | |
297 /* Evaluate to true if targ matches tspec | |
298 * is(targ == tspec) | |
299 * is(targ : tspec) | |
300 */ | |
301 tspec = tspec.semantic(loc, sc); | |
302 //printf("targ = %s\n", targ.toChars()); | |
303 //printf("tspec = %s\n", tspec.toChars()); | |
304 if (tok == TOKcolon) | |
305 { | |
306 if (targ.implicitConvTo(tspec)) | |
307 goto Lyes; | |
308 else | |
309 goto Lno; | |
310 } | |
311 else /* == */ | |
312 { | |
313 if (targ.equals(tspec)) | |
314 goto Lyes; | |
315 else | |
316 goto Lno; | |
317 } | |
318 } | |
319 | |
320 Lyes: | |
321 if (id) | |
322 { | |
323 Dsymbol s = new AliasDeclaration(loc, id, tded); | |
324 s.semantic(sc); | |
325 if (!sc.insert(s)) | |
326 error("declaration %s is already defined", s.toChars()); | |
327 if (sc.sd) | |
13 | 328 s.addMember(sc, sc.sd, true); |
0 | 329 } |
330 //printf("Lyes\n"); | |
331 return new IntegerExp(loc, 1, Type.tbool); | |
332 | |
333 Lno: | |
334 //printf("Lno\n"); | |
335 return new IntegerExp(loc, 0, Type.tbool); | |
336 } | |
337 | |
72 | 338 override void toCBuffer(OutBuffer buf, HdrGenState* hgs) |
0 | 339 { |
72 | 340 buf.writestring("is("); |
341 targ.toCBuffer(buf, id, hgs); | |
342 if (tok2 != TOKreserved) | |
343 { | |
344 buf.printf(" %s %s", Token.toChars(tok), Token.toChars(tok2)); | |
345 } | |
346 else if (tspec) | |
347 { | |
348 if (tok == TOKcolon) | |
349 buf.writestring(" : "); | |
350 else | |
351 buf.writestring(" == "); | |
352 tspec.toCBuffer(buf, null, hgs); | |
353 } | |
354 version (DMDV2) { | |
355 if (parameters) | |
356 { | |
357 // First parameter is already output, so start with second | |
358 for (int i = 1; i < parameters.dim; i++) | |
359 { | |
360 buf.writeByte(','); | |
361 TemplateParameter tp = cast(TemplateParameter)parameters.data[i]; | |
362 tp.toCBuffer(buf, hgs); | |
363 } | |
364 } | |
365 } | |
50 | 366 buf.writeByte(')'); |
0 | 367 } |
368 } | |
369 |