module Language.C.Analysis.NameSpaceMap (
NameSpaceMap, nameSpaceMap, nsMapToList,
globalNames,localNames,hasLocalNames,
defGlobal,
enterNewScope, leaveScope,
defLocal,
lookupName,lookupGlobal,lookupInnermostScope,
mergeNameSpace
)
where
import Prelude hiding (lookup)
import qualified Prelude
import qualified Data.Map as Map (empty, insert, lookup, toList, union)
import qualified Data.List as List (unionBy)
import Data.Map (Map)
data NameSpaceMap k v = NsMap (Map k v)
[[(k, v)]]
globalNames :: (Ord k) => NameSpaceMap k v -> Map k v
globalNames :: forall k v. Ord k => NameSpaceMap k v -> Map k v
globalNames (NsMap Map k v
g [[(k, v)]]
_) = Map k v
g
hasLocalNames :: NameSpaceMap k v -> Bool
hasLocalNames :: forall k v. NameSpaceMap k v -> Bool
hasLocalNames (NsMap Map k v
_ [[(k, v)]]
l) = Bool -> Bool
not ([[(k, v)]] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [[(k, v)]]
l)
localNames :: (Ord k) => NameSpaceMap k v -> [[(k,v)]]
localNames :: forall k v. Ord k => NameSpaceMap k v -> [[(k, v)]]
localNames (NsMap Map k v
_ [[(k, v)]]
l) = [[(k, v)]]
l
nameSpaceMap :: (Ord k) => NameSpaceMap k v
nameSpaceMap :: forall k v. Ord k => NameSpaceMap k v
nameSpaceMap = Map k v -> [[(k, v)]] -> NameSpaceMap k v
forall k v. Map k v -> [[(k, v)]] -> NameSpaceMap k v
NsMap Map k v
forall k a. Map k a
Map.empty []
defGlobal :: (Ord k) => NameSpaceMap k a -> k -> a -> (NameSpaceMap k a, Maybe a)
defGlobal :: forall k a.
Ord k =>
NameSpaceMap k a -> k -> a -> (NameSpaceMap k a, Maybe a)
defGlobal (NsMap Map k a
gs [[(k, a)]]
lss) k
ident a
def
= (Map k a -> [[(k, a)]] -> NameSpaceMap k a
forall k v. Map k v -> [[(k, v)]] -> NameSpaceMap k v
NsMap (k -> a -> Map k a -> Map k a
forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert k
ident a
def Map k a
gs) [[(k, a)]]
lss, k -> Map k a -> Maybe a
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup k
ident Map k a
gs)
enterNewScope :: (Ord k) => NameSpaceMap k a -> NameSpaceMap k a
enterNewScope :: forall k a. Ord k => NameSpaceMap k a -> NameSpaceMap k a
enterNewScope (NsMap Map k a
gs [[(k, a)]]
lss) = Map k a -> [[(k, a)]] -> NameSpaceMap k a
forall k v. Map k v -> [[(k, v)]] -> NameSpaceMap k v
NsMap Map k a
gs ([][(k, a)] -> [[(k, a)]] -> [[(k, a)]]
forall a. a -> [a] -> [a]
:[[(k, a)]]
lss)
leaveScope :: (Ord k) => NameSpaceMap k a -> (NameSpaceMap k a, [(k, a)])
leaveScope :: forall k a.
Ord k =>
NameSpaceMap k a -> (NameSpaceMap k a, [(k, a)])
leaveScope (NsMap Map k a
_ []) = [Char] -> (NameSpaceMap k a, [(k, a)])
forall a. HasCallStack => [Char] -> a
error [Char]
"NsMaps.leaveScope: No local scope!"
leaveScope (NsMap Map k a
gs ([(k, a)]
ls:[[(k, a)]]
lss)) = (Map k a -> [[(k, a)]] -> NameSpaceMap k a
forall k v. Map k v -> [[(k, v)]] -> NameSpaceMap k v
NsMap Map k a
gs [[(k, a)]]
lss, [(k, a)]
ls)
defLocal :: (Ord k) => NameSpaceMap k a -> k -> a -> (NameSpaceMap k a, Maybe a)
defLocal :: forall k a.
Ord k =>
NameSpaceMap k a -> k -> a -> (NameSpaceMap k a, Maybe a)
defLocal ns :: NameSpaceMap k a
ns@(NsMap Map k a
_ []) k
ident a
def = NameSpaceMap k a -> k -> a -> (NameSpaceMap k a, Maybe a)
forall k a.
Ord k =>
NameSpaceMap k a -> k -> a -> (NameSpaceMap k a, Maybe a)
defGlobal NameSpaceMap k a
ns k
ident a
def
defLocal (NsMap Map k a
gs ([(k, a)]
ls:[[(k, a)]]
lss)) k
ident a
def =
(Map k a -> [[(k, a)]] -> NameSpaceMap k a
forall k v. Map k v -> [[(k, v)]] -> NameSpaceMap k v
NsMap Map k a
gs (((k
ident, a
def)(k, a) -> [(k, a)] -> [(k, a)]
forall a. a -> [a] -> [a]
:[(k, a)]
ls)[(k, a)] -> [[(k, a)]] -> [[(k, a)]]
forall a. a -> [a] -> [a]
:[[(k, a)]]
lss),
k -> [(k, a)] -> Maybe a
forall a b. Eq a => a -> [(a, b)] -> Maybe b
Prelude.lookup k
ident [(k, a)]
ls)
lookupName :: (Ord k) => NameSpaceMap k a -> k -> Maybe a
lookupName :: forall k a. Ord k => NameSpaceMap k a -> k -> Maybe a
lookupName ns :: NameSpaceMap k a
ns@(NsMap Map k a
_ [[(k, a)]]
localDefs) k
ident
= case [[(k, a)]] -> Maybe a
forall {a}. [[(k, a)]] -> Maybe a
lookupLocal [[(k, a)]]
localDefs of
Maybe a
Nothing -> NameSpaceMap k a -> k -> Maybe a
forall k a. Ord k => NameSpaceMap k a -> k -> Maybe a
lookupGlobal NameSpaceMap k a
ns k
ident
Just a
def -> a -> Maybe a
forall a. a -> Maybe a
Just a
def
where
lookupLocal :: [[(k, a)]] -> Maybe a
lookupLocal [] = Maybe a
forall a. Maybe a
Nothing
lookupLocal ([(k, a)]
ls:[[(k, a)]]
lss) =
case k -> [(k, a)] -> Maybe a
forall a b. Eq a => a -> [(a, b)] -> Maybe b
Prelude.lookup k
ident [(k, a)]
ls of
Maybe a
Nothing -> [[(k, a)]] -> Maybe a
lookupLocal [[(k, a)]]
lss
Just a
def -> a -> Maybe a
forall a. a -> Maybe a
Just a
def
lookupGlobal :: (Ord k) => NameSpaceMap k a -> k -> Maybe a
lookupGlobal :: forall k a. Ord k => NameSpaceMap k a -> k -> Maybe a
lookupGlobal (NsMap Map k a
gs [[(k, a)]]
_) k
ident = k -> Map k a -> Maybe a
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup k
ident Map k a
gs
lookupInnermostScope :: (Ord k) => NameSpaceMap k a -> k -> Maybe a
lookupInnermostScope :: forall k a. Ord k => NameSpaceMap k a -> k -> Maybe a
lookupInnermostScope nsm :: NameSpaceMap k a
nsm@(NsMap Map k a
_gs [[(k, a)]]
localDefs) k
ident =
case [[(k, a)]]
localDefs of
([(k, a)]
ls : [[(k, a)]]
_lss) -> k -> [(k, a)] -> Maybe a
forall a b. Eq a => a -> [(a, b)] -> Maybe b
Prelude.lookup k
ident [(k, a)]
ls
[] -> NameSpaceMap k a -> k -> Maybe a
forall k a. Ord k => NameSpaceMap k a -> k -> Maybe a
lookupGlobal NameSpaceMap k a
nsm k
ident
nsMapToList :: (Ord k) => NameSpaceMap k a -> [(k, a)]
nsMapToList :: forall k a. Ord k => NameSpaceMap k a -> [(k, a)]
nsMapToList (NsMap Map k a
gs [[(k, a)]]
lss) = [[(k, a)]] -> [(k, a)]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [[(k, a)]]
lss [(k, a)] -> [(k, a)] -> [(k, a)]
forall a. [a] -> [a] -> [a]
++ Map k a -> [(k, a)]
forall k a. Map k a -> [(k, a)]
Map.toList Map k a
gs
mergeNameSpace :: (Ord k) =>
NameSpaceMap k a
-> NameSpaceMap k a
-> NameSpaceMap k a
mergeNameSpace :: forall k a.
Ord k =>
NameSpaceMap k a -> NameSpaceMap k a -> NameSpaceMap k a
mergeNameSpace (NsMap Map k a
global1 [[(k, a)]]
local1) (NsMap Map k a
global2 [[(k, a)]]
local2) =
Map k a -> [[(k, a)]] -> NameSpaceMap k a
forall k v. Map k v -> [[(k, v)]] -> NameSpaceMap k v
NsMap (Map k a -> Map k a -> Map k a
forall k a. Ord k => Map k a -> Map k a -> Map k a
Map.union Map k a
global1 Map k a
global2) ([[(k, a)]] -> [[(k, a)]] -> [[(k, a)]]
forall {a} {b}. Eq a => [[(a, b)]] -> [[(a, b)]] -> [[(a, b)]]
localUnion [[(k, a)]]
local1 [[(k, a)]]
local2)
where localUnion :: [[(a, b)]] -> [[(a, b)]] -> [[(a, b)]]
localUnion ([(a, b)]
l1:[[(a, b)]]
ls1) ([(a, b)]
l2:[[(a, b)]]
ls2) =
((a, b) -> (a, b) -> Bool) -> [(a, b)] -> [(a, b)] -> [(a, b)]
forall a. (a -> a -> Bool) -> [a] -> [a] -> [a]
List.unionBy (\(a, b)
p1 (a, b)
p2 -> (a, b) -> a
forall a b. (a, b) -> a
fst (a, b)
p1 a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== (a, b) -> a
forall a b. (a, b) -> a
fst (a, b)
p2) [(a, b)]
l1 [(a, b)]
l2 [(a, b)] -> [[(a, b)]] -> [[(a, b)]]
forall a. a -> [a] -> [a]
: [[(a, b)]] -> [[(a, b)]] -> [[(a, b)]]
localUnion [[(a, b)]]
ls1 [[(a, b)]]
ls2
localUnion [] [[(a, b)]]
ls2 = [[(a, b)]]
ls2
localUnion [[(a, b)]]
ls1 [] = [[(a, b)]]
ls1