git.iko.soy/rowtype-yoga/purescript-native
on ebbc4e4 help sign in
107 lines 3.8 kB history raw
1module PSCi.Module where
3import Prelude ()
4import Prelude.Compat
6import qualified Language.PureScript as P
7import PSCi.Types
8import System.FilePath (pathSeparator)
9import System.IO.UTF8 (readUTF8File)
10import Control.Monad
12-- | The name of the PSCI support module
13supportModuleName :: P.ModuleName
14supportModuleName = P.ModuleName [P.ProperName "$PSCI", P.ProperName "Support"]
16-- | Support module, contains code to evaluate terms
17supportModule :: P.Module
18supportModule =
19 case P.parseModulesFromFiles id [("", code)] of
20 Right [(_, P.Module ss cs _ ds exps)] -> P.Module ss cs supportModuleName ds exps
21 _ -> P.internalError "Support module could not be parsed"
22 where
23 code :: String
24 code = unlines
25 [ "module S where"
26 , ""
27 , "import Prelude"
28 , "import Control.Monad.Eff"
29 , "import Control.Monad.Eff.Console"
30 , "import Control.Monad.Eff.Unsafe"
31 , ""
32 , "class Eval a where"
33 , " eval :: a -> Eff (console :: CONSOLE) Unit"
34 , ""
35 , "instance evalShow :: (Show a) => Eval a where"
36 , " eval = print"
37 , ""
38 , "instance evalEff :: (Eval a) => Eval (Eff eff a) where"
39 , " eval x = unsafeInterleaveEff x >>= eval"
40 ]
42-- Module Management
44-- |
45-- Loads a file for use with imports.
46--
47loadModule :: FilePath -> IO (Either String [P.Module])
48loadModule filename = do
49 content <- readUTF8File filename
50 return $ either (Left . P.prettyPrintMultipleErrors False) (Right . map snd) $ P.parseModulesFromFiles id [(filename, content)]
52-- |
53-- Load all modules.
54--
55loadAllModules :: [FilePath] -> IO (Either P.MultipleErrors [(FilePath, P.Module)])
56loadAllModules files = do
57 filesAndContent <- forM files $ \filename -> do
58 content <- readUTF8File filename
59 return (filename, content)
60 return $ P.parseModulesFromFiles id filesAndContent
63-- |
64-- Makes a volatile module to execute the current expression.
65--
66createTemporaryModule :: Bool -> PSCiState -> P.Expr -> P.Module
67createTemporaryModule exec PSCiState{psciImportedModules = imports, psciLetBindings = lets} val =
68 let
69 moduleName = P.ModuleName [P.ProperName "$PSCI"]
70 trace = P.Var (P.Qualified (Just supportModuleName) (P.Ident "eval"))
71 mainValue = P.App trace (P.Var (P.Qualified Nothing (P.Ident "it")))
72 itDecl = P.ValueDeclaration (P.Ident "it") P.Public [] $ Right val
73 mainDecl = P.ValueDeclaration (P.Ident "$main") P.Public [] $ Right mainValue
74 decls = if exec then [itDecl, mainDecl] else [itDecl]
75 in
76 P.Module (P.internalModuleSourceSpan "<internal>") [] moduleName ((importDecl `map` imports) ++ lets ++ decls) Nothing
79-- |
80-- Makes a volatile module to hold a non-qualified type synonym for a fully-qualified data type declaration.
81--
82createTemporaryModuleForKind :: PSCiState -> P.Type -> P.Module
83createTemporaryModuleForKind PSCiState{psciImportedModules = imports, psciLetBindings = lets} typ =
84 let
85 moduleName = P.ModuleName [P.ProperName "$PSCI"]
86 itDecl = P.TypeSynonymDeclaration (P.ProperName "IT") [] typ
87 in
88 P.Module (P.internalModuleSourceSpan "<internal>") [] moduleName ((importDecl `map` imports) ++ lets ++ [itDecl]) Nothing
90-- |
91-- Makes a volatile module to execute the current imports.
92--
93createTemporaryModuleForImports :: PSCiState -> P.Module
94createTemporaryModuleForImports PSCiState{psciImportedModules = imports} =
95 let
96 moduleName = P.ModuleName [P.ProperName "$PSCI"]
97 in
98 P.Module (P.internalModuleSourceSpan "<internal>") [] moduleName (importDecl `map` imports) Nothing
100importDecl :: ImportedModule -> P.Declaration
101importDecl (mn, declType, asQ) = P.ImportDeclaration mn declType asQ False
103indexFile :: FilePath
104indexFile = ".psci_modules" ++ pathSeparator : "index.js"
106modulesDir :: FilePath
107modulesDir = ".psci_modules" ++ pathSeparator : "node_modules"