|
| 1 | +{-# LANGUAGE GADTs #-} |
| 2 | +module LambdaComp.CBPV.Optimization.InlineBinding |
| 3 | + ( runInlineSimpleLet |
| 4 | + ) where |
| 5 | + |
| 6 | +import Control.Applicative (liftA3) |
| 7 | +import Control.Monad.Reader (MonadReader (local), Reader, asks, runReader) |
| 8 | +import Data.Map.Strict (Map) |
| 9 | +import Data.Map.Strict qualified as Map |
| 10 | +import Data.Maybe (fromMaybe) |
| 11 | + |
| 12 | +import LambdaComp.CBPV.Syntax |
| 13 | + |
| 14 | +runInlineSimpleLet :: Tm c -> Tm c |
| 15 | +runInlineSimpleLet = (`runReader` Map.empty) . inlineSimpleLet |
| 16 | + |
| 17 | +type WithSimpleBinding = Reader (Map Ident (Tm Val)) |
| 18 | + |
| 19 | +inlineSimpleLet :: Tm c -> WithSimpleBinding (Tm c) |
| 20 | +inlineSimpleLet tm@(TmVar x) = do |
| 21 | + mayTm' <- asks (Map.!? x) |
| 22 | + pure $ fromMaybe tm mayTm' |
| 23 | +inlineSimpleLet tm@TmUnit = pure tm |
| 24 | +inlineSimpleLet tm@TmTrue = pure tm |
| 25 | +inlineSimpleLet tm@TmFalse = pure tm |
| 26 | +inlineSimpleLet tm@(TmInt _) = pure tm |
| 27 | +inlineSimpleLet tm@(TmDouble _) = pure tm |
| 28 | +inlineSimpleLet (TmThunk tm) = TmThunk <$> inlineSimpleLet tm |
| 29 | +inlineSimpleLet (TmIf tm0 tm1 tm2) = liftA3 TmIf (inlineSimpleLet tm0) (inlineSimpleLet tm1) (inlineSimpleLet tm2) |
| 30 | +inlineSimpleLet (TmLam p tm) = TmLam p <$> local (Map.insert (paramName p) (TmVar (paramName p))) (inlineSimpleLet tm) |
| 31 | +inlineSimpleLet (tmf `TmApp` tma) = liftA2 TmApp (inlineSimpleLet tmf) (inlineSimpleLet tma) |
| 32 | +inlineSimpleLet (TmForce tm) = TmForce <$> inlineSimpleLet tm |
| 33 | +inlineSimpleLet (TmReturn tm) = TmReturn <$> inlineSimpleLet tm |
| 34 | +inlineSimpleLet (TmTo tm0 x tm1) = liftA3 TmTo (inlineSimpleLet tm0) (pure x) (local (Map.insert x (TmVar x)) $ inlineSimpleLet tm1) |
| 35 | +inlineSimpleLet (TmLet x tm0 tm1) = liftA2 (TmLet x) (inlineSimpleLet tm0) (local (Map.insert x xBinding) $ inlineSimpleLet tm1) |
| 36 | + where |
| 37 | + xBinding |
| 38 | + | isSimpleTm x tm0 = tm0 |
| 39 | + | otherwise = TmVar x |
| 40 | +inlineSimpleLet (TmPrimBinOp op tm0 tm1) = liftA2 (TmPrimBinOp op) (inlineSimpleLet tm0) (inlineSimpleLet tm1) |
| 41 | +inlineSimpleLet (TmPrimUnOp op tm) = TmPrimUnOp op <$> inlineSimpleLet tm |
| 42 | +inlineSimpleLet (TmPrintInt tm0 tm1) = liftA2 TmPrintInt (inlineSimpleLet tm0) (inlineSimpleLet tm1) |
| 43 | +inlineSimpleLet (TmPrintDouble tm0 tm1) = liftA2 TmPrintDouble (inlineSimpleLet tm0) (inlineSimpleLet tm1) |
| 44 | +inlineSimpleLet (TmRec p tm) = TmRec p <$> local (Map.insert (paramName p) (TmVar (paramName p))) (inlineSimpleLet tm) |
| 45 | + |
| 46 | +isSimpleTm :: Ident -> Tm Val -> Bool |
| 47 | +isSimpleTm x (TmVar y) = x /= y |
| 48 | +isSimpleTm _ TmUnit = True |
| 49 | +isSimpleTm _ TmTrue = True |
| 50 | +isSimpleTm _ TmFalse = True |
| 51 | +isSimpleTm _ (TmInt _) = True |
| 52 | +isSimpleTm _ (TmDouble _) = True |
| 53 | +isSimpleTm _ (TmThunk _) = False |
0 commit comments