mirror of
https://github.com/thma/LtuPatternFactory.git
synced 2024-11-30 02:03:47 +03:00
clean up Aspects example
This commit is contained in:
parent
866f5b3ac5
commit
e6a142138c
@ -35,6 +35,8 @@ executable LtuPatternFactory
|
||||
, DependencyInjection
|
||||
, CheapskateRenderer
|
||||
, CMarkGFMRenderer
|
||||
, AspectPascal
|
||||
, MiniPascal
|
||||
|
||||
main-is: Main.hs
|
||||
default-language: Haskell2010
|
||||
@ -74,6 +76,8 @@ test-suite LtuPatternFactory-Demo
|
||||
, DependencyInjection
|
||||
, CheapskateRenderer
|
||||
, CMarkGFMRenderer
|
||||
, AspectPascal
|
||||
, MiniPascal
|
||||
|
||||
hs-source-dirs: src
|
||||
main-is: Main.hs
|
||||
|
@ -1,11 +1,12 @@
|
||||
{-# LANGUAGE FlexibleContexts #-}
|
||||
module Aspects1 where
|
||||
module AspectPascal where
|
||||
import Control.Monad.Reader
|
||||
import Control.Monad.State
|
||||
import Control.Monad.Writer
|
||||
import Data.Map (Map, fromList)
|
||||
import qualified Data.Map as Map (lookup, insert)
|
||||
import Aspects (Id, IExp (..), BExp (..), Stmt (..), Store (..), program, lookup', demo, getVar, setVar)
|
||||
import Data.Map (Map)
|
||||
import qualified Data.Map as Map (lookup, insert, fromList)
|
||||
import MiniPascal (Id, IExp (..), BExp (..), Stmt (..), Store (..)
|
||||
, program, demo, getVar, setVar)
|
||||
|
||||
data JoinPointDesc = Get Id | Set Id
|
||||
|
||||
@ -29,15 +30,16 @@ includes _ _ = False
|
||||
data Advice = Before PointCut Stmt
|
||||
| After PointCut Stmt
|
||||
|
||||
-- the countSets Advice traces each setting of a variable and increments the counter "setters"
|
||||
countSets = After ((Setter :&&: (NotAt (AtVar "setters"))) :&&: (NotAt (AtVar "getters")))
|
||||
("setters" := (IVar "setters" :+: Lit 1))
|
||||
|
||||
-- the countGets Advice traces each lookup of a variable and increments the counter "getters"
|
||||
countGets = After ((Getter :&&: (NotAt (AtVar "setters"))) :&&: (NotAt (AtVar "getters")))
|
||||
("getters" := (IVar "getters" :+: Lit 1))
|
||||
|
||||
type Aspects = [Advice]
|
||||
|
||||
|
||||
iexp :: IExp -> ReaderT Aspects (State Store) Int
|
||||
iexp (Lit n) = return n
|
||||
iexp (e1 :+: e2) = liftM2 (+) (iexp e1) (iexp e2)
|
||||
@ -68,6 +70,7 @@ stmt (While b t) = loop
|
||||
x <- bexp b
|
||||
when x $ stmt t >> loop
|
||||
|
||||
withAdvice :: JoinPointDesc -> ReaderT Aspects (State Store) b -> ReaderT Aspects (State Store) b
|
||||
withAdvice d c = do
|
||||
aspects <- ask
|
||||
mapM_ stmt (before d aspects)
|
||||
@ -79,12 +82,11 @@ before, after :: JoinPointDesc -> Aspects -> [Stmt]
|
||||
before d as = [s | Before c s <- as, includes c d]
|
||||
after d as = [s | After c s <- as, includes c d]
|
||||
|
||||
|
||||
run :: Aspects -> Stmt -> Store
|
||||
run a s = execState (runReaderT (stmt s) a) (fromList [])
|
||||
run a s = execState (runReaderT (stmt s) a) (Map.fromList [])
|
||||
|
||||
aspects1Demo :: IO ()
|
||||
aspects1Demo = do
|
||||
aspectPascalDemo :: IO ()
|
||||
aspectPascalDemo = do
|
||||
putStrLn "Aspect Weaving -> Monad Transformers"
|
||||
demo (run [countSets] program)
|
||||
demo (run [countGets] program)
|
@ -17,6 +17,8 @@ import Strategy
|
||||
import TemplateMethod
|
||||
import Visitor
|
||||
import MapReduce
|
||||
import MiniPascal
|
||||
import AspectPascal
|
||||
|
||||
main :: IO ()
|
||||
main = do
|
||||
@ -37,3 +39,5 @@ main = do
|
||||
interpreterDemo
|
||||
infinityDemo
|
||||
mapReduceDemo
|
||||
miniPascalDemo
|
||||
aspectPascalDemo
|
@ -1,12 +1,13 @@
|
||||
{-# LANGUAGE FlexibleContexts #-}
|
||||
module Aspects where
|
||||
module MiniPascal where
|
||||
import Control.Monad.Reader
|
||||
import Control.Monad.State
|
||||
import Control.Monad.Writer
|
||||
import Data.Map (Map, fromList, assocs)
|
||||
import qualified Data.Map as Map (lookup, insert)
|
||||
import Interpreter hiding (eval)
|
||||
import Data.Map (Map)
|
||||
import qualified Data.Map as Map (lookup, insert, fromList, assocs)
|
||||
import Interpreter (Exp (..), Env (..), letExp, fetch)
|
||||
|
||||
-- adding a logging capability to the expression evaluator
|
||||
eval :: Show a => Exp a -> WriterT [String] (Reader (Env a)) a
|
||||
eval (Var x) = tell ["lookup " ++ x] >> asks (fetch x)
|
||||
eval (Val i) = tell [show i] >> return i
|
||||
@ -41,6 +42,8 @@ data Stmt = Skip
|
||||
| If BExp Stmt Stmt
|
||||
| While BExp Stmt deriving (Show)
|
||||
|
||||
-- an example program: the MiniPascal equivalent of `sum [1..10]`
|
||||
program :: Stmt
|
||||
program =
|
||||
Begin [
|
||||
"total" := Lit 0,
|
||||
@ -54,9 +57,6 @@ program =
|
||||
|
||||
type Store = Map Id Int
|
||||
|
||||
lookup' :: Ord a => Map a b -> a -> Maybe b
|
||||
lookup' = flip Map.lookup
|
||||
|
||||
iexp :: IExp -> State Store Int
|
||||
iexp (Lit n) = return n
|
||||
iexp (e1 :+: e2) = liftM2 (+) (iexp e1) (iexp e2)
|
||||
@ -95,19 +95,19 @@ setVar i x = do
|
||||
getVar :: MonadState Store m => Id -> m Int
|
||||
getVar i = do
|
||||
s <- get
|
||||
case lookup' s i of
|
||||
case Map.lookup i s of
|
||||
Nothing -> return 0
|
||||
(Just v) -> return v
|
||||
|
||||
|
||||
run :: Stmt -> Store
|
||||
run s = execState (stmt s) (fromList [])
|
||||
run s = execState (stmt s) (Map.fromList [])
|
||||
|
||||
demo :: Store -> IO ()
|
||||
demo store = print (assocs store)
|
||||
demo store = print (Map.assocs store)
|
||||
|
||||
aspectsDemo :: IO ()
|
||||
aspectsDemo = do
|
||||
miniPascalDemo :: IO ()
|
||||
miniPascalDemo = do
|
||||
putStrLn "Aspect Weaving -> Monad Transformers"
|
||||
let env = [("pi", pi)]
|
||||
print $ runReader (runWriterT (eval letExp)) env
|
Loading…
Reference in New Issue
Block a user