X-Git-Url: https://git.stderr.nl/gitweb?a=blobdiff_plain;f=NormalizeTools.hs;h=f016cfa9fc34684604a8efe487ac8f254297d5c3;hb=969b7ddd86b69d2fc61b101961affcca0364749c;hp=c36d85f2006f54aa84632c54afb4a9f40ce45efb;hpb=b5fe532686b527c92994415c1e7e287d33861242;p=matthijs%2Fmaster-project%2Fc%CE%BBash.git diff --git a/NormalizeTools.hs b/NormalizeTools.hs index c36d85f..f016cfa 100644 --- a/NormalizeTools.hs +++ b/NormalizeTools.hs @@ -7,6 +7,7 @@ module NormalizeTools where import Debug.Trace import qualified List import qualified Data.Monoid as Monoid +import qualified Control.Arrow as Arrow import qualified Control.Monad as Monad import qualified Control.Monad.Trans.State as State import qualified Control.Monad.Trans.Writer as Writer @@ -74,6 +75,17 @@ cloneVar v = do -- contains, but vannillaIdInfo is always correct, since it means "no info"). return $ Var.lazySetVarIdInfo (Var.setVarUnique v uniq) IdInfo.vanillaIdInfo +-- Creates a new function with the same name as the given binder (but with a +-- new unique) and with the given function body. Returns the new binder for +-- this function. +mkFunction :: CoreBndr -> CoreExpr -> TransformMonad CoreBndr +mkFunction bndr body = do + let ty = CoreUtils.exprType body + id <- cloneVar bndr + let newid = Var.setVarType id ty + Trans.lift $ addGlobalBind newid body + return newid + -- Apply the given transformation to all expressions in the given expression, -- including the expression itself. everywhere :: (String, Transform) -> Transform @@ -107,6 +119,11 @@ subeverywhere trans (App a b) = do b' <- trans b return $ App a' b' +subeverywhere trans (Let (NonRec b bexpr) expr) = do + bexpr' <- trans bexpr + expr' <- trans expr + return $ Let (NonRec b bexpr') expr' + subeverywhere trans (Let (Rec binds) expr) = do expr' <- trans expr binds' <- mapM transbind binds @@ -130,26 +147,33 @@ subeverywhere trans (Case scrut b t alts) = do 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 @@ -191,8 +215,21 @@ mkUnique = Trans.lift $ do -- Replace each of the binders given with the coresponding expressions in the -- given expression. substitute :: [(CoreBndr, CoreExpr)] -> CoreExpr -> CoreExpr -substitute replace expr = CoreSubst.substExpr subs expr - where subs = foldl (\s (b, e) -> CoreSubst.extendSubst s b e) CoreSubst.emptySubst replace +substitute [] expr = expr +-- Apply one substitution on the expression, but also on any remaining +-- substitutions. This seems to be the only way to handle substitutions like +-- [(b, c), (a, b)]. This means we reuse a substitution, which is not allowed +-- according to CoreSubst documentation (but it doesn't seem to be a problem). +-- TODO: Find out how this works, exactly. +substitute ((b, e):subss) expr = substitute subss' expr' + where + -- Create the Subst + subs = (CoreSubst.extendSubst CoreSubst.emptySubst b e) + -- Apply this substitution to the main expression + expr' = CoreSubst.substExpr subs expr + -- Apply this substitution on all the expressions in the remaining + -- substitutions + subss' = map (Arrow.second (CoreSubst.substExpr subs)) subss -- Run a given TransformSession. Used mostly to setup the right calls and -- an initial state.