module Language.PureScript.Interactive.Types
( PSCiConfig(..)
, psciEnvironment
, PSCiState
, ImportedModule
, psciExports
, psciImports
, psciLoadedExterns
, psciInteractivePrint
, psciImportedModules
, psciLetBindings
, initialPSCiState
, initialInteractivePrint
, psciImportedModuleNames
, updateImportedModules
, updateLoadedExterns
, updateLets
, setInteractivePrint
, Command(..)
, ReplQuery(..)
, replQueries
, replQueryStrings
, showReplQuery
, parseReplQuery
, Directive(..)
) where
import Prelude.Compat
import qualified Language.PureScript as P
import qualified Data.Map as M
import Data.List (foldl')
import Language.PureScript.Sugar.Names.Env (nullImports, primExports)
import Control.Monad.Trans.Except (runExceptT)
import Control.Monad.Writer.Strict (runWriterT)
newtype PSCiConfig = PSCiConfig
{ psciFileGlobs :: [String]
} deriving Show
data PSCiState = PSCiState
[ImportedModule]
[P.Declaration]
[(P.Module, P.ExternsFile)]
(P.ModuleName, P.Ident)
P.Imports
P.Exports
deriving Show
psciImportedModules :: PSCiState -> [ImportedModule]
psciImportedModules (PSCiState x _ _ _ _ _) = x
psciLetBindings :: PSCiState -> [P.Declaration]
psciLetBindings (PSCiState _ x _ _ _ _) = x
psciLoadedExterns :: PSCiState -> [(P.Module, P.ExternsFile)]
psciLoadedExterns (PSCiState _ _ x _ _ _) = x
psciInteractivePrint :: PSCiState -> (P.ModuleName, P.Ident)
psciInteractivePrint (PSCiState _ _ _ x _ _) = x
psciImports :: PSCiState -> P.Imports
psciImports (PSCiState _ _ _ _ x _) = x
psciExports :: PSCiState -> P.Exports
psciExports (PSCiState _ _ _ _ _ x) = x
initialPSCiState :: PSCiState
initialPSCiState = PSCiState [] [] [] initialInteractivePrint nullImports primExports
initialInteractivePrint :: (P.ModuleName, P.Ident)
initialInteractivePrint = (P.moduleNameFromString "PSCI.Support", P.Ident "eval")
psciEnvironment :: PSCiState -> P.Environment
psciEnvironment st = foldl' (flip P.applyExternsFileToEnvironment) P.initEnvironment externs
where externs = map snd (psciLoadedExterns st)
type ImportedModule = (P.ModuleName, P.ImportDeclarationType, Maybe P.ModuleName)
psciImportedModuleNames :: PSCiState -> [P.ModuleName]
psciImportedModuleNames st =
map (\(mn, _, _) -> mn) (psciImportedModules st)
updateImportExports :: PSCiState -> PSCiState
updateImportExports st@(PSCiState modules lets externs iprint _ _) =
case desugarModule [temporaryModule] of
Left _ -> st
Right (env, _) ->
case M.lookup temporaryName env of
Just (_, is, es) -> PSCiState modules lets externs iprint is es
_ -> st
where
desugarModule :: [P.Module] -> Either P.MultipleErrors (P.Env, [P.Module])
desugarModule = runExceptT =<< hushWarnings . P.desugarImportsWithEnv (map snd externs)
hushWarnings = fmap fst . runWriterT
temporaryName :: P.ModuleName
temporaryName = P.ModuleName [P.ProperName "$PSCI"]
temporaryModule :: P.Module
temporaryModule =
let
prim = (P.ModuleName [P.ProperName "Prim"], P.Implicit, Nothing)
decl = (importDecl `map` (prim : modules)) ++ lets
in
P.Module internalSpan [] temporaryName decl Nothing
importDecl :: ImportedModule -> P.Declaration
importDecl (mn, declType, asQ) = P.ImportDeclaration (internalSpan, []) mn declType asQ
internalSpan :: P.SourceSpan
internalSpan = P.internalModuleSourceSpan "<internal>"
updateImportedModules :: ([ImportedModule] -> [ImportedModule]) -> PSCiState -> PSCiState
updateImportedModules f (PSCiState x a b c d e) =
updateImportExports (PSCiState (f x) a b c d e)
updateLoadedExterns :: ([(P.Module, P.ExternsFile)] -> [(P.Module, P.ExternsFile)]) -> PSCiState -> PSCiState
updateLoadedExterns f (PSCiState a b x c d e) =
updateImportExports (PSCiState a b (f x) c d e)
updateLets :: ([P.Declaration] -> [P.Declaration]) -> PSCiState -> PSCiState
updateLets f (PSCiState a x b c d e) =
updateImportExports (PSCiState a (f x) b c d e)
setInteractivePrint :: (P.ModuleName, P.Ident) -> PSCiState -> PSCiState
setInteractivePrint iprint (PSCiState a b c _ d e) =
PSCiState a b c iprint d e
data Command
= Expression P.Expr
| ShowHelp
| Import ImportedModule
| BrowseModule P.ModuleName
| QuitPSCi
| ReloadState
| ClearState
| Decls [P.Declaration]
| TypeOf P.Expr
| KindOf P.SourceType
| ShowInfo ReplQuery
| PasteLines
| CompleteStr String
| SetInteractivePrint (P.ModuleName, P.Ident)
deriving Show
data ReplQuery
= QueryLoaded
| QueryImport
| QueryPrint
deriving (Eq, Show)
replQueries :: [ReplQuery]
replQueries = [QueryLoaded, QueryImport, QueryPrint]
replQueryStrings :: [String]
replQueryStrings = map showReplQuery replQueries
showReplQuery :: ReplQuery -> String
showReplQuery QueryLoaded = "loaded"
showReplQuery QueryImport = "import"
showReplQuery QueryPrint = "print"
parseReplQuery :: String -> Maybe ReplQuery
parseReplQuery "loaded" = Just QueryLoaded
parseReplQuery "import" = Just QueryImport
parseReplQuery "print" = Just QueryPrint
parseReplQuery _ = Nothing
data Directive
= Help
| Quit
| Reload
| Clear
| Browse
| Type
| Kind
| Show
| Paste
| Complete
| Print
deriving (Eq, Show)