Mercurial > projects > ddmd
comparison dmd/IsExp.d @ 0:10317f0c89a5
Initial commit
author | korDen |
---|---|
date | Sat, 24 Oct 2009 08:42:06 +0400 |
parents | |
children | 427f8aa74d28 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:10317f0c89a5 |
---|---|
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; | |
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; | |
30 import dmd.Argument; | |
31 | |
32 class IsExp : Expression | |
33 { | |
34 /* is(targ id tok tspec) | |
35 * is(targ id == tok2) | |
36 */ | |
37 Type targ; | |
38 Identifier id; // can be null | |
39 TOK tok; // ':' or '==' | |
40 Type tspec; // can be null | |
41 TOK tok2; // 'struct', 'union', 'typedef', etc. | |
42 TemplateParameters parameters; | |
43 | |
44 this(Loc loc, Type targ, Identifier id, TOK tok, Type tspec, TOK tok2, TemplateParameters parameters) | |
45 { | |
46 super(loc, TOK.TOKis, IsExp.sizeof); | |
47 | |
48 this.targ = targ; | |
49 this.id = id; | |
50 this.tok = tok; | |
51 this.tspec = tspec; | |
52 this.tok2 = tok2; | |
53 this.parameters = parameters; | |
54 } | |
55 | |
56 Expression syntaxCopy() | |
57 { | |
58 assert(false); | |
59 } | |
60 | |
61 Expression semantic(Scope sc) | |
62 { | |
63 Type tded; | |
64 | |
65 /* is(targ id tok tspec) | |
66 * is(targ id == tok2) | |
67 */ | |
68 | |
69 //printf("IsExp.semantic(%s)\n", toChars()); | |
70 if (id && !(sc.flags & SCOPE.SCOPEstaticif)) | |
71 error("can only declare type aliases within static if conditionals"); | |
72 | |
73 Type t = targ.trySemantic(loc, sc); | |
74 if (!t) | |
75 goto Lno; // errors, so condition is false | |
76 targ = t; | |
77 if (tok2 != TOK.TOKreserved) | |
78 { | |
79 switch (tok2) | |
80 { | |
81 case TOKtypedef: | |
82 if (targ.ty != Ttypedef) | |
83 goto Lno; | |
84 tded = (cast(TypeTypedef)targ).sym.basetype; | |
85 break; | |
86 | |
87 case TOKstruct: | |
88 if (targ.ty != Tstruct) | |
89 goto Lno; | |
90 if ((cast(TypeStruct)targ).sym.isUnionDeclaration()) | |
91 goto Lno; | |
92 tded = targ; | |
93 break; | |
94 | |
95 case TOKunion: | |
96 if (targ.ty != Tstruct) | |
97 goto Lno; | |
98 if (!(cast(TypeStruct)targ).sym.isUnionDeclaration()) | |
99 goto Lno; | |
100 tded = targ; | |
101 break; | |
102 | |
103 case TOKclass: | |
104 if (targ.ty != Tclass) | |
105 goto Lno; | |
106 if ((cast(TypeClass)targ).sym.isInterfaceDeclaration()) | |
107 goto Lno; | |
108 tded = targ; | |
109 break; | |
110 | |
111 case TOKinterface: | |
112 if (targ.ty != Tclass) | |
113 goto Lno; | |
114 if (!(cast(TypeClass)targ).sym.isInterfaceDeclaration()) | |
115 goto Lno; | |
116 tded = targ; | |
117 break; | |
118 version (DMDV2) { | |
119 case TOKconst: | |
120 if (!targ.isConst()) | |
121 goto Lno; | |
122 tded = targ; | |
123 break; | |
124 | |
125 case TOKinvariant: | |
126 case TOKimmutable: | |
127 if (!targ.isInvariant()) | |
128 goto Lno; | |
129 tded = targ; | |
130 break; | |
131 | |
132 case TOKshared: | |
133 if (!targ.isShared()) | |
134 goto Lno; | |
135 tded = targ; | |
136 break; | |
137 } | |
138 | |
139 case TOKsuper: | |
140 // If class or interface, get the base class and interfaces | |
141 if (targ.ty != Tclass) | |
142 goto Lno; | |
143 else | |
144 { ClassDeclaration cd = (cast(TypeClass)targ).sym; | |
145 Arguments args = new Arguments; | |
146 args.reserve(cd.baseclasses.dim); | |
147 for (size_t i = 0; i < cd.baseclasses.dim; i++) | |
148 { | |
149 BaseClass b = cast(BaseClass)cd.baseclasses.data[i]; | |
150 args.push(cast(void*)new Argument(STCin, b.type, null, null)); | |
151 } | |
152 tded = new TypeTuple(args); | |
153 } | |
154 break; | |
155 | |
156 case TOKenum: | |
157 if (targ.ty != Tenum) | |
158 goto Lno; | |
159 tded = (cast(TypeEnum)targ).sym.memtype; | |
160 break; | |
161 | |
162 case TOKdelegate: | |
163 if (targ.ty != Tdelegate) | |
164 goto Lno; | |
165 tded = (cast(TypeDelegate)targ).next; // the underlying function type | |
166 break; | |
167 | |
168 case TOKfunction: | |
169 { | |
170 if (targ.ty != Tfunction) | |
171 goto Lno; | |
172 tded = targ; | |
173 | |
174 /* Generate tuple from function parameter types. | |
175 */ | |
176 assert(tded.ty == Tfunction); | |
177 Arguments params = (cast(TypeFunction)tded).parameters; | |
178 size_t dim = Argument.dim(params); | |
179 Arguments args = new Arguments; | |
180 args.reserve(dim); | |
181 for (size_t i = 0; i < dim; i++) | |
182 { | |
183 Argument arg = Argument.getNth(params, i); | |
184 assert(arg && arg.type); | |
185 args.push(cast(void*)new Argument(arg.storageClass, arg.type, null, null)); | |
186 } | |
187 tded = new TypeTuple(args); | |
188 break; | |
189 } | |
190 | |
191 case TOKreturn: | |
192 /* Get the 'return type' for the function, | |
193 * delegate, or pointer to function. | |
194 */ | |
195 if (targ.ty == Tfunction) | |
196 tded = (cast(TypeFunction)targ).next; | |
197 else if (targ.ty == Tdelegate) | |
198 { tded = (cast(TypeDelegate)targ).next; | |
199 tded = (cast(TypeFunction)tded).next; | |
200 } | |
201 else if (targ.ty == Tpointer && | |
202 (cast(TypePointer)targ).next.ty == Tfunction) | |
203 { tded = (cast(TypePointer)targ).next; | |
204 tded = (cast(TypeFunction)tded).next; | |
205 } | |
206 else | |
207 goto Lno; | |
208 break; | |
209 | |
210 default: | |
211 assert(0); | |
212 } | |
213 goto Lyes; | |
214 } | |
215 else if (id && tspec) | |
216 { | |
217 /* Evaluate to true if targ matches tspec. | |
218 * If true, declare id as an alias for the specialized type. | |
219 */ | |
220 | |
221 MATCH m; | |
222 assert(parameters && parameters.dim); | |
223 | |
224 scope Objects dedtypes = new Objects(); | |
225 dedtypes.setDim(parameters.dim); | |
226 dedtypes.zero(); | |
227 | |
228 m = targ.deduceType(null, tspec, parameters, dedtypes); | |
229 if (m == MATCHnomatch || | |
230 (m != MATCHexact && tok == TOKequal)) | |
231 { | |
232 goto Lno; | |
233 } | |
234 else | |
235 { | |
236 tded = cast(Type)dedtypes.data[0]; | |
237 if (!tded) | |
238 tded = targ; | |
239 | |
240 scope Objects tiargs = new Objects(); | |
241 tiargs.setDim(1); | |
242 tiargs.data[0] = cast(void*)targ; | |
243 | |
244 /* Declare trailing parameters | |
245 */ | |
246 for (int i = 1; i < parameters.dim; i++) | |
247 { | |
248 TemplateParameter tp = cast(TemplateParameter)parameters.data[i]; | |
249 Declaration s = null; | |
250 | |
251 m = tp.matchArg(sc, tiargs, i, parameters, dedtypes, &s); | |
252 if (m == MATCHnomatch) | |
253 goto Lno; | |
254 s.semantic(sc); | |
255 if (!sc.insert(s)) | |
256 error("declaration %s is already defined", s.toChars()); | |
257 static if (false) { | |
258 Object o = cast(Object)dedtypes.data[i]; | |
259 Dsymbol s = TemplateDeclaration.declareParameter(loc, sc, tp, o); | |
260 } | |
261 if (sc.sd) | |
262 s.addMember(sc, sc.sd, 1); | |
263 } | |
264 | |
265 goto Lyes; | |
266 } | |
267 } | |
268 else if (id) | |
269 { | |
270 /* Declare id as an alias for type targ. Evaluate to true | |
271 */ | |
272 tded = targ; | |
273 goto Lyes; | |
274 } | |
275 else if (tspec) | |
276 { | |
277 /* Evaluate to true if targ matches tspec | |
278 * is(targ == tspec) | |
279 * is(targ : tspec) | |
280 */ | |
281 tspec = tspec.semantic(loc, sc); | |
282 //printf("targ = %s\n", targ.toChars()); | |
283 //printf("tspec = %s\n", tspec.toChars()); | |
284 if (tok == TOKcolon) | |
285 { | |
286 if (targ.implicitConvTo(tspec)) | |
287 goto Lyes; | |
288 else | |
289 goto Lno; | |
290 } | |
291 else /* == */ | |
292 { | |
293 if (targ.equals(tspec)) | |
294 goto Lyes; | |
295 else | |
296 goto Lno; | |
297 } | |
298 } | |
299 | |
300 Lyes: | |
301 if (id) | |
302 { | |
303 Dsymbol s = new AliasDeclaration(loc, id, tded); | |
304 s.semantic(sc); | |
305 if (!sc.insert(s)) | |
306 error("declaration %s is already defined", s.toChars()); | |
307 if (sc.sd) | |
308 s.addMember(sc, sc.sd, 1); | |
309 } | |
310 //printf("Lyes\n"); | |
311 return new IntegerExp(loc, 1, Type.tbool); | |
312 | |
313 Lno: | |
314 //printf("Lno\n"); | |
315 return new IntegerExp(loc, 0, Type.tbool); | |
316 } | |
317 | |
318 void toCBuffer(OutBuffer buf, HdrGenState* hgs) | |
319 { | |
320 assert(false); | |
321 } | |
322 } | |
323 |