{-# LANGUAGE TypeOperators #-} module Functions.Mono where import DataTypes.Mono import Data.Comp import Data.Comp.MacroAutomata import Data.Comp.Automata import Data.Comp.Mapping import Data.Map (Map) import qualified Data.Map as Map pathAnnTrans :: (Functor g, Traversable g) => DownTrans g [Int] (g :&: [Int]) pathAnnTrans q t = simpCxt (fmap (\ (Numbered n s) -> s (n:q)) (number t) :&: q) -- Inlining inlineTrans :: MacroTrans' ArithLet (Map Var) ArithLet inlineTrans m (Var v) = case Map.lookup v m of Nothing -> iVar v Just e -> e inlineTrans m (Let v x y) = y (Map.insert v (x m) m) inlineTrans m f = Term $ fmap ($ m) f inlineTransExplicit :: MacroTrans ArithLet (Map Var) ArithLet inlineTransExplicit m (Var v) = case Map.lookup v m of Nothing -> iVar v Just e -> Hole e inlineTransExplicit m (Let v x y) = Hole $ y (Map.insert v (Hole $ x m') m') where m' = fmap Hole m inlineTransExplicit m (Add x y) = iAdd (Hole $ x m') (Hole $ y m') where m' = fmap Hole m inlineTransExplicit m (Mult x y) = iMult (Hole $ x m') (Hole $ y m') where m' = fmap Hole m inlineTransExplicit m (Sub x y) = iSub (Hole $ x m') (Hole $ y m') where m' = fmap Hole m inlineTransExplicit _ (Val n) = iVal n inlineAnnFuse :: Term ArithLet -> Term (ArithLet :&: [Int]) inlineAnnFuse t = runMacroTrans (compMacroDown (propAnnMacro inlineTransExplicit) pathAnnTrans) (Map.empty :&: []) t inlineAnnImpFuse :: Term ArithLet -> Term (ArithLet :&: [Int]) inlineAnnImpFuse t = runMacroTrans (compMacroDown (propAnnMacro $ mkMacroTrans inlineTrans) pathAnnTrans) (Map.empty :&: []) t inlineAnnSeq :: Term ArithLet -> Term (ArithLet :&: [Int]) inlineAnnSeq t = runMacroTrans (propAnnMacro inlineTransExplicit) Map.empty (runDownTrans pathAnnTrans [] t) inlineAnnImpSeq :: Term ArithLet -> Term (ArithLet :&: [Int]) inlineAnnImpSeq t = runMacroTrans (propAnnMacro $ mkMacroTrans inlineTrans) Map.empty (runDownTrans pathAnnTrans [] t) annInlineFuse :: Term ArithLet -> Term (ArithLet :&: [Int]) annInlineFuse t = runMacroTrans (compDownMacro pathAnnTrans inlineTransExplicit) (Map.empty :^: []) t annInlineImpFuse :: Term ArithLet -> Term (ArithLet :&: [Int]) annInlineImpFuse t = runMacroTrans (compDownMacro pathAnnTrans (mkMacroTrans inlineTrans)) (Map.empty :^: []) t annInlineSeq :: Term ArithLet -> Term (ArithLet :&: [Int]) annInlineSeq t = runDownTrans pathAnnTrans [] (runMacroTrans inlineTransExplicit Map.empty t) annInlineImpSeq :: Term ArithLet -> Term (ArithLet :&: [Int]) annInlineImpSeq t = runDownTrans pathAnnTrans [] (runMacroTrans (mkMacroTrans inlineTrans) Map.empty t) -- Code generator compTrans :: MacroTransId' ArithExc Code compTrans q (Val' n) = iPUSH n q compTrans q (Add' x y) = x $ y $ iADD q compTrans _ Throw = iTHROW compTrans q (Catch x h) = iMARK (h q) (x $ iUNMARK q) compAnnFuse :: Term ArithExc -> Term (Code :&: [Int]) compAnnFuse t = runMacroTrans (compMacroDown (propAnnMacro $ fromMacroTransId' compTrans) pathAnnTrans ) (I (ann [] iNIL) :&: []) t compAnnSeq :: Term ArithExc -> Term (Code :&: [Int]) compAnnSeq t = runMacroTrans (propAnnMacro $ fromMacroTransId' compTrans) (I (ann [] iNIL)) (runDownTrans pathAnnTrans [] t) annCompFuse :: Term ArithExc -> Term (Code :&: [Int]) annCompFuse t = runMacroTrans (compDownMacro pathAnnTrans (fromMacroTransId' compTrans)) (I (`ann` iNIL) :^: []) t annCompSeq :: Term ArithExc -> Term (Code :&: [Int]) annCompSeq t = runDownTrans pathAnnTrans [] (runMacroTrans (fromMacroTransId' compTrans) (I iNIL) t)