diff --git a/Compiler.hs b/Compiler.hs
--- a/Compiler.hs
+++ b/Compiler.hs
@@ -1,6 +1,6 @@
-import qualified NXT.AttoParser as P
 import NXT.Types
-import NXT.Inference
+import NXT.Compiler.Inference
+import qualified NXT.Parser.AttoParser as P
 
 import System.Environment
 
diff --git a/Example.hs b/Example.hs
deleted file mode 100644
--- a/Example.hs
+++ /dev/null
@@ -1,7 +0,0 @@
-import ExampleCode
-import NXT.Core
-
-import Control.Monad ((=<<), (>>=))
-
-main =
-    tree >>= (mkProg "lineFollow.nxc")
diff --git a/ExampleVM.hs b/ExampleVM.hs
deleted file mode 100644
--- a/ExampleVM.hs
+++ /dev/null
@@ -1,36 +0,0 @@
-import ExampleCode
-import NXT.Interpretation
-
-import Control.Monad
-import Control.Monad.Trans
-import Control.Monad.Trans.Resource
-import Control.Concurrent
-import Control.Concurrent.STM
-
-main =
-    do t <- tree
-       runResourceT $ do env <- runVM t
-                         liftIO $ threadDelay 500000 -- 50 ms setup time
-                         liftIO $ setLoop env
-    where
-      assertMotor name m expect =
-          do got <- atomically $ do b <- readTVar (m_b m)
-                                    c <- readTVar (m_c m)
-                                    return (b, c)
-             when (expect /= got) $ error $ "Assertion (" ++ name ++ ") failed. Expected motor values: "
-                      ++ (show expect) ++ ". Got: " ++ (show got)
-
-      setLoop t@(envQ, motor) =
-          do atomically $ writeTBQueue envQ (RealEnv 55 0)
-             threadDelay 100000 -- 10 ms
-             assertMotor "light = 55" motor (37, 37)
-
-             atomically $ writeTBQueue envQ (RealEnv 0 0)
-             threadDelay 100000 -- 10 ms
-             assertMotor "light = 0" motor (0, 75)
-
-             atomically $ writeTBQueue envQ (RealEnv 100 0)
-             threadDelay 100000 -- 10 ms
-             assertMotor "light = 100" motor (75, 0)
-
-             setLoop t
diff --git a/NXT/Common.hs b/NXT/Common.hs
deleted file mode 100644
--- a/NXT/Common.hs
+++ /dev/null
@@ -1,17 +0,0 @@
-{-# LANGUAGE DeriveDataTypeable #-}
--- |
--- Module      : NXT.Interpretation
--- Copyright   : Alexander Thiemann <mail@agrafix.net>
--- License     : BSD3
---
--- Maintainer  : Alexander Thiemann <mail@agrafix.net>
--- Stability   : experimental
--- Portability : non-portable (GHC extensions)
---
-module NXT.Common where
-
-import NXT.Core
-import Data.Typeable
-
-wait :: V (V Integer -> V ())
-wait = defExt "Wait"
diff --git a/NXT/Core.hs b/NXT/Core.hs
--- a/NXT/Core.hs
+++ b/NXT/Core.hs
@@ -33,7 +33,6 @@
 where
 
 import NXT.Types
-import NXT.Interpretation
 
 import Data.List
 import Data.Typeable
diff --git a/NXT/Interpretation.hs b/NXT/Interpretation.hs
deleted file mode 100644
--- a/NXT/Interpretation.hs
+++ /dev/null
@@ -1,300 +0,0 @@
-{-# LANGUAGE DeriveDataTypeable, DoAndIfThenElse #-}
--- |
--- Module      : NXT.Interpretation
--- Copyright   : Alexander Thiemann <mail@agrafix.net>
--- License     : BSD3
---
--- Maintainer  : Alexander Thiemann <mail@agrafix.net>
--- Stability   : experimental
--- Portability : non-portable (GHC extensions)
---
-module NXT.Interpretation
-    ( runVM
-    , RealEnv (..)
-    , MotorState(..)
-    )
-where
-
-import NXT.Types
-
-import Data.IORef
-import Control.Applicative
-import Control.Concurrent
-import Control.Concurrent.STM
-import Control.Monad.Trans
-import Control.Monad.Trans.Resource
-import qualified Data.HashMap.Strict as HM
-
-type EnvChan = TBQueue RealEnv
-data RealEnv
-   = RealEnv
-   { re_light :: Int
-   , re_ultra :: Int
-   } deriving (Show)
-
-data MotorState
-   = MotorState
-   { m_a :: TVar Int
-   , m_b :: TVar Int
-   , m_c :: TVar Int
-   }
-
-getMS 0 = m_a
-getMS 1 = m_b
-getMS 2 = m_c
-
-data SensorState
-   = SensorState
-   { s_1 :: TVar Int
-   , s_2 :: TVar Int
-   , s_3 :: TVar Int
-   , s_4 :: TVar Int
-   }
-
-data SensorReads
-   = SensorReads
-   { sr_1 :: TVar (RealEnv -> Int)
-   , sr_2 :: TVar (RealEnv -> Int)
-   , sr_3 :: TVar (RealEnv -> Int)
-   , sr_4 :: TVar (RealEnv -> Int)
-   }
-
-getSS :: Int -> (SensorState -> TVar Int)
-getSS 0 = s_1
-getSS 1 = s_2
-getSS 2 = s_3
-getSS 3 = s_4
-
-getSR :: Int -> (SensorReads -> TVar (RealEnv -> Int))
-getSR 0 = sr_1
-getSR 1 = sr_2
-getSR 2 = sr_3
-getSR 3 = sr_4
-
-data FunMap
-   = FunMap
-    { fm_funs :: HM.HashMap String FunDefinition
-    , fm_apiCall  :: String -> [NXTVal] -> IO NXTVal
-    }
-
-type Env = IORef (HM.HashMap String (IORef NXTVal))
-
-data NXTVal
-   = NInt Int
-   | NFloat Float
-   | NStr String
-   | NBool Bool
-   | NVoid
-   deriving (Eq, Show, Ord)
-
-emptyEnv :: IO Env
-emptyEnv = newIORef HM.empty
-
-isBound :: Env -> String -> IO Bool
-isBound envR var =
-    readIORef envR >>= return . maybe False (const True) . HM.lookup var
-
-getVar :: Env -> String -> IO NXTVal
-getVar envR var =
-    do env <- liftIO $ readIORef envR
-       maybe (error $ "Getting an unbound variable " ++ var)
-                 (liftIO . readIORef)
-                 (HM.lookup var env)
-
-setVar :: Env -> String -> NXTVal -> IO NXTVal
-setVar envR var value =
-    do env <- liftIO $ readIORef envR
-       maybe (error $ "Setting an unbound variable " ++ var)
-                 (liftIO . (flip writeIORef value))
-                 (HM.lookup var env)
-       return value
-
-defineVar :: Env -> String -> NXTVal -> IO NXTVal
-defineVar envR var value = do
-    alreadyDefined <- liftIO $ isBound envR var
-    if alreadyDefined
-       then setVar envR var value >> return value
-       else liftIO $ do
-          valueR <- newIORef value
-          env <- readIORef envR
-          writeIORef envR (HM.insert var valueR env)
-          return value
-
-runVM :: MonadResource m => [FunDefinition] -> m (EnvChan, MotorState)
-runVM fd =
-    do env <- liftIO emptyEnv
-       envChan <- liftIO $ atomically $ newTBQueue 20
-       b <- liftIO motorState
-       c <- liftIO sensorState
-       d <- liftIO sensorReads
-
-       case HM.lookup "main" funMap of
-         Just fd ->
-             do _ <- allocate (forkIO (updateLoop envChan c d)) (killThread)
-                _ <- allocate (forkIO $ runDef (FunMap funMap (apiCall envChan b c d)) env fd) (killThread)
-                return (envChan, b)
-         Nothing ->
-             error "No main task found."
-    where
-      updateLoop envQ sensor sensorR =
-          do logE <- atomically $
-                     do env <- readTBQueue envQ
-                        mapM_ (\sensorId ->
-                               do extractFun <- readTVar ((getSR sensorId) sensorR)
-                                  let envVal = (extractFun env)
-                                  writeTVar ((getSS sensorId) sensor) envVal
-                              ) [0..3]
-                        return env
-             putStrLn $ "New Environment: " ++ (show logE)
-             updateLoop envQ sensor sensorR
-
-      funMap = foldl (\hm f@(FunDefinition name _ _ _) -> HM.insert name f hm) HM.empty fd
-      apiCall env motor sensor sensorR funName input =
-          do ret <- apiCall' env motor sensor sensorR funName input
-             putStrLn $ "Called " ++ (show (funName, input))
-             putStrLn $ "Got: " ++ show ret
-             return ret
-      apiCall' env motor sensor sensorR funName input =
-          case (funName, input) of
-            ("Wait", [NInt time]) ->
-                do threadDelay (1000 * time)
-                   return NVoid
-            ("SetSensorLight", [NInt sensorId]) ->
-                do atomically $ writeTVar ((getSR sensorId) sensorR) re_light
-                   return NVoid
-            ("Sensor", [NInt sensorId]) ->
-                do ct <- atomically $ readTVar ((getSS sensorId) sensor)
-                   return $ NInt ct
-            ("OnFwd", [NInt motorId, NInt motorPwr]) ->
-                do atomically $ writeTVar ((getMS motorId) motor) motorPwr
-                   return NVoid
-            x ->
-                error $ "Call to undefined function " ++ (show x)
-
-      motorState = MotorState <$> zero <*> zero <*> zero
-      sensorState = SensorState <$> zero <*> zero <*> zero <*> zero
-      sensorReads = SensorReads
-                    <$> unknown
-                    <*> unknown
-                    <*> unknown
-                    <*> unknown
-      zero = atomically $ newTVar 0
-      unknown = atomically $ newTVar $ (\_ -> -1)
-
-runDef :: FunMap -> Env -> FunDefinition -> IO ()
-runDef funMap env (FunDefinition _ _ _ body) =
-    mapM_ (runStmt funMap env) body
-
-runStmt :: FunMap -> Env -> Stmt -> IO ()
-runStmt funMap env (If condR t f) =
-    do (NBool cond) <- runT funMap env condR
-       if cond
-       then mapM_ (runStmt funMap env) t
-       else mapM_ (runStmt funMap env) f
-runStmt funMap env l@(While condR loop) =
-    do (NBool cond) <- runT funMap env condR
-       if cond
-       then do mapM_ (runStmt funMap env) loop
-               runStmt funMap env l
-       else return ()
-runStmt funMap env (DeclVar _ (VarP p)) =
-    do defineVar env p NVoid
-       return ()
-runStmt funMap env (AssignVar (VarP p) valR) =
-    do val <- runT funMap env valR
-       setVar env p val
-       return ()
-
-runStmt funMap env (Eval v) =
-    do _ <- runT funMap env v
-       return ()
-runStmt funMap env (FunReturn v) =
-    do val <- runT funMap env v
-       defineVar env "__funReturnVal" val
-       return ()
-
-runV :: FunMap -> Env -> V a -> IO NXTVal
-runV funMap env ct = runT funMap env (unpack ct)
-
-runT :: FunMap -> Env -> T -> IO NXTVal
-runT _ _ Void = return NVoid
-runT _ env (VarP p) = getVar env p
-runT _ env (Lit i) = return $ NInt i
-runT _ env (Rat i) = return $ NFloat i
-runT _ env (StrLit str) = return $ NStr str
-runT _ env (BoolLit b) = return $ NBool b
-
-runT funMap env (CastOp "cast2int" val) =
-     do evaluated <- runT funMap env val
-        case evaluated of
-          NFloat f -> return $ NInt $ floor f
-          _ -> error "Invalid cast."
-runT funMap env (CastOp "cast2float" val) =
-     do evaluated <- runT funMap env val
-        case evaluated of
-          NInt i -> return $ NFloat $ fromIntegral i
-          _ -> error "Invalid cast."
-
-runT funMap env (BinOp op xR yR) =
-    do x <- runT funMap env xR
-       y <- runT funMap env yR
-
-       case (x, op, y) of
-         (NInt a, BAdd, NInt b) -> return $ NInt (a + b)
-         (NInt a, BSub, NInt b) -> return $ NInt (a - b)
-         (NInt a, BMul, NInt b) -> return $ NInt (a * b)
-
-         (NFloat a, BAdd, NFloat b) -> return $ NFloat (a + b)
-         (NFloat a, BSub, NFloat b) -> return $ NFloat (a - b)
-         (NFloat a, BMul, NFloat b) -> return $ NFloat (a * b)
-         (NFloat a, BDiv, NFloat b) -> return $ NFloat (a / b)
-
-         (NInt a, BSub, NFloat b) -> return $ NFloat ((fromIntegral a) - b)
-         (NFloat a, BSub, NInt b) -> return $ NFloat (a - (fromIntegral b))
-         (NInt a, BMul, NFloat b) -> return $ NFloat ((fromIntegral a) * b)
-         (NFloat a, BMul, NInt b) -> return $ NFloat (a * (fromIntegral b))
-         (NInt a, BAdd, NFloat b) -> return $ NFloat ((fromIntegral a) + b)
-         (NFloat a, BAdd, NInt b) -> return $ NFloat (a + (fromIntegral b))
-
-         (a, BEq, b) -> return $ NBool (a == b)
-         (a, BNEq, b) -> return $ NBool (a /= b)
-         (a, BLt, b) -> return $ NBool (a > b)
-         (a, BSt, b) -> return $ NBool (a < b)
-         (a, BLEq, b) -> return $ NBool (a >= b)
-         (a, BSEq, b) -> return $ NBool (a <= b)
-
-         (NBool a, BAnd, NBool b) -> return $ NBool (a && b)
-         (NBool a, BOr, NBool b) -> return $ NBool (a || b)
-         x -> error $ "Unknown operation: " ++ show x
-
-runT funMap env (FunCall name args) =
-    do evaled <- mapM (runT funMap env) args
-       apply funMap name evaled
-
-runT _ env t = error $ "Not implemented:" ++ (prettyT t)
-
-reqV (VarP p) = p
-reqV x = error $ "Require a variable, but got: " ++ (prettyT x)
-
-getArgs funMap funName =
-    case HM.lookup funName (fm_funs funMap) of
-      Just (FunDefinition _ _ args _) ->
-          map (\(DeclVar _ arg) -> reqV arg) args
-      Nothing ->
-          error $ "Function " ++ funName ++ " is not defined."
-
-apply :: FunMap -> String -> [NXTVal] -> IO NXTVal
-apply funMap funName inpVals =
-    do funEnv <- emptyEnv
-
-       case HM.lookup funName (fm_funs funMap) of
-         Just fd ->
-             do let args = getArgs funMap funName
-                    vars = zip inpVals args
-                mapM_ (\(src, tgt) ->
-                           defineVar funEnv tgt src
-                      ) vars
-                runDef funMap funEnv fd
-                getVar funEnv "__funReturnVal"
-         Nothing ->
-             (fm_apiCall funMap) funName inpVals
diff --git a/NXT/Motor.hs b/NXT/Motor.hs
deleted file mode 100644
--- a/NXT/Motor.hs
+++ /dev/null
@@ -1,48 +0,0 @@
-{-# LANGUAGE DeriveDataTypeable #-}
--- |
--- Module      : NXT.Motor
--- Copyright   : Alexander Thiemann <mail@agrafix.net>
--- License     : BSD3
---
--- Maintainer  : Alexander Thiemann <mail@agrafix.net>
--- Stability   : experimental
--- Portability : non-portable (GHC extensions)
---
-module NXT.Motor where
-
-import NXT.Core
-import Data.Typeable
-
-data Motor = Motor deriving (Typeable)
-
-_OUT_A_ :: V Motor
-_OUT_A_ = mkLit 0
-
-_OUT_B_ :: V Motor
-_OUT_B_ = mkLit 1
-
-_OUT_C_ :: V Motor
-_OUT_C_ = mkLit 2
-
-{--
-_OUT_AB_ :: V Motor
-_OUT_AB_ = mkLit 3
-
-_OUT_AC_ :: V Motor
-_OUT_AC_ = mkLit 4
-
-_OUT_BC_ :: V Motor
-_OUT_BC_ = mkLit 5
-
-_OUT_ABC_ :: V Motor
-_OUT_ABC_ = mkLit 6
---}
-
-onFwd :: V (V Motor -> V Int -> V ())
-onFwd = defExt "OnFwd"
-
-onRev :: V (V Motor -> V Int -> V ())
-onRev = defExt "OnRev"
-
-off :: V (V Motor -> V ())
-off = defExt "Off"
diff --git a/NXT/Sensor.hs b/NXT/Sensor.hs
deleted file mode 100644
--- a/NXT/Sensor.hs
+++ /dev/null
@@ -1,34 +0,0 @@
-{-# LANGUAGE DeriveDataTypeable #-}
--- |
--- Module      : NXT.Sensor
--- Copyright   : Alexander Thiemann <mail@agrafix.net>
--- License     : BSD3
---
--- Maintainer  : Alexander Thiemann <mail@agrafix.net>
--- Stability   : experimental
--- Portability : non-portable (GHC extensions)
---
-module NXT.Sensor where
-
-import NXT.Core
-import Data.Typeable
-
-data Sensor = Sensor deriving (Typeable)
-
-_IN_1_ :: V Sensor
-_IN_1_ = mkLit 0
-
-_IN_2_ :: V Sensor
-_IN_2_ = mkLit 1
-
-_IN_3_ :: V Sensor
-_IN_3_ = mkLit 2
-
-_IN_4_ :: V Sensor
-_IN_4_ = mkLit 3
-
-setSensorLight :: V (V Sensor -> V ())
-setSensorLight = defExt "SetSensorLight"
-
-sensor :: V (V Sensor -> V Int)
-sensor = defExt "Sensor"
diff --git a/NXT/Stdlib/Common.hs b/NXT/Stdlib/Common.hs
new file mode 100644
--- /dev/null
+++ b/NXT/Stdlib/Common.hs
@@ -0,0 +1,18 @@
+{-# LANGUAGE DeriveDataTypeable #-}
+-- |
+-- Module      : NXT.Interpretation
+-- Copyright   : Alexander Thiemann <mail@agrafix.net>
+-- License     : BSD3
+--
+-- Maintainer  : Alexander Thiemann <mail@agrafix.net>
+-- Stability   : experimental
+-- Portability : non-portable (GHC extensions)
+--
+module NXT.Stdlib.Common where
+
+import NXT.Core
+
+import Data.Typeable
+
+wait :: V (V Integer -> V ())
+wait = defExt "Wait"
diff --git a/NXT/Stdlib/Motor.hs b/NXT/Stdlib/Motor.hs
new file mode 100644
--- /dev/null
+++ b/NXT/Stdlib/Motor.hs
@@ -0,0 +1,48 @@
+{-# LANGUAGE DeriveDataTypeable #-}
+-- |
+-- Module      : NXT.Motor
+-- Copyright   : Alexander Thiemann <mail@agrafix.net>
+-- License     : BSD3
+--
+-- Maintainer  : Alexander Thiemann <mail@agrafix.net>
+-- Stability   : experimental
+-- Portability : non-portable (GHC extensions)
+--
+module NXT.Stdlib.Motor where
+
+import NXT.Core
+import Data.Typeable
+
+data Motor = Motor deriving (Typeable)
+
+_OUT_A_ :: V Motor
+_OUT_A_ = mkLit 0
+
+_OUT_B_ :: V Motor
+_OUT_B_ = mkLit 1
+
+_OUT_C_ :: V Motor
+_OUT_C_ = mkLit 2
+
+{--
+_OUT_AB_ :: V Motor
+_OUT_AB_ = mkLit 3
+
+_OUT_AC_ :: V Motor
+_OUT_AC_ = mkLit 4
+
+_OUT_BC_ :: V Motor
+_OUT_BC_ = mkLit 5
+
+_OUT_ABC_ :: V Motor
+_OUT_ABC_ = mkLit 6
+--}
+
+onFwd :: V (V Motor -> V Int -> V ())
+onFwd = defExt "OnFwd"
+
+onRev :: V (V Motor -> V Int -> V ())
+onRev = defExt "OnRev"
+
+off :: V (V Motor -> V ())
+off = defExt "Off"
diff --git a/NXT/Stdlib/Sensor.hs b/NXT/Stdlib/Sensor.hs
new file mode 100644
--- /dev/null
+++ b/NXT/Stdlib/Sensor.hs
@@ -0,0 +1,35 @@
+{-# LANGUAGE DeriveDataTypeable #-}
+-- |
+-- Module      : NXT.Sensor
+-- Copyright   : Alexander Thiemann <mail@agrafix.net>
+-- License     : BSD3
+--
+-- Maintainer  : Alexander Thiemann <mail@agrafix.net>
+-- Stability   : experimental
+-- Portability : non-portable (GHC extensions)
+--
+module NXT.Stdlib.Sensor where
+
+import NXT.Core
+
+import Data.Typeable
+
+data Sensor = Sensor deriving (Typeable)
+
+_IN_1_ :: V Sensor
+_IN_1_ = mkLit 0
+
+_IN_2_ :: V Sensor
+_IN_2_ = mkLit 1
+
+_IN_3_ :: V Sensor
+_IN_3_ = mkLit 2
+
+_IN_4_ :: V Sensor
+_IN_4_ = mkLit 3
+
+setSensorLight :: V (V Sensor -> V ())
+setSensorLight = defExt "SetSensorLight"
+
+sensor :: V (V Sensor -> V Int)
+sensor = defExt "Sensor"
diff --git a/NXT/VM/Interpretation.hs b/NXT/VM/Interpretation.hs
new file mode 100644
--- /dev/null
+++ b/NXT/VM/Interpretation.hs
@@ -0,0 +1,300 @@
+{-# LANGUAGE DeriveDataTypeable, DoAndIfThenElse #-}
+-- |
+-- Module      : NXT.Interpretation
+-- Copyright   : Alexander Thiemann <mail@agrafix.net>
+-- License     : BSD3
+--
+-- Maintainer  : Alexander Thiemann <mail@agrafix.net>
+-- Stability   : experimental
+-- Portability : non-portable (GHC extensions)
+--
+module NXT.VM.Interpretation
+    ( runVM
+    , RealEnv (..)
+    , MotorState(..)
+    )
+where
+
+import NXT.Types
+
+import Data.IORef
+import Control.Applicative
+import Control.Concurrent
+import Control.Concurrent.STM
+import Control.Monad.Trans
+import Control.Monad.Trans.Resource
+import qualified Data.HashMap.Strict as HM
+
+type EnvChan = TBQueue RealEnv
+data RealEnv
+   = RealEnv
+   { re_light :: Int
+   , re_ultra :: Int
+   } deriving (Show)
+
+data MotorState
+   = MotorState
+   { m_a :: TVar Int
+   , m_b :: TVar Int
+   , m_c :: TVar Int
+   }
+
+getMS 0 = m_a
+getMS 1 = m_b
+getMS 2 = m_c
+
+data SensorState
+   = SensorState
+   { s_1 :: TVar Int
+   , s_2 :: TVar Int
+   , s_3 :: TVar Int
+   , s_4 :: TVar Int
+   }
+
+data SensorReads
+   = SensorReads
+   { sr_1 :: TVar (RealEnv -> Int)
+   , sr_2 :: TVar (RealEnv -> Int)
+   , sr_3 :: TVar (RealEnv -> Int)
+   , sr_4 :: TVar (RealEnv -> Int)
+   }
+
+getSS :: Int -> (SensorState -> TVar Int)
+getSS 0 = s_1
+getSS 1 = s_2
+getSS 2 = s_3
+getSS 3 = s_4
+
+getSR :: Int -> (SensorReads -> TVar (RealEnv -> Int))
+getSR 0 = sr_1
+getSR 1 = sr_2
+getSR 2 = sr_3
+getSR 3 = sr_4
+
+data FunMap
+   = FunMap
+    { fm_funs :: HM.HashMap String FunDefinition
+    , fm_apiCall  :: String -> [NXTVal] -> IO NXTVal
+    }
+
+type Env = IORef (HM.HashMap String (IORef NXTVal))
+
+data NXTVal
+   = NInt Int
+   | NFloat Float
+   | NStr String
+   | NBool Bool
+   | NVoid
+   deriving (Eq, Show, Ord)
+
+emptyEnv :: IO Env
+emptyEnv = newIORef HM.empty
+
+isBound :: Env -> String -> IO Bool
+isBound envR var =
+    readIORef envR >>= return . maybe False (const True) . HM.lookup var
+
+getVar :: Env -> String -> IO NXTVal
+getVar envR var =
+    do env <- liftIO $ readIORef envR
+       maybe (error $ "Getting an unbound variable " ++ var)
+                 (liftIO . readIORef)
+                 (HM.lookup var env)
+
+setVar :: Env -> String -> NXTVal -> IO NXTVal
+setVar envR var value =
+    do env <- liftIO $ readIORef envR
+       maybe (error $ "Setting an unbound variable " ++ var)
+                 (liftIO . (flip writeIORef value))
+                 (HM.lookup var env)
+       return value
+
+defineVar :: Env -> String -> NXTVal -> IO NXTVal
+defineVar envR var value = do
+    alreadyDefined <- liftIO $ isBound envR var
+    if alreadyDefined
+       then setVar envR var value >> return value
+       else liftIO $ do
+          valueR <- newIORef value
+          env <- readIORef envR
+          writeIORef envR (HM.insert var valueR env)
+          return value
+
+runVM :: MonadResource m => [FunDefinition] -> m (EnvChan, MotorState)
+runVM fd =
+    do env <- liftIO emptyEnv
+       envChan <- liftIO $ atomically $ newTBQueue 20
+       b <- liftIO motorState
+       c <- liftIO sensorState
+       d <- liftIO sensorReads
+
+       case HM.lookup "main" funMap of
+         Just fd ->
+             do _ <- allocate (forkIO (updateLoop envChan c d)) (killThread)
+                _ <- allocate (forkIO $ runDef (FunMap funMap (apiCall envChan b c d)) env fd) (killThread)
+                return (envChan, b)
+         Nothing ->
+             error "No main task found."
+    where
+      updateLoop envQ sensor sensorR =
+          do logE <- atomically $
+                     do env <- readTBQueue envQ
+                        mapM_ (\sensorId ->
+                               do extractFun <- readTVar ((getSR sensorId) sensorR)
+                                  let envVal = (extractFun env)
+                                  writeTVar ((getSS sensorId) sensor) envVal
+                              ) [0..3]
+                        return env
+             putStrLn $ "New Environment: " ++ (show logE)
+             updateLoop envQ sensor sensorR
+
+      funMap = foldl (\hm f@(FunDefinition name _ _ _) -> HM.insert name f hm) HM.empty fd
+      apiCall env motor sensor sensorR funName input =
+          do ret <- apiCall' env motor sensor sensorR funName input
+             putStrLn $ "Called " ++ (show (funName, input))
+             putStrLn $ "Got: " ++ show ret
+             return ret
+      apiCall' env motor sensor sensorR funName input =
+          case (funName, input) of
+            ("Wait", [NInt time]) ->
+                do threadDelay (1000 * time)
+                   return NVoid
+            ("SetSensorLight", [NInt sensorId]) ->
+                do atomically $ writeTVar ((getSR sensorId) sensorR) re_light
+                   return NVoid
+            ("Sensor", [NInt sensorId]) ->
+                do ct <- atomically $ readTVar ((getSS sensorId) sensor)
+                   return $ NInt ct
+            ("OnFwd", [NInt motorId, NInt motorPwr]) ->
+                do atomically $ writeTVar ((getMS motorId) motor) motorPwr
+                   return NVoid
+            x ->
+                error $ "Call to undefined function " ++ (show x)
+
+      motorState = MotorState <$> zero <*> zero <*> zero
+      sensorState = SensorState <$> zero <*> zero <*> zero <*> zero
+      sensorReads = SensorReads
+                    <$> unknown
+                    <*> unknown
+                    <*> unknown
+                    <*> unknown
+      zero = atomically $ newTVar 0
+      unknown = atomically $ newTVar $ (\_ -> -1)
+
+runDef :: FunMap -> Env -> FunDefinition -> IO ()
+runDef funMap env (FunDefinition _ _ _ body) =
+    mapM_ (runStmt funMap env) body
+
+runStmt :: FunMap -> Env -> Stmt -> IO ()
+runStmt funMap env (If condR t f) =
+    do (NBool cond) <- runT funMap env condR
+       if cond
+       then mapM_ (runStmt funMap env) t
+       else mapM_ (runStmt funMap env) f
+runStmt funMap env l@(While condR loop) =
+    do (NBool cond) <- runT funMap env condR
+       if cond
+       then do mapM_ (runStmt funMap env) loop
+               runStmt funMap env l
+       else return ()
+runStmt funMap env (DeclVar _ (VarP p)) =
+    do defineVar env p NVoid
+       return ()
+runStmt funMap env (AssignVar (VarP p) valR) =
+    do val <- runT funMap env valR
+       setVar env p val
+       return ()
+
+runStmt funMap env (Eval v) =
+    do _ <- runT funMap env v
+       return ()
+runStmt funMap env (FunReturn v) =
+    do val <- runT funMap env v
+       defineVar env "__funReturnVal" val
+       return ()
+
+runV :: FunMap -> Env -> V a -> IO NXTVal
+runV funMap env ct = runT funMap env (unpack ct)
+
+runT :: FunMap -> Env -> T -> IO NXTVal
+runT _ _ Void = return NVoid
+runT _ env (VarP p) = getVar env p
+runT _ env (Lit i) = return $ NInt i
+runT _ env (Rat i) = return $ NFloat i
+runT _ env (StrLit str) = return $ NStr str
+runT _ env (BoolLit b) = return $ NBool b
+
+runT funMap env (CastOp "cast2int" val) =
+     do evaluated <- runT funMap env val
+        case evaluated of
+          NFloat f -> return $ NInt $ floor f
+          _ -> error "Invalid cast."
+runT funMap env (CastOp "cast2float" val) =
+     do evaluated <- runT funMap env val
+        case evaluated of
+          NInt i -> return $ NFloat $ fromIntegral i
+          _ -> error "Invalid cast."
+
+runT funMap env (BinOp op xR yR) =
+    do x <- runT funMap env xR
+       y <- runT funMap env yR
+
+       case (x, op, y) of
+         (NInt a, BAdd, NInt b) -> return $ NInt (a + b)
+         (NInt a, BSub, NInt b) -> return $ NInt (a - b)
+         (NInt a, BMul, NInt b) -> return $ NInt (a * b)
+
+         (NFloat a, BAdd, NFloat b) -> return $ NFloat (a + b)
+         (NFloat a, BSub, NFloat b) -> return $ NFloat (a - b)
+         (NFloat a, BMul, NFloat b) -> return $ NFloat (a * b)
+         (NFloat a, BDiv, NFloat b) -> return $ NFloat (a / b)
+
+         (NInt a, BSub, NFloat b) -> return $ NFloat ((fromIntegral a) - b)
+         (NFloat a, BSub, NInt b) -> return $ NFloat (a - (fromIntegral b))
+         (NInt a, BMul, NFloat b) -> return $ NFloat ((fromIntegral a) * b)
+         (NFloat a, BMul, NInt b) -> return $ NFloat (a * (fromIntegral b))
+         (NInt a, BAdd, NFloat b) -> return $ NFloat ((fromIntegral a) + b)
+         (NFloat a, BAdd, NInt b) -> return $ NFloat (a + (fromIntegral b))
+
+         (a, BEq, b) -> return $ NBool (a == b)
+         (a, BNEq, b) -> return $ NBool (a /= b)
+         (a, BLt, b) -> return $ NBool (a > b)
+         (a, BSt, b) -> return $ NBool (a < b)
+         (a, BLEq, b) -> return $ NBool (a >= b)
+         (a, BSEq, b) -> return $ NBool (a <= b)
+
+         (NBool a, BAnd, NBool b) -> return $ NBool (a && b)
+         (NBool a, BOr, NBool b) -> return $ NBool (a || b)
+         x -> error $ "Unknown operation: " ++ show x
+
+runT funMap env (FunCall name args) =
+    do evaled <- mapM (runT funMap env) args
+       apply funMap name evaled
+
+runT _ env t = error $ "Not implemented:" ++ (prettyT t)
+
+reqV (VarP p) = p
+reqV x = error $ "Require a variable, but got: " ++ (prettyT x)
+
+getArgs funMap funName =
+    case HM.lookup funName (fm_funs funMap) of
+      Just (FunDefinition _ _ args _) ->
+          map (\(DeclVar _ arg) -> reqV arg) args
+      Nothing ->
+          error $ "Function " ++ funName ++ " is not defined."
+
+apply :: FunMap -> String -> [NXTVal] -> IO NXTVal
+apply funMap funName inpVals =
+    do funEnv <- emptyEnv
+
+       case HM.lookup funName (fm_funs funMap) of
+         Just fd ->
+             do let args = getArgs funMap funName
+                    vars = zip inpVals args
+                mapM_ (\(src, tgt) ->
+                           defineVar funEnv tgt src
+                      ) vars
+                runDef funMap funEnv fd
+                getVar funEnv "__funReturnVal"
+         Nothing ->
+             (fm_apiCall funMap) funName inpVals
diff --git a/NXTDSL.cabal b/NXTDSL.cabal
--- a/NXTDSL.cabal
+++ b/NXTDSL.cabal
@@ -1,5 +1,5 @@
 Name:                NXTDSL
-Version:             0.3
+Version:             0.4
 Synopsis:            Generate NXC Code from DSL
 Description:         Typesafe code generation for the LEGO-NXT
 License:             BSD3
@@ -15,16 +15,9 @@
 
 Library
    Build-Depends:     base >= 3 && < 5, mtl, unordered-containers, resourcet >= 0.4.4, stm >= 2.4.2, text, attoparsec >= 0.10.4.0, hashable >= 1.2.0.5
-   Exposed-modules:   NXT.Core, NXT.Interpretation, NXT.Common, NXT.Motor, NXT.Sensor
-
-Executable ExampleRun
-   Main-Is: Example.hs
-
-Executable ExampleVM
-   Main-Is: ExampleVM.hs
-   ghc-options:       -threaded
+   Exposed-modules:   NXT.Core, NXT.VM.Interpretation, NXT.Stdlib.Common, NXT.Stdlib.Motor, NXT.Stdlib.Sensor
 
-Executable Compiler
+Executable legoDSL
    Main-Is: Compiler.hs
 
 Source-repository head
