New command line processing.

This commit is contained in:
2016-04-30 16:15:00 -07:00
parent 079796ecc3
commit edc2a7161a
3 changed files with 58 additions and 39 deletions

View File

@@ -14,9 +14,9 @@ cabal-version: >=1.10
executable bang executable bang
main-is: Main.hs main-is: Main.hs
build-depends: base >= 4.8 && < 4.9, build-depends: base >= 4.8 && < 4.9,
bytestring >= 0.10 && < 0.11, bytestring >= 0.10 && < 0.11,
cmdargs >= 0.10.14 && < 0.12 optparse-applicative >= 0.12.1 && < 0.14
hs-source-dirs: src hs-source-dirs: src
build-tools: alex, happy build-tools: alex, happy
default-language: Haskell2010 default-language: Haskell2010

View File

@@ -1,8 +1,10 @@
import Syntax.CommandLine import Syntax.CommandLine
main :: IO () main :: IO ()
main = getCommand >>= \ mode -> main = getCommand >>= \ cmd ->
putStrLn (show mode) case cmdCommand cmd of
Lex _lexOpts -> putStrLn ("LEX: " ++ show cmd)
Help -> putStrLn helpString
{- {-

View File

@@ -1,47 +1,64 @@
{-# LANGUAGE DeriveDataTypeable #-}
module Syntax.CommandLine( module Syntax.CommandLine(
Bang(..), getCommand BangCommand(..)
, BangOperation(..)
, LexerOptions(..)
, getCommand
, helpString
) )
where where
import Data.Version(showVersion) import Data.Version(showVersion)
import Paths_bang(version) import Paths_bang(version)
import System.Console.CmdArgs hiding (verbosity) import Options.Applicative
import Options.Applicative.Help
data Bang = Bang { data BangCommand = BangCommand {
verbosity :: Word cmdVerbosity :: Verbosity
, files :: [FilePath] , cmdOutputFile :: FilePath
, mode :: BangMode , cmdCommand :: BangOperation
} }
deriving (Data, Typeable, Show, Eq) deriving (Show)
data BangMode = Lex | Parse data Verbosity = Silent | Normal | Verbose
deriving (Data, Typeable, Show, Eq) deriving (Eq, Show)
lexer :: Bang verboseOption :: Parser Verbosity
lexer = Bang { verboseOption = flag Normal Silent (short 'q' <> long "quiet")
verbosity = 0 &= name "verbose" &= name "v" <|> flag Normal Verbose (short 'v' <> long "verbose")
, files = [] &= args
, mode = Lex
} &= name "lex"
parser :: Bang outputFile :: Parser FilePath
parser = Bang { outputFile = strOption (short 'o' <> long "output-file" <> metavar "FILE"
verbosity = 0 &= name "verbose" &= name "v" <> help "The file to output as a result of this action."
, files = [] &= args <> value "/dev/stdout" <> showDefault)
, mode = Parse
} &= name "parse"
bang :: Bang data BangOperation = Help
bang = modes [lexer, parser] | Lex LexerOptions
&= versionArg [explicit, name "version", summary programInfo] deriving (Show)
&= summary (programInfo ++ ", " ++ copyright)
&= help "A nifty little compiler for a new language"
&= helpArg [explicit, name "help", name "h", name "?"]
&= program "bang"
where
programInfo = "bang version " ++ showVersion version
copyright = "(C) 2016 Adam Wick"
getCommand :: IO Bang bangOperation :: Parser BangOperation
getCommand = cmdArgs bang bangOperation = subparser $
command "help" (pure Help `withInfo` "Describe common commands.") <>
command "lex" (parseLex `withInfo` "Lex a file into its component tokens.")
withInfo :: Parser a -> String -> ParserInfo a
withInfo opts desc = info (helper <*> opts) (progDesc desc)
data LexerOptions = LexerOptions {
lexInputFile :: FilePath
}
deriving (Show)
parseLex :: Parser BangOperation
parseLex = Lex <$> parseLexOptions
parseLexOptions :: Parser LexerOptions
parseLexOptions = LexerOptions <$> argument str (metavar "FILE")
parseOptions :: Parser BangCommand
parseOptions = BangCommand <$> verboseOption <*> outputFile <*> bangOperation
helpString :: String
helpString = show (parserHelp (ParserPrefs "" False False True 80) parseOptions)
getCommand :: IO BangCommand
getCommand = execParser (parseOptions `withInfo` "Run a bang language action.")