Mercurial > lcfOS
diff 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 |
line wrap: on
line diff
--- a/python/ppci/c3/codegenerator.py Sun Mar 09 18:49:10 2014 +0100 +++ b/python/ppci/c3/codegenerator.py Thu Mar 13 18:59:06 2014 +0100 @@ -1,4 +1,5 @@ import logging +import struct from .. import ir from .. import irutils from . import astnodes as ast @@ -200,6 +201,8 @@ self.emit(ir.Jump(bbfalse)) else: raise NotImplementedError('Unknown cond {}'.format(expr)) + + # Check that the condition is a boolean value: if not self.equalTypes(expr.typ, self.boolType): self.error('Condition must be boolean', expr.loc) @@ -272,6 +275,23 @@ bt = self.the_type(expr.base.typ) offset = ir.Const(bt.fieldOffset(expr.field)) return ir.Mem(ir.Add(base.e, offset)) + elif type(expr) is ast.Index: + """ Array indexing """ + base = self.genExprCode(expr.base) + idx = self.genExprCode(expr.i) + base_typ = self.the_type(expr.base.typ) + if not isinstance(base_typ, ast.ArrayType): + raise SemanticError('Cannot index non-array type {}'.format(base_typ), expr.base.loc) + idx_type = self.the_type(expr.i.typ) + if not self.equalTypes(idx_type, self.intType): + raise SemanticError('Index must be int not {}'.format(idx_type), expr.i.loc) + assert type(base) is ir.Mem + element_type = self.the_type(base_typ.element_type) + element_size = self.size_of(element_type) + expr.typ = base_typ.element_type + expr.lvalue = True + + return ir.Mem(ir.Add(base.e, ir.Mul(idx, ir.Const(element_size)))) elif type(expr) is ast.Literal: expr.lvalue = False typemap = {int: 'int', float: 'double', bool: 'bool', str:'string'} @@ -279,7 +299,12 @@ expr.typ = self.pkg.scope[typemap[type(expr.val)]] else: raise SemanticError('Unknown literal type {}'.format(expr.val), expr.loc) - return ir.Const(expr.val) + # Construct correct const value: + if type(expr.val) is str: + cval = struct.pack('<I', len(expr.val)) + expr.val.encode('ascii') + return ir.Addr(ir.Const(cval)) + else: + return ir.Const(expr.val) elif type(expr) is ast.TypeCast: return self.gen_type_cast(expr) elif type(expr) is ast.FunctionCall: @@ -299,6 +324,10 @@ isinstance(to_type, ast.PointerType): expr.typ = expr.to_type return ar + elif type(from_type) is ast.BaseType and from_type.name == 'byte' and \ + type(to_type) is ast.BaseType and to_type.name == 'int': + expr.typ = expr.to_type + return ar else: raise SemanticError('Cannot cast {} to {}' .format(from_type, to_type), expr.loc) @@ -357,6 +386,8 @@ return t.bytesize elif type(t) is ast.StructureType: return sum(self.size_of(mem.typ) for mem in t.mems) + elif type(t) is ast.ArrayType: + return t.size * self.size_of(t.element_type) else: raise NotImplementedError(str(t)) @@ -395,6 +426,8 @@ return False return all(self.equalTypes(am.typ, bm.typ) for am, bm in zip(a.mems, b.mems)) + elif type(a) is ast.ArrayType: + return self.equalTypes(a.element_type, b.element_type) else: raise NotImplementedError('{} not implemented'.format(type(a))) return False