Subversion

Galculator

?curdirlinks? - Rev 3

?prevdifflink? - Blame



{-# LANGUAGE GADTs, Rank2Types #-}
{-# OPTIONS_GHC -Wall #-}

-------------------------------------------------------------------------------

{- |
Module      :  Language.R.Rewrite
Description :  Strategic rewriting combinators for the expression
               representation.
Copyright   :  (c) Paulo Silva
License     :  LGPL

Maintainer  :  paufil@di.uminho.pt
Stability   :  experimental
Portability :  portable

-}


-------------------------------------------------------------------------------


module Language.R.Rewrite (
 GenericM,
 seqRules,
 nop,
 failM,
 (>>>),
 (|||),
 (|<|),
 many,
 many1,
 try,
 once,
 everywhere,
 everywhere',
 innermost,
 all,
 one
 ) where

import Control.MonadOr
import Control.Monad.State
import Language.R.Spine
import Language.R.Syntax
import Language.Type.Syntax
import Prelude hiding (all)

-------------------------------------------------------------------------------

type GenericM m = forall a . Type a -> R a -> m (R a)

-------------------------------------------------------------------------------

seqRules :: MonadOr m => [GenericM m] -> GenericM m
seqRules [] = failM
seqRules (x:xs) = x |<| seqRules xs

-------------------------------------------------------------------------------

nop :: Monad m => GenericM m
nop _ = return

-------------------------------------------------------------------------------

failM :: MonadPlus m => GenericM m
failM _ _ = mzero

-------------------------------------------------------------------------------

(>>>) :: Monad m => GenericM m -> GenericM m -> GenericM m
(f >>> g) t = f t >=> g t

-------------------------------------------------------------------------------

(|||) :: MonadPlus m => GenericM m -> GenericM m -> GenericM m
(f ||| g) t x = f t x `mplus` g t x

-------------------------------------------------------------------------------

(|<|) :: MonadOr m => GenericM m -> GenericM m -> GenericM m
(f |<| g) t x = f t x `morelse` g t x

-------------------------------------------------------------------------------

many :: MonadOr m => GenericM m -> GenericM m
many r = (r >>> many r) |<| nop

-------------------------------------------------------------------------------

many1 :: MonadOr m => GenericM m -> GenericM m
many1 r = r >>> many r

-------------------------------------------------------------------------------

try :: MonadOr m => GenericM m -> GenericM m
try x = x |<| nop

-------------------------------------------------------------------------------

once :: MonadOr m => GenericM m -> GenericM m
once f = f |<| one (once f)

-------------------------------------------------------------------------------

everywhere :: Monad m => GenericM m -> GenericM m
everywhere f = f >>> all (everywhere f)

-------------------------------------------------------------------------------

everywhere' :: Monad m => GenericM m -> GenericM m
everywhere' f = all (everywhere' f) >>> f

-------------------------------------------------------------------------------

innermost :: MonadOr m => GenericM m -> GenericM m
innermost f = all (innermost f) >>> try (f >>> innermost f)

-------------------------------------------------------------------------------

all :: Monad m => GenericM m -> GenericM m
all strg typ expr = do
  s <- aux strg (toSpine typ expr)
  return (fromSpine s)
  where
    aux :: Monad m => GenericM m -> (Spine a -> m (Spine a))
    aux _ x@(Constr _) = return x
    aux g (f `Ap` (t :| x)) = do
      h <- aux g f
      y <- g t x
      return (h `Ap` (t :| y))

-------------------------------------------------------------------------------

one :: MonadOr m => GenericM m -> GenericM m
one strg typ expr = do
  s <- aux strg (toSpine typ expr)
  return (fromSpine s)
  where
    aux :: MonadOr m => GenericM m -> (Spine a -> m (Spine a))
    aux _ (Constr _) = mzero
    aux g (f `Ap` (t :| x)) =
      (do h <- aux g f
          return $ h `Ap` (t :| x))
      `morelse`
      (do j <- g t x
          return $ f `Ap` (t :| j))

-------------------------------------------------------------------------------
 

Theme by Vikram Singh | Powered by WebSVN v2.3.3