diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright Bernard Pope 2012, 2013
+
+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.
+
+    * Neither the name of Bernard Pope nor the names of other
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+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
+OWNER 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.lhs b/Setup.lhs
new file mode 100644
--- /dev/null
+++ b/Setup.lhs
@@ -0,0 +1,3 @@
+#!/usr/bin/env runhaskell
+> import Distribution.Simple
+> main = defaultMain
diff --git a/blip.cabal b/blip.cabal
new file mode 100644
--- /dev/null
+++ b/blip.cabal
@@ -0,0 +1,37 @@
+Name:                blip 
+Version:             0.1.0
+Synopsis:            Python to bytecode compiler.
+Homepage:            https://github.com/bjpop/blip  
+License:             BSD3
+License-file:        LICENSE
+Author:              Bernie Pope
+Maintainer:          Bernie Pope <florbitous@gmail.com>
+Stability:           Experimental
+category:            Language 
+Build-type:          Simple
+Cabal-version:       >=1.8
+Description:
+ Compiles Python 3 source code to bytecode. The resulting
+ bytecode is written to a '.pyc' file, compatible with the
+ CPython implementation (the default Python interpreter).
+
+source-repository head
+  type: git
+  location: git://github.com/bjpop/blip.git
+
+Executable blip {
+  ghc-options: -Wall -fno-warn-name-shadowing -fno-warn-orphans
+  main-is: Main.hs
+  hs-source-dirs: src
+  build-depends: base==4.*,
+     bliplib == 0.1.*,
+     -- directory == 1.2.*,
+     filepath == 1.3.*,
+     parseargs == 0.1.* ,
+     language-python==0.4.*,
+     mtl==2.1.*,
+     containers==0.5.*,
+     bytestring==0.10.*,
+     old-time==1.1.*,
+     pretty==1.1.*
+}
diff --git a/src/Main.hs b/src/Main.hs
new file mode 100644
--- /dev/null
+++ b/src/Main.hs
@@ -0,0 +1,140 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module      : Main
+-- Copyright   : (c) 2012, 2013 Bernie Pope
+-- License     : BSD-style
+-- Maintainer  : florbitous@gmail.com
+-- Stability   : experimental
+-- Portability : ghc
+--
+-- The Main module of Blip. Contains the entry point of the compiler, and
+-- handles command line argument parsing.
+--
+-----------------------------------------------------------------------------
+
+module Main where
+
+import System.Exit (exitFailure, exitSuccess)
+import Control.Monad (when)
+import System.Console.ParseArgs
+   (Argtype (..), argDataOptional, Arg (..)
+   , gotArg, getArg, parseArgsIO, ArgsComplete (..), Args(..))
+import Blip.Version (versionString)
+import Compile (compileFile)
+import ProgName (progName)
+import Data.Set as Set (Set, empty, singleton, union)
+import Types (Dumpable (..), CompileConfig (..))
+
+main :: IO ()
+main = do
+   let argDescriptions = [version, help, magicNumberArg, dumpScopeArg, dumpASTArg]
+   args <- parseArgsIO (ArgsTrailing "PYTHON_FILES") argDescriptions
+   when (gotArg args Help) $ do
+      putStrLn $ argsUsage args
+      exitSuccess
+   when (gotArg args Version) $ do
+      putStrLn $ progName ++ " version " ++ versionString
+      exitSuccess
+   let pythonFiles = argsRest args
+   when (null pythonFiles) $ do
+      putStrLn $ progName ++ ": no Python input files specified"
+      putStrLn $ argsUsage args
+      exitFailure 
+   let magicNumber = getMagicNumber args
+       dumps = getDumps args
+       config = initCompileConfig 
+                   { compileConfig_magic = fromIntegral magicNumber
+                   , compileConfig_dumps = dumps }
+   mapM_ (compileFile config) pythonFiles
+
+data ArgIndex
+   = Help
+   | InputFile
+   | Version
+   | MagicNumber
+   | Dump Dumpable
+   deriving (Eq, Ord, Show)
+
+help :: Arg ArgIndex
+help =
+   Arg
+   { argIndex = Help
+   , argAbbr = Just 'h'
+   , argName = Just "help"
+   , argData = Nothing
+   , argDesc = "Display a help message."
+   }
+
+inputFile :: Arg ArgIndex
+inputFile =
+   Arg
+   { argIndex = InputFile
+   , argAbbr = Nothing
+   , argName = Nothing
+   , argData = argDataOptional "input file" ArgtypeString
+   , argDesc = "Name of the input Python file."
+   }
+
+version :: Arg ArgIndex
+version =
+   Arg
+   { argIndex = Version
+   , argAbbr = Nothing
+   , argName = Just "version"
+   , argData = Nothing
+   , argDesc = "Show the version number of " ++ progName ++ "."
+   }
+
+-- this works for CPython 3.3.0
+defaultMagicNumber :: Int
+defaultMagicNumber = 168627358
+
+magicNumberArg :: Arg ArgIndex
+magicNumberArg =
+   Arg
+   { argIndex = MagicNumber 
+   , argAbbr = Nothing
+   , argName = Just "magic"
+   , argData = argDataOptional "magic number" ArgtypeInt
+   , argDesc = "Magic number to include in pyc file header."
+   }
+
+dumpScopeArg :: Arg ArgIndex
+dumpScopeArg =
+   Arg
+   { argIndex = Dump DumpScope
+   , argAbbr = Nothing
+   , argName = Just "dumpScope"
+   , argData = Nothing
+   , argDesc = "Dump the variable scope."
+   }
+
+dumpASTArg :: Arg ArgIndex
+dumpASTArg =
+   Arg
+   { argIndex = Dump DumpAST
+   , argAbbr = Nothing
+   , argName = Just "dumpAST"
+   , argData = Nothing
+   , argDesc = "Dump the abstract syntax tree."
+   }
+
+getInputFile :: Args ArgIndex -> Maybe FilePath
+getInputFile args = getArg args InputFile 
+
+getMagicNumber :: Args ArgIndex -> Int
+getMagicNumber args = 
+   maybe defaultMagicNumber id $ getArg args MagicNumber
+
+getDumps :: Args ArgIndex -> Set.Set Dumpable 
+getDumps args
+   = getDump DumpScope args `Set.union` getDump DumpAST args
+   where
+   getDump :: Dumpable -> Args ArgIndex -> Set.Set Dumpable
+   getDump dumpable args
+      | gotArg args (Dump dumpable) = Set.singleton dumpable
+      | otherwise = Set.empty
+
+initCompileConfig :: CompileConfig
+initCompileConfig =
+   CompileConfig { compileConfig_magic = 0, compileConfig_dumps = Set.empty }
