module Hint.Eval (
interpret, as, infer,
unsafeInterpret,
eval, runStmt,
parens
) where
import qualified GHC.Exts (unsafeCoerce#)
import Control.Exception
import Data.Typeable hiding (typeOf)
import qualified Data.Typeable (typeOf)
import Hint.Base
import Hint.Context
import Hint.Parsers
import Hint.Util
import qualified Hint.GHC as GHC
as, infer :: Typeable a => a
as = undefined
infer = undefined
interpret :: (MonadInterpreter m, Typeable a) => String -> a -> m a
interpret expr wit = unsafeInterpret expr (show $ Data.Typeable.typeOf wit)
unsafeInterpret :: (MonadInterpreter m) => String -> String -> m a
unsafeInterpret expr type_str =
do
failOnParseError parseExpr expr
let expr_typesig = concat [parens expr, " :: ", type_str]
expr_val <- mayFail $ runGhc1 compileExpr expr_typesig
return (GHC.Exts.unsafeCoerce# expr_val :: a)
compileExpr :: GHC.GhcMonad m => String -> m (Maybe GHC.HValue)
compileExpr = fmap Just . GHC.compileExpr
eval :: MonadInterpreter m => String -> m String
eval expr = do in_scope_show <- supportShow
in_scope_String <- supportString
let show_expr = unwords [in_scope_show, parens expr]
unsafeInterpret show_expr in_scope_String
runStmt :: (MonadInterpreter m) => String -> m ()
runStmt = mayFail . runGhc1 go
where
go statements = do
result <- GHC.execStmt statements GHC.execOptions
return $ case result of
GHC.ExecComplete { GHC.execResult = Right _ } -> Just ()
GHC.ExecComplete { GHC.execResult = Left e } -> throw e
_ -> Nothing
parens :: String -> String
parens s = concat ["(let {", foo, " =\n", s, "\n",
" ;} in ", foo, ")"]
where foo = safeBndFor s