Mercurial > projects > dang
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 |