diff --git a/array-forth.cabal b/array-forth.cabal
--- a/array-forth.cabal
+++ b/array-forth.cabal
@@ -10,7 +10,7 @@
 -- PVP summary:      +-+------- breaking API changes
 --                   | | +----- non-breaking API additions
 --                   | | | +--- code changes with no API change
-version:             0.2.0.2
+version:             0.2.0.3
 
 -- A short (one-line) description of the package.
 synopsis:            A simple interpreter for arrayForth, the language used on GreenArrays chips.
@@ -66,17 +66,17 @@
   -- other-modules:       
   
   -- Other library packages from which modules are imported.
-  build-depends:       base ==4.5.*, mcmc-synthesis >=0.1, MonadRandom ==0.1.*,
+  build-depends:       base >3 && <=5, mcmc-synthesis >=0.1, MonadRandom ==0.1.*,
                        OddWord >=1.0.0, split ==0.1.*, vector ==0.9.*
   GHC-options:         -Wall -funbox-strict-fields -fno-warn-orphans -rtsopts
 
 executable mcmc-demo
   Main-is:             src/Main.hs
-  build-depends:       base ==4.5.*, mcmc-synthesis >=0.1, array-forth,
-                       MonadRandom ==0.1.*
+  build-depends:       base >3 && <=5, mcmc-synthesis >=0.1, array-forth,
+                       MonadRandom ==0.1.*, optparse-applicative ==0.5.*
   GHC-options:         -Wall -rtsopts
 
 executable array-forth
   Main-is:             src/Run.hs
-  build-depends:       base ==4.5.*, vector ==0.9.*, split ==0.1.*, array-forth
+  build-depends:       base >3 && <=5, vector ==0.9.*, split ==0.1.*, array-forth
   GHC-options:         -Wall -rtsopts
diff --git a/src/Language/ArrayForth/Program.hs b/src/Language/ArrayForth/Program.hs
--- a/src/Language/ArrayForth/Program.hs
+++ b/src/Language/ArrayForth/Program.hs
@@ -73,16 +73,17 @@
 -- nops before + instructions.
 toNative :: Program -> NativeProgram
 toNative = (>>= toInstrs) . splitWords bound . fixSlot3 . (>>= nopsPlus) . labels . filter (/= Unused)
-  where labels program = map convert $ filter (not . label) program
+  where labels program = map fixLabel $ filter (not . label) program
           where label Label{} = True
                 label _       = False
                 values = go 0 program
                 go _ []                  = []
                 go n (Label name : rest) = (name, n) : go n rest
                 go n (_ : rest)          = go (n + 1) rest
-                convert (Jump op (Abstract l)) = maybe (error $ "Unknown label " ++ l)
-                                                 (Jump op . Concrete) $ lookup l values
-                convert x                      = x
+                fixLabel (Jump op (Abstract l)) =
+                  maybe (error $ "Unknown label " ++ l)
+                        (Jump op . Concrete) $ lookup l values
+                fixLabel x                      = x
         nop = Opcode Nop
         bound Jump{} = True
         bound _      = False
diff --git a/src/Main.hs b/src/Main.hs
--- a/src/Main.hs
+++ b/src/Main.hs
@@ -1,13 +1,17 @@
+{-# LANGUAGE NamedFieldPuns    #-}
+{-# LANGUAGE OverloadedStrings #-}
 module Main where
 
 import           Control.Monad.Random            (evalRandIO)
 
 import           Data.List                       (find)
 
+import           Options.Applicative
+
 import           Language.ArrayForth.Distance    (Distance, registers)
 import           Language.ArrayForth.Interpreter (eval)
 import           Language.ArrayForth.Parse       ()
-import           Language.ArrayForth.Program     (Program, load)
+import           Language.ArrayForth.Program     (Program, load, readProgram)
 import           Language.ArrayForth.State       (State (..), startState)
 import           Language.ArrayForth.Synthesis   (defaultMutations, defaultOps,
                                                   evaluate)
@@ -16,15 +20,29 @@
 import           Language.Synthesis.Synthesis    (Problem (..), runningBest,
                                                   synthesizeMhList)
 
+data Options = Options { verbose :: Bool }
+
+options :: Parser Options
+options =  Options <$> switch (long "verbose" <>
+                               short 'v' <>
+                               help "Print intermediate state to STDOUT.")
+
+specP :: Parser Program
+specP = argument (either (const Nothing) Just . readProgram) (metavar "SPEC")
+
 main :: IO ()
-main = verbose
+main = do Options { verbose } <- execParser go
+          if verbose then verbosely else run
+  where go = info (helper <*> options) (fullDesc <>
+                                        progDesc "Synthesize arrayForth programs using MCMC." <>
+                                        header "mcmc-demo - simple synthesis with MCMC")
 
 good :: (Program, Double) -> Bool
 good (_, val) = val >= 0.5
 
-verbose :: IO ()
-verbose = do ls <- evalRandIO (synthesizeMhList inclusiveOr)
-             mapM_ print . zip ls . takeWhile (not . good) $ runningBest ls
+verbosely :: IO ()
+verbosely = do ls <- evalRandIO (synthesizeMhList inclusiveOr)
+               mapM_ print . zip ls . takeWhile (not . good) $ runningBest ls
 
 run :: IO ()
 run = evalRandIO (synthesizeMhList inclusiveOr) >>= print . find good . runningBest
