Subversion

Galculator

?curdirlinks? - Rev 5

?prevdifflink? - Blame



{-# LANGUAGE FlexibleContexts #-}
{-# OPTIONS_GHC -Wall #-}

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

{- |
Module      :  Language.R.Verify
Description :  Validation of the uniqueness of definitions and the existence
               of references.
Copyright   :  (c) Paulo Silva
License     :  LGPL

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

-}


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

module Language.R.Verify (
  verify,
  getDefs,
  replaceDefs,
  Env'(..),
  ExtEnv,
  reps
 ) where

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

import Control.GalcError
import Control.Monad.Error
import Control.Monad.Reader
import Control.Monad.State
import Data.Env
import Data.List
import Language.R.Syntax
import Language.R.SyntaxADT

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

-- ========
type ExtEnv = Env RType
type IntEnv = Env S
data Env' = Env' {internal :: IntEnv, external :: ExtEnv }


reps :: Ord a => [a] -> [a]
reps = map head . filter ((>1) . length ) . group . sort
-- ========
-------------------------------------------------------------------------------

verify :: MonadError GalcError m => ExtEnv -> S -> m S
verify extEnv s = let
    env = getDefs s
    ids = reps $ indexes extEnv ++ map fst env
  in if null ids
     then runReaderT (replaceDefs s) $ Env' {internal = fromListEnv env,
                                             external = extEnv }
     else throwError $ MultiDefError . concatMap ((++"\n") . show) $ ids

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

getDefs :: S -> [(String, S)]
getDefs d@(DefS _ n _) = [(n,d)]
getDefs g@(GDefS _ n f1 f2 o1 o2) =
  (n,g) : getDefs f1 ++ getDefs f2 ++ getDefs o1 ++ getDefs o2
getDefs (MeetS _ s1 s2) = getDefs s1 ++ getDefs s2
getDefs (JoinS _ s1 s2) =  getDefs s1 ++ getDefs s2
getDefs (ConvS _ s) = getDefs s
getDefs (CompS _ s1 s2) = getDefs s1 ++ getDefs s2
getDefs (SplitS _ s1 s2) = getDefs s1 ++ getDefs s2
getDefs (OrdS _ s) = getDefs s
getDefs (FunS _ s) = getDefs s  
getDefs (LeftsecS _ s1 s2) = getDefs s1 ++ getDefs s2
getDefs (RightsecS _ s1 s2) = getDefs s1 ++ getDefs s2
getDefs (ApplyS _ s1 s2) = getDefs s1 ++ getDefs s2
getDefs (ProdS _ s1 s2) = getDefs s1 ++ getDefs s2
getDefs (EitherS _ s1 s2) = getDefs s1 ++ getDefs s2
getDefs (MaybeS _ s) = getDefs s  
getDefs (ListS _ s) = getDefs s  
getDefs (SetS _ s) = getDefs s  
getDefs (MapS _ s) = getDefs s  
getDefs (ReynoldsS _ s1 s2) = getDefs s1 ++ getDefs s2
getDefs (FCompS _ s1 s2) = getDefs s1 ++ getDefs s2
getDefs (OCompS _ s1 s2) = getDefs s1 ++ getDefs s2
getDefs (OConvS _ s) = getDefs s
getDefs (OProdS _ s) = getDefs s
getDefs (OJoinS _ s) = getDefs s
getDefs (OMeetS _ s) = getDefs s
getDefs (OMaxS _ s) = getDefs s
getDefs (OMinS _ s) = getDefs s
getDefs (GCompS _ s1 s2) = getDefs s1 ++ getDefs s2
getDefs (GConvS _ s) = getDefs s
getDefs (GLAdjS _ s) = getDefs s
getDefs (GUAdjS _ s) = getDefs s
getDefs (GLOrdS _ s) = getDefs s
getDefs (GUOrdS _ s) = getDefs s
getDefs _ = []

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

replaceDefs :: (MonadError GalcError m, MonadReader Env' m)
            => S -> m S
replaceDefs (RefS p n) = do -- TODO position in the substitution
  extEnv <- asks external
  maybe (maybe (throwError $ ReferenceError n) (return . RefExtS p) .
         lookupEnv n $ extEnv)
         return . lookupEnv n =<< asks internal
replaceDefs (NegS p s) = do
 s' <- replaceDefs s
 return $ NegS p s'
replaceDefs (MeetS p s1 s2) = do
 s1' <- replaceDefs s1
 s2' <- replaceDefs s2
 return $ MeetS p s1' s2'
replaceDefs (JoinS p s1 s2) = do
 s1' <- replaceDefs s1
 s2' <- replaceDefs s2
 return $ JoinS p s1' s2'
replaceDefs (ConvS p s) = do
 s' <- replaceDefs s
 return $ ConvS p s'
replaceDefs (CompS p s1 s2) = do
 s1' <- replaceDefs s1
 s2' <- replaceDefs s2
 return $ CompS p s1' s2'
replaceDefs (SplitS p s1 s2) = do
 s1' <- replaceDefs s1
 s2' <- replaceDefs s2
 return $ SplitS p s1' s2'
replaceDefs (OrdS p s) = do
 s' <- replaceDefs s
 return $ OrdS p s'
replaceDefs (FunS p s) = do
 s' <- replaceDefs s
 return $ FunS p s'
replaceDefs (LeftsecS p s1 s2) = do
 s1' <- replaceDefs s1
 s2' <- replaceDefs s2
 return $ LeftsecS p s1' s2'
replaceDefs (RightsecS p s1 s2) = do
 s1' <- replaceDefs s1
 s2' <- replaceDefs s2
 return $ RightsecS p s1' s2'
replaceDefs (ApplyS p s1 s2) = do
 s1' <- replaceDefs s1
 s2' <- replaceDefs s2
 return $ ApplyS p s1' s2'
replaceDefs (ProdS p s1 s2) = do
 s1' <- replaceDefs s1
 s2' <- replaceDefs s2
 return $ ProdS p s1' s2'
replaceDefs (EitherS p s1 s2) = do
 s1' <- replaceDefs s1
 s2' <- replaceDefs s2
 return $ EitherS p s1' s2'
replaceDefs (MaybeS p s) = do
 s' <- replaceDefs s
 return $ MaybeS p s'
replaceDefs (ListS p s) = do
 s' <- replaceDefs s
 return $ ListS p s'
replaceDefs (SetS p s) = do
 s' <- replaceDefs s
 return $ SetS p s'
replaceDefs (MapS p s) = do
 s' <- replaceDefs s
 return $ MapS p s'
replaceDefs (ReynoldsS p s1 s2) = do
 s1' <- replaceDefs s1
 s2' <- replaceDefs s2
 return $ ReynoldsS p s1' s2'
replaceDefs (FCompS p s1 s2) = do
 s1' <- replaceDefs s1
 s2' <- replaceDefs s2
 return $ FCompS p s1' s2'
replaceDefs (OCompS p s1 s2) = do
 s1' <- replaceDefs s1
 s2' <- replaceDefs s2
 return $ OCompS p s1' s2'
replaceDefs (OConvS p s) = do
 s' <- replaceDefs s
 return $ OConvS p s'
replaceDefs (OProdS p s) = do
 s' <- replaceDefs s
 return $ OProdS p s'
replaceDefs (OJoinS p s) =  do
 s' <- replaceDefs s
 return $ OJoinS p s'
replaceDefs (OMeetS p s) = do
 s' <- replaceDefs s
 return $ (OMeetS p s')
replaceDefs (OMaxS p s) = do
 s' <- replaceDefs s
 return $ (OMaxS p s')
replaceDefs (OMinS p s) = do
 s' <- replaceDefs s
 return $ (OMinS p s')
replaceDefs (GDefS p n f1 f2 o1 o2) = do
  f1' <- replaceDefs f1
  f2' <- replaceDefs f2
  o1' <- replaceDefs o1
  o2' <- replaceDefs o2
  return $ GDefS p n f1' f2' o1' o2'
replaceDefs (GCompS p s1 s2) = do
 s1' <- replaceDefs s1
 s2' <- replaceDefs s2
 return $ GCompS p s1' s2'
replaceDefs (GConvS p s) = do
 s' <- replaceDefs s
 return $ GConvS p s'
replaceDefs (GLAdjS p s) = do
 s' <- replaceDefs s
 return $ GLAdjS p s'
replaceDefs (GUAdjS p s) = do
 s' <- replaceDefs s
 return $ GUAdjS p s'
replaceDefs (GLOrdS p s) = do
 s' <- replaceDefs s
 return $ GLOrdS p s'
replaceDefs (GUOrdS p s) = do
 s' <- replaceDefs s
 return $ GUOrdS p s'
replaceDefs s = return s

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

Theme by Vikram Singh | Powered by WebSVN v2.3.3