--Standard modules
import qualified Maybe
import qualified System.IO.Unsafe
+import qualified Data.Map as Map
+import qualified Data.Accessor.Monad.Trans.State as MonadState
-- GHC API
import qualified GHC
type Binding = (CoreSyn.CoreBndr, CoreSyn.CoreExpr)
-- | Evaluate a core Type representing type level int from the tfp
--- library to a real int.
+-- library to a real int. Checks if the type really is a Dec type and
+-- caches the results.
+tfp_to_int :: Type.Type -> TypeSession Int
+tfp_to_int ty = do
+ hscenv <- MonadState.get tsHscEnv
+ let norm_ty = normalise_tfp_int hscenv ty
+ case Type.splitTyConApp_maybe norm_ty of
+ Just (tycon, args) -> do
+ let name = Name.getOccString (TyCon.tyConName tycon)
+ case name of
+ "Dec" ->
+ tfp_to_int' ty
+ otherwise -> do
+ return $ error ("Callin tfp_to_int on non-dec:" ++ (show ty))
+ Nothing -> return $ error ("Callin tfp_to_int on non-dec:" ++ (show ty))
+
+-- | Evaluate a core Type representing type level int from the tfp
+-- library to a real int. Caches the results. Do not use directly, use
+-- tfp_to_int instead.
+tfp_to_int' :: Type.Type -> TypeSession Int
+tfp_to_int' ty = do
+ lens <- MonadState.get tsTfpInts
+ hscenv <- MonadState.get tsHscEnv
+ let norm_ty = normalise_tfp_int hscenv ty
+ let existing_len = Map.lookup (OrdType norm_ty) lens
+ case existing_len of
+ Just len -> return len
+ Nothing -> do
+ let new_len = eval_tfp_int hscenv ty
+ MonadState.modify tsTfpInts (Map.insert (OrdType norm_ty) (new_len))
+ return new_len
+
+-- | Evaluate a core Type representing type level int from the tfp
+-- library to a real int. Do not use directly, use tfp_to_int instead.
eval_tfp_int :: HscTypes.HscEnv -> Type.Type -> Int
eval_tfp_int env ty =
unsafeRunGhc libdir $ do
-- arguments, to get at the value arguments.
n = length tyvars + length predtypes
-getLiterals :: HscTypes.HscEnv -> CoreSyn.CoreExpr -> [CoreSyn.CoreExpr]
-getLiterals _ app@(CoreSyn.App _ _) = literals
- where
- (CoreSyn.Var f, args) = CoreSyn.collectArgs app
- literals = filter (is_lit) args
-
-getLiterals _ lit@(CoreSyn.Lit _) = [lit]
-
-getLiterals hscenv letrec@(CoreSyn.Let (CoreSyn.NonRec letBind (letExpr)) letRes) = [lit]
- where
- ty = Var.varType letBind
- litInt = eval_tfp_int hscenv ty
- lit = CoreSyn.Lit (Literal.mkMachInt (toInteger litInt))
-
-getLiterals _ expr = error $ "\nCoreTools.getLiterals: Not a known Lit: " ++ pprString expr
+-- Finds out what literal Integer this expression represents.
+getIntegerLiteral :: CoreSyn.CoreExpr -> TranslatorSession Integer
+getIntegerLiteral expr =
+ case CoreSyn.collectArgs expr of
+ (CoreSyn.Var f, [CoreSyn.Lit (Literal.MachInt integer)])
+ | getFullString f == "GHC.Integer.smallInteger" -> return integer
+ (CoreSyn.Var f, [CoreSyn.Lit (Literal.MachInt64 integer)])
+ | getFullString f == "GHC.Integer.int64ToInteger" -> return integer
+ (CoreSyn.Var f, [CoreSyn.Lit (Literal.MachWord integer)])
+ | getFullString f == "GHC.Integer.wordToInteger" -> return integer
+ (CoreSyn.Var f, [CoreSyn.Lit (Literal.MachWord64 integer)])
+ | getFullString f == "GHC.Integer.word64ToInteger" -> return integer
+ -- fromIntegerT returns the integer corresponding to the type of its
+ -- (third) argument. Since it is polymorphic, the type of that
+ -- argument is passed as the first argument, so we can just use that
+ -- one.
+ (CoreSyn.Var f, [CoreSyn.Type dec_ty, dec_dict, CoreSyn.Type num_ty, num_dict, arg])
+ | getFullString f == "Types.Data.Num.Ops.fromIntegerT" -> do
+ int <- MonadState.lift tsType $ tfp_to_int dec_ty
+ return $ toInteger int
+ _ -> error $ "CoreTools.getIntegerLiteral: Unsupported Integer literal: " ++ pprString expr
reduceCoreListToHsList ::
[HscTypes.CoreModule] -- ^ The modules where parts of the list are hidden
let binders = take i wildbndrs ++ [sel_bndr] ++ drop (i+1) wildbndrs
return $ CoreSyn.Case scrut scrut_bndr scrut_ty [(CoreSyn.DataAlt datacon, binders, CoreSyn.Var sel_bndr)]
dcs -> error $ "CoreTools.mkSelCase: Scrutinee type must have exactly one datacon. Extracting element " ++ (show i) ++ " from '" ++ pprString scrut ++ "' Datacons: " ++ (show dcs) ++ " Type: " ++ (pprString scrut_ty)
- Nothing -> error $ "CoreTools.mkSelCase: Creating extractor case, but scrutinee has no tycon? Extracting element " ++ (show i) ++ " from '" ++ pprString scrut ++ "'"
+ Nothing -> error $ "CoreTools.mkSelCase: Creating extractor case, but scrutinee has no tycon? Extracting element " ++ (show i) ++ " from '" ++ pprString scrut ++ "'" ++ " Type: " ++ (pprString scrut_ty)