git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
A little more work on the REPL
ea3dba5Phil Freeman
libraries/prelude/prelude.purs+2
@@ -311,6 +311,8 @@ module Trace where
311
311
312 foreign import trace "function trace(s) { return function() { console.log(s); return {}; }; }" :: forall r. String -> Eff (trace :: Trace | r) {}
312 foreign import trace "function trace(s) { return function() { console.log(s); return {}; }; }" :: forall r. String -> Eff (trace :: Trace | r) {}
313
313
314+ foreign import print "function print(o) { return function() { console.log(JSON.stringify(o)); return {}; }; }" :: forall a r. a -> Eff (trace :: Trace | r) {}
315+
314module ST where
316module ST where
315
317
316 import Eff
318 import Eff
psci/Main.hs+39−24
@@ -18,10 +18,12 @@ module Main where
18
18
19import Control.Monad (forever)
19import Control.Monad (forever)
20import Control.Monad.Trans.Class
20import Control.Monad.Trans.Class
21+import Control.Monad.IO.Class
21
22
22import Data.Generics
23import Data.Generics
23import Data.List (isPrefixOf)
24import Data.List (isPrefixOf)
24
25
26+import System.Process
25import System.Console.Haskeline
27import System.Console.Haskeline
26
28
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"
34
36
35options :: P.Options
37options :: P.Options
36−options = P.Options True False True False
38+options = P.Options True False True True
37
39
38data InterpreterState = InterpreterState { interpEnv :: [P.DoNotationElement] } deriving (Show)
40data InterpreterState = InterpreterState { interpEnv :: [P.DoNotationElement] } deriving (Show)
39
41
@@ -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
54+
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 _ = []
59+
56− binderToNames :: P.Binder -> [P.Ident]
60+binderToNames :: P.Binder -> [P.Ident]
57− binderToNames = everything (++) (mkQ [] find)
61+binderToNames = everything (++) (mkQ [] find)
58− where
62+ where
59− find (P.VarBinder ident) = [ident]
63+ find (P.VarBinder ident) = [ident]
60− find _ = []
64+ find _ = []
61−
65+
62−createTemporaryModule :: [P.DoNotationElement] -> P.Module
66+createTemporaryModule :: [P.DoNotationElement] -> P.DoNotationElement -> P.Module
63−createTemporaryModule decls =
67+createTemporaryModule decls decl =
64 let
68 let
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))
71 in
80 in
72 P.Module moduleName [importDecl prelude, itDecl]
81 P.Module moduleName [importDecl prelude, itDecl]
73
82
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
87+ st <- lift S.get
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
93+ outputStrLn output
94+ lift . S.put $ st { interpEnv = interpEnv st ++ [decl] }
95+
74main :: IO ()
96main :: IO ()
75main = do
97main = do
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
89− st <- lift S.get
90− let m = createTemporaryModule (interpEnv st ++ [decl])
91− case P.compile options (prelude ++ [m]) of
92− Left err -> outputStrLn err
93− Right (js, _, _) -> do
94− outputStrLn js
95− lift . S.put $ st { interpEnv = interpEnv st ++ [decl] }
96
111
purescript.cabal+2−1
@@ -76,7 +76,8 @@ executable psc
76executable psci
76executable psci
77 build-depends: base >=4 && <5, containers -any,
77 build-depends: base >=4 && <5, containers -any,
78 mtl -any, parsec -any, haskeline -any,
78 mtl -any, parsec -any, haskeline -any,
79− purescript -any, syb -any, transformers -any, utf8-string -any
79+ purescript -any, syb -any, transformers -any, utf8-string -any,
80+ process -any
80 main-is: Main.hs
81 main-is: Main.hs
81 hs-source-dirs: psci
82 hs-source-dirs: psci
82 buildable: True
83 buildable: True