git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
Allow more declarations
b8d96ccHarry Garrood
psci/Commands.hs+2−2
@@ -50,9 +50,9 @@ data Command
50 --
50 --
51 | Reset
51 | Reset
52 -- |
52 -- |
53− -- Binds a value to a name
53+ -- Add some declarations to the current evaluation context.
54 --
54 --
55− | Let [Declaration]
55+ | Decls [Declaration]
56 -- |
56 -- |
57 -- Find the type of an expression
57 -- Find the type of an expression
58 --
58 --
psci/Main.hs+5−5
@@ -437,11 +437,11 @@ handleDeclaration val = do
437 Nothing -> PSCI $ outputStrLn "Couldn't find node.js"
437 Nothing -> PSCI $ outputStrLn "Couldn't find node.js"
438
438
439-- |
439-- |
440−-- Takes a let declaration and updates the environment, then run a make. If the declaration fails,
440+-- Takes a list of declarations and updates the environment, then run a make. If the declaration fails,
441−-- restore the pre-let environment.
441+-- restore the original environment.
442--
442--
443−handleLet :: [P.Declaration] -> PSCI ()
443+handleDecls :: [P.Declaration] -> PSCI ()
444−handleLet ds = do
444+handleDecls ds = do
445 st <- PSCI $ lift get
445 st <- PSCI $ lift get
446 let st' = updateLets ds st
446 let st' = updateLets ds st
447 let m = createTemporaryModule False st' (P.ObjectLiteral [])
447 let m = createTemporaryModule False st' (P.ObjectLiteral [])
@@ -599,7 +599,7 @@ handleCommand :: C.Command -> PSCI ()
599handleCommand (C.Expression val) = handleDeclaration val
599handleCommand (C.Expression val) = handleDeclaration val
600handleCommand C.Help = PSCI $ outputStrLn helpMessage
600handleCommand C.Help = PSCI $ outputStrLn helpMessage
601handleCommand (C.Import im) = handleImport im
601handleCommand (C.Import im) = handleImport im
602−handleCommand (C.Let l) = handleLet l
602+handleCommand (C.Decls l) = handleDecls l
603handleCommand (C.LoadFile filePath) = do
603handleCommand (C.LoadFile filePath) = do
604 absPath <- psciIO $ expandTilde filePath
604 absPath <- psciIO $ expandTilde filePath
605 exists <- psciIO $ doesFileExist absPath
605 exists <- psciIO $ doesFileExist absPath
psci/Parser.hs+86−51
@@ -13,8 +13,8 @@
13--
13--
14-----------------------------------------------------------------------------
14-----------------------------------------------------------------------------
15
15
16−module Parser (
16+module Parser
17− parseCommand
17+ ( parseCommand
18 ) where
18 ) where
19
19
20import Prelude hiding (lex)
20import Prelude hiding (lex)
@@ -38,53 +38,88 @@ parseCommand :: String -> Either String C.Command
38parseCommand cmdString =
38parseCommand cmdString =
39 case cmdString of
39 case cmdString of
40 (':' : cmd) -> parseDirective cmd
40 (':' : cmd) -> parseDirective cmd
41− _ -> parseRest (psciImport <|> psciLet <|> psciExpression) cmdString
41+ _ -> parseRest psciCommand cmdString
42+
43+parseRest :: P.TokenParser a -> String -> Either String a
44+parseRest p s = either (Left . show) Right $ do
45+ ts <- P.lex "" s
46+ P.runTokenParser "" (p <* eof) ts
47+
48+psciCommand :: P.TokenParser C.Command
49+psciCommand = choice (map try parsers)
42 where
50 where
43− parseRest :: P.TokenParser a -> String -> Either String a
51+ parsers =
44− parseRest p s = either (Left . show) Right $ do
52+ [ psciLet
45− ts <- P.lex "" s
53+ , psciImport
46− P.runTokenParser "" (p <* eof) ts
54+ , psciOtherDeclaration
47−
55+ , psciExpression
56+ ]
57+
48− trim :: String -> String
58+trim :: String -> String
49− trim = trimEnd . trimStart
59+trim = trimEnd . trimStart
50−
60+
51− trimStart :: String -> String
61+trimStart :: String -> String
52− trimStart = dropWhile isSpace
62+trimStart = dropWhile isSpace
53−
63+
54− trimEnd :: String -> String
64+trimEnd :: String -> String
55− trimEnd = reverse . trimStart . reverse
65+trimEnd = reverse . trimStart . reverse
56−
66+
57− parseDirective :: String -> Either String C.Command
67+parseDirective :: String -> Either String C.Command
58− parseDirective cmd =
68+parseDirective cmd =
59− case D.parseDirective dstr of
69+ case D.parseDirective dstr of
60− Just D.Help -> return C.Help
70+ Just D.Help -> return C.Help
61− Just D.Quit -> return C.Quit
71+ Just D.Quit -> return C.Quit
62− Just D.Reset -> return C.Reset
72+ Just D.Reset -> return C.Reset
63− Just D.Browse -> C.Browse <$> parseRest P.moduleName arg
73+ Just D.Browse -> C.Browse <$> parseRest P.moduleName arg
64− Just D.Load -> return $ C.LoadFile (trim arg)
74+ Just D.Load -> return $ C.LoadFile (trim arg)
65− Just D.Show -> return $ C.Show (trim arg)
75+ Just D.Show -> return $ C.Show (trim arg)
66− Just D.Type -> C.TypeOf <$> parseRest P.parseValue arg
76+ Just D.Type -> C.TypeOf <$> parseRest P.parseValue arg
67− Just D.Kind -> C.KindOf <$> parseRest P.parseType arg
77+ Just D.Kind -> C.KindOf <$> parseRest P.parseType arg
68− Nothing -> Left $ "Unrecognized command. Type :? for help."
78+ Nothing -> Left $ "Unrecognized command. Type :? for help."
69− where (dstr, arg) = break isSpace cmd
79+ where (dstr, arg) = break isSpace cmd
70−
80+
71− -- |
81+-- |
72− -- Parses expressions entered at the PSCI repl.
82+-- Parses expressions entered at the PSCI repl.
73− --
83+--
74− psciExpression :: P.TokenParser C.Command
84+psciExpression :: P.TokenParser C.Command
75− psciExpression = C.Expression <$> P.parseValue
85+psciExpression = C.Expression <$> P.parseValue
76−
86+
77− -- |
87+-- |
78− -- PSCI version of @let@.
88+-- PSCI version of @let@.
79− -- This is essentially let from do-notation.
89+-- This is essentially let from do-notation.
80− -- However, since we don't support the @Eff@ monad,
90+-- However, since we don't support the @Eff@ monad,
81− -- we actually want the normal @let@.
91+-- we actually want the normal @let@.
82− --
92+--
83− psciLet :: P.TokenParser C.Command
93+psciLet :: P.TokenParser C.Command
84− psciLet = C.Let <$> (P.reserved "let" *> P.indented *> manyDecls)
94+psciLet = C.Decls <$> (P.reserved "let" *> P.indented *> manyDecls)
85− where
95+ where
86− manyDecls :: P.TokenParser [P.Declaration]
96+ manyDecls :: P.TokenParser [P.Declaration]
87− manyDecls = C.mark (many1 (C.same *> P.parseDeclaration))
97+ manyDecls = C.mark (many1 (C.same *> P.parseLocalDeclaration))
88−
98+
99+-- | Imports must be handled separately from other declarations, so that
100+-- :show import works, for example.
89− psciImport :: P.TokenParser C.Command
101+psciImport :: P.TokenParser C.Command
90− psciImport = C.Import <$> P.parseImportDeclaration'
102+psciImport = C.Import <$> P.parseImportDeclaration'
103+
104+-- | Any other declaration that we don't need a 'special case' parser for
105+-- (like let or import declarations).
106+psciOtherDeclaration :: P.TokenParser C.Command
107+psciOtherDeclaration = C.Decls . (:[]) <$> do
108+ decl <- discardPositionInfo <$> P.parseDeclaration
109+ if acceptable decl
110+ then return decl
111+ else fail "this kind of declaration is not supported in psci"
112+
113+discardPositionInfo :: P.Declaration -> P.Declaration
114+discardPositionInfo (P.PositionedDeclaration _ _ d) = d
115+discardPositionInfo d = d
116+
117+acceptable :: P.Declaration -> Bool
118+acceptable (P.DataDeclaration _ _ _ _) = True
119+acceptable (P.TypeSynonymDeclaration _ _ _) = True
120+acceptable (P.ExternDeclaration _ _ _ _) = True
121+acceptable (P.ExternDataDeclaration _ _) = True
122+acceptable (P.ExternInstanceDeclaration _ _ _ _) = True
123+acceptable (P.TypeClassDeclaration _ _ _ _) = True
124+acceptable (P.TypeInstanceDeclaration _ _ _ _ _) = True
125+acceptable _ = False
src/Language/PureScript/Parser/Declarations.hs+1
@@ -25,6 +25,7 @@ module Language.PureScript.Parser.Declarations (
25 parseBinder,
25 parseBinder,
26 parseBinderNoParens,
26 parseBinderNoParens,
27 parseImportDeclaration',
27 parseImportDeclaration',
28+ parseLocalDeclaration
28) where
29) where
29
30
30import Prelude hiding (lex)
31import Prelude hiding (lex)