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