@@ -18,10 +18,12 @@ module Main where
19import Control.Monad (forever)
19import Control.Monad (forever)
20import Control.Monad.Trans.Class
20import Control.Monad.Trans.Class
21+import Control.Monad.IO.Class
22import Data.Generics
23import Data.Generics
23import Data.List (isPrefixOf)
24import Data.List (isPrefixOf)
25import System.Console.Haskeline
27import System.Console.Haskeline
27import qualified Language.PureScript as P
29import qualified Language.PureScript as P
@@ -33,7 +35,7 @@ getPreludeFilename :: IO FilePath
33getPreludeFilename = Paths.getDataFileName "libraries/prelude/prelude.purs"
35getPreludeFilename = Paths.getDataFileName "libraries/prelude/prelude.purs"
35options :: P.Options
37options :: P.Options
36−options = P.Options True False True False
38+options = P.Options True False True True
38data InterpreterState = InterpreterState { interpEnv :: [P.DoNotationElement] } deriving (Show)
40data InterpreterState = InterpreterState { interpEnv :: [P.DoNotationElement] } deriving (Show)
@@ -46,31 +48,51 @@ completion = completeWord Nothing " \t\n\r" findCompletions
46 findCompletions :: (S.MonadState InterpreterState m) => String -> m [Completion]
48 findCompletions :: (S.MonadState InterpreterState m) => String -> m [Completion]
47 findCompletions str = do
49 findCompletions str = do
48 st <- S.get
50 st <- S.get
49− let names = map show . concatMap toNames . interpEnv $ st
51+ let names = map show . concatMap findAllNames . interpEnv $ st
50 let matches = filter (isPrefixOf str) names
52 let matches = filter (isPrefixOf str) names
51 return $ map simpleCompletion matches
53 return $ map simpleCompletion matches
52− toNames :: P.DoNotationElement -> [P.Ident]
55+findAllNames :: P.DoNotationElement -> [P.Ident]
53− toNames (P.DoNotationLet binder _) = binderToNames binder
56+findAllNames (P.DoNotationLet binder _) = binderToNames binder
54− toNames (P.DoNotationBind binder _) = binderToNames binder
57+findAllNames (P.DoNotationBind binder _) = binderToNames binder
55− toNames _ = []
58+findAllNames _ = []
56− binderToNames :: P.Binder -> [P.Ident]
60+binderToNames :: P.Binder -> [P.Ident]
57− binderToNames = everything (++) (mkQ [] find)
61+binderToNames = everything (++) (mkQ [] find)
59− find (P.VarBinder ident) = [ident]
63+ find (P.VarBinder ident) = [ident]
60− find _ = []
64+ find _ = []
62−createTemporaryModule :: [P.DoNotationElement] -> P.Module
66+createTemporaryModule :: [P.DoNotationElement] -> P.DoNotationElement -> P.Module
63−createTemporaryModule decls =
67+createTemporaryModule decls decl =
65− moduleName = P.ProperName "Temp"
69+ moduleName = P.ProperName "Main"
66 importDecl m = P.ImportDeclaration m Nothing
70 importDecl m = P.ImportDeclaration m Nothing
67 prelude = P.ModuleName (P.ProperName "Prelude")
71 prelude = P.ModuleName (P.ProperName "Prelude")
68 effModule = P.ModuleName (P.ProperName "Eff")
72 effModule = P.ModuleName (P.ProperName "Eff")
73+ traceModule = P.ModuleName (P.ProperName "Trace")
69 effMonad = P.Var (P.Qualified (Just effModule) (P.Ident "eff"))
74 effMonad = P.Var (P.Qualified (Just effModule) (P.Ident "eff"))
75+ trace = P.Var (P.Qualified (Just traceModule) (P.Ident "print"))
76+ varsIntroduced = findAllNames decl
77+ traceVars | null varsIntroduced = [P.DoNotationValue (P.App trace [P.StringLiteral "Done"])]
78+ | otherwise = map (\ident -> P.DoNotationValue (P.App trace [P.Var (P.Qualified Nothing ident)])) varsIntroduced
70− itDecl = P.ValueDeclaration (P.Ident "it") [] Nothing (P.Do effMonad decls)
79+ itDecl = P.ValueDeclaration (P.Ident "main") [] Nothing (P.Do effMonad (decls ++ decl : traceVars))
72 P.Module moduleName [importDecl prelude, itDecl]
81 P.Module moduleName [importDecl prelude, itDecl]
83+handleDeclaration :: (S.MonadState InterpreterState m, S.MonadIO m) => [P.Module] -> P.DoNotationElement -> InputT m ()
84+handleDeclaration _ (P.DoNotationReturn _) = outputStrLn "return statements are not supported in interactive mode"
85+handleDeclaration prelude (P.DoNotationValue val) = handleDeclaration prelude (P.DoNotationBind (P.VarBinder (P.Ident "it")) val)
86+handleDeclaration prelude decl = do
88+ let m = createTemporaryModule (interpEnv st) decl
89+ case P.compile options (prelude ++ [m]) of
90+ Left err -> outputStrLn err
91+ Right (js, _, _) -> do
92+ output <- liftIO $ readProcess "nodejs" [] js
94+ lift . S.put $ st { interpEnv = interpEnv st ++ [decl] }
74main :: IO ()
96main :: IO ()
76 preludeFilename <- getPreludeFilename
98 preludeFilename <- getPreludeFilename
@@ -85,12 +107,5 @@ main = do
85 Just line' ->
107 Just line' ->
86 case P.runIndentParser P.parseDoNotationElement line' of
108 case P.runIndentParser P.parseDoNotationElement line' of
87 Left err -> outputStrLn (show err)
109 Left err -> outputStrLn (show err)
88− Right decl -> do
110+ Right decl -> handleDeclaration prelude decl
90− let m = createTemporaryModule (interpEnv st ++ [decl])
91− case P.compile options (prelude ++ [m]) of
92− Left err -> outputStrLn err
93− Right (js, _, _) -> do
95− lift . S.put $ st { interpEnv = interpEnv st ++ [decl] }