diff options
Diffstat (limited to 'lib/Language/Elna/SymbolTable.hs')
| -rw-r--r-- | lib/Language/Elna/SymbolTable.hs | 55 |
1 files changed, 31 insertions, 24 deletions
diff --git a/lib/Language/Elna/SymbolTable.hs b/lib/Language/Elna/SymbolTable.hs index c8406fc..52b8542 100644 --- a/lib/Language/Elna/SymbolTable.hs +++ b/lib/Language/Elna/SymbolTable.hs @@ -1,64 +1,72 @@ module Language.Elna.SymbolTable ( SymbolTable - , empty - {-, Info(..) + , Info(..) , ParameterInfo(..) , builtInSymbolTable + , empty , enter , fromList , lookup - , member -} + , member + , scope + , toMap + , update ) where -data SymbolTable = SymbolTable -- (HashMap Identifier Info) - deriving (Eq, Show) - -empty :: SymbolTable -empty = SymbolTable -- HashMap.empty - -{- import Data.HashMap.Strict (HashMap) import qualified Data.HashMap.Strict as HashMap import Data.List (sort) import Data.List.NonEmpty (NonEmpty) import qualified Data.List.NonEmpty as NonEmpty +import Data.Maybe (isJust) import Data.Vector (Vector) import Language.Elna.Location (Identifier(..)) import Language.Elna.Types (Type(..), intType, booleanType) import Prelude hiding (lookup) -instance Semigroup SymbolTable - where - (SymbolTable lhs) <> (SymbolTable rhs) = SymbolTable $ rhs <> lhs +data SymbolTable = SymbolTable (Maybe SymbolTable) (HashMap Identifier Info) + deriving (Eq, Show) -instance Monoid SymbolTable - where - mempty = empty +empty :: SymbolTable +empty = SymbolTable Nothing HashMap.empty + +update :: (Info -> Maybe Info) -> Identifier -> SymbolTable -> SymbolTable +update updater key (SymbolTable parent mappings) = SymbolTable parent + $ HashMap.update updater key mappings + +scope :: SymbolTable -> SymbolTable -> SymbolTable +scope parent (SymbolTable _ mappings) = SymbolTable (Just parent) mappings builtInSymbolTable :: SymbolTable -builtInSymbolTable = SymbolTable $ HashMap.fromList +builtInSymbolTable = SymbolTable Nothing $ HashMap.fromList [ ("boolean", TypeInfo booleanType) , ("int", TypeInfo intType) ] +toMap :: SymbolTable -> HashMap Identifier Info +toMap (SymbolTable _ map') = map' + enter :: Identifier -> Info -> SymbolTable -> Maybe SymbolTable -enter identifier info table@(SymbolTable hashTable) +enter identifier info table@(SymbolTable parent hashTable) | member identifier table = Nothing | otherwise = Just - $ SymbolTable - $ HashMap.insert identifier info hashTable + $ SymbolTable parent (HashMap.insert identifier info hashTable) lookup :: Identifier -> SymbolTable -> Maybe Info -lookup identifier (SymbolTable table) = HashMap.lookup identifier table +lookup identifier (SymbolTable parent table) + | Just found <- HashMap.lookup identifier table = Just found + | Just parent' <- parent = lookup identifier parent' + | otherwise = Nothing member :: Identifier -> SymbolTable -> Bool -member identifier (SymbolTable table) = HashMap.member identifier table +member identifier table = + isJust $ lookup identifier table fromList :: [(Identifier, Info)] -> Either (NonEmpty Identifier) SymbolTable fromList elements | Just identifierDuplicates' <- identifierDuplicates = Left identifierDuplicates' - | otherwise = Right $ SymbolTable $ HashMap.fromList elements + | otherwise = Right $ SymbolTable Nothing $ HashMap.fromList elements where identifierDuplicates = NonEmpty.nonEmpty $ fmap NonEmpty.head @@ -77,4 +85,3 @@ data Info | VariableInfo Bool Type | ProcedureInfo SymbolTable (Vector ParameterInfo) deriving (Eq, Show) --} |
