Mercurial > lcfOS
comparison python/ppci/c3/codegenerator.py @ 354:5477e499b039
Added some sort of string functionality
author | Windel Bouwman |
---|---|
date | Thu, 13 Mar 2014 18:59:06 +0100 |
parents | b8ad45b3a573 |
children | 42343d189e14 |
comparison
equal
deleted
inserted
replaced
353:b8ad45b3a573 | 354:5477e499b039 |
---|---|
1 import logging | 1 import logging |
2 import struct | |
2 from .. import ir | 3 from .. import ir |
3 from .. import irutils | 4 from .. import irutils |
4 from . import astnodes as ast | 5 from . import astnodes as ast |
5 | 6 |
6 | 7 |
198 self.emit(ir.Jump(bbtrue)) | 199 self.emit(ir.Jump(bbtrue)) |
199 else: | 200 else: |
200 self.emit(ir.Jump(bbfalse)) | 201 self.emit(ir.Jump(bbfalse)) |
201 else: | 202 else: |
202 raise NotImplementedError('Unknown cond {}'.format(expr)) | 203 raise NotImplementedError('Unknown cond {}'.format(expr)) |
204 | |
205 # Check that the condition is a boolean value: | |
203 if not self.equalTypes(expr.typ, self.boolType): | 206 if not self.equalTypes(expr.typ, self.boolType): |
204 self.error('Condition must be boolean', expr.loc) | 207 self.error('Condition must be boolean', expr.loc) |
205 | 208 |
206 def genExprCode(self, expr): | 209 def genExprCode(self, expr): |
207 """ Generate code for an expression. Return the generated ir-value """ | 210 """ Generate code for an expression. Return the generated ir-value """ |
270 | 273 |
271 assert type(base) is ir.Mem, type(base) | 274 assert type(base) is ir.Mem, type(base) |
272 bt = self.the_type(expr.base.typ) | 275 bt = self.the_type(expr.base.typ) |
273 offset = ir.Const(bt.fieldOffset(expr.field)) | 276 offset = ir.Const(bt.fieldOffset(expr.field)) |
274 return ir.Mem(ir.Add(base.e, offset)) | 277 return ir.Mem(ir.Add(base.e, offset)) |
278 elif type(expr) is ast.Index: | |
279 """ Array indexing """ | |
280 base = self.genExprCode(expr.base) | |
281 idx = self.genExprCode(expr.i) | |
282 base_typ = self.the_type(expr.base.typ) | |
283 if not isinstance(base_typ, ast.ArrayType): | |
284 raise SemanticError('Cannot index non-array type {}'.format(base_typ), expr.base.loc) | |
285 idx_type = self.the_type(expr.i.typ) | |
286 if not self.equalTypes(idx_type, self.intType): | |
287 raise SemanticError('Index must be int not {}'.format(idx_type), expr.i.loc) | |
288 assert type(base) is ir.Mem | |
289 element_type = self.the_type(base_typ.element_type) | |
290 element_size = self.size_of(element_type) | |
291 expr.typ = base_typ.element_type | |
292 expr.lvalue = True | |
293 | |
294 return ir.Mem(ir.Add(base.e, ir.Mul(idx, ir.Const(element_size)))) | |
275 elif type(expr) is ast.Literal: | 295 elif type(expr) is ast.Literal: |
276 expr.lvalue = False | 296 expr.lvalue = False |
277 typemap = {int: 'int', float: 'double', bool: 'bool', str:'string'} | 297 typemap = {int: 'int', float: 'double', bool: 'bool', str:'string'} |
278 if type(expr.val) in typemap: | 298 if type(expr.val) in typemap: |
279 expr.typ = self.pkg.scope[typemap[type(expr.val)]] | 299 expr.typ = self.pkg.scope[typemap[type(expr.val)]] |
280 else: | 300 else: |
281 raise SemanticError('Unknown literal type {}'.format(expr.val), expr.loc) | 301 raise SemanticError('Unknown literal type {}'.format(expr.val), expr.loc) |
282 return ir.Const(expr.val) | 302 # Construct correct const value: |
303 if type(expr.val) is str: | |
304 cval = struct.pack('<I', len(expr.val)) + expr.val.encode('ascii') | |
305 return ir.Addr(ir.Const(cval)) | |
306 else: | |
307 return ir.Const(expr.val) | |
283 elif type(expr) is ast.TypeCast: | 308 elif type(expr) is ast.TypeCast: |
284 return self.gen_type_cast(expr) | 309 return self.gen_type_cast(expr) |
285 elif type(expr) is ast.FunctionCall: | 310 elif type(expr) is ast.FunctionCall: |
286 return self.gen_function_call(expr) | 311 return self.gen_function_call(expr) |
287 else: | 312 else: |
295 if isinstance(from_type, ast.PointerType) and isinstance(to_type, ast.PointerType): | 320 if isinstance(from_type, ast.PointerType) and isinstance(to_type, ast.PointerType): |
296 expr.typ = expr.to_type | 321 expr.typ = expr.to_type |
297 return ar | 322 return ar |
298 elif type(from_type) is ast.BaseType and from_type.name == 'int' and \ | 323 elif type(from_type) is ast.BaseType and from_type.name == 'int' and \ |
299 isinstance(to_type, ast.PointerType): | 324 isinstance(to_type, ast.PointerType): |
325 expr.typ = expr.to_type | |
326 return ar | |
327 elif type(from_type) is ast.BaseType and from_type.name == 'byte' and \ | |
328 type(to_type) is ast.BaseType and to_type.name == 'int': | |
300 expr.typ = expr.to_type | 329 expr.typ = expr.to_type |
301 return ar | 330 return ar |
302 else: | 331 else: |
303 raise SemanticError('Cannot cast {} to {}' | 332 raise SemanticError('Cannot cast {} to {}' |
304 .format(from_type, to_type), expr.loc) | 333 .format(from_type, to_type), expr.loc) |
355 t = self.the_type(t) | 384 t = self.the_type(t) |
356 if type(t) is ast.BaseType: | 385 if type(t) is ast.BaseType: |
357 return t.bytesize | 386 return t.bytesize |
358 elif type(t) is ast.StructureType: | 387 elif type(t) is ast.StructureType: |
359 return sum(self.size_of(mem.typ) for mem in t.mems) | 388 return sum(self.size_of(mem.typ) for mem in t.mems) |
389 elif type(t) is ast.ArrayType: | |
390 return t.size * self.size_of(t.element_type) | |
360 else: | 391 else: |
361 raise NotImplementedError(str(t)) | 392 raise NotImplementedError(str(t)) |
362 | 393 |
363 def the_type(self, t): | 394 def the_type(self, t): |
364 """ Recurse until a 'real' type is found """ | 395 """ Recurse until a 'real' type is found """ |
393 elif type(a) is ast.StructureType: | 424 elif type(a) is ast.StructureType: |
394 if len(a.mems) != len(b.mems): | 425 if len(a.mems) != len(b.mems): |
395 return False | 426 return False |
396 return all(self.equalTypes(am.typ, bm.typ) for am, bm in | 427 return all(self.equalTypes(am.typ, bm.typ) for am, bm in |
397 zip(a.mems, b.mems)) | 428 zip(a.mems, b.mems)) |
429 elif type(a) is ast.ArrayType: | |
430 return self.equalTypes(a.element_type, b.element_type) | |
398 else: | 431 else: |
399 raise NotImplementedError('{} not implemented'.format(type(a))) | 432 raise NotImplementedError('{} not implemented'.format(type(a))) |
400 return False | 433 return False |