{- CAO Compiler
Copyright (C) 2014 Cryptography and Information Security Group, HASLab - INESC TEC and Universidade do Minho
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see . -}
{-# LANGUAGE PatternGuards #-}
{- |
Module : $Header$
Description : Heap for type checking.
Copyright : (C) 2014 Cryptography and Information Security Group, HASLab - INESC TEC and Universidade do Minho
License : GPL
Maintainer : Paulo Silva
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)