content: -- Copyright (c) 2015-16 Nicola Bonelli <nicola@pfq.io>
  --
  -- This program is free software; you can redistribute it and/or modify
  -- it under the terms of the GNU General Public License as published by
  -- the Free Software Foundation; either version 2 of the License, or
  -- (at your option) any later version.
  --
  -- This program is distributed in the hope that it will be useful,
  -- but WITHOUT ANY WARRANTY; without even the implied warranty of
  -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  -- GNU General Public License for more details.
  --
  -- You should have received a copy of the GNU General Public License
  -- along with this program; if not, write to the Free Software
  -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  --
  
  {-# LANGUAGE TupleSections #-}
  
  module Lang.Parser
    ( defaultImports
    , parseCode
    , mkMainFunction
    , mkImportList
    ) where
  
  import Language.Haskell.Interpreter
  -- import Data.List
  
  import Control.Monad.Reader
  import Options
  import Data.Maybe
  
  
  defaultImports :: [(ModuleName, Maybe String)]
  defaultImports =
      [ ("Prelude", Just "P")
      , ("Data.Bits", Nothing)
      , ("Data.Monoid", Nothing)
      , ("Network.PFQ", Nothing)
      , ("Network.PFQ.Lang", Nothing)
      , ("Network.PFQ.Types", Nothing)
      , ("Network.PFQ.Lang.Prelude", Nothing)
      , ("Network.PFQ.Lang.Default", Nothing)
      , ("Network.PFQ.Lang.Experimental", Nothing)
      ]
  
  
  parseCode :: String -> (String, [(ModuleName, Maybe String)])
  parseCode code = (unlines (map snd xs), mapMaybe fst xs)
    where xs = map parseLine (lines code)
  
  
  type Import = (ModuleName, Maybe String)
  
  
  parseLine :: String -> (Maybe Import, String)
  parseLine xs = case () of
    _  | "import": "qualified": modname: "as": alias : ys <- ws  -> (Just (modname, Just alias), unwords ys)
       | "import": "qualified": modname : ys <- ws               -> (Just (modname, Just modname), unwords ys)
       | "import": modname : ys <- ws                            -> (Just (modname, Nothing), unwords ys)
       |  otherwise                                              -> (Nothing, xs)
    where ws = words xs
  
  
  mkMainFunction :: String -> String
  mkMainFunction code = "(let " ++ code ++ " in main)"
  
  
  mkImportList :: (Monad m) => [(ModuleName, Maybe String)] -> OptionT m [(ModuleName, Maybe String)]
  mkImportList xs = do
    opt <- ask
    return $ defaultImports ++ map (, Nothing) (modules opt) ++ xs
  
  