1{-# LANGUAGE ScopedTypeVariables #-}
2--tools to execute an atom function body
3module ProjectM36.AtomFunctionBody where
7import Control.Monad.IO.Class
8import Control.Exception
9import Data.Text hiding (map)
13import GHC.Paths (libdir)
15import Outputable hiding ((<>))
17import Type hiding (pprTyThing)
18import System.FilePath.Glob
20data ScriptSession = ScriptSession {
22 atomFunctionBodyType :: Type
25-- | Configure a GHC environment/session which we will use for all script compilation.
26initScriptSession :: [String] -> IO ScriptSession
27initScriptSession ghcPkgPaths = do
28 --for the sake of convenience, for developers' builds, include the local cabal sandbox pacakge database
29 sandboxPkgPaths <- liftIO (glob ".cabal-sandbox/*packages.conf.d")
30 runGhc (Just libdir) $ do
31 dflags <- getSessionDynFlags
32 let localPkgPaths = map PkgConfFile (ghcPkgPaths ++ sandboxPkgPaths)
34 let dflags' = dflags { hscTarget = HscInterpreted ,
35 ghcLink = LinkInMemory,
36 safeHaskell = Sf_Trustworthy,
39 --trustFlags = [TrustPackage "base"] -- new in 8
40 packageFlags = (packageFlags dflags) ++ packages,
41 extraPkgConfs = const ([GlobalPkgConf, UserPkgConf] ++ localPkgPaths)
43 `xopt_set` Opt_ExtendedDefaultRules
44 `xopt_set` Opt_ImplicitPrelude
45 `xopt_set` Opt_OverloadedStrings
46 `gopt_set` Opt_DistrustAllPackages
47 `xopt_set` Opt_ScopedTypeVariables
48 `gopt_set` Opt_PackageTrust
49 --`gopt_set` Opt_ImplicitImportQualified
50 packages = map TrustPackage ["base",
52 "unordered-containers",
58 "vector-binary-instances",
61 "bytestring"] -- package flags changed in 8.0
62 _ <- setSessionDynFlags dflags'
63 let safeImportDecl mn = ImportDecl {
64 ideclSourceSrc = Nothing,
66 ideclPkgQual = Nothing,
69 ideclImplicit = False,
70 ideclQualified = False,
74 setContext (map (\modn -> IIDecl $ safeImportDecl (mkModuleName modn))
79 fType <- mkAtomFunctionBodyType
80 pure (ScriptSession env fType)
82mkAtomFunctionBodyType :: Ghc Type
83mkAtomFunctionBodyType = do
84 lBodyName <- parseName "AtomFunctionBodyType"
86 [] -> error "failed to parse AtomFunctionBodyType"
87 _:_:_ -> error "too many name matches"
89 mThing <- lookupName bodyName
91 Nothing -> error "failed to find AtomFunctionBodyType"
92 Just (ATyCon tyCon) -> case synTyConRhs_maybe tyCon of
94 Nothing -> error "AtomFunctionBodyType is not a type synonym"
95 Just _ -> error "failed to find type synonym AtomFunctionBodyType"
97addImport :: String -> Ghc ()
98addImport moduleNam = do
100 setContext ( (IIDecl $ simpleImportDecl (mkModuleName moduleNam)) : ctx )
102showType :: DynFlags -> Type -> String
103showType dflags ty = showSDocForUser dflags alwaysQualify (pprTypeForUser ty)
105-- | Typecheck and validate the
106typeCheckAtomFunctionScript :: Type -> AtomFunctionBodyScript -> Ghc (Maybe AtomFunctionBodyCompilationError)
107typeCheckAtomFunctionScript expectedType inp = do
108 dflags <- getSessionDynFlags
109 --catch exception for SyntaxError
110 funcType <- GHC.exprType (unpack inp)
112 if eqType funcType expectedType then
115 pure (Just (TypeCheckCompilationError (showType dflags expectedType) (showType dflags funcType)))
117-- | After compiling the script, it must accept a list of Atoms and return an Atom, otherwise an AtomFunctionBodyCompilationError is returned
118compileAtomFunctionScript :: ScriptSession -> AtomFunctionBodyScript -> Ghc (Either AtomFunctionBodyCompilationError AtomFunctionBodyType)
119compileAtomFunctionScript (ScriptSession _ funcType) script = do
120 let sScript = unpack script
121 mErr <- typeCheckAtomFunctionScript funcType script
123 Just err -> pure (Left err)
125 --catch exception here
126 --we could potentially wrap the script with Atom pattern matching so that the script doesn't have to do it, but the change to an Atom ADT should make it easier. Still, it would be nice if the script didn't have to handle a list of arguments, for example.
127 -- we can't use dynCompileExpr here because
128 func <- compileExpr sScript
129 pure $ Right (unsafeCoerce func)
131catchCompileException :: MonadIO m => IO a -> m (Either AtomFunctionBodyCompilationError a)
132catchCompileException m = liftIO $ do
135 Left (err :: SomeException) -> do
136 pure (Left (OtherScriptCompilationError (show err)))
137 Right res -> pure (Right res)
139compiledAtomFunctionBody :: AtomFunctionBodyType -> AtomFunctionBody
140compiledAtomFunctionBody func = AtomFunctionBody Nothing func
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list