Mercurial > projects > dang
comparison sema/TypeCheck.d @ 168:7982eb63c0eb
Some changes to get function overloading to work. Also class inherit works now - to some extend. needs vtables and all the complex stuff of it.
author | Anders Johnsen <skabet@gmail.com> |
---|---|
date | Thu, 24 Jul 2008 12:06:48 +0200 |
parents | 7606387b2f0a |
children | 20ff3c31f600 |
comparison
equal
deleted
inserted
replaced
166:9cfa33517526 | 168:7982eb63c0eb |
---|---|
86 | 86 |
87 override void visitCallExp(CallExp exp) | 87 override void visitCallExp(CallExp exp) |
88 { | 88 { |
89 super.visitCallExp(exp); | 89 super.visitCallExp(exp); |
90 | 90 |
91 Exp[] newArgs; | 91 if (auto iden = cast(Identifier)exp.exp) |
92 | 92 { |
93 foreach(i, arg; exp.args) | 93 Exp[] newArgs; |
94 { | 94 |
95 auto argType = exp.exp.type.asFunction.params[i]; | 95 Symbol[] methods; |
96 auto expType = arg.type; | 96 |
97 if(argType.byteSize != expType.byteSize) | 97 foreach (decl ; iden.env.find(iden.get)) |
98 { | 98 methods ~= decl.sym; |
99 if(!expType.hasImplicitConversionTo(argType)) | 99 |
100 messages.report(InvalidImplicitCast, exp.loc) | 100 if (!methods.length) |
101 .arg(expType.toString) | 101 { |
102 .arg(argType.toString); | 102 messages.report(NoMethodByName, iden.loc); |
103 | 103 return; |
104 auto castExp = new CastExp( | 104 } |
105 SLoc.Invalid, | 105 |
106 new Identifier(argType.name), | 106 Symbol sel = getBestMatch(exp.args, methods); |
107 arg); | 107 |
108 castExp.env = exp.exp.env; | 108 if (sel) |
109 newArgs ~= castExp; | 109 { |
110 foreach (i, arg; exp.args) | |
111 { | |
112 auto argType = sel.type.asFunction.params[i]; | |
113 auto expType = arg.type; | |
114 if (argType.byteSize != expType.byteSize) | |
115 { | |
116 if (!expType.hasImplicitConversionTo(argType)) | |
117 messages.report(InvalidImplicitCast, exp.loc) | |
118 .arg(expType.toString) | |
119 .arg(argType.toString); | |
120 | |
121 auto castExp = new CastExp( | |
122 SLoc.Invalid, | |
123 new Identifier(argType.name), | |
124 arg); | |
125 castExp.env = iden.env; | |
126 newArgs ~= castExp; | |
127 } | |
128 else | |
129 newArgs ~= arg; | |
130 } | |
131 exp.args = newArgs; | |
132 exp.callSym = sel; | |
110 } | 133 } |
111 else | 134 else |
112 newArgs ~= arg; | 135 { |
113 } | 136 messages.report(NoMachingMethod, exp.loc); |
114 | 137 foreach ( i, s ; methods ) |
115 exp.args = newArgs; | 138 { |
139 messages.report(CandidateNr, | |
140 (cast(FuncDecl)s.decl).identifier.loc) | |
141 .arg(Integer.toString(i+1)); | |
142 } | |
143 } | |
144 | |
145 } | |
146 else | |
147 { | |
148 Exp[] newArgs; | |
149 | |
150 foreach(i, arg; exp.args) | |
151 { | |
152 auto argType = exp.exp.type.asFunction.params[i]; | |
153 auto expType = arg.type; | |
154 if(argType.byteSize != expType.byteSize) | |
155 { | |
156 if(!expType.hasImplicitConversionTo(argType)) | |
157 messages.report(InvalidImplicitCast, exp.loc) | |
158 .arg(expType.toString) | |
159 .arg(argType.toString); | |
160 | |
161 auto castExp = new CastExp( | |
162 SLoc.Invalid, | |
163 new Identifier(argType.name), | |
164 arg); | |
165 castExp.env = exp.exp.env; | |
166 newArgs ~= castExp; | |
167 } | |
168 else | |
169 newArgs ~= arg; | |
170 } | |
171 | |
172 exp.args = newArgs; | |
173 } | |
116 } | 174 } |
117 | 175 |
118 override void visitNewExp(NewExp exp) | 176 override void visitNewExp(NewExp exp) |
119 { | 177 { |
120 super.visitNewExp(exp); | 178 super.visitNewExp(exp); |
121 | 179 |
122 Exp[] newArgs; | 180 Exp[] newArgs; |
123 | 181 |
124 Symbol[] methods = exp.newType.getSymbol.findMembers("this"); | 182 Symbol[] methods = exp.newType.getSymbol.findFunctionMembers("this"); |
125 | 183 |
126 if (!methods.length) | 184 if (!methods.length) |
127 { | 185 { |
128 messages.report(NoConstructor, exp.newType.loc); | 186 messages.report(NoConstructor, exp.newType.loc); |
129 return; | 187 return; |
241 } | 299 } |
242 } | 300 } |
243 } | 301 } |
244 | 302 |
245 private Symbol getBestMatch(Exp[] arg_list , Symbol[] available) | 303 private Symbol getBestMatch(Exp[] arg_list , Symbol[] available) |
304 in | |
305 { | |
306 foreach (a ; available) | |
307 assert(a.type.isFunction, "A non-function found in available-list."); | |
308 } | |
246 body | 309 body |
247 { | 310 { |
248 Symbol[] _a; | |
249 foreach (a ; available) | |
250 if (a.type.isFunction) | |
251 _a ~= a; | |
252 available = _a; | |
253 | |
254 assert(available.length, "No available methods in symbol-list."); | 311 assert(available.length, "No available methods in symbol-list."); |
255 | 312 |
256 Symbol[] possible; | 313 Symbol[] possible; |
257 Symbol perfect; | 314 Symbol perfect; |
258 | 315 |
260 { | 317 { |
261 if (s.type.asFunction.params.length < arg_list.length) | 318 if (s.type.asFunction.params.length < arg_list.length) |
262 continue; | 319 continue; |
263 | 320 |
264 bool per = true; | 321 bool per = true; |
322 bool work = true; | |
265 | 323 |
266 foreach (i, arg; arg_list) | 324 foreach (i, arg; arg_list) |
267 { | 325 { |
268 auto argType = s.type.asFunction.params[i]; | 326 auto argType = s.type.asFunction.params[i]; |
269 auto expType = arg.type; | 327 auto expType = arg.type; |
270 if (argType != expType) | 328 if (argType != expType) |
271 { | 329 { |
272 per = false; | 330 per = false; |
273 if( !expType.hasImplicitConversionTo(argType) ) | 331 if( !expType.hasImplicitConversionTo(argType) ) |
332 { | |
333 work = false; | |
274 break; | 334 break; |
275 } | 335 } |
276 | 336 } |
277 if (i == arg_list.length-1) | 337 } |
278 { | 338 |
279 bool work = true; | 339 foreach (a ; (cast(FuncDecl)s.decl).funcArgs[arg_list.length..$]) |
280 foreach (a ; (cast(FuncDecl)s.decl).funcArgs[i+1..$]) | 340 if (a.init is null) |
281 if (a.init is null) | 341 work = false; |
282 work = false; | 342 |
283 | 343 if (work) |
284 if (work) | 344 if (per) |
285 if (per) | 345 return s; |
286 return s; | 346 else |
287 else | 347 possible ~= s; |
288 possible ~= s; | |
289 } | |
290 } | |
291 } | 348 } |
292 | 349 |
293 if (possible.length) | 350 if (possible.length) |
294 return possible[0]; | 351 return possible[0]; |
295 | 352 |