Mercurial > lcfOS
comparison python/ppci/c3/codegenerator.py @ 393:6ae782a085e0
Added init program
author | Windel Bouwman |
---|---|
date | Sat, 17 May 2014 21:17:40 +0200 |
parents | 2ec730e45ea1 |
children | 988f3fb861e4 |
comparison
equal
deleted
inserted
replaced
392:bb4289c84907 | 393:6ae782a085e0 |
---|---|
111 for s in code.statements: | 111 for s in code.statements: |
112 self.genCode(s) | 112 self.genCode(s) |
113 elif type(code) is ast.Empty: | 113 elif type(code) is ast.Empty: |
114 pass | 114 pass |
115 elif type(code) is ast.Assignment: | 115 elif type(code) is ast.Assignment: |
116 lval = self.genExprCode(code.lval) | 116 lval = self.gen_expr_code(code.lval) |
117 rval = self.genExprCode(code.rval) | 117 rval = self.gen_expr_code(code.rval) |
118 if not self.equal_types(code.lval.typ, code.rval.typ): | 118 if not self.equal_types(code.lval.typ, code.rval.typ): |
119 raise SemanticError('Cannot assign {} to {}' | 119 raise SemanticError('Cannot assign {} to {}' |
120 .format(code.rval.typ, code.lval.typ), | 120 .format(code.rval.typ, code.lval.typ), |
121 code.loc) | 121 code.loc) |
122 if not code.lval.lvalue: | 122 if not code.lval.lvalue: |
123 raise SemanticError('No valid lvalue {}'.format(code.lval), | 123 raise SemanticError('No valid lvalue {}'.format(code.lval), |
124 code.lval.loc) | 124 code.lval.loc) |
125 self.emit(ir.Move(lval, rval)) | 125 self.emit(ir.Move(lval, rval)) |
126 elif type(code) is ast.ExpressionStatement: | 126 elif type(code) is ast.ExpressionStatement: |
127 self.emit(ir.Exp(self.genExprCode(code.ex))) | 127 self.emit(ir.Exp(self.gen_expr_code(code.ex))) |
128 elif type(code) is ast.If: | 128 elif type(code) is ast.If: |
129 bbtrue = self.newBlock() | 129 bbtrue = self.newBlock() |
130 bbfalse = self.newBlock() | 130 bbfalse = self.newBlock() |
131 te = self.newBlock() | 131 te = self.newBlock() |
132 self.gen_cond_code(code.condition, bbtrue, bbfalse) | 132 self.gen_cond_code(code.condition, bbtrue, bbfalse) |
136 self.setBlock(bbfalse) | 136 self.setBlock(bbfalse) |
137 self.genCode(code.falsestatement) | 137 self.genCode(code.falsestatement) |
138 self.emit(ir.Jump(te)) | 138 self.emit(ir.Jump(te)) |
139 self.setBlock(te) | 139 self.setBlock(te) |
140 elif type(code) is ast.Return: | 140 elif type(code) is ast.Return: |
141 re = self.genExprCode(code.expr) | 141 re = self.gen_expr_code(code.expr) |
142 self.emit(ir.Move(self.fn.return_value, re)) | 142 self.emit(ir.Move(self.fn.return_value, re)) |
143 self.emit(ir.Jump(self.fn.epiloog)) | 143 self.emit(ir.Jump(self.fn.epiloog)) |
144 b = self.newBlock() | 144 b = self.newBlock() |
145 self.setBlock(b) | 145 self.setBlock(b) |
146 elif type(code) is ast.While: | 146 elif type(code) is ast.While: |
165 self.setBlock(bbdo) | 165 self.setBlock(bbdo) |
166 self.genCode(code.statement) | 166 self.genCode(code.statement) |
167 self.genCode(code.final) | 167 self.genCode(code.final) |
168 self.emit(ir.Jump(bbtest)) | 168 self.emit(ir.Jump(bbtest)) |
169 self.setBlock(te) | 169 self.setBlock(te) |
170 elif type(code) is ast.Switch: | |
171 raise NotImplementedError('Unknown stmt {}'.format(code)) | |
170 else: | 172 else: |
171 raise NotImplementedError('Unknown stmt {}'.format(code)) | 173 raise NotImplementedError('Unknown stmt {}'.format(code)) |
172 | 174 |
173 def gen_cond_code(self, expr, bbtrue, bbfalse): | 175 def gen_cond_code(self, expr, bbtrue, bbfalse): |
174 """ Generate conditional logic. | 176 """ Generate conditional logic. |
191 self.setBlock(l2) | 193 self.setBlock(l2) |
192 self.gen_cond_code(expr.b, bbtrue, bbfalse) | 194 self.gen_cond_code(expr.b, bbtrue, bbfalse) |
193 if not self.equal_types(expr.b.typ, self.boolType): | 195 if not self.equal_types(expr.b.typ, self.boolType): |
194 raise SemanticError('Must be boolean', expr.b.loc) | 196 raise SemanticError('Must be boolean', expr.b.loc) |
195 elif expr.op in ['==', '>', '<', '!=', '<=', '>=']: | 197 elif expr.op in ['==', '>', '<', '!=', '<=', '>=']: |
196 ta = self.genExprCode(expr.a) | 198 ta = self.gen_expr_code(expr.a) |
197 tb = self.genExprCode(expr.b) | 199 tb = self.gen_expr_code(expr.b) |
198 if not self.equal_types(expr.a.typ, expr.b.typ): | 200 if not self.equal_types(expr.a.typ, expr.b.typ): |
199 raise SemanticError('Types unequal {} != {}' | 201 raise SemanticError('Types unequal {} != {}' |
200 .format(expr.a.typ, expr.b.typ), | 202 .format(expr.a.typ, expr.b.typ), |
201 expr.loc) | 203 expr.loc) |
202 self.emit(ir.CJump(ta, expr.op, tb, bbtrue, bbfalse)) | 204 self.emit(ir.CJump(ta, expr.op, tb, bbtrue, bbfalse)) |
203 else: | 205 else: |
204 raise SemanticError('non-bool: {}'.format(expr.op), expr.loc) | 206 raise SemanticError('non-bool: {}'.format(expr.op), expr.loc) |
205 expr.typ = self.boolType | 207 expr.typ = self.boolType |
206 elif type(expr) is ast.Literal: | 208 elif type(expr) is ast.Literal: |
207 self.genExprCode(expr) | 209 self.gen_expr_code(expr) |
208 if expr.val: | 210 if expr.val: |
209 self.emit(ir.Jump(bbtrue)) | 211 self.emit(ir.Jump(bbtrue)) |
210 else: | 212 else: |
211 self.emit(ir.Jump(bbfalse)) | 213 self.emit(ir.Jump(bbfalse)) |
212 else: | 214 else: |
214 | 216 |
215 # Check that the condition is a boolean value: | 217 # Check that the condition is a boolean value: |
216 if not self.equal_types(expr.typ, self.boolType): | 218 if not self.equal_types(expr.typ, self.boolType): |
217 self.error('Condition must be boolean', expr.loc) | 219 self.error('Condition must be boolean', expr.loc) |
218 | 220 |
219 def genExprCode(self, expr): | 221 def gen_expr_code(self, expr): |
220 """ Generate code for an expression. Return the generated ir-value """ | 222 """ Generate code for an expression. Return the generated ir-value """ |
221 assert isinstance(expr, ast.Expression) | 223 assert isinstance(expr, ast.Expression) |
222 if type(expr) is ast.Binop: | 224 if type(expr) is ast.Binop: |
223 expr.lvalue = False | 225 expr.lvalue = False |
224 if expr.op in ['+', '-', '*', '/', '<<', '>>', '|', '&']: | 226 if expr.op in ['+', '-', '*', '/', '<<', '>>', '|', '&']: |
225 ra = self.genExprCode(expr.a) | 227 ra = self.gen_expr_code(expr.a) |
226 rb = self.genExprCode(expr.b) | 228 rb = self.gen_expr_code(expr.b) |
227 if self.equal_types(expr.a.typ, self.intType) and \ | 229 if self.equal_types(expr.a.typ, self.intType) and \ |
228 self.equal_types(expr.b.typ, self.intType): | 230 self.equal_types(expr.b.typ, self.intType): |
231 expr.typ = expr.a.typ | |
232 elif self.equal_types(expr.b.typ, self.intType) and \ | |
233 type(expr.a.typ) is ast.PointerType: | |
234 # Special case for pointer arithmatic TODO: coerce! | |
229 expr.typ = expr.a.typ | 235 expr.typ = expr.a.typ |
230 else: | 236 else: |
231 raise SemanticError('Can only add integers', expr.loc) | 237 raise SemanticError('Can only add integers', expr.loc) |
232 else: | 238 else: |
233 raise NotImplementedError("Cannot use equality as expressions") | 239 raise NotImplementedError("Cannot use equality as expressions") |
234 return ir.Binop(ra, expr.op, rb) | 240 return ir.Binop(ra, expr.op, rb) |
235 elif type(expr) is ast.Unop: | 241 elif type(expr) is ast.Unop: |
236 if expr.op == '&': | 242 if expr.op == '&': |
237 ra = self.genExprCode(expr.a) | 243 ra = self.gen_expr_code(expr.a) |
238 expr.typ = ast.PointerType(expr.a.typ) | 244 expr.typ = ast.PointerType(expr.a.typ) |
239 if not expr.a.lvalue: | 245 if not expr.a.lvalue: |
240 raise SemanticError('No valid lvalue', expr.a.loc) | 246 raise SemanticError('No valid lvalue', expr.a.loc) |
241 expr.lvalue = False | 247 expr.lvalue = False |
242 assert type(ra) is ir.Mem | 248 assert type(ra) is ir.Mem |
251 # This returns the dereferenced variable. | 257 # This returns the dereferenced variable. |
252 if isinstance(tg, ast.Variable): | 258 if isinstance(tg, ast.Variable): |
253 expr.lvalue = True | 259 expr.lvalue = True |
254 return ir.Mem(self.varMap[tg]) | 260 return ir.Mem(self.varMap[tg]) |
255 elif isinstance(tg, ast.Constant): | 261 elif isinstance(tg, ast.Constant): |
256 c_val = self.genExprCode(tg.value) | 262 c_val = self.gen_expr_code(tg.value) |
257 return self.evalConst(c_val) | 263 return self.evalConst(c_val) |
258 else: | 264 else: |
259 raise NotImplementedError(str(tg)) | 265 raise NotImplementedError(str(tg)) |
260 elif type(expr) is ast.Deref: | 266 elif type(expr) is ast.Deref: |
261 # dereference pointer type: | 267 # dereference pointer type: |
262 addr = self.genExprCode(expr.ptr) | 268 addr = self.gen_expr_code(expr.ptr) |
263 ptr_typ = self.the_type(expr.ptr.typ) | 269 ptr_typ = self.the_type(expr.ptr.typ) |
264 expr.lvalue = True | 270 expr.lvalue = True |
265 if type(ptr_typ) is ast.PointerType: | 271 if type(ptr_typ) is ast.PointerType: |
266 expr.typ = ptr_typ.ptype | 272 expr.typ = ptr_typ.ptype |
267 return ir.Mem(addr) | 273 return ir.Mem(addr) |
268 else: | 274 else: |
269 raise SemanticError('Cannot deref non-pointer', expr.loc) | 275 raise SemanticError('Cannot deref non-pointer', expr.loc) |
270 elif type(expr) is ast.Member: | 276 elif type(expr) is ast.Member: |
271 base = self.genExprCode(expr.base) | 277 base = self.gen_expr_code(expr.base) |
272 expr.lvalue = expr.base.lvalue | 278 expr.lvalue = expr.base.lvalue |
273 basetype = self.the_type(expr.base.typ) | 279 basetype = self.the_type(expr.base.typ) |
274 if type(basetype) is ast.StructureType: | 280 if type(basetype) is ast.StructureType: |
275 if basetype.hasField(expr.field): | 281 if basetype.hasField(expr.field): |
276 expr.typ = basetype.fieldType(expr.field) | 282 expr.typ = basetype.fieldType(expr.field) |
286 bt = self.the_type(expr.base.typ) | 292 bt = self.the_type(expr.base.typ) |
287 offset = ir.Const(bt.fieldOffset(expr.field)) | 293 offset = ir.Const(bt.fieldOffset(expr.field)) |
288 return ir.Mem(ir.Add(base.e, offset)) | 294 return ir.Mem(ir.Add(base.e, offset)) |
289 elif type(expr) is ast.Index: | 295 elif type(expr) is ast.Index: |
290 """ Array indexing """ | 296 """ Array indexing """ |
291 base = self.genExprCode(expr.base) | 297 base = self.gen_expr_code(expr.base) |
292 idx = self.genExprCode(expr.i) | 298 idx = self.gen_expr_code(expr.i) |
293 base_typ = self.the_type(expr.base.typ) | 299 base_typ = self.the_type(expr.base.typ) |
294 if not isinstance(base_typ, ast.ArrayType): | 300 if not isinstance(base_typ, ast.ArrayType): |
295 raise SemanticError('Cannot index non-array type {}' | 301 raise SemanticError('Cannot index non-array type {}' |
296 .format(base_typ), | 302 .format(base_typ), |
297 expr.base.loc) | 303 expr.base.loc) |
323 return ir.Addr(ir.Const(cval)) | 329 return ir.Addr(ir.Const(cval)) |
324 else: | 330 else: |
325 return ir.Const(expr.val) | 331 return ir.Const(expr.val) |
326 elif type(expr) is ast.TypeCast: | 332 elif type(expr) is ast.TypeCast: |
327 return self.gen_type_cast(expr) | 333 return self.gen_type_cast(expr) |
334 elif type(expr) is ast.Sizeof: | |
335 # The type of this expression is int: | |
336 expr.typ = self.intType | |
337 self.check_type(expr.query_typ) | |
338 type_size = self.size_of(expr.query_typ) | |
339 return ir.Const(type_size) | |
328 elif type(expr) is ast.FunctionCall: | 340 elif type(expr) is ast.FunctionCall: |
329 return self.gen_function_call(expr) | 341 return self.gen_function_call(expr) |
330 else: | 342 else: |
331 raise NotImplementedError('Unknown expr {}'.format(expr)) | 343 raise NotImplementedError('Unknown expr {}'.format(expr)) |
332 | 344 |
336 data = txt.encode('ascii') | 348 data = txt.encode('ascii') |
337 return length + data | 349 return length + data |
338 | 350 |
339 def gen_type_cast(self, expr): | 351 def gen_type_cast(self, expr): |
340 """ Generate code for type casting """ | 352 """ Generate code for type casting """ |
341 ar = self.genExprCode(expr.a) | 353 ar = self.gen_expr_code(expr.a) |
342 from_type = self.the_type(expr.a.typ) | 354 from_type = self.the_type(expr.a.typ) |
343 to_type = self.the_type(expr.to_type) | 355 to_type = self.the_type(expr.to_type) |
344 if isinstance(from_type, ast.PointerType) and \ | 356 if isinstance(from_type, ast.PointerType) and \ |
345 isinstance(to_type, ast.PointerType): | 357 isinstance(to_type, ast.PointerType): |
346 expr.typ = expr.to_type | 358 expr.typ = expr.to_type |
362 .format(from_type, to_type), expr.loc) | 374 .format(from_type, to_type), expr.loc) |
363 | 375 |
364 def gen_function_call(self, expr): | 376 def gen_function_call(self, expr): |
365 """ Generate code for a function call """ | 377 """ Generate code for a function call """ |
366 # Evaluate the arguments: | 378 # Evaluate the arguments: |
367 args = [self.genExprCode(e) for e in expr.args] | 379 args = [self.gen_expr_code(e) for e in expr.args] |
368 # Check arguments: | 380 # Check arguments: |
369 tg = self.resolveSymbol(expr.proc) | 381 tg = self.resolveSymbol(expr.proc) |
370 if type(tg) is not ast.Function: | 382 if type(tg) is not ast.Function: |
371 raise SemanticError('cannot call {}'.format(tg)) | 383 raise SemanticError('cannot call {}'.format(tg)) |
372 ftyp = tg.typ | 384 ftyp = tg.typ |