module Hint.Eval (
interpret, as, infer,
eval )
where
import qualified GHC
import qualified GHC.Exts ( unsafeCoerce# )
import Data.Typeable hiding ( typeOf )
import qualified Data.Typeable ( typeOf )
import Data.Char
import Hint.Base
import Hint.Parsers
import Hint.Sandbox
as, infer :: Typeable a => a
as = undefined
infer = undefined
interpret :: Typeable a => String -> a -> Interpreter a
interpret expr witness = sandboxed go expr
where go e =
do ghc_session <- fromSessionState ghcSession
failOnParseError parseExpr e
let expr_typesig = concat [parens e," :: ",show $ myTypeOf witness]
expr_val <- mayFail $ GHC.compileExpr ghc_session expr_typesig
return (GHC.Exts.unsafeCoerce# expr_val :: a)
myTypeOf :: Typeable a => a -> TypeRep
myTypeOf a
| type_of_a == type_of_string = qual_type_of_string
| otherwise = type_of_a
where type_of_a = Data.Typeable.typeOf a
type_of_string = Data.Typeable.typeOf (undefined :: [Char])
(list_ty_con, _) = splitTyConApp type_of_string
qual_type_of_string = mkTyConApp list_ty_con
[mkTyConApp (mkTyCon "Prelude.Char") []]
eval :: String -> Interpreter String
eval expr = interpret show_expr (as :: String)
where show_expr = "Prelude.show" ++ (parens expr)
parens :: String -> String
parens s = concat ["(let {", foo, " = ", s, "\n",
" ;} in ", foo, ")"]
where foo = "foo_1" ++ filter isDigit s