change (Lam id (App expr (Var id)))
-- Leave all other expressions unchanged
eta e = return e
-etatop = notapplied ("eta", eta)
+etatop = notappargs ("eta", eta)
--------------------------------
-- β-reduction
-- Perform this transform everywhere
betatop = everywhere ("beta", beta)
+--------------------------------
+-- Cast propagation
+--------------------------------
+-- Try to move casts as much downward as possible.
+castprop, castproptop :: Transform
+castprop (Cast (Let binds expr) ty) = change $ Let binds (Cast expr ty)
+castprop expr@(Cast (Case scrut b _ alts) ty) = change (Case scrut b ty alts')
+ where
+ alts' = map (\(con, bndrs, expr) -> (con, bndrs, (Cast expr ty))) alts
+-- Leave all other expressions unchanged
+castprop expr = return expr
+-- Perform this transform everywhere
+castproptop = everywhere ("castprop", castprop)
+
--------------------------------
-- let recursification
--------------------------------
-- What transforms to run?
-transforms = [typeproptop, funproptop, etatop, betatop, letremovetop, letrectop, letsimpltop, letflattop, casewildtop, scrutsimpltop, casevalsimpltop, caseremovetop, inlinefuntop, appsimpltop]
+transforms = [typeproptop, funproptop, etatop, betatop, castproptop, letremovetop, letrectop, letsimpltop, letflattop, casewildtop, scrutsimpltop, casevalsimpltop, caseremovetop, inlinefuntop, appsimpltop]
-- Turns the given bind into VHDL
normalizeModule ::
transalt (con, binders, expr) = do
expr' <- trans expr
return (con, binders, expr')
-
-subeverywhere trans expr = return expr
+subeverywhere trans (Var x) = return $ Var x
+subeverywhere trans (Lit x) = return $ Lit x
+subeverywhere trans (Type x) = return $ Type x
--- Apply the given transformation to all expressions, except for every first
--- argument of an application.
-notapplied :: (String, Transform) -> Transform
-notapplied trans = applyboth (subnotapplied trans) trans
+subeverywhere trans (Cast expr ty) = do
+ expr' <- trans expr
+ return $ Cast expr' ty
+
+subeverywhere trans expr = error $ "NormalizeTools.subeverywhere Unsupported expression: " ++ show expr
+
+-- Apply the given transformation to all expressions, except for direct
+-- arguments of an application
+notappargs :: (String, Transform) -> Transform
+notappargs trans = applyboth (subnotappargs trans) trans
-- Apply the given transformation to all (direct and indirect) subexpressions
--- (but not the expression itself), except for the first argument of an
--- applicfirst argument of an application
-subnotapplied :: (String, Transform) -> Transform
-subnotapplied trans (App a b) = do
- a' <- subnotapplied trans a
- b' <- notapplied trans b
+-- (but not the expression itself), except for direct arguments of an
+-- application
+subnotappargs :: (String, Transform) -> Transform
+subnotappargs trans (App a b) = do
+ a' <- subnotappargs trans a
+ b' <- subnotappargs trans b
return $ App a' b'
-- Let subeverywhere handle all other expressions
-subnotapplied trans expr = subeverywhere (notapplied trans) expr
+subnotappargs trans expr = subeverywhere (notappargs trans) expr
-- Runs each of the transforms repeatedly inside the State monad.
dotransforms :: [Transform] -> CoreExpr -> TransformSession CoreExpr
(CoreSyn.CoreBndr, CoreSyn.CoreExpr) -- ^ The binding to process
-> VHDLState [AST.ConcSm] -- ^ The corresponding VHDL component instantiations.
+
+-- Ignore Cast expressions, they should not longer have any meaning as long as
+-- the type works out.
+mkConcSm (bndr, Cast expr ty) = mkConcSm (bndr, expr)
+
mkConcSm (bndr, app@(CoreSyn.App _ _))= do
let (CoreSyn.Var f, args) = CoreSyn.collectArgs app
let valargs' = filter isValArg args