module E.Diff where
import E.E
import E.FreeVars()
import E.Traverse
import Stats
import Support.FreeVars
diff :: E -> E -> (E,E)
diff a b = f a b where
f (ELetRec ds e) (ELetRec ds' e') = (ELetRec (g ds ds') e, ELetRec (g ds' ds) e')
f a b = (a,b)
g ds ds' = [ d | d@(v,e) <- ds, not (lookup v ds' == Just e) ]
findOddFreeVars :: [TVr] -> E -> E
findOddFreeVars fs (ELetRec ds e) = ELetRec [ ds | ds@(_,e) <- ds, any (`elem` fs) (freeVars e) ] e
findOddFreeVars _ e = e
printEStats :: E -> IO ()
printEStats e = do
stats <- Stats.new
let f e@ELam {} = tick stats "lambda" >> emapE' f e
f e@EVar {} = tick stats "var-use" >> return e
f e@(ELetRec ds _) = ticks stats (length ds) "let-binding" >> emapE' f e
f e@EPi {} = tick stats "pi" >> emapE' f e
f e@ELit {} = tick stats "lit" >> emapE' f e
f e@EPrim {} = tick stats "prim" >> emapE' f e
f e@EError {} = tick stats "error" >> emapE' f e
f e@ECase {} = do
tick stats "case"
ticks stats (length $ caseBodies e) "case-alt"
emapE' f e
f e = tick stats "other" >> emapE' f e
f e
Stats.print "E" stats