module Flite.InterpFrontend (frontend) where import Flite.Syntax import Flite.Traversals import Flite.ConcatApp import Flite.Matching import Flite.Case import Flite.Let import Flite.Identify import Flite.Inline import Flite.Fresh import Control.Monad frontend :: InlineFlag -> Prog -> Prog frontend i p = snd (runFresh (frontendM i p) "$" 0) frontendM :: InlineFlag -> Prog -> Fresh Prog frontendM i p = return (identifyFuncs p) >>= desugarCase >>= desugarEqn >>= inlineLinearLet >>= inlineSimpleLet >>= return . caseElim >>= return . concatApps >>= inlineTop i >>= liftLet >>= return . finalPass finalPass :: Prog -> Prog finalPass = map freshen where freshen (Func f args rhs) = Func f (map Var args') (mkLet bs' e') where n = length args args' = map (('v':) . show) [0..n-1] (bs, e) = body rhs (vs, es) = unzip bs ws = map (('v':) . show) [n..n+length vs-1] from = map var args ++ vs to = args' ++ ws (e':es') = foldr (\(v, w) -> map (subst (Var w) v)) (e:es) (zip from to) bs' = zip ws es' var (Var v) = v body (Let bs e) = (bs, e) body e = ([], e) mkLet [] e = e mkLet bs e = Let bs e