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;