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