Mercurial > projects > dang
comparison sema/TypeCheck.d @ 181:59cd211a1bd3
Better support for function pointers
author | Anders Halager <halager@gmail.com> |
---|---|
date | Fri, 25 Jul 2008 01:39:01 +0200 |
parents | 2a1a635bd531 |
children | 8ea749b7da91 |
comparison
equal
deleted
inserted
replaced
179:2a1a635bd531 | 181:59cd211a1bd3 |
---|---|
111 } | 111 } |
112 } | 112 } |
113 | 113 |
114 Exp[] newArgs; | 114 Exp[] newArgs; |
115 | 115 |
116 Symbol[] methods = internalVisitMemberRef(iden); | 116 DFunction function_type; |
117 | 117 if (iden.type.isFunction()) |
118 if (!methods.length) | 118 { |
119 { | 119 Symbol[] methods = internalVisitMemberRef(iden); |
120 messages.report(NoMethodByName, iden.loc); | 120 |
121 return; | 121 if (!methods.length) |
122 } | 122 { |
123 | 123 messages.report(NoMethodByName, iden.loc); |
124 Symbol sel = getBestMatch(exp.args, methods); | 124 return; |
125 | 125 } |
126 if (sel) | 126 |
127 { | 127 Symbol sel = getBestMatch(exp.args, methods); |
128 foreach (i, arg; exp.args) | 128 exp.callSym = sel; |
129 { | 129 if (sel) |
130 auto argType = sel.type.asFunction.params[i]; | 130 function_type = sel.type.asFunction(); |
131 auto expType = arg.type; | 131 else |
132 if (argType.isSame(expType)) | 132 { |
133 messages.report(NoMachingMethod, exp.loc); | |
134 foreach ( i, s ; methods ) | |
133 { | 135 { |
134 if (!expType.hasImplicitConversionTo(argType)) | 136 messages.report(CandidateNr, |
135 messages.report(InvalidImplicitCast, exp.loc) | 137 (cast(FuncDecl)s.decl).identifier.loc) |
136 .arg(expType.toString) | 138 .arg(Integer.toString(i+1)); |
137 .arg(argType.toString); | |
138 | |
139 auto castExp = new CastExp( | |
140 SLoc.Invalid, | |
141 new Identifier(argType.name), | |
142 arg); | |
143 castExp.env = iden.env; | |
144 newArgs ~= castExp; | |
145 } | 139 } |
146 else | 140 } |
147 newArgs ~= arg; | 141 } |
148 } | 142 else if (iden.type.isCallable) |
149 exp.args = newArgs; | 143 function_type = iden.type.asCallable(); |
144 else assert(0, "Should not happen"); | |
145 | |
146 foreach (i, arg; exp.args) | |
147 { | |
148 auto argType = function_type.params[i]; | |
149 auto expType = arg.type; | |
150 if (argType.isSame(expType)) | |
151 { | |
152 if (!expType.hasImplicitConversionTo(argType)) | |
153 messages.report(InvalidImplicitCast, exp.loc) | |
154 .arg(expType.toString) | |
155 .arg(argType.toString); | |
156 | |
157 auto castExp = new CastExp( | |
158 SLoc.Invalid, | |
159 new Identifier(argType.name), | |
160 arg); | |
161 castExp.env = iden.env; | |
162 newArgs ~= castExp; | |
163 } | |
164 else | |
165 newArgs ~= arg; | |
166 } | |
167 exp.args = newArgs; | |
168 } | |
169 else if (auto iden = cast(Identifier)exp.exp) | |
170 { | |
171 Exp[] newArgs; | |
172 | |
173 DFunction function_type; | |
174 if (iden.type.isFunction()) | |
175 { | |
176 Symbol[] methods; | |
177 | |
178 foreach (decl ; iden.env.find(iden.get)) | |
179 methods ~= decl.sym; | |
180 | |
181 if (!methods.length) | |
182 { | |
183 messages.report(NoMethodByName, iden.loc); | |
184 return; | |
185 } | |
186 | |
187 Symbol sel = getBestMatch(exp.args, methods); | |
150 exp.callSym = sel; | 188 exp.callSym = sel; |
151 } | 189 if (sel) |
152 else | 190 function_type = sel.type.asFunction(); |
153 { | 191 else |
154 messages.report(NoMachingMethod, exp.loc); | 192 { |
155 foreach ( i, s ; methods ) | 193 messages.report(NoMachingMethod, exp.loc); |
156 { | 194 foreach ( i, s ; methods ) |
157 messages.report(CandidateNr, | |
158 (cast(FuncDecl)s.decl).identifier.loc) | |
159 .arg(Integer.toString(i+1)); | |
160 } | |
161 } | |
162 } | |
163 else if (auto iden = cast(Identifier)exp.exp) | |
164 { | |
165 Exp[] newArgs; | |
166 | |
167 Symbol[] methods; | |
168 | |
169 foreach (decl ; iden.env.find(iden.get)) | |
170 methods ~= decl.sym; | |
171 | |
172 if (!methods.length) | |
173 { | |
174 messages.report(NoMethodByName, iden.loc); | |
175 return; | |
176 } | |
177 | |
178 Symbol sel = getBestMatch(exp.args, methods); | |
179 | |
180 if (sel) | |
181 { | |
182 foreach (i, arg; exp.args) | |
183 { | |
184 auto argType = sel.type.asFunction.params[i]; | |
185 auto expType = arg.type; | |
186 if (argType.byteSize != expType.byteSize) | |
187 { | 195 { |
188 if (!expType.hasImplicitConversionTo(argType)) | 196 messages.report(CandidateNr, |
189 messages.report(InvalidImplicitCast, exp.loc) | 197 (cast(FuncDecl)s.decl).identifier.loc) |
190 .arg(expType.toString) | 198 .arg(Integer.toString(i+1)); |
191 .arg(argType.toString); | |
192 | |
193 auto castExp = new CastExp( | |
194 SLoc.Invalid, | |
195 new Identifier(argType.name), | |
196 arg); | |
197 castExp.env = iden.env; | |
198 newArgs ~= castExp; | |
199 } | 199 } |
200 else | 200 } |
201 newArgs ~= arg; | 201 } |
202 } | 202 else if (iden.type.isCallable) |
203 exp.args = newArgs; | 203 function_type = iden.type.asCallable(); |
204 exp.callSym = sel; | 204 else assert(0, "Should not happen"); |
205 } | 205 |
206 else | 206 foreach (i, arg; exp.args) |
207 { | 207 { |
208 messages.report(NoMachingMethod, exp.loc); | 208 auto argType = function_type.params[i]; |
209 foreach ( i, s ; methods ) | 209 auto expType = arg.type; |
210 { | 210 if (argType.isSame(expType)) |
211 messages.report(CandidateNr, | 211 { |
212 (cast(FuncDecl)s.decl).identifier.loc) | 212 if (!expType.hasImplicitConversionTo(argType)) |
213 .arg(Integer.toString(i+1)); | 213 messages.report(InvalidImplicitCast, exp.loc) |
214 } | 214 .arg(expType.toString) |
215 } | 215 .arg(argType.toString); |
216 | |
217 auto castExp = new CastExp( | |
218 SLoc.Invalid, | |
219 new Identifier(argType.name), | |
220 arg); | |
221 castExp.env = iden.env; | |
222 newArgs ~= castExp; | |
223 } | |
224 else | |
225 newArgs ~= arg; | |
226 } | |
227 exp.args = newArgs; | |
216 } | 228 } |
217 else | 229 else |
218 { | 230 { |
219 Exp[] newArgs; | 231 Exp[] newArgs; |
220 | 232 |