changeset 225:1c7364bd74c7

Fixed pointer deref
author Windel Bouwman
date Thu, 11 Jul 2013 07:42:30 +0200
parents 5af52987f5bd
children 240111e0456f
files python/asmnodes.py python/c3/analyse.py python/c3/astnodes.py python/c3/builder.py python/c3/codegenerator.py python/c3/lexer.py python/c3/parser.py python/c3/typecheck.py python/c3/visitor.py python/codegenarm.py python/cortexm3.py python/outstream.py python/ppci/errors.py python/testc3.py python/transform.py
diffstat 15 files changed, 230 insertions(+), 113 deletions(-) [+]
line wrap: on
line diff
--- a/python/asmnodes.py	Tue Jul 09 17:59:15 2013 +0200
+++ b/python/asmnodes.py	Thu Jul 11 07:42:30 2013 +0200
@@ -11,6 +11,12 @@
     def __repr__(self):
         return '{0}:'.format(self.name)
 
+class AComment(ANode):
+    def __init__(self, name):
+        self.txt = name
+    def __repr__(self):
+        return '; {}'.format(self.txt)
+
 class AInstruction(ANode):
     def __init__(self, mnemonic, operands):
         self.mnemonic = mnemonic
--- a/python/c3/analyse.py	Tue Jul 09 17:59:15 2013 +0200
+++ b/python/c3/analyse.py	Thu Jul 11 07:42:30 2013 +0200
@@ -44,6 +44,8 @@
         # Add symbols to current scope:
         if isinstance(sym, Symbol):
             self.addSymbol(sym)
+        if isinstance(sym, DefinedType):
+            self.addSymbol(sym)
 
         # Create subscope:
         if type(sym) in [Package, Function]:
@@ -78,8 +80,11 @@
             return t
         elif type(t) is Designator:
             return self.resolveDesignator(t, scope)
+        elif isinstance(t, Type):
+            # Already resolved??
+            return t
         else:
-            print('ERR resolve type!')
+            raise Exception('Error resolving type {} {}'.format(t, type(t)))
         
     def findRefs(self, sym):
         if type(sym) in [Variable, Constant]:
--- a/python/c3/astnodes.py	Tue Jul 09 17:59:15 2013 +0200
+++ b/python/c3/astnodes.py	Thu Jul 11 07:42:30 2013 +0200
@@ -59,6 +59,7 @@
 
 class PointerType(Type):
     def __init__(self, ptype):
+        assert isinstance(ptype, Type) or isinstance(ptype, Designator)
         self.ptype = ptype
     def __repr__(self):
         return '({}*)'.format(self.ptype)
@@ -66,13 +67,26 @@
 class StructureType(Type):
     def __init__(self, mems):
         self.mems = mems
+    def hasField(self, name):
+        for fn, ft in self.mems:
+            if name == fn:
+                return True
+        return False
+    def fieldType(self, name):
+        for fn, ft in self.mems:
+            if name == fn:
+                return ft
+        raise Exception()
+
 
 class DefinedType(Type):
-   def __init__(self, name, typ):
-      self.name = name
-      self.typ = typ
-   def __repr__(self):
-      return 'Named type {0} of type {1}'.format(self.name, self.typ)
+    def __init__(self, name, typ, loc):
+        assert isinstance(name, str)
+        self.name = name
+        self.typ = typ
+        self.loc = loc
+    def __repr__(self):
+        return 'Named type {0} of type {1}'.format(self.name, self.typ)
 
 class TypeCast(Node):
     def __init__(self, to_type, x):
@@ -109,7 +123,7 @@
       self.isReadOnly = False
       self.isParameter = False
    def __repr__(self):
-      return 'Var {}'.format(self.name)
+      return 'Var {} [{}]'.format(self.name, self.typ)
 
 # Procedure types
 class Function(Symbol):
@@ -126,6 +140,24 @@
 class Expression(Node):
     pass
 
+class Deref(Expression):
+    def __init__(self, ptr, loc):
+        assert isinstance(ptr, Expression)
+        self.ptr = ptr
+        self.loc = loc
+    def __repr__(self):
+      return 'DEREF {}'.format(self.ptr)
+
+class FieldRef(Expression):
+    def __init__(self, base, field, loc):
+        assert isinstance(base, Expression)
+        assert isinstance(field, str)
+        self.base = base
+        self.field = field
+        self.loc = loc
+    def __repr__(self):
+      return 'FIELD {}.{}'.format(self.base, self.field)
+
 class Unop(Expression):
     def __init__(self, op, a, loc):
         assert isinstance(a, Expression)
--- a/python/c3/builder.py	Tue Jul 09 17:59:15 2013 +0200
+++ b/python/c3/builder.py	Thu Jul 11 07:42:30 2013 +0200
@@ -1,5 +1,6 @@
 import ppci
 from . import Parser, TypeChecker, Analyzer, CodeGenerator
+from . astprinter import AstPrinter
 
 class Builder:
     """ 
@@ -19,6 +20,7 @@
             return
       self.pkg = pkg
       # TODO: merge the two below?
+      #AstPrinter().printAst(pkg)
       if not self.al.analyzePackage(pkg):
             return
       if not self.tc.checkPackage(pkg):
--- a/python/c3/codegenerator.py	Tue Jul 09 17:59:15 2013 +0200
+++ b/python/c3/codegenerator.py	Thu Jul 11 07:42:30 2013 +0200
@@ -124,7 +124,7 @@
       else:
          print('Unknown cond', expr)
     def genExprCode(self, expr):
-      if type(expr) is astnodes.Binop:
+        if type(expr) is astnodes.Binop:
          ra = self.genExprCode(expr.a)
          rb = self.genExprCode(expr.b)
          ops = ['+', '-', '*', '/', '|', '&']
@@ -140,37 +140,38 @@
             tmp = self.builder.newTmp()
             # TODO
             return tmp
-      elif type(expr) is astnodes.Unop:
-         ra = self.genExprCode(expr.a)
-         if expr.op == '&':
-            # Address of operator
-            tmp = self.builder.newTmp('addr')
+        elif type(expr) is astnodes.Unop:
+            ra = self.genExprCode(expr.a)
+            if expr.op == '&':
+                # Address of operator
+                tmp = self.builder.newTmp('addr')
+                return tmp
+                #self.builder.addIns(ins)
+            else:
+                raise Exception('Unknown {0}'.format(expr))
+        elif type(expr) is astnodes.Constant:
+            tmp = self.builder.newTmp()
+            # TODO
             return tmp
-            #self.builder.addIns(ins)
-         elif expr.op == '*':
+        elif type(expr) is astnodes.VariableUse:
+            tmp = self.builder.newTmp()
+            loc = self.varMap[expr.target]
+            i = ir.Load(loc, tmp)
+            self.builder.addIns(i)
+            return tmp
+        elif type(expr) is astnodes.Deref:
             # dereference pointer type:
+            addr = self.genExprCode(expr.ptr)
             tmp = self.builder.newTmp('deref')
-            ins = ir.Load(ra, tmp)
+            ins = ir.Load(addr, tmp)
             self.builder.addIns(ins)
             return tmp
-         else:
-            print('Unknown {0}'.format(expr))
-      elif type(expr) is astnodes.Constant:
-         tmp = self.builder.newTmp()
-         # TODO
-         return tmp
-      elif type(expr) is astnodes.VariableUse:
-         tmp = self.builder.newTmp()
-         loc = self.varMap[expr.target]
-         i = ir.Load(loc, tmp)
-         self.builder.addIns(i)
-         return tmp
-      elif type(expr) is astnodes.Literal:
-         tmp = self.builder.newTmp()
-         ins = ir.ImmLoad(tmp, expr.val)
-         self.builder.addIns(ins)
-         return tmp
-      elif type(expr) is astnodes.TypeCast:
+        elif type(expr) is astnodes.Literal:
+            tmp = self.builder.newTmp()
+            ins = ir.ImmLoad(tmp, expr.val)
+            self.builder.addIns(ins)
+            return tmp
+        elif type(expr) is astnodes.TypeCast:
             ar = self.genExprCode(expr.a)
             if isinstance(expr.to_type, astnodes.PointerType):
                 if expr.a.typ is intType:
@@ -179,7 +180,7 @@
                     return ar
                 else:
                     raise Exception()
-      elif type(expr) is astnodes.FunctionCall:
+        elif type(expr) is astnodes.FunctionCall:
          tmp = self.builder.newTmp("res")
          args = []
          for arg in expr.args:
@@ -189,6 +190,6 @@
          ins = ir.Call(fn, args, tmp)
          self.builder.addIns(ins)
          return tmp
-      else:
+        else:
          raise CompilerError('Unknown expr {}'.format(expr))
 
--- a/python/c3/lexer.py	Tue Jul 09 17:59:15 2013 +0200
+++ b/python/c3/lexer.py	Thu Jul 11 07:42:30 2013 +0200
@@ -29,7 +29,7 @@
        ('COMMENTS', r'//.*'),
        ('LONGCOMMENTBEGIN', r'\/\*'),
        ('LONGCOMMENTEND', r'\*\/'),
-       ('LEESTEKEN', r'==|[\.,=:;\-+*\[\]/\(\)]|>=|<=|<>|>|<|{|}|&|\^|\|'),
+       ('LEESTEKEN', r'==|->|[\.,=:;\-+*\[\]/\(\)]|>=|<=|<>|>|<|{|}|&|\^|\|'),
        ('STRING', r"'.*?'")
      ]
      tok_re = '|'.join('(?P<%s>%s)' % pair for pair in tok_spec)
--- a/python/c3/parser.py	Tue Jul 09 17:59:15 2013 +0200
+++ b/python/c3/parser.py	Thu Jul 11 07:42:30 2013 +0200
@@ -75,10 +75,9 @@
          self.Error('Expected function, var, const or type')
 
     def parseDesignator(self):
-      """ A designator designates an object """
-      name = self.Consume('ID')
-      d = astnodes.Designator(name.val, name.loc)
-      return d
+        """ A designator designates an object """
+        name = self.Consume('ID')
+        return astnodes.Designator(name.val, name.loc)
 
     # Type system
     def parseTypeSpec(self):
@@ -109,9 +108,9 @@
         self.Consume('type')
         newtype = self.parseTypeSpec()
         typename = self.Consume('ID')
-        # TODO: action here :)
         self.Consume(';')
-        return astnodes.DefinedType(typename, newtype)
+        df = astnodes.DefinedType(typename.val, newtype, typename.loc)
+        self.addDeclaration(df)
 
     # Variable declarations:
     def parseVarDef(self):
@@ -319,7 +318,10 @@
         if self.Peak in ['&', '*']:
             op = self.Consume(self.Peak)
             ce = self.CastExpression()
-            return astnodes.Unop(op.typ, ce, op.loc)
+            if op.val == '*':
+                return astnodes.Deref(ce, op.loc)
+            else:
+                return astnodes.Unop(op.typ, ce, op.loc)
         else:
             return self.PostFixExpression()
 
@@ -337,8 +339,15 @@
                         args.append(self.Expression())
                     self.Consume(')')
                 pfe = astnodes.FunctionCall(pfe, args, pfe.loc)
+            elif self.hasConsumed('->'):
+                field = self.Consume('ID')
+                pfe = astnodes.Deref(pfe, pfe.loc)
+                pfe = astnodes.FieldRef(pfe, field.val, field.loc)
+            elif self.hasConsumed('.'):
+                field = self.Consume('ID')
+                pfe = astnodes.FieldRef(pfe, field.val, field.loc)
             else:
-                rrrr
+                raise Exception()
         return pfe
 
     def PrimaryExpression(self):
--- a/python/c3/typecheck.py	Tue Jul 09 17:59:15 2013 +0200
+++ b/python/c3/typecheck.py	Thu Jul 11 07:42:30 2013 +0200
@@ -34,19 +34,19 @@
         return self.ok
 
     def check2(self, sym):
-      if type(sym) in [IfStatement, WhileStatement]:
-         if not equalTypes(sym.condition.typ, boolType):
-            self.error('Condition must be of type {0}'.format(boolType), sym.condition.loc)
-      elif type(sym) is Assignment:
+        if type(sym) in [IfStatement, WhileStatement]:
+            if not equalTypes(sym.condition.typ, boolType):
+                self.error('Condition must be of type {0}'.format(boolType), sym.condition.loc)
+        elif type(sym) is Assignment:
             if not equalTypes(sym.lval.typ, sym.rval.typ):
                 self.error('Cannot assign {0} to {1}'.format(sym.rval.typ, sym.lval.typ), sym.loc)
             if not sym.lval.lvalue:
                 self.error('No valid lvalue {}'.format(sym.lval), sym.lval.loc)
             #if sym.rval.lvalue:
             #    self.error('Right hand side must be an rvalue', sym.rval.loc)
-      elif type(sym) is ReturnStatement:
-         pass
-      elif type(sym) is FunctionCall:
+        elif type(sym) is ReturnStatement:
+            pass
+        elif type(sym) is FunctionCall:
          if sym.proc:
             # Check arguments:
             ngiv = len(sym.args)
@@ -62,13 +62,14 @@
             sym.typ = sym.proc.typ.returntype
          else:
             sym.typ = intType
-      elif type(sym) is VariableUse:
+        elif type(sym) is VariableUse:
             sym.lvalue = True
-            if sym.target:
+            if type(sym.target) is Variable:
                 sym.typ = sym.target.typ
             else:
+                print('warning {} has no target, defaulting to int'.format(sym))
                 sym.typ = intType
-      elif type(sym) is Literal:
+        elif type(sym) is Literal:
             sym.lvalue = False
             if type(sym.val) is int:
                 sym.typ = intType
@@ -77,22 +78,35 @@
             elif type(sym.val) is bool:
                 sym.typ = boolType
             else:
-                self.error('Unknown literal type', sym.loc)
-      elif type(sym) is Unop:
+                raise Exception('Unknown literal type'.format(sym.val))
+        elif type(sym) is Unop:
             if sym.op == '&':
                 sym.typ = PointerType(sym.a.typ)
                 sym.lvalue = False
-            elif sym.op == '*':
-                # pointer deref
-                sym.lvalue = True
-                if type(sym.a.typ) is PointerType:
-                    sym.typ = sym.a.typ.ptype
+            else:
+                raise Exception('Unknown unop {0}'.format(sym.op))
+        elif type(sym) is Deref:
+            # pointer deref
+            sym.lvalue = True
+            # check if the to be dereferenced variable is a pointer type:
+            if type(sym.ptr.typ) is PointerType:
+                sym.typ = sym.ptr.typ.ptype
+            else:
+                self.error('Cannot dereference non-pointer type {}'.format(sym.ptr.typ), sym.loc)
+                sym.typ = intType
+        elif type(sym) is FieldRef:
+            basetype = sym.base.typ
+            sym.lvalue = True
+            if type(basetype) is StructureType:
+                if basetype.hasField(sym.field):
+                    sym.typ = basetype.fieldType(sym.field)
                 else:
+                    self.error('{} does not contain field {}'.format(basetype, symfield), sym.loc)
                     sym.typ = intType
-                    self.error('Cannot dereference non-pointer type {}'.format(sym.a.typ), sym.loc)
             else:
-                print('unknown unop', sym.op)
-      elif type(sym) is Binop:
+                self.error('Cannot select field {} of non-structure type {}'.format(sym.field, basetype), sym.loc)
+                sym.typ = intType
+        elif type(sym) is Binop:
          sym.lvalue = False
          if sym.op in ['+', '-', '*', '/']:
             if equalTypes(sym.a.typ, sym.b.typ):
@@ -104,11 +118,11 @@
             else:
                # assume void here? TODO: throw exception!
                sym.typ = intType
-               self.error('Types unequal', sym.loc)
+               self.error('Types unequal {} != {}'.format(sym.a.typ, sym.b.typ), sym.loc)
          elif sym.op in ['>', '<', '==', '<=', '>=']:
             sym.typ = boolType
             if not equalTypes(sym.a.typ, sym.b.typ):
-               self.error('Types unequal', sym.loc)
+               self.error('Types unequal {} != {}'.format(sym.a.typ, sym.b.typ), sym.loc)
          elif sym.op in ['or', 'and']:
             sym.typ = boolType
             if not equalTypes(sym.a.typ, boolType):
@@ -117,24 +131,24 @@
                self.error('Must be {0}'.format(boolType), sym.b.loc)
          elif sym.op in ['|', '&']:
                 sym.typ = intType
+                raise Exception('Not implemented')
                 # TODO: elaborate?
          else:
-            sym.typ = voidType
-            print('unknown binop', sym.op)
-      elif type(sym) is Variable:
+            raise Exception('Unknown binop {0}'.format(sym.op))
+        elif type(sym) is Variable:
          # check initial value type:
          # TODO
          pass
-      elif type(sym) is TypeCast:
+        elif type(sym) is TypeCast:
             if canCast(sym.a.typ, sym.to_type):
                 sym.typ = sym.to_type
             else:
                 self.error('Cannot cast {} to {}'.format(sym.a.typ, sym.to_type))
-      elif type(sym) is Constant:
-         if not equalTypes(sym.typ, sym.value.typ):
-            self.error('Cannot assign {0} to {1}'.format(sym.value.typ, sym.typ), sym.loc)
-      elif type(sym) in [EmptyStatement, CompoundStatement, Package, Function, FunctionType, ExpressionStatement]:
+        elif type(sym) is Constant:
+            if not equalTypes(sym.typ, sym.value.typ):
+                self.error('Cannot assign {0} to {1}'.format(sym.value.typ, sym.typ), sym.loc)
+        elif type(sym) in [EmptyStatement, CompoundStatement, Package, Function, FunctionType, ExpressionStatement, DefinedType]:
          pass
-      else:
+        else:
             raise Exception('Unknown type check {0}'.format(sym))
 
--- a/python/c3/visitor.py	Tue Jul 09 17:59:15 2013 +0200
+++ b/python/c3/visitor.py	Thu Jul 11 07:42:30 2013 +0200
@@ -47,9 +47,13 @@
             self.do(node.ex)
       elif type(node) is TypeCast:
             self.do(node.a)
+      elif type(node) is FieldRef:
+            self.do(node.base)
+      elif type(node) is Deref:
+            self.do(node.ptr)
       elif type(node) is Constant:
          self.do(node.value)
-      elif type(node) in [EmptyStatement, VariableUse, Variable, Literal, FunctionType]:
+      elif type(node) in [EmptyStatement, VariableUse, Variable, Literal, FunctionType, DefinedType]:
          # Those nodes do not have child nodes.
          pass
       elif type(node) is WhileStatement:
--- a/python/codegenarm.py	Tue Jul 09 17:59:15 2013 +0200
+++ b/python/codegenarm.py	Thu Jul 11 07:42:30 2013 +0200
@@ -1,5 +1,5 @@
 import ir
-from asmnodes import ALabel
+from asmnodes import ALabel, AComment
 import cortexm3 as arm
 from ppci import CompilerError
 
@@ -47,6 +47,7 @@
                 self.emit(arm.dcd_ins(v))
             self.outs.align(4)
 
+    # Helper functions:
     def getStack(self, v):
         off = self.stack_frame.index(v)
         return off * 4
@@ -56,43 +57,53 @@
     def getGlobal(self, r, g):
         _global_address = g.name + '__global'
         self.emit(arm.ldr_pcrel(r, ALabel(_global_address)))
+    def loadStack(self, reg, val):
+        self.emit(arm.ldr_sprel(reg, arm.MemSpRel(self.getStack(val))))
+    def comment(self, txt):
+        self.emit(AComment(txt))
 
     def generateInstruction(self, ins):
         if type(ins) is ir.Branch:
             tgt = ALabel(ins.target.name)
             self.emit(arm.jmp_ins(tgt))
         elif type(ins) is ir.ImmLoad:
+            self.comment(str(ins))
             lname = ins.target.name + '_ivalue'
             self.emit(arm.ldr_pcrel(arm.r0, ALabel(lname)))
             self.imms.append((lname, ins.value))
-            self.emit(arm.str_sprel(arm.r0, arm.MemoryOp(arm.sp, self.addStack(ins.target))))
+            self.emit(arm.str_sprel(arm.r0, arm.MemSpRel(self.addStack(ins.target))))
         elif type(ins) is ir.Store:
+            self.comment(str(ins))
             # Load value in r0:
-            self.emit(arm.ldr_sprel(arm.r0, arm.MemoryOp(arm.sp, self.getStack(ins.value))))
+            self.loadStack(arm.r0, ins.value)
             # store in memory:
             self.getGlobal(arm.r1, ins.location)
-            self.emit(arm.storeimm5_ins(arm.r0, arm.MemoryOp(arm.r1, 0)))
+            self.emit(arm.storeimm5_ins(arm.r0, arm.MemR8Rel(arm.r1, 0)))
         elif type(ins) is ir.Load:
+            self.comment(str(ins))
             self.getGlobal(arm.r0, ins.location)
-            self.emit(arm.loadimm5_ins(arm.r0, arm.MemoryOp(arm.r0, 0)))
+            self.emit(arm.loadimm5_ins(arm.r0, arm.MemR8Rel(arm.r0, 0)))
             # Store value on stack:
-            self.emit(arm.str_sprel(arm.r0, arm.MemoryOp(arm.sp, self.addStack(ins.value))))
+            self.emit(arm.str_sprel(arm.r0, arm.MemSpRel(self.addStack(ins.value))))
         elif type(ins) is ir.BinaryOperator:
+            self.comment(str(ins))
             # Load operands:
-            self.emit(arm.ldr_sprel(arm.r0, arm.MemoryOp(arm.sp, self.getStack(ins.value1))))
-            self.emit(arm.ldr_sprel(arm.r1, arm.MemoryOp(arm.sp, self.getStack(ins.value2))))
+            self.loadStack(arm.r0, ins.value1)
+            self.loadStack(arm.r1, ins.value2)
             # do operation:
             if ins.operation == '+':
                 self.emit(arm.addregs_ins(arm.r0, arm.r0, arm.r1))
             else:
                 print('operation not implemented', ins.operation)
             # Store value back:
-            self.emit(arm.str_sprel(arm.r0, arm.MemoryOp(arm.sp, self.addStack(ins.result))))
+            self.emit(arm.str_sprel(arm.r0, arm.MemSpRel(self.addStack(ins.result))))
         elif type(ins) is ir.Return:
+            self.comment(str(ins))
             self.emit(arm.pop_ins(arm.RegisterSet({arm.r4, arm.r5, arm.r6, arm.r7, arm.pc})))
         elif type(ins) is ir.ConditionalBranch:
-            self.emit(arm.ldr_sprel(arm.r0, arm.MemoryOp(arm.sp, self.getStack(ins.a))))
-            self.emit(arm.ldr_sprel(arm.r1, arm.MemoryOp(arm.sp, self.getStack(ins.b))))
+            self.comment(str(ins))
+            self.loadStack(arm.r0, ins.a)
+            self.loadStack(arm.r1, ins.b)
             self.emit(arm.cmp_ins(arm.r1, arm.r0))
             tgt_yes = ALabel(ins.lab1.name)
             if ins.cond == '==':
--- a/python/cortexm3.py	Tue Jul 09 17:59:15 2013 +0200
+++ b/python/cortexm3.py	Thu Jul 11 07:42:30 2013 +0200
@@ -101,7 +101,7 @@
 class MemPcRel(MemRegXRel):
     regname = 'PC'
 
-class MemoryOpReg8Imm5:
+class MemR8Rel:
     def __init__(self, basereg, offset):
         assert type(basereg) is ArmReg
         self.basereg = basereg
@@ -212,19 +212,19 @@
 
 class LS_imm5_base(ArmInstruction):
     """ ??? Rt, [Rn, imm5] """
-    operands = (Reg8Op, MemoryOpReg8Imm5)
+    operands = (Reg8Op, MemR8Rel)
     def __init__(self, rt, memop):
         assert memop.offset % 4 == 0
         self.imm5 = memop.offset >> 2
         self.rn = memop.basereg.num
-        self.rt = rt.num
+        self.rt = rt
         self.memloc = memop
         assert self.rn < 8
-        assert self.rt < 8
+        assert self.rt.num < 8
 
     def encode(self):
         Rn = self.rn
-        Rt = self.rt
+        Rt = self.rt.num
         imm5 = self.imm5
 
         h = (self.opcode << 11) | (imm5 << 6) | (Rn << 3) | Rt
@@ -252,7 +252,6 @@
         rt = self.rt.num
         assert rt < 8
         imm8 = self.offset >> 2
-        print(imm8)
         assert imm8 < 256
         h = (self.opcode << 8) | (rt << 8) | imm8
         return u16(h)
--- a/python/outstream.py	Tue Jul 09 17:59:15 2013 +0200
+++ b/python/outstream.py	Thu Jul 11 07:42:30 2013 +0200
@@ -1,5 +1,5 @@
 import binascii
-from asmnodes import ALabel
+from asmnodes import ALabel, AComment
 """
  The output stream is a stream of instructions that can be output
  to a file or binary or hexfile.
@@ -13,6 +13,7 @@
     def __init__(self):
         self.sections = {}
         self.currentSection = None
+
     def emit(self, item):
         self.sections[self.currentSection].append(item)
 
@@ -36,7 +37,7 @@
                 address = 0x0
             for i in self.sections[s]:
                 i.address = address
-                if type(i) is ALabel:
+                if type(i) in [ALabel, AComment]:
                     continue
                 if type(i) is Alignment:
                     while (address % i.align) != 0:
@@ -53,7 +54,7 @@
     def dumpSection(self, s):
         print('.section '+s)
         for i in self.sections[s]:
-            if type(i) is ALabel:
+            if type(i) in [ALabel, AComment]:
                 print(i)
             elif type(i) is Alignment:
                 pass
--- a/python/ppci/errors.py	Tue Jul 09 17:59:15 2013 +0200
+++ b/python/ppci/errors.py	Thu Jul 11 07:42:30 2013 +0200
@@ -48,21 +48,24 @@
           printLine(r, lines[r-1])
 
 class DiagnosticsManager:
-   def __init__(self):
+    def __init__(self):
       self.diags = []
 
-   def addDiag(self, d):
+    def addDiag(self, d):
       self.diags.append(d)
 
-   def error(self, msg, loc):
+    def error(self, msg, loc):
       self.addDiag(CompilerError(msg, loc))
 
-   def clear(self):
+    def clear(self):
       del self.diags[:]
 
-   def printErrors(self, src):
-      if len(self.diags) > 0:
-         print('{0} Errors'.format(len(self.diags)))
-         for d in self.diags:
-            printError(src, d)
+    def printErrors(self, src):
+        if len(self.diags) > 0:
+            print('==============')
+            print('{0} Errors'.format(len(self.diags)))
+            for d in self.diags:
+                print('==============')
+                printError(src, d)
+            print('==============')
 
--- a/python/testc3.py	Tue Jul 09 17:59:15 2013 +0200
+++ b/python/testc3.py	Thu Jul 11 07:42:30 2013 +0200
@@ -205,14 +205,43 @@
       }
         """
         self.expectOK(snippet)
+
+    def testTypeDef(self):
+        snippet = """
+         package testtypedef;
+         type int my_int;
+         function void t()
+         {
+            var my_int a;
+            var int b;
+            a = 2;
+            b = a + 2;
+         }
+        """
+        self.expectOK(snippet)
+
    
+    def testPointerType1(self):
+        snippet = """
+         package testpointer1;
+         var int* pa;
+         function void t()
+         {
+            var int a;
+            pa = &a;
+            *pa = 22;
+         }
+        """
+        self.expectOK(snippet)
+
     def testPointerType(self):
         snippet = """
          package testpointer;
-         var int* pa;
+         var int* pa, pb;
          function void t(int a, double b)
          {
             pa = &a;
+            pb = pa;
             *pa = 22;
          }
         """
@@ -234,7 +263,6 @@
         """
         self.expectErrors(snippet, [6, 9, 9, 10, 11])
 
-    @unittest.skip 
     def testComplexType(self):
         snippet = """
          package testpointer;
@@ -251,16 +279,21 @@
          } my_struct;
 
          type my_struct* my_sptr;
+         var int* pa;
 
          function void t(int a, double b, my_sptr x)
          {
             var my_struct *msp;
 
+            var my_struct u, v;
+            var point *pt;
+
+            pt = &msp->P1;
             msp = x;
-            *pa = 22;
+            *pa = 22 + u.mem1 * v.memb2 - u.P1.x;
             x->memb2 = *pa + a * b;
 
-            mxp->P1.x = a * x->P1.y;
+            msp->P1.x = a * x->P1.y;
          }
         """
         self.expectOK(snippet)
--- a/python/transform.py	Tue Jul 09 17:59:15 2013 +0200
+++ b/python/transform.py	Thu Jul 11 07:42:30 2013 +0200
@@ -89,15 +89,12 @@
             # find predecessors of this block and replace this block reference with the jumped reference.
             ins = bb.LastInstruction
             if type(ins) is Branch:
-                print('Removing block {}'.format(bb))
-                #print(ins, bb.Predecessors)
                 preds = bb.Predecessors
                 if bb in preds:
                     # Do not remove if preceeded by itself
                     pass
                 else:
                     for pred in bb.Predecessors:
-                          print('predecessor: {}'.format(pred))
                           pred.LastInstruction.changeTarget(bb, ins.target)
                     f.removeBasicBlock(bb)