diff options
author | Tom Smeding <tom.smeding@gmail.com> | 2020-05-23 11:41:50 +0200 |
---|---|---|
committer | Tom Smeding <tom.smeding@gmail.com> | 2020-05-23 11:50:45 +0200 |
commit | 18ea7b6804e09b1ae604b7fb9eadd542677f172d (patch) | |
tree | fba6e312c635ef0b14191011b65b56699e4532cf | |
parent | 243f4f5b58014159be0c4dd7b0fc5c0a8021fd3c (diff) |
Only rewrite _free_ variables in rewall
-rw-r--r-- | src/Haskell/AST.hs | 19 | ||||
-rw-r--r-- | src/Main.hs | 10 |
2 files changed, 25 insertions, 4 deletions
diff --git a/src/Haskell/AST.hs b/src/Haskell/AST.hs index 072fd97..2238b6d 100644 --- a/src/Haskell/AST.hs +++ b/src/Haskell/AST.hs @@ -1,6 +1,7 @@ module Haskell.AST where import Data.List +import qualified Data.Set as Set import Pretty @@ -134,3 +135,21 @@ instance AllRefs Expr where instance AllRefs Inst where allRefs (Inst _ _ ds) = nub $ concatMap allRefs ds + + +boundVars :: Pat -> Set.Set Name +boundVars PatAny = mempty +boundVars (PatVar n) = Set.singleton n +boundVars (PatCon _ ps) = Set.unions (map boundVars ps) +boundVars (PatTup ps) = Set.unions (map boundVars ps) + +freeVariables :: Expr -> Set.Set Name +freeVariables (App e es) = freeVariables e <> Set.unions (map freeVariables es) +freeVariables (Ref n) = Set.singleton n +freeVariables (Con _) = mempty +freeVariables (Num _) = mempty +freeVariables (Tup es) = Set.unions (map freeVariables es) +freeVariables (Lam ns e) = freeVariables e Set.\\ Set.fromList ns +freeVariables (Case e pairs) = + freeVariables e <> Set.unions [freeVariables e' Set.\\ boundVars p + | (p, e') <- pairs] diff --git a/src/Main.hs b/src/Main.hs index a6d80b3..f406f1b 100644 --- a/src/Main.hs +++ b/src/Main.hs @@ -3,6 +3,11 @@ module Main where import Control.Monad import Data.List import Data.Maybe +import qualified Data.Set as Set +import System.Environment +import System.Exit +import System.IO + import Haskell.AST import Haskell.Env import Haskell.Env.Cmd @@ -10,9 +15,6 @@ import Haskell.Env.Context import Haskell.Rewrite import Haskell.Parser import Pretty -import System.Environment -import System.Exit -import System.IO import Util @@ -115,7 +117,7 @@ applyUserCmd appstate = \case Just focus -> let nextStep ctx done = let orig = fromRight (get (topEnv ctx) focus) - in case filter (isRight . get (topEnv ctx)) $ allRefs orig \\ done of + in case filter (isRight . get (topEnv ctx)) $ Set.toList (freeVariables orig) \\ done of [] -> Right ctx (name:_) -> case apply ctx (Action (CRewrite name) focus) of Left err -> Left ("Error rewriting '" ++ name ++ "': " ++ err) |