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..n1]
(bs, e) = body rhs
(vs, es) = unzip bs
ws = map (('v':) . show) [n..n+length vs1]
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