changeset 300:158068af716c

yafm
author Windel Bouwman
date Tue, 03 Dec 2013 18:00:22 +0100
parents 674789d9ff37
children 6753763d3bec
files doc/compiler.rst examples/c3/blink.c3 examples/c3/burn.c3 examples/c3/burn.c3proj examples/c3/burn2.c3 examples/c3/cast.c3 examples/c3/comments.c3 examples/c3/coro.c3 examples/c3/functions.c3 examples/c3/stm32f4xx.c3 examples/c3/types.c3 kernel/arch_arm.c3 kernel/make.py kernel/process.c3 kernel/syscall.c3 python/c3/__init__.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/scope.py python/c3/visitor.py python/c3/wishes/coro.c3 python/codegen/canon.py python/codegen/registerallocator.py python/mem2reg.py python/optimize.py python/ppci/c3/__init__.py python/ppci/c3/analyse.py python/ppci/c3/astnodes.py python/ppci/c3/builder.py python/ppci/c3/codegenerator.py python/ppci/c3/lexer.py python/ppci/c3/parser.py python/ppci/c3/scope.py python/ppci/c3/visitor.py python/ppci/mem2reg.py python/ppci/optimize.py python/ppci/transform.py python/target/armframe.py python/target/arminstructions.py python/target/arminstructionselector.py python/transform.py python/zcc.py readme.rst test/c3examples/blink.c3 test/c3examples/burn.c3 test/c3examples/burn.c3proj test/c3examples/burn2.c3 test/c3examples/cast.c3 test/c3examples/comments.c3 test/c3examples/functions.c3 test/c3examples/stm32f4xx.c3 test/c3examples/types.c3 test/runtests.sh test/testc3.py test/testir.py test/testzcc.py
diffstat 60 files changed, 2271 insertions(+), 2357 deletions(-) [+]
line wrap: on
line diff
--- a/doc/compiler.rst	Sun Dec 01 18:37:23 2013 +0100
+++ b/doc/compiler.rst	Tue Dec 03 18:00:22 2013 +0100
@@ -4,17 +4,11 @@
 ========
 
 This chapter describes the design of the compiler.
-
-
-Overview
---------
-
 The compiler consists a frontend, mid-end and back-end. The frontend deals with
 source file parsing and semantics checking. The mid-end performs optimizations.
 This is optional. The back-end generates machine code. The front-end produces
 intermediate code. This is a simple representation of the source. The back-end
-can accept this kind of representation. This way the compiler is portable and
-a front end can be constructed without having to do the rest.
+can accept this kind of representation.
 
 .. graphviz::
   
@@ -38,6 +32,7 @@
 
 IR-code
 -------
+
 The intermediate representation (IR) of a program de-couples the front end
 from the backend of the compiler.
 
@@ -53,6 +48,7 @@
 .. graphviz::
   
    digraph c3 {
+   rankdir="LR"
    1 [label="source text"]
    10 [label="lexer" ]
    20 [label="parser" ]
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/c3/blink.c3	Tue Dec 03 18:00:22 2013 +0100
@@ -0,0 +1,30 @@
+/* This file blinks a LED on the STM32F4 discovery board.
+
+the board has 4 leds on PD12, PD13, PD14 and PD15
+
+*/
+
+module blink;
+
+import stm32f4xx;
+
+// Functions:
+function void main()
+{
+    // Memory mapped control registers:
+    var GPIO_Type GPIOD;
+    GPIOD = cast<GPIO_Type>(0x40020C00);
+    var RCC_Type RCC;
+    RCC = cast<RCC_Type>(0x40023800);
+
+    // Enable the clock to port D:
+    RCC->AHB1ENR = RCC->AHB1ENR | 0x8;
+
+
+    // PD13 == output (01)
+    GPIOD->MODER = (1 << 26);
+    GPIOD->ODR = (1 << 13);
+
+    while(true) {}
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/c3/burn.c3	Tue Dec 03 18:00:22 2013 +0100
@@ -0,0 +1,39 @@
+/*
+
+This file blinks a LED on the STM32F4 discovery board.
+
+the board has 4 leds on PD12, PD13, PD14 and PD15
+
+*/
+
+module burn;
+
+import stm32f4xx;
+
+/*
+function void init()
+{
+}
+*/
+
+function void main()
+{
+    //init();
+    var RCC_Type RCC;
+    RCC = cast<RCC_Type>(0x40023800);
+
+    // Enable the clock to port D:
+    RCC->AHB1ENR = RCC->AHB1ENR | (1 << 3);
+    // Memory mapped control registers:
+    var GPIO_Type GPIOD;
+    GPIOD = cast<GPIO_Type>(0x40020C00);
+
+    var int pin;
+    pin = 15;
+    // PD13 == output (01)
+    GPIOD->MODER = (1 << (pin << 1));
+    GPIOD->ODR = (1 << pin);
+
+    while(true) {}
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/c3/burn.c3proj	Tue Dec 03 18:00:22 2013 +0100
@@ -0,0 +1,6 @@
+
+[Burn]
+srcs = burn2.c3
+imps = stm32f4xx.c3
+target = arm
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/c3/burn2.c3	Tue Dec 03 18:00:22 2013 +0100
@@ -0,0 +1,59 @@
+/*
+
+This file blinks a LED on the STM32F4 discovery board.
+
+the board has 4 leds on PD12, PD13, PD14 and PD15
+
+*/
+
+module burn2;
+
+import stm32f4xx;
+
+function int add(int a, int b)
+{
+    return a + b;
+}
+
+function void init(int pin)
+{
+    if (pin < 12)
+    {
+        return;
+    }
+
+    if (pin > 15)
+    {
+        return;
+    }
+
+    var stm32f4xx:RCC_Type RCC;
+    RCC = cast<stm32f4xx:RCC_Type>(0x40023800);
+
+    // Enable the clock to port D:
+    RCC->AHB1ENR = RCC->AHB1ENR | (1 << 3);
+    // Memory mapped control registers:
+    var stm32f4xx:GPIO_Type GPIOD;
+    GPIOD = cast<stm32f4xx:GPIO_Type>(0x40020C00);
+
+    // PD13 == output (01)
+    GPIOD->MODER = (1 << (pin << 1));
+    GPIOD->ODR = (1 << pin);
+}
+
+
+function void main()
+{
+    // Vary between 12 and 15:
+    init(13);
+
+    var int a;
+    a = 0
+    while (a < 1000)
+    {
+        a = add(a, 1);
+    }
+
+    while(true) {}
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/c3/cast.c3	Tue Dec 03 18:00:22 2013 +0100
@@ -0,0 +1,18 @@
+
+/*
+ Demo of how to type cast
+*/
+
+module castdemo;
+
+function int testcast()
+{
+    var int a;
+    var int* b;
+    a = 3;
+    
+    b = cast<int*>(a);
+
+    return 0;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/c3/comments.c3	Tue Dec 03 18:00:22 2013 +0100
@@ -0,0 +1,14 @@
+
+/*
+ block
+ comment
+*/
+
+// fjd jjd-
+module comments; // hjfkds
+
+function int tst()
+{
+    return 0;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/c3/coro.c3	Tue Dec 03 18:00:22 2013 +0100
@@ -0,0 +1,91 @@
+module coro;
+
+/*
+  Some co-routines doing some work.
+
+  This example demonstrates how to write co-operating
+  routines in a nice way.
+*/
+
+int regbank[10];
+
+function i2c_write(int address, int d)
+{
+    regbank[2] = address;
+    regbank[0] |= 0x1; // Issue go command
+    while (regbank[1] != 0)
+    {
+        yield;
+    }
+
+    // Wait while busy:
+    while (regbank[1] != 11)
+    {
+        yield;
+    }
+}
+
+function int i2c_read(int address)
+{
+    regbank[2] = address;
+    regbank[0] |= 0x1; // Issue go command
+    while (regbank[1] != 0)
+    {
+        yield;
+    }
+
+    // Wait while busy:
+    while (regbank[1] != 11)
+    {
+        yield;
+    }
+}
+
+function void eeprom_set(int address, int v)
+{
+    i2c_write(address, v);
+    i2c_read(address);
+}
+
+function int calcX(int y)
+{
+  var int x;
+  x = 2;
+  x = x + 2 + 9 * y;
+  return x;
+}
+
+var int counter = 0;
+
+task task1()
+{
+    start task3;
+   var int a = 200;
+   while (a > 0)
+   {
+      yield;
+   }
+}
+
+task task2()
+{
+    while(true)
+    {
+        yield;
+    }
+}
+
+task task3()
+{
+    eeprom_set(99, 1);
+   yield;
+}
+
+task main()
+{
+    start task1;
+    start task2;
+    await task1;
+    await task2;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/c3/functions.c3	Tue Dec 03 18:00:22 2013 +0100
@@ -0,0 +1,27 @@
+
+/*
+ Demo of function usage
+*/
+
+module functiondemo;
+
+function void main()
+{
+    var int a, b, c;
+    a = 3;
+    b = a;
+    a =3;
+    b = fib(a + 9);
+    sum(a, b);
+}
+
+function int fib(int x)
+{
+    return fib(x - 1) * x;
+}
+
+function int sum(int a, int b)
+{
+    return a + b;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/c3/stm32f4xx.c3	Tue Dec 03 18:00:22 2013 +0100
@@ -0,0 +1,31 @@
+
+module stm32f4xx;
+
+type struct {
+    int MODER;
+    int OTYPER;
+    int OSPEEDR;
+    int PUPDR;
+    int IDR;
+    int ODR;
+}* GPIO_Type;
+
+type struct {
+    int CR;
+    int PLLCFGR;
+    int CFGR;
+    int CIR;
+    int AHB1RSTR;
+    int AHB2RSTR;
+    int AHB3RSTR;
+    int reserved0;
+    int APB1RSTR;
+    int APB2RSTR;
+    int reserved1a, reserved1b;
+    int AHB1ENR;
+    int AHB2ENR;
+    int AHB3ENR;
+    int reserved2;
+    int APB1ENR, APB2ENR;
+}* RCC_Type;
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/c3/types.c3	Tue Dec 03 18:00:22 2013 +0100
@@ -0,0 +1,40 @@
+
+/*
+ Demo of how to define types
+*/
+
+module typedemo;
+
+type int A;
+type int B;
+type struct {
+  int x, y;
+  A z;
+} C;
+type struct {
+  C x;
+  B y;
+  int z;
+} D;
+
+type D* E;
+
+function int testcast()
+{
+    var A a;
+    var B b;
+    a = 3;
+    b = a;
+    var C c;
+    c.x = a;
+    c.z = c.y;
+    var D d;
+    var E e;
+    var D* e2;
+    e = &d;
+    e2 = e;
+    e2->x.x = 22;
+    
+    return 0;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kernel/arch_arm.c3	Tue Dec 03 18:00:22 2013 +0100
@@ -0,0 +1,10 @@
+module arch;
+
+function void init()
+{
+}
+
+function void halt()
+{
+}
+
--- a/kernel/make.py	Sun Dec 01 18:37:23 2013 +0100
+++ b/kernel/make.py	Tue Dec 03 18:00:22 2013 +0100
@@ -5,7 +5,7 @@
 sys.path.insert(0, os.path.join('..', 'python'))
 import zcc
 
-arglist = ['memory.c3', 'kernel.c3', 'syscall.c3', 'process.c3', 'schedule.c3']
+arglist = ['memory.c3', 'kernel.c3', 'syscall.c3', 'process.c3', 'schedule.c3', 'arch_arm.c3']
 arglist += ['--target', 'arm']
 arglist += ['--dumpasm']
 arglist += ['--log', 'debug']
--- a/kernel/process.c3	Sun Dec 01 18:37:23 2013 +0100
+++ b/kernel/process.c3	Tue Dec 03 18:00:22 2013 +0100
@@ -1,4 +1,5 @@
 module process;
+
 import memory;
 import kernel;
 
@@ -12,13 +13,13 @@
 // List<process_t> procs;
 
 // init is the root of all processes:
-var process_t* init = 0;
+var process_t* init_pid = 0;
 var int next_pid = 0;
 
 function void init()
 {
     next_pid = 0;
-    init = Create();
+    init_pid = Create();
 }
 
 /*
@@ -26,19 +27,19 @@
 */
 function process_t* Create()
 {
-    process_t* p = memory.Alloc(sizeof(process_t));
+    // process_t* p = memory.Alloc(sizeof(process_t));
     p->id = next_pid;
-    next_pid++;
+    next_pid = next_pid + 1;
     return p;
 }
 
 
-public func void Kill(process_t* p)
+function void Kill(process_t* p)
 {
     // clean memory
 }
 
-public process_t* byId(int id)
+function process_t* byId(int id)
 {
     // Perform lookup
     return 0;
--- a/kernel/syscall.c3	Sun Dec 01 18:37:23 2013 +0100
+++ b/kernel/syscall.c3	Tue Dec 03 18:00:22 2013 +0100
@@ -4,14 +4,18 @@
     This module handles all the system calls from user space.
 */
 
+/*
 enum {
     SendMsg = 1,
     ReceiveMsg = 2,
 
 } syscall_t;
+*/
+
+type int syscall_t;
 
 // System call handlers. System calls are made from user space.
-func void handle_system_call(int callId, int a, int b, int c, int d)
+function void handle_system_call(int callId, int a, int b, int c, int d)
 {
     // Main entry, check what to do here
     switch(callId)
@@ -25,7 +29,7 @@
             }
 
             proc.setMessage();
-            scheduler.current.setState(Sleep);
+            // scheduler.current.setState(Sleep);
             break;
         case ReceiveMsg:
             break;
--- a/python/c3/__init__.py	Sun Dec 01 18:37:23 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-""" This is the C3 language front end. """
-
-
-from .parser import Parser
-from .lexer import Lexer
-from .analyse import Analyzer, TypeChecker
-from .codegenerator import CodeGenerator
-from .visitor import Visitor, AstPrinter
-from .builder import Builder
--- a/python/c3/analyse.py	Sun Dec 01 18:37:23 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,339 +0,0 @@
-import logging
-from .visitor import Visitor
-from .astnodes import *
-from .scope import *
-
-
-class C3Pass:
-    def __init__(self, diag):
-        self.diag = diag
-        self.logger = logging.getLogger('c3')
-        self.ok = True
-        self.visitor = Visitor()
-
-    def error(self, msg, loc=None):
-        self.ok = False
-        self.diag.error(msg, loc)
-
-    def visit(self, pkg, pre, post):
-        self.visitor.visit(pkg, pre, post)
-
-
-class AddScope(C3Pass):
-    """ Scope is attached to the correct modules. """
-    def addScope(self, pkg):
-        self.logger.info('Adding scoping to package {}'.format(pkg.name))
-        # Prepare top level scope and set scope to all objects:
-        self.scopeStack = [topScope]
-        modScope = Scope(self.CurrentScope)
-        self.scopeStack.append(modScope)
-        self.visit(pkg, self.enterScope, self.quitScope)
-        assert len(self.scopeStack) == 2
-        return self.ok
-
-    @property
-    def CurrentScope(self):
-        return self.scopeStack[-1]
-
-    def addSymbol(self, sym):
-        if self.CurrentScope.hasSymbol(sym.name):
-            self.error('Redefinition of {0}'.format(sym.name), sym.loc)
-        else:
-            self.CurrentScope.addSymbol(sym)
-
-    def enterScope(self, sym):
-        # Distribute the scope:
-        sym.scope = self.CurrentScope
-
-        # Add symbols to current scope:
-        if isinstance(sym, Symbol) or isinstance(sym, DefinedType):
-            self.addSymbol(sym)
-
-        # Create subscope:
-        if type(sym) in [Package, Function]:
-            newScope = Scope(self.CurrentScope)
-            self.scopeStack.append(newScope)
-            sym.innerScope = self.CurrentScope
-
-    def quitScope(self, sym):
-        # Pop out of scope:
-        if type(sym) in [Package, Function]:
-            self.scopeStack.pop(-1)
-
-
-class Analyzer(C3Pass):
-    """
-        Context handling is done here.
-        Scope is attached to the correct modules.
-        This class checks names and references.
-    """
-
-    def analyzePackage(self, pkg, packageDict):
-        self.ok = True
-        # Prepare top level scope and set scope to all objects:
-
-        self.logger.info('Resolving imports for package {}'.format(pkg.name))
-        # Handle imports:
-        for i in pkg.imports:
-            if i not in packageDict:
-                self.error('Cannot import {}'.format(i))
-                continue
-            ip = packageDict[i]
-            pkg.scope.addSymbol(ip)
-        FixRefs(self.diag).fixRefs(pkg)
-        return self.ok
-
-
-class FixRefs(C3Pass):
-    def fixRefs(self, pkg):
-        self.visitor.visit(pkg, self.findRefs)
-
-    # Reference fixups:
-    def resolveDesignator(self, d, scope):
-        assert isinstance(d, Designator), type(d)
-        assert type(scope) is Scope
-        if scope.hasSymbol(d.tname):
-            s = scope.getSymbol(d.tname)
-            if isinstance(d, ImportDesignator):
-                if s.innerScope.hasSymbol(d.vname):
-                    return s.innerScope.getSymbol(d.vname)
-            else:
-                if hasattr(s, 'addRef'):
-                    # TODO: make this nicer
-                    s.addRef(None)
-                return s
-        else:
-            self.error('Cannot resolve name {0}'.format(d.tname), d.loc)
-
-    def resolveImportDesignator(self, d, scope):
-        assert isinstance(d, ImportDesignator), type(d)
-        assert type(scope) is Scope
-        if scope.hasSymbol(d.tname):
-            s = scope.getSymbol(d.tname)
-            if hasattr(s, 'addRef'):
-                # TODO: make this nicer
-                s.addRef(None)
-            return s
-        else:
-            self.error('Cannot resolve name {0}'.format(d.tname), d.loc)
-
-    def resolveType(self, t, scope):
-        if type(t) is PointerType:
-            t.ptype = self.resolveType(t.ptype, scope)
-            return t
-        elif type(t) is StructureType:
-            offset = 0
-            for mem in t.mems:
-                mem.offset = offset
-                mem.typ = self.resolveType(mem.typ, scope)
-                offset += theType(mem.typ).bytesize
-            t.bytesize = offset
-            return t
-        elif isinstance(t, Designator):
-            t = self.resolveDesignator(t, scope)
-            if t:
-                return self.resolveType(t, scope)
-        elif isinstance(t, Type):
-            # Already resolved??
-            return t
-        else:
-            raise Exception('Error resolving type {} {}'.format(t, type(t)))
-
-    def findRefs(self, sym):
-        if type(sym) in [Constant] or isinstance(sym, Variable):
-            sym.typ = self.resolveType(sym.typ, sym.scope)
-        elif type(sym) is TypeCast:
-            sym.to_type = self.resolveType(sym.to_type, sym.scope)
-        elif type(sym) is VariableUse:
-            sym.target = self.resolveDesignator(sym.target, sym.scope)
-        elif type(sym) is FunctionCall:
-            varuse = sym.proc
-            sym.proc = self.resolveDesignator(varuse.target, sym.scope)
-        elif type(sym) is Function:
-            # Checkup function type:
-            ft = sym.typ
-            ft.returntype = self.resolveType(ft.returntype, sym.scope)
-            ft.parametertypes = [self.resolveType(pt, sym.scope) for pt in
-                                 ft.parametertypes]
-            # Mark local variables:
-            for d in sym.declarations:
-                if isinstance(d, Variable):
-                    d.isLocal = True
-        elif type(sym) is DefinedType:
-            sym.typ = self.resolveType(sym.typ, sym.scope)
-
-
-# Type checking:
-
-def theType(t):
-    """ Recurse until a 'real' type is found """
-    if type(t) is DefinedType:
-        return theType(t.typ)
-    return t
-
-
-def equalTypes(a, b):
-    """ Compare types a and b for structural equavalence. """
-    # Recurse into named types:
-    a, b = theType(a), theType(b)
-
-    if type(a) is type(b):
-        if type(a) is BaseType:
-            return a.name == b.name
-        elif type(a) is PointerType:
-            return equalTypes(a.ptype, b.ptype)
-        elif type(a) is StructureType:
-            if len(a.mems) != len(b.mems):
-                return False
-            return all(equalTypes(am.typ, bm.typ) for am, bm in
-                       zip(a.mems, b.mems))
-        else:
-            raise NotImplementedError(
-                    'Type compare for {} not implemented'.format(type(a)))
-    return False
-
-
-def canCast(fromT, toT):
-    fromT = theType(fromT)
-    toT = theType(toT)
-    if isinstance(fromT, PointerType) and isinstance(toT, PointerType):
-        return True
-    elif fromT is intType and isinstance(toT, PointerType):
-        return True
-    return False
-
-
-def expectRval(s):
-    # TODO: solve this better
-    s.expect_rvalue = True
-
-
-class TypeChecker(C3Pass):
-    def checkPackage(self, pkg):
-        self.ok = True
-        self.visit(pkg, None, self.check2)
-        return self.ok
-
-    def check2(self, sym):
-        if type(sym) in [IfStatement, WhileStatement]:
-            if not equalTypes(sym.condition.typ, boolType):
-                msg = 'Condition must be of type {}'.format(boolType)
-                self.error(msg, sym.condition.loc)
-        elif type(sym) is Assignment:
-            l, r = sym.lval, sym.rval
-            if not equalTypes(l.typ, r.typ):
-                msg = 'Cannot assign {} to {}'.format(r.typ, l.typ)
-                self.error(msg, sym.loc)
-            if not l.lvalue:
-                self.error('No valid lvalue {}'.format(l), l.loc)
-            #if sym.rval.lvalue:
-            #    self.error('Right hand side must be an rvalue', sym.rval.loc)
-            expectRval(sym.rval)
-        elif type(sym) is ReturnStatement:
-            pass
-        elif type(sym) is FunctionCall:
-            # Check arguments:
-            ngiv = len(sym.args)
-            ptypes = sym.proc.typ.parametertypes
-            nreq = len(ptypes)
-            if ngiv != nreq:
-               self.error('Function {2}: {0} arguments required, {1} given'.format(nreq, ngiv, sym.proc.name), sym.loc)
-            else:
-               for a, at in zip(sym.args, ptypes):
-                  expectRval(a)
-                  if not equalTypes(a.typ, at):
-                     self.error('Got {0}, expected {1}'.format(a.typ, at), a.loc)
-            # determine return type:
-            sym.typ = sym.proc.typ.returntype
-        elif type(sym) is VariableUse:
-            sym.lvalue = True
-            if isinstance(sym.target, 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:
-            sym.lvalue = False
-            if type(sym.val) is int:
-                sym.typ = intType
-            elif type(sym.val) is float:
-                sym.typ = doubleType
-            elif type(sym.val) is bool:
-                sym.typ = boolType
-            else:
-                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
-            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:
-            ptype = theType(sym.ptr.typ)
-            if type(ptype) is PointerType:
-                sym.typ = ptype.ptype
-            else:
-                self.error('Cannot dereference non-pointer type {}'.format(ptype), sym.loc)
-                sym.typ = intType
-        elif type(sym) is FieldRef:
-            basetype = sym.base.typ
-            sym.lvalue = sym.base.lvalue
-            basetype = theType(basetype)
-            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, sym.field), sym.loc)
-                    sym.typ = intType
-            else:
-                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 ['+', '-', '*', '/', '<<', '>>', '|', '&']:
-                expectRval(sym.a)
-                expectRval(sym.b)
-                if equalTypes(sym.a.typ, sym.b.typ):
-                   if equalTypes(sym.a.typ, intType):
-                      sym.typ = sym.a.typ
-                   else:
-                      self.error('Can only add integers', sym.loc)
-                      sym.typ = intType
-                else:
-                   # assume void here? TODO: throw exception!
-                   sym.typ = intType
-                   self.error('Types unequal {} != {}'.format(sym.a.typ, sym.b.typ), sym.loc)
-            elif sym.op in ['>', '<', '==', '<=', '>=']:
-                expectRval(sym.a)
-                expectRval(sym.b)
-                sym.typ = boolType
-                if not equalTypes(sym.a.typ, sym.b.typ):
-                   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):
-                   self.error('Must be {0}'.format(boolType), sym.a.loc)
-                if not equalTypes(sym.b.typ, boolType):
-                   self.error('Must be {0}'.format(boolType), sym.b.loc)
-            else:
-                raise Exception('Unknown binop {0}'.format(sym.op))
-        elif isinstance(sym, Variable):
-            # check initial value type:
-            # TODO
-            pass
-        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), sym.loc)
-                sym.typ = intType
-        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 [CompoundStatement, Package, Function, FunctionType, ExpressionStatement, DefinedType]:
-            pass
-        else:
-            raise NotImplementedError('Unknown type check {0}'.format(sym))
--- a/python/c3/astnodes.py	Sun Dec 01 18:37:23 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,356 +0,0 @@
-"""
-AST (abstract syntax tree) nodes for the c3 language.
-The tree is build by the parser.
-Then it is checked
-Finally code is generated from it.
-"""
-
-from ppci import SourceLocation
-
-
-class Node:
-    pass
-
-
-# Modules
-class Package(Node):
-    def __init__(self, name, loc):
-        self.name = name
-        self.loc = loc
-        self.declarations = []
-        self.imports = []
-
-    def __repr__(self):
-        return 'MODULE {}'.format(self.name)
-
-
-class Designator(Node):
-    def __init__(self, tname, loc):
-        self.tname = tname
-        self.loc = loc
-
-    def __repr__(self):
-        return 'DESIGNATOR {}'.format(self.tname)
-
-
-class ImportDesignator(Designator):
-    def __init__(self, tname, vname, loc):
-        super().__init__(tname, loc)
-        self.vname = vname
-
-    def __repr__(self):
-        return 'IMPORT DESIGNATOR {}:{}'.format(self.tname, self.vname)
-
-
-"""
-Type classes
-
-types must be comparable.
-
-There are the following types:
-- base type -> basic type (built in)
-- struct type -> a composite type that contains a list of named fields
-            of other types
-- function type
-"""
-
-
-class Type(Node):
-    pass
-
-
-class BaseType(Type):
-    def __init__(self, name):
-        self.name = name
-
-    def __repr__(self):
-        return '{}'.format(self.name)
-
-
-class FunctionType(Type):
-    def __init__(self, parametertypes, returntype):
-        self.parametertypes = parametertypes
-        self.returntype = returntype
-
-    def __repr__(self):
-        params = ', '.join([str(v) for v in self.parametertypes])
-        return '{1} f({0})'.format(params, self.returntype)
-
-
-class PointerType(Type):
-    """ A type that points to data of some other type """
-    def __init__(self, ptype):
-        assert isinstance(ptype, Type) or isinstance(ptype, Designator)
-        self.ptype = ptype
-
-    def __repr__(self):
-        return '({}*)'.format(self.ptype)
-
-
-class StructField:
-    def __init__(self, name, typ):
-        self.name = name
-        self.typ = typ
-        self.offset = 0
-
-
-class StructureType(Type):
-    def __init__(self, mems):
-        self.mems = mems
-        for mem in mems:
-            assert type(mem) is StructField
-            assert type(mem.name) is str
-
-    def hasField(self, name):
-        for mem in self.mems:
-            if name == mem.name:
-                return True
-        return False
-
-    def fieldType(self, name):
-        return self.findField(name).typ
-
-    def fieldOffset(self, name):
-        return self.findField(name).offset
-
-    def findField(self, name):
-        for mem in self.mems:
-            if name == mem.name:
-                return mem
-        raise KeyError(name)
-
-    def __repr__(self):
-        return 'STRUCT'
-
-
-class DefinedType(Type):
-    """ A named type indicating another type """
-    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)
-
-
-# Variables, parameters, local variables, constants:
-class Symbol(Node):
-    def __init__(self, name):
-        self.name = name
-        self.refs = []
-
-    def addRef(self, r):
-        self.refs.append(r)
-
-    @property
-    def References(self):
-        return self.refs
-
-
-class Constant(Symbol):
-    def __init__(self, name, typ, value):
-        super().__init__(name)
-        self.typ = typ
-        self.value = value
-
-    def __repr__(self):
-        return 'CONSTANT {0} = {1}'.format(self.name, self.value)
-
-
-class Variable(Symbol):
-    def __init__(self, name, typ):
-        super().__init__(name)
-        self.typ = typ
-        self.ival = None
-        self.isLocal = False
-        self.isReadOnly = False
-        self.isParameter = False
-
-    def __repr__(self):
-        return 'Var {} [{}]'.format(self.name, self.typ)
-
-
-class LocalVariable(Variable):
-    def __init__(self, name, typ):
-        super().__init__(name, typ)
-        self.isLocal = True
-
-
-class FormalParameter(Variable):
-    def __init__(self, name, typ):
-        super().__init__(name, typ)
-        self.isParameter = True
-
-
-# Procedure types
-class Function(Symbol):
-    """ Actual implementation of a function """
-    def __init__(self, name, loc):
-        super().__init__(name)
-        self.loc = loc
-        self.declarations = []
-
-    def __repr__(self):
-        return 'Func {}'.format(self.name)
-
-
-# Operations / Expressions:
-class Expression(Node):
-    def __init__(self, loc):
-        self.loc = loc
-
-
-class Deref(Expression):
-    def __init__(self, ptr, loc):
-        super().__init__(loc)
-        assert isinstance(ptr, Expression)
-        self.ptr = ptr
-
-    def __repr__(self):
-        return 'DEREF {}'.format(self.ptr)
-
-
-class TypeCast(Expression):
-    def __init__(self, to_type, x, loc):
-        super().__init__(loc)
-        self.to_type = to_type
-        self.a = x
-
-    def __repr__(self):
-        return 'TYPECAST {}'.format(self.to_type)
-
-
-class FieldRef(Expression):
-    def __init__(self, base, field, loc):
-        super().__init__(loc)
-        assert isinstance(base, Expression)
-        assert isinstance(field, str)
-        self.base = base
-        self.field = field
-
-    def __repr__(self):
-        return 'FIELD {}.{}'.format(self.base, self.field)
-
-
-class Unop(Expression):
-    def __init__(self, op, a, loc):
-        super().__init__(loc)
-        assert isinstance(a, Expression)
-        assert isinstance(op, str)
-        self.a = a
-        self.op = op
-
-    def __repr__(self):
-        return 'UNOP {}'.format(self.op)
-
-
-class Binop(Expression):
-    def __init__(self, a, op, b, loc):
-        super().__init__(loc)
-        assert isinstance(a, Expression), type(a)
-        assert isinstance(b, Expression)
-        assert isinstance(op, str)
-        self.a = a
-        self.b = b
-        self.op = op   # Operation: '+', '-', '*', '/', 'mod'
-
-    def __repr__(self):
-        return 'BINOP {}'.format(self.op)
-
-
-class VariableUse(Expression):
-    def __init__(self, target, loc):
-        super().__init__(loc)
-        self.target = target
-
-    def __repr__(self):
-        return 'VAR USE {}'.format(self.target)
-
-
-class Literal(Expression):
-    def __init__(self, val, loc):
-        super().__init__(loc)
-        self.val = val
-
-    def __repr__(self):
-        return 'LITERAL {}'.format(self.val)
-
-
-class FunctionCall(Expression):
-    def __init__(self, proc, args, loc):
-        super().__init__(loc)
-        self.proc = proc
-        self.args = args
-
-    def __repr__(self):
-        return 'CALL {0} '.format(self.proc)
-
-
-# Statements
-class Statement(Node):
-    def __init__(self, loc):
-        self.loc = loc
-
-
-class CompoundStatement(Statement):
-    def __init__(self, statements):
-        super().__init__(None)
-        self.statements = statements
-        for s in self.statements:
-            assert isinstance(s, Statement)
-
-    def __repr__(self):
-        return 'COMPOUND STATEMENT'
-
-
-class ReturnStatement(Statement):
-    def __init__(self, expr, loc):
-        super().__init__(loc)
-        self.expr = expr
-
-    def __repr__(self):
-        return 'RETURN STATEMENT'
-
-
-class Assignment(Statement):
-    def __init__(self, lval, rval, loc):
-        super().__init__(loc)
-        assert isinstance(lval, Node)
-        assert isinstance(rval, Node)
-        self.lval = lval
-        self.rval = rval
-
-    def __repr__(self):
-        return 'ASSIGNMENT'
-
-
-class ExpressionStatement(Statement):
-    def __init__(self, ex, loc):
-        super().__init__(loc)
-        self.ex = ex
-
-    def __repr__(self):
-        return 'Epression'
-
-
-class IfStatement(Statement):
-    def __init__(self, condition, truestatement, falsestatement, loc):
-        super().__init__(loc)
-        self.condition = condition
-        self.truestatement = truestatement
-        self.falsestatement = falsestatement
-
-    def __repr__(self):
-        return 'IF-statement'
-
-
-class WhileStatement(Statement):
-    def __init__(self, condition, statement, loc):
-        super().__init__(loc)
-        self.condition = condition
-        self.statement = statement
-
-    def __repr__(self):
-        return 'WHILE-statement'
--- a/python/c3/builder.py	Sun Dec 01 18:37:23 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,60 +0,0 @@
-import logging
-import ppci
-from . import Parser, TypeChecker, Analyzer, CodeGenerator
-from .analyse import AddScope
-
-
-class Builder:
-    """
-        Generates IR-code from c3 source.
-        Reports errors to the diagnostics system
-    """
-    def __init__(self, diag):
-        self.logger = logging.getLogger('c3')
-        self.diag = diag
-        self.parser = Parser(diag)
-        self.tc = TypeChecker(diag)
-        self.al = Analyzer(diag)
-        self.cg = CodeGenerator()
-
-    def checkSource(self, srcs, imps=[]):
-        """ Performs syntax and type check. """
-        iter(srcs)
-        iter(imps)
-        def doParse(srcs):
-            for src in srcs:
-                pkg = self.parser.parseSource(src)
-                if pkg:
-                    yield pkg
-                else:
-                    self.ok = False
-        s_pkgs = set(doParse(srcs))
-        i_pkgs = set(doParse(imps))
-        all_pkgs = s_pkgs | i_pkgs
-        # Fix scopes:
-        def doF(f, pkgs):
-            for pkg in pkgs:
-                if f(pkg):
-                    yield pkg
-                else:
-                    self.ok = False
-        all_pkgs = set(doF(AddScope(self.diag).addScope, all_pkgs))
-        # TODO: fix error handling better
-        def doA(pkgs):
-            packages = {pkg.name: pkg for pkg in pkgs}
-            for pkg in pkgs:
-                if self.al.analyzePackage(pkg, packages):
-                    yield pkg
-                else:
-                    self.ok = False
-        all_pkgs = set(doA(all_pkgs))
-        all_pkgs = set(doF(self.tc.checkPackage, all_pkgs))
-        return all_pkgs & s_pkgs
-
-    def build(self, srcs, imps=[]):
-        """ Create IR-code from sources """
-        self.ok = True
-        for pkg in self.checkSource(srcs, imps):
-            # Only return ircode when everything is OK
-            if self.ok:
-                yield self.cg.gencode(pkg)
--- a/python/c3/codegenerator.py	Sun Dec 01 18:37:23 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,198 +0,0 @@
-import logging
-import ir
-from . import astnodes
-from .scope import boolType, intType
-from ppci import CompilerError
-from .analyse import theType
-
-
-class CodeGenerator(ir.Builder):
-    """
-      Generates intermediate (IR) code from a package. The entry function is
-      'genModule'. The main task of this part is to rewrite complex control
-      structures, such as while and for loops into simple conditional
-      jump statements. Also complex conditional statements are simplified.
-      Such as 'and' and 'or' statements are rewritten in conditional jumps.
-      And structured datatypes are rewritten.
-    """
-    def __init__(self):
-        self.logger = logging.getLogger('c3cgen')
-
-    def gencode(self, pkg):
-        self.prepare()
-        assert type(pkg) is astnodes.Package
-        self.logger.info('Generating ir-code for {}'.format(pkg.name))
-        self.varMap = {}    # Maps variables to storage locations.
-        self.funcMap = {}
-        self.m = ir.Module(pkg.name)
-        self.genModule(pkg)
-        return self.m
-
-    # inner helpers:
-    def genModule(self, pkg):
-        # Take care of forward declarations:
-        for s in pkg.innerScope.Functions:
-            f = self.newFunction(s.name)
-            self.funcMap[s] = f
-        for v in pkg.innerScope.Variables:
-            self.varMap[v] = self.newTemp()
-        for s in pkg.innerScope.Functions:
-            self.genFunction(s)
-
-    def genFunction(self, fn):
-        # TODO: handle arguments
-        f = self.funcMap[fn]
-        f.return_value = self.newTemp()
-        # TODO reserve room for stack, this can be done at later point?
-        self.setFunction(f)
-        l2 = self.newBlock()
-        self.emit(ir.Jump(l2))
-        self.setBlock(l2)
-        # generate room for locals:
-
-        for sym in fn.innerScope:
-            # TODO: handle parameters different
-            if sym.isParameter:
-                v = ir.Parameter(sym.name)
-                f.addParameter(v)
-            elif sym.isLocal:
-                v = ir.LocalVariable(sym.name)
-                f.addLocal(v)
-            else:
-                #v = self.newTemp()
-                raise NotImplementedError('{}'.format(sym))
-            # TODO: make this ssa here??
-            self.varMap[sym] = v
-
-        self.genCode(fn.body)
-        # Set the default return value to zero:
-        # TBD: this may not be required?
-        self.emit(ir.Move(f.return_value, ir.Const(0)))
-        self.emit(ir.Jump(f.epiloog))
-        self.setFunction(None)
-
-    def genCode(self, code):
-        assert isinstance(code, astnodes.Statement)
-        self.setLoc(code.loc)
-        if type(code) is astnodes.CompoundStatement:
-            for s in code.statements:
-                self.genCode(s)
-        elif type(code) is astnodes.Assignment:
-            rval = self.genExprCode(code.rval)
-            lval = self.genExprCode(code.lval)
-            self.emit(ir.Move(lval, rval))
-        elif type(code) is astnodes.ExpressionStatement:
-            self.emit(ir.Exp(self.genExprCode(code.ex)))
-        elif type(code) is astnodes.IfStatement:
-            bbtrue = self.newBlock()
-            bbfalse = self.newBlock()
-            te = self.newBlock()
-            self.genCondCode(code.condition, bbtrue, bbfalse)
-            self.setBlock(bbtrue)
-            self.genCode(code.truestatement)
-            self.emit(ir.Jump(te))
-            self.setBlock(bbfalse)
-            if code.falsestatement:
-                self.genCode(code.falsestatement)
-            self.emit(ir.Jump(te))
-            self.setBlock(te)
-        elif type(code) is astnodes.ReturnStatement:
-            if code.expr:
-                re = self.genExprCode(code.expr)
-                self.emit(ir.Move(self.fn.return_value, re))
-                self.emit(ir.Jump(self.fn.epiloog))
-                b = self.newBlock()
-                self.setBlock(b)
-            else:
-                self.builder.addIns(ir.Return())
-        elif type(code) is astnodes.WhileStatement:
-            bbdo = self.newBlock()
-            bbtest = self.newBlock()
-            te = self.newBlock()
-            self.emit(ir.Jump(bbtest))
-            self.setBlock(bbtest)
-            self.genCondCode(code.condition, bbdo, te)
-            self.setBlock(bbdo)
-            self.genCode(code.statement)
-            self.emit(ir.Jump(bbtest))
-            self.setBlock(te)
-        else:
-            raise NotImplementedError('Unknown stmt {}'.format(code))
-
-    def genCondCode(self, expr, bbtrue, bbfalse):
-        # Implement sequential logical operators
-        assert expr.typ == boolType
-        if type(expr) is astnodes.Binop:
-            if expr.op == 'or':
-                l2 = self.newBlock()
-                self.genCondCode(expr.a, bbtrue, l2)
-                self.setBlock(l2)
-                self.genCondCode(expr.b, bbtrue, bbfalse)
-            elif expr.op == 'and':
-                l2 = self.newBlock()
-                self.genCondCode(expr.a, l2, bbfalse)
-                self.setBlock(l2)
-                self.genCondCode(expr.b, bbtrue, bbfalse)
-            elif expr.op in ['==', '>', '<']:
-                ta = self.genExprCode(expr.a)
-                tb = self.genExprCode(expr.b)
-                self.emit(ir.CJump(ta, expr.op, tb, bbtrue, bbfalse))
-            else:
-                raise NotImplementedError('Unknown condition {}'.format(expr))
-        elif type(expr) is astnodes.Literal:
-            if expr.val:
-                self.emit(ir.Jump(bbtrue))
-            else:
-                self.emit(ir.Jump(bbfalse))
-        else:
-            raise NotImplementedError('Unknown cond {}'.format(expr))
-
-    def genExprCode(self, expr):
-        assert isinstance(expr, astnodes.Expression)
-        if type(expr) is astnodes.Binop and expr.op in ir.Binop.ops:
-            ra = self.genExprCode(expr.a)
-            rb = self.genExprCode(expr.b)
-            return ir.Binop(ra, expr.op, rb)
-        elif type(expr) is astnodes.Unop and expr.op == '&':
-            ra = self.genExprCode(expr.a)
-            assert type(ra) is ir.Mem
-            return ra.e
-        elif type(expr) is astnodes.VariableUse:
-            # This returns the dereferenced variable.
-            if expr.target.isParameter:
-                # TODO: now parameters are handled different. Not nice?
-                return self.varMap[expr.target]
-            else:
-                return ir.Mem(self.varMap[expr.target])
-        elif type(expr) is astnodes.Deref:
-            # dereference pointer type:
-            addr = self.genExprCode(expr.ptr)
-            return ir.Mem(addr)
-        elif type(expr) is astnodes.FieldRef:
-            base = self.genExprCode(expr.base)
-            assert type(base) is ir.Mem, type(base)
-            base = base.e
-            bt = theType(expr.base.typ)
-            offset = ir.Const(bt.fieldOffset(expr.field))
-            return ir.Mem(ir.Add(base, offset))
-        elif type(expr) is astnodes.Literal:
-            return ir.Const(expr.val)
-        elif type(expr) is astnodes.TypeCast:
-            # TODO: improve this mess:
-            ar = self.genExprCode(expr.a)
-            tt = theType(expr.to_type)
-            if isinstance(tt, astnodes.PointerType):
-                if expr.a.typ is intType:
-                    return ar
-                elif isinstance(expr.a.typ, astnodes.PointerType):
-                    return ar
-                else:
-                    raise Exception()
-            else:
-                raise NotImplementedError("not implemented")
-        elif type(expr) is astnodes.FunctionCall:
-            args = [self.genExprCode(e) for e in expr.args]
-            fn = self.funcMap[expr.proc]
-            return ir.Call(fn, args)
-        else:
-            raise NotImplementedError('Unknown expr {}'.format(expr))
--- a/python/c3/lexer.py	Sun Dec 01 18:37:23 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,93 +0,0 @@
-import collections
-import re
-
-from ppci import CompilerError, SourceLocation, Token
-
-"""
- Lexical analyzer part. Splits the input character stream into tokens.
-"""
-
-keywords = ['and', 'or', 'not', 'true', 'false',
-   'else', 'if', 'while', 'return',
-   'function', 'var', 'type', 'const',
-   'struct', 'cast',
-   'import', 'module']
-
-
-class Lexer:
-    def __init__(self, diag):
-        self.diag = diag
-
-    def tokenize(self, input_file):
-        """
-           Tokenizer, generates an iterator that
-           returns tokens!
-
-           Input is a file like object.
-
-           This GREAT example was taken from python re doc page!
-        """
-        filename = input_file.name if hasattr(input_file, 'name') else ''
-        s = input_file.read()
-        input_file.close()
-        self.diag.addSource(filename, s)
-        tok_spec = [
-           ('REAL', r'\d+\.\d+'),
-           ('HEXNUMBER', r'0x[\da-fA-F]+'),
-           ('NUMBER', r'\d+'),
-           ('ID', r'[A-Za-z][A-Za-z\d_]*'),
-           ('NEWLINE', r'\n'),
-           ('SKIP', r'[ \t]'),
-           ('COMMENTS', r'//.*'),
-           ('LONGCOMMENTBEGIN', r'\/\*'),
-           ('LONGCOMMENTEND', r'\*\/'),
-           ('LEESTEKEN', r'==|->|<<|>>|[\.,=:;\-+*\[\]/\(\)]|>=|<=|<>|>|<|{|}|&|\^|\|'),
-           ('STRING', r"'.*?'")
-         ]
-        tok_re = '|'.join('(?P<%s>%s)' % pair for pair in tok_spec)
-        gettok = re.compile(tok_re).match
-        line = 1
-        pos = line_start = 0
-        mo = gettok(s)
-        incomment = False
-        while mo is not None:
-            typ = mo.lastgroup
-            val = mo.group(typ)
-            if typ == 'NEWLINE':
-                line_start = pos
-                line += 1
-            elif typ == 'COMMENTS':
-                pass
-            elif typ == 'LONGCOMMENTBEGIN':
-                incomment = True
-            elif typ == 'LONGCOMMENTEND':
-                incomment = False
-            elif typ == 'SKIP':
-                pass
-            elif incomment:
-                pass # Wait until we are not in a comment section
-            else:
-                if typ == 'ID':
-                    if val in keywords:
-                        typ = val
-                elif typ == 'LEESTEKEN':
-                    typ = val
-                elif typ == 'NUMBER':
-                    val = int(val)
-                elif typ == 'HEXNUMBER':
-                    val = int(val[2:], 16)
-                    typ = 'NUMBER'
-                elif typ == 'REAL':
-                    val = float(val)
-                elif typ == 'STRING':
-                    val = val[1:-1]
-                loc = SourceLocation(filename, line, mo.start() - line_start, mo.end() - mo.start())
-                yield Token(typ, val, loc)
-            pos = mo.end()
-            mo = gettok(s, pos)
-        if pos != len(s):
-            col = pos - line_start
-            loc = SourceLocation(filename, line, col, 1)
-            raise CompilerError('Unexpected character "{0}"'.format(s[pos]), loc)
-        loc = SourceLocation(filename, line, 0, 0)
-        yield Token('END', '', loc)
--- a/python/c3/parser.py	Sun Dec 01 18:37:23 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,412 +0,0 @@
-import logging
-from .lexer import Lexer
-from .astnodes import FieldRef, Literal, TypeCast, Unop, Binop
-from .astnodes import Assignment, ExpressionStatement, CompoundStatement
-from .astnodes import ReturnStatement, WhileStatement, IfStatement
-from .astnodes import FunctionType, Function, FormalParameter
-from .astnodes import StructureType, DefinedType, PointerType
-from .astnodes import Constant, Variable
-from .astnodes import StructField, Deref
-from .astnodes import Package, ImportDesignator
-from .astnodes import Designator, VariableUse, FunctionCall
-from ppci import CompilerError
-
-
-class Parser:
-    """ Parses sourcecode into an abstract syntax tree (AST) """
-    def __init__(self, diag):
-        self.logger = logging.getLogger('c3')
-        self.diag = diag
-        self.lexer = Lexer(diag)
-
-    def parseSource(self, source):
-        self.logger.info('Parsing source')
-        self.initLex(source)
-        try:
-            self.parsePackage()
-            return self.mod
-        except CompilerError as e:
-            self.diag.addDiag(e)
-
-    def Error(self, msg):
-        raise CompilerError(msg, self.token.loc)
-
-    # Lexer helpers:
-    def Consume(self, typ):
-        if self.Peak == typ:
-            return self.NextToken()
-        else:
-            self.Error('Excected: "{0}", got "{1}"'.format(typ, self.Peak))
-
-    @property
-    def Peak(self):
-        return self.token.typ
-
-    @property
-    def CurLoc(self):
-        return self.token.loc
-
-    def hasConsumed(self, typ):
-        if self.Peak == typ:
-            self.Consume(typ)
-            return True
-        return False
-
-    def NextToken(self):
-        t = self.token
-        if t.typ != 'END':
-            self.token = self.tokens.__next__()
-        return t
-
-    def initLex(self, source):
-        self.tokens = self.lexer.tokenize(source)
-        self.token = self.tokens.__next__()
-
-    def addDeclaration(self, decl):
-        self.currentPart.declarations.append(decl)
-
-    def parseImport(self):
-        self.Consume('import')
-        name = self.Consume('ID').val
-        self.mod.imports.append(name)
-        self.Consume(';')
-
-    def parsePackage(self):
-        self.Consume('module')
-        name = self.Consume('ID')
-        self.Consume(';')
-        self.mod = Package(name.val, name.loc)
-        self.currentPart = self.mod
-        while self.Peak != 'END':
-            self.parseTopLevel()
-        self.Consume('END')
-
-    def parseTopLevel(self):
-        if self.Peak == 'function':
-            self.parseFunctionDef()
-        elif self.Peak == 'var':
-            self.parseVarDef()
-        elif self.Peak == 'const':
-            self.parseConstDef()
-        elif self.Peak == 'type':
-            self.parseTypeDef()
-        elif self.Peak == 'import':
-            self.parseImport()
-        else:
-            self.Error('Expected function, var, const or type')
-
-    def parseDesignator(self):
-        """ A designator designates an object """
-        name = self.Consume('ID')
-        if self.hasConsumed(':'):
-            name2 = self.Consume('ID')
-            return ImportDesignator(name.val, name2.val, name.loc)
-        else:
-            return Designator(name.val, name.loc)
-
-    # Type system
-    def parseTypeSpec(self):
-        # For now, do simple type spec, just parse an ID:
-        #return self.parseDesignator()
-        if self.Peak == 'struct':
-            self.Consume('struct')
-            self.Consume('{')
-            mems = []
-            while self.Peak != '}':
-                mem_t = self.parseTypeSpec()
-                mem_n = self.Consume('ID').val
-                mems.append(StructField(mem_n, mem_t))
-                while self.hasConsumed(','):
-                    mem_n = self.Consume('ID').val
-                    mems.append(StructField(mem_n, mem_t))
-                self.Consume(';')
-            self.Consume('}')
-            theT = StructureType(mems)
-        else:
-            theT = self.parseDesignator()
-        # Check for pointer suffix:
-        while self.hasConsumed('*'):
-            theT = PointerType(theT)
-        return theT
-
-    def parseTypeDef(self):
-        self.Consume('type')
-        newtype = self.parseTypeSpec()
-        typename = self.Consume('ID')
-        self.Consume(';')
-        df = DefinedType(typename.val, newtype, typename.loc)
-        self.addDeclaration(df)
-
-    # Variable declarations:
-    def parseVarDef(self):
-        self.Consume('var')
-        t = self.parseTypeSpec()
-        def parseVar():
-            name = self.Consume('ID')
-            v = Variable(name.val, t)
-            v.loc = name.loc
-            if self.hasConsumed('='):
-                v.ival = self.Expression()
-            self.addDeclaration(v)
-        parseVar()
-        while self.hasConsumed(','):
-            parseVar()
-        self.Consume(';')
-
-    def parseConstDef(self):
-        self.Consume('const')
-        t = self.parseTypeSpec()
-        def parseConst():
-            name = self.Consume('ID')
-            self.Consume('=')
-            val = self.Expression()
-            c = Constant(name.val, t, val)
-            c.loc = name.loc
-        parseConst()
-        while self.hasConsumed(','):
-            parseConst()
-        self.Consume(';')
-
-    # Procedures
-    def parseFunctionDef(self):
-        loc = self.Consume('function').loc
-        returntype = self.parseTypeSpec()
-        fname = self.Consume('ID').val
-        f = Function(fname, loc)
-        self.addDeclaration(f)
-        savePart = self.currentPart
-        self.currentPart = f
-        self.Consume('(')
-        parameters = []
-        if not self.hasConsumed(')'):
-            def parseParameter():
-                typ = self.parseTypeSpec()
-                name = self.Consume('ID')
-                param = FormalParameter(name.val, typ)
-                param.loc = name.loc
-                self.addDeclaration(param)
-                parameters.append(param)
-            parseParameter()
-            while self.hasConsumed(','):
-                parseParameter()
-            self.Consume(')')
-        paramtypes = [p.typ for p in parameters]
-        f.typ = FunctionType(paramtypes, returntype)
-        f.body = self.parseCompoundStatement()
-        self.currentPart = savePart
-
-    # Statements:
-
-    def parseIfStatement(self):
-        loc = self.Consume('if').loc
-        self.Consume('(')
-        condition = self.Expression()
-        self.Consume(')')
-        yes = self.parseCompoundStatement()
-        if self.hasConsumed('else'):
-            no = self.parseCompoundStatement()
-        else:
-            no = None
-        return IfStatement(condition, yes, no, loc)
-
-    def parseWhileStatement(self):
-        loc = self.Consume('while').loc
-        self.Consume('(')
-        condition = self.Expression()
-        self.Consume(')')
-        statements = self.parseCompoundStatement()
-        return WhileStatement(condition, statements, loc)
-
-    def parseReturnStatement(self):
-        loc = self.Consume('return').loc
-        if self.Peak == ';':
-            expr = Literal(0, loc)
-        else:
-            expr = self.Expression()
-        self.Consume(';')
-        return ReturnStatement(expr, loc)
-
-    def parseCompoundStatement(self):
-        self.Consume('{')
-        statements = []
-        while not self.hasConsumed('}'):
-            s = self.Statement()
-            if s is None:
-                continue
-            statements.append(s)
-        return CompoundStatement(statements)
-
-    def Statement(self):
-        # Determine statement type based on the pending token:
-        if self.Peak == 'if':
-            return self.parseIfStatement()
-        elif self.Peak == 'while':
-            return self.parseWhileStatement()
-        elif self.Peak == '{':
-            return self.parseCompoundStatement()
-        elif self.hasConsumed(';'):
-            pass
-        elif self.Peak == 'var':
-            self.parseVarDef()
-        elif self.Peak == 'return':
-            return self.parseReturnStatement()
-        else:
-            return self.AssignmentOrCall()
-
-    def AssignmentOrCall(self):
-        x = self.UnaryExpression()
-        if self.Peak == '=':
-            # We enter assignment mode here.
-            loc = self.Consume('=').loc
-            rhs = self.Expression()
-            return Assignment(x, rhs, loc)
-        else:
-            return ExpressionStatement(x, x.loc)
-
-    # Expression section:
-    # We not implement these C constructs:
-    # a(2), f = 2
-    # and this:
-    # a = 2 < x : 4 ? 1;
-
-    def Expression(self):
-        exp = self.LogicalAndExpression()
-        while self.Peak == 'or':
-            loc = self.Consume('or').loc
-            e2 = self.LogicalAndExpression()
-            exp = Binop(exp, 'or', e2, loc)
-        return exp
-
-    def LogicalAndExpression(self):
-        o = self.EqualityExpression()
-        while self.Peak == 'and':
-            loc = self.Consume('and').loc
-            o2 = self.EqualityExpression()
-            o = Binop(o, 'and', o2, loc)
-        return o
-
-    def EqualityExpression(self):
-        ee = self.SimpleExpression()
-        while self.Peak in ['<', '==', '>']:
-            op = self.Consume(self.Peak)
-            ee2 = self.SimpleExpression()
-            ee = Binop(ee, op.typ, ee2, op.loc)
-        return ee
-
-    def SimpleExpression(self):
-        """ Shift operations before + and - ? """
-        e = self.AddExpression()
-        while self.Peak in ['>>', '<<']:
-            op = self.Consume(self.Peak)
-            e2 = self.AddExpression()
-            e = Binop(e, op.typ, e2, op.loc)
-        return e
-
-    def AddExpression(self):
-        e = self.Term()
-        while self.Peak in ['+', '-']:
-            op = self.Consume(self.Peak)
-            e2 = self.Term()
-            e = Binop(e, op.typ, e2, op.loc)
-        return e
-
-    def Term(self):
-        t = self.BitwiseOr()
-        while self.Peak in ['*', '/']:
-            op = self.Consume(self.Peak)
-            t2 = self.BitwiseOr()
-            t = Binop(t, op.typ, t2, op.loc)
-        return t
-
-    def BitwiseOr(self):
-        a = self.BitwiseAnd()
-        while self.Peak in ['|']:
-            op = self.Consume(self.Peak)
-            b = self.BitwiseAnd()
-            a = Binop(a, op.typ, b, op.loc)
-        return a
-
-    def BitwiseAnd(self):
-        a = self.CastExpression()
-        while self.Peak in ['&']:
-            op = self.Consume(self.Peak)
-            b = self.CastExpression()
-            a = Binop(a, op.typ, b, op.loc)
-        return a
-
-    # Domain of unary expressions:
-
-    def CastExpression(self):
-        """
-          the C-style type cast conflicts with '(' expr ')'
-          so introduce extra keyword 'cast'
-        """
-        if self.Peak == 'cast':
-            loc = self.Consume('cast').loc
-            self.Consume('<')
-            t = self.parseTypeSpec()
-            self.Consume('>')
-            self.Consume('(')
-            ce = self.Expression()
-            self.Consume(')')
-            return TypeCast(t, ce, loc)
-        else:
-            return self.UnaryExpression()
-
-    def UnaryExpression(self):
-        if self.Peak in ['&', '*']:
-            op = self.Consume(self.Peak)
-            ce = self.CastExpression()
-            if op.val == '*':
-                return Deref(ce, op.loc)
-            else:
-                return Unop(op.typ, ce, op.loc)
-        else:
-            return self.PostFixExpression()
-
-    def PostFixExpression(self):
-        pfe = self.PrimaryExpression()
-        while self.Peak in ['[', '(', '.', '->']:
-            if self.hasConsumed('['):
-                pass
-            elif self.hasConsumed('('):
-                # Function call
-                args = []
-                if not self.hasConsumed(')'):
-                    args.append(self.Expression())
-                    while self.hasConsumed(','):
-                        args.append(self.Expression())
-                    self.Consume(')')
-                pfe = FunctionCall(pfe, args, pfe.loc)
-            elif self.hasConsumed('->'):
-                field = self.Consume('ID')
-                pfe = Deref(pfe, pfe.loc)
-                pfe = FieldRef(pfe, field.val, field.loc)
-            elif self.hasConsumed('.'):
-                field = self.Consume('ID')
-                pfe = FieldRef(pfe, field.val, field.loc)
-            else:
-                raise Exception()
-        return pfe
-
-    def PrimaryExpression(self):
-        if self.hasConsumed('('):
-            e = self.Expression()
-            self.Consume(')')
-            return e
-        elif self.Peak == 'NUMBER':
-            val = self.Consume('NUMBER')
-            return Literal(val.val, val.loc)
-        elif self.Peak == 'REAL':
-            val = self.Consume('REAL')
-            return Literal(val.val, val.loc)
-        elif self.Peak == 'true':
-            val = self.Consume('true')
-            return Literal(True, val.loc)
-        elif self.Peak == 'false':
-            val = self.Consume('false')
-            return Literal(False, val.loc)
-        elif self.Peak == 'ID':
-            d = self.parseDesignator()
-            return VariableUse(d, d.loc)
-        self.Error('Expected NUM, ID or (expr), got {0}'.format(self.Peak))
--- a/python/c3/scope.py	Sun Dec 01 18:37:23 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +0,0 @@
-from . import astnodes
-
-
-class Scope:
-    """ A scope contains all symbols in a scope """
-    def __init__(self, parent=None):
-        self.symbols = {}
-        self.parent = parent
-
-    def __iter__(self):
-        # Iterate in a deterministic manner:
-        return iter(self.Constants + self.Variables + self.Functions)
-
-    @property
-    def Syms(self):
-        syms = self.symbols.values()
-        return sorted(syms, key=lambda v: v.name)
-
-    @property
-    def Constants(self):
-        return [s for s in self.Syms if type(s) is astnodes.Constant]
-
-    @property
-    def Variables(self):
-        return [s for s in self.Syms if isinstance(s, astnodes.Variable)]
-
-    @property
-    def Functions(self):
-        return [s for s in self.Syms if type(s) is astnodes.Function]
-
-    def getSymbol(self, name):
-        if name in self.symbols:
-            return self.symbols[name]
-        # Look for symbol:
-        if self.parent:
-            return self.parent.getSymbol(name)
-        raise CompilerException("Symbol {0} not found".format(name), name.loc)
-
-    def hasSymbol(self, name):
-        if name in self.symbols:
-            return True
-        if self.parent:
-            return self.parent.hasSymbol(name)
-        return False
-
-    def addSymbol(self, sym):
-        self.symbols[sym.name] = sym
-
-    def __repr__(self):
-        return 'Scope with {} symbols'.format(len(self.symbols))
-
-
-def createBuiltins(scope):
-    for tn in ['u64', 'u32', 'u16', 'u8']:
-        scope.addSymbol(astnodes.BaseType(tn))
-    for t in [intType, doubleType, voidType, boolType, stringType, byteType]:
-        scope.addSymbol(t)
-
-# buildin types:
-intType = astnodes.BaseType('int')
-intType.bytesize = 4
-doubleType = astnodes.BaseType('double')
-voidType = astnodes.BaseType('void')
-boolType = astnodes.BaseType('bool')
-stringType = astnodes.BaseType('string')
-byteType = astnodes.BaseType('byte')
-
-# Create top level scope:
-topScope = Scope()
-createBuiltins(topScope)
--- a/python/c3/visitor.py	Sun Dec 01 18:37:23 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,85 +0,0 @@
-from .astnodes import *
-
-
-class Visitor:
-    """
-        Visitor that can visit all nodes in the AST
-        and run pre and post functions.
-    """
-    def visit(self, node, f_pre=None, f_post=None):
-        self.f_pre = f_pre
-        self.f_post = f_post
-        self.do(node)
-
-    def do(self, node):
-        # Run visitor:
-        if self.f_pre:
-            self.f_pre(node)
-
-        # Descent into subnodes:
-        if type(node) is Package:
-            for decl in node.declarations:
-                self.do(decl)
-        elif type(node) is Function:
-            for s in node.declarations:
-                self.do(s)
-            self.do(node.body)
-        elif type(node) is CompoundStatement:
-            for s in node.statements:
-                self.do(s)
-        elif type(node) is IfStatement:
-            self.do(node.condition)
-            self.do(node.truestatement)
-            if node.falsestatement:
-                self.do(node.falsestatement)
-        elif type(node) is FunctionCall:
-            for arg in node.args:
-                self.do(arg)
-        elif type(node) is Assignment:
-            self.do(node.lval)
-            self.do(node.rval)
-        elif type(node) is ReturnStatement:
-            self.do(node.expr)
-        elif type(node) is Binop:
-            self.do(node.a)
-            self.do(node.b)
-        elif type(node) is Unop:
-            self.do(node.a)
-        elif type(node) is ExpressionStatement:
-            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 [VariableUse, Variable, Literal, FunctionType,
-                            DefinedType, FormalParameter, LocalVariable]:
-            # Those nodes do not have child nodes.
-            pass
-        elif type(node) is WhileStatement:
-            self.do(node.condition)
-            self.do(node.statement)
-        else:
-            raise Exception('Could not visit "{0}"'.format(node))
-
-        # run post function
-        if self.f_post:
-            self.f_post(node)
-
-
-class AstPrinter:
-    """ Prints an AST as text """
-    def printAst(self, pkg):
-        self.indent = 0
-        visitor = Visitor()
-        visitor.visit(pkg, self.print1, self.print2)
-
-    def print1(self, node):
-        print(' ' * self.indent + str(node))
-        self.indent += 2
-
-    def print2(self, node):
-        self.indent -= 2
--- a/python/c3/wishes/coro.c3	Sun Dec 01 18:37:23 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,91 +0,0 @@
-module coro;
-
-/*
-  Some co-routines doing some work.
-
-  This example demonstrates how to write co-operating
-  routines in a nice way.
-*/
-
-int regbank[10];
-
-function i2c_write(int address, int d)
-{
-    regbank[2] = address;
-    regbank[0] |= 0x1; // Issue go command
-    while (regbank[1] != 0)
-    {
-        yield;
-    }
-
-    // Wait while busy:
-    while (regbank[1] != 11)
-    {
-        yield;
-    }
-}
-
-function int i2c_read(int address)
-{
-    regbank[2] = address;
-    regbank[0] |= 0x1; // Issue go command
-    while (regbank[1] != 0)
-    {
-        yield;
-    }
-
-    // Wait while busy:
-    while (regbank[1] != 11)
-    {
-        yield;
-    }
-}
-
-function void eeprom_set(int address, int v)
-{
-    i2c_write(address, v);
-    i2c_read(address);
-}
-
-function int calcX(int y)
-{
-  var int x;
-  x = 2;
-  x = x + 2 + 9 * y;
-  return x;
-}
-
-var int counter = 0;
-
-task task1()
-{
-    start task3;
-   var int a = 200;
-   while (a > 0)
-   {
-      yield;
-   }
-}
-
-task task2()
-{
-    while(true)
-    {
-        yield;
-    }
-}
-
-task task3()
-{
-    eeprom_set(99, 1);
-   yield;
-}
-
-task main()
-{
-    start task1;
-    start task2;
-    await task1;
-    await task2;
-}
-
--- a/python/codegen/canon.py	Sun Dec 01 18:37:23 2013 +0100
+++ b/python/codegen/canon.py	Tue Dec 03 18:00:22 2013 +0100
@@ -27,6 +27,7 @@
 
 # Rewrite rewrites call instructions into Eseq instructions.
 
+
 def rewriteStmt(stmt, frame):
     if isinstance(stmt, ir.Jump):
         pass
@@ -99,6 +100,7 @@
     else:
         raise NotImplementedError('NI: {}'.format(exp))
 
+
 def flattenStmt(stmt):
     if isinstance(stmt, ir.Jump):
         return [stmt]
@@ -125,4 +127,3 @@
     """
     i = list(flattenStmt(s) for s in block.instructions)
     block.instructions = list(chain.from_iterable(i))
-
--- a/python/codegen/registerallocator.py	Sun Dec 01 18:37:23 2013 +0100
+++ b/python/codegen/registerallocator.py	Tue Dec 03 18:00:22 2013 +0100
@@ -4,6 +4,7 @@
 # Nifty first function:
 first = lambda x: next(iter(x))
 
+
 class RegisterAllocator:
     """
         Target independent register allocator.
@@ -67,7 +68,7 @@
 
     def NodeMoves(self, n):
         return n.moves & (self.activeMoves | self.worklistMoves)
-    
+
     def MoveRelated(self, n):
         return bool(self.NodeMoves(n))
 
@@ -108,7 +109,7 @@
                 if m in self.activeMoves:
                     self.activeMoves.remove(m)
                     self.worklistMoves.add(m)
-                
+
     def Coalesc(self):
         """ Coalesc conservative. """
         m = first(self.worklistMoves)
@@ -126,7 +127,7 @@
             self.f.ig.Combine(u, v)
         else:
             self.activeMoves.add(m)
-        
+
     def Conservative(self, u, v):
         """ Briggs conservative criteria for coalesc """
         nodes = u.Adjecent | v.Adjecent
@@ -149,14 +150,14 @@
             self.frozenMoves.add(m)
             # Check other part of the move for still being move related:
             v = m.src[0] if u is m.dst[0] else m.dst[0]
-    
+
     def SelectSpill(self):
         # TODO
         pass
 
     def AssignColors(self):
         """ Add nodes back to the graph to color it. """
-        # Add nodes back to the graph: 
+        # Add nodes back to the graph:
         while self.selectStack:
             n = self.selectStack.pop(-1)
             self.f.ig.addNode(n)
--- a/python/mem2reg.py	Sun Dec 01 18:37:23 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +0,0 @@
-import logging
-from transform import FunctionPass
-from ir import *
-
-def isAllocPromotable(allocinst):
-    # Check if alloc value is only used by load and store operations.
-    assert type(allocinst) is Alloc
-    return all(type(use) in [Load, Store] for use in allocinst.value.used_by)
-
-
-class Mem2RegPromotor(FunctionPass):
-    def promoteSingleBlock(self, ai):
-        v = ai.value
-        bb = ai.Block
-
-        # Replace all loads with the value:
-        loads = [i for i in v.used_by if isinstance(i, Load)]
-        stores = [i for i in v.used_by if isinstance(i, Store)]
-        stores.sort(key=lambda s: s.Position)
-        stores.reverse()
-
-        for load in loads:
-            idx = load.Position
-            # Search upwards:
-            for store in stores:
-                if store.Position < load.Position:
-                    break
-            load.value.replaceby(store.value)
-            logging.debug('replaced {} with {}'.format(load, store.value))
-            bb.removeInstruction(load)
-
-        # Remove store instructions:
-        for store in stores:
-            sv = store.value
-            logging.debug('removing {}'.format(store))
-            bb.removeInstruction(store)
-            #assert sv.Used
-        
-        # Remove alloca instruction:
-        assert not ai.value.Used, ai.value.used_by
-        bb.removeInstruction(ai)
-
-    def promote(self, ai):
-        # Find load operations and replace them with assignments
-        v = ai.value
-        if len(ai.value.UsedInBlocks) == 1:
-            self.promoteSingleBlock(ai)
-            return
-        
-        loads = [i for i in v.used_by if isinstance(i, Load)]
-        stores = [i for i in v.used_by if isinstance(i, Store)]
-
-        # Each store instruction can be removed (later).
-        # Instead of storing the value, we use it 
-        # where the load would have been!
-        replMap = {}
-        for store in stores:
-            replMap[store] = store.value
-
-        # for each load, track back what the defining store
-        # was.
-        for load in loads:
-            pass
-
-    def onFunction(self, f):
-        for bb in f.BasicBlocks:
-            allocs = [i for i in bb.Instructions if isinstance(i, Alloc)]
-            for i in allocs:
-                if isAllocPromotable(i):
-                    self.promote(i)
--- a/python/optimize.py	Sun Dec 01 18:37:23 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,19 +0,0 @@
-from mem2reg import Mem2RegPromotor
-from transform import CommonSubexpressionElimination, CleanPass
-from transform import DeadCodeDeleter, ConstantFolder
-
-def optimize(ir):
-    return 
-    cf = ConstantFolder()
-    cf.run(ir)
-    return
-    dcd = DeadCodeDeleter()
-    m2r = Mem2RegPromotor()
-    clr = CleanPass()
-    cse = CommonSubexpressionElimination()
-    dcd.run(ir)
-    clr.run(ir)
-    m2r.run(ir)
-    cse.run(ir)
-    cf.run(ir)
-    dcd.run(ir)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/ppci/c3/__init__.py	Tue Dec 03 18:00:22 2013 +0100
@@ -0,0 +1,9 @@
+""" This is the C3 language front end. """
+
+
+from .parser import Parser
+from .lexer import Lexer
+from .analyse import Analyzer, TypeChecker
+from .codegenerator import CodeGenerator
+from .visitor import Visitor, AstPrinter
+from .builder import Builder
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/ppci/c3/analyse.py	Tue Dec 03 18:00:22 2013 +0100
@@ -0,0 +1,328 @@
+import logging
+from .visitor import Visitor
+from .astnodes import *
+from .scope import *
+
+
+class C3Pass:
+    def __init__(self, diag):
+        self.diag = diag
+        self.logger = logging.getLogger('c3')
+        self.ok = True
+        self.visitor = Visitor()
+
+    def error(self, msg, loc=None):
+        self.ok = False
+        self.diag.error(msg, loc)
+
+    def visit(self, pkg, pre, post):
+        self.visitor.visit(pkg, pre, post)
+
+
+class AddScope(C3Pass):
+    """ Scope is attached to the correct modules. """
+    def addScope(self, pkg):
+        self.logger.info('Adding scoping to package {}'.format(pkg.name))
+        # Prepare top level scope and set scope to all objects:
+        self.scopeStack = [topScope]
+        modScope = Scope(self.CurrentScope)
+        self.scopeStack.append(modScope)
+        self.visit(pkg, self.enterScope, self.quitScope)
+        assert len(self.scopeStack) == 2
+        return self.ok
+
+    @property
+    def CurrentScope(self):
+        return self.scopeStack[-1]
+
+    def addSymbol(self, sym):
+        if self.CurrentScope.hasSymbol(sym.name):
+            self.error('Redefinition of {0}'.format(sym.name), sym.loc)
+        else:
+            self.CurrentScope.addSymbol(sym)
+
+    def enterScope(self, sym):
+        # Distribute the scope:
+        sym.scope = self.CurrentScope
+
+        # Add symbols to current scope:
+        if isinstance(sym, Symbol) or isinstance(sym, DefinedType):
+            self.addSymbol(sym)
+
+        # Create subscope:
+        if type(sym) in [Package, Function]:
+            newScope = Scope(self.CurrentScope)
+            self.scopeStack.append(newScope)
+            sym.innerScope = self.CurrentScope
+
+    def quitScope(self, sym):
+        # Pop out of scope:
+        if type(sym) in [Package, Function]:
+            self.scopeStack.pop(-1)
+
+
+class Analyzer(C3Pass):
+    """
+        Context handling is done here.
+        Scope is attached to the correct modules.
+        This class checks names and references.
+    """
+
+    def analyzePackage(self, pkg, packageDict):
+        self.ok = True
+        # Prepare top level scope and set scope to all objects:
+
+        self.logger.info('Resolving imports for package {}'.format(pkg.name))
+        # Handle imports:
+        for i in pkg.imports:
+            if i not in packageDict:
+                self.error('Cannot import {}'.format(i))
+                continue
+            ip = packageDict[i]
+            pkg.scope.addSymbol(ip)
+        FixRefs(self.diag).fixRefs(pkg)
+        return self.ok
+
+
+class FixRefs(C3Pass):
+    def fixRefs(self, pkg):
+        self.logger.info('Resolving references for {}'.format(pkg.name))
+        self.visitor.visit(pkg, self.findRefs)
+
+    # Reference fixups:
+    def resolveDesignator(self, d, scope):
+        assert isinstance(d, Designator), type(d)
+        assert type(scope) is Scope
+        if scope.hasSymbol(d.tname):
+            s = scope.getSymbol(d.tname)
+            if isinstance(d, ImportDesignator):
+                if s.innerScope.hasSymbol(d.vname):
+                    return s.innerScope.getSymbol(d.vname)
+            else:
+                s.addRef(None)  # TODO: fix this?
+                return s
+        self.error('Cannot resolve name {0}'.format(d.tname), d.loc)
+
+    def resolveType(self, t, scope):
+        if type(t) is PointerType:
+            t.ptype = self.resolveType(t.ptype, scope)
+            return t
+        elif type(t) is StructureType:
+            offset = 0
+            for mem in t.mems:
+                mem.offset = offset
+                mem.typ = self.resolveType(mem.typ, scope)
+                offset += theType(mem.typ).bytesize
+            t.bytesize = offset
+            return t
+        elif isinstance(t, Designator):
+            t = self.resolveDesignator(t, scope)
+            if t:
+                return self.resolveType(t, scope)
+        elif isinstance(t, Type):
+            # Already resolved??
+            return t
+        else:
+            raise Exception('Error resolving type {} {}'.format(t, type(t)))
+
+    def findRefs(self, sym):
+        if type(sym) is Constant or isinstance(sym, Variable):
+            sym.typ = self.resolveType(sym.typ, sym.scope)
+        elif type(sym) is TypeCast:
+            sym.to_type = self.resolveType(sym.to_type, sym.scope)
+        elif type(sym) is VariableUse:
+            sym.target = self.resolveDesignator(sym.target, sym.scope)
+        elif type(sym) is FunctionCall:
+            varuse = sym.proc
+            print(varuse)
+            if type(varuse) is VariableUse:
+                sym.proc = self.resolveDesignator(varuse.target, sym.scope)
+        elif type(sym) is Function:
+            # Checkup function type:
+            ft = sym.typ
+            ft.returntype = self.resolveType(ft.returntype, sym.scope)
+            ft.parametertypes = [self.resolveType(pt, sym.scope) for pt in
+                                 ft.parametertypes]
+            # Mark local variables:
+            for d in sym.declarations:
+                if isinstance(d, Variable):
+                    d.isLocal = True
+        elif type(sym) is DefinedType:
+            sym.typ = self.resolveType(sym.typ, sym.scope)
+
+
+# Type checking:
+
+def theType(t):
+    """ Recurse until a 'real' type is found """
+    if type(t) is DefinedType:
+        return theType(t.typ)
+    return t
+
+
+def equalTypes(a, b):
+    """ Compare types a and b for structural equavalence. """
+    # Recurse into named types:
+    a, b = theType(a), theType(b)
+
+    if type(a) is type(b):
+        if type(a) is BaseType:
+            return a.name == b.name
+        elif type(a) is PointerType:
+            return equalTypes(a.ptype, b.ptype)
+        elif type(a) is StructureType:
+            if len(a.mems) != len(b.mems):
+                return False
+            return all(equalTypes(am.typ, bm.typ) for am, bm in
+                       zip(a.mems, b.mems))
+        else:
+            raise NotImplementedError(
+                    'Type compare for {} not implemented'.format(type(a)))
+    return False
+
+
+def canCast(fromT, toT):
+    fromT = theType(fromT)
+    toT = theType(toT)
+    if isinstance(fromT, PointerType) and isinstance(toT, PointerType):
+        return True
+    elif fromT is intType and isinstance(toT, PointerType):
+        return True
+    return False
+
+
+def expectRval(s):
+    # TODO: solve this better
+    s.expect_rvalue = True
+
+
+class TypeChecker(C3Pass):
+    def checkPackage(self, pkg):
+        self.logger.info('Type checking {}'.format(pkg.name))
+        self.ok = True
+        self.visit(pkg, None, self.check2)
+        return self.ok
+
+    def check2(self, sym):
+        if type(sym) in [IfStatement, WhileStatement]:
+            if not equalTypes(sym.condition.typ, boolType):
+                msg = 'Condition must be of type {}'.format(boolType)
+                self.error(msg, sym.condition.loc)
+        elif type(sym) is Assignment:
+            l, r = sym.lval, sym.rval
+            if not equalTypes(l.typ, r.typ):
+                msg = 'Cannot assign {} to {}'.format(r.typ, l.typ)
+                self.error(msg, sym.loc)
+            if not l.lvalue:
+                self.error('No valid lvalue {}'.format(l), l.loc)
+            #if sym.rval.lvalue:
+            #    self.error('Right hand side must be an rvalue', sym.rval.loc)
+            expectRval(sym.rval)
+        elif type(sym) is ReturnStatement:
+            pass
+        elif type(sym) is FunctionCall:
+            # Check arguments:
+            ngiv = len(sym.args)
+            ptypes = sym.proc.typ.parametertypes
+            nreq = len(ptypes)
+            if ngiv != nreq:
+                self.error('Function {2}: {0} arguments required, {1} given'.format(nreq, ngiv, sym.proc.name), sym.loc)
+            else:
+                for a, at in zip(sym.args, ptypes):
+                    expectRval(a)
+                    if not equalTypes(a.typ, at):
+                        self.error('Got {0}, expected {1}'.format(a.typ, at), a.loc)
+            # determine return type:
+            sym.typ = sym.proc.typ.returntype
+        elif type(sym) is VariableUse:
+            sym.lvalue = True
+            if isinstance(sym.target, 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:
+            sym.lvalue = False
+            if type(sym.val) is int:
+                sym.typ = intType
+            elif type(sym.val) is float:
+                sym.typ = doubleType
+            elif type(sym.val) is bool:
+                sym.typ = boolType
+            else:
+                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
+            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:
+            ptype = theType(sym.ptr.typ)
+            if type(ptype) is PointerType:
+                sym.typ = ptype.ptype
+            else:
+                self.error('Cannot dereference non-pointer type {}'.format(ptype), sym.loc)
+                sym.typ = intType
+        elif type(sym) is FieldRef:
+            basetype = sym.base.typ
+            sym.lvalue = sym.base.lvalue
+            basetype = theType(basetype)
+            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, sym.field), sym.loc)
+                    sym.typ = intType
+            else:
+                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 ['+', '-', '*', '/', '<<', '>>', '|', '&']:
+                expectRval(sym.a)
+                expectRval(sym.b)
+                if equalTypes(sym.a.typ, sym.b.typ):
+                    if equalTypes(sym.a.typ, intType):
+                        sym.typ = sym.a.typ
+                    else:
+                        self.error('Can only add integers', sym.loc)
+                        sym.typ = intType
+                else:
+                    # assume void here? TODO: throw exception!
+                    sym.typ = intType
+                    self.error('Types unequal {} != {}'.format(sym.a.typ, sym.b.typ), sym.loc)
+            elif sym.op in ['>', '<', '==', '<=', '>=', '!=']:
+                expectRval(sym.a)
+                expectRval(sym.b)
+                sym.typ = boolType
+                if not equalTypes(sym.a.typ, sym.b.typ):
+                    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):
+                    self.error('Must be {0}'.format(boolType), sym.a.loc)
+                if not equalTypes(sym.b.typ, boolType):
+                    self.error('Must be {0}'.format(boolType), sym.b.loc)
+            else:
+                raise Exception('Unknown binop {0}'.format(sym.op))
+        elif isinstance(sym, Variable):
+            # check initial value type:
+            # TODO
+            pass
+        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), sym.loc)
+                sym.typ = intType
+        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 [CompoundStatement, Package, Function, FunctionType, ExpressionStatement, DefinedType]:
+            pass
+        else:
+            raise NotImplementedError('Unknown type check {0}'.format(sym))
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/ppci/c3/astnodes.py	Tue Dec 03 18:00:22 2013 +0100
@@ -0,0 +1,361 @@
+"""
+AST (abstract syntax tree) nodes for the c3 language.
+The tree is build by the parser.
+Then it is checked
+Finally code is generated from it.
+"""
+
+from ppci import SourceLocation
+
+
+class Node:
+    pass
+
+
+# Variables, parameters, local variables, constants and named types:
+class Symbol(Node):
+    def __init__(self, name):
+        self.name = name
+        self.refs = []
+
+    def addRef(self, r):
+        self.refs.append(r)
+
+    @property
+    def References(self):
+        return self.refs
+
+
+# Modules
+class Package(Node):
+    def __init__(self, name, loc):
+        self.name = name
+        self.loc = loc
+        self.declarations = []
+        self.imports = []
+
+    def __repr__(self):
+        return 'MODULE {}'.format(self.name)
+
+
+class Designator(Node):
+    def __init__(self, tname, loc):
+        self.tname = tname
+        self.loc = loc
+
+    def __repr__(self):
+        return 'DESIGNATOR {}'.format(self.tname)
+
+
+class ImportDesignator(Designator):
+    def __init__(self, tname, vname, loc):
+        super().__init__(tname, loc)
+        self.vname = vname
+
+    def __repr__(self):
+        return 'IMPORT DESIGNATOR {}:{}'.format(self.tname, self.vname)
+
+
+"""
+Type classes
+
+types must be comparable.
+
+There are the following types:
+- base type -> basic type (built in)
+- struct type -> a composite type that contains a list of named fields
+            of other types
+- function type
+"""
+
+
+class Type(Node):
+    pass
+
+
+class NamedType(Type, Symbol):
+    def __init__(self, name):
+        Symbol.__init__(self, name)
+
+
+class BaseType(NamedType):
+    def __init__(self, name):
+        super().__init__(name)
+
+    def __repr__(self):
+        return '{}'.format(self.name)
+
+
+class FunctionType(Type):
+    def __init__(self, parametertypes, returntype):
+        self.parametertypes = parametertypes
+        self.returntype = returntype
+
+    def __repr__(self):
+        params = ', '.join([str(v) for v in self.parametertypes])
+        return '{1} f({0})'.format(params, self.returntype)
+
+
+class PointerType(Type):
+    """ A type that points to data of some other type """
+    def __init__(self, ptype):
+        assert isinstance(ptype, Type) or isinstance(ptype, Designator)
+        self.ptype = ptype
+
+    def __repr__(self):
+        return '({}*)'.format(self.ptype)
+
+
+class StructField:
+    def __init__(self, name, typ):
+        self.name = name
+        self.typ = typ
+        self.offset = 0
+
+
+class StructureType(Type):
+    def __init__(self, mems):
+        self.mems = mems
+        for mem in mems:
+            assert type(mem) is StructField
+            assert type(mem.name) is str
+
+    def hasField(self, name):
+        for mem in self.mems:
+            if name == mem.name:
+                return True
+        return False
+
+    def fieldType(self, name):
+        return self.findField(name).typ
+
+    def fieldOffset(self, name):
+        return self.findField(name).offset
+
+    def findField(self, name):
+        for mem in self.mems:
+            if name == mem.name:
+                return mem
+        raise KeyError(name)
+
+    def __repr__(self):
+        return 'STRUCT'
+
+
+class DefinedType(NamedType):
+    """ A named type indicating another type """
+    def __init__(self, name, typ, loc):
+        assert isinstance(name, str)
+        super().__init__(name)
+        self.typ = typ
+        self.loc = loc
+
+    def __repr__(self):
+        return 'Named type {0} of type {1}'.format(self.name, self.typ)
+
+
+class Constant(Symbol):
+    def __init__(self, name, typ, value):
+        super().__init__(name)
+        self.typ = typ
+        self.value = value
+
+    def __repr__(self):
+        return 'CONSTANT {0} = {1}'.format(self.name, self.value)
+
+
+class Variable(Symbol):
+    def __init__(self, name, typ):
+        super().__init__(name)
+        self.typ = typ
+        self.ival = None
+        self.isLocal = False
+        self.isReadOnly = False
+        self.isParameter = False
+
+    def __repr__(self):
+        return 'Var {} [{}]'.format(self.name, self.typ)
+
+
+class LocalVariable(Variable):
+    def __init__(self, name, typ):
+        super().__init__(name, typ)
+        self.isLocal = True
+
+
+class FormalParameter(Variable):
+    def __init__(self, name, typ):
+        super().__init__(name, typ)
+        self.isParameter = True
+
+
+# Procedure types
+class Function(Symbol):
+    """ Actual implementation of a function """
+    def __init__(self, name, loc):
+        super().__init__(name)
+        self.loc = loc
+        self.declarations = []
+
+    def __repr__(self):
+        return 'Func {}'.format(self.name)
+
+
+# Operations / Expressions:
+class Expression(Node):
+    def __init__(self, loc):
+        self.loc = loc
+
+
+class Deref(Expression):
+    def __init__(self, ptr, loc):
+        super().__init__(loc)
+        assert isinstance(ptr, Expression)
+        self.ptr = ptr
+
+    def __repr__(self):
+        return 'DEREF {}'.format(self.ptr)
+
+
+class TypeCast(Expression):
+    def __init__(self, to_type, x, loc):
+        super().__init__(loc)
+        self.to_type = to_type
+        self.a = x
+
+    def __repr__(self):
+        return 'TYPECAST {}'.format(self.to_type)
+
+
+class FieldRef(Expression):
+    def __init__(self, base, field, loc):
+        super().__init__(loc)
+        assert isinstance(base, Expression)
+        assert isinstance(field, str)
+        self.base = base
+        self.field = field
+
+    def __repr__(self):
+        return 'FIELD {}.{}'.format(self.base, self.field)
+
+
+class Unop(Expression):
+    def __init__(self, op, a, loc):
+        super().__init__(loc)
+        assert isinstance(a, Expression)
+        assert isinstance(op, str)
+        self.a = a
+        self.op = op
+
+    def __repr__(self):
+        return 'UNOP {}'.format(self.op)
+
+
+class Binop(Expression):
+    def __init__(self, a, op, b, loc):
+        super().__init__(loc)
+        assert isinstance(a, Expression), type(a)
+        assert isinstance(b, Expression)
+        assert isinstance(op, str)
+        self.a = a
+        self.b = b
+        self.op = op   # Operation: '+', '-', '*', '/', 'mod'
+
+    def __repr__(self):
+        return 'BINOP {}'.format(self.op)
+
+
+class VariableUse(Expression):
+    def __init__(self, target, loc):
+        super().__init__(loc)
+        self.target = target
+
+    def __repr__(self):
+        return 'VAR USE {}'.format(self.target)
+
+
+class Literal(Expression):
+    def __init__(self, val, loc):
+        super().__init__(loc)
+        self.val = val
+
+    def __repr__(self):
+        return 'LITERAL {}'.format(self.val)
+
+
+class FunctionCall(Expression):
+    def __init__(self, proc, args, loc):
+        super().__init__(loc)
+        self.proc = proc
+        self.args = args
+
+    def __repr__(self):
+        return 'CALL {0} '.format(self.proc)
+
+
+# Statements
+class Statement(Node):
+    def __init__(self, loc):
+        self.loc = loc
+
+
+class CompoundStatement(Statement):
+    def __init__(self, statements):
+        super().__init__(None)
+        self.statements = statements
+        for s in self.statements:
+            assert isinstance(s, Statement)
+
+    def __repr__(self):
+        return 'COMPOUND STATEMENT'
+
+
+class ReturnStatement(Statement):
+    def __init__(self, expr, loc):
+        super().__init__(loc)
+        self.expr = expr
+
+    def __repr__(self):
+        return 'RETURN STATEMENT'
+
+
+class Assignment(Statement):
+    def __init__(self, lval, rval, loc):
+        super().__init__(loc)
+        assert isinstance(lval, Node)
+        assert isinstance(rval, Node)
+        self.lval = lval
+        self.rval = rval
+
+    def __repr__(self):
+        return 'ASSIGNMENT'
+
+
+class ExpressionStatement(Statement):
+    def __init__(self, ex, loc):
+        super().__init__(loc)
+        self.ex = ex
+
+    def __repr__(self):
+        return 'Epression'
+
+
+class IfStatement(Statement):
+    def __init__(self, condition, truestatement, falsestatement, loc):
+        super().__init__(loc)
+        self.condition = condition
+        self.truestatement = truestatement
+        self.falsestatement = falsestatement
+
+    def __repr__(self):
+        return 'IF-statement'
+
+
+class WhileStatement(Statement):
+    def __init__(self, condition, statement, loc):
+        super().__init__(loc)
+        self.condition = condition
+        self.statement = statement
+
+    def __repr__(self):
+        return 'WHILE-statement'
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/ppci/c3/builder.py	Tue Dec 03 18:00:22 2013 +0100
@@ -0,0 +1,66 @@
+import logging
+import ppci
+from .parser import Parser
+from .analyse import TypeChecker, Analyzer
+from .codegenerator import CodeGenerator
+from .analyse import AddScope
+
+
+class Builder:
+    """
+        Generates IR-code from c3 source.
+        Reports errors to the diagnostics system.
+    """
+    def __init__(self, diag):
+        self.logger = logging.getLogger('c3')
+        self.diag = diag
+        self.parser = Parser(diag)
+        self.tc = TypeChecker(diag)
+        self.al = Analyzer(diag)
+        self.cg = CodeGenerator()
+
+    def checkSource(self, srcs, imps=[]):
+        """ Performs syntax and type check. """
+        iter(srcs)
+        iter(imps)
+
+        def doParse(srcs):
+            for src in srcs:
+                pkg = self.parser.parseSource(src)
+                if pkg:
+                    yield pkg
+                else:
+                    self.ok = False
+        s_pkgs = set(doParse(srcs))
+        i_pkgs = set(doParse(imps))
+        all_pkgs = s_pkgs | i_pkgs
+        # Fix scopes:
+
+        def doF(f, pkgs):
+            for pkg in pkgs:
+                if f(pkg):
+                    yield pkg
+                else:
+                    self.ok = False
+        all_pkgs = set(doF(AddScope(self.diag).addScope, all_pkgs))
+        # TODO: fix error handling better
+
+        def doA(pkgs):
+            packages = {pkg.name: pkg for pkg in pkgs}
+            for pkg in pkgs:
+                if self.al.analyzePackage(pkg, packages):
+                    yield pkg
+                else:
+                    self.ok = False
+        all_pkgs = set(doA(all_pkgs))
+        all_pkgs = set(doF(self.tc.checkPackage, all_pkgs))
+        return all_pkgs & s_pkgs
+
+    def build(self, srcs, imps=[]):
+        """ Create IR-code from sources """
+        self.logger.info('Starting build with {}'.format(srcs))
+        self.ok = True
+        for pkg in self.checkSource(srcs, imps):
+            # Only return ircode when everything is OK
+            if self.ok:
+                yield self.cg.gencode(pkg)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/ppci/c3/codegenerator.py	Tue Dec 03 18:00:22 2013 +0100
@@ -0,0 +1,198 @@
+import logging
+import ir
+from . import astnodes
+from .scope import boolType, intType
+from ppci import CompilerError
+from .analyse import theType
+
+
+class CodeGenerator(ir.Builder):
+    """
+      Generates intermediate (IR) code from a package. The entry function is
+      'genModule'. The main task of this part is to rewrite complex control
+      structures, such as while and for loops into simple conditional
+      jump statements. Also complex conditional statements are simplified.
+      Such as 'and' and 'or' statements are rewritten in conditional jumps.
+      And structured datatypes are rewritten.
+    """
+    def __init__(self):
+        self.logger = logging.getLogger('c3cgen')
+
+    def gencode(self, pkg):
+        self.prepare()
+        assert type(pkg) is astnodes.Package
+        self.logger.info('Generating ir-code for {}'.format(pkg.name))
+        self.varMap = {}    # Maps variables to storage locations.
+        self.funcMap = {}
+        self.m = ir.Module(pkg.name)
+        self.genModule(pkg)
+        return self.m
+
+    # inner helpers:
+    def genModule(self, pkg):
+        # Take care of forward declarations:
+        for s in pkg.innerScope.Functions:
+            f = self.newFunction(s.name)
+            self.funcMap[s] = f
+        for v in pkg.innerScope.Variables:
+            self.varMap[v] = self.newTemp()
+        for s in pkg.innerScope.Functions:
+            self.genFunction(s)
+
+    def genFunction(self, fn):
+        # TODO: handle arguments
+        f = self.funcMap[fn]
+        f.return_value = self.newTemp()
+        # TODO reserve room for stack, this can be done at later point?
+        self.setFunction(f)
+        l2 = self.newBlock()
+        self.emit(ir.Jump(l2))
+        self.setBlock(l2)
+        # generate room for locals:
+
+        for sym in fn.innerScope:
+            # TODO: handle parameters different
+            if sym.isParameter:
+                v = ir.Parameter(sym.name)
+                f.addParameter(v)
+            elif sym.isLocal:
+                v = ir.LocalVariable(sym.name)
+                f.addLocal(v)
+            else:
+                #v = self.newTemp()
+                raise NotImplementedError('{}'.format(sym))
+            # TODO: make this ssa here??
+            self.varMap[sym] = v
+
+        self.genCode(fn.body)
+        # Set the default return value to zero:
+        # TBD: this may not be required?
+        self.emit(ir.Move(f.return_value, ir.Const(0)))
+        self.emit(ir.Jump(f.epiloog))
+        self.setFunction(None)
+
+    def genCode(self, code):
+        assert isinstance(code, astnodes.Statement)
+        self.setLoc(code.loc)
+        if type(code) is astnodes.CompoundStatement:
+            for s in code.statements:
+                self.genCode(s)
+        elif type(code) is astnodes.Assignment:
+            rval = self.genExprCode(code.rval)
+            lval = self.genExprCode(code.lval)
+            self.emit(ir.Move(lval, rval))
+        elif type(code) is astnodes.ExpressionStatement:
+            self.emit(ir.Exp(self.genExprCode(code.ex)))
+        elif type(code) is astnodes.IfStatement:
+            bbtrue = self.newBlock()
+            bbfalse = self.newBlock()
+            te = self.newBlock()
+            self.genCondCode(code.condition, bbtrue, bbfalse)
+            self.setBlock(bbtrue)
+            self.genCode(code.truestatement)
+            self.emit(ir.Jump(te))
+            self.setBlock(bbfalse)
+            if code.falsestatement:
+                self.genCode(code.falsestatement)
+            self.emit(ir.Jump(te))
+            self.setBlock(te)
+        elif type(code) is astnodes.ReturnStatement:
+            if code.expr:
+                re = self.genExprCode(code.expr)
+                self.emit(ir.Move(self.fn.return_value, re))
+                self.emit(ir.Jump(self.fn.epiloog))
+                b = self.newBlock()
+                self.setBlock(b)
+            else:
+                self.builder.addIns(ir.Return())
+        elif type(code) is astnodes.WhileStatement:
+            bbdo = self.newBlock()
+            bbtest = self.newBlock()
+            te = self.newBlock()
+            self.emit(ir.Jump(bbtest))
+            self.setBlock(bbtest)
+            self.genCondCode(code.condition, bbdo, te)
+            self.setBlock(bbdo)
+            self.genCode(code.statement)
+            self.emit(ir.Jump(bbtest))
+            self.setBlock(te)
+        else:
+            raise NotImplementedError('Unknown stmt {}'.format(code))
+
+    def genCondCode(self, expr, bbtrue, bbfalse):
+        # Implement sequential logical operators
+        assert expr.typ == boolType
+        if type(expr) is astnodes.Binop:
+            if expr.op == 'or':
+                l2 = self.newBlock()
+                self.genCondCode(expr.a, bbtrue, l2)
+                self.setBlock(l2)
+                self.genCondCode(expr.b, bbtrue, bbfalse)
+            elif expr.op == 'and':
+                l2 = self.newBlock()
+                self.genCondCode(expr.a, l2, bbfalse)
+                self.setBlock(l2)
+                self.genCondCode(expr.b, bbtrue, bbfalse)
+            elif expr.op in ['==', '>', '<']:
+                ta = self.genExprCode(expr.a)
+                tb = self.genExprCode(expr.b)
+                self.emit(ir.CJump(ta, expr.op, tb, bbtrue, bbfalse))
+            else:
+                raise NotImplementedError('Unknown condition {}'.format(expr))
+        elif type(expr) is astnodes.Literal:
+            if expr.val:
+                self.emit(ir.Jump(bbtrue))
+            else:
+                self.emit(ir.Jump(bbfalse))
+        else:
+            raise NotImplementedError('Unknown cond {}'.format(expr))
+
+    def genExprCode(self, expr):
+        assert isinstance(expr, astnodes.Expression)
+        if type(expr) is astnodes.Binop and expr.op in ir.Binop.ops:
+            ra = self.genExprCode(expr.a)
+            rb = self.genExprCode(expr.b)
+            return ir.Binop(ra, expr.op, rb)
+        elif type(expr) is astnodes.Unop and expr.op == '&':
+            ra = self.genExprCode(expr.a)
+            assert type(ra) is ir.Mem
+            return ra.e
+        elif type(expr) is astnodes.VariableUse:
+            # This returns the dereferenced variable.
+            if expr.target.isParameter:
+                # TODO: now parameters are handled different. Not nice?
+                return self.varMap[expr.target]
+            else:
+                return ir.Mem(self.varMap[expr.target])
+        elif type(expr) is astnodes.Deref:
+            # dereference pointer type:
+            addr = self.genExprCode(expr.ptr)
+            return ir.Mem(addr)
+        elif type(expr) is astnodes.FieldRef:
+            base = self.genExprCode(expr.base)
+            assert type(base) is ir.Mem, type(base)
+            base = base.e
+            bt = theType(expr.base.typ)
+            offset = ir.Const(bt.fieldOffset(expr.field))
+            return ir.Mem(ir.Add(base, offset))
+        elif type(expr) is astnodes.Literal:
+            return ir.Const(expr.val)
+        elif type(expr) is astnodes.TypeCast:
+            # TODO: improve this mess:
+            ar = self.genExprCode(expr.a)
+            tt = theType(expr.to_type)
+            if isinstance(tt, astnodes.PointerType):
+                if expr.a.typ is intType:
+                    return ar
+                elif isinstance(expr.a.typ, astnodes.PointerType):
+                    return ar
+                else:
+                    raise Exception()
+            else:
+                raise NotImplementedError("not implemented")
+        elif type(expr) is astnodes.FunctionCall:
+            args = [self.genExprCode(e) for e in expr.args]
+            fn = self.funcMap[expr.proc]
+            return ir.Call(fn, args)
+        else:
+            raise NotImplementedError('Unknown expr {}'.format(expr))
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/ppci/c3/lexer.py	Tue Dec 03 18:00:22 2013 +0100
@@ -0,0 +1,94 @@
+import collections
+import re
+
+from ppci import CompilerError, SourceLocation, Token
+
+"""
+ Lexical analyzer part. Splits the input character stream into tokens.
+"""
+
+keywords = ['and', 'or', 'not', 'true', 'false',
+        'else', 'if', 'while', 'return',
+        'function', 'var', 'type', 'const',
+        'struct', 'cast',
+        'import', 'module']
+
+
+class Lexer:
+    def __init__(self, diag):
+        self.diag = diag
+
+    def tokenize(self, input_file):
+        """
+           Tokenizer, generates an iterator that
+           returns tokens!
+
+           Input is a file like object.
+
+           This GREAT example was taken from python re doc page!
+        """
+        filename = input_file.name if hasattr(input_file, 'name') else ''
+        s = input_file.read()
+        input_file.close()
+        self.diag.addSource(filename, s)
+        tok_spec = [
+           ('REAL', r'\d+\.\d+'),
+           ('HEXNUMBER', r'0x[\da-fA-F]+'),
+           ('NUMBER', r'\d+'),
+           ('ID', r'[A-Za-z][A-Za-z\d_]*'),
+           ('NEWLINE', r'\n'),
+           ('SKIP', r'[ \t]'),
+           ('COMMENTS', r'//.*'),
+           ('LONGCOMMENTBEGIN', r'\/\*'),
+           ('LONGCOMMENTEND', r'\*\/'),
+           ('LEESTEKEN', r'==|->|<<|>>|!=|[\.,=:;\-+*\[\]/\(\)]|>=|<=|<>|>|<|{|}|&|\^|\|'),
+           ('STRING', r"'.*?'")
+            ]
+        tok_re = '|'.join('(?P<%s>%s)' % pair for pair in tok_spec)
+        gettok = re.compile(tok_re).match
+        line = 1
+        pos = line_start = 0
+        mo = gettok(s)
+        incomment = False
+        while mo is not None:
+            typ = mo.lastgroup
+            val = mo.group(typ)
+            if typ == 'NEWLINE':
+                line_start = pos
+                line += 1
+            elif typ == 'COMMENTS':
+                pass
+            elif typ == 'LONGCOMMENTBEGIN':
+                incomment = True
+            elif typ == 'LONGCOMMENTEND':
+                incomment = False
+            elif typ == 'SKIP':
+                pass
+            elif incomment:
+                pass # Wait until we are not in a comment section
+            else:
+                if typ == 'ID':
+                    if val in keywords:
+                        typ = val
+                elif typ == 'LEESTEKEN':
+                    typ = val
+                elif typ == 'NUMBER':
+                    val = int(val)
+                elif typ == 'HEXNUMBER':
+                    val = int(val[2:], 16)
+                    typ = 'NUMBER'
+                elif typ == 'REAL':
+                    val = float(val)
+                elif typ == 'STRING':
+                    val = val[1:-1]
+                loc = SourceLocation(filename, line, mo.start() - line_start,
+                        mo.end() - mo.start())
+                yield Token(typ, val, loc)
+            pos = mo.end()
+            mo = gettok(s, pos)
+        if pos != len(s):
+            col = pos - line_start
+            loc = SourceLocation(filename, line, col, 1)
+            raise CompilerError('Unexpected: "{0}"'.format(s[pos]), loc)
+        loc = SourceLocation(filename, line, 0, 0)
+        yield Token('END', '', loc)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/ppci/c3/parser.py	Tue Dec 03 18:00:22 2013 +0100
@@ -0,0 +1,414 @@
+import logging
+from .lexer import Lexer
+from .astnodes import FieldRef, Literal, TypeCast, Unop, Binop
+from .astnodes import Assignment, ExpressionStatement, CompoundStatement
+from .astnodes import ReturnStatement, WhileStatement, IfStatement
+from .astnodes import FunctionType, Function, FormalParameter
+from .astnodes import StructureType, DefinedType, PointerType
+from .astnodes import Constant, Variable
+from .astnodes import StructField, Deref
+from .astnodes import Package, ImportDesignator
+from .astnodes import Designator, VariableUse, FunctionCall
+from ppci import CompilerError
+
+
+class Parser:
+    """ Parses sourcecode into an abstract syntax tree (AST) """
+    def __init__(self, diag):
+        self.logger = logging.getLogger('c3')
+        self.diag = diag
+        self.lexer = Lexer(diag)
+
+    def parseSource(self, source):
+        self.logger.info('Parsing source')
+        self.initLex(source)
+        try:
+            self.parsePackage()
+            return self.mod
+        except CompilerError as e:
+            self.diag.addDiag(e)
+
+    def Error(self, msg):
+        raise CompilerError(msg, self.token.loc)
+
+    # Lexer helpers:
+    def Consume(self, typ):
+        if self.Peak == typ:
+            return self.NextToken()
+        else:
+            self.Error('Excected: "{0}", got "{1}"'.format(typ, self.Peak))
+
+    @property
+    def Peak(self):
+        return self.token.typ
+
+    @property
+    def CurLoc(self):
+        return self.token.loc
+
+    def hasConsumed(self, typ):
+        if self.Peak == typ:
+            self.Consume(typ)
+            return True
+        return False
+
+    def NextToken(self):
+        t = self.token
+        if t.typ != 'END':
+            self.token = self.tokens.__next__()
+        return t
+
+    def initLex(self, source):
+        self.tokens = self.lexer.tokenize(source)
+        self.token = self.tokens.__next__()
+
+    def addDeclaration(self, decl):
+        self.currentPart.declarations.append(decl)
+
+    def parseImport(self):
+        self.Consume('import')
+        name = self.Consume('ID').val
+        self.mod.imports.append(name)
+        self.Consume(';')
+
+    def parsePackage(self):
+        self.Consume('module')
+        name = self.Consume('ID')
+        self.Consume(';')
+        self.mod = Package(name.val, name.loc)
+        self.currentPart = self.mod
+        while self.Peak != 'END':
+            self.parseTopLevel()
+        self.Consume('END')
+
+    def parseTopLevel(self):
+        if self.Peak == 'function':
+            self.parseFunctionDef()
+        elif self.Peak == 'var':
+            self.parseVarDef()
+        elif self.Peak == 'const':
+            self.parseConstDef()
+        elif self.Peak == 'type':
+            self.parseTypeDef()
+        elif self.Peak == 'import':
+            self.parseImport()
+        else:
+            self.Error('Expected function, var, const or type')
+
+    def parseDesignator(self):
+        """ A designator designates an object """
+        name = self.Consume('ID')
+        if self.hasConsumed(':'):
+            name2 = self.Consume('ID')
+            return ImportDesignator(name.val, name2.val, name.loc)
+        else:
+            return Designator(name.val, name.loc)
+
+    # Type system
+    def parseTypeSpec(self):
+        # For now, do simple type spec, just parse an ID:
+        #return self.parseDesignator()
+        if self.Peak == 'struct':
+            self.Consume('struct')
+            self.Consume('{')
+            mems = []
+            while self.Peak != '}':
+                mem_t = self.parseTypeSpec()
+                mem_n = self.Consume('ID').val
+                mems.append(StructField(mem_n, mem_t))
+                while self.hasConsumed(','):
+                    mem_n = self.Consume('ID').val
+                    mems.append(StructField(mem_n, mem_t))
+                self.Consume(';')
+            self.Consume('}')
+            theT = StructureType(mems)
+        else:
+            theT = self.parseDesignator()
+        # Check for pointer suffix:
+        while self.hasConsumed('*'):
+            theT = PointerType(theT)
+        return theT
+
+    def parseTypeDef(self):
+        self.Consume('type')
+        newtype = self.parseTypeSpec()
+        typename = self.Consume('ID')
+        self.Consume(';')
+        df = DefinedType(typename.val, newtype, typename.loc)
+        self.addDeclaration(df)
+
+    # Variable declarations:
+    def parseVarDef(self):
+        self.Consume('var')
+        t = self.parseTypeSpec()
+
+        def parseVar():
+            name = self.Consume('ID')
+            v = Variable(name.val, t)
+            v.loc = name.loc
+            if self.hasConsumed('='):
+                v.ival = self.Expression()
+            self.addDeclaration(v)
+        parseVar()
+        while self.hasConsumed(','):
+            parseVar()
+        self.Consume(';')
+
+    def parseConstDef(self):
+        self.Consume('const')
+        t = self.parseTypeSpec()
+
+        def parseConst():
+            name = self.Consume('ID')
+            self.Consume('=')
+            val = self.Expression()
+            c = Constant(name.val, t, val)
+            c.loc = name.loc
+        parseConst()
+        while self.hasConsumed(','):
+            parseConst()
+        self.Consume(';')
+
+    # Procedures
+    def parseFunctionDef(self):
+        loc = self.Consume('function').loc
+        returntype = self.parseTypeSpec()
+        fname = self.Consume('ID').val
+        f = Function(fname, loc)
+        self.addDeclaration(f)
+        savePart = self.currentPart
+        self.currentPart = f
+        self.Consume('(')
+        parameters = []
+        if not self.hasConsumed(')'):
+            def parseParameter():
+                typ = self.parseTypeSpec()
+                name = self.Consume('ID')
+                param = FormalParameter(name.val, typ)
+                param.loc = name.loc
+                self.addDeclaration(param)
+                parameters.append(param)
+            parseParameter()
+            while self.hasConsumed(','):
+                parseParameter()
+            self.Consume(')')
+        paramtypes = [p.typ for p in parameters]
+        f.typ = FunctionType(paramtypes, returntype)
+        f.body = self.parseCompoundStatement()
+        self.currentPart = savePart
+
+    # Statements:
+
+    def parseIfStatement(self):
+        loc = self.Consume('if').loc
+        self.Consume('(')
+        condition = self.Expression()
+        self.Consume(')')
+        yes = self.parseCompoundStatement()
+        if self.hasConsumed('else'):
+            no = self.parseCompoundStatement()
+        else:
+            no = None
+        return IfStatement(condition, yes, no, loc)
+
+    def parseWhileStatement(self):
+        loc = self.Consume('while').loc
+        self.Consume('(')
+        condition = self.Expression()
+        self.Consume(')')
+        statements = self.parseCompoundStatement()
+        return WhileStatement(condition, statements, loc)
+
+    def parseReturnStatement(self):
+        loc = self.Consume('return').loc
+        if self.Peak == ';':
+            expr = Literal(0, loc)
+        else:
+            expr = self.Expression()
+        self.Consume(';')
+        return ReturnStatement(expr, loc)
+
+    def parseCompoundStatement(self):
+        self.Consume('{')
+        statements = []
+        while not self.hasConsumed('}'):
+            s = self.Statement()
+            if s is None:
+                continue
+            statements.append(s)
+        return CompoundStatement(statements)
+
+    def Statement(self):
+        # Determine statement type based on the pending token:
+        if self.Peak == 'if':
+            return self.parseIfStatement()
+        elif self.Peak == 'while':
+            return self.parseWhileStatement()
+        elif self.Peak == '{':
+            return self.parseCompoundStatement()
+        elif self.hasConsumed(';'):
+            pass
+        elif self.Peak == 'var':
+            self.parseVarDef()
+        elif self.Peak == 'return':
+            return self.parseReturnStatement()
+        else:
+            return self.AssignmentOrCall()
+
+    def AssignmentOrCall(self):
+        x = self.UnaryExpression()
+        if self.Peak == '=':
+            # We enter assignment mode here.
+            loc = self.Consume('=').loc
+            rhs = self.Expression()
+            return Assignment(x, rhs, loc)
+        else:
+            return ExpressionStatement(x, x.loc)
+
+    # Expression section:
+    # We not implement these C constructs:
+    # a(2), f = 2
+    # and this:
+    # a = 2 < x : 4 ? 1;
+
+    def Expression(self):
+        exp = self.LogicalAndExpression()
+        while self.Peak == 'or':
+            loc = self.Consume('or').loc
+            e2 = self.LogicalAndExpression()
+            exp = Binop(exp, 'or', e2, loc)
+        return exp
+
+    def LogicalAndExpression(self):
+        o = self.EqualityExpression()
+        while self.Peak == 'and':
+            loc = self.Consume('and').loc
+            o2 = self.EqualityExpression()
+            o = Binop(o, 'and', o2, loc)
+        return o
+
+    def EqualityExpression(self):
+        ee = self.SimpleExpression()
+        while self.Peak in ['<', '==', '>', '>=', '<=', '!=']:
+            op = self.Consume(self.Peak)
+            ee2 = self.SimpleExpression()
+            ee = Binop(ee, op.typ, ee2, op.loc)
+        return ee
+
+    def SimpleExpression(self):
+        """ Shift operations before + and - ? """
+        e = self.AddExpression()
+        while self.Peak in ['>>', '<<']:
+            op = self.Consume(self.Peak)
+            e2 = self.AddExpression()
+            e = Binop(e, op.typ, e2, op.loc)
+        return e
+
+    def AddExpression(self):
+        e = self.Term()
+        while self.Peak in ['+', '-']:
+            op = self.Consume(self.Peak)
+            e2 = self.Term()
+            e = Binop(e, op.typ, e2, op.loc)
+        return e
+
+    def Term(self):
+        t = self.BitwiseOr()
+        while self.Peak in ['*', '/']:
+            op = self.Consume(self.Peak)
+            t2 = self.BitwiseOr()
+            t = Binop(t, op.typ, t2, op.loc)
+        return t
+
+    def BitwiseOr(self):
+        a = self.BitwiseAnd()
+        while self.Peak in ['|']:
+            op = self.Consume(self.Peak)
+            b = self.BitwiseAnd()
+            a = Binop(a, op.typ, b, op.loc)
+        return a
+
+    def BitwiseAnd(self):
+        a = self.CastExpression()
+        while self.Peak in ['&']:
+            op = self.Consume(self.Peak)
+            b = self.CastExpression()
+            a = Binop(a, op.typ, b, op.loc)
+        return a
+
+    # Domain of unary expressions:
+
+    def CastExpression(self):
+        """
+          the C-style type cast conflicts with '(' expr ')'
+          so introduce extra keyword 'cast'
+        """
+        if self.Peak == 'cast':
+            loc = self.Consume('cast').loc
+            self.Consume('<')
+            t = self.parseTypeSpec()
+            self.Consume('>')
+            self.Consume('(')
+            ce = self.Expression()
+            self.Consume(')')
+            return TypeCast(t, ce, loc)
+        else:
+            return self.UnaryExpression()
+
+    def UnaryExpression(self):
+        if self.Peak in ['&', '*']:
+            op = self.Consume(self.Peak)
+            ce = self.CastExpression()
+            if op.val == '*':
+                return Deref(ce, op.loc)
+            else:
+                return Unop(op.typ, ce, op.loc)
+        else:
+            return self.PostFixExpression()
+
+    def PostFixExpression(self):
+        pfe = self.PrimaryExpression()
+        while self.Peak in ['[', '(', '.', '->']:
+            if self.hasConsumed('['):
+                pass
+            elif self.hasConsumed('('):
+                # Function call
+                args = []
+                if not self.hasConsumed(')'):
+                    args.append(self.Expression())
+                    while self.hasConsumed(','):
+                        args.append(self.Expression())
+                    self.Consume(')')
+                pfe = FunctionCall(pfe, args, pfe.loc)
+            elif self.hasConsumed('->'):
+                field = self.Consume('ID')
+                pfe = Deref(pfe, pfe.loc)
+                pfe = FieldRef(pfe, field.val, field.loc)
+            elif self.hasConsumed('.'):
+                field = self.Consume('ID')
+                pfe = FieldRef(pfe, field.val, field.loc)
+            else:
+                raise Exception()
+        return pfe
+
+    def PrimaryExpression(self):
+        if self.hasConsumed('('):
+            e = self.Expression()
+            self.Consume(')')
+            return e
+        elif self.Peak == 'NUMBER':
+            val = self.Consume('NUMBER')
+            return Literal(val.val, val.loc)
+        elif self.Peak == 'REAL':
+            val = self.Consume('REAL')
+            return Literal(val.val, val.loc)
+        elif self.Peak == 'true':
+            val = self.Consume('true')
+            return Literal(True, val.loc)
+        elif self.Peak == 'false':
+            val = self.Consume('false')
+            return Literal(False, val.loc)
+        elif self.Peak == 'ID':
+            d = self.parseDesignator()
+            return VariableUse(d, d.loc)
+        self.Error('Expected NUM, ID or (expr), got {0}'.format(self.Peak))
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/ppci/c3/scope.py	Tue Dec 03 18:00:22 2013 +0100
@@ -0,0 +1,70 @@
+from . import astnodes
+
+
+class Scope:
+    """ A scope contains all symbols in a scope """
+    def __init__(self, parent=None):
+        self.symbols = {}
+        self.parent = parent
+
+    def __iter__(self):
+        # Iterate in a deterministic manner:
+        return iter(self.Constants + self.Variables + self.Functions)
+
+    @property
+    def Syms(self):
+        syms = self.symbols.values()
+        return sorted(syms, key=lambda v: v.name)
+
+    @property
+    def Constants(self):
+        return [s for s in self.Syms if type(s) is astnodes.Constant]
+
+    @property
+    def Variables(self):
+        return [s for s in self.Syms if isinstance(s, astnodes.Variable)]
+
+    @property
+    def Functions(self):
+        return [s for s in self.Syms if type(s) is astnodes.Function]
+
+    def getSymbol(self, name):
+        if name in self.symbols:
+            return self.symbols[name]
+        # Look for symbol:
+        if self.parent:
+            return self.parent.getSymbol(name)
+        raise CompilerException("Symbol {0} not found".format(name), name.loc)
+
+    def hasSymbol(self, name):
+        if name in self.symbols:
+            return True
+        if self.parent:
+            return self.parent.hasSymbol(name)
+        return False
+
+    def addSymbol(self, sym):
+        self.symbols[sym.name] = sym
+
+    def __repr__(self):
+        return 'Scope with {} symbols'.format(len(self.symbols))
+
+
+def createBuiltins(scope):
+    for tn in ['u64', 'u32', 'u16', 'u8']:
+        scope.addSymbol(astnodes.BaseType(tn))
+    for t in [intType, doubleType, voidType, boolType, stringType, byteType]:
+        scope.addSymbol(t)
+
+# buildin types:
+intType = astnodes.BaseType('int')
+intType.bytesize = 4
+doubleType = astnodes.BaseType('double')
+voidType = astnodes.BaseType('void')
+boolType = astnodes.BaseType('bool')
+stringType = astnodes.BaseType('string')
+byteType = astnodes.BaseType('byte')
+
+# Create top level scope:
+topScope = Scope()
+createBuiltins(topScope)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/ppci/c3/visitor.py	Tue Dec 03 18:00:22 2013 +0100
@@ -0,0 +1,85 @@
+from .astnodes import *
+
+
+class Visitor:
+    """
+        Visitor that can visit all nodes in the AST
+        and run pre and post functions.
+    """
+    def visit(self, node, f_pre=None, f_post=None):
+        self.f_pre = f_pre
+        self.f_post = f_post
+        self.do(node)
+
+    def do(self, node):
+        # Run visitor:
+        if self.f_pre:
+            self.f_pre(node)
+
+        # Descent into subnodes:
+        if type(node) is Package:
+            for decl in node.declarations:
+                self.do(decl)
+        elif type(node) is Function:
+            for s in node.declarations:
+                self.do(s)
+            self.do(node.body)
+        elif type(node) is CompoundStatement:
+            for s in node.statements:
+                self.do(s)
+        elif type(node) is IfStatement:
+            self.do(node.condition)
+            self.do(node.truestatement)
+            if node.falsestatement:
+                self.do(node.falsestatement)
+        elif type(node) is FunctionCall:
+            for arg in node.args:
+                self.do(arg)
+        elif type(node) is Assignment:
+            self.do(node.lval)
+            self.do(node.rval)
+        elif type(node) is ReturnStatement:
+            self.do(node.expr)
+        elif type(node) is Binop:
+            self.do(node.a)
+            self.do(node.b)
+        elif type(node) is Unop:
+            self.do(node.a)
+        elif type(node) is ExpressionStatement:
+            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 [VariableUse, Variable, Literal, FunctionType,
+                            DefinedType, FormalParameter, LocalVariable]:
+            # Those nodes do not have child nodes.
+            pass
+        elif type(node) is WhileStatement:
+            self.do(node.condition)
+            self.do(node.statement)
+        else:
+            raise Exception('Could not visit "{0}"'.format(node))
+
+        # run post function
+        if self.f_post:
+            self.f_post(node)
+
+
+class AstPrinter:
+    """ Prints an AST as text """
+    def printAst(self, pkg):
+        self.indent = 0
+        visitor = Visitor()
+        visitor.visit(pkg, self.print1, self.print2)
+
+    def print1(self, node):
+        print(' ' * self.indent + str(node))
+        self.indent += 2
+
+    def print2(self, node):
+        self.indent -= 2
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/ppci/mem2reg.py	Tue Dec 03 18:00:22 2013 +0100
@@ -0,0 +1,70 @@
+import logging
+from transform import FunctionPass
+from ir import *
+
+def isAllocPromotable(allocinst):
+    # Check if alloc value is only used by load and store operations.
+    assert type(allocinst) is Alloc
+    return all(type(use) in [Load, Store] for use in allocinst.value.used_by)
+
+
+class Mem2RegPromotor(FunctionPass):
+    def promoteSingleBlock(self, ai):
+        v = ai.value
+        bb = ai.Block
+
+        # Replace all loads with the value:
+        loads = [i for i in v.used_by if isinstance(i, Load)]
+        stores = [i for i in v.used_by if isinstance(i, Store)]
+        stores.sort(key=lambda s: s.Position)
+        stores.reverse()
+
+        for load in loads:
+            idx = load.Position
+            # Search upwards:
+            for store in stores:
+                if store.Position < load.Position:
+                    break
+            load.value.replaceby(store.value)
+            logging.debug('replaced {} with {}'.format(load, store.value))
+            bb.removeInstruction(load)
+
+        # Remove store instructions:
+        for store in stores:
+            sv = store.value
+            logging.debug('removing {}'.format(store))
+            bb.removeInstruction(store)
+            #assert sv.Used
+        
+        # Remove alloca instruction:
+        assert not ai.value.Used, ai.value.used_by
+        bb.removeInstruction(ai)
+
+    def promote(self, ai):
+        # Find load operations and replace them with assignments
+        v = ai.value
+        if len(ai.value.UsedInBlocks) == 1:
+            self.promoteSingleBlock(ai)
+            return
+        
+        loads = [i for i in v.used_by if isinstance(i, Load)]
+        stores = [i for i in v.used_by if isinstance(i, Store)]
+
+        # Each store instruction can be removed (later).
+        # Instead of storing the value, we use it 
+        # where the load would have been!
+        replMap = {}
+        for store in stores:
+            replMap[store] = store.value
+
+        # for each load, track back what the defining store
+        # was.
+        for load in loads:
+            pass
+
+    def onFunction(self, f):
+        for bb in f.BasicBlocks:
+            allocs = [i for i in bb.Instructions if isinstance(i, Alloc)]
+            for i in allocs:
+                if isAllocPromotable(i):
+                    self.promote(i)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/ppci/optimize.py	Tue Dec 03 18:00:22 2013 +0100
@@ -0,0 +1,19 @@
+from mem2reg import Mem2RegPromotor
+from transform import CommonSubexpressionElimination, CleanPass
+from transform import DeadCodeDeleter, ConstantFolder
+
+def optimize(ir):
+    return 
+    cf = ConstantFolder()
+    cf.run(ir)
+    return
+    dcd = DeadCodeDeleter()
+    m2r = Mem2RegPromotor()
+    clr = CleanPass()
+    cse = CommonSubexpressionElimination()
+    dcd.run(ir)
+    clr.run(ir)
+    m2r.run(ir)
+    cse.run(ir)
+    cf.run(ir)
+    dcd.run(ir)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/ppci/transform.py	Tue Dec 03 18:00:22 2013 +0100
@@ -0,0 +1,142 @@
+"""
+ Transformation to optimize IR-code
+"""
+
+import logging
+import ir
+# Standard passes:
+
+class FunctionPass:
+    def __init__(self):
+        self.logger = logging.getLogger('optimize')
+
+    def run(self, ir):
+        """ Main entry point for the pass """
+        self.logger.info('Running pass {}'.format(type(self)))
+        ir.check()
+        self.prepare()
+        for f in ir.Functions:
+            self.onFunction(f)
+        ir.check()
+
+    def onFunction(self, f):
+        """ Override this virtual method """
+        raise NotImplementedError()
+
+    def prepare(self):
+        pass
+
+
+class BasicBlockPass(FunctionPass):
+    def onFunction(self, f):
+        for bb in f.Blocks:
+            self.onBasicBlock(bb)
+
+    def onBasicBlock(self, bb):
+        """ Override this virtual method """
+        raise NotImplementedError()
+
+
+class InstructionPass(BasicBlockPass):
+    def onBasicBlock(self, bb):
+        for ins in iter(bb.Instructions):
+            self.onInstruction(ins)
+
+    def onInstruction(self, ins):
+        """ Override this virtual method """
+        raise NotImplementedError()
+
+
+class BasePass(BasicBlockPass):
+    def onBasicBlock(self, bb):
+        pass
+
+
+# Usefull transforms:
+class ConstantFolder(BasePass):
+    def __init__(self):
+        super().__init__()
+        self.ops = {}
+        self.ops['+'] = lambda x, y: x + y
+        self.ops['-'] = lambda x, y: x - y
+        self.ops['*'] = lambda x, y: x * y
+        self.ops['<<'] = lambda x, y: x << y
+
+    def postExpr(self, expr):
+        if type(i) is BinaryOperator and i.operation in self.ops.keys() and type(i.a) is Const and type(i.b) is Const:
+            vr = self.ops[i.operation](i.a.value, i.b.value)
+            return Const(vr)
+        else:
+            return expr
+
+
+class DeadCodeDeleter(BasicBlockPass):
+    def onBasicBlock(self, bb):
+        def instructionUsed(ins):
+            if not type(ins) in [ImmLoad, BinaryOperator]:
+                return True
+            if len(ins.defs) == 0:
+                # In case this instruction does not define any 
+                # variables, assume it is usefull.
+                return True
+            return any(d.Used for d in ins.defs)
+
+        change = True
+        while change:
+            change = False
+            for i in bb.Instructions:
+                if instructionUsed(i):
+                    continue
+                bb.removeInstruction(i)
+                change = True
+
+
+class CommonSubexpressionElimination(BasicBlockPass):
+    def onBasicBlock(self, bb):
+        constMap = {}
+        to_remove = []
+        for i in bb.Instructions:
+            if isinstance(i, ImmLoad):
+                if i.value in constMap:
+                    t_new = constMap[i.value]
+                    t_old = i.target
+                    logging.debug('Replacing {} with {}'.format(t_old, t_new))
+                    t_old.replaceby(t_new)
+                    to_remove.append(i)
+                else:
+                    constMap[i.value] = i.target
+            elif isinstance(i, BinaryOperator):
+                k = (i.value1, i.operation, i.value2)
+                if k in constMap:
+                    t_old = i.result
+                    t_new = constMap[k]
+                    logging.debug('Replacing {} with {}'.format(t_old, t_new))
+                    t_old.replaceby(t_new)
+                    to_remove.append(i)
+                else:
+                    constMap[k] = i.result
+        for i in to_remove:
+            logging.debug('removing {}'.format(i))
+            bb.removeInstruction(i)
+
+
+class CleanPass(FunctionPass):
+    def onFunction(self, f):
+        removeEmptyBasicBlocks(f)
+
+
+def removeEmptyBlocks(f):
+    """ Remove empty basic blocks from function. """
+    # If a block only contains a branch, it can be removed:
+    empty = lambda b: type(b.FirstInstruction) is ir.Jump
+    empty_blocks = list(filter(empty, f.Blocks))
+    for b in empty_blocks:
+        # Update predecessors
+        preds = b.Predecessors
+        if b not in preds + [f.entry]:
+            # Do not remove if preceeded by itself
+            tgt = b.LastInstruction.target
+            for pred in preds:
+                  pred.LastInstruction.changeTarget(b, tgt)
+            logging.debug('Removing empty block: {}'.format(b))
+            f.removeBlock(b)
--- a/python/target/armframe.py	Sun Dec 01 18:37:23 2013 +0100
+++ b/python/target/armframe.py	Tue Dec 03 18:00:22 2013 +0100
@@ -1,7 +1,7 @@
 import ir
 from .basetarget import Label, Comment, Alignment, LabelRef, DebugInfo, Nop
 from .basetarget import Imm7
-from irmach import AbstractInstruction as makeIns, Frame
+from irmach import makeIns, Frame
 from .arminstructions import Dcd, AddSp, SubSp, Push, Pop, Mov2
 from .arminstructions import R0, R1, R2, R3, R4, R5, R6, R7, LR, PC, SP
 
--- a/python/target/arminstructions.py	Sun Dec 01 18:37:23 2013 +0100
+++ b/python/target/arminstructions.py	Tue Dec 03 18:00:22 2013 +0100
@@ -418,14 +418,14 @@
         return '{} {}, {}, {}'.format(self.mnemonic, self.rd, self.rn, self.imm3.imm)
 
 @instruction
-class addregregimm3_ins(regregimm3_base):
+class Add2(regregimm3_base):
     """ add Rd, Rn, imm3 """
     mnemonic = 'add'
     opcode = 0b0001110
 
 
 @instruction
-class subregregimm3_ins(regregimm3_base):
+class Sub2(regregimm3_base):
     """ sub Rd, Rn, imm3 """
     mnemonic = 'sub'
     opcode = 0b0001111
@@ -491,7 +491,7 @@
         
 
 @instruction
-class mulregreg_ins(ArmInstruction):
+class Mul(ArmInstruction):
     """ mul Rn, Rdm """
     operands = (Reg8Op, Reg8Op)
     mnemonic = 'MUL'
--- a/python/target/arminstructionselector.py	Sun Dec 01 18:37:23 2013 +0100
+++ b/python/target/arminstructionselector.py	Tue Dec 03 18:00:22 2013 +0100
@@ -4,7 +4,7 @@
 from .instructionselector import InstructionSelector
 from .arminstructions import Orr, Lsl, Str2, Ldr2, Ldr3, B, Bl, Bgt, Blt, Beq
 from .arminstructions import Mov2, Mov3
-from .arminstructions import Add, Sub, Cmp
+from .arminstructions import Add, Sub, Cmp, Sub2, Add2, Mul
 from .basetarget import Imm8, Imm7, Imm3
 
 
@@ -18,7 +18,7 @@
             a = self.munchExpr(e.a)
             d = self.newTmp()
             c = Imm3(e.b.value)
-            self.emit(arm.addregregimm3_ins, others=[c], dst=[d], src=[a])
+            self.emit(Add2, others=[c], dst=[d], src=[a])
             return d
         elif isinstance(e, ir.Binop) and e.operation == '+':
             a = self.munchExpr(e.a)
@@ -31,7 +31,7 @@
             a = self.munchExpr(e.a)
             d = self.newTmp()
             c = Imm3(e.b.value)
-            self.emit(arm.subregregimm3_ins, others=[c], dst=[d], src=[a])
+            self.emit(Sub2, others=[c], dst=[d], src=[a])
             return d
         elif isinstance(e, ir.Binop) and e.operation == '-':
             a = self.munchExpr(e.a)
@@ -59,7 +59,7 @@
             d = self.newTmp()
             self.move(d, a)
             # this mul instruction has operands swapped:
-            self.emit(arm.mulregreg_ins, dst=[d], src=[b, d])
+            self.emit(Mul, dst=[d], src=[b, d])
             return d
         elif isinstance(e, ir.Const) and e.value < 256:
             d = self.newTmp()
--- a/python/transform.py	Sun Dec 01 18:37:23 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,142 +0,0 @@
-"""
- Transformation to optimize IR-code
-"""
-
-import logging
-import ir
-# Standard passes:
-
-class FunctionPass:
-    def __init__(self):
-        self.logger = logging.getLogger('optimize')
-
-    def run(self, ir):
-        """ Main entry point for the pass """
-        self.logger.info('Running pass {}'.format(type(self)))
-        ir.check()
-        self.prepare()
-        for f in ir.Functions:
-            self.onFunction(f)
-        ir.check()
-
-    def onFunction(self, f):
-        """ Override this virtual method """
-        raise NotImplementedError()
-
-    def prepare(self):
-        pass
-
-
-class BasicBlockPass(FunctionPass):
-    def onFunction(self, f):
-        for bb in f.Blocks:
-            self.onBasicBlock(bb)
-
-    def onBasicBlock(self, bb):
-        """ Override this virtual method """
-        raise NotImplementedError()
-
-
-class InstructionPass(BasicBlockPass):
-    def onBasicBlock(self, bb):
-        for ins in iter(bb.Instructions):
-            self.onInstruction(ins)
-
-    def onInstruction(self, ins):
-        """ Override this virtual method """
-        raise NotImplementedError()
-
-
-class BasePass(BasicBlockPass):
-    def onBasicBlock(self, bb):
-        pass
-
-
-# Usefull transforms:
-class ConstantFolder(BasePass):
-    def __init__(self):
-        super().__init__()
-        self.ops = {}
-        self.ops['+'] = lambda x, y: x + y
-        self.ops['-'] = lambda x, y: x - y
-        self.ops['*'] = lambda x, y: x * y
-        self.ops['<<'] = lambda x, y: x << y
-
-    def postExpr(self, expr):
-        if type(i) is BinaryOperator and i.operation in self.ops.keys() and type(i.a) is Const and type(i.b) is Const:
-            vr = self.ops[i.operation](i.a.value, i.b.value)
-            return Const(vr)
-        else:
-            return expr
-
-
-class DeadCodeDeleter(BasicBlockPass):
-    def onBasicBlock(self, bb):
-        def instructionUsed(ins):
-            if not type(ins) in [ImmLoad, BinaryOperator]:
-                return True
-            if len(ins.defs) == 0:
-                # In case this instruction does not define any 
-                # variables, assume it is usefull.
-                return True
-            return any(d.Used for d in ins.defs)
-
-        change = True
-        while change:
-            change = False
-            for i in bb.Instructions:
-                if instructionUsed(i):
-                    continue
-                bb.removeInstruction(i)
-                change = True
-
-
-class CommonSubexpressionElimination(BasicBlockPass):
-    def onBasicBlock(self, bb):
-        constMap = {}
-        to_remove = []
-        for i in bb.Instructions:
-            if isinstance(i, ImmLoad):
-                if i.value in constMap:
-                    t_new = constMap[i.value]
-                    t_old = i.target
-                    logging.debug('Replacing {} with {}'.format(t_old, t_new))
-                    t_old.replaceby(t_new)
-                    to_remove.append(i)
-                else:
-                    constMap[i.value] = i.target
-            elif isinstance(i, BinaryOperator):
-                k = (i.value1, i.operation, i.value2)
-                if k in constMap:
-                    t_old = i.result
-                    t_new = constMap[k]
-                    logging.debug('Replacing {} with {}'.format(t_old, t_new))
-                    t_old.replaceby(t_new)
-                    to_remove.append(i)
-                else:
-                    constMap[k] = i.result
-        for i in to_remove:
-            logging.debug('removing {}'.format(i))
-            bb.removeInstruction(i)
-
-
-class CleanPass(FunctionPass):
-    def onFunction(self, f):
-        removeEmptyBasicBlocks(f)
-
-
-def removeEmptyBlocks(f):
-    """ Remove empty basic blocks from function. """
-    # If a block only contains a branch, it can be removed:
-    empty = lambda b: type(b.FirstInstruction) is ir.Jump
-    empty_blocks = list(filter(empty, f.Blocks))
-    for b in empty_blocks:
-        # Update predecessors
-        preds = b.Predecessors
-        if b not in preds + [f.entry]:
-            # Do not remove if preceeded by itself
-            tgt = b.LastInstruction.target
-            for pred in preds:
-                  pred.LastInstruction.changeTarget(b, tgt)
-            logging.debug('Removing empty block: {}'.format(b))
-            f.removeBlock(b)
--- a/python/zcc.py	Sun Dec 01 18:37:23 2013 +0100
+++ b/python/zcc.py	Tue Dec 03 18:00:22 2013 +0100
@@ -4,7 +4,7 @@
 import argparse
 import logging
 
-import c3
+from ppci.c3 import Builder
 import ppci
 import codegen
 import outstream
@@ -52,7 +52,7 @@
     """
     logging.info('Zcc started')
     # Front end:
-    c3b = c3.Builder(diag)
+    c3b = Builder(diag)
     cg = codegen.CodeGenerator(tg)
 
     # TODO: remove this arm specifics:
--- a/readme.rst	Sun Dec 01 18:37:23 2013 +0100
+++ b/readme.rst	Tue Dec 03 18:00:22 2013 +0100
@@ -18,7 +18,7 @@
 Software dependencies
 ---------------------
 
-* python3
+* python3.3
 * (optional) pyqt5, pyqt4 or pyside
 
 How to start the IDE
@@ -33,7 +33,7 @@
 Docs
 ----
 
-Docs are here:
+Docs are located here:
 http://lcfos.readthedocs.org/en/latest/
 
 Run unittests
@@ -42,12 +42,14 @@
 .. code:: bash
 
     cd test
-    python -m unittest
+    ./runtests.sh
 
 
 Status
 ------
 
+The project is contains tests which are run continuously at drone.io.
+
 .. image:: https://drone.io/bitbucket.org/windel/lcfos/status.png
 
 .. image:: https://www.ohloh.net/p/lcfos/widgets/project_thin_badge.gif
--- a/test/c3examples/blink.c3	Sun Dec 01 18:37:23 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-/* This file blinks a LED on the STM32F4 discovery board.
-
-the board has 4 leds on PD12, PD13, PD14 and PD15
-
-*/
-
-module blink;
-
-import stm32f4xx;
-
-// Functions:
-function void main()
-{
-    // Memory mapped control registers:
-    var GPIO_Type GPIOD;
-    GPIOD = cast<GPIO_Type>(0x40020C00);
-    var RCC_Type RCC;
-    RCC = cast<RCC_Type>(0x40023800);
-
-    // Enable the clock to port D:
-    RCC->AHB1ENR = RCC->AHB1ENR | 0x8;
-
-
-    // PD13 == output (01)
-    GPIOD->MODER = (1 << 26);
-    GPIOD->ODR = (1 << 13);
-
-    while(true) {}
-}
-
--- a/test/c3examples/burn.c3	Sun Dec 01 18:37:23 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-/*
-
-This file blinks a LED on the STM32F4 discovery board.
-
-the board has 4 leds on PD12, PD13, PD14 and PD15
-
-*/
-
-module burn;
-
-import stm32f4xx;
-
-/*
-function void init()
-{
-}
-*/
-
-function void main()
-{
-    //init();
-    var RCC_Type RCC;
-    RCC = cast<RCC_Type>(0x40023800);
-
-    // Enable the clock to port D:
-    RCC->AHB1ENR = RCC->AHB1ENR | (1 << 3);
-    // Memory mapped control registers:
-    var GPIO_Type GPIOD;
-    GPIOD = cast<GPIO_Type>(0x40020C00);
-
-    var int pin;
-    pin = 15;
-    // PD13 == output (01)
-    GPIOD->MODER = (1 << (pin << 1));
-    GPIOD->ODR = (1 << pin);
-
-    while(true) {}
-}
-
--- a/test/c3examples/burn.c3proj	Sun Dec 01 18:37:23 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,6 +0,0 @@
-
-[Burn]
-srcs = burn2.c3
-imps = stm32f4xx.c3
-target = arm
-
--- a/test/c3examples/burn2.c3	Sun Dec 01 18:37:23 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +0,0 @@
-/*
-
-This file blinks a LED on the STM32F4 discovery board.
-
-the board has 4 leds on PD12, PD13, PD14 and PD15
-
-*/
-
-module burn2;
-
-import stm32f4xx;
-
-function int add(int a, int b)
-{
-    return a + b;
-}
-
-function void init(int pin)
-{
-    if (pin < 12)
-    {
-        return;
-    }
-
-    if (pin > 15)
-    {
-        return;
-    }
-
-    var stm32f4xx:RCC_Type RCC;
-    RCC = cast<stm32f4xx:RCC_Type>(0x40023800);
-
-    // Enable the clock to port D:
-    RCC->AHB1ENR = RCC->AHB1ENR | (1 << 3);
-    // Memory mapped control registers:
-    var stm32f4xx:GPIO_Type GPIOD;
-    GPIOD = cast<stm32f4xx:GPIO_Type>(0x40020C00);
-
-    // PD13 == output (01)
-    GPIOD->MODER = (1 << (pin << 1));
-    GPIOD->ODR = (1 << pin);
-}
-
-
-function void main()
-{
-    // Vary between 12 and 15:
-    init(13);
-
-    var int a;
-    a = 0
-    while (a < 1000)
-    {
-        a = add(a, 1);
-    }
-
-    while(true) {}
-}
-
--- a/test/c3examples/cast.c3	Sun Dec 01 18:37:23 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,18 +0,0 @@
-
-/*
- Demo of how to type cast
-*/
-
-module castdemo;
-
-function int testcast()
-{
-    var int a;
-    var int* b;
-    a = 3;
-    
-    b = cast<int*>(a);
-
-    return 0;
-}
-
--- a/test/c3examples/comments.c3	Sun Dec 01 18:37:23 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,14 +0,0 @@
-
-/*
- block
- comment
-*/
-
-// fjd jjd-
-module comments; // hjfkds
-
-function int tst()
-{
-    return 0;
-}
-
--- a/test/c3examples/functions.c3	Sun Dec 01 18:37:23 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-
-/*
- Demo of function usage
-*/
-
-module functiondemo;
-
-function void main()
-{
-    var int a, b, c;
-    a = 3;
-    b = a;
-    a =3;
-    b = fib(a + 9);
-    sum(a, b);
-}
-
-function int fib(int x)
-{
-    return fib(x - 1) * x;
-}
-
-function int sum(int a, int b)
-{
-    return a + b;
-}
-
--- a/test/c3examples/stm32f4xx.c3	Sun Dec 01 18:37:23 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,31 +0,0 @@
-
-module stm32f4xx;
-
-type struct {
-    int MODER;
-    int OTYPER;
-    int OSPEEDR;
-    int PUPDR;
-    int IDR;
-    int ODR;
-}* GPIO_Type;
-
-type struct {
-    int CR;
-    int PLLCFGR;
-    int CFGR;
-    int CIR;
-    int AHB1RSTR;
-    int AHB2RSTR;
-    int AHB3RSTR;
-    int reserved0;
-    int APB1RSTR;
-    int APB2RSTR;
-    int reserved1a, reserved1b;
-    int AHB1ENR;
-    int AHB2ENR;
-    int AHB3ENR;
-    int reserved2;
-    int APB1ENR, APB2ENR;
-}* RCC_Type;
-
--- a/test/c3examples/types.c3	Sun Dec 01 18:37:23 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,40 +0,0 @@
-
-/*
- Demo of how to define types
-*/
-
-module typedemo;
-
-type int A;
-type int B;
-type struct {
-  int x, y;
-  A z;
-} C;
-type struct {
-  C x;
-  B y;
-  int z;
-} D;
-
-type D* E;
-
-function int testcast()
-{
-    var A a;
-    var B b;
-    a = 3;
-    b = a;
-    var C c;
-    c.x = a;
-    c.z = c.y;
-    var D d;
-    var E e;
-    var D* e2;
-    e = &d;
-    e2 = e;
-    e2->x.x = 22;
-    
-    return 0;
-}
-
--- a/test/runtests.sh	Sun Dec 01 18:37:23 2013 +0100
+++ b/test/runtests.sh	Tue Dec 03 18:00:22 2013 +0100
@@ -14,7 +14,7 @@
   done
 else
   set -e
-  python -m unittest -v
+  python -m unittest
 fi
 
 
--- a/test/testc3.py	Sun Dec 01 18:37:23 2013 +0100
+++ b/test/testc3.py	Tue Dec 03 18:00:22 2013 +0100
@@ -1,74 +1,13 @@
-import c3
-import time
+from ppci.c3 import Builder, Lexer
 import ppci
-import ir
 import unittest
-import glob
 import io
 
-testsrc = """module test;
-
-/*
- demo of the source that is correct :)
-*/ 
-var int c, d;
-var double e;
-var int f;
-
-const int A = 1337;
-
-function void test1()
-{
-    var int bdd;
-    var int a = 10;
-    bdd = 20;
-    var int buf;
-    var int i;
-    i = 2;
-    var int zero = i - 2;
-    if (i > 1)
-    {
-       buf = b + 22 * i - 13 + (55 * 2 *9-2) / 44 - 1;
-    }
-    else
-    {
-      ;;;
-    }
-
-    t2(2, 3);
-}
-
-function int t2(int a, int b)
-{
-   if (a > 0)
-   {
-      a = 2 + t2(a - 1, 10);
-   }
-
-   return a + b;
-}
-
-var int a, b;
-
-function int t3(int aap, int blah)
-{
-   if (a > blah and blah < 45 + 33 or 33 > aap or 6 > 2 and true)
-   {
-      a = 2 + t2(a - 1, 0);
-   }
-
-   return a + b;
-}
-
-var int hahaa = 23 * 2;
-
-
-"""
 
 class testLexer(unittest.TestCase):
     def setUp(self):
         diag = ppci.DiagnosticsManager()
-        self.l = c3.Lexer(diag)
+        self.l = Lexer(diag)
 
     def testUnexpectedCharacter(self):
         snippet = io.StringIO(""" var s \u6c34 """)
@@ -102,12 +41,9 @@
 class testBuilder(unittest.TestCase):
     def setUp(self):
         self.diag = ppci.DiagnosticsManager()
-        self.builder = c3.Builder(self.diag)
+        self.builder = Builder(self.diag)
         self.diag.clear()
 
-    def testSrc(self):
-        self.expectOK(testsrc)
-
     def expectErrors(self, snippet, rows):
         """ Helper to test for expected errors on rows """
         ircode = list(self.builder.build([io.StringIO(snippet)]))
@@ -309,7 +245,6 @@
         """
         self.expectOK(snippet)
 
-    @unittest.skip('Too strange to handle')
     def testStructCall(self):
         snippet = """
          module teststruct1;
@@ -437,41 +372,6 @@
         """
         self.expectOK(snippet)
 
-    @unittest.skip('To be rewritten')
-    def testExamples(self):
-        """ Test all examples in the c3/examples directory """
-        example_filenames = glob.glob('./c3examples/*.c3')
-        for filename in example_filenames:
-            with open(filename, 'r') as f:
-                self.expectOK(f)
-
-    def test2(self):
-        # testsrc2 is valid code:
-        snippet = """
-        module test2;
-
-        function void tst()
-        {
-           var int a, b;
-           a = 2 * 33 - 12;
-           b = a * 2 + 13;
-           a = b + a;
-           if (a > b and b == 3)
-           {
-              var int x = a;
-              x = b * 2 - a;
-              a = x*x;
-           }
-           else
-           {
-              a = b + a;
-           }
-        }
-
-        """
-        self.expectOK(snippet)
 
 if __name__ == '__main__':
     unittest.main()
-
-
--- a/test/testir.py	Sun Dec 01 18:37:23 2013 +0100
+++ b/test/testir.py	Tue Dec 03 18:00:22 2013 +0100
@@ -1,10 +1,8 @@
 import unittest, os
 import sys
-import c3
 import ppci
 import ir
-import transform
-import optimize
+from ppci.transform import ConstantFolder
 
 
 class IrCodeTestCase(unittest.TestCase):
@@ -53,7 +51,7 @@
 class ConstantFolderTestCase(unittest.TestCase):
     def setUp(self):
         self.b = ir.Builder()
-        self.cf = transform.ConstantFolder()
+        self.cf = ConstantFolder()
         self.m = ir.Module('test')
         self.b.setModule(self.m)
 
--- a/test/testzcc.py	Sun Dec 01 18:37:23 2013 +0100
+++ b/test/testzcc.py	Tue Dec 03 18:00:22 2013 +0100
@@ -11,7 +11,7 @@
     """ Tests the compiler driver """
 
     def do(self, filenames, imps=[]):
-        basedir = 'c3examples'
+        basedir = os.path.join('..', 'examples', 'c3')
         arg_list = [os.path.join(basedir, fn) for fn in filenames]
         for fn in imps:
             arg_list.append('-i')
@@ -21,10 +21,6 @@
         args = zcc.parser.parse_args(arg_list)
         self.assertEqual(0, zcc.main(args))
 
-    @unittest.skip('Not working yet')
-    def testBurn(self):
-        self.do(['burn.c3'], ['stm32f4xx.c3'])
-
     def testBurn2(self):
         self.do(['burn2.c3'], ['stm32f4xx.c3'])
 
@@ -34,6 +30,9 @@
     def testCast(self):
         self.do(['cast.c3'])
 
+    def testFunctions(self):
+        self.do(['functions.c3'])
+
     def testSectionAddress(self):
         src = """module tst; 
             function void t2() {var int t3; t3 = 2;}
@@ -51,4 +50,3 @@
 
 if __name__ == '__main__':
     unittest.main()
-