changeset 287:1c7c1e619be8

File movage
author Windel Bouwman
date Thu, 21 Nov 2013 11:57:27 +0100
parents d9df72971cbf
children a747a45dcd78
files cos/bochsrc.txt python/asm.py python/c3/__init__.py python/c3/analyse.py python/c3/builder.py python/c3/codegenerator.py python/c3/lexer.py python/c3/typecheck.py python/cortexm3.py python/grind.py python/hexedit.py python/ide.py python/iso9660.py python/old/assembler.py python/old/modules.py python/ppci/common.py python/thex.py python/x86_2.py python/zcc.py test/c3examples/burn2.c3 test/grind.py test/gui/testhexedit.py test/runtests.sh test/testc3.py test/testx86asm.py test/testzcc.py
diffstat 26 files changed, 851 insertions(+), 1051 deletions(-) [+]
line wrap: on
line diff
--- a/cos/bochsrc.txt	Fri Nov 15 13:52:32 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,31 +0,0 @@
-display_library: x, options="gui_debug" # use GTK debugger gui
-romimage: file=$BXSHARE/BIOS-bochs-latest 
-cpu: count=1, ips=1500000, reset_on_triple_fault=1, ignore_bad_msrs=1, msrs="msrs.def"
-cpuid: mmx=1, sep=1, sse=sse4_2, aes=1, movbe=1, xsave=1
-memory: guest=128, host=256
-megs: 48
-vgaromimage: file=$BXSHARE/VGABIOS-lgpl-latest
-vga: extension=vbe
-floppya: image=bootdisk.img, status=inserted
-ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14
-ata1: enabled=1, ioaddr1=0x170, ioaddr2=0x370, irq=15
-ata2: enabled=0, ioaddr1=0x1e8, ioaddr2=0x3e0, irq=11
-ata3: enabled=0, ioaddr1=0x168, ioaddr2=0x360, irq=9
-boot: floppy
-floppy_bootsig_check: disabled=0
-panic: action=ask
-error: action=report
-info: action=report
-debug: action=ignore
-debugger_log: -
-
-vga_update_interval: 300000
-keyboard_serial_delay: 250
-keyboard_paste_delay: 100000
-mouse: enabled=0
-private_colormap: enabled=0
-keyboard_mapping: enabled=0, map=
-i440fxsupport: enabled=1
-
-magic_break: enabled=1
-
--- a/python/asm.py	Fri Nov 15 13:52:32 2013 +0100
+++ b/python/asm.py	Thu Nov 21 11:57:27 2013 +0100
@@ -45,15 +45,16 @@
          elif typ == 'STRING':
            val = val[1:-1]
          col = mo.start() - line_start
-         loc = SourceLocation(line, col, 0)   # TODO retrieve length?
+         loc = SourceLocation('', line, col, 0)   # TODO retrieve length?
          yield Token(typ, val, loc)
        pos = mo.end()
        mo = gettok(s, pos)
      if pos != len(s):
        col = pos - line_start
-       loc = SourceLocation(line, col, 0)
+       loc = SourceLocation('', line, col, 0)
        raise CompilerError('Unexpected character {0}'.format(s[pos]), loc)
 
+
 class Lexer:
    def __init__(self, src):
       self.tokens = tokenize(src)
@@ -66,6 +67,7 @@
    def Peak(self):
       return self.curTok
 
+
 class Parser:
     def __init__(self):
         # Construct a parser given a grammar:
--- a/python/c3/__init__.py	Fri Nov 15 13:52:32 2013 +0100
+++ b/python/c3/__init__.py	Thu Nov 21 11:57:27 2013 +0100
@@ -6,8 +6,7 @@
 # Convenience imports:
 
 from .parser import Parser
-from .typecheck import TypeChecker
-from .analyse import Analyzer
+from .analyse import Analyzer, TypeChecker
 from .codegenerator import CodeGenerator
 from .astprinter import AstPrinter
 from .visitor import Visitor
--- a/python/c3/analyse.py	Fri Nov 15 13:52:32 2013 +0100
+++ b/python/c3/analyse.py	Thu Nov 21 11:57:27 2013 +0100
@@ -1,14 +1,14 @@
 import logging
 from .visitor import Visitor
 from .astnodes import *
-from .scope import Scope, topScope
-from .typecheck import theType
+from .scope import *
+
 
 class Analyzer:
     """ 
         Context handling is done here.
         Scope is attached to the correct modules.
-        This class checks names and references 
+        This class checks names and references.
     """
     def __init__(self, diag):
         self.diag = diag
@@ -18,7 +18,7 @@
         self.logger.info('Checking package {}'.format(pkg.name))
         self.ok = True
         visitor = Visitor()
-        # Prepare top level scope:
+        # Prepare top level scope and set scope to all objects:
         self.scopeStack = [topScope]
         modScope = Scope(self.CurrentScope)
         self.scopeStack.append(modScope)
@@ -34,7 +34,6 @@
             for x in ip.declarations:
                 modScope.addSymbol(x)
         visitor.visit(pkg, self.findRefs)
-        visitor.visit(pkg, self.sanity)
         return self.ok
 
     def error(self, msg, loc=None):
@@ -82,12 +81,9 @@
                 s.addRef(None)
             return s
         else:
-            self.ok = False
-            msg = 'Cannot resolve name {0}'.format(d.tname)
-            self.diag.error(msg, d.loc)
+            self.error('Cannot resolve name {0}'.format(d.tname), d.loc)
 
     def resolveType(self, t, scope):
-        # TODO: what about structs?
         if type(t) is PointerType:
             t.ptype = self.resolveType(t.ptype, scope)
             return t
@@ -131,9 +127,192 @@
         elif type(sym) is DefinedType:
             sym.typ = self.resolveType(sym.typ, sym.scope)
 
-    def sanity(self, sym):
-        if type(sym) is FunctionType:
+# 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 equality.
+        Not equal until proven otherwise.
+    """
+    # Recurse into named types:
+    a = theType(a)
+    b = theType(b)
+
+    # Compare for structural equivalence:
+    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
+            for amem, bmem in zip(a.mems, b.mems):
+                if not equalTypes(amem.typ, bmem.typ):
+                    return False
+            return True
+        else:
+            raise Exception('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:
+    def __init__(self, diag):
+        self.diag = diag
+
+    def error(self, msg, loc):
+        """
+            Wrapper that registers the message and marks the result invalid
+        """
+        self.diag.error(msg, loc)
+        self.ok = False
+
+    def checkPackage(self, pkg):
+        self.ok = True
+        visitor = Visitor()
+        visitor.visit(pkg, f_post=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 Function:
+        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/builder.py	Fri Nov 15 13:52:32 2013 +0100
+++ b/python/c3/builder.py	Thu Nov 21 11:57:27 2013 +0100
@@ -4,13 +4,13 @@
 from . astprinter import AstPrinter
 import glob
 
+
 class Builder:
     """ 
         Generates IR-code from c3 source.
         Reports errors to the diagnostics system
     """
     def __init__(self, diag):
-        self.pack_dir = None
         self.logger = logging.getLogger('c3')
         self.diag = diag
         self.parser = Parser(diag)
@@ -23,44 +23,29 @@
         """ package provider for use when analyzing """
         if pname in self.packages:
             return self.packages[pname]
-        else:
-            # Try to lookup package from file
-            fns = glob.glob('./**/{}.c3'.format(pname))
-            if fns:
-                with open(fns[0]) as f:
-                    src = f.read()
-                self.build(src)
-            if self.pack_dir:
-                fns = glob.glob('{}/{}.c3'.format(self.pack_dir, pname))
-                if fns:
-                    with open(fns[0]) as f:
-                        src = f.read()
-                    self.build(src)
-            if pname in self.packages:
-                return self.packages[pname]
 
-    def parse(self, src):
-        pkg = self.parser.parseSource(src)
-        if not pkg:
-            return
+    def checkSource(self, srcs, imps=[]):
+        """ Performs syntax and type check. """
+        # Parse source:
+        for src in srcs:
+            pkg = self.parser.parseSource(src)
+            src.close()
+            if not pkg:
+                return
+            # Store for later use:
+            self.packages[pkg.name] = pkg
 
-        # TODO: merge the two below?
-        #AstPrinter().printAst(pkg)
-        if not self.al.analyzePackage(pkg, self):
-            return
-        if not self.tc.checkPackage(pkg):
-            return
+        for pkg in self.packages.values():
+            # Only return ircode when everything is OK
+            # TODO: merge the two below?
+            if not self.al.analyzePackage(pkg, self):
+                return
+            if not self.tc.checkPackage(pkg):
+                return
+            yield pkg
 
-        # Store for later use:
-        self.packages[pkg.name] = pkg
-        return pkg
-
-    def build(self, src, pack_dir=None):
+    def build(self, srcs, imps=[]):
         """ Create IR-code from sources """
-        self.pack_dir = pack_dir
-        pkg = self.parse(src)
+        for pkg in self.checkSource(srcs, imps):
+            yield self.cg.gencode(pkg)
 
-        # Only return ircode when everything is OK
-        if pkg:
-            return self.cg.gencode(pkg)
-
--- a/python/c3/codegenerator.py	Fri Nov 15 13:52:32 2013 +0100
+++ b/python/c3/codegenerator.py	Thu Nov 21 11:57:27 2013 +0100
@@ -3,7 +3,7 @@
 from . import astnodes
 from .scope import boolType, intType
 from ppci import CompilerError
-from .typecheck import theType
+from .analyse import theType
 
 
 class CodeGenerator(ir.Builder):
--- a/python/c3/lexer.py	Fri Nov 15 13:52:32 2013 +0100
+++ b/python/c3/lexer.py	Thu Nov 21 11:57:27 2013 +0100
@@ -12,14 +12,18 @@
    'struct', 'cast', \
    'import', 'module' ]
 
-def tokenize(s):
-     """
+def tokenize(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!
-     """
-     tok_spec = [
+    """
+    filename = input_file.name if hasattr(input_file, 'name') else ''
+    s = input_file.read()
+    tok_spec = [
        ('REAL', r'\d+\.\d+'),
        ('HEXNUMBER', r'0x[\da-fA-F]+'),
        ('NUMBER', r'\d+'),
@@ -32,13 +36,13 @@
        ('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:
+    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':
@@ -69,14 +73,14 @@
            val = float(val)
          elif typ == 'STRING':
            val = val[1:-1]
-         loc = SourceLocation(line, mo.start()-line_start, mo.end() - mo.start())
+         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(line, col, 1)
-         raise CompilerError('Unexpected character "{0}"'.format(s[pos]), loc)
-     loc = SourceLocation(line, 0, 0)
-     yield Token('END', '', loc)
+    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/typecheck.py	Fri Nov 15 13:52:32 2013 +0100
+++ b/python/c3/typecheck.py	Thu Nov 21 11:57:27 2013 +0100
@@ -1,192 +1,4 @@
 from .astnodes import *
-from .scope import *
 from .visitor import Visitor
 
-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 equality.
-        Not equal until proven otherwise.
-    """
-    # Recurse into named types:
-    a = theType(a)
-    b = theType(b)
-
-    # Compare for structural equivalence:
-    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
-            for amem, bmem in zip(a.mems, b.mems):
-                if not equalTypes(amem.typ, bmem.typ):
-                    return False
-            return True
-        else:
-            raise Exception('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:
-    def __init__(self, diag):
-        self.diag = diag
-
-    def error(self, msg, loc):
-        """
-            Wrapper that registers the message and marks the result invalid
-        """
-        self.diag.error(msg, loc)
-        self.ok = False
-
-    def checkPackage(self, pkg):
-        self.ok = True
-        visitor = Visitor()
-        visitor.visit(pkg, f_post=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/cortexm3.py	Fri Nov 15 13:52:32 2013 +0100
+++ b/python/cortexm3.py	Thu Nov 21 11:57:27 2013 +0100
@@ -6,6 +6,10 @@
 from ppci import CompilerError
 import ir
 
+"""
+    ARM target description.
+"""
+
 # TODO: encode this in DSL (domain specific language)
 # TBD: is this required?
 
--- a/python/grind.py	Fri Nov 15 13:52:32 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,12 +0,0 @@
-
-import cProfile
-import unittest
-import pstats
-
-if __name__ == '__main__':
-    suite = unittest.TestLoader().discover('.')
-    def runtests():
-        unittest.TextTestRunner().run(suite)
-    #s = cProfile.run('runtests()',sort='cumtime')
-    s = cProfile.run('runtests()',sort='tottime')
-
--- a/python/hexedit.py	Fri Nov 15 13:52:32 2013 +0100
+++ b/python/hexedit.py	Thu Nov 21 11:57:27 2013 +0100
@@ -1,6 +1,7 @@
 #!/usr/bin/python
 
 import sys
+import os
 from PyQt4.QtCore import *
 from PyQt4.QtGui import *
 from PyQt4 import uic
@@ -167,7 +168,8 @@
 class HexEditor(QMainWindow):
    def __init__(self):
       super().__init__()
-      uic.loadUi('hexeditor.ui', baseinstance=self)
+      basedir = os.path.dirname(__file__)
+      uic.loadUi(os.path.join(basedir, 'hexeditor.ui'), baseinstance=self)
       self.he = HexEdit()
       self.setCentralWidget(self.he)
       self.actionOpen.triggered.connect(self.doOpen)
--- a/python/ide.py	Fri Nov 15 13:52:32 2013 +0100
+++ b/python/ide.py	Thu Nov 21 11:57:27 2013 +0100
@@ -3,6 +3,7 @@
 import sys
 import os
 import logging
+import traceback
 
 from PyQt4.QtCore import *
 from PyQt4.QtGui import *
@@ -12,11 +13,11 @@
 from astviewer import AstViewer
 from codeedit import CodeEdit
 from logview import LogView as BuildOutput
+from disasm import Disassembly
 stutil = __import__('st-util')
 import c3
 import zcc
 import outstream
-import traceback
 
 
 def handle_exception(tp, v, tb):
@@ -65,51 +66,6 @@
         self.sigErrorSelected.emit(err)
 
 
-class DisAsmModel(QAbstractTableModel):
-    def __init__(self):
-        super().__init__()
-        self.outs = None
-        self.instructions = []
-        self.headers = ['Address', 'Bytes', 'Instruction']
-        self.txts = []
-        self.txts.append(lambda i: '0x{:08x}'.format(i.address))
-        self.txts.append(lambda i: str(i.encode()))
-        self.txts.append(lambda i: str(i))
-
-    def rowCount(self, parent):
-        return len(self.instructions)
-        
-    def columnCount(self, parent):
-        return len(self.headers)
-
-    def data(self, index, role):
-        if not index.isValid():
-            return
-        row, col = index.row(), index.column()
-        if role == Qt.DisplayRole:
-            i = self.instructions[row]
-            return self.txts[col](i)
-
-    def headerData(self, section, orientation, role):
-        if orientation == Qt.Horizontal and role == Qt.DisplayRole:
-            return self.headers[section]
-            
-    def setInstructions(self, ins):
-        self.instructions = ins
-        self.modelReset.emit()
-    
-
-class Disassembly(QTableView):
-    def __init__(self):
-        super().__init__()
-        self.dm = DisAsmModel()
-        self.setModel(self.dm)
-
-    def showPos(self, p):
-        for i in self.dm.instructions:
-            if i.address == p:
-                row = self.dm.instructions.index(i)
-                self.selectRow(row)
 
 class AboutDialog(QDialog):
     def __init__(self, parent=None):
@@ -350,7 +306,7 @@
         wd = os.path.dirname(fn)
         self.diag.clear()
         outs = outstream.TextOutputStream()
-        if not zcc.zcc(ce.Source, outs, self.diag, do_optimize=True, pack_dir=wd):
+        if not zcc.zcc(ce.Source, outs, self.diag, do_optimize=True):
             # Set errors:
             self.builderrors.setErrorList(self.diag.diags)
             ce.setErrors(self.diag.diags)
--- a/python/iso9660.py	Fri Nov 15 13:52:32 2013 +0100
+++ b/python/iso9660.py	Thu Nov 21 11:57:27 2013 +0100
@@ -1,49 +1,82 @@
+#!/usr/bin/env python
 
 import argparse
 
-"""
+__doc__ = """
   ISO 9660 filesystem utility.
 """
 
-def read_vol_desc(f):
-    s = f.read(2048)
-    ty = s[0]
-    Id = s[1:6]
-    assert Id == 'CD001'.encode('ascii')
-    ver = s[6]
-    assert ver == 1
-    data = s[7:]
-    assert len(data) == 2041
-    return ty, Id, s
+
+class VolumeDescriptor:
+    @classmethod
+    def FromData(cls, d):
+        ty = d[0]
+        Id = d[1:6]
+        assert Id == 'CD001'.encode('ascii')
+        ver = d[6]
+        assert ver == 1
+        cls = vol_desc_types[ty]
+        return cls(d)
+
 
-def parse_boot_record(sec):
-    boot_sys_id = sec[7:39]
-    boot_id = sec[39:71]
-    print(boot_sys_id)
-    print(boot_id)
+vol_desc_types = {}
+def vol_type(t):
+    def reg_func(cls):
+        vol_desc_types[t] = cls
+        return cls
+    return reg_func
+
+
+@vol_type(0)
+class BootRecordVolumeDescriptor(VolumeDescriptor):
+    def __init__(self, d):
+        boot_sys_id = d[7:39]
+        boot_id = d[39:71]
+        print(boot_sys_id)
+        print(boot_id)
+
 
-def parse_primary_volume(sec):
-    sys_id = sec[8:40]
-    vol_id = sec[40:72]
-    print(sys_id)
-    print(vol_id)
+@vol_type(1)
+class PrimaryVolumeDescriptor(VolumeDescriptor):
+    def __init__(self, d):
+        sys_id = d[8:40]
+        vol_id = d[40:72]
+        print(sys_id)
+        print(vol_id)
+
+
+@vol_type(255)
+class VolumeDescriptorTerminator(VolumeDescriptor):
+    def __init__(self, d):
+        pass
+
 
-def read_iso(f):
-    # System area
-    system = f.read(16 * 2048)
-    while True:
-        ty, Id, dat = read_vol_desc(f)
-        print(ty, Id)
-        if ty == 255:
-            break
-        elif ty == 0:
-            parse_boot_record(dat)
-        elif ty == 1:
-            parse_primary_volume(dat)
+class ISOfs:
+    def __init__(self):
+        self.vol_descriptors = []
+
+    def read(self, f):
+        # System area:
+        self.system_area = f.read(16 * 2048)
+        while True:
+            d = f.read(2048)
+            desc = VolumeDescriptor.FromData(d)
+            self.vol_descriptors.append(desc)
+            if type(desc) is VolumeDescriptorTerminator:
+                break
+
+    def dump(self):
+        for vd in self.vol_descriptors:
+            print(vd)
 
 
 if __name__ == '__main__':
-    with open('mikeos.iso', 'rb') as f:
-        read_iso(f)
+    parser = argparse.ArgumentParser(description=__doc__)
+    parser.add_argument('filename')
+    args = parser.parse_args()
+    fs = ISOfs()
+    with open(args.filename, 'rb') as f:
+        fs.read(f)
+    fs.dump()
 
 
--- a/python/old/assembler.py	Fri Nov 15 13:52:32 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,354 +0,0 @@
-"""
- Assembler code generation functions
-"""
-
-from .errors import Error
-
-modrm = {'rax': 0, 'rbx': 1}
-
-# Table 3.1 of the intel manual:
-# use REX.W on the table below:
-regs64 = {'rax': 0,'rcx':1,'rdx':2,'rbx':3,'rsp':4,'rbp':5,'rsi':6,'rdi':7,'r8':0,'r9':1,'r10':2,'r11':3,'r12':4,'r13':5,'r14':6,'r15':7}
-regs32 = {'eax': 0, 'ecx':1, 'edx':2, 'ebx': 3, 'esp': 4, 'ebp': 5, 'esi':6, 'edi':7}
-regs8 = {'al':0,'cl':1,'dl':2,'bl':3,'ah':4,'ch':5,'dh':6,'bh':7}
-
-# Calculation of the rexb bit:
-rexbit = {'rax': 0, 'rcx':0, 'rdx':0, 'rbx': 0, 'rsp': 0, 'rbp': 0, 'rsi':0, 'rdi':0,'r8':1,'r9':1,'r10':1,'r11':1,'r12':1,'r13':1,'r14':1,'r15':1}
-
-# Helper functions:
-def imm64(x):
-   """ represent 64 bits integer in little endian 8 bytes"""
-   if x < 0:
-      x = x + (1 << 64)
-   x = x & 0xFFFFFFFFFFFFFFFF
-   return [ (x >> (p*8)) & 0xFF for p in range(8) ]
-
-def imm32(x):
-   """ represent 32 bits integer in little endian 4 bytes"""
-   if x < 0:
-      x = x + (1 << 32)
-   x = x & 0xFFFFFFFF
-   return [ (x >> (p*8)) & 0xFF for p in range(4) ]
-
-def imm8(x):
-   if x < 0:
-      x = x + (1 << 8)
-   x = x & 0xFF
-   return [ x ]
-
-def modrm(mod=0, rm=0, reg=0):
-   """ Construct the modrm byte from its components """
-   assert(mod <= 3)
-   assert(rm <= 7)
-   assert(reg <= 7)
-   return (mod << 6) | (reg << 3) | rm
-
-def rex(w=0, r=0, x=0, b=0):
-   """ Create a REX prefix byte """
-   assert(w <= 1)
-   assert(r <= 1)
-   assert(x <= 1)
-   assert(b <= 1)
-   return 0x40 | (w<<3) | (r<<2) | (x<<1) | b
-
-def sib(ss=0, index=0, base=0):
-   assert(ss <= 3)
-   assert(index <= 7)
-   assert(base <= 7)
-   return (ss << 6) | (index << 3) | base
-
-tttn = {'L':0xc,'G':0xf,'NE':0x5,'GE':0xd,'LE':0xe, 'E':0x4}
-
-# Actual instructions:
-def nearjump(distance, condition=None):
-   """ jmp imm32 """
-   lim = (1<<30)
-   if abs(distance) > lim:
-      Error('near jump cannot jump over more than {0} bytes'.format(lim))
-   if condition:
-      if distance < 0:
-         distance -= 6 # Skip own instruction
-      opcode = 0x80 | tttn[condition] # Jcc imm32
-      return [0x0F, opcode] + imm32(distance)
-   else:
-      if distance < 0:
-         distance -= 5 # Skip own instruction
-      return [ 0xE9 ] + imm32(distance)
-
-def shortjump(distance, condition=None):
-   """ jmp imm8 """
-   lim = 118
-   if abs(distance) > lim:
-      Error('short jump cannot jump over more than {0} bytes'.format(lim))
-   if distance < 0:
-      distance -= 2 # Skip own instruction
-   if condition:
-      opcode = 0x70 | tttn[condition] # Jcc rel8
-   else:
-      opcode = 0xeb # jmp rel8
-   return [opcode] + imm8(distance)
-
-# Helper that determines jump type:
-def reljump(distance):
-   if abs(distance) < 110:
-      return shortjump(distance)
-   else:
-      return nearjump(distance)
-
-def push(reg):
-   if reg in regs64:
-      if rexbit[reg] == 1:
-         return [0x41, 0x50 + regs64[reg]]
-      else:
-         return [0x50 + regs64[reg]]
-   else:
-      Error('push for {0} not implemented'.format(reg))
-
-def pop(reg):
-   if reg in regs64:
-      if rexbit[reg] == 1:
-         rexprefix = rex(b=1)
-         opcode = 0x58 + regs64[reg]
-         return [rexprefix, opcode]
-      else:
-         opcode = 0x58 + regs64[reg]
-         return [ opcode ]
-   else:
-      Error('pop for {0} not implemented'.format(reg))
-
-def INT(number):
-   opcode = 0xcd
-   return [opcode] + imm8(number)
-
-def syscall():
-   return [0x0F, 0x05]
-
-def call(distance):
-   if type(distance) is int:
-      return [0xe8]+imm32(distance)
-   elif type(distance) is str and distance in regs64:
-      reg = distance
-      opcode = 0xFF # 0xFF /2 == call r/m64
-      mod_rm = modrm(mod=3, reg=2, rm=regs64[reg])
-      if rexbit[reg] == 1:
-         rexprefix = rex(b=rexbit[reg])
-         return [rexprefix, opcode, mod_rm]
-      else:
-         return [opcode, mod_rm]
-   else:
-      Error('Cannot call to {0}'.format(distance))
-
-def ret():
-   return [ 0xc3 ]
-
-def increg64(reg):
-   assert(reg in regs64)
-   rexprefix = rex(w=1, b=rexbit[reg])
-   opcode = 0xff
-   mod_rm = modrm(mod=3, rm=regs64[reg])
-   return [rexprefix, opcode, mod_rm]
-
-def prepost8(r8, rm8):
-   assert(r8 in regs8)
-   pre = []
-   if type(rm8) is list:
-      # TODO: merge mem access with prepost for 64 bits
-      if len(rm8) == 1:
-         base, = rm8
-         if type(base) is str and base in regs64:
-            assert(not base in ['rbp', 'rsp', 'r12', 'r13'])
-            mod_rm = modrm(mod=0, rm=regs64[base], reg=regs8[r8])
-            if rexbit[base] == 1:
-               pre.append(rex(b=1))
-            post = [mod_rm]
-         else:
-            Error('One arg of type {0} not implemented'.format(base))
-      elif len(rm8) == 2:
-         base, offset = rm8
-         assert(type(offset) is int)
-         assert(base in regs64)
-
-         if base == 'rsp' or base == 'r12':
-            Error('Cannot use rsp or r12 as base yet')
-         if rexbit[base] == 1:
-            pre.append( rex(b=1) )
-         mod_rm = modrm(mod=1, rm=regs64[base], reg=regs8[r8])
-         post = [mod_rm] + imm8(offset)
-      else:
-         Error('not supporting prepost8 with list len {0}'.format(len(rm8)))
-   else:
-      Error('Not supporting move with reg8 {0}'.format(r8))
-   return pre, post
-
-def prepost(r64, rm64):
-   assert(r64 in regs64)
-   if type(rm64) is list:
-      if len(rm64) == 3:
-            base, index, disp = rm64
-            assert(base in regs64)
-            assert(index in regs64)
-            assert(type(disp) is int)
-            # Assert that no special cases are used:
-            # TODO: swap base and index to avoid special cases
-            # TODO: exploit special cases and make better code
-            assert(index != 'rsp')
-
-            rexprefix = rex(w=1, r=rexbit[r64], x=rexbit[index], b=rexbit[base])
-            # mod=1 and rm=4 indicates a SIB byte: [--][--]+imm8
-            mod_rm = modrm(mod=1, rm=4, reg=regs64[r64])
-            si_b = sib(ss=0, index=regs64[index], base=regs64[base])
-            return [rexprefix], [mod_rm, si_b] + imm8(disp)
-      elif len(rm64) == 2:
-         base, offset = rm64
-         assert(type(offset) is int)
-         if base == 'RIP':
-            # RIP pointer relative addressing mode!
-            rexprefix = rex(w=1, r=rexbit[r64])
-            mod_rm = modrm(mod=0, rm=5, reg=regs64[r64])
-            return [rexprefix], [mod_rm] + imm32(offset)
-         else:
-            assert(base in regs64)
-
-            if base == 'rsp' or base == 'r12':
-               # extended function that uses SIB byte
-               rexprefix = rex(w=1, r=rexbit[r64], b=rexbit[base])
-               # rm=4 indicates a SIB byte follows
-               mod_rm = modrm(mod=1, rm=4, reg=regs64[r64])
-               # index=4 indicates that index is not used
-               si_b = sib(ss=0, index=4, base=regs64[base])
-               return [rexprefix], [mod_rm, si_b] + imm8(offset)
-            else:
-               rexprefix = rex(w=1, r=rexbit[r64], b=rexbit[base])
-               mod_rm = modrm(mod=1, rm=regs64[base], reg=regs64[r64])
-               return [rexprefix], [mod_rm] + imm8(offset)
-      elif len(rm64) == 1:
-         offset = rm64[0]
-         if type(offset) is int:
-            rexprefix = rex(w=1, r=rexbit[r64])
-            mod_rm = modrm(mod=0, rm=4,reg=regs64[r64])
-            si_b = sib(ss=0, index=4,base=5) # 0x25
-            return [rexprefix], [mod_rm, si_b] + imm32(offset)
-         else:
-            Error('Memory reference of type {0} not implemented'.format(offset))
-      else:
-         Error('Memory reference not implemented')
-   elif rm64 in regs64:
-      rexprefix = rex(w=1, r=rexbit[r64], b=rexbit[rm64])
-      mod_rm = modrm(3, rm=regs64[rm64], reg=regs64[r64])
-      return [rexprefix], [mod_rm]
-
-def leareg64(rega, m):
-   opcode = 0x8d # lea r64, m
-   pre, post = prepost(rega, m)
-   return pre + [opcode] + post
-
-def mov(rega, regb):
-   if type(regb) is int:
-      pre = [rex(w=1, b=rexbit[rega])]
-      opcode = 0xb8 + regs64[rega]
-      post = imm64(regb)
-   elif type(regb) is str:
-      if regb in regs64:
-         opcode = 0x89 # mov r/m64, r64
-         pre, post = prepost(regb, rega)
-      elif regb in regs8:
-         opcode = 0x88 # mov r/m8, r8
-         pre, post = prepost8(regb, rega)
-      else:
-         Error('Unknown register {0}'.format(regb))
-   elif type(rega) is str:
-      if rega in regs64:
-         opcode = 0x8b # mov r64, r/m64
-         pre, post = prepost(rega, regb)
-      else:
-         Error('Unknown register {0}'.format(rega))
-   else:
-      Error('Move of this kind {0}, {1} not implemented'.format(rega, regb))
-   return pre + [opcode] + post
-
-def xorreg64(rega, regb):
-   rexprefix = rex(w=1, r=rexbit[regb], b=rexbit[rega])
-   opcode = 0x31 # XOR r/m64, r64
-   # Alternative is 0x33 XOR r64, r/m64
-   mod_rm = modrm(3, rm=regs64[rega], reg=regs64[regb])
-   return [rexprefix, opcode, mod_rm]
-
-# integer arithmatic:
-def addreg64(rega, regb):
-   if regb in regs64:
-      pre, post = prepost(regb, rega)
-      opcode = 0x01 # ADD r/m64, r64
-      return pre + [opcode] + post
-   elif type(regb) is int:
-      if regb < 100:
-         rexprefix = rex(w=1, b=rexbit[rega])
-         opcode = 0x83 # add r/m, imm8
-         mod_rm = modrm(3, rm=regs64[rega], reg=0)
-         return [rexprefix, opcode, mod_rm]+imm8(regb)
-      elif regb < (1<<31):
-         rexprefix = rex(w=1, b=rexbit[rega])
-         opcode = 0x81 # add r/m64, imm32
-         mod_rm = modrm(3, rm=regs64[rega], reg=0)
-         return [rexprefix, opcode, mod_rm]+imm32(regb)
-      else:
-         Error('Constant value too large!')
-   else:
-      Error('unknown second operand!'.format(regb))
-
-def subreg64(rega, regb):
-   if regb in regs64:
-      pre, post = prepost(regb, rega)
-      opcode = 0x29 # SUB r/m64, r64
-      return pre + [opcode] + post
-   elif type(regb) is int:
-      if regb < 100:
-         rexprefix = rex(w=1, b=rexbit[rega])
-         opcode = 0x83 # sub r/m, imm8
-         mod_rm = modrm(3, rm=regs64[rega], reg=5)
-         return [rexprefix, opcode, mod_rm]+imm8(regb)
-      elif regb < (1<<31):
-         rexprefix = rex(w=1, b=rexbit[rega])
-         opcode = 0x81 # sub r/m64, imm32
-         mod_rm = modrm(3, rm=regs64[rega], reg=5)
-         return [rexprefix, opcode, mod_rm]+imm32(regb)
-      else:
-         Error('Constant value too large!')
-
-   else:
-      Error('unknown second operand!'.format(regb))
-
-def idivreg64(reg):
-   rexprefix = rex(w=1, b=rexbit[reg])
-   opcode = 0xf7 # IDIV r/m64
-   mod_rm = modrm(3, rm=regs64[reg], reg=7)
-   return [rexprefix, opcode, mod_rm]
-
-def imulreg64_rax(reg):
-   rexprefix = rex(w=1, b=rexbit[reg])
-   opcode = 0xf7 # IMUL r/m64
-   mod_rm = modrm(3, rm=regs64[reg], reg=5)
-   return [rexprefix, opcode, mod_rm]
-
-def imulreg64(rega, regb):
-   pre, post = prepost(rega, regb)
-   opcode = 0x0f # IMUL r64, r/m64
-   opcode2 = 0xaf
-   return pre + [opcode, opcode2] + post
-
-def cmpreg64(rega, regb):
-   if regb in regs64:
-      pre, post = prepost(regb, rega)
-      opcode = 0x39 # CMP r/m64, r64
-      return pre + [opcode] + post
-   elif type(regb) is int:
-      rexprefix = rex(w=1, b=rexbit[rega])
-      opcode = 0x83 # CMP r/m64, imm8
-      mod_rm = modrm(3, rm=regs64[rega], reg=7)
-      return [rexprefix, opcode, mod_rm] + imm8(regb)
-      
-   else:
-      Error('not implemented cmp64')
-
-# Mapping that maps string names to the right functions:
-opcodes = {'mov':(mov,2), 'lea':(leareg64,2), 'int':(INT,1), 'syscall':(syscall,0)}
-
--- a/python/old/modules.py	Fri Nov 15 13:52:32 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,193 +0,0 @@
-import struct
-from .errors import Error
-from .nodes import *
-from .builtin import integer, real, char, boolean, void
-import os.path
-
-"""
- File format for compiled modules.
- * [11] magic identifier
- * [STR] mod name
- * [STR] signature, a md5 signature of the module.
- * [I32] size of code
- * code image
- * [I32] entrypoint for initcode
- * imported modules
- ** [I32] num of imported modules
- *** [STR] name of module
- *** signature of the module
- *** [I32] offset in the process image where the interface symbols must be placed
- * public interface
- ** [I32] num of interface elements
- *** [STR] proc name
- *** [I32] offset in code image 
- *** [type] return type
- *** [I32] number of parameters
- **** parameter
- ***** parameter kind
- ***** parameter name
- ***** parameter type
-"""
-
-MAGIC = b'LCFOSMODC'
-
-loadedModules = []
-
-def loadModule(modname):
-   """ returns a Module object specified by a name """
-   # Check if the module was already loaded:
-   for mod in loadedModules:
-      if mod.name == modname:
-         return mod
-
-   # Try to load the module from file:
-   srcfilename = modname + '.mod'
-   binfilename = modname + '.bin'
-   sourceExists = os.path.exists(srcfilename)
-   if os.path.exists(binfilename):
-      if sourceExists:
-         compileModule()
-      else:
-         return loadModuleFromFile(binfilename)
-   else:
-      Error("Cannot load module '{0}'!".format(modname))
-
-def loadModuleFromFile(filename):
-   f = open(filename, 'rb')
-   magic = f.read(len(MAGIC))
-   assert(magic == MAGIC)
-
-   # Helper functions:
-   def readI32():
-      int32, = struct.unpack('<I', f.read(4))
-      return int32
-   def readSTR():
-      length = readI32()
-      b = f.read(length)
-      return b.decode(encoding='ascii')
-   def readType():
-      code, = f.read(1)
-      basetypes = {0x11:integer, 0x12:real, 0x13:char,0x14:boolean, 0x15:void}
-      if code in list(basetypes.keys()):
-         return basetypes[code]
-      elif code == 0x20:
-         dimension, elementType = readI32(), readType()
-         return ArrayType(dimension, elementType)
-      elif code == 0x21:
-         returntype = readType()
-         numparams = readI32()
-         parameters = []
-         kinds = {0x1:'value', 0x2:'var', 0x3:'const'}
-         for i in range(numparams):
-            byt, = f.read(1)
-            kind = kinds[byt]
-            name, typ = readSTR(), readType()
-            parameters.append(Parameter(kind, name, typ))
-         return ProcedureType(parameters, returntype)
-      else:
-         Error('Reading of this typ not supported')
-
-   # Begin of actual loading
-   modname = readSTR()
-   modsignature = readSTR()
-   codesize = readI32()
-   image = f.read(codesize)
-   initcodeentry = readI32()
-   # Check which modules this module loads:
-   numimports = readI32()
-   imports = []
-   for i in range(numimports):
-      modname = readSTR()
-      signature = readSTR()
-      symname = readSTR()
-      offset = readI32()
-      impsym = ImportedSymbol(modname, symname)
-      impsym.signature = signature
-      impsym.offset = offset
-      imports.append(impsym)
-   # Modules exported interface:
-   numexports = readI32()
-   exports = []
-   for i in range(numexports):
-      name = readSTR()
-      imageoffset = readI32() # Offset in image where symbol is located
-      typ = readType()
-      export = ExportedSymbol(name, typ)
-      export.imageoffset = imageoffset
-      exports.append(export)
-   f.close()
-
-   # Construct imported module object:
-   module = Module(modname)
-   module.signature = modsignature
-   module.exports = exports # Symbols provided to other modules
-   module.imports = imports # Symbols of others used by this module.
-   module.initcodeentry = initcodeentry
-   module.image = image # The binary blob
-   global loadedModules
-   loadedModules.append(module)
-   return module
-
-def storeModule(mod, filename):
-   """ Class to store a module in a file """
-   f = open(filename, 'wb')
-
-   def writeI32(int32):
-      f.write( struct.pack('<I', int32) )
-   def writeSTR(s):
-      writeI32(len(s))
-      f.write(bytes(s, encoding='ascii'))
-   def writeType(typ):
-      if type(typ) is BaseType:
-         basetypecode = {'integer': 0x11, 'real': 0x12, 'char': 0x13, 'boolean':0x14, 'void':0x15}
-         code = basetypecode[typ.name]
-         f.write( bytes([code]))
-      elif type(typ) is ArrayType:
-         f.write(bytes([0x20]))
-         writeI32(typ.dimension)
-         writeType(typ.elementType)
-      elif type(typ) is ProcedureType:
-         f.write(bytes([0x21]))
-         writeType(typ.returntype)
-         writeI32(len(typ.parameters))
-         for parameter in typ.parameters:
-            kinds = {'value': 0x1, 'var': 0x2, 'const': 0x3}
-            kind = kinds[parameter.kind]
-            f.write(bytes([kind]))
-            writeSTR(parameter.name)
-            writeType(parameter.typ)
-      else:
-         Error('Type storage not implemented {0}'.format(typ))
-
-   # Begin of actual storage function
-   f.write(MAGIC)
-   writeSTR(mod.name)
-   writeSTR(mod.signature)
-   writeI32(len(mod.image))
-   f.write(bytes(mod.image))
-   writeI32(mod.initcodeentry)
-   # modules imported symbols:
-   writeI32(len(mod.imports))
-   for imp in mod.imports:
-      writeSTR(imp.modname)
-      writeSTR(imp.signature)
-      writeSTR(imp.name)
-      writeI32(imp.offset)
-   # modules provided interface
-   writeI32(len(mod.exports))
-   # Store exported symbols:
-   for sym in mod.exports:
-      writeSTR(sym.name) # proc name
-      writeI32(sym.imageoffset) # proc entry point
-      writeType(sym.typ) # Procedure type
-   f.close()
-
-   storeModuleInCache(mod)
-
-def storeModuleInCache(newmod):
-   global loadedModules
-   for mod in loadedModules:
-      if newmod.name == mod.name:
-         return
-   loadedModules.append(newmod)
-
--- a/python/ppci/common.py	Fri Nov 15 13:52:32 2013 +0100
+++ b/python/ppci/common.py	Thu Nov 21 11:57:27 2013 +0100
@@ -1,26 +1,29 @@
 from collections import namedtuple
 
+
 # Token is used in the lexical analyzer:
 class Token:
     def __init__(self, typ, val, loc=None):
         self.typ = typ
         self.val = val
         if loc is None:
-            loc = SourceLocation(0, 0, 0)
+            loc = SourceLocation('', 0, 0, 0)
         assert type(loc) is SourceLocation
         self.loc = loc
     def __repr__(self):
         return 'Token({0}, {1})'.format(self.typ, self.val)
 
+
 class SourceLocation:
-    def __init__(self, row, col, ln):
+    def __init__(self, filename, row, col, ln):
+        self.filename = filename
         self.row = row
         self.col = col
         self.length = ln
-        self.filename = ''
 
     def __repr__(self):
         return '{}, {}'.format(self.row, self.col)
 
+
 SourceRange = namedtuple('SourceRange', ['p1', 'p2'])
 
--- a/python/thex.py	Fri Nov 15 13:52:32 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-import unittest
-import hexedit
-from PyQt4.QtGui import QApplication
-from PyQt4.QtTest import QTest
-from PyQt4.QtCore import Qt
-import sys
-
-class HexTest(unittest.TestCase):
-    def setUp(self):
-        self.app = QApplication(sys.argv)
-        self.ui = hexedit.HexEditor()
-        self.bv = self.ui.he.bv
-        # Provide some random data:
-        self.bv.Data = bytearray(range(10)) * 8 + b'x'
-    def tearDown(self):
-        self.app.processEvents()
-        self.app.quit()
-    def testOpenButton(self):
-        QTest.mouseClick(self.bv, Qt.LeftButton)
-        self.assertEqual(self.bv.CursorPosition, 161)
-        QTest.keyClick(self.bv, Qt.Key_Left)
-        self.assertEqual(self.bv.CursorPosition, 160)
-        QTest.keyClick(self.bv, Qt.Key_Up)
-        self.assertEqual(self.bv.CursorPosition, 128)
-
-if __name__ == '__main__':
-    unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/x86_2.py	Thu Nov 21 11:57:27 2013 +0100
@@ -0,0 +1,356 @@
+"""
+    X86 target descriptions and encodings.
+
+"""
+
+from target import Register, Instruction, Target, Imm8, Label, Imm3, LabelRef
+
+
+modrm = {'rax': 0, 'rbx': 1}
+
+# Table 3.1 of the intel manual:
+# use REX.W on the table below:
+regs64 = {'rax': 0,'rcx':1,'rdx':2,'rbx':3,'rsp':4,'rbp':5,'rsi':6,'rdi':7,'r8':0,'r9':1,'r10':2,'r11':3,'r12':4,'r13':5,'r14':6,'r15':7}
+regs32 = {'eax': 0, 'ecx':1, 'edx':2, 'ebx': 3, 'esp': 4, 'ebp': 5, 'esi':6, 'edi':7}
+regs8 = {'al':0,'cl':1,'dl':2,'bl':3,'ah':4,'ch':5,'dh':6,'bh':7}
+
+# Calculation of the rexb bit:
+rexbit = {'rax': 0, 'rcx':0, 'rdx':0, 'rbx': 0, 'rsp': 0, 'rbp': 0, 'rsi':0, 'rdi':0,'r8':1,'r9':1,'r10':1,'r11':1,'r12':1,'r13':1,'r14':1,'r15':1}
+
+# Helper functions:
+def imm64(x):
+   """ represent 64 bits integer in little endian 8 bytes"""
+   if x < 0:
+      x = x + (1 << 64)
+   x = x & 0xFFFFFFFFFFFFFFFF
+   return [ (x >> (p*8)) & 0xFF for p in range(8) ]
+
+def imm32(x):
+   """ represent 32 bits integer in little endian 4 bytes"""
+   if x < 0:
+      x = x + (1 << 32)
+   x = x & 0xFFFFFFFF
+   return [ (x >> (p*8)) & 0xFF for p in range(4) ]
+
+def imm8(x):
+   if x < 0:
+      x = x + (1 << 8)
+   x = x & 0xFF
+   return [ x ]
+
+def modrm(mod=0, rm=0, reg=0):
+   """ Construct the modrm byte from its components """
+   assert(mod <= 3)
+   assert(rm <= 7)
+   assert(reg <= 7)
+   return (mod << 6) | (reg << 3) | rm
+
+def rex(w=0, r=0, x=0, b=0):
+   """ Create a REX prefix byte """
+   assert(w <= 1)
+   assert(r <= 1)
+   assert(x <= 1)
+   assert(b <= 1)
+   return 0x40 | (w<<3) | (r<<2) | (x<<1) | b
+
+def sib(ss=0, index=0, base=0):
+   assert(ss <= 3)
+   assert(index <= 7)
+   assert(base <= 7)
+   return (ss << 6) | (index << 3) | base
+
+tttn = {'L':0xc,'G':0xf,'NE':0x5,'GE':0xd,'LE':0xe, 'E':0x4}
+
+# Actual instructions:
+def nearjump(distance, condition=None):
+   """ jmp imm32 """
+   lim = (1<<30)
+   if abs(distance) > lim:
+      Error('near jump cannot jump over more than {0} bytes'.format(lim))
+   if condition:
+      if distance < 0:
+         distance -= 6 # Skip own instruction
+      opcode = 0x80 | tttn[condition] # Jcc imm32
+      return [0x0F, opcode] + imm32(distance)
+   else:
+      if distance < 0:
+         distance -= 5 # Skip own instruction
+      return [ 0xE9 ] + imm32(distance)
+
+def shortjump(distance, condition=None):
+   """ jmp imm8 """
+   lim = 118
+   if abs(distance) > lim:
+      Error('short jump cannot jump over more than {0} bytes'.format(lim))
+   if distance < 0:
+      distance -= 2 # Skip own instruction
+   if condition:
+      opcode = 0x70 | tttn[condition] # Jcc rel8
+   else:
+      opcode = 0xeb # jmp rel8
+   return [opcode] + imm8(distance)
+
+# Helper that determines jump type:
+def reljump(distance):
+   if abs(distance) < 110:
+      return shortjump(distance)
+   else:
+      return nearjump(distance)
+
+def push(reg):
+   if reg in regs64:
+      if rexbit[reg] == 1:
+         return [0x41, 0x50 + regs64[reg]]
+      else:
+         return [0x50 + regs64[reg]]
+   else:
+      Error('push for {0} not implemented'.format(reg))
+
+def pop(reg):
+   if reg in regs64:
+      if rexbit[reg] == 1:
+         rexprefix = rex(b=1)
+         opcode = 0x58 + regs64[reg]
+         return [rexprefix, opcode]
+      else:
+         opcode = 0x58 + regs64[reg]
+         return [ opcode ]
+   else:
+      Error('pop for {0} not implemented'.format(reg))
+
+def INT(number):
+   opcode = 0xcd
+   return [opcode] + imm8(number)
+
+def syscall():
+   return [0x0F, 0x05]
+
+def call(distance):
+   if type(distance) is int:
+      return [0xe8]+imm32(distance)
+   elif type(distance) is str and distance in regs64:
+      reg = distance
+      opcode = 0xFF # 0xFF /2 == call r/m64
+      mod_rm = modrm(mod=3, reg=2, rm=regs64[reg])
+      if rexbit[reg] == 1:
+         rexprefix = rex(b=rexbit[reg])
+         return [rexprefix, opcode, mod_rm]
+      else:
+         return [opcode, mod_rm]
+   else:
+      Error('Cannot call to {0}'.format(distance))
+
+def ret():
+   return [ 0xc3 ]
+
+def increg64(reg):
+   assert(reg in regs64)
+   rexprefix = rex(w=1, b=rexbit[reg])
+   opcode = 0xff
+   mod_rm = modrm(mod=3, rm=regs64[reg])
+   return [rexprefix, opcode, mod_rm]
+
+def prepost8(r8, rm8):
+   assert(r8 in regs8)
+   pre = []
+   if type(rm8) is list:
+      # TODO: merge mem access with prepost for 64 bits
+      if len(rm8) == 1:
+         base, = rm8
+         if type(base) is str and base in regs64:
+            assert(not base in ['rbp', 'rsp', 'r12', 'r13'])
+            mod_rm = modrm(mod=0, rm=regs64[base], reg=regs8[r8])
+            if rexbit[base] == 1:
+               pre.append(rex(b=1))
+            post = [mod_rm]
+         else:
+            Error('One arg of type {0} not implemented'.format(base))
+      elif len(rm8) == 2:
+         base, offset = rm8
+         assert(type(offset) is int)
+         assert(base in regs64)
+
+         if base == 'rsp' or base == 'r12':
+            Error('Cannot use rsp or r12 as base yet')
+         if rexbit[base] == 1:
+            pre.append( rex(b=1) )
+         mod_rm = modrm(mod=1, rm=regs64[base], reg=regs8[r8])
+         post = [mod_rm] + imm8(offset)
+      else:
+         Error('not supporting prepost8 with list len {0}'.format(len(rm8)))
+   else:
+      Error('Not supporting move with reg8 {0}'.format(r8))
+   return pre, post
+
+def prepost(r64, rm64):
+   assert(r64 in regs64)
+   if type(rm64) is list:
+      if len(rm64) == 3:
+            base, index, disp = rm64
+            assert(base in regs64)
+            assert(index in regs64)
+            assert(type(disp) is int)
+            # Assert that no special cases are used:
+            # TODO: swap base and index to avoid special cases
+            # TODO: exploit special cases and make better code
+            assert(index != 'rsp')
+
+            rexprefix = rex(w=1, r=rexbit[r64], x=rexbit[index], b=rexbit[base])
+            # mod=1 and rm=4 indicates a SIB byte: [--][--]+imm8
+            mod_rm = modrm(mod=1, rm=4, reg=regs64[r64])
+            si_b = sib(ss=0, index=regs64[index], base=regs64[base])
+            return [rexprefix], [mod_rm, si_b] + imm8(disp)
+      elif len(rm64) == 2:
+         base, offset = rm64
+         assert(type(offset) is int)
+         if base == 'RIP':
+            # RIP pointer relative addressing mode!
+            rexprefix = rex(w=1, r=rexbit[r64])
+            mod_rm = modrm(mod=0, rm=5, reg=regs64[r64])
+            return [rexprefix], [mod_rm] + imm32(offset)
+         else:
+            assert(base in regs64)
+
+            if base == 'rsp' or base == 'r12':
+               # extended function that uses SIB byte
+               rexprefix = rex(w=1, r=rexbit[r64], b=rexbit[base])
+               # rm=4 indicates a SIB byte follows
+               mod_rm = modrm(mod=1, rm=4, reg=regs64[r64])
+               # index=4 indicates that index is not used
+               si_b = sib(ss=0, index=4, base=regs64[base])
+               return [rexprefix], [mod_rm, si_b] + imm8(offset)
+            else:
+               rexprefix = rex(w=1, r=rexbit[r64], b=rexbit[base])
+               mod_rm = modrm(mod=1, rm=regs64[base], reg=regs64[r64])
+               return [rexprefix], [mod_rm] + imm8(offset)
+      elif len(rm64) == 1:
+         offset = rm64[0]
+         if type(offset) is int:
+            rexprefix = rex(w=1, r=rexbit[r64])
+            mod_rm = modrm(mod=0, rm=4,reg=regs64[r64])
+            si_b = sib(ss=0, index=4,base=5) # 0x25
+            return [rexprefix], [mod_rm, si_b] + imm32(offset)
+         else:
+            Error('Memory reference of type {0} not implemented'.format(offset))
+      else:
+         Error('Memory reference not implemented')
+   elif rm64 in regs64:
+      rexprefix = rex(w=1, r=rexbit[r64], b=rexbit[rm64])
+      mod_rm = modrm(3, rm=regs64[rm64], reg=regs64[r64])
+      return [rexprefix], [mod_rm]
+
+def leareg64(rega, m):
+   opcode = 0x8d # lea r64, m
+   pre, post = prepost(rega, m)
+   return pre + [opcode] + post
+
+def mov(rega, regb):
+   if type(regb) is int:
+      pre = [rex(w=1, b=rexbit[rega])]
+      opcode = 0xb8 + regs64[rega]
+      post = imm64(regb)
+   elif type(regb) is str:
+      if regb in regs64:
+         opcode = 0x89 # mov r/m64, r64
+         pre, post = prepost(regb, rega)
+      elif regb in regs8:
+         opcode = 0x88 # mov r/m8, r8
+         pre, post = prepost8(regb, rega)
+      else:
+         Error('Unknown register {0}'.format(regb))
+   elif type(rega) is str:
+      if rega in regs64:
+         opcode = 0x8b # mov r64, r/m64
+         pre, post = prepost(rega, regb)
+      else:
+         Error('Unknown register {0}'.format(rega))
+   else:
+      Error('Move of this kind {0}, {1} not implemented'.format(rega, regb))
+   return pre + [opcode] + post
+
+def xorreg64(rega, regb):
+   rexprefix = rex(w=1, r=rexbit[regb], b=rexbit[rega])
+   opcode = 0x31 # XOR r/m64, r64
+   # Alternative is 0x33 XOR r64, r/m64
+   mod_rm = modrm(3, rm=regs64[rega], reg=regs64[regb])
+   return [rexprefix, opcode, mod_rm]
+
+# integer arithmatic:
+def addreg64(rega, regb):
+   if regb in regs64:
+      pre, post = prepost(regb, rega)
+      opcode = 0x01 # ADD r/m64, r64
+      return pre + [opcode] + post
+   elif type(regb) is int:
+      if regb < 100:
+         rexprefix = rex(w=1, b=rexbit[rega])
+         opcode = 0x83 # add r/m, imm8
+         mod_rm = modrm(3, rm=regs64[rega], reg=0)
+         return [rexprefix, opcode, mod_rm]+imm8(regb)
+      elif regb < (1<<31):
+         rexprefix = rex(w=1, b=rexbit[rega])
+         opcode = 0x81 # add r/m64, imm32
+         mod_rm = modrm(3, rm=regs64[rega], reg=0)
+         return [rexprefix, opcode, mod_rm]+imm32(regb)
+      else:
+         Error('Constant value too large!')
+   else:
+      Error('unknown second operand!'.format(regb))
+
+def subreg64(rega, regb):
+   if regb in regs64:
+      pre, post = prepost(regb, rega)
+      opcode = 0x29 # SUB r/m64, r64
+      return pre + [opcode] + post
+   elif type(regb) is int:
+      if regb < 100:
+         rexprefix = rex(w=1, b=rexbit[rega])
+         opcode = 0x83 # sub r/m, imm8
+         mod_rm = modrm(3, rm=regs64[rega], reg=5)
+         return [rexprefix, opcode, mod_rm]+imm8(regb)
+      elif regb < (1<<31):
+         rexprefix = rex(w=1, b=rexbit[rega])
+         opcode = 0x81 # sub r/m64, imm32
+         mod_rm = modrm(3, rm=regs64[rega], reg=5)
+         return [rexprefix, opcode, mod_rm]+imm32(regb)
+      else:
+         Error('Constant value too large!')
+
+   else:
+      Error('unknown second operand!'.format(regb))
+
+def idivreg64(reg):
+   rexprefix = rex(w=1, b=rexbit[reg])
+   opcode = 0xf7 # IDIV r/m64
+   mod_rm = modrm(3, rm=regs64[reg], reg=7)
+   return [rexprefix, opcode, mod_rm]
+
+def imulreg64_rax(reg):
+   rexprefix = rex(w=1, b=rexbit[reg])
+   opcode = 0xf7 # IMUL r/m64
+   mod_rm = modrm(3, rm=regs64[reg], reg=5)
+   return [rexprefix, opcode, mod_rm]
+
+def imulreg64(rega, regb):
+   pre, post = prepost(rega, regb)
+   opcode = 0x0f # IMUL r64, r/m64
+   opcode2 = 0xaf
+   return pre + [opcode, opcode2] + post
+
+def cmpreg64(rega, regb):
+   if regb in regs64:
+      pre, post = prepost(regb, rega)
+      opcode = 0x39 # CMP r/m64, r64
+      return pre + [opcode] + post
+   elif type(regb) is int:
+      rexprefix = rex(w=1, b=rexbit[rega])
+      opcode = 0x83 # CMP r/m64, imm8
+      mod_rm = modrm(3, rm=regs64[rega], reg=7)
+      return [rexprefix, opcode, mod_rm] + imm8(regb)
+      
+   else:
+      Error('not implemented cmp64')
+
+# Mapping that maps string names to the right functions:
+opcodes = {'mov':(mov,2), 'lea':(leareg64,2), 'int':(INT,1), 'syscall':(syscall,0)}
+
--- a/python/zcc.py	Fri Nov 15 13:52:32 2013 +0100
+++ b/python/zcc.py	Thu Nov 21 11:57:27 2013 +0100
@@ -1,12 +1,16 @@
 #!/usr/bin/python
 
-import sys, argparse
-import c3, ppci, codegen
+import sys
+import argparse
+import logging
+
+import c3
+import ppci
+import codegen
 import codegenarm
 from optimize import optimize
 import outstream
 import hexfile
-import logging
 
 logformat='%(asctime)s|%(levelname)s|%(name)s|%(message)s'
 
@@ -18,45 +22,54 @@
 
 # Parse arguments:
 parser = argparse.ArgumentParser(description='lcfos Compiler')
+# Input:
 parser.add_argument('source', type=argparse.FileType('r'), \
-  help='the source file to build')
+  help='the source file to build', nargs="+")
+parser.add_argument('-i', '--import', type=argparse.FileType('r'), \
+  help='Possible import module', action='append')
+
 parser.add_argument('--dumpir', action='store_true', help="Dump IR-code")
 parser.add_argument('--dumpasm', action='store_true', help="Dump ASM-code")
 parser.add_argument('--optimize', action='store_true', help="Optimize")
-parser.add_argument('--package_dir', help="Look in this directory for packages")
+parser.add_argument('--target', help="Backend selection")
 parser.add_argument('-o', '--output', help='Output file', metavar='filename')
 parser.add_argument('--hexfile', help='Output hexfile', type=argparse.FileType('w'))
 parser.add_argument('--log', help='Log level (INFO,DEBUG)', type=logLevel)
 
-def zcc(src, outs, diag, dumpir=False, do_optimize=False, pack_dir=None):
+def zcc(srcs, outs, diag, dumpir=False, do_optimize=False):
+    """
+        Compile sources into output stream.
+        Sources is an iterable of open files.
+    """
     logging.info('Zcc started')
     # Front end:
     c3b = c3.Builder(diag)
-    ircode = c3b.build(src, pack_dir=pack_dir)
-    if not ircode:
-        return
+    imps = []
+    for ircode in c3b.build(srcs, imps):
+        print(ircode)
+        if not ircode:
+            return
 
-    # Optimization passes:
-    if do_optimize:
-        optimize(ircode)
+        # Optimization passes:
+        if do_optimize:
+            optimize(ircode)
 
-    if dumpir:
-        ircode.dump()
+        if dumpir:
+            ircode.dump()
 
-    # Code generation:
-    cg = codegenarm.ArmCodeGenerator(outs)
-    obj = cg.generate(ircode)
+        # Code generation:
+        cg = codegenarm.ArmCodeGenerator(outs)
+        obj = cg.generate(ircode)
     return True
 
 def main(args):
     logging.basicConfig(format=logformat, level=args.log)
-    src = args.source.read()
-    args.source.close()
+    src = args.source
     diag = ppci.DiagnosticsManager()
     outs = outstream.TextOutputStream()
 
     # Invoke compiler:
-    res = zcc(src, outs, diag, dumpir=args.dumpir, do_optimize=args.optimize, pack_dir=args.package_dir)
+    res = zcc(src, outs, diag, dumpir=args.dumpir, do_optimize=args.optimize)
     if not res:
         diag.printErrors(src)
         return 1
@@ -65,14 +78,10 @@
         outs.dump()
 
     code_bytes = outs.sections['code'].to_bytes()
-    #print('bytes:', code_bytes)
     if args.output:
         output_filename = args.output
-    else:
-        output_filename = 'b.output'
-
-    with open(output_filename, 'wb') as f:
-        f.write(code_bytes)
+        with open(output_filename, 'wb') as f:
+            f.write(code_bytes)
 
     if args.hexfile:
         logging.info('Creating hexfile')
@@ -83,5 +92,6 @@
 
 if __name__ == '__main__':
     arguments = parser.parse_args()
+    print(arguments)
     sys.exit(main(arguments))
 
--- a/test/c3examples/burn2.c3	Fri Nov 15 13:52:32 2013 +0100
+++ b/test/c3examples/burn2.c3	Thu Nov 21 11:57:27 2013 +0100
@@ -22,12 +22,12 @@
         return;
     }
 
-    /*if (pin > 15)
+    if (pin > 15)
     {
         return;
-    }*/
+    }
 
-    var RCC_Type RCC;
+    var stm32f4xx.RCC_Type RCC;
     RCC = cast<RCC_Type>(0x40023800);
 
     // Enable the clock to port D:
@@ -51,7 +51,7 @@
     a = 0
     while (a < 1000)
     {
-        a = a + 1;
+        a = add(a, 1);
     }
 
     while(true) {}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/grind.py	Thu Nov 21 11:57:27 2013 +0100
@@ -0,0 +1,12 @@
+
+import cProfile
+import unittest
+import pstats
+
+if __name__ == '__main__':
+    suite = unittest.TestLoader().discover('.')
+    def runtests():
+        unittest.TextTestRunner().run(suite)
+    #s = cProfile.run('runtests()',sort='cumtime')
+    s = cProfile.run('runtests()',sort='tottime')
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/gui/testhexedit.py	Thu Nov 21 11:57:27 2013 +0100
@@ -0,0 +1,32 @@
+import unittest
+import hexedit
+from PyQt4.QtGui import QApplication
+from PyQt4.QtTest import QTest
+from PyQt4.QtCore import Qt
+import sys
+
+
+class HexTest(unittest.TestCase):
+    def setUp(self):
+        self.app = QApplication(sys.argv)
+        self.ui = hexedit.HexEditor()
+        self.bv = self.ui.he.bv
+        # Provide some random data:
+        self.bv.Data = bytearray(range(10)) * 8 + b'x'
+
+    def tearDown(self):
+        self.app.processEvents()
+        self.app.quit()
+
+    def testOpenButton(self):
+        self.assertEqual(0, self.bv.CursorPosition)
+        #QTest.mouseClick(self.bv, Qt.LeftButton)
+        self.assertEqual(161, self.bv.CursorPosition)
+        QTest.keyClick(self.bv, Qt.Key_Left)
+        self.assertEqual(160, self.bv.CursorPosition)
+        QTest.keyClick(self.bv, Qt.Key_Up)
+        self.assertEqual(128, self.bv.CursorPosition)
+
+
+if __name__ == '__main__':
+    unittest.main()
--- a/test/runtests.sh	Fri Nov 15 13:52:32 2013 +0100
+++ b/test/runtests.sh	Thu Nov 21 11:57:27 2013 +0100
@@ -1,11 +1,14 @@
 #!/usr/bin/env bash
 
-export PYTHONPATH=$PYTHONPATH:../python
+export PYTHONPATH=$PYTHONPATH:`pwd`/../python
 
 if [ $1 == "loop" ]; then
   DIR=..
   while :; do
-    python -m unittest
+    python -m unittest -v
+    cd gui
+    #python -m unittest -v
+    cd ..
     echo "Awaiting changes in $DIR"
     inotifywait -r -e modify $DIR
   done
--- a/test/testc3.py	Fri Nov 15 13:52:32 2013 +0100
+++ b/test/testc3.py	Thu Nov 21 11:57:27 2013 +0100
@@ -1,7 +1,11 @@
 import c3
-import time, ppci, x86, ir
+import time
+import ppci
+import x86
+import ir
 import unittest
 import glob
+import io
 
 testsrc = """module test;
 
@@ -64,29 +68,30 @@
 
 class testLexer(unittest.TestCase):
     def testUnexpectedCharacter(self):
-        snippet = """ var s \u6c34 """
+        snippet = io.StringIO(""" var s \u6c34 """)
         with self.assertRaises(ppci.CompilerError):
             list(c3.lexer.tokenize(snippet))
 
     def testBlockComment(self):
-        snippet = """
+        snippet = io.StringIO("""
           /* Demo */
           var int x = 0;
-        """
+        """)
         toks = ['var', 'ID', 'ID', '=', 'NUMBER', ';', 'END']
         self.assertSequenceEqual([tok.typ for tok in c3.lexer.tokenize(snippet)], toks)
 
     def testBlockCommentMultiLine(self):
-        snippet = """
+        snippet = io.StringIO("""
           /* Demo
           bla1
           bla2
           */
           var int x = 0;
-        """
+        """)
         toks = ['var', 'ID', 'ID', '=', 'NUMBER', ';', 'END']
         self.assertSequenceEqual([tok.typ for tok in c3.lexer.tokenize(snippet)], toks)
 
+
 class testBuilder(unittest.TestCase):
     def setUp(self):
         self.diag = ppci.DiagnosticsManager()
@@ -98,33 +103,35 @@
 
     def expectErrors(self, snippet, rows):
         """ Helper to test for expected errors on rows """
-        ircode = self.builder.build(snippet)
+        ircode = list(self.builder.build([io.StringIO(snippet)]))
         actualErrors = [err.row for err in self.diag.diags]
         if rows != actualErrors:
             self.diag.printErrors(snippet)
         self.assertSequenceEqual(rows, actualErrors)
-        self.assertFalse(ircode)
+        # self.assertFalse(all(ircode))
 
-    def expectOK(self, snippet, pack_dir=None):
-        ircode = self.builder.build(snippet, pack_dir=pack_dir)
+    def expectOK(self, snippet):
+        if type(snippet) is list:
+            ircode = self.builder.build(snippet)
+        else:
+            ircode = self.builder.build([io.StringIO(snippet)])
         if not ircode:
             self.diag.printErrors(snippet)
-        self.assertTrue(ircode)
+        self.assertTrue(all(ircode))
         return ircode
 
     def testPackage(self):
         p1 = """module p1;
         type int A;
         """
-        self.assertTrue(self.builder.build(p1))
         p2 = """module p2;
         import p1;
         var A b;
         """
-        self.expectOK(p2)
+        self.expectOK([io.StringIO(s) for s in (p1, p2)])
 
     def testFunctArgs(self):
-      snippet = """
+        snippet = """
          module testargs;
          function void t2(int a, double b)
          {
@@ -132,11 +139,11 @@
             t2(2);
             t2(1, 1.2);
          }
-      """
-      self.expectErrors(snippet, [5, 6])
+        """
+        self.expectErrors(snippet, [5, 6])
 
     def testExpressions(self):
-      snippet = """
+        snippet = """
          module test;
          function void t(int a, double b)
          {
@@ -147,11 +154,11 @@
             c = a;
             c = b > 1;
          }
-      """
-      self.expectErrors(snippet, [8, 9, 10])
+        """
+        self.expectErrors(snippet, [8, 9, 10])
 
     def testExpression1(self):
-      snippet = """
+        snippet = """
          module testexpr1;
          function void t()
          {
@@ -160,34 +167,34 @@
             b = a * 2 + a * a;
             c = b * a - 3;
          }
-      """
-      self.expectOK(snippet)
+        """
+        self.expectOK(snippet)
 
     def testEmpty(self):
-      snippet = """
-      module A
-      """
-      self.expectErrors(snippet, [3])
+        snippet = """
+        module A
+        """
+        self.expectErrors(snippet, [3])
 
     def testEmpty2(self):
-      snippet = ""
-      self.expectErrors(snippet, [1])
+        snippet = ""
+        self.expectErrors(snippet, [1])
 
     def testRedefine(self):
-      snippet = """
-      module test;
-      var int a;
-      var int b;
-      var int a;
-      """
-      self.expectErrors(snippet, [5])
+        snippet = """
+        module test;
+        var int a;
+        var int b;
+        var int a;
+        """
+        self.expectErrors(snippet, [5])
 
     def testWhile(self):
-      snippet = """
-      module tstwhile;
-      var int a;
-      function void t()
-      {
+        snippet = """
+        module tstwhile;
+        var int a;
+        function void t()
+         {
          var int i = 0;
          while (i < 1054)
          {
@@ -202,15 +209,15 @@
          while(false)
          {
          }
-      }
-      """
-      self.expectOK(snippet)
+        }
+        """
+        self.expectOK(snippet)
 
     def testIf(self):
         snippet = """
-      module tstIFF;
-      function void t(int b)
-      {
+        module tstIFF;
+        function void t(int b)
+         {
          var int a;
          a = 2;
          if (a > b)
@@ -226,7 +233,7 @@
          }
 
          return b;
-      }
+        }
         """
         self.expectOK(snippet)
 
@@ -426,8 +433,7 @@
         }
 
         """
-        ircode = self.expectOK(snippet)
-        self.assertEqual(1, len(ircode.Functions))
+        self.expectOK(snippet)
 
 if __name__ == '__main__':
     unittest.main()
--- a/test/testx86asm.py	Fri Nov 15 13:52:32 2013 +0100
+++ b/test/testx86asm.py	Thu Nov 21 11:57:27 2013 +0100
@@ -24,6 +24,7 @@
    def testCall(self):
       assert(assembler.call('r10') == [0x41, 0xff, 0xd2])
       assert(assembler.call('rcx') == [0xff, 0xd1])
+
    def testXOR(self):
       assert(assembler.xorreg64('rax', 'rax') == [0x48, 0x31, 0xc0])
       assert(assembler.xorreg64('r9', 'r8') == [0x4d, 0x31, 0xc1])
--- a/test/testzcc.py	Fri Nov 15 13:52:32 2013 +0100
+++ b/test/testzcc.py	Thu Nov 21 11:57:27 2013 +0100
@@ -3,27 +3,45 @@
 import zcc
 import outstream
 import ppci
+import io
+import os
 
 
 class ZccTestCase(unittest.TestCase):
     """ Tests the compiler driver """
 
-    def do(self, fn):
-        """ Compile blink.c3 """
-        args = zcc.parser.parse_args([fn, '--package_dir', './c3examples/'])
+    def do(self, filenames):
+        basedir = 'c3examples'
+        filenames = [os.path.join(basedir, fn) for fn in filenames]
+        args = zcc.parser.parse_args(filenames + [])
         self.assertEqual(0, zcc.main(args))
 
-    def testExamples(self):
+    def t2estExamples(self):
         """ Test all examples in the c3/examples directory """
         example_filenames = glob.glob('./c3examples/*.c3')
         for filename in example_filenames:
             self.do(filename)
 
+    def testBurn(self):
+        self.do(['stm32f4xx.c3', 'burn.c3'])
+
+    def testBurn2(self):
+        self.do(['stm32f4xx.c3','burn2.c3'])
+
+    def testComments(self):
+        self.do(['comments.c3'])
+
+    def testCast(self):
+        self.do(['cast.c3'])
+
     def testSectionAddress(self):
-        src = "module tst; function void t2() {var int t3; t3 = 2;}"
+        src = """module tst; 
+            function void t2() {var int t3; t3 = 2;}
+        """
+        f = io.StringIO(src)
         diag = ppci.DiagnosticsManager()
         outs = outstream.TextOutputStream()
-        self.assertTrue(zcc.zcc(src, outs, diag))
+        self.assertTrue(zcc.zcc([f], outs, diag))
         code = outs.getSection('code')
         self.assertEqual(0x08000000, code.address)
         data = outs.getSection('data')