-
Notifications
You must be signed in to change notification settings - Fork 0
/
shush.hs
45 lines (38 loc) · 1.6 KB
/
shush.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
import Shell.Token
import System.Console.Readline
import System.Exit (ExitCode(ExitSuccess, ExitFailure))
import System.Process
import Text.Printf
-- using a CommandToken as a String (for now)
type CommandToken = Tokenized String
-- for now, using the naïve tokenization of words/unwords
runCmd :: Tokenized String -> [Tokenized String] -> IO ()
runCmd (Token (External, cmd)) args
= readProcessWithExitCode cmd untokenizedArgs ""
>>= (\p -> printf "`%s %s` %s" (printProcessResult p) cmd argString)
where untokenizedArgs = (map tokenFilling args)
argString = foldr (++) [] untokenizedArgs
printProcessResult :: (ExitCode, String, String) -> String
printProcessResult (ExitSuccess, pOut, pErr) = pOut ++ pErr
printProcessResult (ExitFailure i, pOut, pErr) = printf "exited %i:\n%s\n%s" i pOut pErr
unrecognizedCommand :: IO ()
unrecognizedCommand = putStrLn "unrecognized command"
processCommands :: String -> IO ()
processCommands "" = return ()
processCommands line | tokenType command == External = runCmd command args
| tokenFilling command == "echo" = putStrLn untokenizedArgs
| otherwise = unrecognizedCommand
where command = head (tokenize line)
args = tail (tokenize line)
untokenizedArgs = unwords (map show args)
repl :: IO ()
repl = do
maybeLine <- readline "% "
case maybeLine of
Nothing -> return ()
Just "exit" -> return ()
Just line -> do addHistory line
processCommands line
repl
main :: IO ()
main = repl