Repository : ssh://darcs.haskell.org//srv/darcs/ghc On branch : supercompiler
http://hackage.haskell.org/trac/ghc/changeset/a0e161356f2eaecbe751fe90592637036aa94382 >--------------------------------------------------------------- commit a0e161356f2eaecbe751fe90592637036aa94382 Author: Max Bolingbroke <batterseapo...@hotmail.com> Date: Wed Jan 18 18:03:55 2012 +0000 Checkpoint adding exceptions to Process3 >--------------------------------------------------------------- .../supercompile/Supercompile/Drive/Process3.hs | 40 ++++++++++++++++++- 1 files changed, 37 insertions(+), 3 deletions(-) diff --git a/compiler/supercompile/Supercompile/Drive/Process3.hs b/compiler/supercompile/Supercompile/Drive/Process3.hs index b7397ed..9b21a99 100644 --- a/compiler/supercompile/Supercompile/Drive/Process3.hs +++ b/compiler/supercompile/Supercompile/Drive/Process3.hs @@ -1,4 +1,4 @@ -{-# LANGUAGE GeneralizedNewtypeDeriving #-} +{-# LANGUAGE GeneralizedNewtypeDeriving, RankNTypes #-} module Supercompile.Drive.Process3 (supercompile) where import Supercompile.Drive.Match @@ -29,6 +29,7 @@ import FastString (mkFastString) import Control.Monad (join) +import Data.Function (on) import qualified Data.Map as M import Data.Monoid (mempty) @@ -116,8 +117,10 @@ data ScpEnv = ScpEnv { scpTagAnnotations :: TagAnnotations } +type ScpResType = (FVedTerm, ScpState) + newtype ScpM a = ScpM { unScpM :: StateT ScpState - (ReaderT ScpEnv Identity) a } + (ReaderT ScpEnv (ContT ScpResType Identity)) a } deriving (Functor, Applicative, Monad) instance MonadStatics ScpM where @@ -133,11 +136,42 @@ runScpM tag_anns me = fvedTermSize e' `seq` trace ("Deepest path:\n" ++ showSDoc hist = pROCESS_HISTORY fs = FS { fulfilments = [] } parent = generatedKey hist - (e, s') = unI $ unReaderT (unStateT (unScpM me) (ScpState ms hist fs emptyResidTags emptyParentChildren)) (ScpEnv 0 parent [] nothingSpeculated tag_anns) + (e, s') = unI $ runContT $ unReaderT (unStateT (unScpM me) (ScpState ms hist fs emptyResidTags emptyParentChildren)) (ScpEnv 0 parent [] nothingSpeculated tag_anns) fulfils = fulfilments (scpFulfilmentState s') e' = letRec fulfils e +callCCM :: ((forall b. a -> ScpM b) -> ScpM a) -> ScpM a +callCCM act = ScpM $ StateT $ \s -> ReaderT $ \env -> callCC (\jump_back -> unReaderT (unStateT (unScpM (act (\a -> ScpM $ StateT $ \s' -> ReaderT $ \_ -> jump_back (a, s' `rolledBackTo` s)))) s) env) + +catchM :: ((forall b. c -> ScpM b) -> ScpM a) -- ^ Action to try: supplies a function than can be called to "raise an exception". Raising an exception restores the original ScpEnv and ScpState + -> (c -> ScpM a) -- ^ Handler deferred to if an exception is raised + -> ScpM a -- ^ Result from either the main action or the handler +catchM try handler = do + ei_exc_res <- callCCM $ \jump_back -> fmap Right (try (jump_back . Left)) + case ei_exc_res of + Left exc -> handler exc + Right res -> return res + +rolledBackTo :: ScpState -> ScpState -> ScpState +rolledBackTo s s' = ScpState { + scpMemoState = MS { + promises = promises (scpMemoState s), + hNames = hNames (scpMemoState s') + }, + scpProcessHistory = scpProcessHistory s, + scpFulfilmentState = FS { + fulfilments = ((\funs' funs -> pruneFulfilments (fulfilments (scpFulfilmentState s')) (funs' `minusVarSet` funs)) `on` (mkVarSet . map fun . promises . scpMemoState)) s' s + }, + scpResidTags = scpResidTags s', -- FIXME: not totally accurate + scpParentChildren = scpParentChildren s' + } + where + pruneFulfilments fulfilments rolled_back + | null dump = fulfilments + | otherwise = pruneFulfilments keep (rolled_back `unionVarSet` mkVarSet (map fst dump)) + where (dump, keep) = partition (\(_, e) -> fvedTermFreeVars e `intersectsVarSet` rolled_back) fulfilments + scpDepth :: ScpEnv -> Int scpDepth = length . scpParents _______________________________________________ Cvs-ghc mailing list Cvs-ghc@haskell.org http://www.haskell.org/mailman/listinfo/cvs-ghc