Mercurial > lcfOS
comparison python/ppci/c3/codegenerator.py @ 316:56e6ff84f646
Fixed burn led demo
author | Windel Bouwman |
---|---|
date | Sat, 21 Dec 2013 13:13:26 +0100 |
parents | 084cccaa5deb |
children | 6f4753202b9a |
comparison
equal
deleted
inserted
replaced
315:084cccaa5deb | 316:56e6ff84f646 |
---|---|
53 | 53 |
54 def error(self, msg, loc=None): | 54 def error(self, msg, loc=None): |
55 self.pkg.ok = False | 55 self.pkg.ok = False |
56 self.diag.error(msg, loc) | 56 self.diag.error(msg, loc) |
57 | 57 |
58 def checkType(self, t): | |
59 """ Verify the type is correct """ | |
60 t = self.theType(t) | |
61 | |
62 def gen_function(self, fn): | 58 def gen_function(self, fn): |
63 # TODO: handle arguments | 59 # TODO: handle arguments |
64 f = self.funcMap[fn] | 60 f = self.funcMap[fn] |
65 f.return_value = self.newTemp() | 61 f.return_value = self.newTemp() |
66 self.setFunction(f) | 62 self.setFunction(f) |
68 self.emit(ir.Jump(l2)) | 64 self.emit(ir.Jump(l2)) |
69 self.setBlock(l2) | 65 self.setBlock(l2) |
70 # generate room for locals: | 66 # generate room for locals: |
71 | 67 |
72 for sym in fn.innerScope: | 68 for sym in fn.innerScope: |
73 # TODO: handle parameters different | 69 self.the_type(sym.typ) |
74 self.checkType(sym.typ) | |
75 if sym.isParameter: | 70 if sym.isParameter: |
76 variable = ir.Parameter(sym.name) | 71 p = ir.Parameter(sym.name) |
77 f.addParameter(variable) | 72 variable = ir.LocalVariable(sym.name + '_copy') |
73 f.addParameter(p) | |
74 f.addLocal(variable) | |
75 # Move parameter into local copy: | |
76 self.emit(ir.Move(ir.Mem(variable), p)) | |
78 elif sym.isLocal: | 77 elif sym.isLocal: |
79 variable = ir.LocalVariable(sym.name) | 78 variable = ir.LocalVariable(sym.name) |
80 f.addLocal(variable) | 79 f.addLocal(variable) |
81 elif isinstance(sym, ast.Variable): | 80 elif isinstance(sym, ast.Variable): |
82 variable = ir.LocalVariable(sym.name) | 81 variable = ir.LocalVariable(sym.name) |
246 else: | 245 else: |
247 raise NotImplementedError(str(tg)) | 246 raise NotImplementedError(str(tg)) |
248 elif type(expr) is ast.Deref: | 247 elif type(expr) is ast.Deref: |
249 # dereference pointer type: | 248 # dereference pointer type: |
250 addr = self.genExprCode(expr.ptr) | 249 addr = self.genExprCode(expr.ptr) |
251 ptr_typ = self.theType(expr.ptr.typ) | 250 ptr_typ = self.the_type(expr.ptr.typ) |
252 expr.lvalue = True | 251 expr.lvalue = True |
253 if type(ptr_typ) is ast.PointerType: | 252 if type(ptr_typ) is ast.PointerType: |
254 expr.typ = ptr_typ.ptype | 253 expr.typ = ptr_typ.ptype |
255 return ir.Mem(addr) | 254 return ir.Mem(addr) |
256 else: | 255 else: |
257 raise SemanticError('Cannot deref non-pointer', expr.loc) | 256 raise SemanticError('Cannot deref non-pointer', expr.loc) |
258 elif type(expr) is ast.Member: | 257 elif type(expr) is ast.Member: |
259 base = self.genExprCode(expr.base) | 258 base = self.genExprCode(expr.base) |
260 expr.lvalue = expr.base.lvalue | 259 expr.lvalue = expr.base.lvalue |
261 basetype = self.theType(expr.base.typ) | 260 basetype = self.the_type(expr.base.typ) |
262 if type(basetype) is ast.StructureType: | 261 if type(basetype) is ast.StructureType: |
263 if basetype.hasField(expr.field): | 262 if basetype.hasField(expr.field): |
264 expr.typ = basetype.fieldType(expr.field) | 263 expr.typ = basetype.fieldType(expr.field) |
265 else: | 264 else: |
266 raise SemanticError('{} does not contain field {}' | 265 raise SemanticError('{} does not contain field {}' |
268 else: | 267 else: |
269 raise SemanticError('Cannot select {} of non-structure type {}' | 268 raise SemanticError('Cannot select {} of non-structure type {}' |
270 .format(expr.field, basetype), expr.loc) | 269 .format(expr.field, basetype), expr.loc) |
271 | 270 |
272 assert type(base) is ir.Mem, type(base) | 271 assert type(base) is ir.Mem, type(base) |
273 bt = self.theType(expr.base.typ) | 272 bt = self.the_type(expr.base.typ) |
274 offset = ir.Const(bt.fieldOffset(expr.field)) | 273 offset = ir.Const(bt.fieldOffset(expr.field)) |
275 return ir.Mem(ir.Add(base.e, offset)) | 274 return ir.Mem(ir.Add(base.e, offset)) |
276 elif type(expr) is ast.Literal: | 275 elif type(expr) is ast.Literal: |
277 expr.lvalue = False | 276 expr.lvalue = False |
278 typemap = {int: 'int', float: 'double', bool: 'bool', str:'string'} | 277 typemap = {int: 'int', float: 'double', bool: 'bool', str:'string'} |
289 raise NotImplementedError('Unknown expr {}'.format(expr)) | 288 raise NotImplementedError('Unknown expr {}'.format(expr)) |
290 | 289 |
291 def gen_type_cast(self, expr): | 290 def gen_type_cast(self, expr): |
292 """ Generate code for type casting """ | 291 """ Generate code for type casting """ |
293 ar = self.genExprCode(expr.a) | 292 ar = self.genExprCode(expr.a) |
294 from_type = self.theType(expr.a.typ) | 293 from_type = self.the_type(expr.a.typ) |
295 to_type = self.theType(expr.to_type) | 294 to_type = self.the_type(expr.to_type) |
296 if isinstance(from_type, ast.PointerType) and isinstance(to_type, ast.PointerType): | 295 if isinstance(from_type, ast.PointerType) and isinstance(to_type, ast.PointerType): |
297 expr.typ = expr.to_type | 296 expr.typ = expr.to_type |
298 return ar | 297 return ar |
299 elif type(from_type) is ast.BaseType and from_type.name == 'int' and \ | 298 elif type(from_type) is ast.BaseType and from_type.name == 'int' and \ |
300 isinstance(to_type, ast.PointerType): | 299 isinstance(to_type, ast.PointerType): |
349 else: | 348 else: |
350 raise SemanticError('{} undefined'.format(name), sym.loc) | 349 raise SemanticError('{} undefined'.format(name), sym.loc) |
351 assert isinstance(s, ast.Symbol) | 350 assert isinstance(s, ast.Symbol) |
352 return s | 351 return s |
353 | 352 |
354 def theType(self, t): | 353 def size_of(self, t): |
354 """ Determine the byte size of a type """ | |
355 t = self.the_type(t) | |
356 if type(t) is ast.BaseType: | |
357 return t.bytesize | |
358 elif type(t) is ast.StructureType: | |
359 return sum(self.size_of(mem.typ) for mem in t.mems) | |
360 else: | |
361 raise NotImplementedError(str(t)) | |
362 | |
363 def the_type(self, t): | |
355 """ Recurse until a 'real' type is found """ | 364 """ Recurse until a 'real' type is found """ |
356 if type(t) is ast.DefinedType: | 365 if type(t) is ast.DefinedType: |
357 t = self.theType(t.typ) | 366 t = self.the_type(t.typ) |
358 elif type(t) in [ast.Identifier, ast.Member]: | 367 elif type(t) in [ast.Identifier, ast.Member]: |
359 t = self.theType(self.resolveSymbol(t)) | 368 t = self.the_type(self.resolveSymbol(t)) |
369 elif type(t) is ast.StructureType: | |
370 # Setup offsets of fields. Is this the right place?: | |
371 offset = 0 | |
372 for mem in t.mems: | |
373 mem.offset = offset | |
374 offset = offset + self.size_of(mem.typ) | |
360 elif isinstance(t, ast.Type): | 375 elif isinstance(t, ast.Type): |
361 pass | 376 pass |
362 else: | 377 else: |
363 raise NotImplementedError(str(t)) | 378 raise NotImplementedError(str(t)) |
364 assert isinstance(t, ast.Type) | 379 assert isinstance(t, ast.Type) |
365 return t | 380 return t |
366 | 381 |
367 def equalTypes(self, a, b): | 382 def equalTypes(self, a, b): |
368 """ Compare types a and b for structural equavalence. """ | 383 """ Compare types a and b for structural equavalence. """ |
369 # Recurse into named types: | 384 # Recurse into named types: |
370 a = self.theType(a) | 385 a = self.the_type(a) |
371 b = self.theType(b) | 386 b = self.the_type(b) |
372 assert isinstance(a, ast.Type) | |
373 assert isinstance(b, ast.Type) | |
374 | 387 |
375 if type(a) is type(b): | 388 if type(a) is type(b): |
376 if type(a) is ast.BaseType: | 389 if type(a) is ast.BaseType: |
377 return a.name == b.name | 390 return a.name == b.name |
378 elif type(a) is ast.PointerType: | 391 elif type(a) is ast.PointerType: |