-- | Re-exports of base functionality. Note that this module is just
-- used inside the compiler. It's not compiled to JavaScript.
-- Based on the base-extended package (c) 2013 Simon Meier, licensed as BSD3.
{-# LANGUAGE NoImplicitPrelude #-}
module Fay.Compiler.Prelude
  ( module Prelude.Compat -- Partial

  -- * Control modules
  , module Control.Applicative
  , module Control.Arrow -- Partial
  , module Control.Monad.Compat

  -- * Data modules
  , module Data.Char -- Partial
  , module Data.Data -- Partial
  , module Data.Either
  , module Data.Function
  , module Data.List.Compat -- Partial
  , module Data.Maybe
  , module Data.Monoid -- Partial
  , module Data.Ord
  , module Data.Traversable

  -- * Safe
  , module Safe

  -- * Additions
  , anyM
  , io
  , readAllFromProcess
  ) where

import           Control.Applicative
import           Control.Arrow        (first, second, (&&&), (***), (+++), (|||))
import           Control.Monad.Compat hiding (guard)
import           Data.Char            hiding (GeneralCategory (..))
import           Data.Data            (Data (..), Typeable)
import           Data.Either
import           Data.Function        (on)
import           Data.List.Compat
import           Data.Maybe
import           Data.Monoid          (Monoid (..))
import           Data.Ord
import           Data.Traversable
import           Prelude.Compat       hiding (exp, mod)
import           Safe

import           Control.Monad.Except hiding (filterM)
import           System.Exit
import           System.Process

-- | Alias of liftIO, I hate typing it. Hate reading it.
io :: MonadIO m => IO a -> m a
io :: IO a -> m a
io = IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO

-- | Do any of the (monadic) predicates match?
anyM :: (Functor m, Applicative m, Monad m) => (a -> m Bool) -> [a] -> m Bool
anyM :: (a -> m Bool) -> [a] -> m Bool
anyM a -> m Bool
p [a]
l = Bool -> Bool
not (Bool -> Bool) -> ([a] -> Bool) -> [a] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null ([a] -> Bool) -> m [a] -> m Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (a -> m Bool) -> [a] -> m [a]
forall (m :: * -> *) a.
Applicative m =>
(a -> m Bool) -> [a] -> m [a]
filterM a -> m Bool
p [a]
l

-- | Read from a process returning both std err and out.
readAllFromProcess :: FilePath -> [String] -> String -> IO (Either (String,String) (String,String))
readAllFromProcess :: FilePath
-> [FilePath]
-> FilePath
-> IO (Either (FilePath, FilePath) (FilePath, FilePath))
readAllFromProcess FilePath
program [FilePath]
flags FilePath
input = do
  (ExitCode
code,FilePath
out,FilePath
err) <- FilePath
-> [FilePath] -> FilePath -> IO (ExitCode, FilePath, FilePath)
readProcessWithExitCode FilePath
program [FilePath]
flags FilePath
input
  Either (FilePath, FilePath) (FilePath, FilePath)
-> IO (Either (FilePath, FilePath) (FilePath, FilePath))
forall (m :: * -> *) a. Monad m => a -> m a
return (Either (FilePath, FilePath) (FilePath, FilePath)
 -> IO (Either (FilePath, FilePath) (FilePath, FilePath)))
-> Either (FilePath, FilePath) (FilePath, FilePath)
-> IO (Either (FilePath, FilePath) (FilePath, FilePath))
forall a b. (a -> b) -> a -> b
$ case ExitCode
code of
    ExitFailure Int
127 -> (FilePath, FilePath)
-> Either (FilePath, FilePath) (FilePath, FilePath)
forall a b. a -> Either a b
Left (FilePath
"cannot find executable " FilePath -> FilePath -> FilePath
forall a. [a] -> [a] -> [a]
++ FilePath
program, FilePath
"")
    ExitFailure Int
_   -> (FilePath, FilePath)
-> Either (FilePath, FilePath) (FilePath, FilePath)
forall a b. a -> Either a b
Left (FilePath
err, FilePath
out)
    ExitCode
ExitSuccess     -> (FilePath, FilePath)
-> Either (FilePath, FilePath) (FilePath, FilePath)
forall a b. b -> Either a b
Right (FilePath
err, FilePath
out)