changeset 290:7b38782ed496

File moves
author Windel Bouwman
date Sun, 24 Nov 2013 11:24:15 +0100
parents bd2593de3ff8
children b07d28a5ca56 534b94b40aa8
files python/astviewer.py python/bouncing_cube.py python/bouncing_cube_opencl.py python/codeedit.py python/codegen.py python/codegenarm.py python/cortexm3.py python/diagrameditor.py python/hexedit.py python/hexeditor.ui python/hexutil.py python/icons/arrow.png python/icons/chip.png python/icons/error.png python/icons/functionicon.png python/icons/hardware.png python/icons/info.png python/icons/logo.png python/icons/variableicon.png python/icons/warning.png python/ide.py python/ide/astviewer.py python/ide/codeedit.py python/ide/hexedit.py python/ide/hexeditor.ui python/ide/icons/arrow.png python/ide/icons/chip.png python/ide/icons/error.png python/ide/icons/functionicon.png python/ide/icons/hardware.png python/ide/icons/info.png python/ide/icons/logo.png python/ide/icons/variableicon.png python/ide/icons/warning.png python/ide/ide.py python/ide/logview.py python/instructionselector.py python/integration_methods.py python/isa/openrisc.lidl python/iso9660.py python/logview.py python/msp430.py python/optimize.py python/other/bouncing_cube.py python/other/bouncing_cube_opencl.py python/other/diagrameditor.py python/other/integration_methods.py python/other/qtpropertyviewer.py python/qtpropertyviewer.py python/target.py python/target/__init__.py python/target/armframe.py python/target/armtarget.py python/target/basetarget.py python/target/instructionselector.py python/target/msp430.py python/target/openrisc.lidl python/target/x86.py python/target/x86_2.py python/tcodegen.py python/utils/iso9660.py python/x86.py python/x86_2.py python/zcc.py readme.rst test/tcodegen.py test/testasm.py test/testcg.py test/testgraph.py test/testmsp430asm.py
diffstat 70 files changed, 4791 insertions(+), 4754 deletions(-) [+]
line wrap: on
line diff
--- a/python/astviewer.py	Thu Nov 21 15:46:50 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-from PyQt4.QtCore import *
-from PyQt4.QtGui import *
-from c3 import Visitor, astnodes
-
-class AstModelBuilder:
-    def __init__(self):
-      self.functionIco = QIcon(QPixmap('icons/functionicon.png').scaled(32, 32))
-      self.variableIco = QIcon(QPixmap('icons/variableicon.png').scaled(32, 32))
-      self.model = QStandardItemModel()
-      self.model.setHorizontalHeaderLabels(['Object', 'Type'])
-
-    def build(self, pkg):
-        #self.model.clear()
-        c = self.model.rowCount()
-        self.model.removeRows(0, c)
-        self.curItem = self.model.invisibleRootItem()
-        if pkg:
-            visitor = Visitor()
-            visitor.visit(pkg, self.p1, self.p2)
-
-    def p1(self, node):
-      if type(node) is astnodes.Variable:
-         i = QStandardItem(self.variableIco, str(node))
-      elif type(node) is astnodes.Function:
-         i = QStandardItem(self.functionIco, str(node))
-      elif type(node) is astnodes.Package:
-         i = QStandardItem(str(node))
-      else:
-         return
-      typ = str(node.typ) if hasattr(node, 'typ') else ''
-      ti = QStandardItem(str(typ))
-      ti.setData(node)
-      i.setData(node)
-      self.curItem.appendRow([i, ti])
-      self.curItem = i
-
-    def p2(self, node):
-      if type(node) in [astnodes.Variable, astnodes.Function, astnodes.Package]:
-         self.curItem = self.curItem.parent()
-
-# The actual widget:
-class AstViewer(QTreeView):
-    sigNodeSelected = pyqtSignal(object)
-    def __init__(self, parent=None):
-      super(AstViewer, self).__init__(parent)
-      self.clicked.connect(self.selectHandler)
-      self.modelBuilder = AstModelBuilder()
-      self.setModel(self.modelBuilder.model)
-
-    def setAst(self, ast):
-        """ Create a new model and add all ast elements to it """
-        self.modelBuilder.build(ast)
-        self.expandAll()
-
-    def selectHandler(self, index):
-      if not index.isValid():
-         return
-      model = self.model()
-      item = model.itemFromIndex(index)
-      node = item.data()
-      self.sigNodeSelected.emit(node)
-
-
--- a/python/bouncing_cube.py	Thu Nov 21 15:46:50 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,406 +0,0 @@
-from PyQt4.QtGui import *
-from PyQt4.QtCore import *
-from PyQt4.QtOpenGL import QGLWidget
-from OpenGL.GL import *
-from OpenGL.GLU import gluPerspective
-import sys
-from random import random
-from math import pi, cos, sin, fabs, sqrt
-from numpy import mat, array, ones, zeros, eye
-from numpy.linalg import norm
-import numpy as np
-import time
-import scipy.integrate
-#import pyopencl
-
-"""
-  Test script that lets a dice bounce.
-  Converted from 20-sim equations into python code.
-
-  20-sim website:
-    http://www.20sim.com
-
-"""
-def drawCube(w):
-      glBegin(GL_QUADS)			# Start Drawing The Cube
-      glColor3f(0.0,1.0,0.0)			# Set The Color To Blue
-      glVertex3f( w, w,-w)		# Top Right Of The Quad (Top)
-      glVertex3f(-w, w,-w)		# Top Left Of The Quad (Top)
-      glVertex3f(-w, w, w)		# Bottom Left Of The Quad (Top)
-      glVertex3f( w, w, w)		# Bottom Right Of The Quad (Top)
-
-      glColor3f(1.0,0.5,0.0)			# Set The Color To Orange
-      glVertex3f( w,-w, w)		# Top Right Of The Quad (Bottom)
-      glVertex3f(-w,-w, w)		# Top Left Of The Quad (Bottom)
-      glVertex3f(-w,-w,-w)		# Bottom Left Of The Quad (Bottom)
-      glVertex3f( w,-w,-w)		# Bottom Right Of The Quad (Bottom)
-
-      glColor3f(1.0,0.0,0.0)			# Set The Color To Red
-      glVertex3f( w, w, w)		# Top Right Of The Quad (Front)
-      glVertex3f(-w, w, w)		# Top Left Of The Quad (Front)
-      glVertex3f(-w,-w, w)		# Bottom Left Of The Quad (Front)
-      glVertex3f( w,-w, w)		# Bottom Right Of The Quad (Front)
-
-      glColor3f(1.0,1.0,0.0)			# Set The Color To Yellow
-      glVertex3f( w,-w,-w)		# Bottom Left Of The Quad (Back)
-      glVertex3f(-w,-w,-w)		# Bottom Right Of The Quad (Back)
-      glVertex3f(-w, w,-w)		# Top Right Of The Quad (Back)
-      glVertex3f( w, w,-w)		# Top Left Of The Quad (Back)
-
-      glColor3f(0.0,0.0,1.0)			# Set The Color To Blue
-      glVertex3f(-w, w, w)		# Top Right Of The Quad (Left)
-      glVertex3f(-w, w,-w)		# Top Left Of The Quad (Left)
-      glVertex3f(-w,-w,-w)		# Bottom Left Of The Quad (Left)
-      glVertex3f(-w,-w, w)		# Bottom Right Of The Quad (Left)
-
-      glColor3f(1.0,0.0,1.0)			# Set The Color To Violet
-      glVertex3f( w, w,-w)		# Top Right Of The Quad (Right)
-      glVertex3f( w, w, w)		# Top Left Of The Quad (Right)
-      glVertex3f( w,-w, w)		# Bottom Left Of The Quad (Right)
-      glVertex3f( w,-w,-w)		# Bottom Right Of The Quad (Right)
-      glEnd()				# Done Drawing The Quad
-
-def drawFloor(w, h):
-      glBegin(GL_QUADS)			# Start Drawing The Cube
-
-      glColor3f(1.0,0.5,0.0) # Set The Color To Orange
-      glVertex3f( w,-w,h)# Top Right Of The Quad (Bottom)
-      glVertex3f(-w,-w,h)# Top Left Of The Quad (Bottom)
-      glVertex3f(-w,w,h)# Bottom Left Of The Quad (Bottom)
-      glVertex3f( w,w,h)# Bottom Right Of The Quad (Bottom)
-      glEnd()				# Done Drawing The Quad
-
-def drawAxis():
-  glLineWidth(0.5)
-  glBegin(GL_LINES)
-  glColor3f(1.0, 0.0, 0.0)
-  glVertex3f(0,0,0)
-  glVertex3f(1,0,0)
-  glColor3f(0.0, 1.0, 0.0)
-  glVertex3f(0,0,0)
-  glVertex3f(0,1,0)
-  glColor3f(0.0, 0.0, 1.0)
-  glVertex3f(0,0,0)
-  glVertex3f(0,0,1)
-  glEnd()
-
-
-def cross(A, B):
-   a = A.A1
-   b = B.A1
-   return mat(np.cross(a, b)).T
-
-def skew(X):
-  Y = mat(zeros( (3, 3) ))
-  a,b,c = X.A1
-  Y[0,1] = -c
-  Y[0,2] = b
-  Y[1,0] = c
-  Y[1,2] = -a
-  Y[2,0] = -b
-  Y[2,1] = a
-  return Y
-
-def adjoint(T):
-  W = T[0:3, 0]
-  V = T[3:6, 0]
-  a = mat(zeros( (6,6) ) )
-  a[0:3, 0:3] = skew(W)
-  a[3:6, 0:3] = skew(V)
-  a[3:6, 3:6] = skew(W)
-  return a
-
-def Adjoint(H):
-  R = H[0:3, 0:3]
-  P = H[0:3, 3]
-  a = mat(zeros( (6,6) ) )
-  a[0:3, 0:3] = R
-  a[3:6, 3:6] = R
-  a[3:6, 0:3] = skew(P) * R
-  return a
-
-def quatToR(q):
-  x, y, z, w = q.A1
-  r = mat(eye(3))
-  r[0,0] = 1 - (2*y**2+2*z**2)
-  r[0,1] = 2*x*y+2*z*w
-  r[0,2] = 2*x*z - 2*y*w
-  r[1,0] = 2*x*y-2*z*w
-  r[1,1] = 1 - (2*x**2 + 2*z**2)
-  r[1,2] = 2*y*z + 2*x*w
-  r[2,0] = 2*x*z+2*y*w
-  r[2,1] = 2*y*z - 2*x*w
-  r[2,2] = 1 - (2*x**2+2*y**2)
-  return r
-
-def rotateAbout(axis, angle):
-   ax, ay, az = (axis/norm(axis)).A1
-   qx = ax*sin(angle/2.0)
-   qy = ay*sin(angle/2.0)
-   qz = az*sin(angle/2.0)
-   qw = cos(angle/2.0)
-   q = mat(array([qx,qy,qz,qw])).T
-   return q
-
-def normalizeQuaternion(quat):
-  x,y,z,w = quat.A1
-  magnitude = sqrt(x*x + y*y + z*z + w*w)
-  x = x / magnitude
-  y = y / magnitude
-  z = z / magnitude
-  w = w / magnitude
-  quat[0, 0] = x
-  quat[1, 0] = y
-  quat[2, 0] = z
-  quat[3, 0] = w
-  return quat
-
-def VTo4x4(V):
-    v1, v2, v3 = V.A1
-    return mat(array( \
-      [[0.0, -v3,  v2, -v1], \
-      [ v3,  0.0, -v1, -v2], \
-      [-v2, v1, 0.0, -v3], \
-      [v1, v2, v3, 0.0] ]))
-
-def homogeneous(R,p):
-    H = mat(eye(4))
-    H[0:3, 0:3] = R
-    H[0:3, 3] = p
-    return H
-
-def rateOfChange(states, thetime, parameters):
-    quat = states[0:4,  0] # Orientation (4)
-    pos  = states[4:7,  0] # Position (3)
-    P    = states[7:13, 0] # Momentum (6)
-    massI, gravity = parameters
-    # Rigid body parts:
-    # Forward Kinematic chain:
-    H = homogeneous(quatToR(quat), pos) # Forward kinematics
-
-    AdjX2 = mat(eye(6)) # The connectionpoint in the real world
-    adjAdjX2_1 = adjoint(AdjX2[0:6,0])
-    adjAdjX2_2 = adjoint(AdjX2[0:6,1])
-    adjAdjX2_3 = adjoint(AdjX2[0:6,2])
-    adjAdjX2_4 = adjoint(AdjX2[0:6,3])
-    adjAdjX2_5 = adjoint(AdjX2[0:6,4])
-    adjAdjX2_6 = adjoint(AdjX2[0:6,5])
-    AdjInv2 = Adjoint(H.I)
-    M2 = AdjInv2.T * (massI * AdjInv2) # Transfor mass to base frame
-    MassMatrix = M2
-
-    wrenchGrav2 = mat( zeros((1,6)) )
-    wrenchGrav2[0, 0:3] = -cross(gravity, pos).T
-    wrenchGrav2[0, 3:6] = gravity.T
-
-    Bk = mat( zeros( (6,6) ))
-    Bk[0:3, 0:3] = skew(P[0:3, 0])
-    Bk[3:6, 0:3] = skew(P[3:6, 0])
-    Bk[0:3, 3:6] = skew(P[3:6, 0])
-
-    # TODO: do this a cholesky:
-    v = np.linalg.solve(MassMatrix, P) # Matrix inverse like thingy !
-
-    T2_00 = v # Calculate the relative twist!
-    TM2 = T2_00.T * M2
-    twistExternal = T2_00 # Twist van het blokje
-    TMSum2 = TM2
-
-    PDotBodies = mat( zeros( (6,1)) )
-    PDotBodies[0,0] = TMSum2 * (adjAdjX2_1 * T2_00)
-    PDotBodies[1,0] = TMSum2 * (adjAdjX2_2 * T2_00)
-    PDotBodies[2,0] = TMSum2 * (adjAdjX2_3 * T2_00)
-    PDotBodies[3,0] = TMSum2 * (adjAdjX2_4 * T2_00)
-    PDotBodies[4,0] = TMSum2 * (adjAdjX2_5 * T2_00)
-    PDotBodies[5,0] = TMSum2 * (adjAdjX2_6 * T2_00)
-    
-    PDot = -PDotBodies - Bk * v
-    PDot += wrenchGrav2.T
-    
-    ##### Contact wrench part:
-    HB_W = H # Is H-matrix van het blokje
-    WrenchB = mat(zeros( (1,6) ))
-    for px in [-0.5, 0.5]:
-      for py in [-0.5, 0.5]:
-        for pz in [-0.5, 0.5]:
-          HB1_B = homogeneous(mat(eye(3)), mat([px,py,pz]).T)
-          HB1_W = HB_W * HB1_B
-          HW1_W = homogeneous(mat(eye(3)), HB1_W[0:3,3])
-          HW_W1 = HW1_W.I
-          HB_W1 = HW_W1 * HB_W
-    
-          AdjHB_W1 = Adjoint(HB_W1)
-          TB_W1_W1 = AdjHB_W1 * twistExternal
-          z = HB1_W[2, 3]
-          vx, vy, vz = TB_W1_W1[3:6, 0].A1
-          if z < 0:
-            # Contact forces:
-            Fx = -50.0*vx
-            Fy = -50.0*vy
-            Fz = -z*50000.0 
-          else:
-            Fx = 0.0
-            Fy = 0.0
-            Fz = 0.0
-          # TODO: reflect impulse
-          WrenchW1 = mat([0,0,0,0,0,Fz])
-          # Transform it back:
-          WrenchB += (AdjHB_W1.T * WrenchW1.T).T
-    ##### End of contact wrench
-
-    PDot += (WrenchB * AdjInv2).T
-
-    # Position and orientation rates:
-    QOmega = VTo4x4(v[0:3, 0])
-    quatDot = 0.5 * QOmega * quat
-    vel = v[3:6, 0]
-    posDot = skew(v[0:3]) * pos + vel
-    # The rate vector:
-    rates = mat(zeros( (13,1) ))
-    rates[0:4, 0] = quatDot
-    rates[4:7, 0] = posDot
-    rates[7:13, 0] = PDot
-    return rates
-
-def fWrapper(y, t, parameters):
-   y = mat(y).T
-   dy = rateOfChange(y, t, parameters)
-   return dy.T.A1
-  
-def SCIPY(endtime, dt, state, parameters):
-    times = np.arange(0.0, endtime, dt)
-    y0 = state.T.A1
-    res = scipy.integrate.odeint(fWrapper, y0, times, args=(parameters,))
-    states = []
-    res = res.T
-    r,c =  res.shape
-    for ci in range(0,c):
-      states.append(mat(res[:,ci]).T)
-    return states
-  
-def RK4(endtime, dt, state, parameters):
-    t = 0.0
-    states = []
-    while t < endtime:
-      newstate = mat (zeros( state.shape )) # Create a new object
-
-      #### Runge Kutta integration:
-      k1 = rateOfChange(state,             t, parameters)
-      k2 = rateOfChange(state + 0.5*dt*k1, t, parameters)
-      k3 = rateOfChange(state + 0.5*dt*k1, t, parameters)
-      k4 = rateOfChange(state + dt*k3,     t, parameters)
-      newstate = state + (dt/6.0)*(k1+2*k2+2*k3+k4)
-
-      # Normalize quat:
-      newstate[0:4, 0] = normalizeQuaternion(newstate[0:4, 0])
-      states.append(newstate)
-
-      state = newstate
-
-      t += dt
-      print(state[6,0], t, ' ', (t/endtime)*100.0, '%')
-    return states
-  
-
-def simulate(endtime, dt):
-    PInitial = mat( zeros((6,1)) )
-    posInitial = mat(array([-1.2, -1.3, 2.8])).T
-    quatInitial = rotateAbout(mat(array([0.2, 1.0, 0.4])).T, 0.5)
-    # Parameters:
-    gravity = mat( array([0,0,-9.81]) ).T
-    massI = mat(eye(6)) * 1.01 # Mass matrix
-    parameters = (massI, gravity)
-
-    # The state vector!
-    state = mat(zeros( (13,1) ))
-    state[0:4, 0] = quatInitial
-    state[4:7, 0] = posInitial
-    state[7:13, 0] = PInitial
-
-    return SCIPY(endtime, dt, state, parameters)
-
-class W(QGLWidget):
-  time = 0.0
-  index = 0
-  def __init__(self, states, dt, parent=None):
-    super(W, self).__init__(parent)
-    self.firstRun = True
-    self.savePNGS = False
-    self.dt = dt
-    self.resize(500,500)
-    self.states = states
-    self.UP()
-    t = QTimer(self)
-    t.timeout.connect(self.UP)
-    t.start(self.dt*1000.0)
-
-  def UP(self):
-    self.time += self.dt
-    if self.states:
-      state = self.states[self.index]
-      self.Dicequat = state[0:4, 0]
-      self.Dicepos = state[4:7, 0]
-      self.index += 1
-      if self.index == len(self.states):
-        self.index = 0
-        self.firstRun = False
-    # Paint:
-    self.update()
-    if self.firstRun:
-       # Create png images for the movie:
-       if self.savePNGS:
-          pm = self.renderPixmap()
-          pm.save('image'+str(self.index)+'.png')
-
-  def initializeGL(self):
-      glClearColor(0.0, 0.5, 0.0, 1.0)
-      glEnable(GL_DEPTH_TEST)
-      glDepthFunc(GL_LESS)
-      glShadeModel(GL_SMOOTH)
-  def resizeGL(self,w,h):
-      glViewport(0, 0, w, h)
-      glMatrixMode(GL_PROJECTION)
-      glLoadIdentity()
-      gluPerspective(45.0, float(w)/float(h), 0.1, 100.0)
-      glMatrixMode(GL_MODELVIEW)
-  def paintGL(self):
-      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) # Clear buffers
-      glLoadIdentity() # Reset The View
-
-      glLoadIdentity()
-      glTranslatef(0.0,-2.0,-10.0) # Move Left And Into The Screen
-      glRotatef(-90.0, 1.0, 0.0, 0.0)
-      drawFloor(2.0, 0.0)
-      drawAxis()
-      self.renderText(1.0, 0.0, 0.0, 'X')
-      self.renderText(0.0, 1.0, 0.0, 'Y')
-      self.renderText(0.0, 0.0, 1.0, 'Z')
-
-      self.renderText(0.0,0.0,1.2,str(self.time))
-
-      x,y,z = self.Dicepos.A1
-      R = quatToR(self.Dicequat)
-
-      glTranslatef(x, y, z)
-      # Trick to rotate the openGL matrix:
-      r = R.A1
-      rotR = (r[0], r[3], r[6], 0.0,
-              r[1], r[4], r[7], 0.0,
-              r[2], r[5], r[8], 0.0,
-              0.0,  0.0,  0.0,  1.0)
-      glMultMatrixd(rotR)
-      
-      drawCube(0.6)
-
-et = 20.0
-dt = 0.04
-print('starting integration... endtime =', et, ' stepsize =', dt)
-t0 = time.time()
-states = simulate(et, dt)
-t1 = time.time()
-print('That was heavy, it took me ', t1-t0, ' seconds!')
-app = QApplication(sys.argv)
-w = W(states, dt)
-w.show()
-sys.exit(app.exec_())
-
--- a/python/bouncing_cube_opencl.py	Thu Nov 21 15:46:50 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,406 +0,0 @@
-from PyQt4.QtGui import *
-from PyQt4.QtCore import *
-from PyQt4.QtOpenGL import QGLWidget
-from OpenGL.GL import *
-from OpenGL.GLU import gluPerspective
-import sys
-from random import random
-from math import pi, cos, sin, fabs, sqrt
-from numpy import mat, array, ones, zeros, eye
-from numpy.linalg import norm
-import numpy as np
-import time
-import scipy.integrate
-import pyopencl
-
-"""
-  Test script that lets a dice bounce.
-  Converted from 20-sim equations into python code.
-
-  20-sim website:
-    http://www.20sim.com
-
-"""
-def drawCube(w):
-      glBegin(GL_QUADS)			# Start Drawing The Cube
-      glColor3f(0.0,1.0,0.0)			# Set The Color To Blue
-      glVertex3f( w, w,-w)		# Top Right Of The Quad (Top)
-      glVertex3f(-w, w,-w)		# Top Left Of The Quad (Top)
-      glVertex3f(-w, w, w)		# Bottom Left Of The Quad (Top)
-      glVertex3f( w, w, w)		# Bottom Right Of The Quad (Top)
-
-      glColor3f(1.0,0.5,0.0)			# Set The Color To Orange
-      glVertex3f( w,-w, w)		# Top Right Of The Quad (Bottom)
-      glVertex3f(-w,-w, w)		# Top Left Of The Quad (Bottom)
-      glVertex3f(-w,-w,-w)		# Bottom Left Of The Quad (Bottom)
-      glVertex3f( w,-w,-w)		# Bottom Right Of The Quad (Bottom)
-
-      glColor3f(1.0,0.0,0.0)			# Set The Color To Red
-      glVertex3f( w, w, w)		# Top Right Of The Quad (Front)
-      glVertex3f(-w, w, w)		# Top Left Of The Quad (Front)
-      glVertex3f(-w,-w, w)		# Bottom Left Of The Quad (Front)
-      glVertex3f( w,-w, w)		# Bottom Right Of The Quad (Front)
-
-      glColor3f(1.0,1.0,0.0)			# Set The Color To Yellow
-      glVertex3f( w,-w,-w)		# Bottom Left Of The Quad (Back)
-      glVertex3f(-w,-w,-w)		# Bottom Right Of The Quad (Back)
-      glVertex3f(-w, w,-w)		# Top Right Of The Quad (Back)
-      glVertex3f( w, w,-w)		# Top Left Of The Quad (Back)
-
-      glColor3f(0.0,0.0,1.0)			# Set The Color To Blue
-      glVertex3f(-w, w, w)		# Top Right Of The Quad (Left)
-      glVertex3f(-w, w,-w)		# Top Left Of The Quad (Left)
-      glVertex3f(-w,-w,-w)		# Bottom Left Of The Quad (Left)
-      glVertex3f(-w,-w, w)		# Bottom Right Of The Quad (Left)
-
-      glColor3f(1.0,0.0,1.0)			# Set The Color To Violet
-      glVertex3f( w, w,-w)		# Top Right Of The Quad (Right)
-      glVertex3f( w, w, w)		# Top Left Of The Quad (Right)
-      glVertex3f( w,-w, w)		# Bottom Left Of The Quad (Right)
-      glVertex3f( w,-w,-w)		# Bottom Right Of The Quad (Right)
-      glEnd()				# Done Drawing The Quad
-
-def drawFloor(w, h):
-      glBegin(GL_QUADS)			# Start Drawing The Cube
-
-      glColor3f(1.0,0.5,0.0) # Set The Color To Orange
-      glVertex3f( w,-w,h)# Top Right Of The Quad (Bottom)
-      glVertex3f(-w,-w,h)# Top Left Of The Quad (Bottom)
-      glVertex3f(-w,w,h)# Bottom Left Of The Quad (Bottom)
-      glVertex3f( w,w,h)# Bottom Right Of The Quad (Bottom)
-      glEnd()				# Done Drawing The Quad
-
-def drawAxis():
-  glLineWidth(0.5)
-  glBegin(GL_LINES)
-  glColor3f(1.0, 0.0, 0.0)
-  glVertex3f(0,0,0)
-  glVertex3f(1,0,0)
-  glColor3f(0.0, 1.0, 0.0)
-  glVertex3f(0,0,0)
-  glVertex3f(0,1,0)
-  glColor3f(0.0, 0.0, 1.0)
-  glVertex3f(0,0,0)
-  glVertex3f(0,0,1)
-  glEnd()
-
-
-def cross(A, B):
-   a = A.A1
-   b = B.A1
-   return mat(np.cross(a, b)).T
-
-def skew(X):
-  Y = mat(zeros( (3, 3) ))
-  a,b,c = X.A1
-  Y[0,1] = -c
-  Y[0,2] = b
-  Y[1,0] = c
-  Y[1,2] = -a
-  Y[2,0] = -b
-  Y[2,1] = a
-  return Y
-
-def adjoint(T):
-  W = T[0:3, 0]
-  V = T[3:6, 0]
-  a = mat(zeros( (6,6) ) )
-  a[0:3, 0:3] = skew(W)
-  a[3:6, 0:3] = skew(V)
-  a[3:6, 3:6] = skew(W)
-  return a
-
-def Adjoint(H):
-  R = H[0:3, 0:3]
-  P = H[0:3, 3]
-  a = mat(zeros( (6,6) ) )
-  a[0:3, 0:3] = R
-  a[3:6, 3:6] = R
-  a[3:6, 0:3] = skew(P) * R
-  return a
-
-def quatToR(q):
-  x, y, z, w = q.A1
-  r = mat(eye(3))
-  r[0,0] = 1 - (2*y**2+2*z**2)
-  r[0,1] = 2*x*y+2*z*w
-  r[0,2] = 2*x*z - 2*y*w
-  r[1,0] = 2*x*y-2*z*w
-  r[1,1] = 1 - (2*x**2 + 2*z**2)
-  r[1,2] = 2*y*z + 2*x*w
-  r[2,0] = 2*x*z+2*y*w
-  r[2,1] = 2*y*z - 2*x*w
-  r[2,2] = 1 - (2*x**2+2*y**2)
-  return r
-
-def rotateAbout(axis, angle):
-   ax, ay, az = (axis/norm(axis)).A1
-   qx = ax*sin(angle/2.0)
-   qy = ay*sin(angle/2.0)
-   qz = az*sin(angle/2.0)
-   qw = cos(angle/2.0)
-   q = mat(array([qx,qy,qz,qw])).T
-   return q
-
-def normalizeQuaternion(quat):
-  x,y,z,w = quat.A1
-  magnitude = sqrt(x*x + y*y + z*z + w*w)
-  x = x / magnitude
-  y = y / magnitude
-  z = z / magnitude
-  w = w / magnitude
-  quat[0, 0] = x
-  quat[1, 0] = y
-  quat[2, 0] = z
-  quat[3, 0] = w
-  return quat
-
-def VTo4x4(V):
-    v1, v2, v3 = V.A1
-    return mat(array( \
-      [[0.0, -v3,  v2, -v1], \
-      [ v3,  0.0, -v1, -v2], \
-      [-v2, v1, 0.0, -v3], \
-      [v1, v2, v3, 0.0] ]))
-
-def homogeneous(R,p):
-    H = mat(eye(4))
-    H[0:3, 0:3] = R
-    H[0:3, 3] = p
-    return H
-
-def rateOfChange(states, thetime, parameters):
-    quat = states[0:4,  0] # Orientation (4)
-    pos  = states[4:7,  0] # Position (3)
-    P    = states[7:13, 0] # Momentum (6)
-    massI, gravity = parameters
-    # Rigid body parts:
-    # Forward Kinematic chain:
-    H = homogeneous(quatToR(quat), pos) # Forward kinematics
-
-    AdjX2 = mat(eye(6)) # The connectionpoint in the real world
-    adjAdjX2_1 = adjoint(AdjX2[0:6,0])
-    adjAdjX2_2 = adjoint(AdjX2[0:6,1])
-    adjAdjX2_3 = adjoint(AdjX2[0:6,2])
-    adjAdjX2_4 = adjoint(AdjX2[0:6,3])
-    adjAdjX2_5 = adjoint(AdjX2[0:6,4])
-    adjAdjX2_6 = adjoint(AdjX2[0:6,5])
-    AdjInv2 = Adjoint(H.I)
-    M2 = AdjInv2.T * (massI * AdjInv2) # Transfor mass to base frame
-    MassMatrix = M2
-
-    wrenchGrav2 = mat( zeros((1,6)) )
-    wrenchGrav2[0, 0:3] = -cross(gravity, pos).T
-    wrenchGrav2[0, 3:6] = gravity.T
-
-    Bk = mat( zeros( (6,6) ))
-    Bk[0:3, 0:3] = skew(P[0:3, 0])
-    Bk[3:6, 0:3] = skew(P[3:6, 0])
-    Bk[0:3, 3:6] = skew(P[3:6, 0])
-
-    # TODO: do this a cholesky:
-    v = np.linalg.solve(MassMatrix, P) # Matrix inverse like thingy !
-
-    T2_00 = v # Calculate the relative twist!
-    TM2 = T2_00.T * M2
-    twistExternal = T2_00 # Twist van het blokje
-    TMSum2 = TM2
-
-    PDotBodies = mat( zeros( (6,1)) )
-    PDotBodies[0,0] = TMSum2 * (adjAdjX2_1 * T2_00)
-    PDotBodies[1,0] = TMSum2 * (adjAdjX2_2 * T2_00)
-    PDotBodies[2,0] = TMSum2 * (adjAdjX2_3 * T2_00)
-    PDotBodies[3,0] = TMSum2 * (adjAdjX2_4 * T2_00)
-    PDotBodies[4,0] = TMSum2 * (adjAdjX2_5 * T2_00)
-    PDotBodies[5,0] = TMSum2 * (adjAdjX2_6 * T2_00)
-    
-    PDot = -PDotBodies - Bk * v
-    PDot += wrenchGrav2.T
-    
-    ##### Contact wrench part:
-    HB_W = H # Is H-matrix van het blokje
-    WrenchB = mat(zeros( (1,6) ))
-    for px in [-0.5, 0.5]:
-      for py in [-0.5, 0.5]:
-        for pz in [-0.5, 0.5]:
-          HB1_B = homogeneous(mat(eye(3)), mat([px,py,pz]).T)
-          HB1_W = HB_W * HB1_B
-          HW1_W = homogeneous(mat(eye(3)), HB1_W[0:3,3])
-          HW_W1 = HW1_W.I
-          HB_W1 = HW_W1 * HB_W
-    
-          AdjHB_W1 = Adjoint(HB_W1)
-          TB_W1_W1 = AdjHB_W1 * twistExternal
-          z = HB1_W[2, 3]
-          vx, vy, vz = TB_W1_W1[3:6, 0].A1
-          if z < 0:
-            # Contact forces:
-            Fx = -50.0*vx
-            Fy = -50.0*vy
-            Fz = -z*50000.0 
-          else:
-            Fx = 0.0
-            Fy = 0.0
-            Fz = 0.0
-          # TODO: reflect impulse
-          WrenchW1 = mat([0,0,0,0,0,Fz])
-          # Transform it back:
-          WrenchB += (AdjHB_W1.T * WrenchW1.T).T
-    ##### End of contact wrench
-
-    PDot += (WrenchB * AdjInv2).T
-
-    # Position and orientation rates:
-    QOmega = VTo4x4(v[0:3, 0])
-    quatDot = 0.5 * QOmega * quat
-    vel = v[3:6, 0]
-    posDot = skew(v[0:3]) * pos + vel
-    # The rate vector:
-    rates = mat(zeros( (13,1) ))
-    rates[0:4, 0] = quatDot
-    rates[4:7, 0] = posDot
-    rates[7:13, 0] = PDot
-    return rates
-
-def fWrapper(y, t, parameters):
-   y = mat(y).T
-   dy = rateOfChange(y, t, parameters)
-   return dy.T.A1
-  
-def SCIPY(endtime, dt, state, parameters):
-    times = np.arange(0.0, endtime, dt)
-    y0 = state.T.A1
-    res = scipy.integrate.odeint(fWrapper, y0, times, args=(parameters,))
-    states = []
-    res = res.T
-    r,c =  res.shape
-    for ci in range(0,c):
-      states.append(mat(res[:,ci]).T)
-    return states
-  
-def RK4(endtime, dt, state, parameters):
-    t = 0.0
-    states = []
-    while t < endtime:
-      newstate = mat (zeros( state.shape )) # Create a new object
-
-      #### Runge Kutta integration:
-      k1 = rateOfChange(state,             t, parameters)
-      k2 = rateOfChange(state + 0.5*dt*k1, t, parameters)
-      k3 = rateOfChange(state + 0.5*dt*k1, t, parameters)
-      k4 = rateOfChange(state + dt*k3,     t, parameters)
-      newstate = state + (dt/6.0)*(k1+2*k2+2*k3+k4)
-
-      # Normalize quat:
-      newstate[0:4, 0] = normalizeQuaternion(newstate[0:4, 0])
-      states.append(newstate)
-
-      state = newstate
-
-      t += dt
-      print state[6,0], t, ' ', (t/endtime)*100.0, '%'
-    return states
-  
-
-def simulate(endtime, dt):
-    PInitial = mat( zeros((6,1)) )
-    posInitial = mat(array([-1.2, -1.3, 2.8])).T
-    quatInitial = rotateAbout(mat(array([0.2, 1.0, 0.4])).T, 0.5)
-    # Parameters:
-    gravity = mat( array([0,0,-9.81]) ).T
-    massI = mat(eye(6)) * 1.01 # Mass matrix
-    parameters = (massI, gravity)
-
-    # The state vector!
-    state = mat(zeros( (13,1) ))
-    state[0:4, 0] = quatInitial
-    state[4:7, 0] = posInitial
-    state[7:13, 0] = PInitial
-
-    return SCIPY(endtime, dt, state, parameters)
-
-class W(QGLWidget):
-  time = 0.0
-  index = 0
-  def __init__(self, states, dt, parent=None):
-    super(W, self).__init__(parent)
-    self.firstRun = True
-    self.savePNGS = False
-    self.dt = dt
-    self.resize(500,500)
-    self.states = states
-    self.UP()
-    t = QTimer(self)
-    t.timeout.connect(self.UP)
-    t.start(self.dt*1000.0)
-
-  def UP(self):
-    self.time += self.dt
-    if self.states:
-      state = self.states[self.index]
-      self.Dicequat = state[0:4, 0]
-      self.Dicepos = state[4:7, 0]
-      self.index += 1
-      if self.index == len(self.states):
-        self.index = 0
-        self.firstRun = False
-    # Paint:
-    self.update()
-    if self.firstRun:
-       # Create png images for the movie:
-       if self.savePNGS:
-          pm = self.renderPixmap()
-          pm.save('image'+str(self.index)+'.png')
-
-  def initializeGL(self):
-      glClearColor(0.0, 0.5, 0.0, 1.0)
-      glEnable(GL_DEPTH_TEST)
-      glDepthFunc(GL_LESS)
-      glShadeModel(GL_SMOOTH)
-  def resizeGL(self,w,h):
-      glViewport(0, 0, w, h)
-      glMatrixMode(GL_PROJECTION)
-      glLoadIdentity()
-      gluPerspective(45.0, float(w)/float(h), 0.1, 100.0)
-      glMatrixMode(GL_MODELVIEW)
-  def paintGL(self):
-      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) # Clear buffers
-      glLoadIdentity() # Reset The View
-
-      glLoadIdentity()
-      glTranslatef(0.0,-2.0,-10.0) # Move Left And Into The Screen
-      glRotatef(-90.0, 1.0, 0.0, 0.0)
-      drawFloor(2.0, 0.0)
-      drawAxis()
-      self.renderText(1.0, 0.0, 0.0, 'X')
-      self.renderText(0.0, 1.0, 0.0, 'Y')
-      self.renderText(0.0, 0.0, 1.0, 'Z')
-
-      self.renderText(0.0,0.0,1.2,str(self.time))
-
-      x,y,z = self.Dicepos.A1
-      R = quatToR(self.Dicequat)
-
-      glTranslatef(x, y, z)
-      # Trick to rotate the openGL matrix:
-      r = R.A1
-      rotR = (r[0], r[3], r[6], 0.0,
-              r[1], r[4], r[7], 0.0,
-              r[2], r[5], r[8], 0.0,
-              0.0,  0.0,  0.0,  1.0)
-      glMultMatrixd(rotR)
-      
-      drawCube(0.6)
-
-et = 20.0
-dt = 0.04
-print 'starting integration... endtime =', et, ' stepsize =', dt
-t0 = time.time()
-states = simulate(et, dt)
-t1 = time.time()
-print 'That was heavy, it took me ', t1-t0, ' seconds!'
-app = QApplication(sys.argv)
-w = W(states, dt)
-w.show()
-sys.exit(app.exec_())
-
--- a/python/codeedit.py	Thu Nov 21 15:46:50 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,291 +0,0 @@
-#!/usr/bin/python
-
-import sys
-import os
-from PyQt4.QtCore import *
-from PyQt4.QtGui import *
-import inspect
-
-GAP = 5
-
-def clipVal(v, mn, mx):
-   if v < mn: return mn
-   if v > mx: return mx
-   return v
-
-class InnerCode(QWidget):
-    textChanged = pyqtSignal()
-    def __init__(self, scrollArea):
-      super().__init__(scrollArea)
-      self.scrollArea = scrollArea
-      self.setFont(QFont('Courier', 12))
-      self.setFocusPolicy(Qt.StrongFocus)
-      # TODO: only beam cursor in text area..
-      self.setCursor(Qt.IBeamCursor)
-      h = QFontMetrics(self.font()).height()
-      self.errorPixmap = QPixmap('icons/error.png').scaled(h, h)
-      self.arrowPixmap = QPixmap('icons/arrow.png').scaled(h, h)
-      self.blinkcursor = False
-      self.errorlist = []
-      self.arrow = None
-      # Initial values:
-      self.setSource('')
-      self.CursorPosition = 0
-      self.t = QTimer(self)
-      self.t.timeout.connect(self.updateCursor)
-      self.t.setInterval(500)
-      self.t.start()
-
-    def updateCursor(self):
-        self.blinkcursor = not self.blinkcursor
-        self.update()
-        #self.update(self.cursorX, self.cursorY, self.charWidth, self.charHeight)
-
-    def setSource(self, src):
-        self.src = src
-        self.adjust()
-
-    def getSource(self):
-        return self.src
-
-    def setErrors(self, el):
-        self.errorlist = el
-        self.update()
-
-    def setCursorPosition(self, c):
-        self.cursorPosition = clipVal(c, 0, len(self.src))
-        self.update()
-
-    CursorPosition = property(lambda self: self.cursorPosition, setCursorPosition)
-
-    @property
-    def Rows(self):
-        # Make this nicer:
-        return self.src.split('\n')
-
-    @property
-    def CursorRow(self):
-        # TODO: make this nice.
-        txt = self.src[0:self.cursorPosition]
-        return len(txt.split('\n'))
-
-    @property
-    def CursorCol(self):
-        txt = self.src[0:self.cursorPosition]
-        curLine = txt.split('\n')[-1]
-        return len(curLine) + 1
-
-    @property
-    def CurrentLine(self):
-        return self.getRow(self.CursorRow)
-
-    def setRowCol(self, r, c):
-      prevRows = self.Rows[:r-1]
-      txt = '\n'.join(prevRows)
-      c = clipVal(c, 1, len(self.getRow(r)))
-      self.CursorPosition = len(txt) + c + 1
-      self.showRow(self.CursorRow)
-
-    def getRow(self, r):
-      rows = self.Rows
-      r = r - 1
-      if r < 0 or r > len(rows) - 1:
-         return ''
-      else:
-         return rows[r]
-
-    def showRow(self, r):
-      self.scrollArea.ensureVisible(self.xposTXT, r * self.charHeight, 4, self.charHeight)
-
-    # Annotations:
-    def addAnnotation(self, row, col, ln, msg):
-      pass
-
-    # Text modification:
-    def getChar(self, pos):
-      pass
-
-    def insertText(self, txt):
-        self.setSource(self.src[0:self.CursorPosition] + txt + self.src[self.CursorPosition:])
-        self.CursorPosition += len(txt)
-        self.textChanged.emit()
-
-    def deleteChar(self):
-        self.setSource(self.src[0:self.CursorPosition] + self.src[self.CursorPosition+1:])
-        self.textChanged.emit()
-
-    def GotoNextChar(self):
-        if self.src[self.CursorPosition] != '\n':
-            self.CursorPosition += 1
-
-    def GotoPrevChar(self):
-        if self.src[self.CursorPosition - 1] != '\n':
-            self.CursorPosition -= 1
-
-    def GotoNextLine(self):
-        curLine = self.CurrentLine
-        c = self.CursorCol - 1 # go to zero based
-        self.CursorPosition += len(curLine) - c + 1 # line break char!
-        curLine = self.CurrentLine
-        if len(curLine) < c:
-            self.CursorPosition += len(curLine)
-        else:
-            self.CursorPosition += c
-        self.showRow(self.CursorRow)
-
-    def GotoPrevLine(self):
-        c = self.CursorCol - 1 # go to zero based
-        self.CursorPosition -= c + 1 # line break char!
-        curLine = self.CurrentLine
-        if len(curLine) > c:
-            self.CursorPosition -= len(curLine) - c
-        self.showRow(self.CursorRow)
-
-    def paintEvent(self, event):
-      # Helper variables:
-      er = event.rect()
-      chw, chh = self.charWidth, self.charHeight
-      painter = QPainter(self)
-      # Background:
-      painter.fillRect(er, self.palette().color(QPalette.Base))
-      painter.fillRect(QRect(self.xposLNA, er.top(), 4 * chw, er.bottom() + 1), Qt.gray)
-      errorPen = QPen(Qt.red, 3)
-      # first and last row:
-      row1 = max(int(er.top() / chh) - 1, 1)
-      row2 = max(int(er.bottom() / chh) + 1, 1)
-      # Draw contents:
-      ypos = row1 * chh - self.charDescent
-      curRow = self.CursorRow
-      ydt = -chh + self.charDescent
-      for row in range(row1, row2 + 1):
-         if curRow == row and self.hasFocus():
-            painter.fillRect(self.xposTXT, ypos + ydt, er.width(), chh, Qt.yellow)
-            # cursor
-            if self.blinkcursor:
-               cursorX = self.CursorCol * self.charWidth + self.xposTXT - self.charWidth
-               cursorY = ypos + ydt
-               painter.fillRect(cursorX, cursorY, 2, chh, Qt.black)
-         painter.setPen(Qt.black)
-         painter.drawText(self.xposLNA, ypos, '{0}'.format(row))
-         xpos = self.xposTXT
-         painter.drawText(xpos, ypos, self.getRow(row))
-         if self.arrow and self.arrow.row == row:
-                painter.drawPixmap(self.xposERR, ypos + ydt, self.arrowPixmap)
-         curErrors = [e for e in self.errorlist if e.loc and e.loc.row == row]
-         for e in curErrors:
-               painter.drawPixmap(self.xposERR, ypos + ydt, self.errorPixmap)
-               painter.setPen(errorPen)
-               x = self.xposTXT + (e.loc.col - 1) * chw - 2
-               wt = e.loc.length * chw + 4
-               dy = self.charDescent
-               painter.drawLine(x, ypos + dy, x + wt, ypos + dy)
-               #painter.drawRoundedRect(x, ypos + ydt, wt, chh, 7, 7)
-               # print error balloon
-               #painter.drawText(x, ypos + chh, e.msg)
-         #if len(curErrors) > 0:
-         #   ypos += chh
-         ypos += chh
-
-    def keyPressEvent(self, event):
-      if event.matches(QKeySequence.MoveToNextChar):
-         self.GotoNextChar()
-      elif event.matches(QKeySequence.MoveToPreviousChar):
-         self.GotoPrevChar()
-      elif event.matches(QKeySequence.MoveToNextLine):
-         self.GotoNextLine()
-      elif event.matches(QKeySequence.MoveToPreviousLine):
-         self.GotoPrevLine()
-      elif event.matches(QKeySequence.MoveToNextPage):
-         for i in range(5):
-            self.GotoNextLine()
-      elif event.matches(QKeySequence.MoveToPreviousPage):
-         for i in range(5):
-            self.GotoPrevLine()
-      elif event.matches(QKeySequence.MoveToEndOfLine):
-         self.CursorPosition += len(self.CurrentLine) - self.CursorCol + 1
-      elif event.matches(QKeySequence.MoveToStartOfLine):
-         self.CursorPosition -= self.CursorCol - 1
-      elif event.matches(QKeySequence.Delete):
-         self.deleteChar()
-      elif event.matches(QKeySequence.InsertParagraphSeparator):
-         self.insertText('\n')
-      elif event.key() == Qt.Key_Backspace:
-         self.CursorPosition -= 1
-         self.deleteChar()
-      else:
-         char = event.text()
-         if char:
-            self.insertText(char)
-      self.update()
-
-    def mousePressEvent(self, event):
-        pos = event.pos()
-        if pos.x() > self.xposTXT and pos.x():
-            c = round((pos.x() - self.xposTXT) / self.charWidth)
-            r = int(pos.y() / self.charHeight) + 1
-            self.setRowCol(r, c)
-        super().mousePressEvent(event)
-
-    def adjust(self):
-        metrics = self.fontMetrics()
-        self.charHeight = metrics.height()
-        self.charWidth = metrics.width('x')
-        self.charDescent = metrics.descent()
-        self.xposERR = GAP
-        self.xposLNA = self.xposERR + GAP + self.errorPixmap.width()
-        self.xposTXT = self.xposLNA + 4 * self.charWidth + GAP
-        self.xposEnd = self.xposTXT + self.charWidth * 80
-        self.setMinimumWidth(self.xposEnd)
-        txt = self.src.split('\n')
-        self.setMinimumHeight(self.charHeight * len(txt))
-        self.update()
-
-class CodeEdit(QScrollArea):
-    def __init__(self):
-        super().__init__()
-        self.ic = InnerCode(self)
-        self.textChanged = self.ic.textChanged
-        self.setWidget(self.ic)
-        self.setWidgetResizable(True)
-        self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
-        self.setFocusPolicy(Qt.NoFocus)
-        self.showRow = self.ic.showRow
-        self.setRowCol = self.ic.setRowCol
-        self.FileName = None
-    Source = property(lambda s: s.ic.getSource(), lambda s, v: s.ic.setSource(v))
-
-    def setErrors(self, el):
-        self.ic.setErrors(el)
-
-    def setFocus(self):
-        self.ic.setFocus()
-        super().setFocus()
-
-    def setFileName(self, fn):
-        self.filename = fn
-        if fn:
-            fn = os.path.basename(fn)
-        else:
-            fn = 'Untitled'
-        self.setWindowTitle(fn)
-
-    def getFileName(self):
-        return self.filename
-    FileName = property(getFileName, setFileName)
-
-    def save(self):
-        if self.FileName:
-            s = self.Source
-            with open(self.FileName, 'w') as f:
-                f.write(s)
-
-
-if __name__ == '__main__':
-    app = QApplication(sys.argv)
-    ce = CodeEdit()
-    ce.show()
-    src = ''.join(inspect.getsourcelines(InnerCode)[0])
-    ce.Source = src
-    ce.resize(600, 800)
-    app.exec()
-
--- a/python/codegen.py	Thu Nov 21 15:46:50 2013 +0100
+++ b/python/codegen.py	Sun Nov 24 11:24:15 2013 +0100
@@ -1,30 +1,65 @@
-import ir, target
+import ir
+import target
 from ppci import CompilerError
+import transform
+import canon
 
+
+# TODO: this class could be target independent:
 class CodeGenerator:
-    """ Target independent code generator """
-    def __init__(self, tg):
+    def __init__(self, outs, target):
+        # TODO: schedule traces in better order.
+        # This is optional!
         assert isinstance(tg, target.Target)
-        self.tg = tg
+        self.target = target
+        self.ins_sel = ArmInstructionSelector()
+        self.ra = registerallocator.RegisterAllocator()
+        self.outs = outs
+        self.outs.getSection('code').address = 0x08000000
+        self.outs.getSection('data').address = 0x20000000
+
+    def generateFunc(self, irfunc):
+        """ Generate code for one function into a frame """
+        # Cleanup function:
+        transform.removeEmptyBlocks(irfunc)
+
+        # Create a frame for this function:
+        frame = ArmFrame(irfunc.name)
 
-    def tryMap(self, ii):
-        for mi in self.tg.instructions:
-            if mi.irpattern is ii:
-                return mi.FromIr(ii)
-        raise CompilerError('Cannot map {0}'.format(ii))
+        # Canonicalize the intermediate language:
+        canon.make(irfunc, frame)
+        self.ins_sel.munchFunction(irfunc, frame)
         
+        # Do register allocation:
+        self.ra.allocFrame(frame)
+        # TODO: Peep-hole here?
+
+        # Can we materialize here??
+
+        # Add label and return and stack adjustment:
+        frame.EntryExitGlue3()
+
+        # Materialize assembly
+        # Materialize the register allocated instructions into a stream of
+        # real instructions.
+        frame.lower_to(self.outs)
+        return frame
+
     def generate(self, ircode):
         assert isinstance(ircode, ir.Module)
-        obj = object()
-        for gvar in ircode.Variables:
-            print(gvar)
-            raise Exception() # TODO
-        for f in ircode.Functions:
-            for bb in f.Blocks:
-                for ins in bb.Instructions:
-                    # Instruction selection:
-                    #mi = self.tryMap(ins)
-                    pass
-        return obj
-                        
+        self.outs.selectSection('code')
+        # assembly glue to make it work:
+        # TODO: this must be in source code, not in compiler
+        self.outs.emit(arm.dcd_ins(Imm32(0x20000678)))   # initial SP
+        self.outs.emit(arm.dcd_ins(Imm32(0x08000009)))   # reset vector
+        self.outs.emit(arm.b_ins(LabelRef('main')))
 
+        # Munch program into a bunch of frames. One frame per function.
+        # Each frame has a flat list of abstract instructions.
+        # Generate code for all functions:
+        self.frames = [self.generateFunc(func) for func in ircode.Functions]
+
+        # TODO: fixup references, do this in another way?
+        self.outs.backpatch()
+        self.outs.backpatch()  # Why two times?
+        return self.frames
--- a/python/codegenarm.py	Thu Nov 21 15:46:50 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,281 +0,0 @@
-import logging
-import ir
-from target import Label, Comment, Alignment, LabelRef, Imm32, DebugInfo, Nop
-from target import Imm3
-import cortexm3 as arm
-from ppci import CompilerError
-import registerallocator
-from instructionselector import InstructionSelector
-import irmach
-from irmach import AbstractInstruction as makeIns
-import canon
-import transform
-import asm
-
-class ArmFrame(irmach.Frame):
-    """
-      Arm specific frame for functions.
-    """
-    def __init__(self, name):
-        # We use r7 as frame pointer.
-        super().__init__(name)
-        self.regs = [arm.r0, arm.r1, arm.r2, arm.r3, arm.r4, arm.r5, arm.r6]
-        self.rv = ir.Temp('special_RV')
-        self.p1 = ir.Temp('special_P1')
-        self.p2 = ir.Temp('special_P2')
-        self.p3 = ir.Temp('special_P3')
-        self.p4 = ir.Temp('special_P4')
-        self.fp = ir.Temp('special_FP')
-        # Pre-colored registers:
-        self.tempMap = {}
-        self.tempMap[self.rv] = arm.r0
-        self.tempMap[self.p1] = arm.r1
-        self.tempMap[self.p2] = arm.r2
-        self.tempMap[self.p3] = arm.r3
-        self.tempMap[self.p4] = arm.r4
-        self.tempMap[self.fp] = arm.r7
-        self.locVars = {}
-        self.parMap = {}
-        # Literal pool:
-        self.constants = []
-
-    def argLoc(self, pos):
-        """
-            Gets the function parameter location in IR-code format.
-        """
-        if pos == 0:
-            return self.p1
-        elif pos == 1:
-            return self.p2
-        elif pos == 2:
-            return self.p3
-        elif pos == 3:
-            return self.p4
-        else:
-            raise NotImplementedError('No more than 4 parameters implemented')
-
-    def allocVar(self, lvar):
-        if lvar not in self.locVars:
-            self.locVars[lvar] = self.stacksize
-            self.stacksize = self.stacksize + 4
-        return self.locVars[lvar]
-
-    def addConstant(self, value):
-        lab_name = '{}_literal_{}'.format(self.name, len(self.constants))
-        self.constants.append((lab_name, value))
-        return lab_name
-
-    def EntryExitGlue3(self):
-        """
-            Add code for the prologue and the epilogue. Add a label, the
-            return instruction and the stack pointer adjustment for the frame.
-        """
-        self.instructions.insert(0, makeIns(arm.Label(self.name)))
-        self.instructions.insert(1, makeIns(arm.push_ins(arm.RegisterSet({arm.lr, arm.r7}))))
-        # Reserve stack space for locals:
-        self.instructions.insert(2, makeIns(arm.subspsp_ins(arm.sp, arm.sp, arm.Imm7(self.stacksize))))
-        # Setup frame pointer:
-        self.instructions.insert(3, makeIns(arm.movregreg_ext_ins(arm.r7, arm.sp)))
-        # Stack grows downwards
-        self.instructions.append(makeIns(arm.addspsp_ins(arm.sp, arm.sp, arm.Imm7(self.stacksize))))
-        self.instructions.append(makeIns(arm.pop_ins(arm.RegisterSet({arm.pc, arm.r7}))))
-        # Add constant literals:
-        self.instructions.append(makeIns(Alignment(4))) # Align at 4 bytes
-        for ln, v in self.constants:
-            self.instructions.append(makeIns(arm.Label(ln)))
-            self.instructions.append(makeIns(arm.dcd_ins(v)))
-
-
-class ArmInstructionSelector(InstructionSelector):
-
-    """ Instruction selector for the arm architecture """
-    def munchExpr(self, e):
-        if isinstance(e, ir.Alloc):
-            return 0
-        elif isinstance(e, ir.Binop) and e.operation == '+' and \
-            isinstance(e.b, ir.Const) and e.b.value < 8:
-            a = self.munchExpr(e.a)
-            d = self.newTmp()
-            c = Imm3(e.b.value)
-            self.emit(arm.addregregimm3_ins, others=[c], dst=[d], src=[a])
-            return d
-        elif isinstance(e, ir.Binop) and e.operation == '+':
-            a = self.munchExpr(e.a)
-            b = self.munchExpr(e.b)
-            d = self.newTmp()
-            self.emit(arm.addregs_ins, dst=[d], src=[a, b])
-            return d
-        elif isinstance(e, ir.Binop) and e.operation == '-' and \
-            isinstance(e.b, ir.Const) and e.b.value < 8:
-            a = self.munchExpr(e.a)
-            d = self.newTmp()
-            c = Imm3(e.b.value)
-            self.emit(arm.subregregimm3_ins, others=[c], dst=[d], src=[a])
-            return d
-        elif isinstance(e, ir.Binop) and e.operation == '-':
-            a = self.munchExpr(e.a)
-            b = self.munchExpr(e.b)
-            d = self.newTmp()
-            self.emit(arm.subregs_ins, dst=[d], src=[a, b])
-            return d
-        elif isinstance(e, ir.Binop) and e.operation == '|':
-            a = self.munchExpr(e.a)
-            b = self.munchExpr(e.b)
-            d = self.newTmp()
-            self.move(d, a)
-            self.emit(arm.orrregs_ins, dst=[], src=[b, d])
-            return d
-        elif isinstance(e, ir.Binop) and e.operation == '<<':
-            a = self.munchExpr(e.a)
-            b = self.munchExpr(e.b)
-            d = self.newTmp()
-            self.move(d, a)
-            self.emit(arm.lslregs_ins, dst=[], src=[b, d]) # TODO: is d a source variable?
-            return d
-        elif isinstance(e, ir.Binop) and e.operation == '*':
-            a = self.munchExpr(e.a)
-            b = self.munchExpr(e.b)
-            d = self.newTmp()
-            self.move(d, a)
-            # this mul instruction has operands swapped:
-            self.emit(arm.mulregreg_ins, dst=[d], src=[b, d])
-            return d
-        elif isinstance(e, ir.Const) and e.value < 256:
-            d = self.newTmp()
-            self.emit(arm.mov_imm8_ins, others=[arm.Imm8(e.value)], dst=[d])
-            return d
-        elif isinstance(e, ir.Const) and e.value < (2**31):
-            d = self.newTmp()
-            ln = LabelRef(self.frame.addConstant(e.value))
-            self.emit(arm.ldr_pcrel, others=[ln], dst=[d])
-            return d
-        elif isinstance(e, ir.Mem) and isinstance(e.e, ir.Binop) and \
-                e.e.operation == '+' and isinstance(e.e.b, ir.Const):
-            base = self.munchExpr(e.e.a)
-            d = self.newTmp()
-            c = e.e.b.value
-            self.emit(arm.loadimm5_ins, others=[c], src=[base], dst=[d])
-            return d
-        elif isinstance(e, ir.Mem):
-            # Load from memory
-            base = self.munchExpr(e.e)
-            d = self.newTmp()
-            self.emit(arm.loadimm5_ins, others=[0], src=[base], dst=[d])
-            return d
-        elif isinstance(e, ir.Temp):
-            return e
-        elif isinstance(e, ir.Call):
-            # Move arguments into proper locations:
-            reguses = []
-            for i, a in enumerate(e.arguments):
-                loc = self.frame.argLoc(i)
-                m = ir.Move(loc, a)
-                self.munchStm(m)
-                if isinstance(loc, ir.Temp):
-                    reguses.append(loc)
-            self.emit(arm.bl_ins(LabelRef(e.f.name)), src=reguses, dst=[self.frame.rv])
-            d = self.newTmp()
-            self.move(d, self.frame.rv)
-            return d
-        else:
-            raise NotImplementedError('Expr --> {}'.format(e))
-
-    def munchStm(self, s):
-        if isinstance(s, ir.Terminator):
-            pass
-        elif isinstance(s, ir.Move) and isinstance(s.dst, ir.Mem) and \
-            isinstance(s.dst.e, ir.Binop) and s.dst.e.operation == '+' and \
-            isinstance(s.dst.e.b, ir.Const):
-            a = self.munchExpr(s.dst.e.a)
-            val = self.munchExpr(s.src)
-            c = s.dst.e.b.value
-            self.emit(arm.storeimm5_ins, others=[c], src=[a, val])
-        elif isinstance(s, ir.Move) and isinstance(s.dst, ir.Mem):
-            memloc = self.munchExpr(s.dst.e)
-            val = self.munchExpr(s.src)
-            self.emit(arm.storeimm5_ins, others=[0], src=[memloc, val])
-        elif isinstance(s, ir.Move) and isinstance(s.dst, ir.Temp):
-            val = self.munchExpr(s.src)
-            dreg = s.dst
-            self.move(dreg, val)
-        elif isinstance(s, ir.Exp):
-            # Generate expression code and discard the result.
-            x = self.munchExpr(s.e)
-            self.emit(Nop(), src=[x])
-        elif isinstance(s, ir.Jump):
-            tgt = self.targets[s.target]
-            self.emit(arm.b_ins(LabelRef(s.target.name)), jumps=[tgt])
-        elif isinstance(s, ir.CJump):
-            a = self.munchExpr(s.a)
-            b = self.munchExpr(s.b)
-            self.emit(arm.cmp_ins, src=[a, b])
-            ntgt = self.targets[s.lab_no]
-            ytgt = self.targets[s.lab_yes]
-            jmp_ins = makeIns(arm.b_ins(LabelRef(s.lab_no.name)), jumps=[ntgt])
-            opnames = {'<': arm.blt_ins, '>':arm.bgt_ins, '==':arm.beq_ins}
-            op = opnames[s.cond](LabelRef(s.lab_yes.name))
-            self.emit(op, jumps=[ytgt, jmp_ins]) # Explicitely add fallthrough
-            self.emit2(jmp_ins)
-        else:
-            raise NotImplementedError('Stmt --> {}'.format(s))
-
-    def move(self, dst, src):
-        self.emit(arm.movregreg_ext_ins, src=[src], dst=[dst])
-
-
-# TODO: this class could be target independent:
-class ArmCodeGenerator:
-    def __init__(self, outs):
-        # TODO: schedule traces in better order.
-        # This is optional!
-        self.ins_sel = ArmInstructionSelector()
-        self.ra = registerallocator.RegisterAllocator()
-        self.outs = outs
-        self.outs.getSection('code').address = 0x08000000
-        self.outs.getSection('data').address = 0x20000000
-
-    def generateFunc(self, irfunc):
-        """ Generate code for one function into a frame """
-        # Cleanup function:
-        transform.removeEmptyBlocks(irfunc)
-
-        # Create a frame for this function:
-        frame = ArmFrame(irfunc.name)
-
-        # Canonicalize the intermediate language:
-        canon.make(irfunc, frame)
-        self.ins_sel.munchFunction(irfunc, frame)
-        
-        # Do register allocation:
-        self.ra.allocFrame(frame)
-        # TODO: Peep-hole here?
-
-        # Can we materialize here??
-
-        # Add label and return and stack adjustment:
-        frame.EntryExitGlue3()
-
-        # Materialize assembly
-        # Materialize the register allocated instructions into a stream of
-        # real instructions.
-        frame.lower_to(self.outs)
-        return frame
-
-    def generate(self, ircode):
-        self.outs.selectSection('code')
-        # assembly glue to make it work:
-        # TODO: this must be in source code, not in compiler
-        self.outs.emit(arm.dcd_ins(Imm32(0x20000678))) # initial SP
-        self.outs.emit(arm.dcd_ins(Imm32(0x08000009))) # reset vector
-        self.outs.emit(arm.b_ins(LabelRef('main')))
-
-        # Munch program into a bunch of frames. One frame per function.
-        # Each frame has a flat list of abstract instructions.
-        # Generate code for all functions:
-        self.frames = [self.generateFunc(func) for func in ircode.Functions]
-
-        # TODO: fixup references, do this in another way?
-        self.outs.backpatch()
-        self.outs.backpatch()
-        return self.frames
-
--- a/python/cortexm3.py	Thu Nov 21 15:46:50 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,757 +0,0 @@
-import struct
-import types
-from target import Register, Instruction, Target, Imm8, Label, Imm3, LabelRef
-from target import Imm32, Imm7
-from asmnodes import ASymbol, ANumber, AUnop, ABinop
-from ppci import CompilerError
-import ir
-
-"""
-    ARM target description.
-"""
-
-# TODO: encode this in DSL (domain specific language)
-# TBD: is this required?
-
-def u16(h):
-    return struct.pack('<H', h)
-
-def u32(x):
-    return struct.pack('<I', x)
-
-armtarget = Target('arm')
-
-class ArmRegister(Register):
-    def __init__(self, num, name):
-        super().__init__(name)
-        self.num = num
-
-    def __repr__(self):
-        return self.name
-
-    @classmethod
-    def Create(cls, vop):
-        if type(vop) is ASymbol:
-            name = vop.name
-            regs = {}
-            for r in armtarget.registers:
-                regs[r.name] = r
-            if name in regs:
-                r = regs[name]
-                if isinstance(r, cls):
-                    return r
-
-
-class Reg8Op(ArmRegister):
-    pass
-
-
-class Reg16Op(ArmRegister):
-    pass
-
-
-class RegSpOp:
-    @classmethod
-    def Create(cls, vop):
-        if type(vop) is ASymbol:
-            if vop.name.lower() == 'sp':
-                return cls()
-
-def getRegNum(n):
-    for r in armtarget.registers:
-        if r.num == n:
-            return r
-
-def getRegisterRange(n1, n2):
-    regs = []
-    if n1.num < n2.num:
-        for n in range(n1.num, n2.num + 1):
-            r = getRegNum(n)
-            assert r
-            regs.append(r)
-    return regs
-
-def isRegOffset(regname, x, y):
-    if type(x) is ASymbol and type(y) is ANumber and x.name.upper() == regname:
-        return y.number
-    elif type(y) is ASymbol and type(x) is ANumber and y.name.upper() == regname:
-        return x.number
-    
-
-class MemRegXRel:
-    def __init__(self, offset):
-        assert offset % 4 == 0
-        self.offset = offset
-
-    def __repr__(self):
-        return '[{}, #{}]'.format(self.regname, self.offset)
-
-    @classmethod
-    def Create(cls, vop):
-        if type(vop) is AUnop and vop.operation == '[]' and type(vop.arg) is ABinop and vop.arg.op == '+':
-            vop = vop.arg # descent
-            offset = isRegOffset(cls.regname, vop.arg1, vop.arg2)
-            if type(offset) is int:
-                if offset % 4 == 0:
-                    offset = vop.arg2.number
-                    return cls(offset)
-            elif type(vop) is ASymbol and vop.name.upper() == self.regname:
-                return cls(0)
-
-
-class MemSpRel(MemRegXRel):
-    regname = 'SP'
-
-
-class MemR8Rel:
-    def __init__(self, basereg, offset):
-        assert type(basereg) is Reg8Op
-        assert type(offset) is int
-        self.basereg = basereg
-        self.offset = offset
-
-    def __repr__(self):
-        return '[{}, #{}]'.format(self.basereg, self.offset)
-
-    @classmethod
-    def Create(cls, vop):
-        if type(vop) is AUnop and vop.operation == '[]':
-            vop = vop.arg # descent
-            if type(vop) is ABinop:
-                if vop.op == '+' and type(vop.arg1) is ASymbol and type(vop.arg2) is ANumber:
-                    offset = vop.arg2.number
-                    if offset > 120:
-                        return
-                    basereg = Reg8Op.Create(vop.arg1)
-                    if not basereg:
-                        return
-                else:
-                    return
-            elif type(vop) is ASymbol:
-                offset = 0
-                basereg = Reg8Op.Create(vop)
-                if not basereg:
-                    return
-            else:
-                return
-            return cls(getRegNum(basereg.num), offset)
-
-class RegisterSet:
-    def __init__(self, regs):
-        assert type(regs) is set
-        self.regs = regs
-
-    def __repr__(self):
-        return ','.join([str(r) for r in self.regs])
-
-    @classmethod
-    def Create(cls, vop):
-        assert type(vop) is AUnop and vop.operation == '{}'
-        assert type(vop.arg) is list
-        regs = set()
-        for arg in vop.arg:
-            if type(arg) is ASymbol:
-                reg = ArmRegister.Create(arg)
-                if not reg:
-                    return
-                regs.add(reg)
-            elif type(arg) is ABinop and arg.op == '-':
-                reg1 = ArmRegister.Create(arg.arg1)
-                reg2 = ArmRegister.Create(arg.arg2)
-                if not reg1:
-                    return
-                if not reg2:
-                    return
-                for r in getRegisterRange(reg1, reg2):
-                    regs.add(r)
-            else:
-                raise Exception('Cannot be')
-        return cls(regs)
-
-    def registerNumbers(self):
-        return [r.num for r in self.regs]
-
-def makeReg(cls, num, name):
-    r = cls(num, name)
-    armtarget.registers.append(r)
-    return r
-
-# 8 bit registers:
-r0 = makeReg(Reg8Op, 0, 'r0')
-r1 = makeReg(Reg8Op, 1, 'r1')
-r2 = makeReg(Reg8Op, 2, 'r2')
-r3 = makeReg(Reg8Op, 3, 'r3')
-r4 = makeReg(Reg8Op, 4, 'r4')
-r5 = makeReg(Reg8Op, 5, 'r5')
-r6 = makeReg(Reg8Op, 6, 'r6')
-r7 = makeReg(Reg8Op, 7, 'r7')
-# Other registers:
-# TODO
-sp = makeReg(ArmRegister, 13, 'sp')
-lr = makeReg(ArmRegister, 14, 'lr')
-pc = makeReg(ArmRegister, 15, 'pc')
-
-# Sanity checks:
-assert isinstance(sp, ArmRegister)
-assert isinstance(r3, ArmRegister)
-assert ArmRegister.Create(ASymbol('r3')) is r3
-assert ArmRegister.Create(ASymbol('sp')) is sp
-
-
-class ArmInstruction(Instruction):
-    pass
-
-
-@armtarget.instruction
-class dcd_ins(ArmInstruction):
-    mnemonic = 'dcd'
-    operands = (Imm32,)
-    def __init__(self, expr):
-        if isinstance(expr, Imm32):
-            self.expr = expr.imm
-            self.label = None
-        elif isinstance(expr, LabelRef):
-            self.expr = 0
-            self.label = expr
-        elif isinstance(expr, int):
-            self.expr = expr
-            self.label = None
-        else:
-            raise NotImplementedError()
-
-    def resolve(self, f):
-        if self.label:
-            self.expr = f(self.label.name)
-
-    def encode(self):
-        return u32(self.expr)
-
-    def __repr__(self):
-        return 'DCD 0x{0:X}'.format(self.expr)
-
-
-@armtarget.instruction
-class nop_ins(ArmInstruction):
-    mnemonic = 'nop'
-    operands = tuple()
-
-    def encode(self):
-        return bytes()
-
-    def __repr__(self):
-        return 'NOP'
-
-
-# Memory related
-
-class LS_imm5_base(ArmInstruction):
-    """ ??? Rt, [Rn, imm5] """
-    operands = (Reg8Op, MemR8Rel)
-    def __init__(self, rt, memop):
-        assert memop.offset % 4 == 0
-        self.imm5 = memop.offset >> 2
-        self.rn = memop.basereg.num
-        self.rt = rt
-        self.memloc = memop
-        assert self.rn < 8
-        assert self.rt.num < 8
-
-    def encode(self):
-        Rn = self.rn
-        Rt = self.rt.num
-        imm5 = self.imm5
-
-        h = (self.opcode << 11) | (imm5 << 6) | (Rn << 3) | Rt
-        return u16(h)
-
-
-    def __repr__(self):
-        return '{} {}, {}'.format(self.mnemonic, self.rt, self.memloc)
-
-
-@armtarget.instruction
-class storeimm5_ins(LS_imm5_base):
-    mnemonic = 'STR'
-    opcode = 0xC
-
-    @classmethod
-    def fromim(cls, im):
-        mem = MemR8Rel(im.src[0], im.others[0])
-        return cls(im.src[1], mem)
-
-
-@armtarget.instruction
-class loadimm5_ins(LS_imm5_base):
-    mnemonic = 'LDR'
-    opcode = 0xD
-
-    @classmethod
-    def fromim(cls, im):
-        mem = MemR8Rel(im.src[0], im.others[0])
-        return cls(im.dst[0], mem)
-
-class ls_sp_base_imm8(ArmInstruction):
-    operands = (Reg8Op, MemSpRel)
-    def __init__(self, rt, memop):
-        self.rt = rt
-        self.offset = memop.offset
-
-    def encode(self):
-        rt = self.rt.num
-        assert rt < 8
-        imm8 = self.offset >> 2
-        assert imm8 < 256
-        h = (self.opcode << 8) | (rt << 8) | imm8
-        return u16(h)
-
-    def __repr__(self):
-        return '{} {}, [sp,#{}]'.format(self.mnemonic, self.rt, self.offset)
-
-def align(x, m):
-    while ((x % m) != 0):
-        x = x + 1
-    return x
-
-
-@armtarget.instruction
-class ldr_pcrel(ArmInstruction):
-    """ ldr Rt, LABEL, load value from pc relative position """
-    mnemonic = 'ldr'
-    operands = (Reg8Op, LabelRef)
-    def __init__(self, rt, label):
-        assert isinstance(label, LabelRef)
-        self.rt = rt
-        self.label = label
-        self.offset = 0
-
-    @classmethod
-    def fromim(cls, im):
-        return cls(im.dst[0], im.others[0])
-
-    def resolve(self, f):
-        la = f(self.label.name)
-        sa = align(self.address + 2, 4)
-        self.offset = (la - sa)
-        if self.offset < 0:
-            self.offset = 0
-
-    def encode(self):
-        rt = self.rt.num
-        assert rt < 8
-        assert self.offset % 4 == 0
-        imm8 = self.offset >> 2
-        assert imm8 < 256
-        assert imm8 >= 0
-        h = (0x9 << 11) | (rt << 8) | imm8
-        return u16(h)
-
-    def __repr__(self):
-        return 'LDR {}, {}'.format(self.rt, self.label.name)
-
-
-@armtarget.instruction
-class ldr_sprel(ls_sp_base_imm8):
-    """ ldr Rt, [SP, imm8] """
-    mnemonic = 'LDR'
-    opcode = 0x98
-
-
-@armtarget.instruction
-class str_sprel(ls_sp_base_imm8):
-    """ str Rt, [SP, imm8] """
-    mnemonic = 'STR'
-    opcode = 0x90
-
-
-@armtarget.instruction
-class mov_imm8_ins(ArmInstruction):
-    """ mov Rd, imm8, move immediate value into register """
-    mnemonic = 'mov'
-    opcode = 4 # 00100 Rd(3) imm8
-    operands = (Reg8Op, Imm8)
-    def __init__(self, rd, imm):
-        if type(imm) is int:
-            imm = Imm8(imm)
-        assert type(imm) is Imm8
-        self.imm = imm.imm
-        assert type(rd) is Reg8Op, str(type(rd))
-        self.rd = rd
-
-    @classmethod
-    def fromim(cls, im):
-        return cls(im.dst[0], im.others[0])
-
-    def encode(self):
-        rd = self.rd.num
-        opcode = self.opcode
-        imm8 = self.imm
-        h = (opcode << 11) | (rd << 8) | imm8
-        return u16(h)
-
-    def __repr__(self):
-        return 'MOV {}, {}'.format(self.rd, self.imm)
-
-
-
-# Arithmatics:
-
-
-
-class regregimm3_base(ArmInstruction):
-    operands = (Reg8Op, Reg8Op, Imm3)
-    def __init__(self, rd, rn, imm3):
-        self.rd = rd
-        self.rn = rn
-        assert type(imm3) is Imm3
-        self.imm3 = imm3
-
-    @classmethod
-    def fromim(cls, im):
-        return cls(im.dst[0], im.src[0], im.others[0])
-
-    def encode(self):
-        rd = self.rd.num
-        rn = self.rn.num
-        imm3 = self.imm3.imm
-        opcode = self.opcode
-        h = (self.opcode << 9) | (imm3 << 6) | (rn << 3) | rd
-        return u16(h)
-
-    def __repr__(self):
-        return '{} {}, {}, {}'.format(self.mnemonic, self.rd, self.rn, self.imm3.imm)
-
-@armtarget.instruction
-class addregregimm3_ins(regregimm3_base):
-    """ add Rd, Rn, imm3 """
-    mnemonic = 'add'
-    opcode = 0b0001110
-
-
-@armtarget.instruction
-class subregregimm3_ins(regregimm3_base):
-    """ sub Rd, Rn, imm3 """
-    mnemonic = 'sub'
-    opcode = 0b0001111
-
-
-class regregreg_base(ArmInstruction):
-    """ ??? Rd, Rn, Rm """
-    operands = (Reg8Op, Reg8Op, Reg8Op)
-    def __init__(self, rd, rn, rm):
-        self.rd = rd
-        self.rn = rn
-        self.rm = rm
-
-    @classmethod
-    def fromim(cls, im):
-        return cls(im.dst[0], im.src[0], im.src[1])
-
-    def encode(self):
-        rd = self.rd.num
-        rn = self.rn.num
-        rm = self.rm.num
-        h = (self.opcode << 9) | (rm << 6) | (rn << 3) | rd
-        return u16(h)
-
-    def __repr__(self):
-        return '{} {}, {}, {}'.format(self.mnemonic, self.rd, self.rn, self.rm)
-
-
-@armtarget.instruction
-class addregs_ins(regregreg_base):
-    mnemonic = 'ADD'
-    opcode = 0b0001100
-
-
-@armtarget.instruction
-class subregs_ins(regregreg_base):
-    mnemonic = 'SUB'
-    opcode = 0b0001101
-
-
-
-@armtarget.instruction
-class movregreg_ext_ins(ArmInstruction):
-    """ mov rd, rm """
-    operands = (ArmRegister, ArmRegister)
-    mnemonic = 'MOV'
-    def __init__(self, rd, rm):
-        self.rd = rd
-        self.rm = rm
-
-    @classmethod
-    def fromim(cls, im):
-        return cls(im.dst[0], im.src[0])
-
-    def encode(self):
-        Rd = self.rd.num & 0x7
-        D = (self.rd.num >> 3) & 0x1
-        Rm = self.rm.num
-        opcode = 0b01000110
-        return u16((opcode << 8) | (D << 7) |(Rm << 3) | Rd)
-
-    def __repr__(self):
-        return '{} {}, {}'.format(self.mnemonic, self.rd, self.rm)
-        
-
-@armtarget.instruction
-class mulregreg_ins(ArmInstruction):
-    """ mul Rn, Rdm """
-    operands = (Reg8Op, Reg8Op)
-    mnemonic = 'MUL'
-    def __init__(self, rn, rdm):
-        self.rn = rn
-        self.rdm = rdm
-
-    @classmethod
-    def fromim(cls, im):
-        assert im.src[1] is im.dst[0]
-        return cls(im.src[0], im.dst[0])
-
-    def encode(self):
-        rn = self.rn.num
-        rdm = self.rdm.num
-        opcode = 0b0100001101
-        h = (opcode << 6) | (rn << 3) | rdm
-        return u16(h)
-
-    def __repr__(self):
-        return '{} {}, {}'.format(self.mnemonic, self.rn, self.rdm)
-
-
-class regreg_base(ArmInstruction):
-    """ ??? Rdn, Rm """
-    operands = (Reg8Op, Reg8Op)
-    # TODO: integrate with the code gen interface:
-    src = (0, 1)
-    dst = (0,)
-    def __init__(self, rdn, rm):
-        self.rdn = rdn
-        self.rm = rm
-
-    @classmethod
-    def fromim(cls, im):
-        return cls(im.src[0], im.src[1])
-
-    def encode(self):
-        rdn = self.rdn.num
-        rm = self.rm.num
-        h = (self.opcode << 6) | (rm << 3) | rdn
-        return u16(h)
-
-    def __repr__(self):
-        return '{} {}, {}'.format(self.mnemonic, self.rdn, self.rm)
-
-
-@armtarget.instruction
-class movregreg_ins(regreg_base):
-    """ mov Rd, Rm (reg8 operands) """
-    # TODO: match this:
-    pattern = ir.Move(ir.Temp, ir.Temp)
-    mnemonic = 'mov'
-    opcode = 0
-
-
-@armtarget.instruction
-class andregs_ins(regreg_base):
-    mnemonic = 'AND'
-    opcode = 0b0100000000
-
-
-@armtarget.instruction
-class orrregs_ins(regreg_base):
-    mnemonic = 'ORR'
-    opcode = 0b0100001100
-
-
-@armtarget.instruction
-class cmp_ins(regreg_base):
-    mnemonic = 'CMP'
-    opcode = 0b0100001010
-
-
-@armtarget.instruction
-class lslregs_ins(regreg_base):
-    mnemonic = 'LSL'
-    opcode = 0b0100000010
-
-@armtarget.instruction
-class cmpregimm8_ins(ArmInstruction):
-    """ cmp Rn, imm8 """
-    mnemonic = 'cmp'
-    opcode = 5 # 00101
-    operands = (Reg8Op, Imm8)
-    def __init__(self, rn, imm):
-        self.rn = rn
-        self.imm = imm
-    def encode(self):
-        rn = self.rn.num
-        imm = self.imm.imm
-        opcode = self.opcode
-        h = (opcode << 11) | (rn << 8) | imm
-        return u16(h)
-
-
-# Jumping:
-
-def wrap_negative(x, bits):
-    b = struct.unpack('<I', struct.pack('<i', x))[0]
-    mask = (1 << bits) - 1
-    return b & mask
-
-class jumpBase_ins(ArmInstruction):
-    operands = (LabelRef,)
-    def __init__(self, target_label):
-        assert type(target_label) is LabelRef
-        self.target = target_label
-        self.offset = 0
-
-    def resolve(self, f):
-        la = f(self.target.name)
-        sa = self.address + 4
-        self.offset = (la - sa)
-
-    def __repr__(self):
-        return '{} {}'.format(self.mnemonic, self.target.name)
-
-
-@armtarget.instruction
-class b_ins(jumpBase_ins):
-    mnemonic = 'B'
-    def encode(self):
-        imm11 = wrap_negative(self.offset >> 1, 11)
-        h = (0b11100 << 11) | imm11 # | 1 # 1 to enable thumb mode
-        return u16(h)
-
-
-@armtarget.instruction
-class bl_ins(jumpBase_ins):
-    mnemonic = 'BL'
-    def encode(self):
-        imm32 = wrap_negative(self.offset >> 1, 32)
-        imm11 = imm32 & 0x7FF
-        imm10 = (imm32 >> 11) & 0x3FF
-        j1 = 1 # TODO: what do these mean?
-        j2 = 1
-        s = (imm32 >> 24) & 0x1
-        h1 = (0b11110 << 11) | (s << 10) | imm10 
-        h2 = (0b1101 << 12) | (j1 << 13) | (j2 << 11) | imm11
-        return u16(h1) + u16(h2)
-
-
-class cond_base_ins(jumpBase_ins):
-    def encode(self):
-        imm8 = wrap_negative(self.offset >> 1, 8)
-        h = (0b1101 << 12) | (self.cond << 8) | imm8
-        return u16(h)
-
-
-@armtarget.instruction
-class beq_ins(cond_base_ins):
-    mnemonic = 'beq'
-    cond = 0
-
-
-@armtarget.instruction
-class bne_ins(cond_base_ins):
-    mnemonic = 'bne'
-    cond = 1
-
-
-@armtarget.instruction
-class blt_ins(cond_base_ins):
-    mnemonic = 'blt'
-    cond = 0b1011
-
-
-@armtarget.instruction
-class bgt_ins(cond_base_ins):
-    mnemonic = 'bgt'
-    cond = 0b1100
-
-
-@armtarget.instruction
-class push_ins(ArmInstruction):
-    operands = (RegisterSet,)
-    mnemonic = 'push'
-    def __init__(self, regs):
-        assert (type(regs),) == self.operands, (type(regs),)
-        self.regs = regs
-    def __repr__(self):
-        return '{0} {{{1}}}'.format(self.mnemonic, self.regs)
-    def encode(self):
-        reg_list = 0
-        M = 0
-        for n in self.regs.registerNumbers():
-            if n < 8:
-                reg_list |= (1 << n)
-            elif n == 14:
-                M = 1
-            else:
-                raise NotImplementedError('not implemented for this register')
-        h = (0x5a << 9) | (M << 8) | reg_list
-        return u16(h)
-
-
-@armtarget.instruction
-class pop_ins(ArmInstruction):
-    operands = (RegisterSet,)
-    mnemonic = 'pop'
-
-    def __init__(self, regs):
-        self.regs = regs
-
-    def __repr__(self):
-        return '{0} {{{1}}}'.format(self.mnemonic, self.regs)
-
-    def encode(self):
-        reg_list = 0
-        P = 0
-        for n in self.regs.registerNumbers():
-            if n < 8:
-                reg_list |= (1 << n)
-            elif n == 15:
-                P = 1
-            else:
-                raise NotImplementedError('not implemented for this register')
-        h = (0x5E << 9) | (P << 8) | reg_list
-        return u16(h)
-
-
-@armtarget.instruction
-class yield_ins(ArmInstruction):
-    operands = ()
-    mnemonic = 'yield'
-
-    def encode(self):
-        return u16(0xbf10)
-
-# misc:
-
-# add/sub SP:
-class addspsp_base(ArmInstruction):
-    operands = (RegSpOp, RegSpOp, Imm7)
-    def __init__(self, _sp, _sp2, imm7):
-        self.imm7 = imm7.imm
-        assert self.imm7 % 4 == 0
-        self.imm7 >>= 2
-
-    def encode(self):
-        return u16((self.opcode << 7) |self.imm7)
-
-    def __repr__(self):
-        return '{} sp, sp, {}'.format(self.mnemonic, self.imm7 << 2)
-
-@armtarget.instruction
-class addspsp_ins(addspsp_base):
-    mnemonic = 'add'
-    opcode = 0b101100000
-    
-
-@armtarget.instruction
-class subspsp_ins(addspsp_base):
-    mnemonic = 'sub'
-    opcode = 0b101100001
-
-armtarget.check()
-
--- a/python/diagrameditor.py	Thu Nov 21 15:46:50 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,316 +0,0 @@
-#!/usr/bin/python
-
-from PyQt4.QtGui import *
-from PyQt4.QtCore import *
-import sys, json, base64
-
-from diagramitems import Connection, ResizeSelectionHandle, Block, DiagramScene, CodeBlock
-from icons import newicon, saveicon, loadicon
-import diagramitems
-
-"""
- Author: Windel Bouwman
- Year: 2012
- Description: This script implements a diagram editor.
- run with python 3.x as:
-  $ python [thisfile.py]
-"""
-def indent(lines):
-   return ['   ' + line for line in lines]
-
-class ParameterDialog(QDialog):
-   def __init__(self, block, parent = None):
-      super(ParameterDialog, self).__init__(parent)
-      self.block = block
-      self.button = QPushButton('Ok', self)
-      self.nameEdit = QLineEdit(self.block.name)
-      self.codeEdit = QTextEdit(self)
-      self.codeEdit.setPlainText(self.block.code)
-      l = QFormLayout(self)
-      l.addRow('Name:', self.nameEdit)
-      l.addRow('Code:', self.codeEdit)
-      l.addWidget(self.button)
-      self.button.clicked.connect(self.OK)
-   def OK(self):
-      self.block.name = self.nameEdit.text()
-      self.block.code = self.codeEdit.toPlainText()
-      self.close()
-
-class EditorGraphicsView(QGraphicsView):
-   def __init__(self, parent=None):
-      QGraphicsView.__init__(self, parent)
-      self.setDragMode(QGraphicsView.RubberBandDrag)
-      self.delShort = QShortcut(QKeySequence.Delete, self)
-      self._model = None
-      self.treeView = QTreeView()
-      self.treeView.clicked.connect(self.itemActivated)
-   def itemActivated(self, idx):
-      b = idx.internalPointer()
-      s = b.scene()
-      s.clearSelection()
-      b.setSelected(True)
-   def setDiagram(self, d):
-      self.setScene(d)
-      self.delShort.activated.connect(d.deleteItems)
-   def getModel(self): 
-      return self._model
-   def setModel(self, m):
-      self._model = m
-      if m:
-         self.treeView.setModel(m)
-         self.diagram = m.rootDiagram
-         self.model.modelReset.connect(self.treeView.expandAll)
-   model = property(getModel, setModel)
-   diagram = property(lambda s: s.scene(), setDiagram)
-   def save(self):
-      if self.model:
-         if not self.model.filename:
-            self.model.filename = QFileDialog.getSaveFileName(self)
-         if self.model.filename:
-            with open(self.model.filename, 'w') as f:
-               f.write(json.dumps(self.model.Dict, indent=2))
-   def load(self):
-      filename = QFileDialog.getOpenFileName(self)
-      if filename:
-         self.model = loadModel(filename)
-   def newModel(self):
-      self.model = ModelHierarchyModel()
-   def goUp(self):
-      if hasattr(self.diagram, 'containingBlock'):
-         self.diagram = self.diagram.containingBlock.scene()
-         self.zoomAll()
-   def showCode(self):
-      if self.model:
-         c = self.model.gencode()
-         c = '\n'.join(c)
-         d = QDialog()
-         l = QFormLayout(d)
-         codeview = QTextEdit()
-         codeview.setPlainText(c)
-         l.addRow('code', codeview)
-         runButton = QPushButton('Run')
-         outputview = QTextEdit()
-         l.addRow('Output', outputview)
-         l.addWidget(runButton)
-         def print2(txt):
-            txt2 = outputview.toPlainText()
-            outputview.setPlainText(txt2 + '\n' + txt)
-         def runIt():
-            outputview.clear()
-            globs = {'print': print2}
-            exec(codeview.toPlainText(), globs)
-         runButton.clicked.connect(runIt)
-         d.exec_()
-   def zoomAll(self):
-      """ zoom to fit all items """
-      rect = self.diagram.itemsBoundingRect()
-      self.fitInView(rect, Qt.KeepAspectRatio)
-   def wheelEvent(self, event):
-      pos = event.pos()
-      posbefore = self.mapToScene(pos)
-      degrees = event.delta() / 8.0
-      sx = (100.0 + degrees) / 100.0
-      self.scale(sx, sx)
-      event.accept()
-   def dragEnterEvent(self, event):
-      if event.mimeData().hasFormat('component/name'):
-         event.accept()
-   def dragMoveEvent(self, event):
-      if event.mimeData().hasFormat('component/name'): event.accept()
-   def dropEvent(self, event):
-      if event.mimeData().hasFormat('component/name'):
-         name = bytes(event.mimeData().data('component/name')).decode()
-         kind, name = name.split(':')
-         pos = self.mapToScene(event.pos())
-         s = self.scene()
-         if not s:
-            return
-         print(kind, 'name:', name)
-         kind = getattr(diagramitems, kind)
-         print(kind)
-         b = kind(s.uniqify(name))
-         b.setPos(pos)
-         s.addItem(b)
-
-class LibraryModel(QStandardItemModel):
-   mimeTypes = lambda self: ['component/name']
-   def mimeData(self, idxs):
-      mimedata = QMimeData()
-      for idx in idxs:
-         if idx.isValid():
-            txt = self.data(idx, Qt.DisplayRole)
-            mimedata.setData('component/name', txt)
-      return mimedata
-
-class ModelHierarchyModel(QAbstractItemModel):
-   def __init__(self):
-      super(ModelHierarchyModel, self).__init__()
-      self.rootDiagram = DiagramScene()
-      self.rootDiagram.structureChanged.connect(self.handlechange)
-      self.filename = None
-   def handlechange(self):
-      self.modelReset.emit()
-   def setDict(self, d):
-      self.rootDiagram.Dict = d
-      self.modelReset.emit()
-   def getDict(self):
-      return self.rootDiagram.Dict
-   Dict = property(getDict, setDict)
-   def gencode(self):
-      c = ['def topLevel():']
-      c += indent(self.rootDiagram.gencode())
-      c.append('print("Running model")')
-      c.append('topLevel()')
-      c.append('print("Done")')
-      return c
-   def index(self, row, column, parent=None):
-      if parent.isValid():
-         parent = parent.internalPointer().subModel
-      else:
-         parent = self.rootDiagram
-      blocks = sorted(parent.blocks, key=lambda b:  b.name)
-      block = blocks[row]
-      # Store the index to retrieve it later in the parent function.
-      # TODO: solve this in a better way.
-      block.index = self.createIndex(row, column, block)
-      return block.index
-   def parent(self, index):
-      if index.isValid():
-         block = index.internalPointer()
-         if block.scene() == self.rootDiagram:
-            return QModelIndex()
-         else:
-            print(block)
-            outerBlock = block.scene().containingBlock
-            return outerBlock.index
-      print('parent: No valid index')
-   def data(self, index, role):
-      if index.isValid() and role == Qt.DisplayRole:
-         b = index.internalPointer()
-         if index.column() == 0:
-            return b.name
-         elif index.column() == 1:
-            return str(type(b))
-   def headerData(self, section, orientation, role):
-      if orientation == Qt.Horizontal and role == Qt.DisplayRole:
-         if section == 0:
-            return "Element"
-         elif section == 1:
-            return "Type"
-         else:
-            return "x"
-   def rowCount(self, parent):
-      if parent.column() > 0: 
-         return 0
-      if parent.isValid():
-         block = parent.internalPointer()
-         if hasattr(block, 'subModel'):
-            return len(block.subModel.blocks)
-         else:
-            return 0
-      else:
-         return len(self.rootDiagram.blocks)
-   def columnCount(self, parent):
-      return 2
-
-class LibraryWidget(QListView):
-   def __init__(self):
-      super(LibraryWidget, self).__init__(None)
-      self.libraryModel = LibraryModel(self)
-      self.libraryModel.setColumnCount(1)
-      # Create an icon with an icon:
-      pixmap = QPixmap(60, 60)
-      pixmap.fill()
-      painter = QPainter(pixmap)
-      painter.fillRect(10, 10, 40, 40, Qt.blue)
-      painter.setBrush(Qt.yellow)
-      painter.drawEllipse(20, 20, 20, 20)
-      painter.end()
-      # Fill library:
-      for name in ['CodeBlock:codeBlock', 'DiagramBlock:submod', 'Block:blk']:
-         self.libraryModel.appendRow(QStandardItem(QIcon(pixmap), name))
-      self.setModel(self.libraryModel)
-      self.setViewMode(self.IconMode)
-      self.setDragDropMode(self.DragOnly)
-
-def warning(txt):
-   QMessageBox.warning(None, "Warning", txt)
-
-def loadModel(filename):
-   try:
-      m = ModelHierarchyModel()
-      with open(filename, 'r') as f: data = f.read()
-      m.filename = filename
-      m.Dict = json.loads(data)
-      return m
-   except KeyError:
-      warning('Corrupt model: {0}'.format(filename))
-   except ValueError:
-      warning('Corrupt model: {0}'.format(filename))
-   except FileNotFoundError:
-      warning('File [{0}] not found'.format(filename))
-
-class Main(QMainWindow):
-   def __init__(self):
-      super(Main, self).__init__(None)
-      self.editor = EditorGraphicsView()
-      self.setCentralWidget(self.editor)
-      self.setWindowTitle("Diagram editor")
-      def buildIcon(b64):
-         icon = base64.decodestring(b64)
-         pm = QPixmap()
-         pm.loadFromData(icon)
-         return QIcon(pm)
-      toolbar = self.addToolBar('Tools')
-      toolbar.setObjectName('Tools')
-      def act(name, shortcut, callback, icon=None):
-         a = QAction(icon, name, self) if icon else QAction(name, self)
-         a.setShortcuts(shortcut)
-         a.triggered.connect(callback)
-         toolbar.addAction(a)
-      act('New', QKeySequence.New, self.editor.newModel, buildIcon(newicon))
-      act('Save', QKeySequence.Save, self.editor.save, buildIcon(saveicon))
-      act('Load', QKeySequence.Open, self.editor.load, buildIcon(loadicon))
-      act('Full screen', QKeySequence("F11"), self.toggleFullScreen)
-      act('Fit in view', QKeySequence("F8"), self.editor.zoomAll)
-      act('Go up', QKeySequence(Qt.Key_Up), self.editor.goUp)
-      act('Model code', QKeySequence("F7"), self.editor.showCode)
-      def addDock(name, widget):
-         dock = QDockWidget(name, self)
-         dock.setObjectName(name)
-         dock.setWidget(widget)
-         self.addDockWidget(Qt.LeftDockWidgetArea, dock)
-      addDock('Library', LibraryWidget())
-      addDock('Model tree', self.editor.treeView)
-      self.settings = QSettings('windelsoft', 'diagrameditor')
-      self.loadSettings()
-   def toggleFullScreen(self):
-      self.setWindowState(self.windowState() ^ Qt.WindowFullScreen)
-      self.editor.zoomAll()
-   def loadSettings(self):
-      if self.settings.contains('mainwindowstate'):
-         self.restoreState(self.settings.value('mainwindowstate'))
-      if self.settings.contains('mainwindowgeometry'):
-         self.restoreGeometry(self.settings.value('mainwindowgeometry'))
-      if self.settings.contains('openedmodel'):
-         modelfile = self.settings.value('openedmodel')
-         self.editor.model = loadModel(modelfile)
-   def closeEvent(self, ev):
-      self.settings.setValue('mainwindowstate', self.saveState())
-      self.settings.setValue('mainwindowgeometry', self.saveGeometry())
-      if self.editor.model and self.editor.model.filename:
-         self.settings.setValue('openedmodel', self.editor.model.filename)
-         # TODO: ask for save of opened files
-      else:
-         self.settings.remove('openedmodel')
-      ev.accept()
-
-if __name__ == '__main__':
-   if sys.version_info.major != 3:
-      print('Please use python 3.x')
-      sys.exit(1)
-   app = QApplication(sys.argv)
-   main = Main()
-   main.show()
-   app.exec_()
-
--- a/python/hexedit.py	Thu Nov 21 15:46:50 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,207 +0,0 @@
-#!/usr/bin/python
-
-import sys
-import os
-from PyQt4.QtCore import *
-from PyQt4.QtGui import *
-from PyQt4 import uic
-
-BYTES_PER_LINE, GAP = 8, 12
-
-def clamp(minimum, x, maximum):
-   return max(minimum, min(x, maximum))
-
-def asciiChar(v):
-   if v < 0x20 or v > 0x7e:
-      return '.'
-   else:
-      return chr(v)
-
-class BinViewer(QWidget):
-   """ The view has an address, hex byte and ascii column """
-   def __init__(self, scrollArea):
-      super().__init__(scrollArea)
-      self.scrollArea = scrollArea
-      self.setFont(QFont('Courier', 16))
-      self.setFocusPolicy(Qt.StrongFocus)
-      self.blinkcursor = False
-      self.cursorX = self.cursorY = 0
-      self.scrollArea = scrollArea
-      self.Data = bytearray()
-      self.Offset = 0
-      t = QTimer(self)
-      t.timeout.connect(self.updateCursor)
-      t.setInterval(500)
-      t.start()
-   def updateCursor(self):
-      self.blinkcursor = not self.blinkcursor
-      self.update(self.cursorX, self.cursorY, self.charWidth, self.charHeight)
-   def setCursorPosition(self, position):
-      position = clamp(0, int(position), len(self.Data) * 2 - 1)
-      self.cursorPosition = position
-      x = position % (2 * BYTES_PER_LINE)
-      x = x + int(x / 2) # Create a gap between hex values
-      self.cursorX = self.xposHex + x * self.charWidth
-      y = int(position / (2 * BYTES_PER_LINE))
-      self.cursorY = y * self.charHeight + 2
-      self.blinkcursor = True
-      self.update()
-   def getCursorPosition(self):
-      return self.cursorPosition
-   CursorPosition = property(getCursorPosition, setCursorPosition)
-   def setOffset(self, off):
-      self.offset = off
-      self.update()
-   Offset = property(lambda self: self.offset, setOffset)
-   def paintEvent(self, event):
-      # Helper variables:
-      er = event.rect()
-      chw, chh = self.charWidth, self.charHeight
-      painter = QPainter(self)
-      # Background:
-      painter.fillRect(er, self.palette().color(QPalette.Base))
-      painter.fillRect(QRect(self.xposAddr, er.top(), 8 * chw, er.bottom() + 1), Qt.gray)
-      painter.setPen(Qt.gray)
-      x = self.xposAscii - (GAP / 2)
-      painter.drawLine(x, er.top(), x, er.bottom())
-      x = self.xposEnd - (GAP / 2)
-      painter.drawLine(x, er.top(), x, er.bottom())
-      # first and last index
-      firstIndex = max((int(er.top() / chh) - chh) * BYTES_PER_LINE, 0)
-      lastIndex = max((int(er.bottom() / chh) + chh) * BYTES_PER_LINE, 0)
-      yposStart = int(firstIndex / BYTES_PER_LINE) * chh + chh
-      # Draw contents:
-      painter.setPen(Qt.black)
-      ypos = yposStart
-      for index in range(firstIndex, lastIndex, BYTES_PER_LINE):
-         painter.setPen(Qt.black)
-         painter.drawText(self.xposAddr, ypos, '{0:08X}'.format(index + self.Offset))
-         xpos = self.xposHex
-         xposAscii = self.xposAscii
-         for colIndex in range(BYTES_PER_LINE):
-            if index + colIndex < len(self.Data):
-               b = self.Data[index + colIndex]
-               bo = self.originalData[index + colIndex]
-               if b == bo:
-                  painter.setPen(Qt.black)
-               else:
-                  painter.setPen(Qt.red)
-               painter.drawText(xpos, ypos, '{0:02X}'.format(b))
-               painter.drawText(xposAscii, ypos, asciiChar(b))
-               xpos += 3 * chw
-               xposAscii += chw
-         ypos += chh
-      # cursor
-      if self.blinkcursor:
-         painter.fillRect(self.cursorX, self.cursorY + chh - 2, chw, 2, Qt.black)
-   def keyPressEvent(self, event):
-      if event.matches(QKeySequence.MoveToNextChar):
-         self.CursorPosition += 1
-      if event.matches(QKeySequence.MoveToPreviousChar):
-         self.CursorPosition -= 1
-      if event.matches(QKeySequence.MoveToNextLine):
-         self.CursorPosition += 2 * BYTES_PER_LINE
-      if event.matches(QKeySequence.MoveToPreviousLine):
-         self.CursorPosition -= 2 * BYTES_PER_LINE
-      if event.matches(QKeySequence.MoveToNextPage):
-         rows = int(self.scrollArea.viewport().height() / self.charHeight)
-         self.CursorPosition += (rows - 1) * 2 * BYTES_PER_LINE
-      if event.matches(QKeySequence.MoveToPreviousPage):
-         rows = int(self.scrollArea.viewport().height() / self.charHeight)
-         self.CursorPosition -= (rows - 1) * 2 * BYTES_PER_LINE
-      char = event.text().lower()
-      if char and char in '0123456789abcdef':
-         i = int(self.CursorPosition / 2)
-         hb = self.CursorPosition % 2
-         v = int(char, 16)
-         if hb == 0:
-            # high half byte
-            self.data[i] = (self.data[i] & 0xF) | (v << 4)
-         else:
-            self.data[i] = (self.data[i] & 0xF0) | v
-         self.CursorPosition += 1
-      self.scrollArea.ensureVisible(self.cursorX, self.cursorY + self.charHeight / 2, 4, self.charHeight / 2 + 4)
-      self.update()
-   def setCursorPositionAt(self, pos):
-      """ Calculate cursor position at a certain point """
-      if pos.x() > self.xposHex and pos.x() < self.xposAscii:
-         x = round((2 * (pos.x() - self.xposHex)) / (self.charWidth * 3))
-         y = int(pos.y() / self.charHeight) * 2 * BYTES_PER_LINE
-         self.setCursorPosition(x + y)
-   def mousePressEvent(self, event):
-      self.setCursorPositionAt(event.pos())
-   def adjust(self):
-      self.charHeight = self.fontMetrics().height()
-      self.charWidth = self.fontMetrics().width('x')
-      self.xposAddr = GAP
-      self.xposHex = self.xposAddr + 8 * self.charWidth + GAP
-      self.xposAscii = self.xposHex + (BYTES_PER_LINE * 3 - 1) * self.charWidth + GAP
-      self.xposEnd = self.xposAscii + self.charWidth * BYTES_PER_LINE + GAP
-      self.setMinimumWidth(self.xposEnd)
-      if self.isVisible():
-         sbw = self.scrollArea.verticalScrollBar().width()
-         self.scrollArea.setMinimumWidth(self.xposEnd + sbw + 5)
-      r = len(self.Data) % BYTES_PER_LINE
-      r = 1 if r > 0 else 0
-      self.setMinimumHeight((int(len(self.Data) / BYTES_PER_LINE) + r) * self.charHeight + 4)
-      self.scrollArea.setMinimumHeight(self.charHeight * 8)
-      self.update()
-   def showEvent(self, e):
-      self.adjust()
-      super().showEvent(e)
-   def setData(self, d):
-      self.data = bytearray(d)
-      self.originalData = bytearray(d)
-      self.adjust()
-      self.setCursorPosition(0)
-   Data = property(lambda self: self.data, setData)
-
-class HexEdit(QScrollArea):
-   def __init__(self):
-      super().__init__()
-      self.bv = BinViewer(self)
-      self.setWidget(self.bv)
-      self.setWidgetResizable(True)
-      self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
-      self.setFocusPolicy(Qt.NoFocus)
-
-class HexEditor(QMainWindow):
-   def __init__(self):
-      super().__init__()
-      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)
-      self.actionSave.triggered.connect(self.doSave)
-      self.actionSaveAs.triggered.connect(self.doSaveAs)
-      self.fileName = None
-      self.updateControls()
-   def updateControls(self):
-      s = True if self.fileName else False
-      self.actionSave.setEnabled(s)
-      self.actionSaveAs.setEnabled(s)
-   def doOpen(self):
-      filename = QFileDialog.getOpenFileName(self)
-      if filename:
-         with open(filename, 'rb') as f:
-            self.he.bv.Data = f.read()
-         self.fileName = filename
-      self.updateControls()
-   def doSave(self):
-      self.updateControls()
-   def doSaveAs(self):
-      filename = QFileDialog.getSaveFileName(self)
-      if filename:
-         with open(filename, 'wb') as f:
-            f.write(self.he.bv.Data)
-         self.fileName = filename
-      self.updateControls()
-
-if __name__ == '__main__':
-   app = QApplication(sys.argv)
-   he = HexEditor()
-   he.show()
-   #he.bv.Data = bytearray(range(100)) * 8 + b'x'
-   app.exec()
-
--- a/python/hexeditor.ui	Thu Nov 21 15:46:50 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,78 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>MainWindow</class>
- <widget class="QMainWindow" name="MainWindow">
-  <property name="geometry">
-   <rect>
-    <x>0</x>
-    <y>0</y>
-    <width>617</width>
-    <height>503</height>
-   </rect>
-  </property>
-  <property name="windowTitle">
-   <string>HexEditor</string>
-  </property>
-  <widget class="QWidget" name="centralwidget"/>
-  <widget class="QMenuBar" name="menubar">
-   <property name="geometry">
-    <rect>
-     <x>0</x>
-     <y>0</y>
-     <width>617</width>
-     <height>25</height>
-    </rect>
-   </property>
-   <widget class="QMenu" name="menuFile">
-    <property name="title">
-     <string>File</string>
-    </property>
-    <addaction name="actionOpen"/>
-    <addaction name="actionSave"/>
-    <addaction name="actionSaveAs"/>
-   </widget>
-   <addaction name="menuFile"/>
-  </widget>
-  <widget class="QStatusBar" name="statusbar"/>
-  <widget class="QToolBar" name="toolBar">
-   <property name="windowTitle">
-    <string>toolBar</string>
-   </property>
-   <attribute name="toolBarArea">
-    <enum>TopToolBarArea</enum>
-   </attribute>
-   <attribute name="toolBarBreak">
-    <bool>false</bool>
-   </attribute>
-   <addaction name="actionOpen"/>
-   <addaction name="actionSave"/>
-   <addaction name="actionSaveAs"/>
-  </widget>
-  <action name="actionOpen">
-   <property name="text">
-    <string>Open</string>
-   </property>
-   <property name="toolTip">
-    <string>Opens a file for editing</string>
-   </property>
-   <property name="shortcut">
-    <string>Ctrl+O</string>
-   </property>
-  </action>
-  <action name="actionSave">
-   <property name="text">
-    <string>Save</string>
-   </property>
-   <property name="shortcut">
-    <string>Ctrl+S</string>
-   </property>
-  </action>
-  <action name="actionSaveAs">
-   <property name="text">
-    <string>Save As</string>
-   </property>
-  </action>
- </widget>
- <resources/>
- <connections/>
-</ui>
--- a/python/hexutil.py	Thu Nov 21 15:46:50 2013 +0100
+++ b/python/hexutil.py	Sun Nov 24 11:24:15 2013 +0100
@@ -28,6 +28,7 @@
 p.add_argument('hexfile2', type=argparse.FileType('r'), help="hexfile 2")
 p.add_argument('rhexfile', type=argparse.FileType('w'), help="resulting hexfile")
 
+
 def main(args):
     if args.command == 'info':
         hf = HexFile()
@@ -56,4 +57,3 @@
         parser.print_usage()
         sys.exit(1)
     main(args)
-
Binary file python/icons/arrow.png has changed
Binary file python/icons/chip.png has changed
Binary file python/icons/error.png has changed
Binary file python/icons/functionicon.png has changed
Binary file python/icons/hardware.png has changed
Binary file python/icons/info.png has changed
Binary file python/icons/logo.png has changed
Binary file python/icons/variableicon.png has changed
Binary file python/icons/warning.png has changed
--- a/python/ide.py	Thu Nov 21 15:46:50 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,338 +0,0 @@
-#!/usr/bin/python
-
-import sys
-import os
-import logging
-import traceback
-import io
-
-from PyQt4.QtCore import *
-from PyQt4.QtGui import *
-
-# Compiler imports:
-import ppci
-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
-
-
-def handle_exception(tp, v, tb):
-    logging.critical(str(v))
-    tb = traceback.format_tb(tb)
-    for i in tb:
-        logging.critical(i.strip())
-
-sys.excepthook = handle_exception
-
-class BuildErrors(QTreeView):
-    sigErrorSelected = pyqtSignal(object)
-
-    def __init__(self, parent=None):
-        super(BuildErrors, self).__init__(parent)
-        model = QStandardItemModel()
-        self.setModel(model)
-        self.clicked.connect(self.itemSelected)
-        self.errorIcon = QIcon('icons/error.png')
-        self.model = QStandardItemModel()
-        self.model.setHorizontalHeaderLabels(['Message', 'Row', 'Column'])
-        self.header().setStretchLastSection(True)
-        self.setModel(self.model)
-
-    def setErrorList(self, errorlist):
-        c = self.model.rowCount()
-        self.model.removeRows(0, c)
-        for e in errorlist:
-            item = QStandardItem(self.errorIcon, str(e.msg))
-            item.setData(e)
-            row = str(e.loc.row) if e.loc else ''
-            irow = QStandardItem(row)
-            irow.setData(e)
-            col = str(e.loc.col) if e.loc else ''
-            icol = QStandardItem(col)
-            icol.setData(e)
-            self.model.appendRow([item, irow, icol])
-        for i in range(3):
-            self.resizeColumnToContents(i)
-
-    def itemSelected(self, index):
-        if not index.isValid():
-            return
-        item = self.model.itemFromIndex(index)
-        err = item.data()
-        self.sigErrorSelected.emit(err)
-
-
-
-class AboutDialog(QDialog):
-    def __init__(self, parent=None):
-        super(AboutDialog, self).__init__(parent)
-        self.setWindowTitle('About')
-        l = QVBoxLayout(self)
-        txt = QTextEdit(self)
-        txt.setReadOnly(True)
-        with open(os.path.join('..', 'readme.rst'), 'r') as f:
-            aboutText = f.read()
-        txt.append(aboutText)
-        l.addWidget(txt)
-        but = QPushButton('OK')
-        but.setDefault(True)
-        but.clicked.connect(self.close)
-        l.addWidget(but)
-
-
-class Ide(QMainWindow):
-    def __init__(self, parent=None):
-        super(Ide, self).__init__(parent)
-        self.to_open_files = []
-        self.logger = logging.getLogger('ide')
-
-        self.setWindowTitle('LCFOS IDE')
-        icon = QIcon('icons/logo.png')
-        self.setWindowIcon(icon)
-
-        # Create menus:
-        mb = self.menuBar()
-        self.fileMenu = mb.addMenu('File')
-        self.viewMenu = mb.addMenu('View')
-        self.helpMenu = mb.addMenu('Help')
-
-        # Create mdi area:
-        self.mdiArea = QMdiArea()
-        self.mdiArea.setViewMode(QMdiArea.TabbedView)
-        self.mdiArea.setTabsClosable(True)
-        self.mdiArea.setTabsMovable(True)
-        self.setCentralWidget(self.mdiArea)
-
-        # Create components:
-        def addComponent(name, widget):
-            dw = QDockWidget(name)
-            dw.setWidget(widget)
-            dw.setObjectName(name)
-            self.addDockWidget(Qt.RightDockWidgetArea, dw)
-            self.viewMenu.addAction(dw.toggleViewAction())
-            return widget
-
-        self.buildOutput = addComponent('Build output', BuildOutput())
-        self.astViewer = addComponent('AST viewer', AstViewer())
-        self.astViewer.sigNodeSelected.connect(lambda node: self.showLoc(node.loc))
-        self.builderrors = addComponent('Build errors', BuildErrors())
-        self.builderrors.sigErrorSelected.connect(lambda err: self.showLoc(err.loc))
-        self.devxplr = addComponent('Device explorer', stutil.DeviceExplorer())
-        self.regview = addComponent('Registers', stutil.RegisterView())
-        self.memview = addComponent('Memory', stutil.MemoryView())
-        self.disasm = addComponent('Disasm', Disassembly())
-        self.ctrlToolbar = stutil.DebugToolbar()
-        self.addToolBar(self.ctrlToolbar)
-        self.ctrlToolbar.setObjectName('debugToolbar')
-        self.devxplr.deviceSelected.connect(self.regview.mdl.setDevice)
-        self.ctrlToolbar.statusChange.connect(self.memview.refresh)
-        self.devxplr.deviceSelected.connect(self.memview.setDevice)
-        self.devxplr.deviceSelected.connect(self.ctrlToolbar.setDevice)
-        self.ctrlToolbar.statusChange.connect(self.regview.refresh)
-        self.ctrlToolbar.codePosition.connect(self.pointCode)
-
-        # About dialog:
-        self.aboutDialog = AboutDialog()
-        self.aboutDialog.setWindowIcon(icon)
-
-        # Create actions:
-        def addMenuEntry(name, menu, callback, shortcut=None):
-            a = QAction(name, self)
-            menu.addAction(a)
-            a.triggered.connect(callback)
-            if shortcut:
-                a.setShortcut(shortcut)
-
-        addMenuEntry("New", self.fileMenu, self.newFile, shortcut=QKeySequence(QKeySequence.New))
-        addMenuEntry("Open", self.fileMenu, self.openFile, shortcut=QKeySequence(QKeySequence.Open))
-        addMenuEntry("Save", self.fileMenu, self.saveFile, shortcut=QKeySequence(QKeySequence.Save))
-        addMenuEntry("Build", self.fileMenu, self.buildFile, shortcut=QKeySequence("F7"))
-        addMenuEntry("Build and flash", self.fileMenu, self.buildFileAndFlash, shortcut=QKeySequence("F8"))
-
-        self.helpAction = QAction('Help', self)
-        self.helpAction.setShortcut(QKeySequence('F1'))
-        self.helpMenu.addAction(self.helpAction)
-        addMenuEntry('About', self.helpMenu, self.aboutDialog.open)
-
-        addMenuEntry('Cascade windows', self.viewMenu, self.mdiArea.cascadeSubWindows)
-        addMenuEntry('Tile windows', self.viewMenu, self.mdiArea.tileSubWindows)
-        sb = self.statusBar()
-
-        # Load settings:
-        self.settings = QSettings('windelsoft', 'lcfoside')
-        self.loadSettings()
-        self.diag = ppci.DiagnosticsManager()
-        self.c3front = c3.Builder(self.diag)
-
-    # File handling:
-    def newFile(self):
-        self.newCodeEdit()
-
-    def openFile(self):
-        filename = QFileDialog.getOpenFileName(self, "Open C3 file...", "*.c3",
-                    "C3 source files (*.c3)")
-        if filename:
-            self.loadFile(filename)
-
-    def saveFile(self):
-        ac = self.activeMdiChild()
-        if ac:
-            ac.save()
-
-    def loadFile(self, filename):
-        ce = self.newCodeEdit()
-        try:
-            with open(filename) as f:
-                ce.Source = f.read()
-                ce.FileName = filename
-        except Exception as e:
-            print('exception opening file', e)
-
-    # MDI:
-    def newCodeEdit(self):
-        ce = CodeEdit()
-        ce.textChanged.connect(self.parseFile)
-        w = self.mdiArea.addSubWindow(ce)
-        self.mdiArea.setActiveSubWindow(w)
-        ce.showMaximized()
-        return ce
-
-    def activeMdiChild(self):
-        aw = self.mdiArea.activeSubWindow()
-        if aw:
-            return aw.widget()
-
-    def findMdiChild(self, filename):
-        for wid in self.allChildren():
-            if wid.filename == filename:
-                return wid
-
-    def allChildren(self):
-        return [w.widget() for w in self.mdiArea.subWindowList()]
-
-    # Settings:
-    def loadSettings(self):
-        if self.settings.contains('mainwindowstate'):
-            self.restoreState(self.settings.value('mainwindowstate'))
-        if self.settings.contains('mainwindowgeometry'):
-            self.restoreGeometry(self.settings.value('mainwindowgeometry'))
-        if self.settings.contains('lastfiles'):
-            lfs = self.settings.value('lastfiles')
-            if lfs:
-                self.to_open_files.extend(lfs)
-
-    def showEvent(self, ev):
-        super().showEvent(ev)
-        while self.to_open_files:
-            fn = self.to_open_files.pop(0)
-            self.loadFile(fn)
-
-    def closeEvent(self, ev):
-        self.settings.setValue('mainwindowstate', self.saveState())
-        self.settings.setValue('mainwindowgeometry', self.saveGeometry())
-        ac = self.activeMdiChild()
-        lfs = [ce.FileName for ce in self.allChildren() if ce.FileName]
-        self.settings.setValue('lastfiles', lfs)
-        ev.accept()
-
-    # Error handling:
-    def nodeSelected(self, node):
-        self.showLoc(node.loc)
-
-    def showLoc(self, loc):
-        ce = self.activeMdiChild()
-        if not ce:
-            return
-        if loc:
-            ce.setRowCol(loc.row, loc.col)
-            ce.setFocus()
-
-    def pointCode(self, p):
-        # Lookup pc in debug infos:
-        loc = None
-        print(p)
-        self.disasm.showPos(p)
-        if hasattr(self, 'debugInfo'):
-            for di in self.debugInfo:
-                if di.address > p:
-                    loc = di.info
-                    break
-        if loc:
-            ce = self.activeMdiChild()
-            if ce:
-                ce.ic.arrow = loc
-            self.showLoc(loc)
-
-    # Build recepy:
-    def parseFile(self):
-        self.logger.info('Parsing!')
-        ce = self.activeMdiChild()
-        if not ce:
-            return
-        self.diag.clear()
-        pkg = self.c3front.parse(ce.Source)
-
-        # Set errors:
-        self.builderrors.setErrorList(self.diag.diags)
-        ce.setErrors(self.diag.diags)
-        self.astViewer.setAst(pkg)
-        if pkg:
-            c3.AstPrinter().printAst(pkg)
-        self.logger.info('Done!')
-
-    def buildFile(self):
-        ce = self.activeMdiChild()
-        if not ce:
-            return
-        fn = ce.FileName
-        self.diag.clear()
-        outs = outstream.TextOutputStream()
-        if not zcc.zcc([io.StringIO(ce.Source)], [], outs, self.diag):
-            # Set errors:
-            self.builderrors.setErrorList(self.diag.diags)
-            ce.setErrors(self.diag.diags)
-            return
-
-    def buildFileAndFlash(self):
-        ce = self.activeMdiChild()
-        if not ce:
-            return
-        fn = ce.FileName
-        self.diag.clear()
-        outs = outstream.TextOutputStream()
-        imps = [open(ce.FileName, 'r') for ce in self.allChildren() if ce.FileName and ce.FileName != fn]
-        if not zcc.zcc([open(fn, 'r')], imps, outs, self.diag):
-            # Set errors:
-            self.builderrors.setErrorList(self.diag.diags)
-            ce.setErrors(self.diag.diags)
-            return
-
-        outs.dump()
-        code_s = outs.getSection('code')
-        self.disasm.dm.setInstructions(code_s.instructions)
-        self.debugInfo = code_s.debugInfos()
-        if self.ctrlToolbar.device:
-            logging.info('Flashing stm32f4 discovery')
-            bts = code_s.to_bytes()
-            self.ctrlToolbar.device.writeFlash(0x08000000, bts)
-            stl = self.ctrlToolbar.device.iface
-            stl.reset()
-            stl.halt()
-            stl.run()
-            logging.info('Done!')
-        else:
-            self.logger.warning('Not connected to device, skipping flash')
-
-
-if __name__ == '__main__':
-    logging.basicConfig(format=zcc.logformat, level=logging.DEBUG)
-    app = QApplication(sys.argv)
-    ide = Ide()
-    ide.show()
-    ide.logger.info('IDE started')
-    app.exec_()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/ide/astviewer.py	Sun Nov 24 11:24:15 2013 +0100
@@ -0,0 +1,63 @@
+from PyQt4.QtCore import *
+from PyQt4.QtGui import *
+from c3 import Visitor, astnodes
+
+class AstModelBuilder:
+    def __init__(self):
+      self.functionIco = QIcon(QPixmap('icons/functionicon.png').scaled(32, 32))
+      self.variableIco = QIcon(QPixmap('icons/variableicon.png').scaled(32, 32))
+      self.model = QStandardItemModel()
+      self.model.setHorizontalHeaderLabels(['Object', 'Type'])
+
+    def build(self, pkg):
+        #self.model.clear()
+        c = self.model.rowCount()
+        self.model.removeRows(0, c)
+        self.curItem = self.model.invisibleRootItem()
+        if pkg:
+            visitor = Visitor()
+            visitor.visit(pkg, self.p1, self.p2)
+
+    def p1(self, node):
+      if type(node) is astnodes.Variable:
+         i = QStandardItem(self.variableIco, str(node))
+      elif type(node) is astnodes.Function:
+         i = QStandardItem(self.functionIco, str(node))
+      elif type(node) is astnodes.Package:
+         i = QStandardItem(str(node))
+      else:
+         return
+      typ = str(node.typ) if hasattr(node, 'typ') else ''
+      ti = QStandardItem(str(typ))
+      ti.setData(node)
+      i.setData(node)
+      self.curItem.appendRow([i, ti])
+      self.curItem = i
+
+    def p2(self, node):
+      if type(node) in [astnodes.Variable, astnodes.Function, astnodes.Package]:
+         self.curItem = self.curItem.parent()
+
+# The actual widget:
+class AstViewer(QTreeView):
+    sigNodeSelected = pyqtSignal(object)
+    def __init__(self, parent=None):
+      super(AstViewer, self).__init__(parent)
+      self.clicked.connect(self.selectHandler)
+      self.modelBuilder = AstModelBuilder()
+      self.setModel(self.modelBuilder.model)
+
+    def setAst(self, ast):
+        """ Create a new model and add all ast elements to it """
+        self.modelBuilder.build(ast)
+        self.expandAll()
+
+    def selectHandler(self, index):
+      if not index.isValid():
+         return
+      model = self.model()
+      item = model.itemFromIndex(index)
+      node = item.data()
+      self.sigNodeSelected.emit(node)
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/ide/codeedit.py	Sun Nov 24 11:24:15 2013 +0100
@@ -0,0 +1,291 @@
+#!/usr/bin/python
+
+import sys
+import os
+from PyQt4.QtCore import *
+from PyQt4.QtGui import *
+import inspect
+
+GAP = 5
+
+def clipVal(v, mn, mx):
+   if v < mn: return mn
+   if v > mx: return mx
+   return v
+
+class InnerCode(QWidget):
+    textChanged = pyqtSignal()
+    def __init__(self, scrollArea):
+      super().__init__(scrollArea)
+      self.scrollArea = scrollArea
+      self.setFont(QFont('Courier', 12))
+      self.setFocusPolicy(Qt.StrongFocus)
+      # TODO: only beam cursor in text area..
+      self.setCursor(Qt.IBeamCursor)
+      h = QFontMetrics(self.font()).height()
+      self.errorPixmap = QPixmap('icons/error.png').scaled(h, h)
+      self.arrowPixmap = QPixmap('icons/arrow.png').scaled(h, h)
+      self.blinkcursor = False
+      self.errorlist = []
+      self.arrow = None
+      # Initial values:
+      self.setSource('')
+      self.CursorPosition = 0
+      self.t = QTimer(self)
+      self.t.timeout.connect(self.updateCursor)
+      self.t.setInterval(500)
+      self.t.start()
+
+    def updateCursor(self):
+        self.blinkcursor = not self.blinkcursor
+        self.update()
+        #self.update(self.cursorX, self.cursorY, self.charWidth, self.charHeight)
+
+    def setSource(self, src):
+        self.src = src
+        self.adjust()
+
+    def getSource(self):
+        return self.src
+
+    def setErrors(self, el):
+        self.errorlist = el
+        self.update()
+
+    def setCursorPosition(self, c):
+        self.cursorPosition = clipVal(c, 0, len(self.src))
+        self.update()
+
+    CursorPosition = property(lambda self: self.cursorPosition, setCursorPosition)
+
+    @property
+    def Rows(self):
+        # Make this nicer:
+        return self.src.split('\n')
+
+    @property
+    def CursorRow(self):
+        # TODO: make this nice.
+        txt = self.src[0:self.cursorPosition]
+        return len(txt.split('\n'))
+
+    @property
+    def CursorCol(self):
+        txt = self.src[0:self.cursorPosition]
+        curLine = txt.split('\n')[-1]
+        return len(curLine) + 1
+
+    @property
+    def CurrentLine(self):
+        return self.getRow(self.CursorRow)
+
+    def setRowCol(self, r, c):
+      prevRows = self.Rows[:r-1]
+      txt = '\n'.join(prevRows)
+      c = clipVal(c, 1, len(self.getRow(r)))
+      self.CursorPosition = len(txt) + c + 1
+      self.showRow(self.CursorRow)
+
+    def getRow(self, r):
+      rows = self.Rows
+      r = r - 1
+      if r < 0 or r > len(rows) - 1:
+         return ''
+      else:
+         return rows[r]
+
+    def showRow(self, r):
+      self.scrollArea.ensureVisible(self.xposTXT, r * self.charHeight, 4, self.charHeight)
+
+    # Annotations:
+    def addAnnotation(self, row, col, ln, msg):
+      pass
+
+    # Text modification:
+    def getChar(self, pos):
+      pass
+
+    def insertText(self, txt):
+        self.setSource(self.src[0:self.CursorPosition] + txt + self.src[self.CursorPosition:])
+        self.CursorPosition += len(txt)
+        self.textChanged.emit()
+
+    def deleteChar(self):
+        self.setSource(self.src[0:self.CursorPosition] + self.src[self.CursorPosition+1:])
+        self.textChanged.emit()
+
+    def GotoNextChar(self):
+        if self.src[self.CursorPosition] != '\n':
+            self.CursorPosition += 1
+
+    def GotoPrevChar(self):
+        if self.src[self.CursorPosition - 1] != '\n':
+            self.CursorPosition -= 1
+
+    def GotoNextLine(self):
+        curLine = self.CurrentLine
+        c = self.CursorCol - 1 # go to zero based
+        self.CursorPosition += len(curLine) - c + 1 # line break char!
+        curLine = self.CurrentLine
+        if len(curLine) < c:
+            self.CursorPosition += len(curLine)
+        else:
+            self.CursorPosition += c
+        self.showRow(self.CursorRow)
+
+    def GotoPrevLine(self):
+        c = self.CursorCol - 1 # go to zero based
+        self.CursorPosition -= c + 1 # line break char!
+        curLine = self.CurrentLine
+        if len(curLine) > c:
+            self.CursorPosition -= len(curLine) - c
+        self.showRow(self.CursorRow)
+
+    def paintEvent(self, event):
+      # Helper variables:
+      er = event.rect()
+      chw, chh = self.charWidth, self.charHeight
+      painter = QPainter(self)
+      # Background:
+      painter.fillRect(er, self.palette().color(QPalette.Base))
+      painter.fillRect(QRect(self.xposLNA, er.top(), 4 * chw, er.bottom() + 1), Qt.gray)
+      errorPen = QPen(Qt.red, 3)
+      # first and last row:
+      row1 = max(int(er.top() / chh) - 1, 1)
+      row2 = max(int(er.bottom() / chh) + 1, 1)
+      # Draw contents:
+      ypos = row1 * chh - self.charDescent
+      curRow = self.CursorRow
+      ydt = -chh + self.charDescent
+      for row in range(row1, row2 + 1):
+         if curRow == row and self.hasFocus():
+            painter.fillRect(self.xposTXT, ypos + ydt, er.width(), chh, Qt.yellow)
+            # cursor
+            if self.blinkcursor:
+               cursorX = self.CursorCol * self.charWidth + self.xposTXT - self.charWidth
+               cursorY = ypos + ydt
+               painter.fillRect(cursorX, cursorY, 2, chh, Qt.black)
+         painter.setPen(Qt.black)
+         painter.drawText(self.xposLNA, ypos, '{0}'.format(row))
+         xpos = self.xposTXT
+         painter.drawText(xpos, ypos, self.getRow(row))
+         if self.arrow and self.arrow.row == row:
+                painter.drawPixmap(self.xposERR, ypos + ydt, self.arrowPixmap)
+         curErrors = [e for e in self.errorlist if e.loc and e.loc.row == row]
+         for e in curErrors:
+               painter.drawPixmap(self.xposERR, ypos + ydt, self.errorPixmap)
+               painter.setPen(errorPen)
+               x = self.xposTXT + (e.loc.col - 1) * chw - 2
+               wt = e.loc.length * chw + 4
+               dy = self.charDescent
+               painter.drawLine(x, ypos + dy, x + wt, ypos + dy)
+               #painter.drawRoundedRect(x, ypos + ydt, wt, chh, 7, 7)
+               # print error balloon
+               #painter.drawText(x, ypos + chh, e.msg)
+         #if len(curErrors) > 0:
+         #   ypos += chh
+         ypos += chh
+
+    def keyPressEvent(self, event):
+      if event.matches(QKeySequence.MoveToNextChar):
+         self.GotoNextChar()
+      elif event.matches(QKeySequence.MoveToPreviousChar):
+         self.GotoPrevChar()
+      elif event.matches(QKeySequence.MoveToNextLine):
+         self.GotoNextLine()
+      elif event.matches(QKeySequence.MoveToPreviousLine):
+         self.GotoPrevLine()
+      elif event.matches(QKeySequence.MoveToNextPage):
+         for i in range(5):
+            self.GotoNextLine()
+      elif event.matches(QKeySequence.MoveToPreviousPage):
+         for i in range(5):
+            self.GotoPrevLine()
+      elif event.matches(QKeySequence.MoveToEndOfLine):
+         self.CursorPosition += len(self.CurrentLine) - self.CursorCol + 1
+      elif event.matches(QKeySequence.MoveToStartOfLine):
+         self.CursorPosition -= self.CursorCol - 1
+      elif event.matches(QKeySequence.Delete):
+         self.deleteChar()
+      elif event.matches(QKeySequence.InsertParagraphSeparator):
+         self.insertText('\n')
+      elif event.key() == Qt.Key_Backspace:
+         self.CursorPosition -= 1
+         self.deleteChar()
+      else:
+         char = event.text()
+         if char:
+            self.insertText(char)
+      self.update()
+
+    def mousePressEvent(self, event):
+        pos = event.pos()
+        if pos.x() > self.xposTXT and pos.x():
+            c = round((pos.x() - self.xposTXT) / self.charWidth)
+            r = int(pos.y() / self.charHeight) + 1
+            self.setRowCol(r, c)
+        super().mousePressEvent(event)
+
+    def adjust(self):
+        metrics = self.fontMetrics()
+        self.charHeight = metrics.height()
+        self.charWidth = metrics.width('x')
+        self.charDescent = metrics.descent()
+        self.xposERR = GAP
+        self.xposLNA = self.xposERR + GAP + self.errorPixmap.width()
+        self.xposTXT = self.xposLNA + 4 * self.charWidth + GAP
+        self.xposEnd = self.xposTXT + self.charWidth * 80
+        self.setMinimumWidth(self.xposEnd)
+        txt = self.src.split('\n')
+        self.setMinimumHeight(self.charHeight * len(txt))
+        self.update()
+
+class CodeEdit(QScrollArea):
+    def __init__(self):
+        super().__init__()
+        self.ic = InnerCode(self)
+        self.textChanged = self.ic.textChanged
+        self.setWidget(self.ic)
+        self.setWidgetResizable(True)
+        self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
+        self.setFocusPolicy(Qt.NoFocus)
+        self.showRow = self.ic.showRow
+        self.setRowCol = self.ic.setRowCol
+        self.FileName = None
+    Source = property(lambda s: s.ic.getSource(), lambda s, v: s.ic.setSource(v))
+
+    def setErrors(self, el):
+        self.ic.setErrors(el)
+
+    def setFocus(self):
+        self.ic.setFocus()
+        super().setFocus()
+
+    def setFileName(self, fn):
+        self.filename = fn
+        if fn:
+            fn = os.path.basename(fn)
+        else:
+            fn = 'Untitled'
+        self.setWindowTitle(fn)
+
+    def getFileName(self):
+        return self.filename
+    FileName = property(getFileName, setFileName)
+
+    def save(self):
+        if self.FileName:
+            s = self.Source
+            with open(self.FileName, 'w') as f:
+                f.write(s)
+
+
+if __name__ == '__main__':
+    app = QApplication(sys.argv)
+    ce = CodeEdit()
+    ce.show()
+    src = ''.join(inspect.getsourcelines(InnerCode)[0])
+    ce.Source = src
+    ce.resize(600, 800)
+    app.exec()
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/ide/hexedit.py	Sun Nov 24 11:24:15 2013 +0100
@@ -0,0 +1,207 @@
+#!/usr/bin/python
+
+import sys
+import os
+from PyQt4.QtCore import *
+from PyQt4.QtGui import *
+from PyQt4 import uic
+
+BYTES_PER_LINE, GAP = 8, 12
+
+def clamp(minimum, x, maximum):
+   return max(minimum, min(x, maximum))
+
+def asciiChar(v):
+   if v < 0x20 or v > 0x7e:
+      return '.'
+   else:
+      return chr(v)
+
+class BinViewer(QWidget):
+   """ The view has an address, hex byte and ascii column """
+   def __init__(self, scrollArea):
+      super().__init__(scrollArea)
+      self.scrollArea = scrollArea
+      self.setFont(QFont('Courier', 16))
+      self.setFocusPolicy(Qt.StrongFocus)
+      self.blinkcursor = False
+      self.cursorX = self.cursorY = 0
+      self.scrollArea = scrollArea
+      self.Data = bytearray()
+      self.Offset = 0
+      t = QTimer(self)
+      t.timeout.connect(self.updateCursor)
+      t.setInterval(500)
+      t.start()
+   def updateCursor(self):
+      self.blinkcursor = not self.blinkcursor
+      self.update(self.cursorX, self.cursorY, self.charWidth, self.charHeight)
+   def setCursorPosition(self, position):
+      position = clamp(0, int(position), len(self.Data) * 2 - 1)
+      self.cursorPosition = position
+      x = position % (2 * BYTES_PER_LINE)
+      x = x + int(x / 2) # Create a gap between hex values
+      self.cursorX = self.xposHex + x * self.charWidth
+      y = int(position / (2 * BYTES_PER_LINE))
+      self.cursorY = y * self.charHeight + 2
+      self.blinkcursor = True
+      self.update()
+   def getCursorPosition(self):
+      return self.cursorPosition
+   CursorPosition = property(getCursorPosition, setCursorPosition)
+   def setOffset(self, off):
+      self.offset = off
+      self.update()
+   Offset = property(lambda self: self.offset, setOffset)
+   def paintEvent(self, event):
+      # Helper variables:
+      er = event.rect()
+      chw, chh = self.charWidth, self.charHeight
+      painter = QPainter(self)
+      # Background:
+      painter.fillRect(er, self.palette().color(QPalette.Base))
+      painter.fillRect(QRect(self.xposAddr, er.top(), 8 * chw, er.bottom() + 1), Qt.gray)
+      painter.setPen(Qt.gray)
+      x = self.xposAscii - (GAP / 2)
+      painter.drawLine(x, er.top(), x, er.bottom())
+      x = self.xposEnd - (GAP / 2)
+      painter.drawLine(x, er.top(), x, er.bottom())
+      # first and last index
+      firstIndex = max((int(er.top() / chh) - chh) * BYTES_PER_LINE, 0)
+      lastIndex = max((int(er.bottom() / chh) + chh) * BYTES_PER_LINE, 0)
+      yposStart = int(firstIndex / BYTES_PER_LINE) * chh + chh
+      # Draw contents:
+      painter.setPen(Qt.black)
+      ypos = yposStart
+      for index in range(firstIndex, lastIndex, BYTES_PER_LINE):
+         painter.setPen(Qt.black)
+         painter.drawText(self.xposAddr, ypos, '{0:08X}'.format(index + self.Offset))
+         xpos = self.xposHex
+         xposAscii = self.xposAscii
+         for colIndex in range(BYTES_PER_LINE):
+            if index + colIndex < len(self.Data):
+               b = self.Data[index + colIndex]
+               bo = self.originalData[index + colIndex]
+               if b == bo:
+                  painter.setPen(Qt.black)
+               else:
+                  painter.setPen(Qt.red)
+               painter.drawText(xpos, ypos, '{0:02X}'.format(b))
+               painter.drawText(xposAscii, ypos, asciiChar(b))
+               xpos += 3 * chw
+               xposAscii += chw
+         ypos += chh
+      # cursor
+      if self.blinkcursor:
+         painter.fillRect(self.cursorX, self.cursorY + chh - 2, chw, 2, Qt.black)
+   def keyPressEvent(self, event):
+      if event.matches(QKeySequence.MoveToNextChar):
+         self.CursorPosition += 1
+      if event.matches(QKeySequence.MoveToPreviousChar):
+         self.CursorPosition -= 1
+      if event.matches(QKeySequence.MoveToNextLine):
+         self.CursorPosition += 2 * BYTES_PER_LINE
+      if event.matches(QKeySequence.MoveToPreviousLine):
+         self.CursorPosition -= 2 * BYTES_PER_LINE
+      if event.matches(QKeySequence.MoveToNextPage):
+         rows = int(self.scrollArea.viewport().height() / self.charHeight)
+         self.CursorPosition += (rows - 1) * 2 * BYTES_PER_LINE
+      if event.matches(QKeySequence.MoveToPreviousPage):
+         rows = int(self.scrollArea.viewport().height() / self.charHeight)
+         self.CursorPosition -= (rows - 1) * 2 * BYTES_PER_LINE
+      char = event.text().lower()
+      if char and char in '0123456789abcdef':
+         i = int(self.CursorPosition / 2)
+         hb = self.CursorPosition % 2
+         v = int(char, 16)
+         if hb == 0:
+            # high half byte
+            self.data[i] = (self.data[i] & 0xF) | (v << 4)
+         else:
+            self.data[i] = (self.data[i] & 0xF0) | v
+         self.CursorPosition += 1
+      self.scrollArea.ensureVisible(self.cursorX, self.cursorY + self.charHeight / 2, 4, self.charHeight / 2 + 4)
+      self.update()
+   def setCursorPositionAt(self, pos):
+      """ Calculate cursor position at a certain point """
+      if pos.x() > self.xposHex and pos.x() < self.xposAscii:
+         x = round((2 * (pos.x() - self.xposHex)) / (self.charWidth * 3))
+         y = int(pos.y() / self.charHeight) * 2 * BYTES_PER_LINE
+         self.setCursorPosition(x + y)
+   def mousePressEvent(self, event):
+      self.setCursorPositionAt(event.pos())
+   def adjust(self):
+      self.charHeight = self.fontMetrics().height()
+      self.charWidth = self.fontMetrics().width('x')
+      self.xposAddr = GAP
+      self.xposHex = self.xposAddr + 8 * self.charWidth + GAP
+      self.xposAscii = self.xposHex + (BYTES_PER_LINE * 3 - 1) * self.charWidth + GAP
+      self.xposEnd = self.xposAscii + self.charWidth * BYTES_PER_LINE + GAP
+      self.setMinimumWidth(self.xposEnd)
+      if self.isVisible():
+         sbw = self.scrollArea.verticalScrollBar().width()
+         self.scrollArea.setMinimumWidth(self.xposEnd + sbw + 5)
+      r = len(self.Data) % BYTES_PER_LINE
+      r = 1 if r > 0 else 0
+      self.setMinimumHeight((int(len(self.Data) / BYTES_PER_LINE) + r) * self.charHeight + 4)
+      self.scrollArea.setMinimumHeight(self.charHeight * 8)
+      self.update()
+   def showEvent(self, e):
+      self.adjust()
+      super().showEvent(e)
+   def setData(self, d):
+      self.data = bytearray(d)
+      self.originalData = bytearray(d)
+      self.adjust()
+      self.setCursorPosition(0)
+   Data = property(lambda self: self.data, setData)
+
+class HexEdit(QScrollArea):
+   def __init__(self):
+      super().__init__()
+      self.bv = BinViewer(self)
+      self.setWidget(self.bv)
+      self.setWidgetResizable(True)
+      self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
+      self.setFocusPolicy(Qt.NoFocus)
+
+class HexEditor(QMainWindow):
+   def __init__(self):
+      super().__init__()
+      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)
+      self.actionSave.triggered.connect(self.doSave)
+      self.actionSaveAs.triggered.connect(self.doSaveAs)
+      self.fileName = None
+      self.updateControls()
+   def updateControls(self):
+      s = True if self.fileName else False
+      self.actionSave.setEnabled(s)
+      self.actionSaveAs.setEnabled(s)
+   def doOpen(self):
+      filename = QFileDialog.getOpenFileName(self)
+      if filename:
+         with open(filename, 'rb') as f:
+            self.he.bv.Data = f.read()
+         self.fileName = filename
+      self.updateControls()
+   def doSave(self):
+      self.updateControls()
+   def doSaveAs(self):
+      filename = QFileDialog.getSaveFileName(self)
+      if filename:
+         with open(filename, 'wb') as f:
+            f.write(self.he.bv.Data)
+         self.fileName = filename
+      self.updateControls()
+
+if __name__ == '__main__':
+   app = QApplication(sys.argv)
+   he = HexEditor()
+   he.show()
+   #he.bv.Data = bytearray(range(100)) * 8 + b'x'
+   app.exec()
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/ide/hexeditor.ui	Sun Nov 24 11:24:15 2013 +0100
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MainWindow</class>
+ <widget class="QMainWindow" name="MainWindow">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>617</width>
+    <height>503</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>HexEditor</string>
+  </property>
+  <widget class="QWidget" name="centralwidget"/>
+  <widget class="QMenuBar" name="menubar">
+   <property name="geometry">
+    <rect>
+     <x>0</x>
+     <y>0</y>
+     <width>617</width>
+     <height>25</height>
+    </rect>
+   </property>
+   <widget class="QMenu" name="menuFile">
+    <property name="title">
+     <string>File</string>
+    </property>
+    <addaction name="actionOpen"/>
+    <addaction name="actionSave"/>
+    <addaction name="actionSaveAs"/>
+   </widget>
+   <addaction name="menuFile"/>
+  </widget>
+  <widget class="QStatusBar" name="statusbar"/>
+  <widget class="QToolBar" name="toolBar">
+   <property name="windowTitle">
+    <string>toolBar</string>
+   </property>
+   <attribute name="toolBarArea">
+    <enum>TopToolBarArea</enum>
+   </attribute>
+   <attribute name="toolBarBreak">
+    <bool>false</bool>
+   </attribute>
+   <addaction name="actionOpen"/>
+   <addaction name="actionSave"/>
+   <addaction name="actionSaveAs"/>
+  </widget>
+  <action name="actionOpen">
+   <property name="text">
+    <string>Open</string>
+   </property>
+   <property name="toolTip">
+    <string>Opens a file for editing</string>
+   </property>
+   <property name="shortcut">
+    <string>Ctrl+O</string>
+   </property>
+  </action>
+  <action name="actionSave">
+   <property name="text">
+    <string>Save</string>
+   </property>
+   <property name="shortcut">
+    <string>Ctrl+S</string>
+   </property>
+  </action>
+  <action name="actionSaveAs">
+   <property name="text">
+    <string>Save As</string>
+   </property>
+  </action>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
Binary file python/ide/icons/arrow.png has changed
Binary file python/ide/icons/chip.png has changed
Binary file python/ide/icons/error.png has changed
Binary file python/ide/icons/functionicon.png has changed
Binary file python/ide/icons/hardware.png has changed
Binary file python/ide/icons/info.png has changed
Binary file python/ide/icons/logo.png has changed
Binary file python/ide/icons/variableicon.png has changed
Binary file python/ide/icons/warning.png has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/ide/ide.py	Sun Nov 24 11:24:15 2013 +0100
@@ -0,0 +1,338 @@
+#!/usr/bin/python
+
+import sys
+import os
+import logging
+import traceback
+import io
+
+from PyQt4.QtCore import *
+from PyQt4.QtGui import *
+
+# Compiler imports:
+import ppci
+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
+
+
+def handle_exception(tp, v, tb):
+    logging.critical(str(v))
+    tb = traceback.format_tb(tb)
+    for i in tb:
+        logging.critical(i.strip())
+
+sys.excepthook = handle_exception
+
+class BuildErrors(QTreeView):
+    sigErrorSelected = pyqtSignal(object)
+
+    def __init__(self, parent=None):
+        super(BuildErrors, self).__init__(parent)
+        model = QStandardItemModel()
+        self.setModel(model)
+        self.clicked.connect(self.itemSelected)
+        self.errorIcon = QIcon('icons/error.png')
+        self.model = QStandardItemModel()
+        self.model.setHorizontalHeaderLabels(['Message', 'Row', 'Column'])
+        self.header().setStretchLastSection(True)
+        self.setModel(self.model)
+
+    def setErrorList(self, errorlist):
+        c = self.model.rowCount()
+        self.model.removeRows(0, c)
+        for e in errorlist:
+            item = QStandardItem(self.errorIcon, str(e.msg))
+            item.setData(e)
+            row = str(e.loc.row) if e.loc else ''
+            irow = QStandardItem(row)
+            irow.setData(e)
+            col = str(e.loc.col) if e.loc else ''
+            icol = QStandardItem(col)
+            icol.setData(e)
+            self.model.appendRow([item, irow, icol])
+        for i in range(3):
+            self.resizeColumnToContents(i)
+
+    def itemSelected(self, index):
+        if not index.isValid():
+            return
+        item = self.model.itemFromIndex(index)
+        err = item.data()
+        self.sigErrorSelected.emit(err)
+
+
+
+class AboutDialog(QDialog):
+    def __init__(self, parent=None):
+        super(AboutDialog, self).__init__(parent)
+        self.setWindowTitle('About')
+        l = QVBoxLayout(self)
+        txt = QTextEdit(self)
+        txt.setReadOnly(True)
+        with open(os.path.join('..', 'readme.rst'), 'r') as f:
+            aboutText = f.read()
+        txt.append(aboutText)
+        l.addWidget(txt)
+        but = QPushButton('OK')
+        but.setDefault(True)
+        but.clicked.connect(self.close)
+        l.addWidget(but)
+
+
+class Ide(QMainWindow):
+    def __init__(self, parent=None):
+        super(Ide, self).__init__(parent)
+        self.to_open_files = []
+        self.logger = logging.getLogger('ide')
+
+        self.setWindowTitle('LCFOS IDE')
+        icon = QIcon('icons/logo.png')
+        self.setWindowIcon(icon)
+
+        # Create menus:
+        mb = self.menuBar()
+        self.fileMenu = mb.addMenu('File')
+        self.viewMenu = mb.addMenu('View')
+        self.helpMenu = mb.addMenu('Help')
+
+        # Create mdi area:
+        self.mdiArea = QMdiArea()
+        self.mdiArea.setViewMode(QMdiArea.TabbedView)
+        self.mdiArea.setTabsClosable(True)
+        self.mdiArea.setTabsMovable(True)
+        self.setCentralWidget(self.mdiArea)
+
+        # Create components:
+        def addComponent(name, widget):
+            dw = QDockWidget(name)
+            dw.setWidget(widget)
+            dw.setObjectName(name)
+            self.addDockWidget(Qt.RightDockWidgetArea, dw)
+            self.viewMenu.addAction(dw.toggleViewAction())
+            return widget
+
+        self.buildOutput = addComponent('Build output', BuildOutput())
+        self.astViewer = addComponent('AST viewer', AstViewer())
+        self.astViewer.sigNodeSelected.connect(lambda node: self.showLoc(node.loc))
+        self.builderrors = addComponent('Build errors', BuildErrors())
+        self.builderrors.sigErrorSelected.connect(lambda err: self.showLoc(err.loc))
+        self.devxplr = addComponent('Device explorer', stutil.DeviceExplorer())
+        self.regview = addComponent('Registers', stutil.RegisterView())
+        self.memview = addComponent('Memory', stutil.MemoryView())
+        self.disasm = addComponent('Disasm', Disassembly())
+        self.ctrlToolbar = stutil.DebugToolbar()
+        self.addToolBar(self.ctrlToolbar)
+        self.ctrlToolbar.setObjectName('debugToolbar')
+        self.devxplr.deviceSelected.connect(self.regview.mdl.setDevice)
+        self.ctrlToolbar.statusChange.connect(self.memview.refresh)
+        self.devxplr.deviceSelected.connect(self.memview.setDevice)
+        self.devxplr.deviceSelected.connect(self.ctrlToolbar.setDevice)
+        self.ctrlToolbar.statusChange.connect(self.regview.refresh)
+        self.ctrlToolbar.codePosition.connect(self.pointCode)
+
+        # About dialog:
+        self.aboutDialog = AboutDialog()
+        self.aboutDialog.setWindowIcon(icon)
+
+        # Create actions:
+        def addMenuEntry(name, menu, callback, shortcut=None):
+            a = QAction(name, self)
+            menu.addAction(a)
+            a.triggered.connect(callback)
+            if shortcut:
+                a.setShortcut(shortcut)
+
+        addMenuEntry("New", self.fileMenu, self.newFile, shortcut=QKeySequence(QKeySequence.New))
+        addMenuEntry("Open", self.fileMenu, self.openFile, shortcut=QKeySequence(QKeySequence.Open))
+        addMenuEntry("Save", self.fileMenu, self.saveFile, shortcut=QKeySequence(QKeySequence.Save))
+        addMenuEntry("Build", self.fileMenu, self.buildFile, shortcut=QKeySequence("F7"))
+        addMenuEntry("Build and flash", self.fileMenu, self.buildFileAndFlash, shortcut=QKeySequence("F8"))
+
+        self.helpAction = QAction('Help', self)
+        self.helpAction.setShortcut(QKeySequence('F1'))
+        self.helpMenu.addAction(self.helpAction)
+        addMenuEntry('About', self.helpMenu, self.aboutDialog.open)
+
+        addMenuEntry('Cascade windows', self.viewMenu, self.mdiArea.cascadeSubWindows)
+        addMenuEntry('Tile windows', self.viewMenu, self.mdiArea.tileSubWindows)
+        sb = self.statusBar()
+
+        # Load settings:
+        self.settings = QSettings('windelsoft', 'lcfoside')
+        self.loadSettings()
+        self.diag = ppci.DiagnosticsManager()
+        self.c3front = c3.Builder(self.diag)
+
+    # File handling:
+    def newFile(self):
+        self.newCodeEdit()
+
+    def openFile(self):
+        filename = QFileDialog.getOpenFileName(self, "Open C3 file...", "*.c3",
+                    "C3 source files (*.c3)")
+        if filename:
+            self.loadFile(filename)
+
+    def saveFile(self):
+        ac = self.activeMdiChild()
+        if ac:
+            ac.save()
+
+    def loadFile(self, filename):
+        ce = self.newCodeEdit()
+        try:
+            with open(filename) as f:
+                ce.Source = f.read()
+                ce.FileName = filename
+        except Exception as e:
+            print('exception opening file', e)
+
+    # MDI:
+    def newCodeEdit(self):
+        ce = CodeEdit()
+        ce.textChanged.connect(self.parseFile)
+        w = self.mdiArea.addSubWindow(ce)
+        self.mdiArea.setActiveSubWindow(w)
+        ce.showMaximized()
+        return ce
+
+    def activeMdiChild(self):
+        aw = self.mdiArea.activeSubWindow()
+        if aw:
+            return aw.widget()
+
+    def findMdiChild(self, filename):
+        for wid in self.allChildren():
+            if wid.filename == filename:
+                return wid
+
+    def allChildren(self):
+        return [w.widget() for w in self.mdiArea.subWindowList()]
+
+    # Settings:
+    def loadSettings(self):
+        if self.settings.contains('mainwindowstate'):
+            self.restoreState(self.settings.value('mainwindowstate'))
+        if self.settings.contains('mainwindowgeometry'):
+            self.restoreGeometry(self.settings.value('mainwindowgeometry'))
+        if self.settings.contains('lastfiles'):
+            lfs = self.settings.value('lastfiles')
+            if lfs:
+                self.to_open_files.extend(lfs)
+
+    def showEvent(self, ev):
+        super().showEvent(ev)
+        while self.to_open_files:
+            fn = self.to_open_files.pop(0)
+            self.loadFile(fn)
+
+    def closeEvent(self, ev):
+        self.settings.setValue('mainwindowstate', self.saveState())
+        self.settings.setValue('mainwindowgeometry', self.saveGeometry())
+        ac = self.activeMdiChild()
+        lfs = [ce.FileName for ce in self.allChildren() if ce.FileName]
+        self.settings.setValue('lastfiles', lfs)
+        ev.accept()
+
+    # Error handling:
+    def nodeSelected(self, node):
+        self.showLoc(node.loc)
+
+    def showLoc(self, loc):
+        ce = self.activeMdiChild()
+        if not ce:
+            return
+        if loc:
+            ce.setRowCol(loc.row, loc.col)
+            ce.setFocus()
+
+    def pointCode(self, p):
+        # Lookup pc in debug infos:
+        loc = None
+        print(p)
+        self.disasm.showPos(p)
+        if hasattr(self, 'debugInfo'):
+            for di in self.debugInfo:
+                if di.address > p:
+                    loc = di.info
+                    break
+        if loc:
+            ce = self.activeMdiChild()
+            if ce:
+                ce.ic.arrow = loc
+            self.showLoc(loc)
+
+    # Build recepy:
+    def parseFile(self):
+        self.logger.info('Parsing!')
+        ce = self.activeMdiChild()
+        if not ce:
+            return
+        self.diag.clear()
+        pkg = self.c3front.parse(ce.Source)
+
+        # Set errors:
+        self.builderrors.setErrorList(self.diag.diags)
+        ce.setErrors(self.diag.diags)
+        self.astViewer.setAst(pkg)
+        if pkg:
+            c3.AstPrinter().printAst(pkg)
+        self.logger.info('Done!')
+
+    def buildFile(self):
+        ce = self.activeMdiChild()
+        if not ce:
+            return
+        fn = ce.FileName
+        self.diag.clear()
+        outs = outstream.TextOutputStream()
+        if not zcc.zcc([io.StringIO(ce.Source)], [], outs, self.diag):
+            # Set errors:
+            self.builderrors.setErrorList(self.diag.diags)
+            ce.setErrors(self.diag.diags)
+            return
+
+    def buildFileAndFlash(self):
+        ce = self.activeMdiChild()
+        if not ce:
+            return
+        fn = ce.FileName
+        self.diag.clear()
+        outs = outstream.TextOutputStream()
+        imps = [open(ce.FileName, 'r') for ce in self.allChildren() if ce.FileName and ce.FileName != fn]
+        if not zcc.zcc([open(fn, 'r')], imps, outs, self.diag):
+            # Set errors:
+            self.builderrors.setErrorList(self.diag.diags)
+            ce.setErrors(self.diag.diags)
+            return
+
+        outs.dump()
+        code_s = outs.getSection('code')
+        self.disasm.dm.setInstructions(code_s.instructions)
+        self.debugInfo = code_s.debugInfos()
+        if self.ctrlToolbar.device:
+            logging.info('Flashing stm32f4 discovery')
+            bts = code_s.to_bytes()
+            self.ctrlToolbar.device.writeFlash(0x08000000, bts)
+            stl = self.ctrlToolbar.device.iface
+            stl.reset()
+            stl.halt()
+            stl.run()
+            logging.info('Done!')
+        else:
+            self.logger.warning('Not connected to device, skipping flash')
+
+
+if __name__ == '__main__':
+    logging.basicConfig(format=zcc.logformat, level=logging.DEBUG)
+    app = QApplication(sys.argv)
+    ide = Ide()
+    ide.show()
+    ide.logger.info('IDE started')
+    app.exec_()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/ide/logview.py	Sun Nov 24 11:24:15 2013 +0100
@@ -0,0 +1,80 @@
+#!/usr/bin/python
+
+import sys
+import os
+import logging
+import datetime
+
+from PyQt4.QtGui import QApplication, QWidget, QTableView, QVBoxLayout
+from PyQt4.QtGui import QHeaderView
+from PyQt4.QtCore import Qt
+from PyQt4.QtCore import QAbstractTableModel
+
+def formatTime(t):
+    t2 = datetime.datetime.fromtimestamp(t)
+    return t2.strftime('%H:%M:%S')
+
+class LogModel(QAbstractTableModel):
+    def __init__(self):
+        super().__init__()
+        self.entries = []
+        self.headers = ['Time', 'Level', 'Logger', 'Message']
+        self.txts = []
+        self.txts.append(lambda e: str(formatTime(e.created)))
+        self.txts.append(lambda e: str(e.levelname))
+        self.txts.append(lambda e: str(e.name))
+        self.txts.append(lambda e: str(e.msg))
+
+    def rowCount(self, parent):
+        return len(self.entries)
+        
+    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:
+            le = self.entries[row]
+            return self.txts[col](le)
+
+    def headerData(self, section, orientation, role):
+        if orientation == Qt.Horizontal and role == Qt.DisplayRole:
+            return self.headers[section]
+            
+    def newLog(self, x):
+        self.entries.append(x)
+        self.modelReset.emit()
+
+
+class LogView(QWidget):
+    """ Log view component """
+    def __init__(self, parent=None):
+        super().__init__(parent)
+        l = QVBoxLayout(self)
+        self.tv = QTableView(self)
+        self.tv.horizontalHeader().setStretchLastSection(True)
+        l.addWidget(self.tv)
+        self.lm = LogModel()
+        self.tv.setModel(self.lm)
+    
+        class MyHandler(logging.Handler):
+            def emit(self2, x):
+                self.lm.newLog(x)
+                self.tv.scrollToBottom()
+                for i in range(3):
+                    self.tv.resizeColumnToContents(i)
+
+        logging.getLogger().addHandler(MyHandler())
+
+
+if __name__ == '__main__':
+    app = QApplication(sys.argv)
+    lv = LogView()
+    lv.show()
+    lv.resize(600, 200)
+    logging.error('Error!!!')
+    logging.warn('Warn here!')
+    app.exec_()
+
--- a/python/instructionselector.py	Thu Nov 21 15:46:50 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,60 +0,0 @@
-import ir
-import irmach
-from irmach import AbstractInstruction as makeIns
-import target
-
-def genTemps():
-    n = 900
-    while True:
-        yield ir.Temp('t{}'.format(n))
-        n = n + 1
-
-
-class InstructionSelector:
-    """
-        Base instruction selector. This class must be overridden by
-        backends.
-    """
-    def __init__(self):
-        self.temps = genTemps()
-
-    def newTmp(self):
-        return self.temps.__next__()
-
-    def munchFunction(self, f, frame):
-        # Entry point for instruction selection
-        assert isinstance(f, ir.Function)
-        self.targets = {}
-        # Enter a frame per function:
-        self.frame = frame
-        # First define labels:
-        for bb in f.Blocks:
-            itgt = makeIns(target.Label(bb.name))
-            self.targets[bb] = itgt
-        # Generate code for all blocks:
-        for bb in f.Blocks:
-            self.emit2(self.targets[bb])
-            for i in bb.Instructions:
-                self.munchStm(i)
-        self.munchStm(ir.Move(self.frame.rv, f.return_value))
-
-    def move(self, dst, src):
-        raise NotImplementedError('Not target implemented')
-
-    def emit(self, *args, **kwargs):
-        """ Abstract instruction emitter """
-        i = makeIns(*args, **kwargs)
-        return self.emit2(i)
-
-    def emit2(self, i):
-        self.frame.instructions.append(i)
-        return i
-
-    def munchStm(self, s):
-        """ Implement this in the target specific back-end """
-        raise NotImplementedError()
-
-    def munchExpr(self, e):
-        """ Implement this in the target specific back-end """
-        raise NotImplementedError()
-
--- a/python/integration_methods.py	Thu Nov 21 15:46:50 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,205 +0,0 @@
-import sys
-from random import random
-import numpy as np
-import pylab
-import time
-import scipy.integrate
-
-"""
-  This script compares different methods to solve an ODE.
-
-  The solved system consists of:
-  y_dot = f(y, t, p)
-  y0
-
-  where
-   y: the state vector of the system
-   y0: the initial state of the system
-   y_dot: the derivatives of the state vector
-   f: the function that returns the derivatives.
-   t: the time instant
-   p: the parameters of the system
-"""
-
-def func(y, t, parameters):
-   """
-    The example system is a bouncing point mass on a hunt-cossley surface.
-    State vector:
-    y[0] = height
-    y[1] = vertical momentum
-
-    y_dot[0] = velocity
-    y_dot[1] = force
-   """
-   # Step 1: extract the states into variables:
-   h = y[0]
-   p = y[1]
-   mass = parameters[0]
-   Kp_floor = parameters[1]
-   Kd_floor = parameters[2]
-
-   # Step 2: Calculate model:
-   v = p / mass
-
-   # Ground reaction force:
-   if h > 0:
-      F = 0.0
-   else:
-      F = -h * Kp_floor
-
-   # Gravity:
-   F += -9.81 * mass 
-   y_dot = np.array([v, F], dtype=np.float)
-   return y_dot
-
-parameters = np.array([3, 50000, 3000], dtype=np.float)
-y0 = np.array([1, 0], dtype=np.float) # Start at 1 meter, with 0 momentum
-
-class SCIPY:
-   def __init__(self, dt):
-      self.dt = dt
-   def name(self):
-      return "scipy.integrate"
-   def integrate(self, f, y0, parameters, endtime):
-      timevector = np.arange(0.0, endtime, self.dt)
-      states = scipy.integrate.odeint(f, y0, timevector, args=(parameters,))
-      return timevector, states
-
-class RK4:
-   def __init__(self, dt):
-      self.dt = dt
-
-   def name(self):
-      return "RK4"
-   def integrate(self, f, y0, parameters, endtime):
-      print(y0, parameters)
-      t = 0.0
-      states = []
-      timevector = []
-      state = y0
-      states.append(state)
-      timevector.append(t)
-      while t < endtime:
-         #### Runge Kutta integration:
-         k1 = func(state,             t, parameters)
-         k2 = func(state + 0.5*self.dt*k1, t, parameters)
-         k3 = func(state + 0.5*self.dt*k1, t, parameters)
-         k4 = func(state + self.dt*k3,     t, parameters)
-         newstate = state + (self.dt/6.0)*(k1+2*k2+2*k3+k4)
-
-         t += self.dt
-         state = newstate
-
-         states.append(state)
-         timevector.append(t)
-
-      return np.array(timevector, dtype=np.float), np.array(states, dtype=np.float)
-
-
-class BDFfixed:
-   def __init__(self, order):
-      self.order = order
-   def name(self):
-      return "BDF"
-   def integrate(self, f, y0, parameters, endtime):
-      timevector = []
-      states = []
-      timevector.append(0.0)
-      states.append(y0)
-      t = 0.0
-      h = 0.01
-      state = y0
-      while t < endtime:
-         if len(states) < 4:
-            k1 = func(state,             t, parameters)
-            k2 = func(state + 0.5*h*k1, t, parameters)
-            k3 = func(state + 0.5*h*k1, t, parameters)
-            k4 = func(state + h*k3,     t, parameters)
-            newstate = state + (h/6.0)*(k1+2*k2+2*k3+k4)
-            state = newstate
-            t += h
-            timevector.append(t)
-            states.append(state)
-         else:
-            t += h
-            if np.max(state) > 10:
-               break
-            hyn = (11.0/6.0)*states[-1] + (-3)*states[-2] + (3/2)*states[-3] + (-1/3)*states[-4]
-            state = state + hyn
-            timevector.append(t)
-            states.append(state)
-
-      return np.array(timevector, dtype=np.float), np.array(states, dtype=np.float)
-
-class WODE:
-   def __init__(self):
-      pass
-   def integrate(self, f, y0, parameters, endtime):
-      timevector = []
-      states = []
-      timevector.append(0.0)
-      states.append(y0)
-      return np.array(timevector, dtype=np.float), np.array(states, dtype=np.float)
-
-class DOPRI45:
-   def __init__(self):
-      pass
-   def name(self):
-      return "DOPRI"
-   def integrate(self, f, y0, parameters, endtime):
-      timevector = []
-      states = []
-      timevector.append(0.0)
-      states.append(y0)
-      y = y0
-      t = 0.0
-
-      h = 0.01
-      iteration = 0
-      while t < endtime:
-         k1 = h*f(y, t, parameters)
-         k2 = h*f(y + (1.0/5.0)*k1, t + (1.0/5.0)*h, parameters)
-         k3 = h*f(y + (3.0/40.0)*k1 + (9.0/40.0)*k2, t + (3.0/10.0)*h, parameters)
-         k4 = h*f(y + (44.0/45.0)*k1 - (56.0/15.0)*k2 + (32.0/9.0)*k3, t + (4.0/5.0)*h, parameters)
-         k5 = h*f(y + (19372.0/6561.0)*k1 - (25360.0/2187.0)*k2 + (64448.0/6561.0)*k3 - (212.0/729.0)*k4, t + (8.0/9.0)*h, parameters)
-         k6 = h*f(y + (9017.0/3168.0)*k1 - (355.0/33.0)*k2 - (46732.0/5247.0)*k3 + (49.0/176.0)*k4 - (5103.0/18656.0)*k5, t + h, parameters)
-         k7 = h*f(y + (35.0/384.0)*k1 + (500.0/1113.0)*k3 + (125.0/192.0)*k4 - (2187.0/6784.0)*k5 + (11.0/84.0)*k6, t + h, parameters)
-
-
-         y_next = y + (35.0/384.0)*k1 + (500.0/1113.0)*k3 + (125.0/192.0)*k4 - (2187.0/6784.0)*k5 + (11.0/84.0)*k6
-         z_next = y + (5179.0/57600.0)*k1 + (7571.0/16695.0)*k3 + (393.0/640.0)*k4 - (92097.0/339200.0)*k5 + (187.0/2100.0)*k6 + (1.0/40.0)*k7
-         error = np.linalg.norm(y_next - z_next)
-         #print(error, t)
-         eps = 0.01
-         if error < eps:
-            y = y_next
-            t = t + h
-            timevector.append(t)
-            states.append(y)
-
-         s = ((eps*h)/(2*error)) ** (1.0/5.0)
-         h = s * h
-         if h < 1e-5:
-            h = 1e-5
-         iteration += 1
-         if iteration > 10000:
-            break
-
-      return np.array(timevector, dtype=np.float), np.array(states, dtype=np.float)
-
-rk4 = RK4(0.01)
-sp = SCIPY(0.01)
-wode = BDFfixed(4)
-dopri = DOPRI45()
-methods = [rk4, sp, dopri]
-
-pylab.figure()
-pylab.hold(True)
-for method in methods:
-   t, s = method.integrate(func, y0, parameters, 10)
-   print(t.shape, s.shape)
-   pylab.plot(t, s[:,0], 'x-', label=method.name())
-
-pylab.legend()
-pylab.show()
-
--- a/python/isa/openrisc.lidl	Thu Nov 21 15:46:50 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,26 +0,0 @@
-
-// Openrisc description in lidl (lcfos isa description language)
-
-// Register storage:
-storage r {
-  width: 32
-  size: 32
-}
-
-
-instruction add {
-  encoding: '111111111DDDDDDAAAAAABBBBBB'
-  semantics: D = A + B
-}
-
-
-// ...
-
-instruction push {
-  encoding: ''
-  semantics: {
-    sp = X
-    sp  = sp - 4
-  }
-}
-
--- a/python/iso9660.py	Thu Nov 21 15:46:50 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,82 +0,0 @@
-#!/usr/bin/env python
-
-import argparse
-
-__doc__ = """
-  ISO 9660 filesystem utility.
-"""
-
-
-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)
-
-
-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)
-
-
-@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
-
-
-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__':
-    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/logview.py	Thu Nov 21 15:46:50 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,80 +0,0 @@
-#!/usr/bin/python
-
-import sys
-import os
-import logging
-import datetime
-
-from PyQt4.QtGui import QApplication, QWidget, QTableView, QVBoxLayout
-from PyQt4.QtGui import QHeaderView
-from PyQt4.QtCore import Qt
-from PyQt4.QtCore import QAbstractTableModel
-
-def formatTime(t):
-    t2 = datetime.datetime.fromtimestamp(t)
-    return t2.strftime('%H:%M:%S')
-
-class LogModel(QAbstractTableModel):
-    def __init__(self):
-        super().__init__()
-        self.entries = []
-        self.headers = ['Time', 'Level', 'Logger', 'Message']
-        self.txts = []
-        self.txts.append(lambda e: str(formatTime(e.created)))
-        self.txts.append(lambda e: str(e.levelname))
-        self.txts.append(lambda e: str(e.name))
-        self.txts.append(lambda e: str(e.msg))
-
-    def rowCount(self, parent):
-        return len(self.entries)
-        
-    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:
-            le = self.entries[row]
-            return self.txts[col](le)
-
-    def headerData(self, section, orientation, role):
-        if orientation == Qt.Horizontal and role == Qt.DisplayRole:
-            return self.headers[section]
-            
-    def newLog(self, x):
-        self.entries.append(x)
-        self.modelReset.emit()
-
-
-class LogView(QWidget):
-    """ Log view component """
-    def __init__(self, parent=None):
-        super().__init__(parent)
-        l = QVBoxLayout(self)
-        self.tv = QTableView(self)
-        self.tv.horizontalHeader().setStretchLastSection(True)
-        l.addWidget(self.tv)
-        self.lm = LogModel()
-        self.tv.setModel(self.lm)
-    
-        class MyHandler(logging.Handler):
-            def emit(self2, x):
-                self.lm.newLog(x)
-                self.tv.scrollToBottom()
-                for i in range(3):
-                    self.tv.resizeColumnToContents(i)
-
-        logging.getLogger().addHandler(MyHandler())
-
-
-if __name__ == '__main__':
-    app = QApplication(sys.argv)
-    lv = LogView()
-    lv.show()
-    lv.resize(600, 200)
-    logging.error('Error!!!')
-    logging.warn('Warn here!')
-    app.exec_()
-
--- a/python/msp430.py	Thu Nov 21 15:46:50 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,247 +0,0 @@
-from target import Register, Instruction, Target
-from asmnodes import ASymbol, ANumber
-from ppci import CompilerError
-import struct, types
-
-# Create the target class (singleton):
-msp430target = Target("MSP430")
-
-REGISTER_MODE = 1
-SYMBOLIC_MODE = 3
-ABSOLUTE_MODE = 4
-#TODO: add more modes!
-IMMEDIATE_MODE = 7
-
-# Target description for the MSP430 processor
-
-class MSP430Reg(Register):
-    def __init__(self, num, name):
-        super().__init__(name)
-        self.num = num
-
-# 8 bit registers:
-PCB = MSP430Reg(0, 'r0')
-rpc = PCB
-r11 = MSP430Reg(11, 'r11')
-r12 = MSP430Reg(12, 'r12')
-r13 = MSP430Reg(13, 'r13')
-r14 = MSP430Reg(14, 'r14')
-r15 = MSP430Reg(15, 'r15')
-
-class MSP430Mem:
-    pass
-
-msp430target.registers.append(r11)
-msp430target.registers.append(r12)
-msp430target.registers.append(r13)
-msp430target.registers.append(r14)
-msp430target.registers.append(r15)
-
-# .. etc
-
-#GR8 = RegisterClass((PCB, R15B))
-
-class MSP430Operand:
-    def __init__(self, mode, param):
-        self.mode = mode
-        self.param = param
-    def regField(self):
-        if self.mode == REGISTER_MODE:
-            return self.param
-        elif self.mode == IMMEDIATE_MODE:
-            return rpc.num
-    def asField(self):
-        if self.mode == REGISTER_MODE:
-            return 0
-        elif self.mode == IMMEDIATE_MODE:
-            return 3
-    def adField(self):
-        if self.mode == REGISTER_MODE:
-            return 0
-        elif self.mode == IMMEDIATE_MODE:
-            raise CompilerError('Cannot use immediate mode for destination operand')
-    def extraBytes(self):
-        if self.mode == IMMEDIATE_MODE:
-            return pack_ins(self.param)
-        return bytes()
-    
-    @classmethod
-    def Create(cls, vop):
-        if type(vop) is ASymbol:
-            # try to map to register:
-            regs = {}
-            for r in msp430target.registers:
-                regs[r.name] = r
-            if vop.name in regs:
-                reg = regs[vop.name]
-                return cls(REGISTER_MODE, reg.num)
-        elif type(vop) is ANumber:
-            # Immediate mode:
-            return cls(IMMEDIATE_MODE, vop.number)
-
-def pack_ins(h):
-    return struct.pack('<H', h)
-
-class MSP430Instruction(Instruction):
-    b = 0
-
-class BInstruction:
-    pass
-
-class MSP430CoreInstruction(Instruction):
-    pass
-
-#########################
-# Single operand arithmatic:
-#########################
-
-@msp430target.instruction
-class reti_ins(MSP430Instruction):
-    mnemonic = 'reti'
-    operands = ()
-    def encode(self):
-        h = 0x1300
-        return pack_ins(h)
-
-class OneOpArith(MSP430Instruction):
-    operands = (MSP430Reg, )
-    def __init__(self, op1):
-        self.op1 = op1
-    def encode(self):
-        # TODO:
-        bits[15:10] = '00100'
-        h1 = (self.opcode << 4)
-        return pack_ins(h1)
-
-def oneOpIns(mne, opc):
-    """ Helper function to define a one operand arithmetic instruction """
-    members = {'mnemonic': mne, 'opcode': opc}
-    ins_cls = type(mne + '_ins', (OneOpArith,), members)
-    msp430target.addInstruction(ins_cls)
-
-oneOpIns('rrc', 0)
-oneOpIns('swpb', 1)
-oneOpIns('rra', 2)
-oneOpIns('sxt', 3)
-oneOpIns('push', 4)
-oneOpIns('call', 5)
-
-#########################
-# Jump instructions:
-#########################
-
-class JumpInstruction(Instruction):
-    def __init__(self, offset):
-        self.offset = offset
-
-    def encode(self):
-        h = (1 << 13) | (self.condition << 10) | (self.offset)
-        return pack_ins(h)
-
-@msp430target.instruction
-class jnz_ins(JumpInstruction):
-    mnemonic = 'jnz'
-    condition = 0
-
-@msp430target.instruction
-class jz_ins(JumpInstruction):
-    mnemonic = 'jz'
-    condition = 1
-
-@msp430target.instruction
-class jnc_ins(JumpInstruction):
-    mnemonic = 'jnc'
-    condition = 2
-
-@msp430target.instruction
-class jc_ins(JumpInstruction):
-    mnemonic = 'jc'
-    condition = 3
-
-@msp430target.instruction
-class jn_ins(JumpInstruction):
-    mnemonic = 'jn'
-    condition = 4
-
-@msp430target.instruction
-class jge_ins(JumpInstruction):
-    mnemonic = 'jge'
-    condition = 5
-
-@msp430target.instruction
-class jl_ins(JumpInstruction):
-    mnemonic = 'jl'
-    condition = 6
-
-@msp430target.instruction
-class jmp_ins(JumpInstruction):
-    mnemonic = 'jmp'
-    condition = 7
-
-#########################
-# Two operand arithmatic instructions:
-#########################
-
-
-class TwoOpArith(MSP430Instruction):
-    operands = (MSP430Operand, MSP430Operand)
-    def __init__(self, src, dst):
-        self.op1 = src
-        self.op2 = dst
-
-    def encode(self):
-        """
-            Smart things have been done by MSP430 designers.
-            As (2 bits) is the source addressing mode selector.
-            Ad (1 bit) is the destination adressing mode selector.
-            For the source there are 7 different addressing mode.
-            For the destination there are 4.
-            The trick is to use also the register to distuingish the
-            different modes.
-        """
-        # TODO: Make memory also possible
-
-        As = self.op1.asField() # addressing mode for the source
-        Ad = self.op2.adField() # Addressing mode for dst
-        b = self.b # When b=1, the operation is byte mode
-        source = self.op1.regField()
-        destination = self.op2.regField()
-        h = (self.opcode << 12) | (source << 8)
-        h |= (self.b << 6) | (As << 4) | (Ad << 7) | destination
-        additions = self.op1.extraBytes() + self.op2.extraBytes()
-        return pack_ins(h) + additions
-
-    def decode(self, data):
-        pass
-
-
-def twoOpIns(mne, opc):
-    """ Helper function to define a two operand arithmetic instruction """
-    members = {'mnemonic': mne, 'opcode': opc}
-    ins_cls = type(mne + '_ins', (TwoOpArith,), members)
-    msp430target.addInstruction(ins_cls)
-
-twoOpIns('mov', 4)
-
-# This is equivalent to the helper function twoOpIns:
-@msp430target.instruction
-class add_ins(TwoOpArith):
-    """ Adds the source to the destination """
-    mnemonic = 'add'
-    opcode = 5
-
-    def operate(self):
-        dst.value = dst.value + src.value
-        setFlags()
-
-twoOpIns('addc', 6)
-twoOpIns('subc', 7)
-twoOpIns('sub', 8)
-twoOpIns('cmp', 9)
-twoOpIns('dadd', 10)
-twoOpIns('bit', 11)
-twoOpIns('bic', 12)
-twoOpIns('bis', 13)
-twoOpIns('xor', 14)
-twoOpIns('and', 15)
-
--- a/python/optimize.py	Thu Nov 21 15:46:50 2013 +0100
+++ b/python/optimize.py	Sun Nov 24 11:24:15 2013 +0100
@@ -17,6 +17,3 @@
     cse.run(ir)
     cf.run(ir)
     dcd.run(ir)
-
-
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/other/bouncing_cube.py	Sun Nov 24 11:24:15 2013 +0100
@@ -0,0 +1,406 @@
+from PyQt4.QtGui import *
+from PyQt4.QtCore import *
+from PyQt4.QtOpenGL import QGLWidget
+from OpenGL.GL import *
+from OpenGL.GLU import gluPerspective
+import sys
+from random import random
+from math import pi, cos, sin, fabs, sqrt
+from numpy import mat, array, ones, zeros, eye
+from numpy.linalg import norm
+import numpy as np
+import time
+import scipy.integrate
+#import pyopencl
+
+"""
+  Test script that lets a dice bounce.
+  Converted from 20-sim equations into python code.
+
+  20-sim website:
+    http://www.20sim.com
+
+"""
+def drawCube(w):
+      glBegin(GL_QUADS)			# Start Drawing The Cube
+      glColor3f(0.0,1.0,0.0)			# Set The Color To Blue
+      glVertex3f( w, w,-w)		# Top Right Of The Quad (Top)
+      glVertex3f(-w, w,-w)		# Top Left Of The Quad (Top)
+      glVertex3f(-w, w, w)		# Bottom Left Of The Quad (Top)
+      glVertex3f( w, w, w)		# Bottom Right Of The Quad (Top)
+
+      glColor3f(1.0,0.5,0.0)			# Set The Color To Orange
+      glVertex3f( w,-w, w)		# Top Right Of The Quad (Bottom)
+      glVertex3f(-w,-w, w)		# Top Left Of The Quad (Bottom)
+      glVertex3f(-w,-w,-w)		# Bottom Left Of The Quad (Bottom)
+      glVertex3f( w,-w,-w)		# Bottom Right Of The Quad (Bottom)
+
+      glColor3f(1.0,0.0,0.0)			# Set The Color To Red
+      glVertex3f( w, w, w)		# Top Right Of The Quad (Front)
+      glVertex3f(-w, w, w)		# Top Left Of The Quad (Front)
+      glVertex3f(-w,-w, w)		# Bottom Left Of The Quad (Front)
+      glVertex3f( w,-w, w)		# Bottom Right Of The Quad (Front)
+
+      glColor3f(1.0,1.0,0.0)			# Set The Color To Yellow
+      glVertex3f( w,-w,-w)		# Bottom Left Of The Quad (Back)
+      glVertex3f(-w,-w,-w)		# Bottom Right Of The Quad (Back)
+      glVertex3f(-w, w,-w)		# Top Right Of The Quad (Back)
+      glVertex3f( w, w,-w)		# Top Left Of The Quad (Back)
+
+      glColor3f(0.0,0.0,1.0)			# Set The Color To Blue
+      glVertex3f(-w, w, w)		# Top Right Of The Quad (Left)
+      glVertex3f(-w, w,-w)		# Top Left Of The Quad (Left)
+      glVertex3f(-w,-w,-w)		# Bottom Left Of The Quad (Left)
+      glVertex3f(-w,-w, w)		# Bottom Right Of The Quad (Left)
+
+      glColor3f(1.0,0.0,1.0)			# Set The Color To Violet
+      glVertex3f( w, w,-w)		# Top Right Of The Quad (Right)
+      glVertex3f( w, w, w)		# Top Left Of The Quad (Right)
+      glVertex3f( w,-w, w)		# Bottom Left Of The Quad (Right)
+      glVertex3f( w,-w,-w)		# Bottom Right Of The Quad (Right)
+      glEnd()				# Done Drawing The Quad
+
+def drawFloor(w, h):
+      glBegin(GL_QUADS)			# Start Drawing The Cube
+
+      glColor3f(1.0,0.5,0.0) # Set The Color To Orange
+      glVertex3f( w,-w,h)# Top Right Of The Quad (Bottom)
+      glVertex3f(-w,-w,h)# Top Left Of The Quad (Bottom)
+      glVertex3f(-w,w,h)# Bottom Left Of The Quad (Bottom)
+      glVertex3f( w,w,h)# Bottom Right Of The Quad (Bottom)
+      glEnd()				# Done Drawing The Quad
+
+def drawAxis():
+  glLineWidth(0.5)
+  glBegin(GL_LINES)
+  glColor3f(1.0, 0.0, 0.0)
+  glVertex3f(0,0,0)
+  glVertex3f(1,0,0)
+  glColor3f(0.0, 1.0, 0.0)
+  glVertex3f(0,0,0)
+  glVertex3f(0,1,0)
+  glColor3f(0.0, 0.0, 1.0)
+  glVertex3f(0,0,0)
+  glVertex3f(0,0,1)
+  glEnd()
+
+
+def cross(A, B):
+   a = A.A1
+   b = B.A1
+   return mat(np.cross(a, b)).T
+
+def skew(X):
+  Y = mat(zeros( (3, 3) ))
+  a,b,c = X.A1
+  Y[0,1] = -c
+  Y[0,2] = b
+  Y[1,0] = c
+  Y[1,2] = -a
+  Y[2,0] = -b
+  Y[2,1] = a
+  return Y
+
+def adjoint(T):
+  W = T[0:3, 0]
+  V = T[3:6, 0]
+  a = mat(zeros( (6,6) ) )
+  a[0:3, 0:3] = skew(W)
+  a[3:6, 0:3] = skew(V)
+  a[3:6, 3:6] = skew(W)
+  return a
+
+def Adjoint(H):
+  R = H[0:3, 0:3]
+  P = H[0:3, 3]
+  a = mat(zeros( (6,6) ) )
+  a[0:3, 0:3] = R
+  a[3:6, 3:6] = R
+  a[3:6, 0:3] = skew(P) * R
+  return a
+
+def quatToR(q):
+  x, y, z, w = q.A1
+  r = mat(eye(3))
+  r[0,0] = 1 - (2*y**2+2*z**2)
+  r[0,1] = 2*x*y+2*z*w
+  r[0,2] = 2*x*z - 2*y*w
+  r[1,0] = 2*x*y-2*z*w
+  r[1,1] = 1 - (2*x**2 + 2*z**2)
+  r[1,2] = 2*y*z + 2*x*w
+  r[2,0] = 2*x*z+2*y*w
+  r[2,1] = 2*y*z - 2*x*w
+  r[2,2] = 1 - (2*x**2+2*y**2)
+  return r
+
+def rotateAbout(axis, angle):
+   ax, ay, az = (axis/norm(axis)).A1
+   qx = ax*sin(angle/2.0)
+   qy = ay*sin(angle/2.0)
+   qz = az*sin(angle/2.0)
+   qw = cos(angle/2.0)
+   q = mat(array([qx,qy,qz,qw])).T
+   return q
+
+def normalizeQuaternion(quat):
+  x,y,z,w = quat.A1
+  magnitude = sqrt(x*x + y*y + z*z + w*w)
+  x = x / magnitude
+  y = y / magnitude
+  z = z / magnitude
+  w = w / magnitude
+  quat[0, 0] = x
+  quat[1, 0] = y
+  quat[2, 0] = z
+  quat[3, 0] = w
+  return quat
+
+def VTo4x4(V):
+    v1, v2, v3 = V.A1
+    return mat(array( \
+      [[0.0, -v3,  v2, -v1], \
+      [ v3,  0.0, -v1, -v2], \
+      [-v2, v1, 0.0, -v3], \
+      [v1, v2, v3, 0.0] ]))
+
+def homogeneous(R,p):
+    H = mat(eye(4))
+    H[0:3, 0:3] = R
+    H[0:3, 3] = p
+    return H
+
+def rateOfChange(states, thetime, parameters):
+    quat = states[0:4,  0] # Orientation (4)
+    pos  = states[4:7,  0] # Position (3)
+    P    = states[7:13, 0] # Momentum (6)
+    massI, gravity = parameters
+    # Rigid body parts:
+    # Forward Kinematic chain:
+    H = homogeneous(quatToR(quat), pos) # Forward kinematics
+
+    AdjX2 = mat(eye(6)) # The connectionpoint in the real world
+    adjAdjX2_1 = adjoint(AdjX2[0:6,0])
+    adjAdjX2_2 = adjoint(AdjX2[0:6,1])
+    adjAdjX2_3 = adjoint(AdjX2[0:6,2])
+    adjAdjX2_4 = adjoint(AdjX2[0:6,3])
+    adjAdjX2_5 = adjoint(AdjX2[0:6,4])
+    adjAdjX2_6 = adjoint(AdjX2[0:6,5])
+    AdjInv2 = Adjoint(H.I)
+    M2 = AdjInv2.T * (massI * AdjInv2) # Transfor mass to base frame
+    MassMatrix = M2
+
+    wrenchGrav2 = mat( zeros((1,6)) )
+    wrenchGrav2[0, 0:3] = -cross(gravity, pos).T
+    wrenchGrav2[0, 3:6] = gravity.T
+
+    Bk = mat( zeros( (6,6) ))
+    Bk[0:3, 0:3] = skew(P[0:3, 0])
+    Bk[3:6, 0:3] = skew(P[3:6, 0])
+    Bk[0:3, 3:6] = skew(P[3:6, 0])
+
+    # TODO: do this a cholesky:
+    v = np.linalg.solve(MassMatrix, P) # Matrix inverse like thingy !
+
+    T2_00 = v # Calculate the relative twist!
+    TM2 = T2_00.T * M2
+    twistExternal = T2_00 # Twist van het blokje
+    TMSum2 = TM2
+
+    PDotBodies = mat( zeros( (6,1)) )
+    PDotBodies[0,0] = TMSum2 * (adjAdjX2_1 * T2_00)
+    PDotBodies[1,0] = TMSum2 * (adjAdjX2_2 * T2_00)
+    PDotBodies[2,0] = TMSum2 * (adjAdjX2_3 * T2_00)
+    PDotBodies[3,0] = TMSum2 * (adjAdjX2_4 * T2_00)
+    PDotBodies[4,0] = TMSum2 * (adjAdjX2_5 * T2_00)
+    PDotBodies[5,0] = TMSum2 * (adjAdjX2_6 * T2_00)
+    
+    PDot = -PDotBodies - Bk * v
+    PDot += wrenchGrav2.T
+    
+    ##### Contact wrench part:
+    HB_W = H # Is H-matrix van het blokje
+    WrenchB = mat(zeros( (1,6) ))
+    for px in [-0.5, 0.5]:
+      for py in [-0.5, 0.5]:
+        for pz in [-0.5, 0.5]:
+          HB1_B = homogeneous(mat(eye(3)), mat([px,py,pz]).T)
+          HB1_W = HB_W * HB1_B
+          HW1_W = homogeneous(mat(eye(3)), HB1_W[0:3,3])
+          HW_W1 = HW1_W.I
+          HB_W1 = HW_W1 * HB_W
+    
+          AdjHB_W1 = Adjoint(HB_W1)
+          TB_W1_W1 = AdjHB_W1 * twistExternal
+          z = HB1_W[2, 3]
+          vx, vy, vz = TB_W1_W1[3:6, 0].A1
+          if z < 0:
+            # Contact forces:
+            Fx = -50.0*vx
+            Fy = -50.0*vy
+            Fz = -z*50000.0 
+          else:
+            Fx = 0.0
+            Fy = 0.0
+            Fz = 0.0
+          # TODO: reflect impulse
+          WrenchW1 = mat([0,0,0,0,0,Fz])
+          # Transform it back:
+          WrenchB += (AdjHB_W1.T * WrenchW1.T).T
+    ##### End of contact wrench
+
+    PDot += (WrenchB * AdjInv2).T
+
+    # Position and orientation rates:
+    QOmega = VTo4x4(v[0:3, 0])
+    quatDot = 0.5 * QOmega * quat
+    vel = v[3:6, 0]
+    posDot = skew(v[0:3]) * pos + vel
+    # The rate vector:
+    rates = mat(zeros( (13,1) ))
+    rates[0:4, 0] = quatDot
+    rates[4:7, 0] = posDot
+    rates[7:13, 0] = PDot
+    return rates
+
+def fWrapper(y, t, parameters):
+   y = mat(y).T
+   dy = rateOfChange(y, t, parameters)
+   return dy.T.A1
+  
+def SCIPY(endtime, dt, state, parameters):
+    times = np.arange(0.0, endtime, dt)
+    y0 = state.T.A1
+    res = scipy.integrate.odeint(fWrapper, y0, times, args=(parameters,))
+    states = []
+    res = res.T
+    r,c =  res.shape
+    for ci in range(0,c):
+      states.append(mat(res[:,ci]).T)
+    return states
+  
+def RK4(endtime, dt, state, parameters):
+    t = 0.0
+    states = []
+    while t < endtime:
+      newstate = mat (zeros( state.shape )) # Create a new object
+
+      #### Runge Kutta integration:
+      k1 = rateOfChange(state,             t, parameters)
+      k2 = rateOfChange(state + 0.5*dt*k1, t, parameters)
+      k3 = rateOfChange(state + 0.5*dt*k1, t, parameters)
+      k4 = rateOfChange(state + dt*k3,     t, parameters)
+      newstate = state + (dt/6.0)*(k1+2*k2+2*k3+k4)
+
+      # Normalize quat:
+      newstate[0:4, 0] = normalizeQuaternion(newstate[0:4, 0])
+      states.append(newstate)
+
+      state = newstate
+
+      t += dt
+      print(state[6,0], t, ' ', (t/endtime)*100.0, '%')
+    return states
+  
+
+def simulate(endtime, dt):
+    PInitial = mat( zeros((6,1)) )
+    posInitial = mat(array([-1.2, -1.3, 2.8])).T
+    quatInitial = rotateAbout(mat(array([0.2, 1.0, 0.4])).T, 0.5)
+    # Parameters:
+    gravity = mat( array([0,0,-9.81]) ).T
+    massI = mat(eye(6)) * 1.01 # Mass matrix
+    parameters = (massI, gravity)
+
+    # The state vector!
+    state = mat(zeros( (13,1) ))
+    state[0:4, 0] = quatInitial
+    state[4:7, 0] = posInitial
+    state[7:13, 0] = PInitial
+
+    return SCIPY(endtime, dt, state, parameters)
+
+class W(QGLWidget):
+  time = 0.0
+  index = 0
+  def __init__(self, states, dt, parent=None):
+    super(W, self).__init__(parent)
+    self.firstRun = True
+    self.savePNGS = False
+    self.dt = dt
+    self.resize(500,500)
+    self.states = states
+    self.UP()
+    t = QTimer(self)
+    t.timeout.connect(self.UP)
+    t.start(self.dt*1000.0)
+
+  def UP(self):
+    self.time += self.dt
+    if self.states:
+      state = self.states[self.index]
+      self.Dicequat = state[0:4, 0]
+      self.Dicepos = state[4:7, 0]
+      self.index += 1
+      if self.index == len(self.states):
+        self.index = 0
+        self.firstRun = False
+    # Paint:
+    self.update()
+    if self.firstRun:
+       # Create png images for the movie:
+       if self.savePNGS:
+          pm = self.renderPixmap()
+          pm.save('image'+str(self.index)+'.png')
+
+  def initializeGL(self):
+      glClearColor(0.0, 0.5, 0.0, 1.0)
+      glEnable(GL_DEPTH_TEST)
+      glDepthFunc(GL_LESS)
+      glShadeModel(GL_SMOOTH)
+  def resizeGL(self,w,h):
+      glViewport(0, 0, w, h)
+      glMatrixMode(GL_PROJECTION)
+      glLoadIdentity()
+      gluPerspective(45.0, float(w)/float(h), 0.1, 100.0)
+      glMatrixMode(GL_MODELVIEW)
+  def paintGL(self):
+      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) # Clear buffers
+      glLoadIdentity() # Reset The View
+
+      glLoadIdentity()
+      glTranslatef(0.0,-2.0,-10.0) # Move Left And Into The Screen
+      glRotatef(-90.0, 1.0, 0.0, 0.0)
+      drawFloor(2.0, 0.0)
+      drawAxis()
+      self.renderText(1.0, 0.0, 0.0, 'X')
+      self.renderText(0.0, 1.0, 0.0, 'Y')
+      self.renderText(0.0, 0.0, 1.0, 'Z')
+
+      self.renderText(0.0,0.0,1.2,str(self.time))
+
+      x,y,z = self.Dicepos.A1
+      R = quatToR(self.Dicequat)
+
+      glTranslatef(x, y, z)
+      # Trick to rotate the openGL matrix:
+      r = R.A1
+      rotR = (r[0], r[3], r[6], 0.0,
+              r[1], r[4], r[7], 0.0,
+              r[2], r[5], r[8], 0.0,
+              0.0,  0.0,  0.0,  1.0)
+      glMultMatrixd(rotR)
+      
+      drawCube(0.6)
+
+et = 20.0
+dt = 0.04
+print('starting integration... endtime =', et, ' stepsize =', dt)
+t0 = time.time()
+states = simulate(et, dt)
+t1 = time.time()
+print('That was heavy, it took me ', t1-t0, ' seconds!')
+app = QApplication(sys.argv)
+w = W(states, dt)
+w.show()
+sys.exit(app.exec_())
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/other/bouncing_cube_opencl.py	Sun Nov 24 11:24:15 2013 +0100
@@ -0,0 +1,406 @@
+from PyQt4.QtGui import *
+from PyQt4.QtCore import *
+from PyQt4.QtOpenGL import QGLWidget
+from OpenGL.GL import *
+from OpenGL.GLU import gluPerspective
+import sys
+from random import random
+from math import pi, cos, sin, fabs, sqrt
+from numpy import mat, array, ones, zeros, eye
+from numpy.linalg import norm
+import numpy as np
+import time
+import scipy.integrate
+import pyopencl
+
+"""
+  Test script that lets a dice bounce.
+  Converted from 20-sim equations into python code.
+
+  20-sim website:
+    http://www.20sim.com
+
+"""
+def drawCube(w):
+      glBegin(GL_QUADS)			# Start Drawing The Cube
+      glColor3f(0.0,1.0,0.0)			# Set The Color To Blue
+      glVertex3f( w, w,-w)		# Top Right Of The Quad (Top)
+      glVertex3f(-w, w,-w)		# Top Left Of The Quad (Top)
+      glVertex3f(-w, w, w)		# Bottom Left Of The Quad (Top)
+      glVertex3f( w, w, w)		# Bottom Right Of The Quad (Top)
+
+      glColor3f(1.0,0.5,0.0)			# Set The Color To Orange
+      glVertex3f( w,-w, w)		# Top Right Of The Quad (Bottom)
+      glVertex3f(-w,-w, w)		# Top Left Of The Quad (Bottom)
+      glVertex3f(-w,-w,-w)		# Bottom Left Of The Quad (Bottom)
+      glVertex3f( w,-w,-w)		# Bottom Right Of The Quad (Bottom)
+
+      glColor3f(1.0,0.0,0.0)			# Set The Color To Red
+      glVertex3f( w, w, w)		# Top Right Of The Quad (Front)
+      glVertex3f(-w, w, w)		# Top Left Of The Quad (Front)
+      glVertex3f(-w,-w, w)		# Bottom Left Of The Quad (Front)
+      glVertex3f( w,-w, w)		# Bottom Right Of The Quad (Front)
+
+      glColor3f(1.0,1.0,0.0)			# Set The Color To Yellow
+      glVertex3f( w,-w,-w)		# Bottom Left Of The Quad (Back)
+      glVertex3f(-w,-w,-w)		# Bottom Right Of The Quad (Back)
+      glVertex3f(-w, w,-w)		# Top Right Of The Quad (Back)
+      glVertex3f( w, w,-w)		# Top Left Of The Quad (Back)
+
+      glColor3f(0.0,0.0,1.0)			# Set The Color To Blue
+      glVertex3f(-w, w, w)		# Top Right Of The Quad (Left)
+      glVertex3f(-w, w,-w)		# Top Left Of The Quad (Left)
+      glVertex3f(-w,-w,-w)		# Bottom Left Of The Quad (Left)
+      glVertex3f(-w,-w, w)		# Bottom Right Of The Quad (Left)
+
+      glColor3f(1.0,0.0,1.0)			# Set The Color To Violet
+      glVertex3f( w, w,-w)		# Top Right Of The Quad (Right)
+      glVertex3f( w, w, w)		# Top Left Of The Quad (Right)
+      glVertex3f( w,-w, w)		# Bottom Left Of The Quad (Right)
+      glVertex3f( w,-w,-w)		# Bottom Right Of The Quad (Right)
+      glEnd()				# Done Drawing The Quad
+
+def drawFloor(w, h):
+      glBegin(GL_QUADS)			# Start Drawing The Cube
+
+      glColor3f(1.0,0.5,0.0) # Set The Color To Orange
+      glVertex3f( w,-w,h)# Top Right Of The Quad (Bottom)
+      glVertex3f(-w,-w,h)# Top Left Of The Quad (Bottom)
+      glVertex3f(-w,w,h)# Bottom Left Of The Quad (Bottom)
+      glVertex3f( w,w,h)# Bottom Right Of The Quad (Bottom)
+      glEnd()				# Done Drawing The Quad
+
+def drawAxis():
+  glLineWidth(0.5)
+  glBegin(GL_LINES)
+  glColor3f(1.0, 0.0, 0.0)
+  glVertex3f(0,0,0)
+  glVertex3f(1,0,0)
+  glColor3f(0.0, 1.0, 0.0)
+  glVertex3f(0,0,0)
+  glVertex3f(0,1,0)
+  glColor3f(0.0, 0.0, 1.0)
+  glVertex3f(0,0,0)
+  glVertex3f(0,0,1)
+  glEnd()
+
+
+def cross(A, B):
+   a = A.A1
+   b = B.A1
+   return mat(np.cross(a, b)).T
+
+def skew(X):
+  Y = mat(zeros( (3, 3) ))
+  a,b,c = X.A1
+  Y[0,1] = -c
+  Y[0,2] = b
+  Y[1,0] = c
+  Y[1,2] = -a
+  Y[2,0] = -b
+  Y[2,1] = a
+  return Y
+
+def adjoint(T):
+  W = T[0:3, 0]
+  V = T[3:6, 0]
+  a = mat(zeros( (6,6) ) )
+  a[0:3, 0:3] = skew(W)
+  a[3:6, 0:3] = skew(V)
+  a[3:6, 3:6] = skew(W)
+  return a
+
+def Adjoint(H):
+  R = H[0:3, 0:3]
+  P = H[0:3, 3]
+  a = mat(zeros( (6,6) ) )
+  a[0:3, 0:3] = R
+  a[3:6, 3:6] = R
+  a[3:6, 0:3] = skew(P) * R
+  return a
+
+def quatToR(q):
+  x, y, z, w = q.A1
+  r = mat(eye(3))
+  r[0,0] = 1 - (2*y**2+2*z**2)
+  r[0,1] = 2*x*y+2*z*w
+  r[0,2] = 2*x*z - 2*y*w
+  r[1,0] = 2*x*y-2*z*w
+  r[1,1] = 1 - (2*x**2 + 2*z**2)
+  r[1,2] = 2*y*z + 2*x*w
+  r[2,0] = 2*x*z+2*y*w
+  r[2,1] = 2*y*z - 2*x*w
+  r[2,2] = 1 - (2*x**2+2*y**2)
+  return r
+
+def rotateAbout(axis, angle):
+   ax, ay, az = (axis/norm(axis)).A1
+   qx = ax*sin(angle/2.0)
+   qy = ay*sin(angle/2.0)
+   qz = az*sin(angle/2.0)
+   qw = cos(angle/2.0)
+   q = mat(array([qx,qy,qz,qw])).T
+   return q
+
+def normalizeQuaternion(quat):
+  x,y,z,w = quat.A1
+  magnitude = sqrt(x*x + y*y + z*z + w*w)
+  x = x / magnitude
+  y = y / magnitude
+  z = z / magnitude
+  w = w / magnitude
+  quat[0, 0] = x
+  quat[1, 0] = y
+  quat[2, 0] = z
+  quat[3, 0] = w
+  return quat
+
+def VTo4x4(V):
+    v1, v2, v3 = V.A1
+    return mat(array( \
+      [[0.0, -v3,  v2, -v1], \
+      [ v3,  0.0, -v1, -v2], \
+      [-v2, v1, 0.0, -v3], \
+      [v1, v2, v3, 0.0] ]))
+
+def homogeneous(R,p):
+    H = mat(eye(4))
+    H[0:3, 0:3] = R
+    H[0:3, 3] = p
+    return H
+
+def rateOfChange(states, thetime, parameters):
+    quat = states[0:4,  0] # Orientation (4)
+    pos  = states[4:7,  0] # Position (3)
+    P    = states[7:13, 0] # Momentum (6)
+    massI, gravity = parameters
+    # Rigid body parts:
+    # Forward Kinematic chain:
+    H = homogeneous(quatToR(quat), pos) # Forward kinematics
+
+    AdjX2 = mat(eye(6)) # The connectionpoint in the real world
+    adjAdjX2_1 = adjoint(AdjX2[0:6,0])
+    adjAdjX2_2 = adjoint(AdjX2[0:6,1])
+    adjAdjX2_3 = adjoint(AdjX2[0:6,2])
+    adjAdjX2_4 = adjoint(AdjX2[0:6,3])
+    adjAdjX2_5 = adjoint(AdjX2[0:6,4])
+    adjAdjX2_6 = adjoint(AdjX2[0:6,5])
+    AdjInv2 = Adjoint(H.I)
+    M2 = AdjInv2.T * (massI * AdjInv2) # Transfor mass to base frame
+    MassMatrix = M2
+
+    wrenchGrav2 = mat( zeros((1,6)) )
+    wrenchGrav2[0, 0:3] = -cross(gravity, pos).T
+    wrenchGrav2[0, 3:6] = gravity.T
+
+    Bk = mat( zeros( (6,6) ))
+    Bk[0:3, 0:3] = skew(P[0:3, 0])
+    Bk[3:6, 0:3] = skew(P[3:6, 0])
+    Bk[0:3, 3:6] = skew(P[3:6, 0])
+
+    # TODO: do this a cholesky:
+    v = np.linalg.solve(MassMatrix, P) # Matrix inverse like thingy !
+
+    T2_00 = v # Calculate the relative twist!
+    TM2 = T2_00.T * M2
+    twistExternal = T2_00 # Twist van het blokje
+    TMSum2 = TM2
+
+    PDotBodies = mat( zeros( (6,1)) )
+    PDotBodies[0,0] = TMSum2 * (adjAdjX2_1 * T2_00)
+    PDotBodies[1,0] = TMSum2 * (adjAdjX2_2 * T2_00)
+    PDotBodies[2,0] = TMSum2 * (adjAdjX2_3 * T2_00)
+    PDotBodies[3,0] = TMSum2 * (adjAdjX2_4 * T2_00)
+    PDotBodies[4,0] = TMSum2 * (adjAdjX2_5 * T2_00)
+    PDotBodies[5,0] = TMSum2 * (adjAdjX2_6 * T2_00)
+    
+    PDot = -PDotBodies - Bk * v
+    PDot += wrenchGrav2.T
+    
+    ##### Contact wrench part:
+    HB_W = H # Is H-matrix van het blokje
+    WrenchB = mat(zeros( (1,6) ))
+    for px in [-0.5, 0.5]:
+      for py in [-0.5, 0.5]:
+        for pz in [-0.5, 0.5]:
+          HB1_B = homogeneous(mat(eye(3)), mat([px,py,pz]).T)
+          HB1_W = HB_W * HB1_B
+          HW1_W = homogeneous(mat(eye(3)), HB1_W[0:3,3])
+          HW_W1 = HW1_W.I
+          HB_W1 = HW_W1 * HB_W
+    
+          AdjHB_W1 = Adjoint(HB_W1)
+          TB_W1_W1 = AdjHB_W1 * twistExternal
+          z = HB1_W[2, 3]
+          vx, vy, vz = TB_W1_W1[3:6, 0].A1
+          if z < 0:
+            # Contact forces:
+            Fx = -50.0*vx
+            Fy = -50.0*vy
+            Fz = -z*50000.0 
+          else:
+            Fx = 0.0
+            Fy = 0.0
+            Fz = 0.0
+          # TODO: reflect impulse
+          WrenchW1 = mat([0,0,0,0,0,Fz])
+          # Transform it back:
+          WrenchB += (AdjHB_W1.T * WrenchW1.T).T
+    ##### End of contact wrench
+
+    PDot += (WrenchB * AdjInv2).T
+
+    # Position and orientation rates:
+    QOmega = VTo4x4(v[0:3, 0])
+    quatDot = 0.5 * QOmega * quat
+    vel = v[3:6, 0]
+    posDot = skew(v[0:3]) * pos + vel
+    # The rate vector:
+    rates = mat(zeros( (13,1) ))
+    rates[0:4, 0] = quatDot
+    rates[4:7, 0] = posDot
+    rates[7:13, 0] = PDot
+    return rates
+
+def fWrapper(y, t, parameters):
+   y = mat(y).T
+   dy = rateOfChange(y, t, parameters)
+   return dy.T.A1
+  
+def SCIPY(endtime, dt, state, parameters):
+    times = np.arange(0.0, endtime, dt)
+    y0 = state.T.A1
+    res = scipy.integrate.odeint(fWrapper, y0, times, args=(parameters,))
+    states = []
+    res = res.T
+    r,c =  res.shape
+    for ci in range(0,c):
+      states.append(mat(res[:,ci]).T)
+    return states
+  
+def RK4(endtime, dt, state, parameters):
+    t = 0.0
+    states = []
+    while t < endtime:
+      newstate = mat (zeros( state.shape )) # Create a new object
+
+      #### Runge Kutta integration:
+      k1 = rateOfChange(state,             t, parameters)
+      k2 = rateOfChange(state + 0.5*dt*k1, t, parameters)
+      k3 = rateOfChange(state + 0.5*dt*k1, t, parameters)
+      k4 = rateOfChange(state + dt*k3,     t, parameters)
+      newstate = state + (dt/6.0)*(k1+2*k2+2*k3+k4)
+
+      # Normalize quat:
+      newstate[0:4, 0] = normalizeQuaternion(newstate[0:4, 0])
+      states.append(newstate)
+
+      state = newstate
+
+      t += dt
+      print state[6,0], t, ' ', (t/endtime)*100.0, '%'
+    return states
+  
+
+def simulate(endtime, dt):
+    PInitial = mat( zeros((6,1)) )
+    posInitial = mat(array([-1.2, -1.3, 2.8])).T
+    quatInitial = rotateAbout(mat(array([0.2, 1.0, 0.4])).T, 0.5)
+    # Parameters:
+    gravity = mat( array([0,0,-9.81]) ).T
+    massI = mat(eye(6)) * 1.01 # Mass matrix
+    parameters = (massI, gravity)
+
+    # The state vector!
+    state = mat(zeros( (13,1) ))
+    state[0:4, 0] = quatInitial
+    state[4:7, 0] = posInitial
+    state[7:13, 0] = PInitial
+
+    return SCIPY(endtime, dt, state, parameters)
+
+class W(QGLWidget):
+  time = 0.0
+  index = 0
+  def __init__(self, states, dt, parent=None):
+    super(W, self).__init__(parent)
+    self.firstRun = True
+    self.savePNGS = False
+    self.dt = dt
+    self.resize(500,500)
+    self.states = states
+    self.UP()
+    t = QTimer(self)
+    t.timeout.connect(self.UP)
+    t.start(self.dt*1000.0)
+
+  def UP(self):
+    self.time += self.dt
+    if self.states:
+      state = self.states[self.index]
+      self.Dicequat = state[0:4, 0]
+      self.Dicepos = state[4:7, 0]
+      self.index += 1
+      if self.index == len(self.states):
+        self.index = 0
+        self.firstRun = False
+    # Paint:
+    self.update()
+    if self.firstRun:
+       # Create png images for the movie:
+       if self.savePNGS:
+          pm = self.renderPixmap()
+          pm.save('image'+str(self.index)+'.png')
+
+  def initializeGL(self):
+      glClearColor(0.0, 0.5, 0.0, 1.0)
+      glEnable(GL_DEPTH_TEST)
+      glDepthFunc(GL_LESS)
+      glShadeModel(GL_SMOOTH)
+  def resizeGL(self,w,h):
+      glViewport(0, 0, w, h)
+      glMatrixMode(GL_PROJECTION)
+      glLoadIdentity()
+      gluPerspective(45.0, float(w)/float(h), 0.1, 100.0)
+      glMatrixMode(GL_MODELVIEW)
+  def paintGL(self):
+      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) # Clear buffers
+      glLoadIdentity() # Reset The View
+
+      glLoadIdentity()
+      glTranslatef(0.0,-2.0,-10.0) # Move Left And Into The Screen
+      glRotatef(-90.0, 1.0, 0.0, 0.0)
+      drawFloor(2.0, 0.0)
+      drawAxis()
+      self.renderText(1.0, 0.0, 0.0, 'X')
+      self.renderText(0.0, 1.0, 0.0, 'Y')
+      self.renderText(0.0, 0.0, 1.0, 'Z')
+
+      self.renderText(0.0,0.0,1.2,str(self.time))
+
+      x,y,z = self.Dicepos.A1
+      R = quatToR(self.Dicequat)
+
+      glTranslatef(x, y, z)
+      # Trick to rotate the openGL matrix:
+      r = R.A1
+      rotR = (r[0], r[3], r[6], 0.0,
+              r[1], r[4], r[7], 0.0,
+              r[2], r[5], r[8], 0.0,
+              0.0,  0.0,  0.0,  1.0)
+      glMultMatrixd(rotR)
+      
+      drawCube(0.6)
+
+et = 20.0
+dt = 0.04
+print 'starting integration... endtime =', et, ' stepsize =', dt
+t0 = time.time()
+states = simulate(et, dt)
+t1 = time.time()
+print 'That was heavy, it took me ', t1-t0, ' seconds!'
+app = QApplication(sys.argv)
+w = W(states, dt)
+w.show()
+sys.exit(app.exec_())
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/other/diagrameditor.py	Sun Nov 24 11:24:15 2013 +0100
@@ -0,0 +1,316 @@
+#!/usr/bin/python
+
+from PyQt4.QtGui import *
+from PyQt4.QtCore import *
+import sys, json, base64
+
+from diagramitems import Connection, ResizeSelectionHandle, Block, DiagramScene, CodeBlock
+from icons import newicon, saveicon, loadicon
+import diagramitems
+
+"""
+ Author: Windel Bouwman
+ Year: 2012
+ Description: This script implements a diagram editor.
+ run with python 3.x as:
+  $ python [thisfile.py]
+"""
+def indent(lines):
+   return ['   ' + line for line in lines]
+
+class ParameterDialog(QDialog):
+   def __init__(self, block, parent = None):
+      super(ParameterDialog, self).__init__(parent)
+      self.block = block
+      self.button = QPushButton('Ok', self)
+      self.nameEdit = QLineEdit(self.block.name)
+      self.codeEdit = QTextEdit(self)
+      self.codeEdit.setPlainText(self.block.code)
+      l = QFormLayout(self)
+      l.addRow('Name:', self.nameEdit)
+      l.addRow('Code:', self.codeEdit)
+      l.addWidget(self.button)
+      self.button.clicked.connect(self.OK)
+   def OK(self):
+      self.block.name = self.nameEdit.text()
+      self.block.code = self.codeEdit.toPlainText()
+      self.close()
+
+class EditorGraphicsView(QGraphicsView):
+   def __init__(self, parent=None):
+      QGraphicsView.__init__(self, parent)
+      self.setDragMode(QGraphicsView.RubberBandDrag)
+      self.delShort = QShortcut(QKeySequence.Delete, self)
+      self._model = None
+      self.treeView = QTreeView()
+      self.treeView.clicked.connect(self.itemActivated)
+   def itemActivated(self, idx):
+      b = idx.internalPointer()
+      s = b.scene()
+      s.clearSelection()
+      b.setSelected(True)
+   def setDiagram(self, d):
+      self.setScene(d)
+      self.delShort.activated.connect(d.deleteItems)
+   def getModel(self): 
+      return self._model
+   def setModel(self, m):
+      self._model = m
+      if m:
+         self.treeView.setModel(m)
+         self.diagram = m.rootDiagram
+         self.model.modelReset.connect(self.treeView.expandAll)
+   model = property(getModel, setModel)
+   diagram = property(lambda s: s.scene(), setDiagram)
+   def save(self):
+      if self.model:
+         if not self.model.filename:
+            self.model.filename = QFileDialog.getSaveFileName(self)
+         if self.model.filename:
+            with open(self.model.filename, 'w') as f:
+               f.write(json.dumps(self.model.Dict, indent=2))
+   def load(self):
+      filename = QFileDialog.getOpenFileName(self)
+      if filename:
+         self.model = loadModel(filename)
+   def newModel(self):
+      self.model = ModelHierarchyModel()
+   def goUp(self):
+      if hasattr(self.diagram, 'containingBlock'):
+         self.diagram = self.diagram.containingBlock.scene()
+         self.zoomAll()
+   def showCode(self):
+      if self.model:
+         c = self.model.gencode()
+         c = '\n'.join(c)
+         d = QDialog()
+         l = QFormLayout(d)
+         codeview = QTextEdit()
+         codeview.setPlainText(c)
+         l.addRow('code', codeview)
+         runButton = QPushButton('Run')
+         outputview = QTextEdit()
+         l.addRow('Output', outputview)
+         l.addWidget(runButton)
+         def print2(txt):
+            txt2 = outputview.toPlainText()
+            outputview.setPlainText(txt2 + '\n' + txt)
+         def runIt():
+            outputview.clear()
+            globs = {'print': print2}
+            exec(codeview.toPlainText(), globs)
+         runButton.clicked.connect(runIt)
+         d.exec_()
+   def zoomAll(self):
+      """ zoom to fit all items """
+      rect = self.diagram.itemsBoundingRect()
+      self.fitInView(rect, Qt.KeepAspectRatio)
+   def wheelEvent(self, event):
+      pos = event.pos()
+      posbefore = self.mapToScene(pos)
+      degrees = event.delta() / 8.0
+      sx = (100.0 + degrees) / 100.0
+      self.scale(sx, sx)
+      event.accept()
+   def dragEnterEvent(self, event):
+      if event.mimeData().hasFormat('component/name'):
+         event.accept()
+   def dragMoveEvent(self, event):
+      if event.mimeData().hasFormat('component/name'): event.accept()
+   def dropEvent(self, event):
+      if event.mimeData().hasFormat('component/name'):
+         name = bytes(event.mimeData().data('component/name')).decode()
+         kind, name = name.split(':')
+         pos = self.mapToScene(event.pos())
+         s = self.scene()
+         if not s:
+            return
+         print(kind, 'name:', name)
+         kind = getattr(diagramitems, kind)
+         print(kind)
+         b = kind(s.uniqify(name))
+         b.setPos(pos)
+         s.addItem(b)
+
+class LibraryModel(QStandardItemModel):
+   mimeTypes = lambda self: ['component/name']
+   def mimeData(self, idxs):
+      mimedata = QMimeData()
+      for idx in idxs:
+         if idx.isValid():
+            txt = self.data(idx, Qt.DisplayRole)
+            mimedata.setData('component/name', txt)
+      return mimedata
+
+class ModelHierarchyModel(QAbstractItemModel):
+   def __init__(self):
+      super(ModelHierarchyModel, self).__init__()
+      self.rootDiagram = DiagramScene()
+      self.rootDiagram.structureChanged.connect(self.handlechange)
+      self.filename = None
+   def handlechange(self):
+      self.modelReset.emit()
+   def setDict(self, d):
+      self.rootDiagram.Dict = d
+      self.modelReset.emit()
+   def getDict(self):
+      return self.rootDiagram.Dict
+   Dict = property(getDict, setDict)
+   def gencode(self):
+      c = ['def topLevel():']
+      c += indent(self.rootDiagram.gencode())
+      c.append('print("Running model")')
+      c.append('topLevel()')
+      c.append('print("Done")')
+      return c
+   def index(self, row, column, parent=None):
+      if parent.isValid():
+         parent = parent.internalPointer().subModel
+      else:
+         parent = self.rootDiagram
+      blocks = sorted(parent.blocks, key=lambda b:  b.name)
+      block = blocks[row]
+      # Store the index to retrieve it later in the parent function.
+      # TODO: solve this in a better way.
+      block.index = self.createIndex(row, column, block)
+      return block.index
+   def parent(self, index):
+      if index.isValid():
+         block = index.internalPointer()
+         if block.scene() == self.rootDiagram:
+            return QModelIndex()
+         else:
+            print(block)
+            outerBlock = block.scene().containingBlock
+            return outerBlock.index
+      print('parent: No valid index')
+   def data(self, index, role):
+      if index.isValid() and role == Qt.DisplayRole:
+         b = index.internalPointer()
+         if index.column() == 0:
+            return b.name
+         elif index.column() == 1:
+            return str(type(b))
+   def headerData(self, section, orientation, role):
+      if orientation == Qt.Horizontal and role == Qt.DisplayRole:
+         if section == 0:
+            return "Element"
+         elif section == 1:
+            return "Type"
+         else:
+            return "x"
+   def rowCount(self, parent):
+      if parent.column() > 0: 
+         return 0
+      if parent.isValid():
+         block = parent.internalPointer()
+         if hasattr(block, 'subModel'):
+            return len(block.subModel.blocks)
+         else:
+            return 0
+      else:
+         return len(self.rootDiagram.blocks)
+   def columnCount(self, parent):
+      return 2
+
+class LibraryWidget(QListView):
+   def __init__(self):
+      super(LibraryWidget, self).__init__(None)
+      self.libraryModel = LibraryModel(self)
+      self.libraryModel.setColumnCount(1)
+      # Create an icon with an icon:
+      pixmap = QPixmap(60, 60)
+      pixmap.fill()
+      painter = QPainter(pixmap)
+      painter.fillRect(10, 10, 40, 40, Qt.blue)
+      painter.setBrush(Qt.yellow)
+      painter.drawEllipse(20, 20, 20, 20)
+      painter.end()
+      # Fill library:
+      for name in ['CodeBlock:codeBlock', 'DiagramBlock:submod', 'Block:blk']:
+         self.libraryModel.appendRow(QStandardItem(QIcon(pixmap), name))
+      self.setModel(self.libraryModel)
+      self.setViewMode(self.IconMode)
+      self.setDragDropMode(self.DragOnly)
+
+def warning(txt):
+   QMessageBox.warning(None, "Warning", txt)
+
+def loadModel(filename):
+   try:
+      m = ModelHierarchyModel()
+      with open(filename, 'r') as f: data = f.read()
+      m.filename = filename
+      m.Dict = json.loads(data)
+      return m
+   except KeyError:
+      warning('Corrupt model: {0}'.format(filename))
+   except ValueError:
+      warning('Corrupt model: {0}'.format(filename))
+   except FileNotFoundError:
+      warning('File [{0}] not found'.format(filename))
+
+class Main(QMainWindow):
+   def __init__(self):
+      super(Main, self).__init__(None)
+      self.editor = EditorGraphicsView()
+      self.setCentralWidget(self.editor)
+      self.setWindowTitle("Diagram editor")
+      def buildIcon(b64):
+         icon = base64.decodestring(b64)
+         pm = QPixmap()
+         pm.loadFromData(icon)
+         return QIcon(pm)
+      toolbar = self.addToolBar('Tools')
+      toolbar.setObjectName('Tools')
+      def act(name, shortcut, callback, icon=None):
+         a = QAction(icon, name, self) if icon else QAction(name, self)
+         a.setShortcuts(shortcut)
+         a.triggered.connect(callback)
+         toolbar.addAction(a)
+      act('New', QKeySequence.New, self.editor.newModel, buildIcon(newicon))
+      act('Save', QKeySequence.Save, self.editor.save, buildIcon(saveicon))
+      act('Load', QKeySequence.Open, self.editor.load, buildIcon(loadicon))
+      act('Full screen', QKeySequence("F11"), self.toggleFullScreen)
+      act('Fit in view', QKeySequence("F8"), self.editor.zoomAll)
+      act('Go up', QKeySequence(Qt.Key_Up), self.editor.goUp)
+      act('Model code', QKeySequence("F7"), self.editor.showCode)
+      def addDock(name, widget):
+         dock = QDockWidget(name, self)
+         dock.setObjectName(name)
+         dock.setWidget(widget)
+         self.addDockWidget(Qt.LeftDockWidgetArea, dock)
+      addDock('Library', LibraryWidget())
+      addDock('Model tree', self.editor.treeView)
+      self.settings = QSettings('windelsoft', 'diagrameditor')
+      self.loadSettings()
+   def toggleFullScreen(self):
+      self.setWindowState(self.windowState() ^ Qt.WindowFullScreen)
+      self.editor.zoomAll()
+   def loadSettings(self):
+      if self.settings.contains('mainwindowstate'):
+         self.restoreState(self.settings.value('mainwindowstate'))
+      if self.settings.contains('mainwindowgeometry'):
+         self.restoreGeometry(self.settings.value('mainwindowgeometry'))
+      if self.settings.contains('openedmodel'):
+         modelfile = self.settings.value('openedmodel')
+         self.editor.model = loadModel(modelfile)
+   def closeEvent(self, ev):
+      self.settings.setValue('mainwindowstate', self.saveState())
+      self.settings.setValue('mainwindowgeometry', self.saveGeometry())
+      if self.editor.model and self.editor.model.filename:
+         self.settings.setValue('openedmodel', self.editor.model.filename)
+         # TODO: ask for save of opened files
+      else:
+         self.settings.remove('openedmodel')
+      ev.accept()
+
+if __name__ == '__main__':
+   if sys.version_info.major != 3:
+      print('Please use python 3.x')
+      sys.exit(1)
+   app = QApplication(sys.argv)
+   main = Main()
+   main.show()
+   app.exec_()
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/other/integration_methods.py	Sun Nov 24 11:24:15 2013 +0100
@@ -0,0 +1,205 @@
+import sys
+from random import random
+import numpy as np
+import pylab
+import time
+import scipy.integrate
+
+"""
+  This script compares different methods to solve an ODE.
+
+  The solved system consists of:
+  y_dot = f(y, t, p)
+  y0
+
+  where
+   y: the state vector of the system
+   y0: the initial state of the system
+   y_dot: the derivatives of the state vector
+   f: the function that returns the derivatives.
+   t: the time instant
+   p: the parameters of the system
+"""
+
+def func(y, t, parameters):
+   """
+    The example system is a bouncing point mass on a hunt-cossley surface.
+    State vector:
+    y[0] = height
+    y[1] = vertical momentum
+
+    y_dot[0] = velocity
+    y_dot[1] = force
+   """
+   # Step 1: extract the states into variables:
+   h = y[0]
+   p = y[1]
+   mass = parameters[0]
+   Kp_floor = parameters[1]
+   Kd_floor = parameters[2]
+
+   # Step 2: Calculate model:
+   v = p / mass
+
+   # Ground reaction force:
+   if h > 0:
+      F = 0.0
+   else:
+      F = -h * Kp_floor
+
+   # Gravity:
+   F += -9.81 * mass 
+   y_dot = np.array([v, F], dtype=np.float)
+   return y_dot
+
+parameters = np.array([3, 50000, 3000], dtype=np.float)
+y0 = np.array([1, 0], dtype=np.float) # Start at 1 meter, with 0 momentum
+
+class SCIPY:
+   def __init__(self, dt):
+      self.dt = dt
+   def name(self):
+      return "scipy.integrate"
+   def integrate(self, f, y0, parameters, endtime):
+      timevector = np.arange(0.0, endtime, self.dt)
+      states = scipy.integrate.odeint(f, y0, timevector, args=(parameters,))
+      return timevector, states
+
+class RK4:
+   def __init__(self, dt):
+      self.dt = dt
+
+   def name(self):
+      return "RK4"
+   def integrate(self, f, y0, parameters, endtime):
+      print(y0, parameters)
+      t = 0.0
+      states = []
+      timevector = []
+      state = y0
+      states.append(state)
+      timevector.append(t)
+      while t < endtime:
+         #### Runge Kutta integration:
+         k1 = func(state,             t, parameters)
+         k2 = func(state + 0.5*self.dt*k1, t, parameters)
+         k3 = func(state + 0.5*self.dt*k1, t, parameters)
+         k4 = func(state + self.dt*k3,     t, parameters)
+         newstate = state + (self.dt/6.0)*(k1+2*k2+2*k3+k4)
+
+         t += self.dt
+         state = newstate
+
+         states.append(state)
+         timevector.append(t)
+
+      return np.array(timevector, dtype=np.float), np.array(states, dtype=np.float)
+
+
+class BDFfixed:
+   def __init__(self, order):
+      self.order = order
+   def name(self):
+      return "BDF"
+   def integrate(self, f, y0, parameters, endtime):
+      timevector = []
+      states = []
+      timevector.append(0.0)
+      states.append(y0)
+      t = 0.0
+      h = 0.01
+      state = y0
+      while t < endtime:
+         if len(states) < 4:
+            k1 = func(state,             t, parameters)
+            k2 = func(state + 0.5*h*k1, t, parameters)
+            k3 = func(state + 0.5*h*k1, t, parameters)
+            k4 = func(state + h*k3,     t, parameters)
+            newstate = state + (h/6.0)*(k1+2*k2+2*k3+k4)
+            state = newstate
+            t += h
+            timevector.append(t)
+            states.append(state)
+         else:
+            t += h
+            if np.max(state) > 10:
+               break
+            hyn = (11.0/6.0)*states[-1] + (-3)*states[-2] + (3/2)*states[-3] + (-1/3)*states[-4]
+            state = state + hyn
+            timevector.append(t)
+            states.append(state)
+
+      return np.array(timevector, dtype=np.float), np.array(states, dtype=np.float)
+
+class WODE:
+   def __init__(self):
+      pass
+   def integrate(self, f, y0, parameters, endtime):
+      timevector = []
+      states = []
+      timevector.append(0.0)
+      states.append(y0)
+      return np.array(timevector, dtype=np.float), np.array(states, dtype=np.float)
+
+class DOPRI45:
+   def __init__(self):
+      pass
+   def name(self):
+      return "DOPRI"
+   def integrate(self, f, y0, parameters, endtime):
+      timevector = []
+      states = []
+      timevector.append(0.0)
+      states.append(y0)
+      y = y0
+      t = 0.0
+
+      h = 0.01
+      iteration = 0
+      while t < endtime:
+         k1 = h*f(y, t, parameters)
+         k2 = h*f(y + (1.0/5.0)*k1, t + (1.0/5.0)*h, parameters)
+         k3 = h*f(y + (3.0/40.0)*k1 + (9.0/40.0)*k2, t + (3.0/10.0)*h, parameters)
+         k4 = h*f(y + (44.0/45.0)*k1 - (56.0/15.0)*k2 + (32.0/9.0)*k3, t + (4.0/5.0)*h, parameters)
+         k5 = h*f(y + (19372.0/6561.0)*k1 - (25360.0/2187.0)*k2 + (64448.0/6561.0)*k3 - (212.0/729.0)*k4, t + (8.0/9.0)*h, parameters)
+         k6 = h*f(y + (9017.0/3168.0)*k1 - (355.0/33.0)*k2 - (46732.0/5247.0)*k3 + (49.0/176.0)*k4 - (5103.0/18656.0)*k5, t + h, parameters)
+         k7 = h*f(y + (35.0/384.0)*k1 + (500.0/1113.0)*k3 + (125.0/192.0)*k4 - (2187.0/6784.0)*k5 + (11.0/84.0)*k6, t + h, parameters)
+
+
+         y_next = y + (35.0/384.0)*k1 + (500.0/1113.0)*k3 + (125.0/192.0)*k4 - (2187.0/6784.0)*k5 + (11.0/84.0)*k6
+         z_next = y + (5179.0/57600.0)*k1 + (7571.0/16695.0)*k3 + (393.0/640.0)*k4 - (92097.0/339200.0)*k5 + (187.0/2100.0)*k6 + (1.0/40.0)*k7
+         error = np.linalg.norm(y_next - z_next)
+         #print(error, t)
+         eps = 0.01
+         if error < eps:
+            y = y_next
+            t = t + h
+            timevector.append(t)
+            states.append(y)
+
+         s = ((eps*h)/(2*error)) ** (1.0/5.0)
+         h = s * h
+         if h < 1e-5:
+            h = 1e-5
+         iteration += 1
+         if iteration > 10000:
+            break
+
+      return np.array(timevector, dtype=np.float), np.array(states, dtype=np.float)
+
+rk4 = RK4(0.01)
+sp = SCIPY(0.01)
+wode = BDFfixed(4)
+dopri = DOPRI45()
+methods = [rk4, sp, dopri]
+
+pylab.figure()
+pylab.hold(True)
+for method in methods:
+   t, s = method.integrate(func, y0, parameters, 10)
+   print(t.shape, s.shape)
+   pylab.plot(t, s[:,0], 'x-', label=method.name())
+
+pylab.legend()
+pylab.show()
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/other/qtpropertyviewer.py	Sun Nov 24 11:24:15 2013 +0100
@@ -0,0 +1,103 @@
+from PyQt4.QtCore import *
+from PyQt4.QtGui import *
+import sys
+
+class QtPropertyModel(QAbstractTableModel):
+   def __init__(self):
+      super().__init__()
+      self.InspectedWidget = None
+   def getInspectedWidget(self):
+      return self.inspectedWidget
+   def setInspectedWidget(self, w):
+      self.inspectedWidget = w
+      if isinstance(self.inspectedWidget, QObject):
+         mo = self.inspectedWidget.metaObject()
+         self.metaprops = [mo.property(i) for i in range(mo.propertyCount())]
+         self.metaprops = sorted(self.metaprops, key=lambda mp: mp.name())
+      else:
+         self.metaprops = []
+      self.modelReset.emit()
+   InspectedWidget = property(getInspectedWidget, setInspectedWidget)
+   def rowCount(self, parent):
+      return len(self.metaprops)
+   def columnCount(self, parent):
+      return 2
+   def headerData(self, section, orientation, role):
+      if orientation == Qt.Horizontal and role == Qt.DisplayRole:
+         if section == 0:
+            return 'Property'
+         elif section == 1:
+            return 'Value'
+   def data(self, index, role):
+      if index.isValid():
+         row = index.row()
+         col = index.column()
+         metaprop = self.metaprops[row]
+         if role == Qt.DisplayRole:
+            propname = metaprop.name()
+            if col == 0:
+               return propname
+            elif col == 1:
+               if metaprop.isReadable():
+                  propval = metaprop.read(self.inspectedWidget)
+                  return propval
+               return 'NOT READABLE'
+            return '{0}, {1}'.format(row, col)
+         elif role == Qt.BackgroundRole:
+            if col == 1:
+               if metaprop.isWritable():
+                  return QBrush(Qt.green)
+               else:
+                  return QBrush(Qt.red)
+         elif role == Qt.CheckStateRole:
+            if col == 1:
+               val = metaprop.read(self.inspectedWidget)
+               if type(val) is bool:
+                  val = Qt.Checked if val else Qt.Unchecked
+                  return val
+
+   def flags(self, index):
+      if index.isValid():
+         row = index.row()
+         col = index.column()
+         metaprop = self.metaprops[row]
+         if col == 1 and metaprop.isWritable():
+            val = metaprop.read(self.inspectedWidget)
+            if type(val) == bool:
+               return super().flags(index) | Qt.ItemIsEditable | Qt.ItemIsUserCheckable
+            else:
+               return super().flags(index) | Qt.ItemIsEditable
+         else:
+            return super().flags(index)
+   def setData(self, index, value, role):
+      if index.isValid():
+         row = index.row()
+         col = index.column()
+         metaprop = self.metaprops[row]
+         if role == Qt.EditRole:
+            metaprop.write(self.inspectedWidget, value)
+            return True
+         elif role == Qt.CheckStateRole:
+            value = True if value == Qt.Checked else False
+            metaprop.write(self.inspectedWidget, value)
+            return True
+         else:
+            print('unknown role:', role)
+            return False
+      return False
+
+class QtPropertyViewer(QWidget):
+   """
+      The binviewer consists of a hex view, a ascii view
+      and perhaps others..
+   """
+   def __init__(self):
+      super().__init__()
+      tableView = QTableView()
+      l = QVBoxLayout(self)
+      l.addWidget(tableView)
+      header = tableView.horizontalHeader()
+      header.setResizeMode(QHeaderView.ResizeToContents)
+      self.propertyModel = QtPropertyModel()
+      tableView.setModel(self.propertyModel)
+
--- a/python/qtpropertyviewer.py	Thu Nov 21 15:46:50 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,103 +0,0 @@
-from PyQt4.QtCore import *
-from PyQt4.QtGui import *
-import sys
-
-class QtPropertyModel(QAbstractTableModel):
-   def __init__(self):
-      super().__init__()
-      self.InspectedWidget = None
-   def getInspectedWidget(self):
-      return self.inspectedWidget
-   def setInspectedWidget(self, w):
-      self.inspectedWidget = w
-      if isinstance(self.inspectedWidget, QObject):
-         mo = self.inspectedWidget.metaObject()
-         self.metaprops = [mo.property(i) for i in range(mo.propertyCount())]
-         self.metaprops = sorted(self.metaprops, key=lambda mp: mp.name())
-      else:
-         self.metaprops = []
-      self.modelReset.emit()
-   InspectedWidget = property(getInspectedWidget, setInspectedWidget)
-   def rowCount(self, parent):
-      return len(self.metaprops)
-   def columnCount(self, parent):
-      return 2
-   def headerData(self, section, orientation, role):
-      if orientation == Qt.Horizontal and role == Qt.DisplayRole:
-         if section == 0:
-            return 'Property'
-         elif section == 1:
-            return 'Value'
-   def data(self, index, role):
-      if index.isValid():
-         row = index.row()
-         col = index.column()
-         metaprop = self.metaprops[row]
-         if role == Qt.DisplayRole:
-            propname = metaprop.name()
-            if col == 0:
-               return propname
-            elif col == 1:
-               if metaprop.isReadable():
-                  propval = metaprop.read(self.inspectedWidget)
-                  return propval
-               return 'NOT READABLE'
-            return '{0}, {1}'.format(row, col)
-         elif role == Qt.BackgroundRole:
-            if col == 1:
-               if metaprop.isWritable():
-                  return QBrush(Qt.green)
-               else:
-                  return QBrush(Qt.red)
-         elif role == Qt.CheckStateRole:
-            if col == 1:
-               val = metaprop.read(self.inspectedWidget)
-               if type(val) is bool:
-                  val = Qt.Checked if val else Qt.Unchecked
-                  return val
-
-   def flags(self, index):
-      if index.isValid():
-         row = index.row()
-         col = index.column()
-         metaprop = self.metaprops[row]
-         if col == 1 and metaprop.isWritable():
-            val = metaprop.read(self.inspectedWidget)
-            if type(val) == bool:
-               return super().flags(index) | Qt.ItemIsEditable | Qt.ItemIsUserCheckable
-            else:
-               return super().flags(index) | Qt.ItemIsEditable
-         else:
-            return super().flags(index)
-   def setData(self, index, value, role):
-      if index.isValid():
-         row = index.row()
-         col = index.column()
-         metaprop = self.metaprops[row]
-         if role == Qt.EditRole:
-            metaprop.write(self.inspectedWidget, value)
-            return True
-         elif role == Qt.CheckStateRole:
-            value = True if value == Qt.Checked else False
-            metaprop.write(self.inspectedWidget, value)
-            return True
-         else:
-            print('unknown role:', role)
-            return False
-      return False
-
-class QtPropertyViewer(QWidget):
-   """
-      The binviewer consists of a hex view, a ascii view
-      and perhaps others..
-   """
-   def __init__(self):
-      super().__init__()
-      tableView = QTableView()
-      l = QVBoxLayout(self)
-      l.addWidget(tableView)
-      header = tableView.horizontalHeader()
-      header.setResizeMode(QHeaderView.ResizeToContents)
-      self.propertyModel = QtPropertyModel()
-      tableView.setModel(self.propertyModel)
-
--- a/python/target.py	Thu Nov 21 15:46:50 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,198 +0,0 @@
-from asmnodes import ASymbol, AInstruction, ANumber
-from ppci import CompilerError
-
-"""
-  Base classes for defining a target
-"""
-
-# Machine code interface:
-class Operand:
-   """ Single machine operand """
-   pass
-
-# standard immediates:
-
-class Imm8:
-    def __init__(self, imm):
-        assert imm < 256
-        self.imm = imm
-
-    @classmethod
-    def Create(cls, vop):
-        if type(vop) is ANumber and vop.number < 256:
-            return cls(vop.number)
-
-class Imm7:
-    def __init__(self, imm):
-        assert imm < 128
-        self.imm = imm
-
-    @classmethod
-    def Create(cls, vop):
-        if type(vop) is ANumber and vop.number < 128:
-            return cls(vop.number)
-
-class Imm3:
-    def __init__(self, imm):
-        assert imm < 8
-        assert type(imm) is int
-        self.imm = imm
-
-    @classmethod
-    def Create(cls, vop):
-        if type(vop) is ANumber and vop.number < 8:
-            return cls(vop.number)
-
-class Imm32:
-    def __init__(self, imm):
-        assert imm < 2**32
-        assert type(imm) is int
-        self.imm = imm
-
-    @classmethod
-    def Create(cls, vop):
-        if type(vop) is ANumber and vop.number < 2**32:
-            return cls(vop.number)
-
-
-class LabelRef:
-    def __init__(self, name):
-        assert type(name) is str
-        self.name = name
-
-    @classmethod
-    def Create(cls, vop):
-        if type(vop) is ASymbol:
-            return cls(vop.name)
-
-class Instruction:
-    def encode(self):
-        raise NotImplementedError('Instruction {0} has no encode yet, TODO'.format(type(self)))
-    def resolve(self, f):
-        pass
-
-
-class Nop(Instruction):
-    """ Instruction that does nothing and has zero size """
-    def encode(self):
-        return bytes()
-
-    
-
-class PseudoInstruction(Instruction):
-    pass
-
-
-class Label(PseudoInstruction):
-    def __init__(self, name):
-        self.name = name
-        self.address = 0
-
-    def __repr__(self):
-        return '{}:'.format(self.name)
-
-    def encode(self):
-        return bytes()
-
-    @classmethod
-    def Create(cls, vop):
-        if type(vop) is ASymbol:
-            name = vop.name
-            return cls(name)
-
-
-class Comment(PseudoInstruction):
-    def __init__(self, txt):
-        self.txt = txt
-
-    def encode(self):
-        return bytes()
-
-    def __repr__(self):
-        return '; {}'.format(self.txt)
-
-
-class Alignment(PseudoInstruction):
-    def __init__(self, a):
-        self.align = a
-
-    def __repr__(self):
-        return 'ALIGN({})'.format(self.align)
-
-    def encode(self):
-        pad = []
-        address = self.address
-        while (address % self.align) != 0:
-            address += 1
-            pad.append(0)
-        return bytes(pad)
-
-class DebugInfo(PseudoInstruction):
-    def __init__(self, i):
-        self.info = i
-
-    def __repr__(self):
-        return 'DebugInfo: {}'.format(self.info)
-
-    def encode(self):
-        return bytes()
-
-class Register(Operand):
-    def __init__(self, name):
-        self.name = name
-
-
-class Target:
-    def __init__(self, name, desc=''):
-        self.name = name
-        self.desc = desc
-        self.registers = []
-        self.instructions = []
-
-    def instruction(self, cls):
-        """ Decorator function that registers an instruction to this target """
-        self.addInstruction(cls)
-        return cls
-
-    def check(self):
-        """ Check target """
-        for i in self.instructions:
-            assert hasattr(i, 'mnemonic')
-            assert hasattr(i, 'operands'), str(i)
-            assert type(i.mnemonic) is str
-            assert type(i.operands) is tuple, str(i)
-
-    def addInstruction(self, ins_class):
-        self.instructions.append(ins_class)
-
-    def mapOperand(self, operand):
-        """ Try to map an operand to a target type """
-        if type(operand) is ASymbol:
-            # Try to map to register:
-            regs = {}
-            for r in self.registers:
-                regs[r.name] = r
-            if operand.name in regs:
-                return regs[operand.name]
-        raise CompilerError('Cannot map {0}'.format(operand))
-
-    def mapInstruction(self, vi):
-        assert type(vi) is AInstruction
-        """ Map ast tree to real instruction for this target """
-
-        # map to real operands:
-        if vi.mnemonic.upper() == 'ALIGN' and len(vi.operands) == 1:
-            if type(vi.operands[0]) == ANumber:
-                return Alignment(vi.operands[0].number)
-
-        # look for a suitable instruction
-        for ic in self.instructions:
-            if ic.mnemonic.upper() == vi.mnemonic.upper() and len(ic.operands) == len(vi.operands):
-                # Try to map operands to the correct operand types:
-                rops = [roptype.Create(vop) for roptype, vop in zip(ic.operands, vi.operands)]
-
-                # Check if we succeeded:
-                if all(isinstance(rop, optype) for rop, optype in zip(rops, ic.operands)):
-                    return ic(*rops)
-        raise CompilerError('No suitable instruction found for "{0}"'.format(vi))
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/target/__init__.py	Sun Nov 24 11:24:15 2013 +0100
@@ -0,0 +1,8 @@
+#!/usr/bin/env python
+
+from .basetarget import Nop, Instruction, Label, Target, Comment, Alignment
+from .basetarget import Imm32, DebugInfo
+#from .armtarget import armtarget
+#from .msp430target import msp430target
+
+#target_list = [armtarget, msp430target]
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/target/armframe.py	Sun Nov 24 11:24:15 2013 +0100
@@ -0,0 +1,219 @@
+import ir
+from ppci import CompilerError
+from .basetarget import Label, Comment, Alignment, LabelRef, DebugInfo, Nop
+from .basetarget import Imm32, Imm3
+import .armtarget as arm
+from .instructionselector import InstructionSelector
+import irmach
+from irmach import AbstractInstruction as makeIns
+import asm
+
+
+class ArmFrame(irmach.Frame):
+    """
+      Arm specific frame for functions.
+    """
+    def __init__(self, name):
+        # We use r7 as frame pointer.
+        super().__init__(name)
+        self.regs = [arm.r0, arm.r1, arm.r2, arm.r3, arm.r4, arm.r5, arm.r6]
+        self.rv = ir.Temp('special_RV')
+        self.p1 = ir.Temp('special_P1')
+        self.p2 = ir.Temp('special_P2')
+        self.p3 = ir.Temp('special_P3')
+        self.p4 = ir.Temp('special_P4')
+        self.fp = ir.Temp('special_FP')
+        # Pre-colored registers:
+        self.tempMap = {}
+        self.tempMap[self.rv] = arm.r0
+        self.tempMap[self.p1] = arm.r1
+        self.tempMap[self.p2] = arm.r2
+        self.tempMap[self.p3] = arm.r3
+        self.tempMap[self.p4] = arm.r4
+        self.tempMap[self.fp] = arm.r7
+        self.locVars = {}
+        self.parMap = {}
+        # Literal pool:
+        self.constants = []
+
+    def argLoc(self, pos):
+        """
+            Gets the function parameter location in IR-code format.
+        """
+        if pos == 0:
+            return self.p1
+        elif pos == 1:
+            return self.p2
+        elif pos == 2:
+            return self.p3
+        elif pos == 3:
+            return self.p4
+        else:
+            raise NotImplementedError('No more than 4 parameters implemented')
+
+    def allocVar(self, lvar):
+        if lvar not in self.locVars:
+            self.locVars[lvar] = self.stacksize
+            self.stacksize = self.stacksize + 4
+        return self.locVars[lvar]
+
+    def addConstant(self, value):
+        lab_name = '{}_literal_{}'.format(self.name, len(self.constants))
+        self.constants.append((lab_name, value))
+        return lab_name
+
+    def EntryExitGlue3(self):
+        """
+            Add code for the prologue and the epilogue. Add a label, the
+            return instruction and the stack pointer adjustment for the frame.
+        """
+        self.instructions.insert(0, makeIns(arm.Label(self.name)))
+        self.instructions.insert(1, makeIns(arm.push_ins(arm.RegisterSet({arm.lr, arm.r7}))))
+        # Reserve stack space for locals:
+        self.instructions.insert(2, makeIns(arm.subspsp_ins(arm.sp, arm.sp, arm.Imm7(self.stacksize))))
+        # Setup frame pointer:
+        self.instructions.insert(3, makeIns(arm.movregreg_ext_ins(arm.r7, arm.sp)))
+        # Stack grows downwards
+        self.instructions.append(makeIns(arm.addspsp_ins(arm.sp, arm.sp, arm.Imm7(self.stacksize))))
+        self.instructions.append(makeIns(arm.pop_ins(arm.RegisterSet({arm.pc, arm.r7}))))
+        # Add constant literals:
+        self.instructions.append(makeIns(Alignment(4))) # Align at 4 bytes
+        for ln, v in self.constants:
+            self.instructions.append(makeIns(arm.Label(ln)))
+            self.instructions.append(makeIns(arm.dcd_ins(v)))
+
+
+class ArmInstructionSelector(InstructionSelector):
+    """ Instruction selector for the arm architecture """
+    def munchExpr(self, e):
+        if isinstance(e, ir.Alloc):
+            return 0
+        elif isinstance(e, ir.Binop) and e.operation == '+' and \
+            isinstance(e.b, ir.Const) and e.b.value < 8:
+            a = self.munchExpr(e.a)
+            d = self.newTmp()
+            c = Imm3(e.b.value)
+            self.emit(arm.addregregimm3_ins, others=[c], dst=[d], src=[a])
+            return d
+        elif isinstance(e, ir.Binop) and e.operation == '+':
+            a = self.munchExpr(e.a)
+            b = self.munchExpr(e.b)
+            d = self.newTmp()
+            self.emit(arm.addregs_ins, dst=[d], src=[a, b])
+            return d
+        elif isinstance(e, ir.Binop) and e.operation == '-' and \
+            isinstance(e.b, ir.Const) and e.b.value < 8:
+            a = self.munchExpr(e.a)
+            d = self.newTmp()
+            c = Imm3(e.b.value)
+            self.emit(arm.subregregimm3_ins, others=[c], dst=[d], src=[a])
+            return d
+        elif isinstance(e, ir.Binop) and e.operation == '-':
+            a = self.munchExpr(e.a)
+            b = self.munchExpr(e.b)
+            d = self.newTmp()
+            self.emit(arm.subregs_ins, dst=[d], src=[a, b])
+            return d
+        elif isinstance(e, ir.Binop) and e.operation == '|':
+            a = self.munchExpr(e.a)
+            b = self.munchExpr(e.b)
+            d = self.newTmp()
+            self.move(d, a)
+            self.emit(arm.orrregs_ins, dst=[], src=[b, d])
+            return d
+        elif isinstance(e, ir.Binop) and e.operation == '<<':
+            a = self.munchExpr(e.a)
+            b = self.munchExpr(e.b)
+            d = self.newTmp()
+            self.move(d, a)
+            self.emit(arm.lslregs_ins, dst=[], src=[b, d]) # TODO: is d a source variable?
+            return d
+        elif isinstance(e, ir.Binop) and e.operation == '*':
+            a = self.munchExpr(e.a)
+            b = self.munchExpr(e.b)
+            d = self.newTmp()
+            self.move(d, a)
+            # this mul instruction has operands swapped:
+            self.emit(arm.mulregreg_ins, dst=[d], src=[b, d])
+            return d
+        elif isinstance(e, ir.Const) and e.value < 256:
+            d = self.newTmp()
+            self.emit(arm.mov_imm8_ins, others=[arm.Imm8(e.value)], dst=[d])
+            return d
+        elif isinstance(e, ir.Const) and e.value < (2**31):
+            d = self.newTmp()
+            ln = LabelRef(self.frame.addConstant(e.value))
+            self.emit(arm.ldr_pcrel, others=[ln], dst=[d])
+            return d
+        elif isinstance(e, ir.Mem) and isinstance(e.e, ir.Binop) and \
+                e.e.operation == '+' and isinstance(e.e.b, ir.Const):
+            base = self.munchExpr(e.e.a)
+            d = self.newTmp()
+            c = e.e.b.value
+            self.emit(arm.loadimm5_ins, others=[c], src=[base], dst=[d])
+            return d
+        elif isinstance(e, ir.Mem):
+            # Load from memory
+            base = self.munchExpr(e.e)
+            d = self.newTmp()
+            self.emit(arm.loadimm5_ins, others=[0], src=[base], dst=[d])
+            return d
+        elif isinstance(e, ir.Temp):
+            return e
+        elif isinstance(e, ir.Call):
+            # Move arguments into proper locations:
+            reguses = []
+            for i, a in enumerate(e.arguments):
+                loc = self.frame.argLoc(i)
+                m = ir.Move(loc, a)
+                self.munchStm(m)
+                if isinstance(loc, ir.Temp):
+                    reguses.append(loc)
+            self.emit(arm.bl_ins(LabelRef(e.f.name)), src=reguses, dst=[self.frame.rv])
+            d = self.newTmp()
+            self.move(d, self.frame.rv)
+            return d
+        else:
+            raise NotImplementedError('Expr --> {}'.format(e))
+
+    def munchStm(self, s):
+        if isinstance(s, ir.Terminator):
+            pass
+        elif isinstance(s, ir.Move) and isinstance(s.dst, ir.Mem) and \
+            isinstance(s.dst.e, ir.Binop) and s.dst.e.operation == '+' and \
+            isinstance(s.dst.e.b, ir.Const):
+            a = self.munchExpr(s.dst.e.a)
+            val = self.munchExpr(s.src)
+            c = s.dst.e.b.value
+            self.emit(arm.storeimm5_ins, others=[c], src=[a, val])
+        elif isinstance(s, ir.Move) and isinstance(s.dst, ir.Mem):
+            memloc = self.munchExpr(s.dst.e)
+            val = self.munchExpr(s.src)
+            self.emit(arm.storeimm5_ins, others=[0], src=[memloc, val])
+        elif isinstance(s, ir.Move) and isinstance(s.dst, ir.Temp):
+            val = self.munchExpr(s.src)
+            dreg = s.dst
+            self.move(dreg, val)
+        elif isinstance(s, ir.Exp):
+            # Generate expression code and discard the result.
+            x = self.munchExpr(s.e)
+            self.emit(Nop(), src=[x])
+        elif isinstance(s, ir.Jump):
+            tgt = self.targets[s.target]
+            self.emit(arm.b_ins(LabelRef(s.target.name)), jumps=[tgt])
+        elif isinstance(s, ir.CJump):
+            a = self.munchExpr(s.a)
+            b = self.munchExpr(s.b)
+            self.emit(arm.cmp_ins, src=[a, b])
+            ntgt = self.targets[s.lab_no]
+            ytgt = self.targets[s.lab_yes]
+            jmp_ins = makeIns(arm.b_ins(LabelRef(s.lab_no.name)), jumps=[ntgt])
+            opnames = {'<': arm.blt_ins, '>':arm.bgt_ins, '==':arm.beq_ins}
+            op = opnames[s.cond](LabelRef(s.lab_yes.name))
+            self.emit(op, jumps=[ytgt, jmp_ins])  # Explicitely add fallthrough
+            self.emit2(jmp_ins)
+        else:
+            raise NotImplementedError('Stmt --> {}'.format(s))
+
+    def move(self, dst, src):
+        self.emit(arm.movregreg_ext_ins, src=[src], dst=[dst])
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/target/armtarget.py	Sun Nov 24 11:24:15 2013 +0100
@@ -0,0 +1,759 @@
+import struct
+import types
+import ir
+from asmnodes import ASymbol, ANumber, AUnop, ABinop
+from ppci import CompilerError
+from .basetarget import Register, Instruction, Target, Label, LabelRef
+from .basetarget import Imm32, Imm8, Imm7, Imm3
+from .armframe import ArmFrame, ArmInstructionSelector
+
+
+""" ARM target description. """
+
+# TODO: encode this in DSL (domain specific language)
+# TBD: is this required?
+
+def u16(h):
+    return struct.pack('<H', h)
+
+def u32(x):
+    return struct.pack('<I', x)
+
+armtarget = Target('arm')
+armtarget.InstructionSelector = ArmInstructionSelector
+armtarget.Frame = ArmFrame
+
+class ArmRegister(Register):
+    def __init__(self, num, name):
+        super().__init__(name)
+        self.num = num
+
+    def __repr__(self):
+        return self.name
+
+    @classmethod
+    def Create(cls, vop):
+        if type(vop) is ASymbol:
+            name = vop.name
+            regs = {}
+            for r in armtarget.registers:
+                regs[r.name] = r
+            if name in regs:
+                r = regs[name]
+                if isinstance(r, cls):
+                    return r
+
+
+class Reg8Op(ArmRegister):
+    pass
+
+
+class Reg16Op(ArmRegister):
+    pass
+
+
+class RegSpOp:
+    @classmethod
+    def Create(cls, vop):
+        if type(vop) is ASymbol:
+            if vop.name.lower() == 'sp':
+                return cls()
+
+def getRegNum(n):
+    for r in armtarget.registers:
+        if r.num == n:
+            return r
+
+def getRegisterRange(n1, n2):
+    regs = []
+    if n1.num < n2.num:
+        for n in range(n1.num, n2.num + 1):
+            r = getRegNum(n)
+            assert r
+            regs.append(r)
+    return regs
+
+def isRegOffset(regname, x, y):
+    if type(x) is ASymbol and type(y) is ANumber and x.name.upper() == regname:
+        return y.number
+    elif type(y) is ASymbol and type(x) is ANumber and y.name.upper() == regname:
+        return x.number
+    
+
+class MemRegXRel:
+    def __init__(self, offset):
+        assert offset % 4 == 0
+        self.offset = offset
+
+    def __repr__(self):
+        return '[{}, #{}]'.format(self.regname, self.offset)
+
+    @classmethod
+    def Create(cls, vop):
+        if type(vop) is AUnop and vop.operation == '[]' and type(vop.arg) is ABinop and vop.arg.op == '+':
+            vop = vop.arg # descent
+            offset = isRegOffset(cls.regname, vop.arg1, vop.arg2)
+            if type(offset) is int:
+                if offset % 4 == 0:
+                    offset = vop.arg2.number
+                    return cls(offset)
+            elif type(vop) is ASymbol and vop.name.upper() == self.regname:
+                return cls(0)
+
+
+class MemSpRel(MemRegXRel):
+    regname = 'SP'
+
+
+class MemR8Rel:
+    def __init__(self, basereg, offset):
+        assert type(basereg) is Reg8Op
+        assert type(offset) is int
+        self.basereg = basereg
+        self.offset = offset
+
+    def __repr__(self):
+        return '[{}, #{}]'.format(self.basereg, self.offset)
+
+    @classmethod
+    def Create(cls, vop):
+        if type(vop) is AUnop and vop.operation == '[]':
+            vop = vop.arg # descent
+            if type(vop) is ABinop:
+                if vop.op == '+' and type(vop.arg1) is ASymbol and type(vop.arg2) is ANumber:
+                    offset = vop.arg2.number
+                    if offset > 120:
+                        return
+                    basereg = Reg8Op.Create(vop.arg1)
+                    if not basereg:
+                        return
+                else:
+                    return
+            elif type(vop) is ASymbol:
+                offset = 0
+                basereg = Reg8Op.Create(vop)
+                if not basereg:
+                    return
+            else:
+                return
+            return cls(getRegNum(basereg.num), offset)
+
+class RegisterSet:
+    def __init__(self, regs):
+        assert type(regs) is set
+        self.regs = regs
+
+    def __repr__(self):
+        return ','.join([str(r) for r in self.regs])
+
+    @classmethod
+    def Create(cls, vop):
+        assert type(vop) is AUnop and vop.operation == '{}'
+        assert type(vop.arg) is list
+        regs = set()
+        for arg in vop.arg:
+            if type(arg) is ASymbol:
+                reg = ArmRegister.Create(arg)
+                if not reg:
+                    return
+                regs.add(reg)
+            elif type(arg) is ABinop and arg.op == '-':
+                reg1 = ArmRegister.Create(arg.arg1)
+                reg2 = ArmRegister.Create(arg.arg2)
+                if not reg1:
+                    return
+                if not reg2:
+                    return
+                for r in getRegisterRange(reg1, reg2):
+                    regs.add(r)
+            else:
+                raise Exception('Cannot be')
+        return cls(regs)
+
+    def registerNumbers(self):
+        return [r.num for r in self.regs]
+
+def makeReg(cls, num, name):
+    r = cls(num, name)
+    armtarget.registers.append(r)
+    return r
+
+# 8 bit registers:
+r0 = makeReg(Reg8Op, 0, 'r0')
+r1 = makeReg(Reg8Op, 1, 'r1')
+r2 = makeReg(Reg8Op, 2, 'r2')
+r3 = makeReg(Reg8Op, 3, 'r3')
+r4 = makeReg(Reg8Op, 4, 'r4')
+r5 = makeReg(Reg8Op, 5, 'r5')
+r6 = makeReg(Reg8Op, 6, 'r6')
+r7 = makeReg(Reg8Op, 7, 'r7')
+# Other registers:
+# TODO
+sp = makeReg(ArmRegister, 13, 'sp')
+lr = makeReg(ArmRegister, 14, 'lr')
+pc = makeReg(ArmRegister, 15, 'pc')
+
+# Sanity checks:
+assert isinstance(sp, ArmRegister)
+assert isinstance(r3, ArmRegister)
+assert ArmRegister.Create(ASymbol('r3')) is r3
+assert ArmRegister.Create(ASymbol('sp')) is sp
+
+
+class ArmInstruction(Instruction):
+    pass
+
+
+@armtarget.instruction
+class dcd_ins(ArmInstruction):
+    mnemonic = 'dcd'
+    operands = (Imm32,)
+    def __init__(self, expr):
+        if isinstance(expr, Imm32):
+            self.expr = expr.imm
+            self.label = None
+        elif isinstance(expr, LabelRef):
+            self.expr = 0
+            self.label = expr
+        elif isinstance(expr, int):
+            self.expr = expr
+            self.label = None
+        else:
+            raise NotImplementedError()
+
+    def resolve(self, f):
+        if self.label:
+            self.expr = f(self.label.name)
+
+    def encode(self):
+        return u32(self.expr)
+
+    def __repr__(self):
+        return 'DCD 0x{0:X}'.format(self.expr)
+
+
+@armtarget.instruction
+class nop_ins(ArmInstruction):
+    mnemonic = 'nop'
+    operands = tuple()
+
+    def encode(self):
+        return bytes()
+
+    def __repr__(self):
+        return 'NOP'
+
+
+# Memory related
+
+class LS_imm5_base(ArmInstruction):
+    """ ??? Rt, [Rn, imm5] """
+    operands = (Reg8Op, MemR8Rel)
+    def __init__(self, rt, memop):
+        assert memop.offset % 4 == 0
+        self.imm5 = memop.offset >> 2
+        self.rn = memop.basereg.num
+        self.rt = rt
+        self.memloc = memop
+        assert self.rn < 8
+        assert self.rt.num < 8
+
+    def encode(self):
+        Rn = self.rn
+        Rt = self.rt.num
+        imm5 = self.imm5
+
+        h = (self.opcode << 11) | (imm5 << 6) | (Rn << 3) | Rt
+        return u16(h)
+
+
+    def __repr__(self):
+        return '{} {}, {}'.format(self.mnemonic, self.rt, self.memloc)
+
+
+@armtarget.instruction
+class storeimm5_ins(LS_imm5_base):
+    mnemonic = 'STR'
+    opcode = 0xC
+
+    @classmethod
+    def fromim(cls, im):
+        mem = MemR8Rel(im.src[0], im.others[0])
+        return cls(im.src[1], mem)
+
+
+@armtarget.instruction
+class loadimm5_ins(LS_imm5_base):
+    mnemonic = 'LDR'
+    opcode = 0xD
+
+    @classmethod
+    def fromim(cls, im):
+        mem = MemR8Rel(im.src[0], im.others[0])
+        return cls(im.dst[0], mem)
+
+class ls_sp_base_imm8(ArmInstruction):
+    operands = (Reg8Op, MemSpRel)
+    def __init__(self, rt, memop):
+        self.rt = rt
+        self.offset = memop.offset
+
+    def encode(self):
+        rt = self.rt.num
+        assert rt < 8
+        imm8 = self.offset >> 2
+        assert imm8 < 256
+        h = (self.opcode << 8) | (rt << 8) | imm8
+        return u16(h)
+
+    def __repr__(self):
+        return '{} {}, [sp,#{}]'.format(self.mnemonic, self.rt, self.offset)
+
+def align(x, m):
+    while ((x % m) != 0):
+        x = x + 1
+    return x
+
+
+@armtarget.instruction
+class ldr_pcrel(ArmInstruction):
+    """ ldr Rt, LABEL, load value from pc relative position """
+    mnemonic = 'ldr'
+    operands = (Reg8Op, LabelRef)
+    def __init__(self, rt, label):
+        assert isinstance(label, LabelRef)
+        self.rt = rt
+        self.label = label
+        self.offset = 0
+
+    @classmethod
+    def fromim(cls, im):
+        return cls(im.dst[0], im.others[0])
+
+    def resolve(self, f):
+        la = f(self.label.name)
+        sa = align(self.address + 2, 4)
+        self.offset = (la - sa)
+        if self.offset < 0:
+            self.offset = 0
+
+    def encode(self):
+        rt = self.rt.num
+        assert rt < 8
+        assert self.offset % 4 == 0
+        imm8 = self.offset >> 2
+        assert imm8 < 256
+        assert imm8 >= 0
+        h = (0x9 << 11) | (rt << 8) | imm8
+        return u16(h)
+
+    def __repr__(self):
+        return 'LDR {}, {}'.format(self.rt, self.label.name)
+
+
+@armtarget.instruction
+class ldr_sprel(ls_sp_base_imm8):
+    """ ldr Rt, [SP, imm8] """
+    mnemonic = 'LDR'
+    opcode = 0x98
+
+
+@armtarget.instruction
+class str_sprel(ls_sp_base_imm8):
+    """ str Rt, [SP, imm8] """
+    mnemonic = 'STR'
+    opcode = 0x90
+
+
+@armtarget.instruction
+class mov_imm8_ins(ArmInstruction):
+    """ mov Rd, imm8, move immediate value into register """
+    mnemonic = 'mov'
+    opcode = 4 # 00100 Rd(3) imm8
+    operands = (Reg8Op, Imm8)
+    def __init__(self, rd, imm):
+        if type(imm) is int:
+            imm = Imm8(imm)
+        assert type(imm) is Imm8
+        self.imm = imm.imm
+        assert type(rd) is Reg8Op, str(type(rd))
+        self.rd = rd
+
+    @classmethod
+    def fromim(cls, im):
+        return cls(im.dst[0], im.others[0])
+
+    def encode(self):
+        rd = self.rd.num
+        opcode = self.opcode
+        imm8 = self.imm
+        h = (opcode << 11) | (rd << 8) | imm8
+        return u16(h)
+
+    def __repr__(self):
+        return 'MOV {}, {}'.format(self.rd, self.imm)
+
+
+
+# Arithmatics:
+
+
+
+class regregimm3_base(ArmInstruction):
+    operands = (Reg8Op, Reg8Op, Imm3)
+    def __init__(self, rd, rn, imm3):
+        self.rd = rd
+        self.rn = rn
+        assert type(imm3) is Imm3
+        self.imm3 = imm3
+
+    @classmethod
+    def fromim(cls, im):
+        return cls(im.dst[0], im.src[0], im.others[0])
+
+    def encode(self):
+        rd = self.rd.num
+        rn = self.rn.num
+        imm3 = self.imm3.imm
+        opcode = self.opcode
+        h = (self.opcode << 9) | (imm3 << 6) | (rn << 3) | rd
+        return u16(h)
+
+    def __repr__(self):
+        return '{} {}, {}, {}'.format(self.mnemonic, self.rd, self.rn, self.imm3.imm)
+
+@armtarget.instruction
+class addregregimm3_ins(regregimm3_base):
+    """ add Rd, Rn, imm3 """
+    mnemonic = 'add'
+    opcode = 0b0001110
+
+
+@armtarget.instruction
+class subregregimm3_ins(regregimm3_base):
+    """ sub Rd, Rn, imm3 """
+    mnemonic = 'sub'
+    opcode = 0b0001111
+
+
+class regregreg_base(ArmInstruction):
+    """ ??? Rd, Rn, Rm """
+    operands = (Reg8Op, Reg8Op, Reg8Op)
+    def __init__(self, rd, rn, rm):
+        self.rd = rd
+        self.rn = rn
+        self.rm = rm
+
+    @classmethod
+    def fromim(cls, im):
+        return cls(im.dst[0], im.src[0], im.src[1])
+
+    def encode(self):
+        rd = self.rd.num
+        rn = self.rn.num
+        rm = self.rm.num
+        h = (self.opcode << 9) | (rm << 6) | (rn << 3) | rd
+        return u16(h)
+
+    def __repr__(self):
+        return '{} {}, {}, {}'.format(self.mnemonic, self.rd, self.rn, self.rm)
+
+
+@armtarget.instruction
+class addregs_ins(regregreg_base):
+    mnemonic = 'ADD'
+    opcode = 0b0001100
+
+
+@armtarget.instruction
+class subregs_ins(regregreg_base):
+    mnemonic = 'SUB'
+    opcode = 0b0001101
+
+
+
+@armtarget.instruction
+class movregreg_ext_ins(ArmInstruction):
+    """ mov rd, rm """
+    operands = (ArmRegister, ArmRegister)
+    mnemonic = 'MOV'
+    def __init__(self, rd, rm):
+        self.rd = rd
+        self.rm = rm
+
+    @classmethod
+    def fromim(cls, im):
+        return cls(im.dst[0], im.src[0])
+
+    def encode(self):
+        Rd = self.rd.num & 0x7
+        D = (self.rd.num >> 3) & 0x1
+        Rm = self.rm.num
+        opcode = 0b01000110
+        return u16((opcode << 8) | (D << 7) |(Rm << 3) | Rd)
+
+    def __repr__(self):
+        return '{} {}, {}'.format(self.mnemonic, self.rd, self.rm)
+        
+
+@armtarget.instruction
+class mulregreg_ins(ArmInstruction):
+    """ mul Rn, Rdm """
+    operands = (Reg8Op, Reg8Op)
+    mnemonic = 'MUL'
+    def __init__(self, rn, rdm):
+        self.rn = rn
+        self.rdm = rdm
+
+    @classmethod
+    def fromim(cls, im):
+        assert im.src[1] is im.dst[0]
+        return cls(im.src[0], im.dst[0])
+
+    def encode(self):
+        rn = self.rn.num
+        rdm = self.rdm.num
+        opcode = 0b0100001101
+        h = (opcode << 6) | (rn << 3) | rdm
+        return u16(h)
+
+    def __repr__(self):
+        return '{} {}, {}'.format(self.mnemonic, self.rn, self.rdm)
+
+
+class regreg_base(ArmInstruction):
+    """ ??? Rdn, Rm """
+    operands = (Reg8Op, Reg8Op)
+    # TODO: integrate with the code gen interface:
+    src = (0, 1)
+    dst = (0,)
+    def __init__(self, rdn, rm):
+        self.rdn = rdn
+        self.rm = rm
+
+    @classmethod
+    def fromim(cls, im):
+        return cls(im.src[0], im.src[1])
+
+    def encode(self):
+        rdn = self.rdn.num
+        rm = self.rm.num
+        h = (self.opcode << 6) | (rm << 3) | rdn
+        return u16(h)
+
+    def __repr__(self):
+        return '{} {}, {}'.format(self.mnemonic, self.rdn, self.rm)
+
+
+@armtarget.instruction
+class movregreg_ins(regreg_base):
+    """ mov Rd, Rm (reg8 operands) """
+    # TODO: match this:
+    pattern = ir.Move(ir.Temp, ir.Temp)
+    mnemonic = 'mov'
+    opcode = 0
+
+
+@armtarget.instruction
+class andregs_ins(regreg_base):
+    mnemonic = 'AND'
+    opcode = 0b0100000000
+
+
+@armtarget.instruction
+class orrregs_ins(regreg_base):
+    mnemonic = 'ORR'
+    opcode = 0b0100001100
+
+
+@armtarget.instruction
+class cmp_ins(regreg_base):
+    mnemonic = 'CMP'
+    opcode = 0b0100001010
+
+
+@armtarget.instruction
+class lslregs_ins(regreg_base):
+    mnemonic = 'LSL'
+    opcode = 0b0100000010
+
+@armtarget.instruction
+class cmpregimm8_ins(ArmInstruction):
+    """ cmp Rn, imm8 """
+    mnemonic = 'cmp'
+    opcode = 5 # 00101
+    operands = (Reg8Op, Imm8)
+    def __init__(self, rn, imm):
+        self.rn = rn
+        self.imm = imm
+    def encode(self):
+        rn = self.rn.num
+        imm = self.imm.imm
+        opcode = self.opcode
+        h = (opcode << 11) | (rn << 8) | imm
+        return u16(h)
+
+
+# Jumping:
+
+def wrap_negative(x, bits):
+    b = struct.unpack('<I', struct.pack('<i', x))[0]
+    mask = (1 << bits) - 1
+    return b & mask
+
+class jumpBase_ins(ArmInstruction):
+    operands = (LabelRef,)
+    def __init__(self, target_label):
+        assert type(target_label) is LabelRef
+        self.target = target_label
+        self.offset = 0
+
+    def resolve(self, f):
+        la = f(self.target.name)
+        sa = self.address + 4
+        self.offset = (la - sa)
+
+    def __repr__(self):
+        return '{} {}'.format(self.mnemonic, self.target.name)
+
+
+@armtarget.instruction
+class b_ins(jumpBase_ins):
+    mnemonic = 'B'
+    def encode(self):
+        imm11 = wrap_negative(self.offset >> 1, 11)
+        h = (0b11100 << 11) | imm11 # | 1 # 1 to enable thumb mode
+        return u16(h)
+
+
+@armtarget.instruction
+class bl_ins(jumpBase_ins):
+    mnemonic = 'BL'
+    def encode(self):
+        imm32 = wrap_negative(self.offset >> 1, 32)
+        imm11 = imm32 & 0x7FF
+        imm10 = (imm32 >> 11) & 0x3FF
+        j1 = 1 # TODO: what do these mean?
+        j2 = 1
+        s = (imm32 >> 24) & 0x1
+        h1 = (0b11110 << 11) | (s << 10) | imm10 
+        h2 = (0b1101 << 12) | (j1 << 13) | (j2 << 11) | imm11
+        return u16(h1) + u16(h2)
+
+
+class cond_base_ins(jumpBase_ins):
+    def encode(self):
+        imm8 = wrap_negative(self.offset >> 1, 8)
+        h = (0b1101 << 12) | (self.cond << 8) | imm8
+        return u16(h)
+
+
+@armtarget.instruction
+class beq_ins(cond_base_ins):
+    mnemonic = 'beq'
+    cond = 0
+
+
+@armtarget.instruction
+class bne_ins(cond_base_ins):
+    mnemonic = 'bne'
+    cond = 1
+
+
+@armtarget.instruction
+class blt_ins(cond_base_ins):
+    mnemonic = 'blt'
+    cond = 0b1011
+
+
+@armtarget.instruction
+class bgt_ins(cond_base_ins):
+    mnemonic = 'bgt'
+    cond = 0b1100
+
+
+@armtarget.instruction
+class push_ins(ArmInstruction):
+    operands = (RegisterSet,)
+    mnemonic = 'push'
+    def __init__(self, regs):
+        assert (type(regs),) == self.operands, (type(regs),)
+        self.regs = regs
+    def __repr__(self):
+        return '{0} {{{1}}}'.format(self.mnemonic, self.regs)
+    def encode(self):
+        reg_list = 0
+        M = 0
+        for n in self.regs.registerNumbers():
+            if n < 8:
+                reg_list |= (1 << n)
+            elif n == 14:
+                M = 1
+            else:
+                raise NotImplementedError('not implemented for this register')
+        h = (0x5a << 9) | (M << 8) | reg_list
+        return u16(h)
+
+
+@armtarget.instruction
+class pop_ins(ArmInstruction):
+    operands = (RegisterSet,)
+    mnemonic = 'pop'
+
+    def __init__(self, regs):
+        self.regs = regs
+
+    def __repr__(self):
+        return '{0} {{{1}}}'.format(self.mnemonic, self.regs)
+
+    def encode(self):
+        reg_list = 0
+        P = 0
+        for n in self.regs.registerNumbers():
+            if n < 8:
+                reg_list |= (1 << n)
+            elif n == 15:
+                P = 1
+            else:
+                raise NotImplementedError('not implemented for this register')
+        h = (0x5E << 9) | (P << 8) | reg_list
+        return u16(h)
+
+
+@armtarget.instruction
+class yield_ins(ArmInstruction):
+    operands = ()
+    mnemonic = 'yield'
+
+    def encode(self):
+        return u16(0xbf10)
+
+# misc:
+
+# add/sub SP:
+class addspsp_base(ArmInstruction):
+    operands = (RegSpOp, RegSpOp, Imm7)
+    def __init__(self, _sp, _sp2, imm7):
+        self.imm7 = imm7.imm
+        assert self.imm7 % 4 == 0
+        self.imm7 >>= 2
+
+    def encode(self):
+        return u16((self.opcode << 7) |self.imm7)
+
+    def __repr__(self):
+        return '{} sp, sp, {}'.format(self.mnemonic, self.imm7 << 2)
+
+@armtarget.instruction
+class addspsp_ins(addspsp_base):
+    mnemonic = 'add'
+    opcode = 0b101100000
+    
+
+@armtarget.instruction
+class subspsp_ins(addspsp_base):
+    mnemonic = 'sub'
+    opcode = 0b101100001
+
+armtarget.check()
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/target/basetarget.py	Sun Nov 24 11:24:15 2013 +0100
@@ -0,0 +1,198 @@
+from asmnodes import ASymbol, AInstruction, ANumber
+from ppci import CompilerError
+
+"""
+  Base classes for defining a target
+"""
+
+# Machine code interface:
+class Operand:
+   """ Single machine operand """
+   pass
+
+# standard immediates:
+
+class Imm8:
+    def __init__(self, imm):
+        assert imm < 256
+        self.imm = imm
+
+    @classmethod
+    def Create(cls, vop):
+        if type(vop) is ANumber and vop.number < 256:
+            return cls(vop.number)
+
+class Imm7:
+    def __init__(self, imm):
+        assert imm < 128
+        self.imm = imm
+
+    @classmethod
+    def Create(cls, vop):
+        if type(vop) is ANumber and vop.number < 128:
+            return cls(vop.number)
+
+class Imm3:
+    def __init__(self, imm):
+        assert imm < 8
+        assert type(imm) is int
+        self.imm = imm
+
+    @classmethod
+    def Create(cls, vop):
+        if type(vop) is ANumber and vop.number < 8:
+            return cls(vop.number)
+
+class Imm32:
+    def __init__(self, imm):
+        assert imm < 2**32
+        assert type(imm) is int
+        self.imm = imm
+
+    @classmethod
+    def Create(cls, vop):
+        if type(vop) is ANumber and vop.number < 2**32:
+            return cls(vop.number)
+
+
+class LabelRef:
+    def __init__(self, name):
+        assert type(name) is str
+        self.name = name
+
+    @classmethod
+    def Create(cls, vop):
+        if type(vop) is ASymbol:
+            return cls(vop.name)
+
+class Instruction:
+    def encode(self):
+        raise NotImplementedError('Instruction {0} has no encode yet, TODO'.format(type(self)))
+    def resolve(self, f):
+        pass
+
+
+class Nop(Instruction):
+    """ Instruction that does nothing and has zero size """
+    def encode(self):
+        return bytes()
+
+    
+
+class PseudoInstruction(Instruction):
+    pass
+
+
+class Label(PseudoInstruction):
+    def __init__(self, name):
+        self.name = name
+        self.address = 0
+
+    def __repr__(self):
+        return '{}:'.format(self.name)
+
+    def encode(self):
+        return bytes()
+
+    @classmethod
+    def Create(cls, vop):
+        if type(vop) is ASymbol:
+            name = vop.name
+            return cls(name)
+
+
+class Comment(PseudoInstruction):
+    def __init__(self, txt):
+        self.txt = txt
+
+    def encode(self):
+        return bytes()
+
+    def __repr__(self):
+        return '; {}'.format(self.txt)
+
+
+class Alignment(PseudoInstruction):
+    def __init__(self, a):
+        self.align = a
+
+    def __repr__(self):
+        return 'ALIGN({})'.format(self.align)
+
+    def encode(self):
+        pad = []
+        address = self.address
+        while (address % self.align) != 0:
+            address += 1
+            pad.append(0)
+        return bytes(pad)
+
+class DebugInfo(PseudoInstruction):
+    def __init__(self, i):
+        self.info = i
+
+    def __repr__(self):
+        return 'DebugInfo: {}'.format(self.info)
+
+    def encode(self):
+        return bytes()
+
+class Register(Operand):
+    def __init__(self, name):
+        self.name = name
+
+
+class Target:
+    def __init__(self, name, desc=''):
+        self.name = name
+        self.desc = desc
+        self.registers = []
+        self.instructions = []
+
+    def instruction(self, cls):
+        """ Decorator function that registers an instruction to this target """
+        self.addInstruction(cls)
+        return cls
+
+    def check(self):
+        """ Check target """
+        for i in self.instructions:
+            assert hasattr(i, 'mnemonic')
+            assert hasattr(i, 'operands'), str(i)
+            assert type(i.mnemonic) is str
+            assert type(i.operands) is tuple, str(i)
+
+    def addInstruction(self, ins_class):
+        self.instructions.append(ins_class)
+
+    def mapOperand(self, operand):
+        """ Try to map an operand to a target type """
+        if type(operand) is ASymbol:
+            # Try to map to register:
+            regs = {}
+            for r in self.registers:
+                regs[r.name] = r
+            if operand.name in regs:
+                return regs[operand.name]
+        raise CompilerError('Cannot map {0}'.format(operand))
+
+    def mapInstruction(self, vi):
+        assert type(vi) is AInstruction
+        """ Map ast tree to real instruction for this target """
+
+        # map to real operands:
+        if vi.mnemonic.upper() == 'ALIGN' and len(vi.operands) == 1:
+            if type(vi.operands[0]) == ANumber:
+                return Alignment(vi.operands[0].number)
+
+        # look for a suitable instruction
+        for ic in self.instructions:
+            if ic.mnemonic.upper() == vi.mnemonic.upper() and len(ic.operands) == len(vi.operands):
+                # Try to map operands to the correct operand types:
+                rops = [roptype.Create(vop) for roptype, vop in zip(ic.operands, vi.operands)]
+
+                # Check if we succeeded:
+                if all(isinstance(rop, optype) for rop, optype in zip(rops, ic.operands)):
+                    return ic(*rops)
+        raise CompilerError('No suitable instruction found for "{0}"'.format(vi))
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/target/instructionselector.py	Sun Nov 24 11:24:15 2013 +0100
@@ -0,0 +1,59 @@
+import ir
+import irmach
+from irmach import AbstractInstruction as makeIns
+import target
+
+def genTemps():
+    n = 900
+    while True:
+        yield ir.Temp('t{}'.format(n))
+        n = n + 1
+
+
+class InstructionSelector:
+    """
+        Base instruction selector. This class must be overridden by
+        backends.
+    """
+    def __init__(self):
+        self.temps = genTemps()
+
+    def newTmp(self):
+        return self.temps.__next__()
+
+    def munchFunction(self, f, frame):
+        # Entry point for instruction selection
+        assert isinstance(f, ir.Function)
+        self.targets = {}
+        # Enter a frame per function:
+        self.frame = frame
+        # First define labels:
+        for bb in f.Blocks:
+            itgt = makeIns(target.Label(bb.name))
+            self.targets[bb] = itgt
+        # Generate code for all blocks:
+        for bb in f.Blocks:
+            self.emit2(self.targets[bb])
+            for i in bb.Instructions:
+                self.munchStm(i)
+        self.munchStm(ir.Move(self.frame.rv, f.return_value))
+
+    def move(self, dst, src):
+        raise NotImplementedError('Not target implemented')
+
+    def emit(self, *args, **kwargs):
+        """ Abstract instruction emitter """
+        i = makeIns(*args, **kwargs)
+        return self.emit2(i)
+
+    def emit2(self, i):
+        self.frame.instructions.append(i)
+        return i
+
+    def munchStm(self, s):
+        """ Implement this in the target specific back-end """
+        raise NotImplementedError()
+
+    def munchExpr(self, e):
+        """ Implement this in the target specific back-end """
+        raise NotImplementedError()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/target/msp430.py	Sun Nov 24 11:24:15 2013 +0100
@@ -0,0 +1,248 @@
+from target import Register, Instruction, Target
+from asmnodes import ASymbol, ANumber
+from ppci import CompilerError
+import struct
+import types
+
+# Create the target class (singleton):
+msp430target = Target("MSP430")
+
+REGISTER_MODE = 1
+SYMBOLIC_MODE = 3
+ABSOLUTE_MODE = 4
+#TODO: add more modes!
+IMMEDIATE_MODE = 7
+
+# Target description for the MSP430 processor
+
+class MSP430Reg(Register):
+    def __init__(self, num, name):
+        super().__init__(name)
+        self.num = num
+
+# 8 bit registers:
+PCB = MSP430Reg(0, 'r0')
+rpc = PCB
+r11 = MSP430Reg(11, 'r11')
+r12 = MSP430Reg(12, 'r12')
+r13 = MSP430Reg(13, 'r13')
+r14 = MSP430Reg(14, 'r14')
+r15 = MSP430Reg(15, 'r15')
+
+class MSP430Mem:
+    pass
+
+msp430target.registers.append(r11)
+msp430target.registers.append(r12)
+msp430target.registers.append(r13)
+msp430target.registers.append(r14)
+msp430target.registers.append(r15)
+
+# .. etc
+
+#GR8 = RegisterClass((PCB, R15B))
+
+class MSP430Operand:
+    def __init__(self, mode, param):
+        self.mode = mode
+        self.param = param
+    def regField(self):
+        if self.mode == REGISTER_MODE:
+            return self.param
+        elif self.mode == IMMEDIATE_MODE:
+            return rpc.num
+    def asField(self):
+        if self.mode == REGISTER_MODE:
+            return 0
+        elif self.mode == IMMEDIATE_MODE:
+            return 3
+    def adField(self):
+        if self.mode == REGISTER_MODE:
+            return 0
+        elif self.mode == IMMEDIATE_MODE:
+            raise CompilerError('Cannot use immediate mode for destination operand')
+    def extraBytes(self):
+        if self.mode == IMMEDIATE_MODE:
+            return pack_ins(self.param)
+        return bytes()
+    
+    @classmethod
+    def Create(cls, vop):
+        if type(vop) is ASymbol:
+            # try to map to register:
+            regs = {}
+            for r in msp430target.registers:
+                regs[r.name] = r
+            if vop.name in regs:
+                reg = regs[vop.name]
+                return cls(REGISTER_MODE, reg.num)
+        elif type(vop) is ANumber:
+            # Immediate mode:
+            return cls(IMMEDIATE_MODE, vop.number)
+
+def pack_ins(h):
+    return struct.pack('<H', h)
+
+class MSP430Instruction(Instruction):
+    b = 0
+
+class BInstruction:
+    pass
+
+class MSP430CoreInstruction(Instruction):
+    pass
+
+#########################
+# Single operand arithmatic:
+#########################
+
+@msp430target.instruction
+class reti_ins(MSP430Instruction):
+    mnemonic = 'reti'
+    operands = ()
+    def encode(self):
+        h = 0x1300
+        return pack_ins(h)
+
+class OneOpArith(MSP430Instruction):
+    operands = (MSP430Reg, )
+    def __init__(self, op1):
+        self.op1 = op1
+    def encode(self):
+        # TODO:
+        bits[15:10] = '00100'
+        h1 = (self.opcode << 4)
+        return pack_ins(h1)
+
+def oneOpIns(mne, opc):
+    """ Helper function to define a one operand arithmetic instruction """
+    members = {'mnemonic': mne, 'opcode': opc}
+    ins_cls = type(mne + '_ins', (OneOpArith,), members)
+    msp430target.addInstruction(ins_cls)
+
+oneOpIns('rrc', 0)
+oneOpIns('swpb', 1)
+oneOpIns('rra', 2)
+oneOpIns('sxt', 3)
+oneOpIns('push', 4)
+oneOpIns('call', 5)
+
+#########################
+# Jump instructions:
+#########################
+
+class JumpInstruction(Instruction):
+    def __init__(self, offset):
+        self.offset = offset
+
+    def encode(self):
+        h = (1 << 13) | (self.condition << 10) | (self.offset)
+        return pack_ins(h)
+
+@msp430target.instruction
+class jnz_ins(JumpInstruction):
+    mnemonic = 'jnz'
+    condition = 0
+
+@msp430target.instruction
+class jz_ins(JumpInstruction):
+    mnemonic = 'jz'
+    condition = 1
+
+@msp430target.instruction
+class jnc_ins(JumpInstruction):
+    mnemonic = 'jnc'
+    condition = 2
+
+@msp430target.instruction
+class jc_ins(JumpInstruction):
+    mnemonic = 'jc'
+    condition = 3
+
+@msp430target.instruction
+class jn_ins(JumpInstruction):
+    mnemonic = 'jn'
+    condition = 4
+
+@msp430target.instruction
+class jge_ins(JumpInstruction):
+    mnemonic = 'jge'
+    condition = 5
+
+@msp430target.instruction
+class jl_ins(JumpInstruction):
+    mnemonic = 'jl'
+    condition = 6
+
+@msp430target.instruction
+class jmp_ins(JumpInstruction):
+    mnemonic = 'jmp'
+    condition = 7
+
+#########################
+# Two operand arithmatic instructions:
+#########################
+
+
+class TwoOpArith(MSP430Instruction):
+    operands = (MSP430Operand, MSP430Operand)
+    def __init__(self, src, dst):
+        self.op1 = src
+        self.op2 = dst
+
+    def encode(self):
+        """
+            Smart things have been done by MSP430 designers.
+            As (2 bits) is the source addressing mode selector.
+            Ad (1 bit) is the destination adressing mode selector.
+            For the source there are 7 different addressing mode.
+            For the destination there are 4.
+            The trick is to use also the register to distuingish the
+            different modes.
+        """
+        # TODO: Make memory also possible
+
+        As = self.op1.asField() # addressing mode for the source
+        Ad = self.op2.adField() # Addressing mode for dst
+        b = self.b # When b=1, the operation is byte mode
+        source = self.op1.regField()
+        destination = self.op2.regField()
+        h = (self.opcode << 12) | (source << 8)
+        h |= (self.b << 6) | (As << 4) | (Ad << 7) | destination
+        additions = self.op1.extraBytes() + self.op2.extraBytes()
+        return pack_ins(h) + additions
+
+    def decode(self, data):
+        pass
+
+
+def twoOpIns(mne, opc):
+    """ Helper function to define a two operand arithmetic instruction """
+    members = {'mnemonic': mne, 'opcode': opc}
+    ins_cls = type(mne + '_ins', (TwoOpArith,), members)
+    msp430target.addInstruction(ins_cls)
+
+twoOpIns('mov', 4)
+
+# This is equivalent to the helper function twoOpIns:
+@msp430target.instruction
+class add_ins(TwoOpArith):
+    """ Adds the source to the destination """
+    mnemonic = 'add'
+    opcode = 5
+
+    def operate(self):
+        dst.value = dst.value + src.value
+        setFlags()
+
+twoOpIns('addc', 6)
+twoOpIns('subc', 7)
+twoOpIns('sub', 8)
+twoOpIns('cmp', 9)
+twoOpIns('dadd', 10)
+twoOpIns('bit', 11)
+twoOpIns('bic', 12)
+twoOpIns('bis', 13)
+twoOpIns('xor', 14)
+twoOpIns('and', 15)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/target/openrisc.lidl	Sun Nov 24 11:24:15 2013 +0100
@@ -0,0 +1,26 @@
+
+// Openrisc description in lidl (lcfos isa description language)
+
+// Register storage:
+storage r {
+  width: 32
+  size: 32
+}
+
+
+instruction add {
+  encoding: '111111111DDDDDDAAAAAABBBBBB'
+  semantics: D = A + B
+}
+
+
+// ...
+
+instruction push {
+  encoding: ''
+  semantics: {
+    sp = X
+    sp  = sp - 4
+  }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/target/x86.py	Sun Nov 24 11:24:15 2013 +0100
@@ -0,0 +1,69 @@
+import ppci
+import ir
+
+class X86CodeGenSimple:
+   """ 
+    Inefficient code generation, assume stack machine 
+    backend
+   """
+   def __init__(self, diag):
+      self.diag = diag
+
+   def emit(self, i):
+      self.asm.append(i)
+
+   def genBin(self, ir):
+      self.asm = []
+      self.genModule(ir)
+      return self.asm
+
+   def genModule(self, ir):
+      for f in ir.Functions:
+         self.genFunction(f)
+   def genFunction(self, f):
+      self.emit('global {0}'.format(f.name))
+      self.emit('{0}:'.format(f.name))
+      self.emit('jmp {0}'.format(f.entry.name))
+      for bb in f.BasicBlocks:
+         self.genBB(bb)
+   def genBB(self, bb):
+      self.emit('{0}:'.format(bb.name))
+      for i in bb.Instructions:
+         self.genIns(i)
+   def genIns(self, i):
+      if type(i) is ir.BinaryOperator:
+         ops = {'+':'add', '-':'sub', '*':'mul'}
+         if i.operation in ops:
+            i.result.reg = 'rax'
+            i.value1.reg = 'rbx'
+            i.value2.reg = 'rbx'
+            self.emit('mov {0}, {1}'.format(i.result.reg, i.value1.reg))
+            self.emit('{0} {1}, {2}'.format(ops[i.operation], i.result.reg, i.value2.reg))
+         else:
+            raise NotImplementedError('op {0}'.format(i.operation))
+      elif type(i) is ir.Load:
+         self.emit('mov {0}, [{1}]'.format(i.value, i.location))
+      elif type(i) is ir.Return:
+         self.emit('ret')
+      elif type(i) is ir.Call:
+         self.emit('call')
+      elif type(i) is ir.ImmLoad:
+         self.emit('mov {0}, {1}'.format(i.target, i.value))
+      elif type(i) is ir.Store:
+         self.emit('mov [{0}], {1}'.format(i.location, i.value))
+      elif type(i) is ir.ConditionalBranch:
+         self.emit('cmp {0}, {1}'.format(i.a, i.b))
+         jmps = {'>':'jg', '<':'jl', '==':'je'}
+         if i.cond in jmps:
+            j = jmps[i.cond]
+            self.emit('{0} {1}'.format(j, i.lab1.name))
+         else:
+            raise NotImplementedError('condition {0}'.format(i.cond))
+         self.emit('jmp {0}'.format(i.lab2.name))
+      elif type(i) is ir.Branch:
+         self.emit('jmp {0}'.format(i.target.name))
+      elif type(i) is ir.Alloc:
+         pass
+      else:
+         raise NotImplementedError('{0}'.format(i))
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/target/x86_2.py	Sun Nov 24 11:24:15 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/tcodegen.py	Thu Nov 21 15:46:50 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,141 +0,0 @@
-
-"""
-  Test individual parts of the code generation for arm using the c3 frontend.
-"""
-
-import c3
-import ppci
-import codegenarm
-import outstream
-import ir
-
-testsrc = """
-package test2;
-
-var int phaa, foo, bar;
-
-function int insanemath(int a, int b)
-{
-  var int c;
-  c = 0;
-  var int i;
-  i = 9;
-  while (i > 1)
-  {
-      c = a + b + 1 + c;
-      i = i - 1;
-      if (c > 90)
-      {
-         return 42;
-      }
-  }
-  return c;
-}
-
-function void tesssst(int henkie)
-{
-   var int a, b, cee;
-   a = 2 * 33 - 12;
-   b = a * 2;
-   a = b + a;
-   cee = a;
-   cee = cee * 2 + cee;
-   insanemath(2, 3);
-   if (cee + a > b and b - a+b== 3*6-insanemath(b, 2))
-   {
-      var int x = a;
-      x = b - a + insanemath(3, 4) - insanemath(33, insanemath(2, 0));
-      a = x * (x + a);
-   }
-   else
-   {
-      a = b + (a + b);
-   }
-   var int y;
-   y = a - b * 53;
-}
-"""
-
-testsrc = """
-package test3;
-
-function int ab(int a, int b)
-{
-  var int c;
-  c = 0;
-  c = c + a + b;
-  return c; 
-}
-
-function void tesssst()
-{
-   var int a, b;
-   a = 2;
-   b = 3;
-   ab(ab(a, b) + ab(9,b), 0);
-}
-"""
-
-testsrc = """
-package test3;
-
-function int ab(int a, int b)
-{
-  var int c;
-  var int *a2;
-  a2 = cast<int*>(2);
-  *a2 = 2;
-  *a2 = *a2 + 2;
-  c = 0;
-  c = c + a + b;
-  return c; 
-}
-
-"""
-def dump_cfg(cga, cfg_file):
-    print('digraph G {', file=cfg_file)
-    #print('edge [constraint=none]', file=cfg_file)
-    print('rankdir=TB', file=cfg_file)
-    for f in cga.frames:
-        print('subgraph cluster_{} {{'.format(f.name), file=cfg_file)
-        print('label={};'.format(f.name), file=cfg_file)
-        print('color=lightgrey;', file=cfg_file)
-        print('style=filled;', file=cfg_file)
-        f.cfg.to_dot(cfg_file)
-        print('}', file=cfg_file)
-    print('}', file=cfg_file)
-
-def dump_ig(cga, ig_file):
-    print('digraph G {', file=ig_file)
-    print('edge [arrowhead=none]', file=ig_file)
-    for f in cga.frames:
-        print('subgraph cluster_{} {{'.format(f.name), file=ig_file)
-        print('label={};'.format(f.name), file=ig_file)
-        print('color=lightgrey;', file=ig_file)
-        print('style=filled;', file=ig_file)
-        f.ig.to_dot(ig_file)
-        print('}', file=ig_file)
-    print('}', file=ig_file)
-
-if __name__ == '__main__':
-    diag = ppci.DiagnosticsManager()
-    builder = c3.Builder(diag)
-    irc = builder.build(testsrc)
-    if not irc:
-        diag.printErrors(testsrc)
-    irc.check()
-    #irc.dump()
-    with open('ir.gv', 'w') as f:
-        ir.dumpgv(irc, f)
-    outs = outstream.TextOutputStream()
-    cga = codegenarm.ArmCodeGenerator(outs)
-    ir2 = cga.generate(irc)
-
-    with open('cfg.gv', 'w') as cfg_file:
-        dump_cfg(cga, cfg_file)
-
-    with open('ig.gv', 'w') as ig_file:
-        dump_ig(cga, ig_file)
-        
-    outs.dump()
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/utils/iso9660.py	Sun Nov 24 11:24:15 2013 +0100
@@ -0,0 +1,82 @@
+#!/usr/bin/env python
+
+import argparse
+
+__doc__ = """
+  ISO 9660 filesystem utility.
+"""
+
+
+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)
+
+
+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)
+
+
+@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
+
+
+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__':
+    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/x86.py	Thu Nov 21 15:46:50 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +0,0 @@
-import ppci
-import ir
-
-class X86CodeGenSimple:
-   """ 
-    Inefficient code generation, assume stack machine 
-    backend
-   """
-   def __init__(self, diag):
-      self.diag = diag
-
-   def emit(self, i):
-      self.asm.append(i)
-
-   def genBin(self, ir):
-      self.asm = []
-      self.genModule(ir)
-      return self.asm
-
-   def genModule(self, ir):
-      for f in ir.Functions:
-         self.genFunction(f)
-   def genFunction(self, f):
-      self.emit('global {0}'.format(f.name))
-      self.emit('{0}:'.format(f.name))
-      self.emit('jmp {0}'.format(f.entry.name))
-      for bb in f.BasicBlocks:
-         self.genBB(bb)
-   def genBB(self, bb):
-      self.emit('{0}:'.format(bb.name))
-      for i in bb.Instructions:
-         self.genIns(i)
-   def genIns(self, i):
-      if type(i) is ir.BinaryOperator:
-         ops = {'+':'add', '-':'sub', '*':'mul'}
-         if i.operation in ops:
-            i.result.reg = 'rax'
-            i.value1.reg = 'rbx'
-            i.value2.reg = 'rbx'
-            self.emit('mov {0}, {1}'.format(i.result.reg, i.value1.reg))
-            self.emit('{0} {1}, {2}'.format(ops[i.operation], i.result.reg, i.value2.reg))
-         else:
-            raise NotImplementedError('op {0}'.format(i.operation))
-      elif type(i) is ir.Load:
-         self.emit('mov {0}, [{1}]'.format(i.value, i.location))
-      elif type(i) is ir.Return:
-         self.emit('ret')
-      elif type(i) is ir.Call:
-         self.emit('call')
-      elif type(i) is ir.ImmLoad:
-         self.emit('mov {0}, {1}'.format(i.target, i.value))
-      elif type(i) is ir.Store:
-         self.emit('mov [{0}], {1}'.format(i.location, i.value))
-      elif type(i) is ir.ConditionalBranch:
-         self.emit('cmp {0}, {1}'.format(i.a, i.b))
-         jmps = {'>':'jg', '<':'jl', '==':'je'}
-         if i.cond in jmps:
-            j = jmps[i.cond]
-            self.emit('{0} {1}'.format(j, i.lab1.name))
-         else:
-            raise NotImplementedError('condition {0}'.format(i.cond))
-         self.emit('jmp {0}'.format(i.lab2.name))
-      elif type(i) is ir.Branch:
-         self.emit('jmp {0}'.format(i.target.name))
-      elif type(i) is ir.Alloc:
-         pass
-      else:
-         raise NotImplementedError('{0}'.format(i))
-
--- a/python/x86_2.py	Thu Nov 21 15:46:50 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,356 +0,0 @@
-"""
-    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	Thu Nov 21 15:46:50 2013 +0100
+++ b/python/zcc.py	Sun Nov 24 11:24:15 2013 +0100
@@ -7,10 +7,9 @@
 import c3
 import ppci
 import codegen
-import codegenarm
-from optimize import optimize
 import outstream
 import hexfile
+import target
 
 
 logformat='%(asctime)s|%(levelname)s|%(name)s|%(message)s'
@@ -23,20 +22,25 @@
     return numeric_level
 
 
+target_list = [target.armtarget]
+targetnames = {t.name: t for t in target_list}
+
 # Parse arguments:
 parser = argparse.ArgumentParser(description='lcfos Compiler')
 # Input:
 parser.add_argument('source', type=argparse.FileType('r'), \
   help='the source file to build', nargs="+")
-parser.add_argument('-i', '--import', type=argparse.FileType('r'), \
+parser.add_argument('-i', '--imp', 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('--target', help="Backend selection")
+parser.add_argument('--target', help="Backend selection",
+    choices=targetnames.keys())
 parser.add_argument('-o', '--output', help='Output file', metavar='filename')
-parser.add_argument('--hexfile', help='Output hexfile', type=argparse.FileType('w'))
+parser.add_argument('--hexfile', help='Output hexfile',
+    type=argparse.FileType('w'))
 parser.add_argument('--log', help='Log level (INFO,DEBUG)', type=logLevel)
 
 
@@ -48,26 +52,27 @@
     logging.info('Zcc started')
     # Front end:
     c3b = c3.Builder(diag)
+    tg = target.armtarget.armtarget
+    # TODO select target here!
+    cg = codegen.CodeGenerator(outs, tg)
     for ircode in c3b.build(srcs, imps):
         if not ircode:
             return
 
-        # Optimization passes:
-        optimize(ircode)
+        # Optimization passes, TODO
 
         if dumpir:
             ircode.dump()
 
-        # TODO select target here!
         # Code generation:
-        codegenarm.ArmCodeGenerator(outs).generate(ircode)
+        cg.generate(ircode)
     return c3b.ok
 
 
 def main(args):
     logging.basicConfig(format=logformat, level=args.log)
     src = args.source
-    imps = getattr(args, 'import')
+    imps = args.imp
     diag = ppci.DiagnosticsManager()
     outs = outstream.TextOutputStream()
 
--- a/readme.rst	Thu Nov 21 15:46:50 2013 +0100
+++ b/readme.rst	Sun Nov 24 11:24:15 2013 +0100
@@ -24,18 +24,23 @@
 How to start the IDE
 --------------------
 
+.. code:: bash
+
     cd python
     python ide.py
 
 Run unittests
 -------------
 
-    cd python
+.. code:: bash
+
+    cd test
     python -m unittest
 
+
 .. image:: https://drone.io/bitbucket.org/windel/lcfos/status.png
 
-.. image:: https://codeship.io/projects/f4a4da90-2ffd-0131-58c6-5ea61a10d89b/status
+.. image:: https://www.ohloh.net/p/lcfos/widgets/project_thin_badge.gif
 
 
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tcodegen.py	Sun Nov 24 11:24:15 2013 +0100
@@ -0,0 +1,141 @@
+
+"""
+  Test individual parts of the code generation for arm using the c3 frontend.
+"""
+
+import c3
+import ppci
+import codegenarm
+import outstream
+import ir
+
+testsrc = """
+package test2;
+
+var int phaa, foo, bar;
+
+function int insanemath(int a, int b)
+{
+  var int c;
+  c = 0;
+  var int i;
+  i = 9;
+  while (i > 1)
+  {
+      c = a + b + 1 + c;
+      i = i - 1;
+      if (c > 90)
+      {
+         return 42;
+      }
+  }
+  return c;
+}
+
+function void tesssst(int henkie)
+{
+   var int a, b, cee;
+   a = 2 * 33 - 12;
+   b = a * 2;
+   a = b + a;
+   cee = a;
+   cee = cee * 2 + cee;
+   insanemath(2, 3);
+   if (cee + a > b and b - a+b== 3*6-insanemath(b, 2))
+   {
+      var int x = a;
+      x = b - a + insanemath(3, 4) - insanemath(33, insanemath(2, 0));
+      a = x * (x + a);
+   }
+   else
+   {
+      a = b + (a + b);
+   }
+   var int y;
+   y = a - b * 53;
+}
+"""
+
+testsrc = """
+package test3;
+
+function int ab(int a, int b)
+{
+  var int c;
+  c = 0;
+  c = c + a + b;
+  return c; 
+}
+
+function void tesssst()
+{
+   var int a, b;
+   a = 2;
+   b = 3;
+   ab(ab(a, b) + ab(9,b), 0);
+}
+"""
+
+testsrc = """
+package test3;
+
+function int ab(int a, int b)
+{
+  var int c;
+  var int *a2;
+  a2 = cast<int*>(2);
+  *a2 = 2;
+  *a2 = *a2 + 2;
+  c = 0;
+  c = c + a + b;
+  return c; 
+}
+
+"""
+def dump_cfg(cga, cfg_file):
+    print('digraph G {', file=cfg_file)
+    #print('edge [constraint=none]', file=cfg_file)
+    print('rankdir=TB', file=cfg_file)
+    for f in cga.frames:
+        print('subgraph cluster_{} {{'.format(f.name), file=cfg_file)
+        print('label={};'.format(f.name), file=cfg_file)
+        print('color=lightgrey;', file=cfg_file)
+        print('style=filled;', file=cfg_file)
+        f.cfg.to_dot(cfg_file)
+        print('}', file=cfg_file)
+    print('}', file=cfg_file)
+
+def dump_ig(cga, ig_file):
+    print('digraph G {', file=ig_file)
+    print('edge [arrowhead=none]', file=ig_file)
+    for f in cga.frames:
+        print('subgraph cluster_{} {{'.format(f.name), file=ig_file)
+        print('label={};'.format(f.name), file=ig_file)
+        print('color=lightgrey;', file=ig_file)
+        print('style=filled;', file=ig_file)
+        f.ig.to_dot(ig_file)
+        print('}', file=ig_file)
+    print('}', file=ig_file)
+
+if __name__ == '__main__':
+    diag = ppci.DiagnosticsManager()
+    builder = c3.Builder(diag)
+    irc = builder.build(testsrc)
+    if not irc:
+        diag.printErrors(testsrc)
+    irc.check()
+    #irc.dump()
+    with open('ir.gv', 'w') as f:
+        ir.dumpgv(irc, f)
+    outs = outstream.TextOutputStream()
+    cga = codegenarm.ArmCodeGenerator(outs)
+    ir2 = cga.generate(irc)
+
+    with open('cfg.gv', 'w') as cfg_file:
+        dump_cfg(cga, cfg_file)
+
+    with open('ig.gv', 'w') as ig_file:
+        dump_ig(cga, ig_file)
+        
+    outs.dump()
+
--- a/test/testasm.py	Thu Nov 21 15:46:50 2013 +0100
+++ b/test/testasm.py	Sun Nov 24 11:24:15 2013 +0100
@@ -4,11 +4,11 @@
 from ppci import CompilerError
 from asmnodes import AInstruction, ABinop, AUnop, ASymbol, ALabel, ANumber
 from asm import tokenize, Assembler
-import msp430
-import cortexm3 as arm
+import target.armtarget as arm
 import outstream
 from target import Label
 
+
 class AssemblerLexingCase(unittest.TestCase):
     """ Tests the assemblers lexer """
 
@@ -33,6 +33,7 @@
         with self.assertRaises(CompilerError):
             list(tokenize(asmline))
 
+
 class AssemblerParsingTestCase(unittest.TestCase):
     """ 
         Tests the assembler parts
@@ -313,6 +314,4 @@
         self.check('32b41519 94420198 049332bc a340ab42 f6d0f5d1 f4e7')
 
 if __name__ == '__main__':
-    #cProfile.run('unittest.main()')
     unittest.main()
-
--- a/test/testcg.py	Thu Nov 21 15:46:50 2013 +0100
+++ b/test/testcg.py	Sun Nov 24 11:24:15 2013 +0100
@@ -4,6 +4,7 @@
 import codegenarm
 import outstream
 
+
 def genTestFunction():
     m = ir.Module('tst')
     f = ir.Function('tst')
@@ -38,4 +39,3 @@
 
 if __name__ == '__main__':
     unittest.main()
-
--- a/test/testgraph.py	Thu Nov 21 15:46:50 2013 +0100
+++ b/test/testgraph.py	Sun Nov 24 11:24:15 2013 +0100
@@ -40,7 +40,7 @@
 
 class DigraphTestCase(unittest.TestCase):
     pass
-        
+
 
 class InterferenceGraphTestCase(unittest.TestCase):
     def testNormalUse(self):
@@ -78,4 +78,3 @@
 
 if __name__ == '__main__':
     unittest.main()
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/testmsp430asm.py	Sun Nov 24 11:24:15 2013 +0100
@@ -0,0 +1,49 @@
+#!/usr/bin/python
+
+import unittest
+from asmnodes import AInstruction, ABinop, AUnop, ASymbol, ALabel, ANumber
+from asm import tokenize, Assembler
+import msp430
+import outstream
+from target import Label
+from testasm import AsmTestCaseBase
+
+
+class AssemblerMSP430TestCase(AsmTestCaseBase):
+    def setUp(self):
+        self.t = msp430.msp430target
+        self.o = outstream.BinOutputStream()
+        self.o.selectSection('.text')
+        self.a = Assembler(target=self.t, stream=self.o)
+
+    def testMapMovInstruction(self):
+        i = AInstruction('mov', [ASymbol('r14'), ASymbol('r15')])
+        ri = self.t.mapInstruction(i)
+
+    def testMapRetiInstruction(self):
+        i = AInstruction('reti', [])
+        ri = self.t.mapInstruction(i)
+
+    def testMov(self):
+        self.feed("mov r14, r15")
+        self.check('0F4E')
+
+    def testMov1337(self):
+        self.feed("mov 0x1337, r12")
+        self.check('3C403713')
+
+    def testAdd(self):
+        self.feed("add r15, r13")
+        self.check('0D5F')
+
+    def testReti(self):
+        self.feed("reti")
+        self.check('0013')
+
+    def testMSPinstructionCount(self):
+        """ Check that there are 27 instructions """
+        self.assertEqual(27, len(self.t.instructions))
+
+
+if __name__ == '__main__':
+    unittest.main()