Mercurial > projects > dang
comparison sema/TypeCheck.d @ 158:57b0b4464a0b
Parsing "new", putting it in AST and performs some tests on it. Eg. if the contructor exists and the params matches.
author | Anders Johnsen <skabet@gmail.com> |
---|---|
date | Tue, 22 Jul 2008 00:33:58 +0200 |
parents | c3b24e7e8cf8 |
children | 6cb2f4201e2a |
comparison
equal
deleted
inserted
replaced
157:bb01c1dc452a | 158:57b0b4464a0b |
---|---|
1 module sema.TypeCheck; | 1 module sema.TypeCheck; |
2 | 2 |
3 import sema.Visitor, | 3 import sema.Visitor, |
4 sema.Symbol, | |
4 sema.DType; | 5 sema.DType; |
5 | 6 |
6 import tango.io.Stdout; | 7 import tango.io.Stdout, |
8 Integer = tango.text.convert.Integer; | |
7 | 9 |
8 import basic.SourceLocation, | 10 import basic.SourceLocation, |
9 basic.Message; | 11 basic.Message; |
10 | 12 |
11 class TypeCheck : Visitor!(void) | 13 class TypeCheck : Visitor!(void) |
88 | 90 |
89 Exp[] newArgs; | 91 Exp[] newArgs; |
90 | 92 |
91 foreach(i, arg; exp.args) | 93 foreach(i, arg; exp.args) |
92 { | 94 { |
93 auto argType = (cast(DFunction)exp.exp.type).params[i]; | 95 auto argType = exp.exp.type.asFunction.params[i]; |
94 auto expType = arg.type; | 96 auto expType = arg.type; |
95 if(argType.byteSize != expType.byteSize) | 97 if(argType.byteSize != expType.byteSize) |
96 { | 98 { |
97 if(!expType.hasImplicitConversionTo(argType)) | 99 if(!expType.hasImplicitConversionTo(argType)) |
98 messages.report(InvalidImplicitCast, exp.loc) | 100 messages.report(InvalidImplicitCast, exp.loc) |
111 } | 113 } |
112 | 114 |
113 exp.args = newArgs; | 115 exp.args = newArgs; |
114 } | 116 } |
115 | 117 |
118 override void visitNewExp(NewExp exp) | |
119 { | |
120 super.visitNewExp(exp); | |
121 | |
122 Exp[] newArgs; | |
123 | |
124 Symbol[] methods = exp.newType.getSymbol.findMembers("this"); | |
125 | |
126 if ( exp.c_args.length ) | |
127 { | |
128 if ( !methods.length ) | |
129 { | |
130 messages.report(NoConstructor, exp.newType.loc); | |
131 return; | |
132 } | |
133 | |
134 Symbol[] possible; | |
135 Symbol perfect; | |
136 | |
137 foreach( s ; methods ) | |
138 { | |
139 bool per = true; | |
140 | |
141 foreach(i, arg; exp.c_args) | |
142 { | |
143 auto argType = s.type.asFunction.params[i]; | |
144 auto expType = arg.type; | |
145 if(argType != expType) | |
146 { | |
147 per = false; | |
148 if( !expType.hasImplicitConversionTo(argType) ) | |
149 break; | |
150 } | |
151 | |
152 if ( i == exp.c_args.length-1 | |
153 && i == s.type.asFunction.params.length-1) | |
154 if (per) | |
155 perfect = s; | |
156 else | |
157 possible ~= s; | |
158 } | |
159 } | |
160 | |
161 Symbol sel; | |
162 | |
163 if ( perfect ) | |
164 sel = perfect; | |
165 else | |
166 if ( possible.length ) | |
167 sel = possible[0]; | |
168 | |
169 if ( sel ) | |
170 { | |
171 foreach(i, arg; exp.c_args) | |
172 { | |
173 auto argType = sel.type.asFunction.params[i]; | |
174 auto expType = arg.type; | |
175 if(argType.byteSize != expType.byteSize) | |
176 { | |
177 if(!expType.hasImplicitConversionTo(argType)) | |
178 messages.report(InvalidImplicitCast, exp.loc) | |
179 .arg(expType.toString) | |
180 .arg(argType.toString); | |
181 | |
182 auto castExp = new CastExp( | |
183 SLoc.Invalid, | |
184 new Identifier(argType.name), | |
185 arg); | |
186 castExp.env = exp.newType.env; | |
187 newArgs ~= castExp; | |
188 } | |
189 else | |
190 newArgs ~= arg; | |
191 } | |
192 exp.c_args = newArgs; | |
193 } | |
194 else | |
195 { | |
196 messages.report(NoMachingCon, exp.newType.loc); | |
197 foreach( i, s ; methods ) | |
198 { | |
199 messages.report(CandidateNr, | |
200 (cast(FuncDecl)s.decl).identifier.loc) | |
201 .arg(Integer.toString(i+1)); | |
202 } | |
203 } | |
204 } | |
205 } | |
206 | |
116 override void visitAssignExp(AssignExp exp) | 207 override void visitAssignExp(AssignExp exp) |
117 { | 208 { |
118 super.visitAssignExp(exp); | 209 super.visitAssignExp(exp); |
119 | 210 |
120 auto identifierType = exp.identifier.type; | 211 auto identifierType = exp.identifier.type; |