git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
#130 Add :t to PSCi
96264c7Phil Freeman
psci/Commands.hs+5
@@ -51,6 +51,10 @@ data Command
51 --
51 --
52 | Reload
52 | Reload
53 -- |
53 -- |
54+ -- Find the type of an expression
55+ --
56+ | TypeOf String
57+ -- |
54 -- An attempt at a meta command that wasn't recognized.
58 -- An attempt at a meta command that wasn't recognized.
55 --
59 --
56 | Unknown deriving (Show, Eq)
60 | Unknown deriving (Show, Eq)
@@ -68,6 +72,7 @@ getCommand = do
68 Just (':':'m':' ':filePath) -> return $ LoadFile filePath
72 Just (':':'m':' ':filePath) -> return $ LoadFile filePath
69 Just ":q" -> return Quit
73 Just ":q" -> return Quit
70 Just ":r" -> return Reload
74 Just ":r" -> return Reload
75+ Just (':':'t':' ':expr) -> return $ TypeOf expr
71 Just (':':_) -> return Unknown
76 Just (':':_) -> return Unknown
72 Just other -> Expression <$> go [other]
77 Just other -> Expression <$> go [other]
73 where
78 where
psci/Main.hs+30−12
@@ -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)
31
31
32+
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
42
44
43-- |
45-- |
44-- The PSCI state.
46-- The PSCI state.
@@ -182,24 +184,25 @@ options = P.Options True False True (Just "Main") True "PS" []
182-- |
184-- |
183-- Makes a volatile module to execute the current expression.
185-- Makes a volatile module to execute the current expression.
184--
186--
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 =
187 let
189 let
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"))))
194 in
197 in
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]
196
199
197-- |
200-- |
198-- Takes a value declaration and evaluates it with the current state.
201-- Takes a value declaration and evaluates it with the current state.
199--
202--
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"
212
215
216+-- |
217+-- Takes a value and prints its type
218+--
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"
228+
213-- Parser helpers
229-- Parser helpers
214
230
215-- |
231-- |
@@ -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
239− Left _ ->
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