diff options
| author | bringert <bringert@cs.chalmers.se> | 2005-12-09 13:06:05 +0000 |
|---|---|---|
| committer | bringert <bringert@cs.chalmers.se> | 2005-12-09 13:06:05 +0000 |
| commit | dc54207d3b49d05483f7dff718ae751970063784 (patch) | |
| tree | a77c121fbd626eaf264381eabed78db7c1e4e044 /src/Transfer/SyntaxToCore.hs | |
| parent | ccfe7fb119aa4aed9b971bd52f72ab0f54df1bf4 (diff) | |
Transfer compiler: rename variables before doing any substitutions.
Diffstat (limited to 'src/Transfer/SyntaxToCore.hs')
| -rw-r--r-- | src/Transfer/SyntaxToCore.hs | 65 |
1 files changed, 64 insertions, 1 deletions
diff --git a/src/Transfer/SyntaxToCore.hs b/src/Transfer/SyntaxToCore.hs index c73120878..32796eb50 100644 --- a/src/Transfer/SyntaxToCore.hs +++ b/src/Transfer/SyntaxToCore.hs @@ -37,7 +37,8 @@ declsToCore_ = deriveDecls >>> optimize optimize :: [Decl] -> C [Decl] -optimize = removeUselessMatch +optimize = uniqueVars + >>> removeUselessMatch >>> betaReduce newState :: CState @@ -46,6 +47,51 @@ newState = CState { nextMeta = 0 } + +-- +-- * Make all variable names unique +-- + +uniqueVars :: [Decl] -> C [Decl] +uniqueVars = mapM (f Map.empty) + where + f :: Map Ident Ident -> Tree a -> C (Tree a) + f ss t = case t of + ELet ds _ -> + do + let vs = Set.toList (letDefBinds ds) + vs' <- freshIdents (length vs) + let ss' = addToSubstEnv (zip vs vs') ss + composOpM (f ss') t + LetDef i e -> + case Map.lookup i ss of + Nothing -> fail $ "let var " ++ printTree i ++ " not renamed" + Just i' -> liftM (LetDef i') (f ss e) + Case p _ _ -> + do + let vs = Set.toList (binds p) + vs' <- freshIdents (length vs) + let ss' = addToSubstEnv (zip vs vs') ss + composOpM (f ss') t + EAbs (VVar i) e -> + do + i' <- freshIdent + let ss' = addToSubstEnv [(i,i')] ss + liftM (EAbs (VVar i')) (f ss' e) + EPi (VVar i) e1 e2 -> + do + i' <- freshIdent + let ss' = addToSubstEnv [(i,i')] ss + liftM2 (EPi (VVar i')) (f ss e1) (f ss' e2) + EVar i -> return $ case Map.lookup i ss of + Nothing -> t -- constructor + Just i' -> EVar i' + PVar i -> return $ case Map.lookup i ss of + Nothing -> t -- constructor + Just i' -> PVar i' + _ -> composOpM (f ss) t + where addToSubstEnv bs m = foldr (\ (k,v) -> Map.insert k v) m bs + -- -- * Number meta variables -- @@ -535,6 +581,7 @@ ifBool :: Exp -> Exp -> Exp -> Exp ifBool c t e = ECase c [Case (PCons (Ident "True") []) gtrue t, Case (PCons (Ident "False") []) gtrue e] + -- -- * Substitution -- @@ -542,6 +589,8 @@ ifBool c t e = ECase c [Case (PCons (Ident "True") []) gtrue t, subst :: Ident -> Exp -> Exp -> Exp subst x e = substs [(x,e)] + + -- | Simultaneuous substitution substs :: [(Ident, Exp)] -> Exp -> Exp substs ss = f (Map.fromList ss) @@ -549,6 +598,19 @@ substs ss = f (Map.fromList ss) f :: Map Ident Exp -> Tree a -> Tree a f ss t | Map.null ss = t f ss t = case t of + EVar i -> Map.findWithDefault t i ss + _ -> composOp (f ss) t + + +{- +-- not needed now that variable names are unique +-- FIXE: this function does not properly rename bound variables +substs :: [(Ident, Exp)] -> Exp -> Exp +substs ss = f (Map.fromList ss) + where + f :: Map Ident Exp -> Tree a -> Tree a + f ss t | Map.null ss = t + f ss t = case t of ELet ds e3 -> ELet [LetDef id (f ss' e2) | LetDef id e2 <- ds] (f ss' e3) where ss' = ss `mapMinusSet` letDefBinds ds @@ -558,6 +620,7 @@ substs ss = f (Map.fromList ss) EPi (VVar id) (f ss e1) (f ss' e2) where ss' = Map.delete id ss EVar i -> Map.findWithDefault t i ss _ -> composOp (f ss) t +-} -- -- * Abstract syntax utilities |
