@@ -30,95 +30,53 @@ import Text.Parsec hiding ((<|>))
3030import qualified Language.PureScript as P
3131import qualified Language.PureScript.Parser.Common as C (mark, same)
3232
33−parseRestWith :: P.TokenParser a -> Parsec String () a
34−parseRestWith p = do
35− s <- many anyChar
36− case P.lex "" s >>= P.runTokenParser "" p of
37− Left err -> fail (show err)
38− Right a -> return a
39−
40−-- |
41−-- PSCI version of @let@.
42−-- This is essentially let from do-notation.
43−-- However, since we don't support the @Eff@ monad,
44−-- we actually want the normal @let@.
45−--
46−psciLet :: Parsec String () Command
47−psciLet = Let <$> (P.Let <$> (string "let" *> spaces *> parseRestWith manyDecls))
48− where
49− manyDecls :: P.TokenParser [P.Declaration]
50− manyDecls = C.mark (many1 (C.same *> P.parseDeclaration))
51−
5233-- |
5334-- Parses PSCI metacommands or expressions input from the user.
5435--
55−parseCommand :: String -> Either ParseError Command
56−parseCommand = flip parse "" $ choice
57− [ spaces *> char ':' *> (psciHelp <|> psciImport <|> psciLoadFile <|> psciQuit <|> psciReload <|> psciTypeOf <|> psciKindOf <|> psciBrowse <|> psciShowModules)
58− , try psciLet
59− , psciExpression
60− ] <* eof
61−
62−-- |
63−-- Parses expressions entered at the PSCI repl.
64−--
65−psciExpression :: Parsec String () Command
66−psciExpression = Expression <$> parseRestWith P.parseValue
67−
68−-- |
69−-- Parses 'Commands.Help' command.
70−--
71−psciHelp :: Parsec String () Command
72−psciHelp = Help <$ char '?'
73−
74−-- |
75−-- Parses 'Commands.Import' command.
76−--
77−psciImport :: Parsec String () Command
78−psciImport = Import <$> (char 'i' *> spaces *> parseRestWith P.moduleName)
79−
80−-- |
81−-- Parses 'Commands.LoadFile' command.
82−--
83−psciLoadFile :: Parsec String () Command
84−psciLoadFile = LoadFile . trimEnd <$> (char 'm' *> spaces *> manyTill anyChar eof)
85−
86−-- | Trim end of input string
87−trimEnd :: String -> String
88−trimEnd = reverse . dropWhile isSpace . reverse
89−
90−-- |
91−-- Parses 'Commands.Quit' command.
92−--
93−psciQuit :: Parsec String () Command
94−psciQuit = Quit <$ char 'q'
95−
96−-- |
97−-- Parses 'Commands.Reload' command.
98−--
99−psciReload :: Parsec String () Command
100−psciReload = Reset <$ char 'r'
101−
102−-- |
103−-- Parses 'Commands.TypeOf' command.
104−--
105−psciTypeOf :: Parsec String () Command
106−psciTypeOf = TypeOf <$> (char 't' *> spaces *> parseRestWith P.parseValue)
107−
108−
109−-- |
110−-- Parses 'Commands.KindOf' command.
111−--
112−psciKindOf :: Parsec String () Command
113−psciKindOf = KindOf <$> (char 'k' *> spaces *> parseRestWith P.parseType)
114−
115−-- |
116−-- Parses 'Commands.Browse' command.
117−--
118−psciBrowse :: Parsec String () Command
119−psciBrowse = Browse <$> (char 'b' *> spaces *> parseRestWith P.moduleName)
120−
121−-- |
122−-- Show Command
123−psciShowModules :: Parsec String () Command
124−psciShowModules = Show . trimEnd <$> (char 's' *> spaces *> manyTill anyChar eof)
36+parseCommand :: String -> Either String Command
37+parseCommand cmdString =
38+ case splitCommand cmdString of
39+ Just ('?', _) -> return Help
40+ Just ('q', _) -> return Quit
41+ Just ('r', _) -> return Reset
42+ Just ('i', moduleName) -> Import <$> parseRest P.moduleName moduleName
43+ Just ('b', moduleName) -> Browse <$> parseRest P.moduleName moduleName
44+ Just ('m', filename) -> return $ LoadFile (trimEnd filename)
45+ Just ('s', command) -> return $ Show (trimEnd command)
46+ Just ('t', expr) -> TypeOf <$> parseRest P.parseValue expr
47+ Just ('k', ty) -> KindOf <$> parseRest P.parseType ty
48+ Just _ -> Left $ "Unrecognized command. Type :? for help."
49+ Nothing -> parseRest (psciLet <|> psciExpression) cmdString
50+ where
51+ parseRest :: P.TokenParser a -> String -> Either String a
52+ parseRest p s = either (Left . show) Right $ do
53+ ts <- P.lex "" s
54+ P.runTokenParser "" (p <* eof) ts
55+
56+ trimEnd :: String -> String
57+ trimEnd = reverse . dropWhile isSpace . reverse
58+
59+ -- |
60+ -- Split a command into a command char and the trailing string
61+ --
62+ splitCommand :: String -> Maybe (Char, String)
63+ splitCommand (':' : c : s) = Just (c, dropWhile isSpace s)
64+ splitCommand _ = Nothing
65+
66+ -- |
67+ -- Parses expressions entered at the PSCI repl.
68+ --
69+ psciExpression :: P.TokenParser Command
70+ psciExpression = Expression <$> P.parseValue
71+
72+ -- |
73+ -- PSCI version of @let@.
74+ -- This is essentially let from do-notation.
75+ -- However, since we don't support the @Eff@ monad,
76+ -- we actually want the normal @let@.
77+ --
78+ psciLet :: P.TokenParser Command
79+ psciLet = Let <$> (P.Let <$> (P.reserved "let" *> P.indented *> manyDecls))
80+ where
81+ manyDecls :: P.TokenParser [P.Declaration]
82+ manyDecls = C.mark (many1 (C.same *> P.parseDeclaration))