diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,10 @@
+Copyright (c) 2012, Coiffier Marc <marc.coiffier@gmail.com>
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+    Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+    Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/alpha.cabal b/alpha.cabal
new file mode 100644
--- /dev/null
+++ b/alpha.cabal
@@ -0,0 +1,27 @@
+name:           alpha
+version:        0.9
+synopsis:       A compiler for the Alpha language
+description:    Alpha is a programming language that aims at being very simple and 
+                low-level, so as to be efficient, while at the same time
+                being able to climb in abstraction through introspection
+                in the Lisp Way.
+category:       Compiler
+author:         Marc Coiffier
+maintainer:     marc.coiffier@gmail.com
+stability:      alpha
+license:        BSD3
+license-file:   LICENSE
+build-type:     Simple
+cabal-version:  >= 1.6
+
+source-repository head
+  type: git
+  location: git://github.com/lih/Alpha.git
+
+executable alpha
+  build-depends:  base<=4.5.1.0, unix, containers, array, mtl, bytestring, bimap, ghc-prim, directory, filepath, cereal, parsec
+  main-is:        Alpha.hs
+  other-modules:  Specialize.Types, Specialize.Architecture, IR.Builtin, IR.Instruction, IR.Value, IR, Serialize, Environment, Compile, Compile.State, Compile.Utils, Util.Prelude, Syntax.Parse, Translate, Specialize, Util.ID, Util.Monad, Util.TimeLine, Util.List, Util.Graph, Util.State, Environment.Axiom, Environment.Foreign, Environment.Value, Environment.Context, Syntax, Alpha.Elf, Alpha.Options
+  hs-source-dirs: src
+  c-sources:      src/Alpha/writeElf.c
+
diff --git a/src/Alpha.hs b/src/Alpha.hs
new file mode 100644
--- /dev/null
+++ b/src/Alpha.hs
@@ -0,0 +1,87 @@
+import System.Environment as SE
+import System.FilePath
+import System.Directory
+import System.Posix.Files
+import Alpha.Options
+import Alpha.Elf (writeElf)
+import Syntax
+import Syntax.Parse
+import Environment.Foreign as E
+import Environment.Context
+import Compile
+import Compile.State
+import Serialize
+import Data.Serialize
+import qualified Data.ByteString as B
+import Data.Maybe
+import Util.Monad
+import Control.Monad.State
+import Util.Prelude
+-- import Specialize
+import IR
+
+main = do
+  args <- getArgs
+  case getSettings args of
+    Right s -> execute s
+    Left err -> fail err
+
+execute s = case action s of
+  PrintHelp -> printHelp
+  PrintVersion -> printVersion
+  Compile b -> print s >> doCompile b s
+  
+printHelp = putStrLn helpMsg
+printVersion = putStrLn "Alpha version 1.0"
+  
+newtype Str = Str String
+instance Show Str where show (Str s) = s
+
+doCompile interactive opts = if interactive then void $ compileFile "/dev/stdin" (runes opts)
+                             else mapM_ compileRune (runes opts)
+  where 
+    runeFile rune = runeDir opts</>rune<.>"r"
+    findScroll rune = findM fileExist (concat [[base,base<.>"a"] | dir <- scrollDirs opts, let base = dir</>rune])
+    compileFile src runes = withEnv defaultEnv $ (>>E.getEnv) $ do 
+      str <- readFile src
+      let sTree = concat $ parseAlpha src str
+      mapM_ doImport runes
+      code <- mapM compileExpr sTree
+      stateEnv $ modify (\e -> e { load = foldr concatCode [] code })
+    compileRune name = do
+      scroll <- fromMaybe (error$"Couldn't find scroll file for rune "++name) $< findScroll name
+      let rune = runeFile name
+      ifM (fileExist rune <&&> (rune `newerThan` scroll)) 
+          (putStrLn $ "Rune "++name++" already compiled. Skipping.") $ do 
+        env <- compileFile scroll []
+        print env
+        createDirectoryIfMissing True (dropFileName rune)
+        B.writeFile rune (encode $ exportContext env)
+    compileExpr expr = do
+      (expr',env) <- envCast expr $< E.getEnv
+      (code,cenv) <- compile env Nothing $< doTransform expr'
+      print expr
+      setEnv (context cenv)
+      mapM_ doImport (imports cenv)
+      return code
+    doImport im = do 
+      e <- E.getEnv
+      putStrLn $ "Importing rune "++im
+      unless (isImport im e) $ do 
+        compileRune im
+        let rune = runeFile im
+        ce <- either error id $< decode $< B.readFile rune
+        print ce
+        mapM_ doImport (getImports ce)
+        e <- E.getEnv ; E.setEnv $ merge e (im,ce)
+      
+-- Copyright (c) 2012, Coiffier Marc <marc.coiffier@gmail.com>
+-- All rights reserved.
+
+-- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+--     Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+--     Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
diff --git a/src/Alpha/Elf.hs b/src/Alpha/Elf.hs
new file mode 100644
--- /dev/null
+++ b/src/Alpha/Elf.hs
@@ -0,0 +1,34 @@
+{-# LANGUAGE ForeignFunctionInterface #-}
+module Alpha.Elf (writeElf) where
+
+import Foreign
+import Foreign.C
+import System.Posix.IO
+import System.Posix.Files
+
+foreign import ccall "writeElf" 
+  c_writeElf :: CInt -> Ptr CUChar -> CInt -> Ptr CUChar -> CInt -> IO ()
+              
+
+outFileMode = ownerModes + groupReadMode + groupExecuteMode + otherReadMode + otherExecuteMode
+  where (+) = unionFileModes
+               
+writeElf :: String -> [Word8] -> [Word8] -> IO ()
+writeElf name c d = do
+  fd <- createFile name outFileMode
+  withArrayLen (map fromIntegral c) 
+    (\nc c -> withArrayLen (map fromIntegral d) 
+              (\nd d ->
+                c_writeElf (fromIntegral fd) c (fromIntegral nc) d (fromIntegral nd)))
+                                            
+
+-- Copyright (c) 2012, Coiffier Marc <marc.coiffier@gmail.com>
+-- All rights reserved.
+
+-- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+--     Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+--     Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
diff --git a/src/Alpha/Options.hs b/src/Alpha/Options.hs
new file mode 100644
--- /dev/null
+++ b/src/Alpha/Options.hs
@@ -0,0 +1,76 @@
+module Alpha.Options (Architecture(..),Action(..),Settings(..),helpMsg,getSettings) where
+
+import Specialize.Architecture
+import System.Console.GetOpt
+import Data.Maybe
+import Util.List
+
+data Flag = Help | Version | Interactive 
+          | Scroll FilePath 
+          | Spell FilePath 
+          | Rune FilePath 
+          | SpellArch Architecture 
+          deriving Show
+data Action = PrintHelp | PrintVersion | Compile Bool
+            deriving Show
+
+data Settings = Settings {
+  action     :: Action,
+  scrollDirs :: [FilePath],
+  runeDir    :: FilePath,
+  spellFile  :: FilePath,
+  outputArch :: Architecture,
+  runes      :: [FilePath]
+  }
+              deriving Show
+
+options = [
+  Option ['h'] ["help"] (NoArg Help) 
+  "prints usage information",
+  Option ['v'] ["version"] (NoArg Version) 
+  "prints Alpha's version information",
+  Option ['i'] ["interactive"] (NoArg Interactive)
+  "starts Alpha in interactive mode",
+  sep,
+  Option ['S'] ["scroll-dir"] (ReqArg Scroll "DIR") 
+  "adds DIR to the list of directories searched for scrolls",
+  Option ['R'] ["rune-dir"] (ReqArg Rune "DIR") 
+  "casts all runes in DIR (default '.')",
+  sep,
+  Option ['s'] ["spell-file"] (ReqArg Spell "FILE") 
+  "writes spell into FILE (default is '/dev/null')",
+  Option ['a'] ["architecture"] (ReqArg (SpellArch . str2arch) "ARCH") 
+  $ "specializes for ARCH instead of the local architecture (ARCH is one of "++foldr glue "" (tails archNames)++")"
+  ]
+  where str2arch s = fromMaybe (error $ "Invalid architecture name "++s) $ lookup s $ zip archNames architectures
+        archNames = map archName architectures
+        glue [a] _ = a
+        glue [a,_] t = a++" or "++t
+        glue (a:_) t = a++", "++t
+        sep = Option [] [] undefined "-----------------"
+helpMsg = usageInfo "Usage: Alpha <options> <files>" options
+
+defaultSettings mods = Settings (Compile False) ["."] "." "/dev/null" hostArch mods
+getSettings [] = Right $ (defaultSettings []) { action = PrintHelp }
+getSettings args = case getOpt Permute options args of
+  (opts,mods,[]) -> Right $ foldl handleOpt (defaultSettings mods) opts
+  (_,_,err) -> Left $ helpMsg ++ concatMap ("\n"++) err
+  where handleOpt s Help          = s { action = PrintHelp }
+        handleOpt s Version       = s { action = PrintVersion }
+        handleOpt s Interactive   = s { action = Compile True }
+        handleOpt s (Scroll d)    = s { scrollDirs = d : scrollDirs s }
+        handleOpt s (Spell f)     = s { spellFile = f }
+        handleOpt s (Rune f)      = s { runeDir = f }
+        handleOpt s (SpellArch a) = s { outputArch = a }
+
+
+-- Copyright (c) 2012, Coiffier Marc <marc.coiffier@gmail.com>
+-- All rights reserved.
+
+-- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+--     Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+--     Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
diff --git a/src/Alpha/writeElf.c b/src/Alpha/writeElf.c
new file mode 100644
--- /dev/null
+++ b/src/Alpha/writeElf.c
@@ -0,0 +1,71 @@
+#include <unistd.h>
+#include <libelf.h>
+#include "writeElf.h"
+
+void writeElf(int fd,byte* code,int codeSize,byte* data,int dataSize) {
+    unsigned int hSize = sizeof(Elf64_Ehdr) + 2*sizeof(Elf64_Phdr);
+    unsigned int entry = (1<<21) + hSize;
+
+    Elf64_Ehdr eh = {
+        .e_ident = { 
+            ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3,
+            ELFCLASS64, ELFDATA2LSB,
+            EV_CURRENT,
+            ELFOSABI_NONE, 0,
+            0
+        },
+        .e_type      = ET_EXEC,
+        .e_machine   = EM_X86_64,
+        .e_version   = EV_CURRENT,
+        .e_entry     = entry,
+        .e_phoff     = sizeof(Elf64_Ehdr),
+        .e_shoff     = 0,
+        .e_flags     = 0,
+        .e_ehsize    = sizeof(Elf64_Ehdr),
+        .e_phentsize = sizeof(Elf64_Phdr),
+        .e_phnum     = 2,
+        .e_shentsize = 0,
+        .e_shnum     = 0,
+        .e_shstrndx  = SHN_UNDEF
+    };
+    Elf64_Phdr pht[2] = {
+        {
+            .p_type   = PT_LOAD,
+            .p_offset = hSize,
+            .p_vaddr  = entry,
+            .p_paddr  = entry,
+            .p_filesz = codeSize,
+            .p_memsz  = codeSize,
+            .p_flags  = PF_R | PF_X,
+            .p_align  = 1<<21
+        },
+        {
+            .p_type   = PT_LOAD,
+            .p_offset = hSize+codeSize,
+            .p_vaddr  = entry+codeSize,
+            .p_paddr  = entry+codeSize,
+            .p_filesz = dataSize,
+            .p_memsz  = dataSize,
+            .p_flags  = PF_R | PF_W | PF_X,
+            .p_align  = 1
+        }
+    };
+    
+    write(fd,&eh,sizeof(eh));
+    write(fd,&pht,sizeof(pht));
+    write(fd,code,codeSize);
+    write(fd,data,dataSize);
+}
+
+/* 
+Copyright (c) 2012, Coiffier Marc <marc.coiffier@gmail.com>
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+    Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+    Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+*/
+
diff --git a/src/Compile.hs b/src/Compile.hs
new file mode 100644
--- /dev/null
+++ b/src/Compile.hs
@@ -0,0 +1,153 @@
+{-# LANGUAGE TupleSections, ParallelListComp #-}
+module Compile(compile) where
+
+import Debug.Trace
+
+import Compile.Utils
+
+import Compile.State as CS
+import IR
+import Util.Prelude
+import Util.ID
+import Util.Graph as G hiding (deleteEdge,deleteNode)
+import Util.State
+import Util.Monad
+import Util.List
+import Syntax
+import Data.Maybe
+import Data.Either
+
+compile env dest expr = runState st (defaultState env)
+  where st = do
+          (_,(start,_)) <- compile' dest expr 
+          simplify start >>= linearize
+    
+compile' dest (Symbol sym) = do
+  name <- getSymName sym
+  let def = SymVal Value sym
+      val = fromMaybe def (IntVal $< (readConstant =<< name))
+  fromMaybe (nullCodeVal val) $ do 
+    v <- dest
+    guard (not $ v `varEqVal` val) 
+    return $ do n <- createNode (Instr $ set v val)
+                return (def,singleCode n)
+compile' dest (Group expr@(Symbol id:args)) = do
+  gl <- getSymVal id
+  let compile = case gl of
+        Just (Axiom a) -> compileAxiom a
+        Just (Builtin b) -> compileBuiltin b
+        _ -> \d a -> compileCall d (Symbol id:a)
+  compile dest args
+compile' dest (Group args) = compileCall dest args
+
+compileBy op dest args = do 
+  (vars,code) <- unzip $< mapM (compile' Nothing) args
+  dest <- maybe newVar return dest
+  n <- createNode (Instr $ op dest vars)
+  sequence_ [createEdge TimeDep n' n | (_,l) <- code, n' <- l]
+  return (SymVal Value dest,(n:concatMap fst code,[n]))
+
+compileBuiltin = compileBy . Op
+compileCall = compileBuiltin BCall
+
+compileAxiom XAlter _ forms = do
+  let (vars,exprs) = partitionEithers $ zipWith ($) (cycle [Left,Right]) forms
+  codes <- sequence [compile' (Just v) e | Symbol v <- vars | e <- exprs] 
+  let (starts,ends) = unzip $ map snd codes
+  return (NullVal,(concat starts,concat ends))
+compileAxiom XBind _ args = doBind args
+  where 
+    doBind' bVars compile = compile *>>= \v -> do 
+      bnd <- bindFromSyntax bVars
+      n <- createNode (Instr $ IR.Bind bnd v)
+      return (NullVal,singleCode n)
+    doBind [bVars] = doBind' bVars $ nullCode
+    doBind [bVars,expr] = doBind' bVars $ compile' Nothing expr
+
+compileAxiom XDo dest [] = nullCode
+compileAxiom XDo dest forms = do 
+  let cs = reverse $ zipWith compile' (dest:repeat Nothing) (reverse forms)
+  foldr1 (*>>) cs
+compileAxiom XChoose dest (cond:forms) = do
+  start <- mkNoop ; end <- mkNoop
+  alts  <- replicateM (length forms) mkNoop
+  v <- maybe newVar return dest
+  let dest = Just v
+  
+  withTopInfo (start,alts,end,dest) $ do
+    return (NullVal,singleCode start) 
+      *>> compile' Nothing cond
+      *>>= \cv -> do
+        let code = zipWith compile' (repeat dest) forms
+            fun alt code = return (NullVal,singleCode alt) *>> code *>> makeBranch NullVal [end]
+        sequence_ $ zipWith fun alts code                   
+        makeBranch cv alts 
+
+  return (SymVal Value v,([start],[end]))
+
+compileAxiom XReturn dest [arg] = withInfo $ \(_,_,end,dest) -> compile' dest arg *>> makeBranch NullVal [end]
+            
+compileAxiom XRestart _ [] = withInfo $ \(start,_,_,_) -> makeBackBranch NullVal [start]
+compileAxiom XRestart _ [arg] = withInfo $ \(_,alts,_,_) -> 
+  compile' Nothing arg *>>= \v -> makeBackBranch v alts
+
+compileAxiom XVerb dest [Group (name:args),expr] = do
+  bindArgs <- mapM bindFromSyntax args
+  (sym,ret,code) <- compileBody name expr
+  modifyF envF $ exportSymVal sym (Verb bindArgs ret code)
+  compile' dest (Symbol sym)
+compileAxiom XVerb dest [Symbol s,Symbol a] = do
+  modifyF envF $ \env -> exportSymVal s (lookupSymVal a env) env
+  compile' dest (Symbol s)
+compileAxiom XNoun dest [name,init] = do
+  (sym,ret,code) <- compileBody name init
+  modifyF envF $ exportSymVal sym (Noun ret code)
+  compile' dest (Symbol sym)
+  
+compileAxiom XRune _ [Symbol s] = do
+  getSymName s >>= maybe (return()) (modify . (\n e -> e { imports = n:imports e }))
+  nullCode
+
+compileAxiom XID dest [Symbol s] = compileValue dest (SymVal SymID s)
+compileAxiom XAddr dest [Symbol s] = compileValue dest (SymVal Address s)
+compileAxiom XSize dest [Symbol s] = compileValue dest (SymVal Size s)
+
+compileAxiom a _ args = error $ "Couldn't compile axiom "++show a++" with args "++show args
+
+compileBody retBind body = do
+  ret <- newVar
+  bv <- bindFromSyntax retBind
+  code <- stateF envF $ \env -> let (c,st) = compile env (Just ret) body in (c,context st)
+  return (bindSym bv,bv { bindSym = ret },code)
+compileValue dest val = do
+  c <- singleCode $< case dest of
+    Just v -> createNode (Instr $ set v val)
+    Nothing -> mkNoop
+  return (val,c)
+
+bindFromSyntax (Symbol v) = return $ BindVar v (0,1) 0 []
+bindFromSyntax (Group (Symbol v:t)) = do
+  let fun (ns,l) (Symbol v) = getSymName v >>= \s -> 
+        maybe (fun' ns l (Symbol v)) (\n -> return (n:ns,l)) (readConstant =<< s)
+      fun (ns,l) e = fun' ns l e  
+      fun' ns l e = do
+        b <- bindFromSyntax e
+        return ([],(b,product ns):l)
+      
+  (pads,subs) <- foldM fun ([],[]) $ reverse t
+  let size = foldl (<+>) (pad,0) $ [(n*a,n*b) | (BindVar _ (a,b) _ _,n) <- subs]
+      pad = if null pads then 0 else product pads
+      (a,b) <+> (a',b') = (a+a',b+b')
+  return $ BindVar v size pad subs
+bindFromSyntax s = error $ "Invalid shape for bindVar : "++show s
+
+-- Copyright (c) 2012, Coiffier Marc <marc.coiffier@gmail.com>
+-- All rights reserved.
+
+-- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+--     Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+--     Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
diff --git a/src/Compile/State.hs b/src/Compile/State.hs
new file mode 100644
--- /dev/null
+++ b/src/Compile/State.hs
@@ -0,0 +1,123 @@
+module Compile.State(
+  module Environment, 
+  module Util.Graph,
+  CompileState(..),BranchType(..),EdgeData(..),NodeData(..),CaseInfo(..),
+  envF,depGraphF,infoStackF,
+  newVar,
+  pushInfo,popInfo,topInfo,withInfo,withTopInfo,
+  defaultState,
+  getSymName,getSymVal,
+  singleCode,
+  isBackEdge,
+  getNodeList,getContext,
+  createEdge,deleteEdge,
+  createNode,deleteNode,
+  nullCode,nullCodeVal,
+  makeTimeDep,makeBranch,makeBackBranch,mkNoop,
+  (*>>=),(*>>)
+  )
+  where
+
+import IR
+import Util.State
+import Util.Monad
+import Util.ID
+import Util.Graph hiding (deleteEdge,deleteNode,getContext,Context,empty)
+import Environment hiding(lookupSymName)
+
+import qualified Util.Graph as G
+import qualified Environment as E
+import qualified Data.Map as M
+
+data BranchType = Forward | Backward
+                deriving (Show,Eq)
+data EdgeData = BranchAlt BranchType Int
+              | TimeDep
+              deriving (Show,Eq)
+data NodeData = Instr Instruction
+              | BrPart IR.Value
+type CaseInfo = (Node,[Node],Node,Maybe ID)
+
+data CompileState = CS {
+  context   :: Context,
+  infoStack :: [CaseInfo],
+  imports   :: [String],
+  depGraph  :: Graph EdgeData NodeData
+  }
+                  deriving Show
+
+getSymName :: ID -> State CompileState (Maybe String)
+getNodeList :: State CompileState [Node]
+getContext  :: Node -> State CompileState (G.Context EdgeData NodeData)
+
+envF = (context,\e cs -> cs { context = e })
+depGraphF = (depGraph,(\g cs -> cs { depGraph = g }))
+infoStackF = (infoStack,(\l cs -> cs { infoStack = l }))
+
+defaultState env = CS env [] [] G.empty
+singleCode n = ([n],[n])
+isBackEdge (_,BranchAlt Backward _) = True
+isBackEdge _ = False
+
+getSymName = getsF envF . E.lookupSymName
+getSymVal  = getsF (envF <.> valsF) . M.lookup
+newVar     = stateF envF createSym
+
+pushInfo        = modifyF infoStackF . (:)
+popInfo         = stateF infoStackF (\(h:t) -> (h,t))
+topInfo         = getsF infoStackF head
+withTopInfo i x = pushInfo i >> x >>= \v -> popInfo >> return v
+withInfo f      = popInfo >>= \i -> f i >>= \ret -> pushInfo i >> return ret
+
+mkNoop        = createNode (Instr Noop)
+nullCode      = nullCodeVal NullVal
+nullCodeVal v = mkNoop >>= \n -> return (v,singleCode n)
+
+getNodeList  = getsF depGraphF nodeList
+getContext n = getsF depGraphF (G.getContext n)
+
+createNode x       = stateF depGraphF (G.insertNode x)
+deleteNode n       = modifyF depGraphF (G.deleteNode n)
+modifyNode n f     = modifyF depGraphF (G.modifyNode n f)
+createEdge x n1 n2 = modifyF depGraphF (G.insertEdge x n1 n2)
+deleteEdge n1 n2   = modifyF depGraphF (G.deleteEdge n1 n2)
+
+makeTimeDep a b = do
+  (v,(_in,_out)) <- a
+  case _out of
+    [] -> return (NullVal,(_in,_out))
+    _ -> do
+      (v,(_in',_out')) <- b v
+      sequence_ [createEdge TimeDep n n' | n <- _out,n' <- _in']
+      return (v,(_in,_out'))
+(*>>=) = makeTimeDep
+a *>> b = a *>>= const b
+
+infixr 1 *>>= 
+infixr 1 *>> 
+
+makeBranch = makeBranch' Forward
+makeBackBranch = makeBranch' Backward
+makeBranch' typ val alts = do
+  br <- createNode (BrPart val)
+  let makeAlt n = createEdge (BranchAlt typ n) br
+  case val of
+    IntVal i -> makeAlt 0 (if i+1<length alts then tail alts!!i else head alts)
+    _        -> sequence_ $ zipWith makeAlt [0..] alts          
+  return (NullVal,([br],[]))
+
+instance Show NodeData where
+  show (Instr i) = show i
+  show (BrPart v) = "case "++show v
+
+
+-- Copyright (c) 2012, Coiffier Marc <marc.coiffier@gmail.com>
+-- All rights reserved.
+
+-- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+--     Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+--     Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
diff --git a/src/Compile/Utils.hs b/src/Compile/Utils.hs
new file mode 100644
--- /dev/null
+++ b/src/Compile/Utils.hs
@@ -0,0 +1,134 @@
+{-# LANGUAGE TupleSections, ViewPatterns #-}
+
+module Compile.Utils where
+
+import Compile.State as CS
+import qualified Util.Graph as G
+import Util.Prelude
+import Util.Monad
+import Util.State
+import Util.List
+
+import qualified Data.Map as M
+import qualified Data.Set as S
+import Data.Maybe
+import IR
+import Syntax  
+
+import Debug.Trace
+
+simplify start = do
+  oldDep <- getF depGraphF ; purgeAll ; newDep <- getF depGraphF
+  return $ concatMap (newStart oldDep newDep) start
+  where 
+    purgeAll = do
+      mapM_ (purgeNode isNoop) =<< getNodeList         
+      mapM_ (purgeNode isEmptyBranch) =<< getNodeList
+    purgeNode p n = do
+      c <- getContext n              
+      if p c then remove (n,c) else return ()
+    isNoop c = case tag c of Instr Noop -> True ; _ -> False
+    isEmptyBranch c = case tag c of 
+      BrPart _ -> not (null o) && all p i && all p' o
+      _ -> False
+      where (i,o) = edges c 
+            p  (_,BranchAlt _ _) = True ; p  _ = False
+            p' (_,BranchAlt _ 0) = True ; p' _ = False
+    remove (n',c) = do
+      let 
+        (lies,loes) = edges c
+        least Forward Forward = Forward   
+        least _       _       = Backward  
+        mergeEdge (BranchAlt t x) (BranchAlt t' _) = BranchAlt (least t t') x
+        mergeEdge TimeDep         b                = b
+        mergeEdge e               t                = mergeEdge t e
+      sequence_ [createEdge (mergeEdge t t')  n  n'' | (n  ,t) <- lies, (n'',t') <- loes ]
+      sequence_ [deleteEdge                   n  n'  | (n  ,_) <- lies                   ]
+      sequence_ [deleteEdge                   n' n'' | (n'',_) <- loes                   ]
+      deleteNode n'
+    newStart old new = newStart
+      where 
+        newStart n = 
+          maybe (maybe [] (\c -> concat [newStart n | (n,_) <- outEdges c])
+                 (lookupContext n old)) 
+          (const [n])
+          (lookupContext n new)
+
+data ANode = ANode {
+  weight :: Int,
+  erNum :: Int,
+  instr :: NodeData
+  }
+           deriving Show
+linearize start = getsF depGraphF (linearize' start)
+linearize' start depG = instrs
+  where 
+    aG = annotate depG
+    getContext n = G.getContext n aG
+    withContext n = (n,getContext n)
+    
+    isBrPart (instr . tag . getContext -> BrPart _) = True
+    isBrPart _ = False
+    instrMap = M.fromList [(n,i) | (i,(n,_)) <- zip [0..] $ concat [map (n,) (getInstr n) | n <- concat blocks]]
+    instrs = concatMap (concatMap getInstr) blocks    
+
+    getInstr (getContext -> c) = case tag c of
+      ANode { instr = BrPart v } -> [Branch v $ map branch (classesBy (===) oes)]
+        where branch ns = minimum $ catMaybes [M.lookup n instrMap | (n,_) <- ns]
+              (_,e) === (_,e') = e==e'
+      ANode { instr = Instr i } -> i : if null oes then [ret] else []
+      where oes = outEdges c
+
+    selectHeads l = [n | (n,c) <- l, weight (tag c)==1]
+    startHeads = selectHeads $ map withContext $ nub start
+    heads = startHeads : deleteBy headsEq startHeads heads
+      where eq n1 n2 = if n1`elem`start then n2`elem`start else c'
+              where c' = n2 `elem` [n | (n,e') <- outEdges $ getContext prev, e==e']
+                    (prev,e) = fromMaybe (error $ "Couldn't find edge of "++show n1++" in graph "++show aG) $ find isBackEdge $ inEdges $ getContext n1
+            headsEq a b = sort a==sort b
+            heads = classesBy eq $ selectHeads $ nodeListFull aG
+    tails = map (nub . concatMap saturate) heads
+    saturate n = if null nexts then [n] else concatMap saturate nexts
+      where nexts = [n' | let c = getContext n                                
+                        , (n',c') <- map withContext $ nextNodes c
+                        , weight (tag c') > weight (tag c)]
+    
+    blocks = map blockFromTails tails
+    blockFromTails tails = evalState (concat $< mapM makeBlock tails) S.empty
+      where 
+        visited n = gets (S.member n) ; visit n = modify (S.insert n)
+    
+        makeBlock n = ifM (visited n) (return []) $ do 
+          prevs <- mapM makeBlock (getPrevs n)
+          visit n
+          return $ concat prevs ++ [n]
+        getPrevs n = map fst $ sortBy cmp $ filter p $ map withContext $ prevNodes context
+          where cmp (_,c) (_,c') = compare (erNum $ tag c') (erNum $ tag c)
+                p (_,c) = weight (tag c) < weight (tag context)
+                context = getContext n
+
+annotate depG = newdepG
+  where 
+    newdepG = mapNodes depCalc depG
+    depCalc (depCalc' -> (a,b)) i = ANode a b i
+    depCalc' (flip G.getContext depG -> c)
+      | any isBackEdge <||> null $ inEdges c = (1,1)
+      | otherwise = (1+maximum a, maximum $ zipWith (+) [0..] (reverse $ sort b))
+      where (a,b) = unzip [(weight t,erNum t) 
+                          | n' <- prevNodes c
+                          , let t = tag $ G.getContext n' newdepG]
+            
+    maximum = foldl max 0
+
+
+
+-- Copyright (c) 2012, Coiffier Marc <marc.coiffier@gmail.com>
+-- All rights reserved.
+
+-- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+--     Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+--     Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
diff --git a/src/Environment.hs b/src/Environment.hs
new file mode 100644
--- /dev/null
+++ b/src/Environment.hs
@@ -0,0 +1,22 @@
+module Environment(
+  module Environment.Axiom,
+  module Environment.Context,
+  module Environment.Foreign,
+  module Environment.Value) where
+
+import Environment.Axiom
+import Environment.Context
+import Environment.Foreign
+import Environment.Value
+
+
+-- Copyright (c) 2012, Coiffier Marc <marc.coiffier@gmail.com>
+-- All rights reserved.
+
+-- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+--     Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+--     Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
diff --git a/src/Environment/Axiom.hs b/src/Environment/Axiom.hs
new file mode 100644
--- /dev/null
+++ b/src/Environment/Axiom.hs
@@ -0,0 +1,19 @@
+module Environment.Axiom where
+
+data Axiom = XAlter | XBind 
+           | XReturn | XRestart | XChoose | XDo
+           | XRune | XVerb | XNoun
+           | XID | XAddr | XSize  
+           deriving Show
+
+
+-- Copyright (c) 2012, Coiffier Marc <marc.coiffier@gmail.com>
+-- All rights reserved.
+
+-- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+--     Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+--     Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
diff --git a/src/Environment/Context.hs b/src/Environment/Context.hs
new file mode 100644
--- /dev/null
+++ b/src/Environment/Context.hs
@@ -0,0 +1,126 @@
+module Environment.Context where
+
+import IR
+import Data.Maybe
+import Environment.Value as E
+import qualified Data.Map as M
+import qualified Data.Set as S
+import qualified Data.Bimap as BM
+import Control.Monad.State
+import Util.State
+import Util.ID
+import Util.List
+import Util.Monad
+import Util.Prelude
+import Translate
+
+data Context = CE {
+  maxID    :: ID,
+  symMap   :: BM.Bimap String ID,
+  aliasMap :: M.Map ID ID,
+  equivMap :: M.Map ID ID,
+  modMap   :: BM.Bimap String IDRange,
+  valMap   :: M.Map ID E.Value,
+  exports  :: S.Set ID,
+  load     :: [Instruction]
+  }
+
+showTable name showLine contents = (name++":"):map ("  "++) (concatMap showLine contents)
+instance Show Context where
+  show e = intercalate "\n" $ showTable "Environment" id [
+    ["Max ID: "++show (maxID e)],
+    showTable "Symbols" (\(s,i) -> [s++" -> "++show i]) $ BM.toList (symMap e),
+    showTable "Aliases" (\(i,i') -> [show i++" -> "++show i']) $ M.toList (aliasMap e),
+    showTable "Equivs" (\(i,i') -> [show i++" -> "++show i']) $ M.toList (equivMap e),
+    showTable "Modules" (\(s,IDRange r) -> [s++" -> "++show r]) $ BM.toList (modMap e),
+    showTable "Values" (\(i,v) -> [show i++" -> "++show v]) $ M.toList (valMap e),
+    ["Exports: "++show (exports e)],
+    ["Load code: "++show (load e)]]
+
+empty = CE (toEnum 0) BM.empty M.empty M.empty BM.empty M.empty S.empty []
+
+symsF = (symMap,\s ce -> ce { symMap = s })
+valsF = (valMap,\v ce -> ce { valMap = v })
+
+createSym e@(CE { maxID = m }) = (m,e { maxID = succ m })
+setSymVal id v e = e { valMap = M.insert id v (valMap e) }
+lookupSymName id e = BM.lookupR id (symMap e)
+lookupSymVal id e = fromMaybe NoValue $ M.lookup id (valMap e) 
+lookupSymMod id e = BM.lookupR (singleRange id) (modMap e) 
+addExport id e = e { exports = S.insert id (exports e) }
+getImports e = map fst $ BM.toList $ modMap e
+isImport im e = BM.member im (modMap e)
+exportSymVal id v = setSymVal id v . addExport id
+
+internSym s e = runState (st $ BM.lookup s (symMap e)) e 
+  where st (Just id) = return id
+        st _ = do
+          i <- state createSym 
+          modifyF symsF (BM.insert s i)  
+          return i
+
+envCast t e = runState (traverseM (state . intern) t) e
+  where intern "?" = createSym
+        intern str = internSym str
+              
+instance Num ID where
+  ID a + ID b = ID (a+b)
+  ID a - ID b = ID (a-b)
+  (*) = undefined
+  negate = undefined
+  abs = undefined
+  signum = undefined
+  fromInteger = undefined
+  
+merge e (mod,e') = if isImport mod e then e else ret
+  where ret = execState st e 
+        syms' = symMap e' ; mods' = modMap e' ; mi' = maxID e'
+        st = do  
+          mapM (state . internSym) (BM.keys syms')
+          mi <- gets maxID ; syms <- gets symMap
+          let aliases = [(i'+mi,fromJust $ BM.lookup s' syms) 
+                        | (s',i') <- BM.toList syms']
+          modify $ \e -> e {
+            maxID = mi+mi',
+            aliasMap = aliasMap e `M.union` M.fromList aliases,
+            equivMap = equivMap e `M.union` M.fromList (map swap aliases)
+            }
+          CE { aliasMap = al , modMap = mods } <- get
+          let tr s = fromMaybe (tr' s) $ M.lookup (tr' s) al
+              tr' s' = fromMaybe (s' + mi) $ do
+                m <- lookupSymMod s' e'
+                IDRange (r,_) <- BM.lookup m mods
+                IDRange (r',_) <- BM.lookup m mods'
+                return $ s'-r'+r
+              newVals = M.mapKeys tr $ M.map (translate tr) $ valMap e'
+          modify $ \e -> e {
+            modMap = BM.insert mod (IDRange (mi,mi+mi')) (modMap e),
+            valMap = M.unionWith (\_ a -> a) (valMap e) newVals,
+            exports = S.difference (exports e) (M.keysSet newVals) 
+            }
+          
+exportContext e = e {
+  symMap = BM.filter exportNameP (symMap e),
+  valMap = vals',
+  aliasMap = M.empty,
+  equivMap = M.empty,
+  exports = S.empty
+  }
+  where set2Map s = M.fromAscList (zip (S.toAscList s) (repeat undefined))
+        ex = exports e ; eqs = equivMap e
+        vals' = M.map (translate tr) $ M.intersection (valMap e) (set2Map ex)
+          where tr s = fromMaybe s $ M.lookup s eqs
+        refs = S.fromList $ concatMap references $ M.elems vals'
+        exportNameP _ s = (S.member s ex || S.member s refs)
+                          && not (M.member s eqs)
+
+-- Copyright (c) 2012, Coiffier Marc <marc.coiffier@gmail.com>
+-- All rights reserved.
+
+-- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+--     Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+--     Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
diff --git a/src/Environment/Foreign.hs b/src/Environment/Foreign.hs
new file mode 100644
--- /dev/null
+++ b/src/Environment/Foreign.hs
@@ -0,0 +1,62 @@
+module Environment.Foreign( 
+  getEnv,setEnv,withEnv,stateEnv,
+  defaultEnv,
+  doTransform
+  )where
+
+import System.IO.Unsafe (unsafePerformIO)
+import Data.IORef
+import Environment.Axiom
+import Environment.Value
+import Environment.Context
+import IR
+import Util.ID
+import Syntax
+import Control.Monad.State
+
+defaultEnv = fromList $ [
+  ("alter"  ,Axiom XAlter),
+  ("bind"   ,Axiom XBind),
+  
+  ("choose" ,Axiom XChoose),
+  ("<-"     ,Axiom XRestart),
+  ("->"     ,Axiom XReturn),
+  ("do"     ,Axiom XDo),
+  
+  ("rune"   ,Axiom XRune),
+  ("verb"   ,Axiom XVerb),
+  ("noun"   ,Axiom XNoun),        
+            
+  ("id"     ,Axiom XID),
+  ("@"      ,Axiom XAddr),
+  ("#"      ,Axiom XSize)]
+  ++ [(n,Builtin b) | (b,n) <- bNames]
+  where fromList l = execState (mapM_ st l) empty
+        st (s,v) = state (internSym s) >>= \i -> modify (setSymVal i v)
+
+context :: IORef Context
+context = unsafePerformIO $ newIORef defaultEnv
+
+getEnv = readIORef context
+setEnv = writeIORef context
+withEnv e a = do
+  e' <- getEnv
+  setEnv e
+  ret <- a
+  setEnv e'
+  return ret
+stateEnv st = getEnv >>= \e -> let (e',s') = runState st e in setEnv s' >> return e'
+doTransform syn = return syn
+
+
+
+-- Copyright (c) 2012, Coiffier Marc <marc.coiffier@gmail.com>
+-- All rights reserved.
+
+-- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+--     Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+--     Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
diff --git a/src/Environment/Value.hs b/src/Environment/Value.hs
new file mode 100644
--- /dev/null
+++ b/src/Environment/Value.hs
@@ -0,0 +1,39 @@
+module Environment.Value where
+
+import IR.Instruction
+import IR.Builtin
+import IR.Value
+import Environment.Axiom
+import Util.ID
+import qualified Data.Set as S
+import Data.Tree
+
+data Value = Axiom Axiom
+           | Builtin Builtin
+           | Verb [BindVar] BindVar [Instruction] 
+           | Noun BindVar [Instruction]
+           | NoValue
+           deriving Show
+
+references val = case val of
+  Verb args ret code -> refs code (bindSyms ret++concatMap bindSyms args)
+  Noun ret code -> refs code (bindSyms ret)
+  _ -> []
+  where refs code local = traverse (S.fromList local) (instrTree 0 nexts)
+          where (_,instr,nexts,_) = navigate code
+                traverse local (Node i subs) = valRefs (instrVals (instr i)) ++ concatMap (traverse newLocal) subs
+                  where valRefs vals = [v | SymVal t v <- vals, t==SymID || not (S.member v local)]
+                        newLocal = S.union local (S.fromList (instrVars (instr i)))
+                  
+
+
+-- Copyright (c) 2012, Coiffier Marc <marc.coiffier@gmail.com>
+-- All rights reserved.
+
+-- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+--     Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+--     Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
diff --git a/src/IR.hs b/src/IR.hs
new file mode 100644
--- /dev/null
+++ b/src/IR.hs
@@ -0,0 +1,24 @@
+module IR(
+  module IR.Builtin,
+  module IR.Instruction,
+  module IR.Value) where
+
+import IR.Builtin
+import IR.Instruction
+import IR.Value
+
+
+
+
+
+
+-- Copyright (c) 2012, Coiffier Marc <marc.coiffier@gmail.com>
+-- All rights reserved.
+
+-- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+--     Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+--     Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
diff --git a/src/IR/Builtin.hs b/src/IR/Builtin.hs
new file mode 100644
--- /dev/null
+++ b/src/IR/Builtin.hs
@@ -0,0 +1,25 @@
+module IR.Builtin where
+
+data Builtin = BAdd | BMul | BSub | BDiv | BMod 
+             | BAnd | BOr | BXor | BNot
+             | BLowerEq | BLowerThan | BGreaterEq | BGreaterThan 
+             | BEqual | BNotEqual
+             | BCall
+             | BSet
+             deriving (Show,Eq)
+
+bNames = [(BAdd,"+"),(BMul,"*"),(BSub,"-"),(BDiv,"/"),(BMod,"%"),
+          (BLowerThan,"<"),(BGreaterThan,">"),(BLowerEq,"<="),(BGreaterEq,">="),
+          (BEqual,"="),(BNotEqual,"<>"),
+          (BAnd,"&"),(BOr,"|"),(BXor,"x|"),(BNot,"not")]
+
+-- Copyright (c) 2012, Coiffier Marc <marc.coiffier@gmail.com>
+-- All rights reserved.
+
+-- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+--     Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+--     Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
diff --git a/src/IR/Instruction.hs b/src/IR/Instruction.hs
new file mode 100644
--- /dev/null
+++ b/src/IR/Instruction.hs
@@ -0,0 +1,93 @@
+{-# LANGUAGE ViewPatterns #-}
+module IR.Instruction where
+
+import Control.Monad.State
+import Data.List
+import Data.Maybe
+import Data.Array
+import Data.Tree
+import qualified Data.Set as S
+import IR.Builtin
+import IR.Value
+import Util.ID
+
+type Addr = Int
+data BindVar = BindVar { 
+  bindSym  :: ID, 
+  bindSize :: (Int,Int), 
+  bindPad  :: Int, 
+  bindSubs :: [(BindVar,Int)]
+  }
+data Instruction = Op Builtin ID [Value]
+                 | Branch Value [Addr]
+                 | Bind BindVar Value
+                 | Noop
+                                      
+isNoop Noop = True
+isNoop _ = False
+isBranch (Branch _ _) = True
+isBranch _ = False
+
+bindSyms bv = bindSym bv : concatMap bindSyms (map fst $ bindSubs bv)
+instrVals (Op _ _ vs) = vs
+instrVals (Bind _ v) = [v]
+instrVals (Branch v _) = [v]
+instrVals _ = []
+instrVars (Op _ v _) = [v]
+instrVars (Bind v _) = bindSyms v
+instrVars _ = []
+
+set v val = Op BSet v [val]
+call v f args = Op BCall v (f:args)
+ret = Branch NullVal []
+
+concatCode c1 [] = c1
+concatCode c1 c2 = map (f g1) c1 ++ map (f g2) c2
+  where f g (Branch v as) = Branch v (g as)
+        f _ i = i
+        g1 as = if null as then [l] else as
+        g2 as = map (l+) as
+        l = length c1
+
+navigate code = (bs,instr,nexts,prevs)
+  where bs@(bMin,bMax) = (0,length code-1)
+        instr n = listArray bs code!n
+        nexts (instr -> Branch _ l) = l
+        nexts n = [n+1]
+        prevs n = accumArray (flip (:)) [] bs [(n,i) | i <- [bMin..bMax], n <- nexts i] ! n
+
+instrTree seed nexts = evalState (unfoldTreeM unfold seed) S.empty
+  where unfold seed = do modify (S.insert seed) ; s <- get 
+                         return (seed,[n | n <- nexts seed, not $ S.member n s])
+            
+instance Show Instruction where  
+  show (Op BCall d (f:args)) = show d ++ " = " ++ show f ++ "(" ++ intercalate "," (map show args) ++ ")"
+  show (Op BSet v [val]) = show v ++ " = " ++ show val
+  show (Op o d vs) = show d ++ " = " ++ intercalate (" "++opStr++" ") (map show vs)
+    where opStr = fromMaybe (error $ "unknown pervasive "++show o) $ lookup o bNames
+  show (Branch _ []) = "return"
+  show (Branch _ [off]) = "goto " ++ show off
+  show (Branch v off) = "case " ++ show v ++ " " ++ show off 
+  show (Bind vars x) = "bind "++show vars++" "++show x
+  show Noop = "noop"
+instance Show BindVar where
+  show (BindVar v (n,nr) pad subs) = case (pad,subs) of
+    (0,[]) -> head varStr
+    _ -> "["++intercalate " " (varStr++padStr++subsStr)++"]"
+    where varStr = [show v++":"++if sizeStr=="" then "0" else sizeStr]
+          sizeStr = intercalate "+" (size++regSize)
+          size = if n==0 then [] else [show n]
+          regSize = if nr==0 then [] else [show nr++"r"]
+          padStr = if pad==0 then [] else [show pad]
+          subsStr = map show subs
+
+-- Copyright (c) 2012, Coiffier Marc <marc.coiffier@gmail.com>
+-- All rights reserved.
+
+-- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+--     Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+--     Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
diff --git a/src/IR/Value.hs b/src/IR/Value.hs
new file mode 100644
--- /dev/null
+++ b/src/IR/Value.hs
@@ -0,0 +1,47 @@
+module IR.Value where
+
+import Control.Monad
+import Control.Monad.Instances
+import Data.Char
+import Data.List
+import Data.Maybe
+import Util.Prelude
+import Util.ID
+
+data ValType = Value | Address | Size | SymID
+             deriving Eq
+data Value = SymVal ValType ID
+           | IntVal Int
+           | NullVal
+
+varEqVal n (SymVal Value n') = n==n'
+varEqVal _ _ = False
+
+readConstant s = let (a,b) = break (=='#') (filter (/='-') s) in eitherToMaybe $
+  parseInt 10 a >>= \r -> if null b then return r else parseInt r (tail b)
+
+parseInt r s 
+  | all isHexDigit s =
+    case find (>=r) digs of 
+      Just d -> Left $ "digit '"++[intToDigit d]++"' too great for base "++show r++" (in numeral constant '"++s++"')" 
+      Nothing -> Right $ sum $ zipWith (*) (reverse digs) $ iterate (*r) 1
+  | otherwise = Left $ "all digits must be alphanumeric characters (in constant '"++s++"')"
+  where digs = map digitToInt s
+        
+instance Show Value where
+  show (SymVal t v)   = prefix++show v
+    where prefix = fromJust $ lookup t [(Value,""),(Address,"@"),(Size,"#"),(SymID,"$")]
+  show (IntVal n)   = show n
+  show NullVal      = "(null)"
+
+
+-- Copyright (c) 2012, Coiffier Marc <marc.coiffier@gmail.com>
+-- All rights reserved.
+
+-- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+--     Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+--     Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
diff --git a/src/Serialize.hs b/src/Serialize.hs
new file mode 100644
--- /dev/null
+++ b/src/Serialize.hs
@@ -0,0 +1,49 @@
+{-# LANGUAGE DeriveGeneric, StandaloneDeriving #-}
+
+module Serialize where
+
+import GHC.Generics
+import Data.Serialize
+
+import Util.Monad
+import Data.Bimap as BM
+import Util.ID
+import IR
+import Environment as E
+
+deriving instance Generic ValType
+deriving instance Generic IR.Value
+deriving instance Generic Instruction
+deriving instance Generic BindVar
+deriving instance Generic Builtin
+deriving instance Generic E.Value
+deriving instance Generic Axiom
+deriving instance Generic ID
+deriving instance Generic IDRange
+deriving instance Generic Context
+
+instance Serialize ValType
+instance Serialize IR.Value
+instance Serialize Instruction
+instance Serialize BindVar
+instance Serialize Builtin
+instance Serialize E.Value
+instance Serialize Axiom
+instance Serialize ID
+instance Serialize IDRange
+instance (Ord a,Ord b,Serialize a,Serialize b) => Serialize (Bimap a b) where
+  get = BM.fromList $< get 
+  put = put . BM.toList
+  
+instance Serialize Context
+
+-- Copyright (c) 2012, Coiffier Marc <marc.coiffier@gmail.com>
+-- All rights reserved.
+
+-- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+--     Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+--     Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
diff --git a/src/Specialize.hs b/src/Specialize.hs
new file mode 100644
--- /dev/null
+++ b/src/Specialize.hs
@@ -0,0 +1,77 @@
+{-# LANGUAGE TupleSections, ViewPatterns #-}
+module Specialize where
+
+import Specialize.Types
+import Specialize.Architecture
+import Util.Monad
+import Util.State
+import Util.List
+import qualified Data.Map as M
+import qualified Data.Set as S
+import Data.Either
+import Data.Array
+import Data.Maybe
+import Data.Tree
+
+import Environment.Value
+
+import IR
+
+addrF = (addresses,\s p -> p { addresses = s })
+bindF = (bindings,\s p -> p { bindings = s })
+regsF = (registers,\r p -> p { registers = r })
+stackF = (stack,\s p -> p { stack = s })
+
+getAddress id = do
+  p <- getp
+  case M.lookup id (addresses p) of
+    Nothing -> runp $ do
+      a <- stateF stackF (stackAlloc (regSize $ architecture $ p))
+      modifyF addrF (M.insert id (Nothing,a))
+      return a
+    Just (_,a) -> return a
+
+shrinkStack s = concatMap f $ tails $ groupBy (\(f1,_) (f2,_) -> not (f1 || f2)) s
+  where f [((True,_):_)] = []
+        f (l@((True,_):_):_) = if total == 0 then [] else [(True,total)]
+          where total = sum [s | (_,s) <- l]
+        f ([l]:_) = [l]
+stackAlloc n s = (a,shrinkStack s')
+  where (h,l) = break (\(free,size) -> free && size>=n) s 
+        a = sum $ map snd h
+        (size,t) = case l of
+          [] -> (n,[])
+          ((_,s):t) -> (s,t)
+        s' = h++[(False,n),(True,size-n)]++t
+stackFree n s = shrinkStack [(i==n || fr,sz) | (i,(fr,sz)) <- zip (scanl (+) 0 (map snd s)) s]
+
+code = [
+  Op BSet r [val b],
+  Op BSet b [val a],
+  Op BNotEqual c [val r,IntVal 0],
+  Branch (val c) [6,4],
+  Op BSet x [val b],
+  Branch NullVal [],
+  Op BSet a [val b],
+  Op BSet b [val r],
+  Op BMod r [val a,val b],
+  Branch NullVal [2]  
+  ]
+  where [a,b,r,c,x] = map var [0..4]
+        var = ID
+        val v = SymVal Value v
+
+specialize arch code = fmap (\n -> (n,instr n)) (instrTree 0 nexts)
+  where (_,instr,nexts,_) = navigate code            
+        
+
+-- Copyright (c) 2012, Coiffier Marc <marc.coiffier@gmail.com>
+-- All rights reserved.
+
+-- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+--     Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+--     Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
diff --git a/src/Specialize/Architecture.hs b/src/Specialize/Architecture.hs
new file mode 100644
--- /dev/null
+++ b/src/Specialize/Architecture.hs
@@ -0,0 +1,45 @@
+module Specialize.Architecture(Architecture(..),arch_x86,arch_x86_64,arch_arm,hostArch,architectures) where
+
+import Specialize.Types
+import IR.Instruction
+import Util.TimeLine
+import Data.Ord
+import Data.Word
+import Data.Set as S
+
+instance Eq Architecture where
+  a == a' = archName a == archName a'
+instance Show Architecture where
+  show a = "#<Arch:"++archName a++">"
+
+architectures = [hostArch,arch_x86,arch_x86_64,arch_arm]
+arch_x86 = Arch {
+  archName = "x86",
+  registers = S.fromList [0..7],
+  regSize = 4,
+  compileInstr = undefined
+  }
+arch_x86_64 = Arch { 
+  archName = "x86_64",
+  registers = S.fromList [0..15],
+  regSize = 8,
+  compileInstr = undefined
+  }
+arch_arm = Arch {
+  archName = "arm",
+  registers = S.fromList [0..15],
+  regSize = 4,
+  compileInstr = undefined
+  }
+hostArch = arch_x86_64 { archName = "host" }
+
+-- Copyright (c) 2012, Coiffier Marc <marc.coiffier@gmail.com>
+-- All rights reserved.
+
+-- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+--     Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+--     Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
diff --git a/src/Specialize/Types.hs b/src/Specialize/Types.hs
new file mode 100644
--- /dev/null
+++ b/src/Specialize/Types.hs
@@ -0,0 +1,36 @@
+module Specialize.Types(
+  module Data.Word, module Util.TimeLine,
+  module IR.Instruction, module Util.ID,
+  Register(..),Address(..), 
+  Architecture(..), 
+  Past(..),Future(..),
+  Allocate(..)) where
+
+import Data.Word
+import Util.TimeLine
+import IR.Instruction
+import Util.ID
+import Data.Map
+import Data.Set
+
+type Register = Int
+type Address = (Maybe ID,Int)
+data Architecture = Arch {
+  archName :: String,
+  registers :: Set Register,
+  regSize :: Int,
+  compileInstr :: Instruction -> Allocate [Word8]
+  }
+data Past = Past { 
+  architecture :: Architecture,
+  isActive :: Bool,
+
+  addresses :: Map ID Address,
+  bindings :: Map ID Register,
+  clobber :: Map ID [ID],
+  stack :: [(Bool,Int)]
+  }
+data Future = Future {
+  fregs :: Map ID Register
+  }
+type Allocate = TimeLine Past Future
diff --git a/src/Syntax.hs b/src/Syntax.hs
new file mode 100644
--- /dev/null
+++ b/src/Syntax.hs
@@ -0,0 +1,38 @@
+module Syntax where
+
+import Prelude hiding (foldl)
+import Data.List (intercalate)
+import Data.Foldable
+import Data.Traversable
+import Control.Applicative
+
+data Syntax a = Group [Syntax a]
+              | Symbol a
+              deriving Eq
+               
+instance Functor Syntax where
+  fmap f (Symbol s) = Symbol $ f s
+  fmap f (Group l) = Group $ map (fmap f) l
+instance Foldable Syntax where
+  foldl f e (Symbol s) = f e s
+  foldl f e (Group l) = foldl (foldl f) e l
+instance Traversable Syntax where
+  traverse f (Symbol s) = Symbol <$> f s
+  traverse f (Group l) = Group <$> traverse (traverse f) l 
+
+instance Show a => Show (Syntax a) where
+  show (Symbol s) = show s
+  show (Group l) = "[" ++ intercalate " " (map show l) ++ "]"
+
+
+
+-- Copyright (c) 2012, Coiffier Marc <marc.coiffier@gmail.com>
+-- All rights reserved.
+
+-- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+--     Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+--     Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
diff --git a/src/Syntax/Parse.hs b/src/Syntax/Parse.hs
new file mode 100644
--- /dev/null
+++ b/src/Syntax/Parse.hs
@@ -0,0 +1,75 @@
+module Syntax.Parse (parseAlpha) where
+
+import Syntax
+import Text.ParserCombinators.Parsec hiding (spaces)
+import Util.Monad  
+import Data.Maybe
+
+parseAlpha file s = lazyMany axiom file s
+
+-- Utilities
+lazyMany p file contents = lm state0
+      where
+        Right state0 = parse getParserState file contents
+
+        lm state = case parse p' "" "" of
+          Left err -> error (show err)
+          Right x -> x
+          where 
+            p' = do
+              setParserState state
+              choice [ 
+                try (oWhite >> eof >> return []),
+                liftM2 (:) (p >>= \p -> optional (oneOf ",;") >> return p) $ lm $< getParserState]
+wrParen e@(_:_:_) = mkNode e 
+wrParen e = concat e 
+mkNode = return . Group . concat
+free :: Parser a -> Parser a
+free e = try $ between oWhite oWhite e
+
+-- Productions
+axiom = free boundExpr
+    
+atom = (:[]) $< symbol  <|> paren
+ 
+wrap beg g end = between (string beg) (string end) g
+paren = wrap "(" (inParen wrParen) ")"
+        <|> wrap "[" (inParen mkNode) "]"
+        <|> wrap "{" (inParen concat) "}"
+inParen wr = wr $< (oWhite >> looseExpr`endBy`oWhite)
+
+looseExpr = (<?>"loose expression") $ concat $< (boundExpr `sepBy1` free (oneOf ",;"))
+boundExpr = (<?>"bound expression") $ wrParen $< (infExpr `sepBy1` free (char '_'))
+infExpr = (<?>"infix expression") $ foldl fun $< tightExpr >$< many tl 
+  where fun e (Left f) = [Group $ f++e]
+        fun e (Right (o,e')) = [Group $ o++e++e']
+        opExpr = (<?>"operator expression") $ concat $< many1 atom
+        tl =  (free (char '.') >> Left  $< opExpr)
+          <|> (free (char ':') >> Right $< ((,) $< opExpr >$< (oWhite >> tightExpr)))
+tightExpr = (<?>"close expression") $ wrParen $< many1 atom
+    
+symbol =  Symbol $< ((string <?> "string") <|> (symbol <?> "symbol"))
+  where string = do 
+          sep <- (char '\'' >> anyChar) <|> char '"'
+          str <- many (quoted $ satisfy (/=sep))
+          char sep
+          return $ '\'':sep:str
+        symbol = many1 $ quoted $ noneOf " \t\n()[]{},;.:_"
+        quoted p = (char '\\' >> esc $< anyChar) <|> p
+        esc c = fromMaybe c $ lookup c [('n','\n'),('t','\t')]
+        
+white = skipMany1 ((comment <|> spaces) <?> "whitespace")
+  where spaces = skipMany1 $ space
+        comment = (char '~' >> optional spaces >> void (many1 atom)) <?> "comment"
+oWhite = optional $ white
+
+-- Copyright (c) 2012, Coiffier Marc <marc.coiffier@gmail.com>
+-- All rights reserved.
+
+-- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+--     Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+--     Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
diff --git a/src/Translate.hs b/src/Translate.hs
new file mode 100644
--- /dev/null
+++ b/src/Translate.hs
@@ -0,0 +1,42 @@
+module Translate where
+
+import Util.Monad
+import Data.Bimap as BM
+import Util.ID
+import IR
+import Environment.Value as E
+
+class Translate t where
+  translate :: (ID -> ID) -> t -> t
+
+instance Translate ID where
+  translate = ($)
+instance Translate IDRange where
+  translate t (IDRange (a,b)) = IDRange (t a,t b)
+instance Translate e => Translate [e] where 
+  translate tr l = map (translate tr) l
+instance Translate E.Value where 
+  translate tr (Verb args ret code) = Verb (translate tr args) (translate tr ret) (translate tr code)
+  translate tr (Noun ret init) = Noun (translate tr ret) (translate tr init)
+  translate tr x = x
+instance Translate Instruction where
+  translate tr (Op b v vs) = Op b (translate tr v) (translate tr vs)
+  translate tr (Branch v as) = Branch (translate tr v) as
+  translate tr (Bind bv v) = Bind (translate tr bv) (translate tr v)
+  translate tr Noop = Noop
+instance Translate IR.Value where
+  translate tr (SymVal t id) = SymVal t (translate tr id)
+  translate tr v = v
+instance Translate BindVar where
+  translate tr (BindVar id s pad subs) = BindVar (translate tr id) s pad [(translate tr bv,s) | (bv,s) <- subs]
+
+-- Copyright (c) 2012, Coiffier Marc <marc.coiffier@gmail.com>
+-- All rights reserved.
+
+-- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+--     Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+--     Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
diff --git a/src/Util/Graph.hs b/src/Util/Graph.hs
new file mode 100644
--- /dev/null
+++ b/src/Util/Graph.hs
@@ -0,0 +1,89 @@
+module Util.Graph( 
+  Context,Graph,Node(..),
+  
+  empty,
+  lookupContext,getContext,
+  insertNode,deleteNode,modifyNode,
+  insertEdge,deleteEdge,
+  
+  modifyInEdges,modifyOutEdges,
+  tag,inEdges,outEdges,edges,
+  nextNodes,prevNodes,
+  
+  nodeList,nodeListFull,
+  
+  mapNodes
+  )
+  where
+
+import qualified Data.Map as M
+import Data.List
+import Data.Maybe
+
+type Node = Int
+data Context e n = Context { 
+  nodeTag :: n, 
+  nodeInEdges :: M.Map Node e, 
+  nodeOutEdges :: M.Map Node e
+  } deriving Show
+data Graph e n = Graph {
+  nbNodes :: Int,
+  graphNodes :: M.Map Node (Context e n)
+  }
+                 
+empty = Graph 0 M.empty
+
+lookupContext n (Graph _ nds) = M.lookup n nds
+getContext n g = fromMaybe (error $ "No node "++show n++" in graph "++show g) $ lookupContext n g
+
+insertNode x (Graph n nds)       = (n,Graph (n+1) (M.insert n (Context x M.empty M.empty) nds))
+deleteNode nd (Graph n nds)      = Graph n (M.delete nd nds)
+modifyNode nd f (Graph n nds)    = Graph n (M.adjust (\(Context t i o) -> Context (f t) i o) nd nds)
+
+insertEdge x n1 n2 (Graph n nds) = Graph n (M.adjust (modifyInEdges (M.insert n1 x)) n2 $
+                                            M.adjust (modifyOutEdges (M.insert n2 x)) n1 nds) 
+deleteEdge n1 n2 (Graph n nds)   = Graph n (M.adjust (modifyInEdges (M.delete n1)) n2 $
+                                            M.adjust (modifyOutEdges (M.delete n2)) n1 nds)
+
+modifyInEdges f c = c { nodeInEdges = f $ nodeInEdges c }
+modifyOutEdges f c = c { nodeOutEdges = f $ nodeOutEdges c }
+
+tag      = nodeTag
+inEdges  = M.toList . nodeInEdges
+outEdges = M.toList . nodeOutEdges
+edges c  = (inEdges c,outEdges c)
+
+nextNodes = map fst . outEdges
+prevNodes = map fst . inEdges
+
+nodeList = map fst . nodeListFull
+nodeListFull = M.toList . graphNodes
+
+mapNodes f (Graph n nds) = Graph n (M.mapWithKey (\n (Context t ie oe) -> Context (f n t) ie oe) nds)
+
+instance Functor (Graph e) where
+  fmap f = mapNodes (const f)
+instance (Show n,Show e) => Show (Graph e n) where
+  show (Graph _ nds) = intercalate "\n" showNodes
+    where showNodes = map showNode $ M.toList nds
+          showNode (n,Context nd ie oe) = 
+            show n++": "++show nd++"\n  "++
+            intercalate "\n  " (map showNEdge (M.toList oe)
+                                ++ map showREdge (M.toList ie))
+              where showNEdge (n',e) = "--"++show e++"--> "++show n'
+                    showREdge (n',e) = "<--"++show e++"-- "++show n'
+  
+            
+  
+
+
+-- Copyright (c) 2012, Coiffier Marc <marc.coiffier@gmail.com>
+-- All rights reserved.
+
+-- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+--     Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+--     Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
diff --git a/src/Util/ID.hs b/src/Util/ID.hs
new file mode 100644
--- /dev/null
+++ b/src/Util/ID.hs
@@ -0,0 +1,35 @@
+module Util.ID where
+
+newtype ID = ID Int
+           deriving (Ord,Eq)
+newtype IDRange = IDRange (ID,ID)
+                deriving Show
+                         
+singleRange i = IDRange (i,i)
+
+instance Eq IDRange where
+  a == b = compare a b == EQ
+instance Ord IDRange where
+  compare (IDRange (a,b)) (IDRange (a',b')) =  
+    if b<=a' then LT
+    else if b'<=a then GT
+         else EQ
+
+instance Enum ID where
+  toEnum = ID
+  fromEnum (ID i) = i
+instance Show ID where
+  show (ID i) = "x"++show i
+
+
+
+-- Copyright (c) 2012, Coiffier Marc <marc.coiffier@gmail.com>
+-- All rights reserved.
+
+-- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+--     Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+--     Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
diff --git a/src/Util/List.hs b/src/Util/List.hs
new file mode 100644
--- /dev/null
+++ b/src/Util/List.hs
@@ -0,0 +1,21 @@
+module Util.List(module Data.List,classesBy,nubOrd) where
+
+import Data.List
+
+nubOrd :: Ord a => [a] -> [a]
+nubOrd = map head . group . sort
+
+classesBy :: (a -> a -> Bool) -> [a] -> [[a]]
+classesBy (==) []    = []
+classesBy (==) (e:l) = let (x,t) = partition (e==) l in (e:x):classesBy (==) t
+
+-- Copyright (c) 2012, Coiffier Marc <marc.coiffier@gmail.com>
+-- All rights reserved.
+
+-- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+--     Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+--     Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
diff --git a/src/Util/Monad.hs b/src/Util/Monad.hs
new file mode 100644
--- /dev/null
+++ b/src/Util/Monad.hs
@@ -0,0 +1,33 @@
+{-# LANGUAGE NoMonomorphismRestriction #-}
+module Util.Monad (module Control.Monad,($<),(>$),(>$<),(<&&>),(<||>),ifM,findM,traverseM) where
+
+import Control.Monad
+import Data.Traversable
+import Control.Applicative
+
+($<)  :: Monad m => (a -> b) -> m a -> m b
+(>$)  :: Monad m => m (a -> b) -> a -> m b
+(>$<) :: Monad m => m (a -> b) -> m a -> m b
+($<) = liftM
+mf >$ x = mf >>= \f -> return (f x)
+(>$<) = ap
+          
+ifM b th el = b >>= \b -> if b then th else el
+a <&&> b = ifM a b (return False)
+a <||> b = ifM a (return True) b
+
+findM p l = foldr fun (return Nothing) l
+  where fun x ret = ifM (p x) (return $ Just x) ret
+
+traverseM f = unwrapMonad . traverse (WrapMonad . f)
+
+-- Copyright (c) 2012, Coiffier Marc <marc.coiffier@gmail.com>
+-- All rights reserved.
+
+-- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+--     Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+--     Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
diff --git a/src/Util/Prelude.hs b/src/Util/Prelude.hs
new file mode 100644
--- /dev/null
+++ b/src/Util/Prelude.hs
@@ -0,0 +1,31 @@
+{-# LANGUAGE NoMonomorphismRestriction #-}
+module Util.Prelude where
+
+import System.Posix.Files
+import Data.Maybe
+import Debug.Trace
+import Util.Monad
+
+debug x = traceShow x x
+
+maybeToEither = maybe (Left undefined) Right
+eitherToMaybe = either (const Nothing) Just
+
+ifThenElse b th el = if b then th else el
+
+swap (a,b) = (b,a)
+
+newerThan f1 f2 = liftM2 (>) (modTime f1) (modTime f2)
+  where modTime f = modificationTime $< getFileStatus f
+
+
+-- Copyright (c) 2012, Coiffier Marc <marc.coiffier@gmail.com>
+-- All rights reserved.
+
+-- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+--     Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+--     Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
diff --git a/src/Util/State.hs b/src/Util/State.hs
new file mode 100644
--- /dev/null
+++ b/src/Util/State.hs
@@ -0,0 +1,47 @@
+{-# LANGUAGE TupleSections #-}
+
+module Util.State(
+  module Control.Monad.State, 
+  Field(..),(<.>),
+  stateF,doF,modifyF,getF,getsF,putF,swapF,
+  fstF,sndF
+  ) where
+
+import Control.Monad.State
+
+type Field f s = (s -> f,f -> s -> s)
+
+stateF  :: Field f s -> (f -> (a,f)) -> State s a
+modifyF :: Field f s -> (f -> f) -> State s ()
+getF    :: Field f s -> State s f
+getsF   :: Field f s -> (f -> a) -> State s a
+putF    :: Field f s -> f -> State s ()
+swapF   :: Field f s -> f -> State s f
+(<.>)   :: Field f s -> Field g f -> Field g s
+
+fstF :: Field a (a,b)
+sndF :: Field b (a,b)
+
+fstF = (fst,(\x (a,b) -> (x,b)))
+sndF = (snd,(\y (a,b) -> (a,y)))
+
+stateF (m,m') st = state (\s -> let (v,st') = st (m s) in (v,m' st' s))
+doF f st         = stateF f (runState st)
+modifyF fld f    = stateF fld (\s -> ((),f s))
+getF (f,_)       = gets f 
+getsF (f,_) g    = gets (g . f)
+putF f v         = modifyF f (const v)
+swapF f v        = stateF f (,v) 
+
+(f,f') <.> (g,g') = (g . f, (\g s -> f' (g' g (f s)) s)) 
+
+-- Copyright (c) 2012, Coiffier Marc <marc.coiffier@gmail.com>
+-- All rights reserved.
+
+-- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+--     Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+--     Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
diff --git a/src/Util/TimeLine.hs b/src/Util/TimeLine.hs
new file mode 100644
--- /dev/null
+++ b/src/Util/TimeLine.hs
@@ -0,0 +1,48 @@
+module Util.TimeLine where
+
+import Util.Monad
+import Util.State
+
+newtype TimeLine p f a = TimeLine { runTimeLine :: (p,f) -> [(p,f,a)] }
+
+instance Monad (TimeLine p f) where
+  tl >>= cc = TimeLine tl'
+    where tl' (p,f) = map snd lb
+            where la = runTimeLine tl (p,f')
+                  lb@((f',_):_) = [(f',(p'',f'',b))
+                                  | (p',f'',a) <- la
+                                  , (p'',f',b) <- runTimeLine (cc a) (p',f)]
+  return a = TimeLine (\(p,f) -> [(p,f,a)])
+
+fork = TimeLine (\(p,f) -> [(p,f,True),(p,f,False)])
+
+statetl = TimeLine . \k st -> let (a,(p,f)) = k st in [(p,f,a)]
+runtl = statetl . runState
+
+statep = runtl . stateF fstF
+runp = statep . runState
+getp = runp get
+getsp = runp . gets
+modifyp = runp . modify
+setp = modifyp . const
+
+statef = runtl . stateF sndF
+runf = statef . runState
+getf = runf get
+getsf = runf . gets
+modifyf = runf . modify
+setf = modifyf . const
+
+(swapplytl,swapplyp,swapplyf) = (f statetl,f statep,f statef)
+  where f st m = st (\x -> (x,m x))
+
+-- Copyright (c) 2012, Coiffier Marc <marc.coiffier@gmail.com>
+-- All rights reserved.
+
+-- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+--     Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+--     Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
