@@ -29,6 +29,7 @@ import Data.List (intercalate, isPrefixOf, nub, sort)
29import Data.Maybe (mapMaybe)
29import Data.Maybe (mapMaybe)
30import Data.Traversable (traverse)
30import Data.Traversable (traverse)
32import System.Console.Haskeline
33import System.Console.Haskeline
33import System.Directory (findExecutable)
34import System.Directory (findExecutable)
34import System.Exit
35import System.Exit
@@ -38,7 +39,8 @@ import System.Process
38import qualified Language.PureScript as P
39import qualified Language.PureScript as P
39import qualified Paths_purescript as Paths
40import qualified Paths_purescript as Paths
40import qualified System.IO.UTF8 as U (readFile)
41import qualified System.IO.UTF8 as U (readFile)
41−import qualified Text.Parsec as Parsec (Parsec, eof)
42+import qualified Text.Parsec as Parsec (Parsec, eof, try)
43+import qualified Data.Map as M
44-- The PSCI state.
46-- The PSCI state.
@@ -182,24 +184,25 @@ options = P.Options True False True (Just "Main") True "PS" []
183-- Makes a volatile module to execute the current expression.
185-- Makes a volatile module to execute the current expression.
185−createTemporaryModule :: [P.ProperName] -> [P.Value -> P.Value] -> P.Value -> P.Module
187+createTemporaryModule :: Bool -> [P.ProperName] -> [P.Value -> P.Value] -> P.Value -> P.Module
186−createTemporaryModule imports lets value =
188+createTemporaryModule exec imports lets value =
188 moduleName = P.ModuleName [P.ProperName "Main"]
190 moduleName = P.ModuleName [P.ProperName "Main"]
189 importDecl m = P.ImportDeclaration m Nothing
191 importDecl m = P.ImportDeclaration m Nothing
190 traceModule = P.ModuleName [P.ProperName "Trace"]
192 traceModule = P.ModuleName [P.ProperName "Trace"]
191 trace = P.Var (P.Qualified (Just traceModule) (P.Ident "print"))
193 trace = P.Var (P.Qualified (Just traceModule) (P.Ident "print"))
192 value' = foldr ($) value lets
194 value' = foldr ($) value lets
195+ itDecl = P.ValueDeclaration (P.Ident "it") [] Nothing value'
193− mainDecl = P.ValueDeclaration (P.Ident "main") [] Nothing (P.App trace value')
196+ mainDecl = P.ValueDeclaration (P.Ident "main") [] Nothing (P.App trace (P.Var (P.Qualified Nothing (P.Ident "it"))))
195− P.Module moduleName $ map (importDecl . P.ModuleName . return) imports ++ [mainDecl]
198+ P.Module moduleName $ map (importDecl . P.ModuleName . return) imports ++ if exec then [itDecl, mainDecl] else [itDecl]
198-- Takes a value declaration and evaluates it with the current state.
201-- Takes a value declaration and evaluates it with the current state.
200handleDeclaration :: P.Value -> PSCI -> InputT IO ()
203handleDeclaration :: P.Value -> PSCI -> InputT IO ()
201handleDeclaration value (PSCI imports loadedModules lets) = do
204handleDeclaration value (PSCI imports loadedModules lets) = do
202− let m = createTemporaryModule imports lets value
205+ let m = createTemporaryModule True imports lets value
203 case P.compile options (loadedModules ++ [m]) of
206 case P.compile options (loadedModules ++ [m]) of
204 Left err -> outputStrLn err
207 Left err -> outputStrLn err
205 Right (js, _, _) -> do
208 Right (js, _, _) -> do
@@ -210,6 +213,19 @@ handleDeclaration value (PSCI imports loadedModules lets) = do
210 Just (ExitFailure _, _, err) -> outputStrLn err
213 Just (ExitFailure _, _, err) -> outputStrLn err
211 Nothing -> outputStrLn "Couldn't find node.js"
214 Nothing -> outputStrLn "Couldn't find node.js"
217+-- Takes a value and prints its type
219+handleTypeOf :: P.Value -> PSCI -> InputT IO ()
220+handleTypeOf value (PSCI imports loadedModules lets) = do
221+ let m = createTemporaryModule False imports lets value
222+ case P.compile options { P.optionsMain = Nothing } (loadedModules ++ [m]) of
223+ Left err -> outputStrLn err
224+ Right (_, _, env') -> do
225+ case M.lookup (P.ModuleName [P.ProperName "Main"], P.Ident "it") (P.names env') of
226+ Just (ty, _) -> outputStrLn . P.prettyPrintType $ ty
227+ Nothing -> outputStrLn "Could not find type"
213-- Parser helpers
229-- Parser helpers
@@ -235,12 +251,14 @@ parseExpression = P.whiteSpace *> P.parseValue <* Parsec.eof
235handleCommand :: Command -> StateT PSCI (InputT IO) ()
251handleCommand :: Command -> StateT PSCI (InputT IO) ()
236handleCommand Empty = return ()
252handleCommand Empty = return ()
237handleCommand (Expression ls) =
253handleCommand (Expression ls) =
238− case P.runIndentParser "" parseLet (unlines ls) of
254+ case P.runIndentParser "" (Left <$> Parsec.try parseLet <|> Right <$> parseExpression) (unlines ls) of
240− case P.runIndentParser "" parseExpression (unlines ls) of
241− Left err -> inputTToState $ outputStrLn (show err)
255+ Left err -> inputTToState $ outputStrLn (show err)
242− Right decl -> get >>= inputTToState . handleDeclaration decl
243− Right l -> modify (updateLets l)
256+ Right (Left l) -> modify (updateLets l)
257+ Right (Right decl) -> get >>= inputTToState . handleDeclaration decl
258+handleCommand (TypeOf expr) =
259+ case P.runIndentParser "" parseExpression expr of
260+ Left err -> inputTToState $ outputStrLn (show err)
261+ Right expr' -> get >>= inputTToState . handleTypeOf expr'
244handleCommand Help = inputTToState $ outputStrLn helpMessage
262handleCommand Help = inputTToState $ outputStrLn helpMessage
245handleCommand (Import moduleName) = modify (updateImports moduleName)
263handleCommand (Import moduleName) = modify (updateImports moduleName)
246handleCommand (LoadFile filePath) = do
264handleCommand (LoadFile filePath) = do