on 267f708 help sign in
elk/src/Elm/Utils.hs
107 lines 2.7 kB history raw
1{-# OPTIONS_GHC -Wall #-}
2{-# LANGUAGE FlexibleContexts #-}
3module Elm.Utils
4 ( (|>), (<|)
5 , run, unwrappedRun
6 , CommandError(..)
7 , isDeclaration
8 ) where
10import Control.Monad.Except (MonadError, MonadIO, liftIO, throwError)
11import qualified Data.List as List
12import System.Exit (ExitCode(ExitSuccess, ExitFailure))
13import System.Process (readProcessWithExitCode)
15import qualified AST.Pattern as Pattern
16import qualified Parse.Helpers as Parse
17import qualified Parse.Expression as Parse
18import qualified Reporting.Annotation as A
21{-| Forward function application `x |> f == f x`. This function is useful
22for avoiding parenthesis and writing code in a more natural way.
23-}
24(|>) :: a -> (a -> b) -> b
25x |> f = f x
28{-| Backward function application `f <| x == f x`. This function is useful for
29avoiding parenthesis.
30-}
31(<|) :: (a -> b) -> a -> b
32f <| x = f x
35infixr 0 <|
36infixl 0 |>
39-- RUN EXECUTABLES
41data CommandError
42 = MissingExe String
43 | CommandFailed String String
46{-| Run a command, throw an error if the command is not found or if something
47goes wrong.
48-}
49run :: (MonadError String m, MonadIO m) => String -> [String] -> m String
50run command args =
51 do result <- liftIO (unwrappedRun command args)
52 case result of
53 Right out ->
54 return out
56 Left err ->
57 throwError (context (message err))
58 where
59 context msg =
60 "failure when running:" ++ concatMap (' ':) (command:args) ++ "\n" ++ msg
62 message err =
63 case err of
64 CommandFailed stdout stderr ->
65 stdout ++ stderr
67 MissingExe msg ->
68 msg
71unwrappedRun :: String -> [String] -> IO (Either CommandError String)
72unwrappedRun command args =
73 do (exitCode, stdout, stderr) <- readProcessWithExitCode command args ""
74 return $
75 case exitCode of
76 ExitSuccess ->
77 Right stdout
79 ExitFailure code ->
80 if code == 127 then
81 Left (missingExe command) -- UNIX
83 else if code == 9009 then
84 Left (missingExe command) -- Windows
86 else
87 Left (CommandFailed stdout stderr)
90missingExe :: String -> CommandError
91missingExe command =
92 MissingExe $
93 "Could not find command `" ++ command ++ "`. Do you have it installed?\n\
94 \ Can it be run from anywhere? Is it on your PATH?"
98-- DECL CHECKER
100isDeclaration :: String -> Maybe String
101isDeclaration string =
102 case Parse.iParse (Parse.definition (,)) string of
103 Right (A.A _ (pattern, _)) ->
104 Just (List.intercalate "$" (Pattern.boundVarList pattern))
106 _ ->
107 Nothing