@@ -16,15 +16,19 @@
17module Main where
17module Main where
19−import Control.Monad.IO.Class
20import Control.Applicative
19import Control.Applicative
21import Control.Monad.Trans.Class
21import Control.Monad.Trans.Class
22+import Control.Monad.Trans.Maybe (MaybeT(..), runMaybeT)
23import Data.List (nub, isPrefixOf)
24import Data.List (nub, isPrefixOf)
24import Data.Maybe (mapMaybe)
25import Data.Maybe (mapMaybe)
26+import Data.Traversable (traverse)
27import System.Console.Haskeline
28import System.Console.Haskeline
29+import System.Directory (findExecutable)
29import qualified Language.PureScript as P
33import qualified Language.PureScript as P
30import qualified Paths_purescript as Paths
34import qualified Paths_purescript as Paths
@@ -35,7 +39,7 @@ getPreludeFilename :: IO FilePath
35getPreludeFilename = Paths.getDataFileName "prelude/prelude.purs"
39getPreludeFilename = Paths.getDataFileName "prelude/prelude.purs"
37options :: P.Options
41options :: P.Options
38−options = P.Options True False True Nothing True "PS" []
42+options = P.Options True False True (Just "Main") True "PS" []
40completion :: [P.Module] -> CompletionFunc IO
44completion :: [P.Module] -> CompletionFunc IO
41completion ms = completeWord Nothing " \t\n\r" findCompletions
45completion ms = completeWord Nothing " \t\n\r" findCompletions
@@ -43,12 +47,12 @@ completion ms = completeWord Nothing " \t\n\r" findCompletions
43 findCompletions :: String -> IO [Completion]
47 findCompletions :: String -> IO [Completion]
44 findCompletions str = do
48 findCompletions str = do
45 files <- listFiles str
49 files <- listFiles str
46− let names = nub $ [ show qual
50+ let names = nub [ show qual
47− | P.Module moduleName ds <- ms
51+ | P.Module moduleName ds <- ms
48− , ident <- mapMaybe getDeclName ds
52+ , ident <- mapMaybe getDeclName ds
49− , qual <- [ P.Qualified Nothing ident
53+ , qual <- [ P.Qualified Nothing ident
50− , P.Qualified (Just (P.ModuleName moduleName)) ident]
54+ , P.Qualified (Just moduleName) ident]
52 let matches = filter (isPrefixOf str) names
56 let matches = filter (isPrefixOf str) names
53 return $ map simpleCompletion matches ++ files
57 return $ map simpleCompletion matches ++ files
54 getDeclName :: P.Declaration -> Maybe P.Ident
58 getDeclName :: P.Declaration -> Maybe P.Ident
@@ -58,16 +62,16 @@ completion ms = completeWord Nothing " \t\n\r" findCompletions
58createTemporaryModule :: [P.ProperName] -> P.Value -> P.Module
62createTemporaryModule :: [P.ProperName] -> P.Value -> P.Module
59createTemporaryModule imports value =
63createTemporaryModule imports value =
61− moduleName = P.ProperName "Main"
65+ moduleName = P.ModuleName [P.ProperName "Main"]
62 importDecl m = P.ImportDeclaration m Nothing
66 importDecl m = P.ImportDeclaration m Nothing
63− traceModule = P.ModuleName (P.ProperName "Trace")
67+ traceModule = P.ModuleName [P.ProperName "Trace"]
64 trace = P.Var (P.Qualified (Just traceModule) (P.Ident "print"))
68 trace = P.Var (P.Qualified (Just traceModule) (P.Ident "print"))
65 mainDecl = P.ValueDeclaration (P.Ident "main") [] Nothing
69 mainDecl = P.ValueDeclaration (P.Ident "main") [] Nothing
66 (P.Do [ P.DoNotationBind (P.VarBinder (P.Ident "it")) value
70 (P.Do [ P.DoNotationBind (P.VarBinder (P.Ident "it")) value
67 , P.DoNotationValue (P.App trace (P.Var (P.Qualified Nothing (P.Ident "it"))) )
71 , P.DoNotationValue (P.App trace (P.Var (P.Qualified Nothing (P.Ident "it"))) )
70− P.Module moduleName $ map (importDecl . P.ModuleName) imports ++ [mainDecl]
74+ P.Module moduleName $ map (importDecl . P.ModuleName . return) imports ++ [mainDecl]
72handleDeclaration :: [P.Module] -> [P.ProperName] -> P.Value -> InputT IO ()
76handleDeclaration :: [P.Module] -> [P.ProperName] -> P.Value -> InputT IO ()
73handleDeclaration loadedModules imports value = do
77handleDeclaration loadedModules imports value = do
@@ -75,8 +79,12 @@ handleDeclaration loadedModules imports value = do
75 case P.compile options (loadedModules ++ [m]) of
79 case P.compile options (loadedModules ++ [m]) of
76 Left err -> outputStrLn err
80 Left err -> outputStrLn err
77 Right (js, _, _) -> do
81 Right (js, _, _) -> do
78− output <- liftIO $ readProcess "nodejs" [] js
82+ process <- lift findNodeProcess
83+ result <- lift $ traverse (\node -> readProcessWithExitCode node [] js) process
85+ Just (ExitSuccess, out, _) -> outputStrLn out
79− outputStrLn output
86+ Just (ExitFailure _, _, err) -> outputStrLn err
87+ Nothing -> outputStrLn "Couldn't find node.js"
81data Command
89data Command
@@ -108,6 +116,10 @@ loadModule moduleFile = do
108 moduleText <- U.readFile moduleFile
116 moduleText <- U.readFile moduleFile
109 return . either (Left . show) Right $ P.runIndentParser "" P.parseModules moduleText
117 return . either (Left . show) Right $ P.runIndentParser "" P.parseModules moduleText
119+findNodeProcess :: IO (Maybe String)
120+findNodeProcess = runMaybeT . msum $ map (MaybeT . findExecutable) names
121+ where names = ["nodejs", "node"]
111main :: IO ()
123main :: IO ()
113 preludeFilename <- getPreludeFilename
125 preludeFilename <- getPreludeFilename
@@ -121,7 +133,7 @@ main = do
121 outputStrLn " |_| "
133 outputStrLn " |_| "
122 outputStrLn ""
134 outputStrLn ""
123 outputStrLn "Expressions are terminated using Ctrl+D"
135 outputStrLn "Expressions are terminated using Ctrl+D"
124− go [P.ProperName "Prelude"] prelude
136+ go [P.ProperName "Prelude", P.ProperName "Eff"] prelude
126 go imports loadedModules = do
138 go imports loadedModules = do
127 cmd <- getCommand
139 cmd <- getCommand