clash-ghc-0.3: src-ghc/CLaSH/GHC/Evaluator.hs
{-# LANGUAGE ViewPatterns #-}
module CLaSH.GHC.Evaluator where
import qualified Data.Bifunctor as Bifunctor
import qualified Data.Either as Either
import qualified Data.HashMap.Strict as HashMap
import qualified Data.List as List
import qualified Data.Text as Text
import CLaSH.Core.DataCon (dcTag)
import CLaSH.Core.Literal (Literal (..))
import CLaSH.Core.Term (Term (..))
import CLaSH.Core.Type (Type (..), ConstTy (..))
import CLaSH.Core.TyCon (TyCon, TyConName, tyConDataCons)
import CLaSH.Core.Util (collectArgs)
reduceConstant :: HashMap.HashMap TyConName TyCon -> Term -> Term
reduceConstant tcm e@(collectArgs -> (Prim nm _, args))
| nm == Text.pack "GHC.Integer.Type.eqInteger#"
= case (map (reduceConstant tcm) . Either.lefts) args of
[Literal (IntegerLiteral i), Literal (IntegerLiteral j)]
| i == j -> Literal (IntegerLiteral 1)
| otherwise -> Literal (IntegerLiteral 0)
_ -> e
| nm == Text.pack "GHC.Prim.<=#" || nm == Text.pack "GHC.Integer.Type.leInteger#"
= case (map (reduceConstant tcm) . Either.lefts) args of
[Literal (IntegerLiteral i), Literal (IntegerLiteral j)]
| i <= j -> Literal (IntegerLiteral 1)
| otherwise -> Literal (IntegerLiteral 0)
_ -> e
| nm == Text.pack "GHC.Integer.Type.integerToInt"
= case (map (reduceConstant tcm) . Either.lefts) args of
[Literal (IntegerLiteral i)] -> Literal (IntegerLiteral i)
_ -> e
| nm == Text.pack "GHC.Prim.tagToEnum#"
= case map (Bifunctor.bimap (reduceConstant tcm) id) args of
[Right (ConstTy (TyCon tcN)), Left (Literal (IntegerLiteral i))] ->
let dc = do { tc <- HashMap.lookup tcN tcm
; let dcs = tyConDataCons tc
; List.find ((== (i+1)) . toInteger . dcTag) dcs
}
in maybe e Data dc
_ -> e
reduceConstant _ e = e