packages feed

cao-0.1: src/Language/CAO/Typechecker/Heap.hs

{-# LANGUAGE PatternGuards #-}
{- |
Module      :  $Header$
Description :  Heap for type checking.
Copyright   :  (c) SMART Team / HASLab
License     :  GPL

Maintainer  :  Paulo Silva <paufil@di.uminho.pt>
Stability   :  experimental
Portability :  non-portable

Heap for type checking.
-}

module Language.CAO.Typechecker.Heap 
    ( Heap
    , emptyHeap
    , lookupGlobalName
    , insertLocalName
    , lookupName
    , lookupLocalName
    , containsName
    , replaceGlobalHeap
    , insertGlobalName
    , insertConstName
    , lookupConstName
    , Name
    , addHyp
    , getHyp
    , getIndexes
 ) where

import Control.Monad

import Data.Map (Map)
import qualified Data.Map as Map

import Language.CAO.Index

import Language.CAO.Common.Var

-------------------------------------------------------------------------------
-- Heap
-------------------------------------------------------------------------------

-- Heap data type -------------------------------------------------------------

data Heap = Heap 
    { globalHeap :: Map Name Var
    , localHeap  :: Map Name Var
    , constsHeap :: Map Name Integer
    , hypothesis :: [ICond Var]
    }

-- Heap manipulation routines --------------------------------------------------

emptyHeap :: Heap
emptyHeap = Heap Map.empty Map.empty Map.empty []

containsName :: Heap -> Name -> Bool
containsName h x =  containsLocalName h x || containsGlobalName h x

lookupName :: Heap -> Name -> Maybe Var
lookupName h x = lookupLocalName h x `mplus` lookupGlobalName h x

replaceGlobalHeap :: Heap -> Heap -> Heap
replaceGlobalHeap h nh = h { globalHeap = globalHeap nh }

-- Global variables -----------------------------------------------------------

{-# INLINE containsGlobalName #-}
containsGlobalName :: Heap -> Name -> Bool
containsGlobalName h x = Map.member x (globalHeap h)

{-# INLINE lookupGlobalName #-}
lookupGlobalName :: Heap -> Name -> Maybe Var
lookupGlobalName h v = Map.lookup v (globalHeap h)

{-# INLINE insertGlobalName #-}
insertGlobalName :: Heap -> Var -> Heap
insertGlobalName h v = 
    h { globalHeap = Map.insert (varName v) v (globalHeap h) }

-- Local variables ------------------------------------------------------------

{-# INLINE containsLocalName #-}
containsLocalName :: Heap -> Name -> Bool
containsLocalName h x = Map.member x (localHeap h)

{-# INLINE lookupLocalName #-}
lookupLocalName :: Heap -> Name -> Maybe Var
lookupLocalName h v = Map.lookup v (localHeap h)

{-# INLINE insertLocalName #-}
insertLocalName :: Heap -> Var -> Heap
insertLocalName h v = 
    h { localHeap = Map.insert (varName v) v (localHeap h) }

-- Constants ------------------------------------------------------------------

{-# INLINE lookupConstName #-}
lookupConstName :: Heap -> Name -> Maybe Integer
lookupConstName h v = Map.lookup v (constsHeap h)

{-# INLINE insertConstName #-}
insertConstName :: Heap -> Name -> Integer -> Heap
insertConstName h x a = h { constsHeap = Map.insert x a (constsHeap h)}

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

-- Hypothesis

{-# INLINE addHyp #-}
addHyp :: Heap -> [ICond Var] -> Heap
addHyp h i = h { hypothesis = i ++ hypothesis h }

{-# INLINE getHyp #-}
getHyp :: Heap -> [ICond Var]
getHyp = hypothesis

getIndexes :: Heap -> [Var]
getIndexes h = filter indVar $ Map.elems (globalHeap h) ++ Map.elems (localHeap h)