<commit_before>module Language.K3.Analysis.Data.BindingEnv where

import Prelude hiding ( lookup )
import Control.Monad.Trans.Except

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

import Data.Text ( Text )
import qualified Data.Text as T

import Language.K3.Core.Common

{- Binding environment data structures -}
type BindingEnv      a = HashMap Identifier a
type BindingStackEnv a = BindingEnv [a]

{- Data.Text helpers -}
mkErr :: String -> Except Text a
mkErr msg = throwE $ T.pack msg

{- BindingEnv helpers -}
empty :: BindingEnv a
empty = Map.empty

member :: BindingEnv a -> Identifier -> Except Text Bool
member env x = return $ Map.member x env

lookup :: BindingEnv a -> Identifier -> Except Text a
lookup env x = maybe err return $ Map.lookup x env
  where err = mkErr $ "Unbound variable in binding environment: " ++ x

mlookup :: BindingEnv a -> Identifier -> Maybe a
mlookup env x = Map.lookup x env

pushWith :: BindingEnv a -> (a -> a -> a) -> Identifier -> a -> BindingEnv a
pushWith env f x v = Map.insertWith f x v env

popWith :: BindingEnv a -> (a -> Maybe a) -> Identifier -> BindingEnv a
popWith env f x = maybe env (maybe (Map.delete x env)
                                   (\nv -> Map.adjust (const nv) x env)
                             . f)
                    $ Map.lookup x env

set :: BindingEnv a -> Identifier -> a -> BindingEnv a
set env x v = Map.insert x v env

delete :: BindingEnv a -> Identifier -> BindingEnv a
delete env x = Map.delete x env

union :: BindingEnv a -> BindingEnv a -> BindingEnv a
union = Map.union

unions :: [BindingEnv a] -> BindingEnv a
unions = Map.unions

foldl :: (b -> Identifier -> a -> b) -> b -> BindingEnv a -> b
foldl f z env = Map.foldlWithKey' f z env

keys :: BindingEnv a -> [Identifier]
keys = Map.keys

partition :: (Identifier -> a -> Bool) -> BindingEnv a -> (BindingEnv a, BindingEnv a)
partition f env = Map.foldlWithKey' part (empty, empty) env
  where part (tacc,facc) k v = if f k v then (Map.insert k v tacc, facc)
                                        else (tacc, Map.insert k v facc)

fromList :: [(Identifier, a)] -> BindingEnv a
fromList = Map.fromList

{- BindingStackEnv helpers -}

slookup :: BindingStackEnv a -> Identifier -> Except Text a
slookup env x = lookup env x >>= safeHead
  where
    safeHead l = if null l then err else return $ head l
    err = mkErr $ "Unbound variable in binding environment: " ++ x

push :: BindingStackEnv a -> Identifier -> a -> BindingStackEnv a<commit_msg>Adding map method to binding env<commit_after>module Language.K3.Analysis.Data.BindingEnv where

import Prelude hiding ( lookup )
import Control.Monad.Trans.Except

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

import Data.Text ( Text )
import qualified Data.Text as T

import Language.K3.Core.Common

{- Binding environment data structures -}
type BindingEnv      a = HashMap Identifier a
type BindingStackEnv a = BindingEnv [a]

{- Data.Text helpers -}
mkErr :: String -> Except Text a
mkErr msg = throwE $ T.pack msg

{- BindingEnv helpers -}
empty :: BindingEnv a
empty = Map.empty

member :: BindingEnv a -> Identifier -> Except Text Bool
member env x = return $ Map.member x env

lookup :: BindingEnv a -> Identifier -> Except Text a
lookup env x = maybe err return $ Map.lookup x env
  where err = mkErr $ "Unbound variable in binding environment: " ++ x

mlookup :: BindingEnv a -> Identifier -> Maybe a
mlookup env x = Map.lookup x env

pushWith :: BindingEnv a -> (a -> a -> a) -> Identifier -> a -> BindingEnv a
pushWith env f x v = Map.insertWith f x v env

popWith :: BindingEnv a -> (a -> Maybe a) -> Identifier -> BindingEnv a
popWith env f x = maybe env (maybe (Map.delete x env)
                                   (\nv -> Map.adjust (const nv) x env)
                             . f)
                    $ Map.lookup x env

set :: BindingEnv a -> Identifier -> a -> BindingEnv a
set env x v = Map.insert x v env

delete :: BindingEnv a -> Identifier -> BindingEnv a
delete env x = Map.delete x env

union :: BindingEnv a -> BindingEnv a -> BindingEnv a
union = Map.union

unions :: [BindingEnv a] -> BindingEnv a
unions = Map.unions

map :: (a -> b) -> BindingEnv a -> BindingEnv b
map f env = Map.map f env

foldl :: (b -> Identifier -> a -> b) -> b -> BindingEnv a -> b
foldl f z env = Map.foldlWithKey' f z env

keys :: BindingEnv a -> [Identifier]
keys = Map.keys

partition :: (Identifier -> a -> Bool) -> BindingEnv a -> (BindingEnv a, BindingEnv a)
partition f env = Map.foldlWithKey' part (empty, empty) env
  where part (tacc,facc) k v = if f k v then (Map.insert k v tacc, facc)
                                        else (tacc, Map.insert k v facc)

fromList :: [(Identifier, a)] -> BindingEnv a
fromList = Map.fromList

{- BindingStackEnv helpers -}

slookup :: BindingStackEnv a -> Identifier -> Except Text a
slookup env x = lookup env x >>= safeHead
  where
    safeHead l = if null l then err else return $ head l
    err = mkErr $ "Unbound variable in binding environment: " ++ x

push :: BindingStackEnv a -> Identifier -> a -> BindingStackEnv a
{'fraction_non_alphanumeric': 0.10700389105058365, 'fraction_numerical': 0.0007782101167315176, 'mean_word_length': 2.706560922855083, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 96, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '517502', 'n_tokens_mistral': 1600, 'n_tokens_neox': 1528, 'n_words': 649}