soyuz-0.0.0: Main.hs
{-# LANGUAGE DeriveDataTypeable #-}
import System.Console.CmdArgs
import System.Exit
import System.IO (hPutStrLn, stderr)
import qualified DCPU16.Assembly.Parser as P
import Data.ByteString (ByteString)
import qualified Data.ByteString.Char8 as B
import Control.Monad (when, void)
import DCPU16.Assembly.Printer
import DCPU16.Assembly.Optimizer
import DCPU16.Assembler
import DCPU16.Disassembler
import DCPU16.Hex
main = do
opts <- cmdArgs options
instr <- readInput opts
let out = processOutput opts . optimize opts $ instr
case output opts of
-- absolutely do not do 'putStrLn', to not break binary input:
"" -> B.putStr out
f -> B.writeFile f out
where
packNlEof s = B.snoc (B.pack s) '\n'
readInput opts = do
instr <- case runMode opts of
Disassemble -> do
s <- B.readFile (inputFile opts)
return . Just . disassemble $ s
_ -> do
let po = P.defaults
{ P.roundedBrackets = parseSmoothBrackets opts
}
P.parseFile po (inputFile opts)
case instr of
Just is -> return is
Nothing -> exitFailure -- parser already printed messages
optimize opts is = if noOptimization opts then is else sizeVariant is
processOutput opts instr = case runMode opts of
Assemble -> binEncoding . assemble $ instr
_ -> packNlEof $ pprint instr
where
binEncoding = if hexdump opts then packNlEof . dumpBytes else id
-- | Print a message to stderr and exit.
errorExit :: String -> IO ()
errorExit msg = hPutStrLn stderr msg >> exitFailure
data RunMode = Assemble | Disassemble | PrettyPrint
deriving (Eq,Show,Read,Data,Typeable)
data Options = Options
{ runMode :: RunMode
, inputFile :: String
, noOptimization :: Bool
, output :: String
, hexdump :: Bool
, parseSmoothBrackets :: Bool
} deriving (Eq,Show,Read,Data,Typeable)
options = Options
{ runMode = enum
[ PrettyPrint&= help "Assembly -> consistently formatted assembly"
, Assemble &= help "Assembly -> machine code"
, Disassemble&= help "Machine code -> assembly"
] &= groupname "Mode of operation"
, inputFile = "" &= argPos 0 &= typ "<FILE>"
, noOptimization = False
&= explicit &= name "no-optimize"
&= help "Disable short literal/label optimization"
&= groupname "Optimization"
, output = def &= typ "<FILE>"
&= help "Write to file instead of stdout"
&= groupname "General"
, hexdump = False &= help "Encode binary data in a 16-bit hexdump"
, parseSmoothBrackets = False
&= explicit &= name "smooth-brackets"
&= help "Parse (a) instead of [a] for indirect mode"
} &= program "soyuz"
&= summary "soyuz 0.0.0, amtal <alex.kropivny@gmail.com>"
&= details
[ "Documentation and source at https://github.com/amtal/soyuz or on Hackage."
]