content: -- Parts of the file generated by the BNF Converter (bnfc 2.9.4.1).
  
  module Main where
  
  import Control.Monad (return, when)
  import Interpret (Escape (Error), Value (Int, Void), runProgram)
  import Latte.Abs (Program)
  import Latte.Lex (Token, mkPosToken)
  import Latte.Par (myLexer, pProgram)
  import Latte.Print (Print, printTree)
  import Latte.Skel ()
  import StaticCheck (checkProgram, initialEnv, runStaticCheck)
  import System.Environment (getArgs)
  import System.Exit (ExitCode (ExitFailure), exitFailure, exitSuccess, exitWith)
  import System.IO (hPutStrLn, stderr)
  import Prelude
    ( Either (..),
      FilePath,
      IO,
      Int,
      Show,
      String,
      concat,
      elem,
      fromIntegral,
      getContents,
      mapM_,
      putStrLn,
      readFile,
      show,
      unlines,
      ($),
      (++),
      (.),
      (==),
      (>),
      (>>),
      (>>=),
    )
  
  type Err = Either String
  
  type ParseFun a = [Token] -> Err a
  
  type Verbosity = Int
  
  putStrV :: Verbosity -> String -> IO ()
  putStrV v s = when (v > 1) $ putStrLn s
  
  parseFile :: (Print a, Show a) => Verbosity -> ParseFun a -> FilePath -> IO a
  parseFile v p f = putStrV v f >> readFile f >>= parse v p
  
  parse :: (Print a, Show a) => Verbosity -> ParseFun a -> String -> IO a
  parse v p s =
    case p ts of
      Left err -> do
        hPutStrLn stderr "\nParse Failed...\n"
        putStrV v "Tokens:"
        mapM_ (putStrV v . showPosToken . mkPosToken) ts
        hPutStrLn stderr err
        exitFailure
      Right tree -> do
        putStrV v "\nParse Successful!"
        showTree v tree
        return tree
    where
      ts = myLexer s
      showPosToken ((l, c), t) = concat [show l, ":", show c, "\t", show t]
  
  showTree :: (Show a, Print a) => Int -> a -> IO ()
  showTree v tree = do
    putStrV v $ "\n[Abstract Syntax]\n\n" ++ show tree
    putStrV v $ "\n[Linearized tree]\n\n" ++ printTree tree
  
  usage :: IO ()
  usage = do
    putStrLn $
      unlines
        [ "usage: Call with one of the following argument combinations:",
          "  --help            Display this help message and exit.",
          "  (no arguments)    Run from stdin.",
          "  (file)            Run from a file.",
          "  -p (no arguments) Parse from stdin. Outputs detailed parsing information.",
          "  -p (files)        Parse files. Outputs detailed parsing information."
        ]
  
  main :: IO ()
  main = do
    args <- getArgs
    program <-
      case args of
        ["--help"] -> usage >> exitSuccess
        [] -> getContents >>= parse 0 pProgram
        ["-p"] -> getContents >>= parse 2 pProgram >> exitSuccess
        [file] -> parseFile 0 pProgram file
        "-p" : fs -> mapM_ (parseFile 2 pProgram) fs >> exitSuccess
        _ -> hPutStrLn stderr "Invalid options. Use --help for usage information." >> exitFailure
    case runStaticCheck initialEnv (checkProgram program) of
      Left err -> hPutStrLn stderr ("Static check error: " ++ err) >> exitFailure
      Right _ -> return ()
    res <- runProgram program
    case res of
      Left (Error reason) -> hPutStrLn stderr ("Program threw error: " ++ reason) >> exitFailure
      Right (Int code) -> if code == 0 then exitSuccess else exitWith (ExitFailure (fromIntegral code))
      Right Void -> exitSuccess
  