HaRe-0.6: StrategyLib-4.0-beta/examples/joos-padl02/Extraction.hs
------------------------------------------------------------------------------
module Extraction where
import Monad
import StrategyLib hiding (replaceFocus)
import VarsAnalyses
import Datatypes
--- Method extraction --------------------------------------------------------
--- Main strategy ---
extractMethod :: (Term t, MonadPlus m) => t -> m t
extractMethod joos = applyTP (once_tdTP (monoTP extrMethFromCls)) joos
extrMethFromCls :: MonadPlus m => ClassDeclaration -> m ClassDeclaration
extrMethFromCls (ClassDecl fin nm sup fs cs ds)
= do (pars,body) <- ifLegalGetParsAndBody ds
ds' <- replaceFocus pars (ds++[constructMethod pars body])
return (ClassDecl fin nm sup fs cs ds')
--- Check legality and extract parameters and body ---
ifLegalGetParsAndBody :: (Term t, MonadPlus m)
=> t -> m ([([Char],Type)],Statement)
ifLegalGetParsAndBody ds
= applyTU (once_peTU [] appendLocals ifLegalGetParsAndBody1) ds
where ifLegalGetParsAndBody1 env
= getFocus `passTU` \s ->
ifthenTU (voidTP (isLegal env))
( freeUseVars env `passTU` \pars ->
constTU (pars,s) )
appendLocals env = op2TU appendMap (tryTU declVars) (constTU env)
--- Replace focussed statement with method invocation ---
replaceFocus :: (Term t, MonadPlus m) => [(Identifier,Type)] -> t -> m t
replaceFocus pars ds = applyTP (once_tdTP (replaceFocus1 pars)) ds
where replaceFocus1 pars = getFocus `passTP` \_ ->
monoTP (const (return (constructMethodCall pars)))
--- Legality check ---
isLegal :: MonadPlus m => [([Char],Type)] -> TP m
isLegal env = freeDefVars env `passTP` \env' ->
if null env' then notTU (once_tdTU getReturn) else failTP
--- Retreive focused statement ---
getFocus :: MonadPlus m => TU Statement m
getFocus = monoTU (\s -> case s of (StatFocus s') -> return s'
_ -> mzero )
--- Test for a return statement ---
getReturn :: MonadPlus m => TU (Maybe Expression) m
getReturn = monoTU (\s -> case s of (ReturnStat x) -> return x
_ -> mzero )
--- Code generattion ---
constructMethod :: [(Identifier,Type)] -> Statement -> MethodDeclaration
constructMethod pars body
= MethodDecl Nothing "newMethod"
(FormalParams fpars) (BlockStatements [] [body])
where fpars = map (\(v,t) -> FormalParam t v) pars
constructMethodCall :: [(Identifier,Type)] -> Statement
constructMethodCall pars
= MethodInvocationStat
(ExpressionInvocation This "newMethod" (Arguments args))
where args = map (\(v,t) -> Identifier v) pars
------------------------------------------------------------------------------