comparison ast/Exp.d @ 58:fc62c5296a1c new_gen

Add types to our Exp
author Anders Halager <halager@gmail.com>
date Mon, 28 Apr 2008 21:51:39 +0200
parents 4ae365eff712
children 1d6f4ad38a91
comparison
equal deleted inserted replaced
57:43bb0a36b869 58:fc62c5296a1c
6 import ast.Decl, 6 import ast.Decl,
7 ast.Stmt; 7 ast.Stmt;
8 8
9 import lexer.Token; 9 import lexer.Token;
10 10
11 import sema.SymbolTable; 11 import sema.SymbolTable,
12 sema.DType;
12 13
13 enum ExpType 14 enum ExpType
14 { 15 {
15 Binary, 16 Binary,
16 Negate, 17 Negate,
27 this(ExpType expType) 28 this(ExpType expType)
28 { 29 {
29 this.expType = expType; 30 this.expType = expType;
30 } 31 }
31 32
33 DType type() { return null; }
34
32 ExpType expType; 35 ExpType expType;
33 Scope env; 36 Scope env;
34 int stmtIndex; 37 int stmtIndex;
35 38
36 Exp simplify() 39 Exp simplify()
44 this(Exp exp, Exp[] args) 47 this(Exp exp, Exp[] args)
45 { 48 {
46 super(ExpType.CallExp); 49 super(ExpType.CallExp);
47 this.exp = exp; 50 this.exp = exp;
48 this.args = args; 51 this.args = args;
52 }
53
54 override DType type()
55 {
56 DFunction f = cast(DFunction)exp.type();
57 assert(f, "Can only call functions");
58 return f.return_type;
49 } 59 }
50 60
51 Exp exp; 61 Exp exp;
52 Exp[] args; 62 Exp[] args;
53 bool sret = false; 63 bool sret = false;
103 exp = exp.simplify; 113 exp = exp.simplify;
104 114
105 return this; 115 return this;
106 } 116 }
107 117
118 override DType type() { return identifier.type(); }
119
108 Exp identifier; 120 Exp identifier;
109 Exp exp; 121 Exp exp;
110 } 122 }
111 123
112 class BinaryExp : Exp 124 class BinaryExp : Exp
130 this.op = op; 142 this.op = op;
131 this.left = left; 143 this.left = left;
132 this.right = right; 144 this.right = right;
133 } 145 }
134 146
147 override DType type()
148 {
149 if (myType)
150 return myType;
151
152 DType l = left.type;
153 DType r = right.type;
154 if (l is r)
155 myType = l;
156 else if (l.hasImplicitConversionTo(r))
157 myType = r;
158 else if (r.hasImplicitConversionTo(l))
159 myType = l;
160 else
161 return null;
162 }
163
135 char[] resultType() 164 char[] resultType()
136 { 165 {
137 if (op >= Operator.Eq && op <= Operator.Ge) 166 if (op >= Operator.Eq && op <= Operator.Ge)
138 return "bool"; 167 return "bool";
139 return null; 168 return null;
145 return this; 174 return this;
146 } 175 }
147 176
148 Operator op; 177 Operator op;
149 Exp left, right; 178 Exp left, right;
179 private DType myType;
150 } 180 }
151 181
152 class NegateExp : Exp 182 class NegateExp : Exp
153 { 183 {
154 this(Exp exp) 184 this(Exp exp)
160 { 190 {
161 exp = exp.simplify; 191 exp = exp.simplify;
162 return this; 192 return this;
163 } 193 }
164 194
195 override DType type() { return exp.type(); }
196
165 public Exp exp; 197 public Exp exp;
166 } 198 }
167 199
168 class IntegerLit : Exp 200 class IntegerLit : Exp
169 { 201 {
174 } 206 }
175 Exp simplify() 207 Exp simplify()
176 { 208 {
177 return this; 209 return this;
178 } 210 }
211
212 override DType type() { return DType.Int; }
179 213
180 Token token; 214 Token token;
181 } 215 }
182 216
183 class MemberReference : Exp 217 class MemberReference : Exp
193 child.simplify; 227 child.simplify;
194 target = target.simplify; 228 target = target.simplify;
195 return this; 229 return this;
196 } 230 }
197 231
232 override DType type()
233 {
234 if (myType)
235 return myType;
236
237 DStruct st = cast(DStruct)target.type;
238 assert(st, "Only structs have members");
239 if (auto t = st.typeOf(child.token.get))
240 myType = t;
241 // no error reporting here
242 else assert(0, "Referencing non-existant member");
243 }
244
198 Identifier child; 245 Identifier child;
199 Exp target; 246 Exp target;
247 private DType myType;
200 } 248 }
201 249
202 class ArrayLookup : Exp 250 class ArrayLookup : Exp
203 { 251 {
204 this(Exp target, IntegerLit pos) 252 this(Exp target, IntegerLit pos)
206 super(ExpType.ArrayLookup); 254 super(ExpType.ArrayLookup);
207 this.target = target; 255 this.target = target;
208 this.pos = pos; 256 this.pos = pos;
209 } 257 }
210 258
259 override DType type() { return target.type(); }
260
211 Exp simplify() 261 Exp simplify()
212 { 262 {
213 target = target.simplify; 263 target = target.simplify;
214 pos.simplify; 264 pos.simplify;
215 return this; 265 return this;
226 super(ExpType.Identifier); 276 super(ExpType.Identifier);
227 this.token = t; 277 this.token = t;
228 name = t.get; 278 name = t.get;
229 } 279 }
230 280
281 override DType type()
282 {
283 if (myType)
284 return myType;
285 myType = env.find(this).type;
286 return myType;
287 }
288
231 this(char[] name) 289 this(char[] name)
232 { 290 {
233 super(ExpType.Identifier); 291 super(ExpType.Identifier);
234 this.name = name; 292 this.name = name;
235 } 293 }
263 return this; 321 return this;
264 } 322 }
265 323
266 Token token; 324 Token token;
267 char[] name; 325 char[] name;
268 } 326 private DType myType;
269 327 }
270 328